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