QGIS API Documentation  3.6.0-Noosa (5873452)
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 );
225  return true;
226 }
227 
229 {
230  return new QgsProjectColorScheme();
231 }
232 
233 
234 //
235 // QgsGplColorScheme
236 //
237 
238 QgsNamedColorList QgsGplColorScheme::fetchColors( const QString &context, const QColor &baseColor )
239 {
240  Q_UNUSED( context );
241  Q_UNUSED( baseColor );
242 
243  QString sourceFilePath = gplFilePath();
244  if ( sourceFilePath.isEmpty() )
245  {
246  QgsNamedColorList noColors;
247  return noColors;
248  }
249 
250  bool ok;
251  QString name;
252  QFile sourceFile( sourceFilePath );
253  return QgsSymbolLayerUtils::importColorsFromGpl( sourceFile, ok, name );
254 }
255 
256 bool QgsGplColorScheme::setColors( const QgsNamedColorList &colors, const QString &context, const QColor &baseColor )
257 {
258  Q_UNUSED( context );
259  Q_UNUSED( baseColor );
260 
261  QString destFilePath = gplFilePath();
262  if ( destFilePath.isEmpty() )
263  {
264  return false;
265  }
266 
267  QFile destFile( destFilePath );
268  if ( QgsSymbolLayerUtils::saveColorsToGpl( destFile, schemeName(), colors ) )
269  {
270  if ( QgsApplication::colorSchemeRegistry()->randomStyleColorScheme() == this )
271  {
272  // force a re-generation of the random style color list, since the color list has changed
274  }
275  return true;
276  }
277  else
278  {
279  return false;
280  }
281 }
282 
283 
284 //
285 // QgsUserColorScheme
286 //
287 
288 QgsUserColorScheme::QgsUserColorScheme( const QString &filename )
289  : mFilename( filename )
290 {
291  QFile sourceFile( gplFilePath() );
292 
293  //read in name
294  if ( sourceFile.open( QIODevice::ReadOnly ) )
295  {
296  QTextStream in( &sourceFile );
297 
298  //find name line
299  QString line;
300  while ( !in.atEnd() && !line.startsWith( QLatin1String( "Name:" ) ) )
301  {
302  line = in.readLine();
303  }
304  if ( !in.atEnd() )
305  {
306  QRegExp rx( "Name:\\s*(\\S.*)$" );
307  if ( rx.indexIn( line ) != -1 )
308  {
309  mName = rx.cap( 1 );
310  }
311  }
312  }
313  if ( mName.isEmpty() )
314  {
315  mName = mFilename;
316  }
317 
318  // we consider this scheme writable if the user has permission, OR
319  // if it DOESN'T already exist (since new schemes are only created when
320  // first written to)
321  QFileInfo sourceFileInfo( gplFilePath() );
322  mEditable = !sourceFileInfo.exists() || sourceFileInfo.isWritable();
323 }
324 
326 {
327  return mName;
328 }
329 
331 {
332  return new QgsUserColorScheme( mFilename );
333 }
334 
335 QgsColorScheme::SchemeFlags QgsUserColorScheme::flags() const
336 {
337  QgsColorScheme::SchemeFlags f = QgsGplColorScheme::flags();
338 
339  QgsSettings s;
340  QStringList showInMenuSchemes = s.value( QStringLiteral( "/colors/showInMenuList" ) ).toStringList();
341 
342  if ( showInMenuSchemes.contains( mName ) )
343  {
345  }
346 
347  return f;
348 }
349 
351 {
352  QString filePath = gplFilePath();
353  if ( filePath.isEmpty() )
354  {
355  return false;
356  }
357 
358  //try to erase gpl file
359  return QFile::remove( filePath );
360 }
361 
363 {
364  QgsSettings s;
365  QStringList showInMenuSchemes = s.value( QStringLiteral( "/colors/showInMenuList" ) ).toStringList();
366 
367  if ( show && !showInMenuSchemes.contains( mName ) )
368  {
369  showInMenuSchemes << mName;
370  }
371  else if ( !show && showInMenuSchemes.contains( mName ) )
372  {
373  showInMenuSchemes.removeAll( mName );
374  }
375 
376  s.setValue( QStringLiteral( "/colors/showInMenuList" ), showInMenuSchemes );
377 }
378 
380 {
381  QString palettesDir = QgsApplication::qgisSettingsDirPath() + "palettes";
382 
383  QDir localDir;
384  if ( !localDir.mkpath( palettesDir ) )
385  {
386  return QString();
387  }
388 
389  return QDir( palettesDir ).filePath( mFilename );
390 }
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
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
virtual SchemeFlags flags() const
Returns the current flags for the color scheme.
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.
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 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.
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.
QStringList readListEntry(const QString &scope, const QString &key, const QStringList &def=QStringList(), bool *ok=nullptr) const
Key value accessors.
void setProjectColors(const QgsNamedColorList &colors)
Sets the colors for the project&#39;s color scheme (see QgsProjectColorScheme).
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.
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:430
static QColor lastUsedColor()
Returns the most recently used color.
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
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)