Branch data Line data Source code
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 : :
21 : : ///@cond PRIVATE
22 : :
23 : 0 : QgsCombineStylesAlgorithm::QgsCombineStylesAlgorithm() = default;
24 : :
25 : 0 : QgsCombineStylesAlgorithm::~QgsCombineStylesAlgorithm() = default;
26 : :
27 : 0 : void QgsCombineStylesAlgorithm::initAlgorithm( const QVariantMap & )
28 : : {
29 : 0 : addParameter( new QgsProcessingParameterMultipleLayers( QStringLiteral( "INPUT" ), QObject::tr( "Input databases" ), QgsProcessing::TypeFile ) );
30 : :
31 : 0 : addParameter( new QgsProcessingParameterFileDestination( QStringLiteral( "OUTPUT" ), QObject::tr( "Output style database" ),
32 : 0 : QObject::tr( "Style files (*.xml)" ) ) );
33 : :
34 : 0 : QStringList options = QStringList()
35 : 0 : << QObject::tr( "Symbols" )
36 : 0 : << QObject::tr( "Color ramps" )
37 : 0 : << QObject::tr( "Text formats" )
38 : 0 : << QObject::tr( "Label settings" );
39 : 0 : addParameter( new QgsProcessingParameterEnum( QStringLiteral( "OBJECTS" ), QObject::tr( "Objects to combine" ), options, true, QVariantList() << 0 << 1 << 2 << 3 ) );
40 : 0 : addOutput( new QgsProcessingOutputNumber( QStringLiteral( "SYMBOLS" ), QObject::tr( "Symbol count" ) ) );
41 : 0 : addOutput( new QgsProcessingOutputNumber( QStringLiteral( "COLORRAMPS" ), QObject::tr( "Color ramp count" ) ) );
42 : 0 : addOutput( new QgsProcessingOutputNumber( QStringLiteral( "TEXTFORMATS" ), QObject::tr( "Text format count" ) ) );
43 : 0 : addOutput( new QgsProcessingOutputNumber( QStringLiteral( "LABELSETTINGS" ), QObject::tr( "Label settings count" ) ) );
44 : 0 : }
45 : :
46 : 0 : QString QgsCombineStylesAlgorithm::name() const
47 : : {
48 : 0 : return QStringLiteral( "combinestyles" );
49 : : }
50 : :
51 : 0 : QString QgsCombineStylesAlgorithm::displayName() const
52 : : {
53 : 0 : return QObject::tr( "Combine style databases" );
54 : : }
55 : :
56 : 0 : QStringList QgsCombineStylesAlgorithm::tags() const
57 : : {
58 : 0 : return QObject::tr( "symbols,colors,ramps,formats,labels,text,fonts,merge" ).split( ',' );
59 : 0 : }
60 : :
61 : 0 : QString QgsCombineStylesAlgorithm::group() const
62 : : {
63 : 0 : return QObject::tr( "Cartography" );
64 : : }
65 : :
66 : 0 : QString QgsCombineStylesAlgorithm::groupId() const
67 : : {
68 : 0 : return QStringLiteral( "cartography" );
69 : : }
70 : :
71 : 0 : QString QgsCombineStylesAlgorithm::shortHelpString() const
72 : : {
73 : 0 : 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 : :
77 : 0 : QString QgsCombineStylesAlgorithm::shortDescription() const
78 : : {
79 : 0 : return QObject::tr( "Combines multiple style databases into a single database." );
80 : : }
81 : :
82 : 0 : QgsCombineStylesAlgorithm *QgsCombineStylesAlgorithm::createInstance() const
83 : : {
84 : 0 : return new QgsCombineStylesAlgorithm();
85 : 0 : }
86 : :
87 : 0 : QVariantMap QgsCombineStylesAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
88 : : {
89 : 0 : const QStringList inputs = parameterAsFileList( parameters, QStringLiteral( "INPUT" ), context );
90 : :
91 : 0 : QList< QgsStyle::StyleEntity > objects;
92 : 0 : const QList< int > selectedObjects = parameterAsEnums( parameters, QStringLiteral( "OBJECTS" ), context );
93 : 0 : if ( selectedObjects.contains( 0 ) )
94 : 0 : objects << QgsStyle::SymbolEntity;
95 : 0 : if ( selectedObjects.contains( 1 ) )
96 : 0 : objects << QgsStyle::ColorrampEntity;
97 : 0 : if ( selectedObjects.contains( 2 ) )
98 : 0 : objects << QgsStyle::TextFormatEntity;
99 : 0 : if ( selectedObjects.contains( 3 ) )
100 : 0 : objects << QgsStyle::LabelSettingsEntity;
101 : :
102 : 0 : QgsStyle style;
103 : 0 : style.createMemoryDatabase();
104 : :
105 : 0 : int i = 0;
106 : 0 : QMap< QgsStyle::StyleEntity, QSet< QString> > usedNames;
107 : 0 : auto makeUniqueName = [&usedNames]( const QString & sourceName, QgsStyle::StyleEntity type )->QString
108 : : {
109 : 0 : QString candidate = sourceName;
110 : 0 : int i = 1;
111 : 0 : bool exists = true;
112 : 0 : while ( exists )
113 : : {
114 : 0 : exists = usedNames[ type ].contains( candidate );
115 : 0 : if ( !exists )
116 : 0 : break;
117 : :
118 : 0 : i++;
119 : 0 : candidate = sourceName + QStringLiteral( " (%1)" ).arg( i );
120 : : }
121 : :
122 : 0 : usedNames[ type ].insert( candidate );
123 : 0 : return candidate;
124 : 0 : };
125 : :
126 : 0 : for ( const QString &source : inputs )
127 : : {
128 : 0 : if ( feedback )
129 : : {
130 : 0 : feedback->setProgress( 100 * i / static_cast< double >( inputs.count() ) );
131 : 0 : feedback->pushInfo( QObject::tr( "Importing %1" ).arg( source ) );
132 : 0 : }
133 : :
134 : 0 : QgsStyle sourceStyle;
135 : 0 : sourceStyle.createMemoryDatabase();
136 : 0 : if ( !sourceStyle.importXml( source ) )
137 : : {
138 : 0 : feedback->reportError( QObject::tr( "Could not read %1" ).arg( source ) );
139 : 0 : i++;
140 : 0 : continue;
141 : : }
142 : :
143 : 0 : if ( objects.contains( QgsStyle::SymbolEntity ) )
144 : : {
145 : 0 : const QStringList symbolNames = sourceStyle.symbolNames();
146 : 0 : for ( const QString &name : symbolNames )
147 : : {
148 : 0 : const QString newName = makeUniqueName( name, QgsStyle::SymbolEntity );
149 : 0 : style.addSymbol( newName, sourceStyle.symbol( name ), true );
150 : 0 : style.tagSymbol( QgsStyle::SymbolEntity, newName, sourceStyle.tagsOfSymbol( QgsStyle::SymbolEntity, name ) );
151 : 0 : }
152 : 0 : }
153 : 0 : if ( objects.contains( QgsStyle::ColorrampEntity ) )
154 : : {
155 : 0 : const QStringList colorRampNames = sourceStyle.colorRampNames();
156 : 0 : for ( const QString &name : colorRampNames )
157 : : {
158 : 0 : const QString newName = makeUniqueName( name, QgsStyle::ColorrampEntity );
159 : 0 : style.addColorRamp( newName, sourceStyle.colorRamp( name ), true );
160 : 0 : style.tagSymbol( QgsStyle::ColorrampEntity, newName, sourceStyle.tagsOfSymbol( QgsStyle::ColorrampEntity, name ) );
161 : 0 : }
162 : 0 : }
163 : 0 : if ( objects.contains( QgsStyle::TextFormatEntity ) )
164 : : {
165 : 0 : const QStringList formatNames = sourceStyle.textFormatNames();
166 : 0 : for ( const QString &name : formatNames )
167 : : {
168 : 0 : const QString newName = makeUniqueName( name, QgsStyle::TextFormatEntity );
169 : 0 : style.addTextFormat( newName, sourceStyle.textFormat( name ), true );
170 : 0 : style.tagSymbol( QgsStyle::TextFormatEntity, newName, sourceStyle.tagsOfSymbol( QgsStyle::TextFormatEntity, name ) );
171 : 0 : }
172 : 0 : }
173 : 0 : if ( objects.contains( QgsStyle::LabelSettingsEntity ) )
174 : : {
175 : 0 : const QStringList formatNames = sourceStyle.labelSettingsNames();
176 : 0 : for ( const QString &name : formatNames )
177 : : {
178 : 0 : const QString newName = makeUniqueName( name, QgsStyle::LabelSettingsEntity );
179 : 0 : style.addLabelSettings( newName, sourceStyle.labelSettings( name ), true );
180 : 0 : style.tagSymbol( QgsStyle::LabelSettingsEntity, newName, sourceStyle.tagsOfSymbol( QgsStyle::LabelSettingsEntity, name ) );
181 : 0 : }
182 : 0 : }
183 : :
184 : 0 : i++;
185 : 0 : }
186 : 0 : if ( feedback )
187 : : {
188 : 0 : feedback->setProgress( 100 );
189 : 0 : feedback->pushInfo( QObject::tr( "Writing output file" ) );
190 : 0 : }
191 : :
192 : 0 : const QString file = parameterAsString( parameters, QStringLiteral( "OUTPUT" ), context );
193 : 0 : if ( !style.exportXml( file ) )
194 : : {
195 : 0 : throw QgsProcessingException( QObject::tr( "Error saving style database as %1" ).arg( file ) );
196 : : }
197 : :
198 : 0 : QVariantMap results;
199 : 0 : results.insert( QStringLiteral( "OUTPUT" ), file );
200 : 0 : results.insert( QStringLiteral( "SYMBOLS" ), style.symbolCount() );
201 : 0 : results.insert( QStringLiteral( "COLORRAMPS" ), style.colorRampCount() );
202 : 0 : results.insert( QStringLiteral( "TEXTFORMATS" ), style.textFormatCount() );
203 : 0 : results.insert( QStringLiteral( "LABELSETTINGS" ), style.labelSettingsCount() );
204 : 0 : return results;
205 : 0 : }
206 : :
207 : : ///@endcond
208 : :
209 : :
210 : :
211 : :
|