QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
22#include <QDomElement>
23#include <QTextStream>
24
25#include "moc_qgsmaplayerstylemanager.cpp"
26
33
34QString QgsMapLayerStyleManager::defaultStyleName()
35{
36 return tr( "default" );
37}
38
39
41{
42 mStyles.insert( defaultStyleName(), QgsMapLayerStyle() ); // insert entry for the default current style
43 mCurrentStyle = defaultStyleName();
44}
45
46void QgsMapLayerStyleManager::readXml( const QDomElement &mgrElement )
47{
48 mCurrentStyle = mgrElement.attribute( QStringLiteral( "current" ) );
49 if ( mCurrentStyle.isEmpty() )
50 {
51 // For old project made with QGIS 2, we migrate to "default".
52 mCurrentStyle = defaultStyleName();
53 }
54
55 mStyles.clear();
56 QDomElement ch = mgrElement.firstChildElement( QStringLiteral( "map-layer-style" ) );
57 while ( !ch.isNull() )
58 {
59 QString name = ch.attribute( QStringLiteral( "name" ) );
60 if ( name.isEmpty() )
61 {
62 // For old project made with QGIS 2, we migrate to "default".
63 name = defaultStyleName();
64 }
66 style.readXml( ch );
67 mStyles.insert( name, style );
68
69 ch = ch.nextSiblingElement( QStringLiteral( "map-layer-style" ) );
70 }
71}
72
73void QgsMapLayerStyleManager::writeXml( QDomElement &mgrElement ) const
74{
75 QDomDocument doc = mgrElement.ownerDocument();
76 mgrElement.setAttribute( QStringLiteral( "current" ), mCurrentStyle );
77
78 const auto constStyles = styles();
79 for ( const QString &name : constStyles )
80 {
81 QDomElement ch = doc.createElement( QStringLiteral( "map-layer-style" ) );
82 ch.setAttribute( QStringLiteral( "name" ), name );
83 mStyles[name].writeXml( ch );
84 mgrElement.appendChild( ch );
85 }
86}
87
89{
90 return mStyles.keys();
91}
92
93QMap<QString, QgsMapLayerStyle> QgsMapLayerStyleManager::mapLayerStyles() const
94{
95 return mStyles;
96}
97
99{
100 if ( name == mCurrentStyle )
101 {
102 // current style's entry is always kept invalid - get the style data from layer's properties
103 QgsMapLayerStyle curr;
104 curr.readFromLayer( mLayer );
105 return curr;
106 }
107
108 return mStyles.value( name );
109}
110
112{
113 if ( mStyles.contains( name ) )
114 return false;
115 if ( !style.isValid() )
116 return false;
117
118 mStyles.insert( name, style );
119 emit styleAdded( name );
120 return true;
121}
122
124{
126 style.readFromLayer( mLayer );
127 return addStyle( name, style );
128}
129
130bool QgsMapLayerStyleManager::removeStyle( const QString &name )
131{
132 if ( !mStyles.contains( name ) )
133 return false;
134 if ( mStyles.count() == 1 )
135 return false; // cannot remove the last one
136
137 // change to a different style if this one is the current
138 if ( mCurrentStyle == name )
139 {
140 QStringList keys = mStyles.keys();
141 QString newCurrent = keys[0];
142 if ( newCurrent == name )
143 newCurrent = keys[1]; // there must be at least one more
144 setCurrentStyle( newCurrent );
145 }
146
147 mStyles.remove( name );
148 emit styleRemoved( name );
149 return true;
150}
151
152bool QgsMapLayerStyleManager::renameStyle( const QString &name, const QString &newName )
153{
154 if ( !mStyles.contains( name ) || mStyles.contains( newName ) )
155 return false;
156
157 if ( name == mCurrentStyle )
158 mCurrentStyle = newName;
159
160 mStyles[newName] = mStyles[name];
161 mStyles.remove( name );
162 emit styleRenamed( name, newName );
163 return true;
164}
165
167{
168 return mCurrentStyle;
169}
170
172{
173 if ( !mStyles.contains( name ) )
174 return false;
175
176 if ( mCurrentStyle == name )
177 return true; // nothing to do
178
179 mStyles[mCurrentStyle].readFromLayer( mLayer ); // sync before unloading it
180 mCurrentStyle = name;
181 mStyles[mCurrentStyle].writeToLayer( mLayer );
182 mStyles[mCurrentStyle].clear(); // current style does not keep any stored data
183 emit currentStyleChanged( mCurrentStyle );
184
185 mLayer->triggerRepaint();
186 return true;
187}
188
189bool QgsMapLayerStyleManager::setOverrideStyle( const QString &styleDef )
190{
191 if ( mOverriddenOriginalStyle )
192 return false; // cannot override the style more than once!
193
194 mLayer->blockSignals( true );
195 if ( mStyles.contains( styleDef ) )
196 {
197 mOverriddenOriginalStyle = new QgsMapLayerStyle;
198 mOverriddenOriginalStyle->readFromLayer( mLayer );
199
200 // apply style name
201 mStyles[styleDef].writeToLayer( mLayer );
202 }
203 else if ( styleDef.startsWith( '<' ) )
204 {
205 mOverriddenOriginalStyle = new QgsMapLayerStyle;
206 mOverriddenOriginalStyle->readFromLayer( mLayer );
207
208 // apply style XML
209 const QgsMapLayerStyle overrideStyle( styleDef );
210 overrideStyle.writeToLayer( mLayer );
211 }
212 mLayer->blockSignals( false );
213
214 return true;
215}
216
218{
219 if ( !mOverriddenOriginalStyle )
220 return false;
221
222 mLayer->blockSignals( true );
223 mOverriddenOriginalStyle->writeToLayer( mLayer );
224 mLayer->blockSignals( false );
225
226 delete mOverriddenOriginalStyle;
227 mOverriddenOriginalStyle = nullptr;
228 return true;
229}
230
231bool QgsMapLayerStyleManager::isDefault( const QString &styleName )
232{
233 return styleName == defaultStyleName();
234}
235
237{
238 const QStringList styleNames = other->mStyles.keys();
239
240 for ( const QString &styleName : styleNames )
241 {
242 mStyles.remove( styleName );
243 addStyle( styleName, other->style( styleName ) );
244 }
245}
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:80