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