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