QGIS API Documentation 4.1.0-Master (60fea48833c)
Loading...
Searching...
No Matches
qgscolorscheme.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgscolorscheme.cpp
3 -------------------
4 begin : July 2014
5 copyright : (C) 2014 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include "qgscolorscheme.h"
19
20#include "qgsapplication.h"
22#include "qgscolorutils.h"
23#include "qgsproject.h"
24#include "qgssettings.h"
25#include "qgssymbollayerutils.h"
26
27#include <QDir>
28#include <QRegularExpression>
29#include <QString>
30#include <QTextStream>
31
32using namespace Qt::StringLiterals;
33
34bool QgsColorScheme::setColors( const QgsNamedColorList &colors, const QString &context, const QColor &baseColor )
35{
36 //base implementation does nothing
37 Q_UNUSED( colors )
38 Q_UNUSED( context )
39 Q_UNUSED( baseColor )
40 return false;
41}
42
43
44//
45// QgsRecentColorScheme
46//
47
48QgsNamedColorList QgsRecentColorScheme::fetchColors( const QString &context, const QColor &baseColor )
49{
50 Q_UNUSED( context )
51 Q_UNUSED( baseColor )
52
53 //fetch recent colors
54 const QgsSettings settings;
55 const QList< QVariant > recentColorVariants = settings.value( u"colors/recent"_s ).toList();
56
57 //generate list from recent colors
58 QgsNamedColorList colorList;
59 const auto constRecentColorVariants = recentColorVariants;
60 for ( const QVariant &color : constRecentColorVariants )
61 {
62 colorList.append( qMakePair( color.value<QColor>(), QgsSymbolLayerUtils::colorToName( color.value<QColor>() ) ) );
63 }
64 return colorList;
65}
66
71
72void QgsRecentColorScheme::addRecentColor( const QColor &color )
73{
74 if ( !color.isValid() )
75 {
76 return;
77 }
78
79 //strip alpha from color
80 QColor opaqueColor = color;
81 opaqueColor.setAlpha( 255 );
82
83 QgsSettings settings;
84 QList< QVariant > recentColorVariants = settings.value( u"colors/recent"_s ).toList();
85
86 //remove colors by name
87 for ( int colorIdx = recentColorVariants.length() - 1; colorIdx >= 0; --colorIdx )
88 {
89 if ( ( recentColorVariants.at( colorIdx ).value<QColor>() ).name() == opaqueColor.name() )
90 {
91 recentColorVariants.removeAt( colorIdx );
92 }
93 }
94
95 //add color
96 const QVariant colorVariant = QVariant( opaqueColor );
97 recentColorVariants.prepend( colorVariant );
98
99 //trim to 20 colors
100 while ( recentColorVariants.count() > 20 )
101 {
102 recentColorVariants.pop_back();
103 }
104
105 settings.setValue( u"colors/recent"_s, recentColorVariants );
106}
107
109{
110 //fetch recent colors
111 const QgsSettings settings;
112 const QList< QVariant > recentColorVariants = settings.value( u"colors/recent"_s ).toList();
113
114 if ( recentColorVariants.isEmpty() )
115 return QColor();
116
117 return recentColorVariants.at( 0 ).value<QColor>();
118}
119
120QgsNamedColorList QgsCustomColorScheme::fetchColors( const QString &context, const QColor &baseColor )
121{
122 Q_UNUSED( context )
123 Q_UNUSED( baseColor )
124
125 //fetch predefined custom colors
126 QgsNamedColorList colorList;
127 const QgsSettings settings;
128
129 //check if settings contains custom palette
130 if ( !settings.contains( u"/colors/palettecolors"_s ) )
131 {
132 //no custom palette, return default colors
133 colorList.append( qMakePair( QColor( 0, 0, 0 ), QString() ) );
134 colorList.append( qMakePair( QColor( 255, 255, 255 ), QString() ) );
135 colorList.append( qMakePair( QColor( 166, 206, 227 ), QString() ) );
136 colorList.append( qMakePair( QColor( 31, 120, 180 ), QString() ) );
137 colorList.append( qMakePair( QColor( 178, 223, 138 ), QString() ) );
138 colorList.append( qMakePair( QColor( 51, 160, 44 ), QString() ) );
139 colorList.append( qMakePair( QColor( 251, 154, 153 ), QString() ) );
140 colorList.append( qMakePair( QColor( 227, 26, 28 ), QString() ) );
141 colorList.append( qMakePair( QColor( 253, 191, 111 ), QString() ) );
142 colorList.append( qMakePair( QColor( 255, 127, 0 ), QString() ) );
143
144 return colorList;
145 }
146
147 QList< QVariant > customColorVariants = settings.value( u"colors/palettecolors"_s ).toList();
148 const QList< QVariant > customColorLabels = settings.value( u"colors/palettelabels"_s ).toList();
149
150 //generate list from custom colors
151 int colorIndex = 0;
152 for ( QList< QVariant >::iterator it = customColorVariants.begin(); it != customColorVariants.end(); ++it )
153 {
154 const QColor color = ( *it ).value<QColor>();
155 QString label;
156 if ( customColorLabels.length() > colorIndex )
157 {
158 label = customColorLabels.at( colorIndex ).toString();
159 }
160
161 colorList.append( qMakePair( color, label ) );
162 colorIndex++;
163 }
164
165 return colorList;
166}
167
168bool QgsCustomColorScheme::setColors( const QgsNamedColorList &colors, const QString &context, const QColor &baseColor )
169{
170 Q_UNUSED( context )
171 Q_UNUSED( baseColor )
172
173 // save colors to settings
174 QgsSettings settings;
175 QList< QVariant > customColors;
176 QList< QVariant > customColorLabels;
177
178 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
179 for ( ; colorIt != colors.constEnd(); ++colorIt )
180 {
181 const QVariant color = ( *colorIt ).first;
182 const QVariant label = ( *colorIt ).second;
183 customColors.append( color );
184 customColorLabels.append( label );
185 }
186 settings.setValue( u"colors/palettecolors"_s, customColors );
187 settings.setValue( u"colors/palettelabels"_s, customColorLabels );
188 return true;
189}
190
195
196
197QgsNamedColorList QgsProjectColorScheme::fetchColors( const QString &context, const QColor &baseColor )
198{
199 Q_UNUSED( context )
200 Q_UNUSED( baseColor )
201
202 QgsNamedColorList colorList;
203
204 QStringList colorStrings = QgsProject::instance()->readListEntry( u"Palette"_s, u"/Colors"_s ); // skip-keyword-check
205 const QStringList colorLabels = QgsProject::instance()->readListEntry( u"Palette"_s, u"/Labels"_s ); // skip-keyword-check
206
207 //generate list from custom colors
208 int colorIndex = 0;
209 for ( QStringList::iterator it = colorStrings.begin(); it != colorStrings.end(); ++it )
210 {
211 const QColor color = QgsColorUtils::colorFromString( *it );
212 QString label;
213 if ( colorLabels.length() > colorIndex )
214 {
215 label = colorLabels.at( colorIndex );
216 }
217
218 colorList.append( qMakePair( color, label ) );
219 colorIndex++;
220 }
221
222 return colorList;
223}
224
225bool QgsProjectColorScheme::setColors( const QgsNamedColorList &colors, const QString &context, const QColor &baseColor )
226{
227 Q_UNUSED( context )
228 Q_UNUSED( baseColor )
229 QgsProject::instance()->setProjectColors( colors ); // skip-keyword-check
230 return true;
231}
232
237
238
239//
240// QgsGplColorScheme
241//
242
243QgsNamedColorList QgsGplColorScheme::fetchColors( const QString &context, const QColor &baseColor )
244{
245 Q_UNUSED( context )
246 Q_UNUSED( baseColor )
247
248 const QString sourceFilePath = gplFilePath();
249 if ( sourceFilePath.isEmpty() )
250 {
251 QgsNamedColorList noColors;
252 return noColors;
253 }
254
255 bool ok;
256 QString name;
257 QFile sourceFile( sourceFilePath );
258 return QgsSymbolLayerUtils::importColorsFromGpl( sourceFile, ok, name );
259}
260
261bool QgsGplColorScheme::setColors( const QgsNamedColorList &colors, const QString &context, const QColor &baseColor )
262{
263 Q_UNUSED( context )
264 Q_UNUSED( baseColor )
265
266 const QString destFilePath = gplFilePath();
267 if ( destFilePath.isEmpty() )
268 {
269 return false;
270 }
271
272 QFile destFile( destFilePath );
273 if ( QgsSymbolLayerUtils::saveColorsToGpl( destFile, schemeName(), colors ) )
274 {
275 if ( QgsApplication::colorSchemeRegistry()->randomStyleColorScheme() == this )
276 {
277 // force a re-generation of the random style color list, since the color list has changed
279 }
280 return true;
281 }
282 else
283 {
284 return false;
285 }
286}
287
288
289//
290// QgsUserColorScheme
291//
292
294 : mFilename( filename )
295{
296 QFile sourceFile( gplFilePath() );
297
298 //read in name
299 if ( sourceFile.open( QIODevice::ReadOnly ) )
300 {
301 QTextStream in( &sourceFile );
302
303 //find name line
304 QString line;
305 while ( !in.atEnd() && !line.startsWith( "Name:"_L1 ) )
306 {
307 line = in.readLine();
308 }
309 if ( !in.atEnd() )
310 {
311 const thread_local QRegularExpression rx( "Name:\\s*(\\S.*)$" );
312 const QRegularExpressionMatch match = rx.match( line );
313 if ( match.hasMatch() )
314 {
315 mName = match.captured( 1 );
316 }
317 }
318 }
319 if ( mName.isEmpty() )
320 {
322 }
323
324 // we consider this scheme writable if the user has permission, OR
325 // if it DOESN'T already exist (since new schemes are only created when
326 // first written to)
327 const QFileInfo sourceFileInfo( gplFilePath() );
328 mEditable = !sourceFileInfo.exists() || sourceFileInfo.isWritable();
329}
330
332{
333 return mName;
334}
335
340
342{
344
345 const QgsSettings s;
346 const QStringList showInMenuSchemes = s.value( u"/colors/showInMenuList"_s ).toStringList();
347
348 if ( showInMenuSchemes.contains( mName ) )
349 {
351 }
352
353 return f;
354}
355
357{
358 const QString filePath = gplFilePath();
359 if ( filePath.isEmpty() )
360 {
361 return false;
362 }
363
364 // if file does not exist, nothing to do on the disk, so we can consider erasing done
365 if ( !QFile::exists( filePath ) )
366 {
367 return true;
368 }
369
370 //try to erase gpl file
371 return QFile::remove( filePath );
372}
373
375{
376 QgsSettings s;
377 QStringList showInMenuSchemes = s.value( u"/colors/showInMenuList"_s ).toStringList();
378
379 if ( show && !showInMenuSchemes.contains( mName ) )
380 {
381 showInMenuSchemes << mName;
382 }
383 else if ( !show && showInMenuSchemes.contains( mName ) )
384 {
385 showInMenuSchemes.removeAll( mName );
386 }
387
388 s.setValue( u"/colors/showInMenuList"_s, showInMenuSchemes );
389}
390
392{
393 const QString palettesDir = QgsApplication::qgisSettingsDirPath() + "palettes";
394
395 const QDir localDir;
396 if ( !localDir.mkpath( palettesDir ) )
397 {
398 return QString();
399 }
400
401 return QDir( palettesDir ).filePath( mFilename );
402}
static QgsColorSchemeRegistry * colorSchemeRegistry()
Returns the application's color scheme registry, used for managing color schemes.
static QString qgisSettingsDirPath()
Returns the path to the settings directory in user's home dir.
void setRandomStyleColorScheme(QgsColorScheme *scheme)
Sets the color scheme to use when fetching random colors to use for symbol styles.
@ ShowInColorButtonMenu
Show scheme in color button drop-down menu.
virtual QString schemeName() const =0
Gets the name for the color scheme.
virtual bool setColors(const QgsNamedColorList &colors, const QString &context=QString(), const QColor &baseColor=QColor())
Sets the colors for the scheme.
virtual SchemeFlags flags() const
Returns the current flags for the color scheme.
QFlags< SchemeFlag > SchemeFlags
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
QgsNamedColorList fetchColors(const QString &context=QString(), const QColor &baseColor=QColor()) override
Gets a list of colors from the scheme.
bool setColors(const QgsNamedColorList &colors, const QString &context=QString(), const QColor &baseColor=QColor()) override
Sets the colors for the scheme.
QgsCustomColorScheme * clone() const override
Clones a color scheme.
QgsCustomColorScheme()=default
virtual QString gplFilePath()=0
Returns the file path for the associated gpl palette file.
QgsNamedColorList fetchColors(const QString &context=QString(), const QColor &baseColor=QColor()) override
Gets a list of colors from the scheme.
bool setColors(const QgsNamedColorList &colors, const QString &context=QString(), const QColor &baseColor=QColor()) override
Sets the colors for the scheme.
QgsProjectColorScheme * clone() const override
Clones a color scheme.
bool setColors(const QgsNamedColorList &colors, const QString &context=QString(), const QColor &baseColor=QColor()) override
Sets the colors for the scheme.
QgsProjectColorScheme()=default
QgsNamedColorList fetchColors(const QString &context=QString(), const QColor &baseColor=QColor()) override
Gets a list of colors from the scheme.
static QgsProject * instance()
Returns the QgsProject singleton instance.
void setProjectColors(const QgsNamedColorList &colors)
Sets the colors for the project's color scheme (see QgsProjectColorScheme).
QStringList readListEntry(const QString &scope, const QString &key, const QStringList &def=QStringList(), bool *ok=nullptr) const
Reads a string list from the specified scope and key.
QgsRecentColorScheme()=default
QgsNamedColorList fetchColors(const QString &context=QString(), const QColor &baseColor=QColor()) override
Gets a list of colors from the scheme.
static QColor lastUsedColor()
Returns the most recently used color.
QgsRecentColorScheme * clone() const override
Clones a color scheme.
static void addRecentColor(const QColor &color)
Adds a color to the list of recent colors.
Stores settings for use within QGIS.
Definition qgssettings.h:68
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static bool saveColorsToGpl(QFile &file, const QString &paletteName, const QgsNamedColorList &colors)
Exports colors to a gpl GIMP palette file.
static QgsNamedColorList importColorsFromGpl(QFile &file, bool &ok, QString &name)
Imports colors from a gpl GIMP palette file.
static QString colorToName(const QColor &color)
Returns a friendly display name for a color.
QString schemeName() const override
Gets the name for the color scheme.
QgsUserColorScheme(const QString &filename)
Constructs a new user color scheme, using a specified gpl palette file.
QgsColorScheme::SchemeFlags flags() const override
Returns the current flags for the color scheme.
QString gplFilePath() override
Returns the file path for the associated gpl palette file.
bool erase()
Erases the associated gpl palette file from the users "palettes" folder.
void setShowSchemeInMenu(bool show)
Sets whether a this scheme should be shown in color button menus.
QgsUserColorScheme * clone() const override
Clones a color scheme.
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.