QGIS API Documentation 3.99.0-Master (d270888f95f)
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();
153 it != customColorVariants.end(); ++it )
154 {
155 const QColor color = ( *it ).value<QColor>();
156 QString label;
157 if ( customColorLabels.length() > colorIndex )
158 {
159 label = customColorLabels.at( colorIndex ).toString();
160 }
161
162 colorList.append( qMakePair( color, label ) );
163 colorIndex++;
164 }
165
166 return colorList;
167}
168
169bool QgsCustomColorScheme::setColors( const QgsNamedColorList &colors, const QString &context, const QColor &baseColor )
170{
171 Q_UNUSED( context )
172 Q_UNUSED( baseColor )
173
174 // save colors to settings
175 QgsSettings settings;
176 QList< QVariant > customColors;
177 QList< QVariant > customColorLabels;
178
179 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
180 for ( ; colorIt != colors.constEnd(); ++colorIt )
181 {
182 const QVariant color = ( *colorIt ).first;
183 const QVariant label = ( *colorIt ).second;
184 customColors.append( color );
185 customColorLabels.append( label );
186 }
187 settings.setValue( u"colors/palettecolors"_s, customColors );
188 settings.setValue( u"colors/palettelabels"_s, customColorLabels );
189 return true;
190}
191
196
197
198QgsNamedColorList QgsProjectColorScheme::fetchColors( const QString &context, const QColor &baseColor )
199{
200 Q_UNUSED( context )
201 Q_UNUSED( baseColor )
202
203 QgsNamedColorList colorList;
204
205 QStringList colorStrings = QgsProject::instance()->readListEntry( u"Palette"_s, u"/Colors"_s ); // skip-keyword-check
206 const QStringList colorLabels = QgsProject::instance()->readListEntry( u"Palette"_s, u"/Labels"_s ); // skip-keyword-check
207
208 //generate list from custom colors
209 int colorIndex = 0;
210 for ( QStringList::iterator it = colorStrings.begin();
211 it != colorStrings.end(); ++it )
212 {
213 const QColor color = QgsColorUtils::colorFromString( *it );
214 QString label;
215 if ( colorLabels.length() > colorIndex )
216 {
217 label = colorLabels.at( colorIndex );
218 }
219
220 colorList.append( qMakePair( color, label ) );
221 colorIndex++;
222 }
223
224 return colorList;
225}
226
227bool QgsProjectColorScheme::setColors( const QgsNamedColorList &colors, const QString &context, const QColor &baseColor )
228{
229 Q_UNUSED( context )
230 Q_UNUSED( baseColor )
231 QgsProject::instance()->setProjectColors( colors ); // skip-keyword-check
232 return true;
233}
234
239
240
241//
242// QgsGplColorScheme
243//
244
245QgsNamedColorList QgsGplColorScheme::fetchColors( const QString &context, const QColor &baseColor )
246{
247 Q_UNUSED( context )
248 Q_UNUSED( baseColor )
249
250 const QString sourceFilePath = gplFilePath();
251 if ( sourceFilePath.isEmpty() )
252 {
253 QgsNamedColorList noColors;
254 return noColors;
255 }
256
257 bool ok;
258 QString name;
259 QFile sourceFile( sourceFilePath );
260 return QgsSymbolLayerUtils::importColorsFromGpl( sourceFile, ok, name );
261}
262
263bool QgsGplColorScheme::setColors( const QgsNamedColorList &colors, const QString &context, const QColor &baseColor )
264{
265 Q_UNUSED( context )
266 Q_UNUSED( baseColor )
267
268 const QString destFilePath = gplFilePath();
269 if ( destFilePath.isEmpty() )
270 {
271 return false;
272 }
273
274 QFile destFile( destFilePath );
275 if ( QgsSymbolLayerUtils::saveColorsToGpl( destFile, schemeName(), colors ) )
276 {
277 if ( QgsApplication::colorSchemeRegistry()->randomStyleColorScheme() == this )
278 {
279 // force a re-generation of the random style color list, since the color list has changed
281 }
282 return true;
283 }
284 else
285 {
286 return false;
287 }
288}
289
290
291//
292// QgsUserColorScheme
293//
294
296 : mFilename( filename )
297{
298 QFile sourceFile( gplFilePath() );
299
300 //read in name
301 if ( sourceFile.open( QIODevice::ReadOnly ) )
302 {
303 QTextStream in( &sourceFile );
304
305 //find name line
306 QString line;
307 while ( !in.atEnd() && !line.startsWith( "Name:"_L1 ) )
308 {
309 line = in.readLine();
310 }
311 if ( !in.atEnd() )
312 {
313 const thread_local QRegularExpression rx( "Name:\\s*(\\S.*)$" );
314 const QRegularExpressionMatch match = rx.match( line );
315 if ( match.hasMatch() )
316 {
317 mName = match.captured( 1 );
318 }
319 }
320 }
321 if ( mName.isEmpty() )
322 {
324 }
325
326 // we consider this scheme writable if the user has permission, OR
327 // if it DOESN'T already exist (since new schemes are only created when
328 // first written to)
329 const QFileInfo sourceFileInfo( gplFilePath() );
330 mEditable = !sourceFileInfo.exists() || sourceFileInfo.isWritable();
331}
332
334{
335 return mName;
336}
337
342
344{
346
347 const QgsSettings s;
348 const QStringList showInMenuSchemes = s.value( u"/colors/showInMenuList"_s ).toStringList();
349
350 if ( showInMenuSchemes.contains( mName ) )
351 {
353 }
354
355 return f;
356}
357
359{
360 const QString filePath = gplFilePath();
361 if ( filePath.isEmpty() )
362 {
363 return false;
364 }
365
366 // if file does not exist, nothing to do on the disk, so we can consider erasing done
367 if ( ! QFile::exists( filePath ) )
368 {
369 return true;
370 }
371
372 //try to erase gpl file
373 return QFile::remove( filePath );
374}
375
377{
378 QgsSettings s;
379 QStringList showInMenuSchemes = s.value( u"/colors/showInMenuList"_s ).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( u"/colors/showInMenuList"_s, showInMenuSchemes );
391}
392
394{
395 const QString palettesDir = QgsApplication::qgisSettingsDirPath() + "palettes";
396
397 const QDir localDir;
398 if ( !localDir.mkpath( palettesDir ) )
399 {
400 return QString();
401 }
402
403 return QDir( palettesDir ).filePath( mFilename );
404}
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.