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