QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsstylealgorithms.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsstylealgorithms.cpp
3 ---------------------
4 begin : July 2019
5 copyright : (C) 2019 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 "qgsstylealgorithms.h"
19#include "qgsstyle.h"
20
22
23QgsCombineStylesAlgorithm::QgsCombineStylesAlgorithm() = default;
24
25QgsCombineStylesAlgorithm::~QgsCombineStylesAlgorithm() = default;
26
27void QgsCombineStylesAlgorithm::initAlgorithm( const QVariantMap & )
28{
29 addParameter( new QgsProcessingParameterMultipleLayers( QStringLiteral( "INPUT" ), QObject::tr( "Input databases" ), Qgis::ProcessingSourceType::File ) );
30
31 addParameter( new QgsProcessingParameterFileDestination( QStringLiteral( "OUTPUT" ), QObject::tr( "Output style database" ),
32 QObject::tr( "Style files (*.xml)" ) ) );
33
34 const QStringList options = QStringList()
35 << QObject::tr( "Symbols" )
36 << QObject::tr( "Color ramps" )
37 << QObject::tr( "Text formats" )
38 << QObject::tr( "Label settings" );
39 addParameter( new QgsProcessingParameterEnum( QStringLiteral( "OBJECTS" ), QObject::tr( "Objects to combine" ), options, true, QVariantList() << 0 << 1 << 2 << 3 ) );
40 addOutput( new QgsProcessingOutputNumber( QStringLiteral( "SYMBOLS" ), QObject::tr( "Symbol count" ) ) );
41 addOutput( new QgsProcessingOutputNumber( QStringLiteral( "COLORRAMPS" ), QObject::tr( "Color ramp count" ) ) );
42 addOutput( new QgsProcessingOutputNumber( QStringLiteral( "TEXTFORMATS" ), QObject::tr( "Text format count" ) ) );
43 addOutput( new QgsProcessingOutputNumber( QStringLiteral( "LABELSETTINGS" ), QObject::tr( "Label settings count" ) ) );
44}
45
46QString QgsCombineStylesAlgorithm::name() const
47{
48 return QStringLiteral( "combinestyles" );
49}
50
51QString QgsCombineStylesAlgorithm::displayName() const
52{
53 return QObject::tr( "Combine style databases" );
54}
55
56QStringList QgsCombineStylesAlgorithm::tags() const
57{
58 return QObject::tr( "symbols,colors,ramps,formats,labels,text,fonts,merge" ).split( ',' );
59}
60
61QString QgsCombineStylesAlgorithm::group() const
62{
63 return QObject::tr( "Cartography" );
64}
65
66QString QgsCombineStylesAlgorithm::groupId() const
67{
68 return QStringLiteral( "cartography" );
69}
70
71QString QgsCombineStylesAlgorithm::shortHelpString() const
72{
73 return QObject::tr( "This algorithm combines multiple QGIS style databases into a single style database. If any symbols exist with duplicate names between the different "
74 "source databases these will be renamed to have unique names in the output combined database." );
75}
76
77QString QgsCombineStylesAlgorithm::shortDescription() const
78{
79 return QObject::tr( "Combines multiple style databases into a single database." );
80}
81
82QgsCombineStylesAlgorithm *QgsCombineStylesAlgorithm::createInstance() const
83{
84 return new QgsCombineStylesAlgorithm();
85}
86
87QVariantMap QgsCombineStylesAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
88{
89 const QStringList inputs = parameterAsFileList( parameters, QStringLiteral( "INPUT" ), context );
90
91 QList< QgsStyle::StyleEntity > objects;
92 const QList< int > selectedObjects = parameterAsEnums( parameters, QStringLiteral( "OBJECTS" ), context );
93 if ( selectedObjects.contains( 0 ) )
94 objects << QgsStyle::SymbolEntity;
95 if ( selectedObjects.contains( 1 ) )
97 if ( selectedObjects.contains( 2 ) )
99 if ( selectedObjects.contains( 3 ) )
101
102 QgsStyle style;
103 style.createMemoryDatabase();
104
105 int i = 0;
106 QMap< QgsStyle::StyleEntity, QSet< QString> > usedNames;
107 auto makeUniqueName = [&usedNames]( const QString & sourceName, QgsStyle::StyleEntity type )->QString
108 {
109 QString candidate = sourceName;
110 int i = 1;
111 bool exists = true;
112 while ( exists )
113 {
114 exists = usedNames[ type ].contains( candidate );
115 if ( !exists )
116 break;
117
118 i++;
119 candidate = sourceName + QStringLiteral( " (%1)" ).arg( i );
120 }
121
122 usedNames[ type ].insert( candidate );
123 return candidate;
124 };
125
126 for ( const QString &source : inputs )
127 {
128 if ( feedback )
129 {
130 feedback->setProgress( 100 * i / static_cast< double >( inputs.count() ) );
131 feedback->pushInfo( QObject::tr( "Importing %1" ).arg( source ) );
132 }
133
134 QgsStyle sourceStyle;
135 sourceStyle.createMemoryDatabase();
136 if ( !sourceStyle.importXml( source ) )
137 {
138 feedback->reportError( QObject::tr( "Could not read %1" ).arg( source ) );
139 i++;
140 continue;
141 }
142
143 if ( objects.contains( QgsStyle::SymbolEntity ) )
144 {
145 const QStringList symbolNames = sourceStyle.symbolNames();
146 for ( const QString &name : symbolNames )
147 {
148 const QString newName = makeUniqueName( name, QgsStyle::SymbolEntity );
149 style.addSymbol( newName, sourceStyle.symbol( name ), true );
150 style.tagSymbol( QgsStyle::SymbolEntity, newName, sourceStyle.tagsOfSymbol( QgsStyle::SymbolEntity, name ) );
151 }
152 }
153 if ( objects.contains( QgsStyle::ColorrampEntity ) )
154 {
155 const QStringList colorRampNames = sourceStyle.colorRampNames();
156 for ( const QString &name : colorRampNames )
157 {
158 const QString newName = makeUniqueName( name, QgsStyle::ColorrampEntity );
159 style.addColorRamp( newName, sourceStyle.colorRamp( name ), true );
160 style.tagSymbol( QgsStyle::ColorrampEntity, newName, sourceStyle.tagsOfSymbol( QgsStyle::ColorrampEntity, name ) );
161 }
162 }
163 if ( objects.contains( QgsStyle::TextFormatEntity ) )
164 {
165 const QStringList formatNames = sourceStyle.textFormatNames();
166 for ( const QString &name : formatNames )
167 {
168 const QString newName = makeUniqueName( name, QgsStyle::TextFormatEntity );
169 style.addTextFormat( newName, sourceStyle.textFormat( name ), true );
170 style.tagSymbol( QgsStyle::TextFormatEntity, newName, sourceStyle.tagsOfSymbol( QgsStyle::TextFormatEntity, name ) );
171 }
172 }
173 if ( objects.contains( QgsStyle::LabelSettingsEntity ) )
174 {
175 const QStringList formatNames = sourceStyle.labelSettingsNames();
176 for ( const QString &name : formatNames )
177 {
178 const QString newName = makeUniqueName( name, QgsStyle::LabelSettingsEntity );
179 style.addLabelSettings( newName, sourceStyle.labelSettings( name ), true );
181 }
182 }
183
184 i++;
185 }
186 if ( feedback )
187 {
188 feedback->setProgress( 100 );
189 feedback->pushInfo( QObject::tr( "Writing output file" ) );
190 }
191
192 const QString file = parameterAsString( parameters, QStringLiteral( "OUTPUT" ), context );
193 if ( !style.exportXml( file ) )
194 {
195 throw QgsProcessingException( QObject::tr( "Error saving style database as %1" ).arg( file ) );
196 }
197
198 QVariantMap results;
199 results.insert( QStringLiteral( "OUTPUT" ), file );
200 results.insert( QStringLiteral( "SYMBOLS" ), style.symbolCount() );
201 results.insert( QStringLiteral( "COLORRAMPS" ), style.colorRampCount() );
202 results.insert( QStringLiteral( "TEXTFORMATS" ), style.textFormatCount() );
203 results.insert( QStringLiteral( "LABELSETTINGS" ), style.labelSettingsCount() );
204 return results;
205}
206
208
209
210
211
@ File
Files (i.e. non map layer sources, such as text files)
void setProgress(double progress)
Sets the current progress for the feedback object.
Definition: qgsfeedback.h:61
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Definition: qgsexception.h:83
Base class for providing feedback from a processing algorithm.
virtual void pushInfo(const QString &info)
Pushes a general informational message from the algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
A numeric output for processing algorithms.
An enum based parameter for processing algorithms, allowing for selection from predefined values.
A generic file based destination parameter, for specifying the destination path for a file (non-map l...
A parameter for processing algorithms which accepts multiple map layers.
int colorRampCount()
Returns count of color ramps.
Definition: qgsstyle.cpp:505
QgsTextFormat textFormat(const QString &name) const
Returns the text format with the specified name.
Definition: qgsstyle.cpp:2152
bool tagSymbol(StyleEntity type, const QString &symbol, const QStringList &tags)
Tags the symbol with the tags in the list.
Definition: qgsstyle.cpp:1787
QStringList textFormatNames() const
Returns a list of names of text formats in the style.
Definition: qgsstyle.cpp:2162
bool addColorRamp(const QString &name, QgsColorRamp *colorRamp, bool update=false)
Adds a color ramp to the style.
Definition: qgsstyle.cpp:345
QgsSymbol * symbol(const QString &name)
Returns a NEW copy of symbol.
Definition: qgsstyle.cpp:317
int labelSettingsCount() const
Returns count of label settings in the style.
Definition: qgsstyle.cpp:2221
StyleEntity
Enum for Entities involved in a style.
Definition: qgsstyle.h:179
@ LabelSettingsEntity
Label settings.
Definition: qgsstyle.h:185
@ TextFormatEntity
Text formats.
Definition: qgsstyle.h:184
@ SymbolEntity
Symbols.
Definition: qgsstyle.h:180
@ ColorrampEntity
Color ramps.
Definition: qgsstyle.h:182
QStringList tagsOfSymbol(StyleEntity type, const QString &symbol)
Returns the tags associated with the symbol.
Definition: qgsstyle.cpp:1943
QStringList colorRampNames() const
Returns a list of names of color ramps.
Definition: qgsstyle.cpp:510
int textFormatCount() const
Returns count of text formats in the style.
Definition: qgsstyle.cpp:2157
bool exportXml(const QString &filename)
Exports the style as a XML file.
Definition: qgsstyle.cpp:2567
QgsColorRamp * colorRamp(const QString &name) const
Returns a new copy of the specified color ramp.
Definition: qgsstyle.cpp:494
int symbolCount()
Returns count of symbols in style.
Definition: qgsstyle.cpp:334
bool createMemoryDatabase()
Creates a temporary memory database.
Definition: qgsstyle.cpp:563
QStringList labelSettingsNames() const
Returns a list of names of label settings in the style.
Definition: qgsstyle.cpp:2226
bool addTextFormat(const QString &name, const QgsTextFormat &format, bool update=false)
Adds a text format with the specified name to the style.
Definition: qgsstyle.cpp:369
QgsPalLayerSettings labelSettings(const QString &name) const
Returns the label settings with the specified name.
Definition: qgsstyle.cpp:2172
bool addSymbol(const QString &name, QgsSymbol *symbol, bool update=false)
Adds a symbol to style and takes symbol's ownership.
Definition: qgsstyle.cpp:223
QStringList symbolNames() const
Returns a list of names of symbols.
Definition: qgsstyle.cpp:339
bool importXml(const QString &filename)
Imports the symbols and colorramps into the default style database from the given XML file.
Definition: qgsstyle.cpp:2730
bool addLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool update=false)
Adds label settings with the specified name to the style.
Definition: qgsstyle.cpp:390