QGIS API Documentation 4.3.0-Master (0cfde48c85b)
Loading...
Searching...
No Matches
qgsmaplayerstylemanager.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmaplayerstylemanager.cpp
3 --------------------------------------
4 Date : January 2015
5 Copyright : (C) 2015 by Martin Dobias
6 Email : wonder dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgslogger.h"
19#include "qgsmaplayer.h"
20#include "qgsmaplayerstyle.h"
21#include "qgsthreadingutils.h"
22
23#include <QDomElement>
24#include <QString>
25#include <QTextStream>
26
27#include "moc_qgsmaplayerstylemanager.cpp"
28
29using namespace Qt::StringLiterals;
30
37
38QString QgsMapLayerStyleManager::defaultStyleName()
39{
40 return tr( "default" );
41}
42
43
45{
47
48 mStyles.insert( defaultStyleName(), QgsMapLayerStyle() ); // insert entry for the default current style
49 mCurrentStyle = defaultStyleName();
50}
51
52void QgsMapLayerStyleManager::readXml( const QDomElement &mgrElement )
53{
55
56 mCurrentStyle = mgrElement.attribute( u"current"_s );
57 if ( mCurrentStyle.isEmpty() )
58 {
59 // For old project made with QGIS 2, we migrate to "default".
60 mCurrentStyle = defaultStyleName();
61 }
62
63 mStyles.clear();
64 QDomElement ch = mgrElement.firstChildElement( u"map-layer-style"_s );
65 while ( !ch.isNull() )
66 {
67 QString name = ch.attribute( u"name"_s );
68 if ( name.isEmpty() )
69 {
70 // For old project made with QGIS 2, we migrate to "default".
71 name = defaultStyleName();
72 }
74 style.readXml( ch );
75 mStyles.insert( name, style );
76
77 ch = ch.nextSiblingElement( u"map-layer-style"_s );
78 }
79}
80
81void QgsMapLayerStyleManager::writeXml( QDomElement &mgrElement ) const
82{
84
85 QDomDocument doc = mgrElement.ownerDocument();
86 mgrElement.setAttribute( u"current"_s, mCurrentStyle );
87
88 const auto constStyles = styles();
89 for ( const QString &name : constStyles )
90 {
91 QDomElement ch = doc.createElement( u"map-layer-style"_s );
92 ch.setAttribute( u"name"_s, name );
93 mStyles[name].writeXml( ch );
94 mgrElement.appendChild( ch );
95 }
96}
97
99{
101
102 return mStyles.keys();
103}
104
105QMap<QString, QgsMapLayerStyle> QgsMapLayerStyleManager::mapLayerStyles() const
106{
108
109 return mStyles;
110}
111
113{
115
116 if ( name == mCurrentStyle )
117 {
118 // current style's entry is always kept invalid - get the style data from layer's properties
119 QgsMapLayerStyle curr;
120 curr.readFromLayer( mLayer );
121 return curr;
122 }
123
124 return mStyles.value( name );
125}
126
128{
130
131 if ( mStyles.contains( name ) )
132 return false;
133 if ( !style.isValid() )
134 return false;
135
136 mStyles.insert( name, style );
137 emit styleAdded( name );
138 return true;
139}
140
142{
144
146 style.readFromLayer( mLayer );
147 return addStyle( name, style );
148}
149
150bool QgsMapLayerStyleManager::removeStyle( const QString &name )
151{
153
154 if ( !mStyles.contains( name ) )
155 return false;
156 if ( mStyles.count() == 1 )
157 return false; // cannot remove the last one
158
159 // change to a different style if this one is the current
160 if ( mCurrentStyle == name )
161 {
162 QStringList keys = mStyles.keys();
163 QString newCurrent = keys[0];
164 if ( newCurrent == name )
165 newCurrent = keys[1]; // there must be at least one more
166 setCurrentStyle( newCurrent );
167 }
168
169 mStyles.remove( name );
170 emit styleRemoved( name );
171 return true;
172}
173
174bool QgsMapLayerStyleManager::renameStyle( const QString &name, const QString &newName )
175{
177
178 if ( !mStyles.contains( name ) || mStyles.contains( newName ) )
179 return false;
180
181 if ( name == mCurrentStyle )
182 mCurrentStyle = newName;
183
184 mStyles[newName] = mStyles[name];
185 mStyles.remove( name );
186 emit styleRenamed( name, newName );
187 return true;
188}
189
191{
193
194 return mCurrentStyle;
195}
196
198{
200
201 if ( !mStyles.contains( name ) )
202 return false;
203
204 if ( mCurrentStyle == name )
205 return true; // nothing to do
206
207 mStyles[mCurrentStyle].readFromLayer( mLayer ); // sync before unloading it
208 mCurrentStyle = name;
209 mStyles[mCurrentStyle].writeToLayer( mLayer );
210 mStyles[mCurrentStyle].clear(); // current style does not keep any stored data
211 emit currentStyleChanged( mCurrentStyle );
212
213 mLayer->triggerRepaint();
214 return true;
215}
216
217bool QgsMapLayerStyleManager::setOverrideStyle( const QString &styleDef )
218{
220
221 if ( mOverriddenOriginalStyle )
222 return false; // cannot override the style more than once!
223
224 mLayer->blockSignals( true );
225 if ( mStyles.contains( styleDef ) )
226 {
227 mOverriddenOriginalStyle = new QgsMapLayerStyle;
228 mOverriddenOriginalStyle->readFromLayer( mLayer );
229
230 // apply style name
231 mStyles[styleDef].writeToLayer( mLayer );
232 }
233 else if ( styleDef.startsWith( '<' ) )
234 {
235 mOverriddenOriginalStyle = new QgsMapLayerStyle;
236 mOverriddenOriginalStyle->readFromLayer( mLayer );
237
238 // apply style XML
239 const QgsMapLayerStyle overrideStyle( styleDef );
240 overrideStyle.writeToLayer( mLayer );
241 }
242 mLayer->blockSignals( false );
243
244 return true;
245}
246
248{
250
251 if ( !mOverriddenOriginalStyle )
252 return false;
253
254 mLayer->blockSignals( true );
255 mOverriddenOriginalStyle->writeToLayer( mLayer );
256 mLayer->blockSignals( false );
257
258 delete mOverriddenOriginalStyle;
259 mOverriddenOriginalStyle = nullptr;
260 return true;
261}
262
263bool QgsMapLayerStyleManager::isDefault( const QString &styleName )
264{
265 return styleName == defaultStyleName();
266}
267
269{
271
272 const QStringList styleNames = other->mStyles.keys();
273
274 for ( const QString &styleName : styleNames )
275 {
276 mStyles.remove( styleName );
277 addStyle( styleName, other->style( styleName ) );
278 }
279}
bool addStyle(const QString &name, const QgsMapLayerStyle &style)
Add a style with given name and data.
QString currentStyle() const
Returns name of the current style.
bool removeStyle(const QString &name)
Remove a stored style.
void copyStylesFrom(QgsMapLayerStyleManager *other)
Copies all styles from other.
QStringList styles() const
Returns list of all defined style names.
bool setCurrentStyle(const QString &name)
Set a different style as the current style - will apply it to the layer.
static bool isDefault(const QString &styleName)
Returns true if this is the default style.
void styleAdded(const QString &name)
Emitted when a new style has been added.
void writeXml(QDomElement &mgrElement) const
Write configuration (for project saving).
void reset()
Reset the style manager to a basic state - with one default style which is set as current.
void styleRenamed(const QString &oldName, const QString &newName)
Emitted when a style has been renamed.
bool restoreOverrideStyle()
Restore the original store after a call to setOverrideStyle().
QgsMapLayer * layer() const
Gets pointer to the associated map layer.
bool addStyleFromLayer(const QString &name)
Add style by cloning the current one.
bool renameStyle(const QString &name, const QString &newName)
Rename a stored style to a different name.
QgsMapLayerStyleManager(QgsMapLayer *layer)
Construct a style manager associated with a map layer (must not be nullptr).
QMap< QString, QgsMapLayerStyle > mapLayerStyles() const
Gets available styles for the associated map layer.
bool setOverrideStyle(const QString &styleDef)
Temporarily apply a different style to the layer.
QgsMapLayerStyle style(const QString &name) const
Returns data of a stored style - accessed by its unique name.
void readXml(const QDomElement &mgrElement)
Read configuration (for project loading).
void currentStyleChanged(const QString &currentName)
Emitted when the current style has been changed.
void styleRemoved(const QString &name)
Emitted when a style has been removed.
Stores style information (renderer, opacity, labeling, diagrams etc.) applicable to a map layer.
void readFromLayer(QgsMapLayer *layer)
Store layer's active style information in the instance.
void writeToLayer(QgsMapLayer *layer) const
Apply stored layer's style information to the layer.
Base class for all map layer types.
Definition qgsmaplayer.h:83
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS