Skip to content

Commit 8b5587f

Browse files
committed
Improve the internals of map layer style manager
- style manager is always enabled (client code does not need to distinguish between enabled/disabled state) - layers currently active style is stored only in QgsMapLayer - in style manager it has entry with no data (avoids duplication of data) This also solves issues with visibility presets and styles when some presets do not have stored style
1 parent 7c4f3f9 commit 8b5587f

9 files changed

+49
-94
lines changed

python/core/qgsmaplayer.sip

-9
Original file line numberDiff line numberDiff line change
@@ -370,17 +370,8 @@ class QgsMapLayer : QObject
370370
*/
371371
QgsMapLayerLegend* legend() const;
372372

373-
/**
374-
* Enable or disable layer's style manager. When disabled (default), the styleManager() will return null pointer.
375-
* By enabling the style manager will be created with one default style (same as the layer's active style).
376-
* By disabling the style manager all associated styles will be lost (only the layer's active style will stay).
377-
* @note added in 2.8
378-
*/
379-
void enableStyleManager( bool enable = true );
380-
381373
/**
382374
* Get access to the layer's style manager. Style manager allows switching between multiple styles.
383-
* If the style manager is not enabled, null pointer will be returned.
384375
* @note added in 2.8
385376
*/
386377
QgsMapLayerStyleManager* styleManager() const;

python/core/qgsmaplayerstylemanager.sip

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ class QgsMapLayerStyle
1111
//! Tell whether the style is valid (i.e. there is something stored in it)
1212
bool isValid() const;
1313

14+
//! Remove any stored style data (will get invalid)
15+
void clear();
16+
1417
//! Return information about the style - for debugging purposes only
1518
QString dump() const;
1619

@@ -35,6 +38,9 @@ class QgsMapLayerStyleManager
3538
//! Construct a style manager associated with a map layer (must not be null)
3639
QgsMapLayerStyleManager( QgsMapLayer* layer );
3740

41+
//! Reset the style manager to a basic state - with one default style which is set as current
42+
void reset();
43+
3844
//! Read configuration (for project loading)
3945
void readXml( const QDomElement& mgrElement );
4046
//! Write configuration (for project saving)

src/app/qgsmaplayerstyleguiutils.cpp

-9
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ QMenu* QgsMapLayerStyleGuiUtils::createStyleManagerMenu( QgsMapLayer* layer )
3333

3434
QgsMapLayerStyleManager* mgr = layer->styleManager();
3535

36-
if ( !mgr )
37-
return m;
38-
3936
QMenu* mRemove = m->addMenu( tr( "Remove" ) );
4037
m->addSeparator();
4138

@@ -78,8 +75,6 @@ void QgsMapLayerStyleGuiUtils::addStyle()
7875
if ( !ok || text.isEmpty() )
7976
return;
8077

81-
layer->enableStyleManager(); // make sure it exists
82-
8378
bool res = layer->styleManager()->addStyleFromLayer( text );
8479

8580
if ( res ) // make it active!
@@ -116,11 +111,7 @@ void QgsMapLayerStyleGuiUtils::removeStyle()
116111
return;
117112

118113
if ( layer->styleManager()->styles().count() == 1 )
119-
{
120-
// let's get rid of the style manager altogether
121-
layer->enableStyleManager( false );
122114
return;
123-
}
124115

125116
QString name = a->text();
126117
if ( name == defaultStyleName() )

src/app/qgsvisibilitypresets.cpp

+4-9
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,7 @@ void QgsVisibilityPresets::addPerLayerCurrentStyle( QgsVisibilityPresets::Preset
115115
if ( !nodeLayer )
116116
continue;
117117

118-
if ( nodeLayer->layer()->styleManager() )
119-
rec.mPerLayerCurrentStyle[layerID] = nodeLayer->layer()->styleManager()->currentStyle();
118+
rec.mPerLayerCurrentStyle[layerID] = nodeLayer->layer()->styleManager()->currentStyle();
120119
}
121120
}
122121

@@ -209,8 +208,7 @@ void QgsVisibilityPresets::applyPresetCheckedLegendNodesToLayer( const QString&
209208
if ( rec.mPerLayerCurrentStyle.contains( layerID ) )
210209
{
211210
// apply desired style first
212-
if ( layer->styleManager() )
213-
layer->styleManager()->setCurrentStyle( rec.mPerLayerCurrentStyle[layerID] );
211+
layer->styleManager()->setCurrentStyle( rec.mPerLayerCurrentStyle[layerID] );
214212
}
215213

216214
QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer*>( layer );
@@ -275,8 +273,7 @@ void QgsVisibilityPresets::applyStateToLayerTreeGroup( QgsLayerTreeGroup* parent
275273
if ( rec.mPerLayerCurrentStyle.contains( nodeLayer->layerId() ) )
276274
{
277275
// apply desired style first
278-
if ( nodeLayer->layer()->styleManager() )
279-
nodeLayer->layer()->styleManager()->setCurrentStyle( rec.mPerLayerCurrentStyle[nodeLayer->layerId()] );
276+
nodeLayer->layer()->styleManager()->setCurrentStyle( rec.mPerLayerCurrentStyle[nodeLayer->layerId()] );
280277
}
281278

282279
QgsLayerTreeModel* model = QgisApp::instance()->layerTreeView()->layerTreeModel();
@@ -359,9 +356,7 @@ void QgsVisibilityPresets::applyState( const QString& presetName )
359356
continue;
360357

361358
QString name = rec.mPerLayerCurrentStyle[layerID];
362-
if ( !ml->styleManager() )
363-
rec.mPerLayerCurrentStyle.remove( layerID );
364-
else if ( !ml->styleManager()->styles().contains( name ) )
359+
if ( !ml->styleManager()->styles().contains( name ) )
365360
rec.mPerLayerCurrentStyle[layerID] = ml->styleManager()->currentStyle();
366361
}
367362
}

src/core/qgsmaplayer.cpp

+4-22
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ QgsMapLayer::QgsMapLayer( QgsMapLayer::LayerType type,
5656
mLayerType( type ),
5757
mBlendMode( QPainter::CompositionMode_SourceOver ) // Default to normal blending
5858
, mLegend( 0 )
59-
, mStyleManager( 0 )
59+
, mStyleManager( new QgsMapLayerStyleManager( this ) )
6060
{
6161
mCRS = new QgsCoordinateReferenceSystem();
6262

@@ -86,6 +86,7 @@ QgsMapLayer::~QgsMapLayer()
8686
{
8787
delete mCRS;
8888
delete mLegend;
89+
delete mStyleManager;
8990
}
9091

9192
QgsMapLayer::LayerType QgsMapLayer::type() const
@@ -708,12 +709,9 @@ void QgsMapLayer::readStyleManager( const QDomNode& layerNode )
708709
{
709710
QDomElement styleMgrElem = layerNode.firstChildElement( "map-layer-style-manager" );
710711
if ( !styleMgrElem.isNull() )
711-
{
712-
enableStyleManager();
713-
styleManager()->readXml( styleMgrElem );
714-
}
712+
mStyleManager->readXml( styleMgrElem );
715713
else
716-
enableStyleManager( false );
714+
mStyleManager->reset();
717715
}
718716

719717
void QgsMapLayer::writeStyleManager( QDomNode& layerNode, QDomDocument& doc ) const
@@ -1448,22 +1446,6 @@ QgsMapLayerLegend*QgsMapLayer::legend() const
14481446
return mLegend;
14491447
}
14501448

1451-
void QgsMapLayer::enableStyleManager( bool enable )
1452-
{
1453-
if (( enable && mStyleManager ) || ( !enable && !mStyleManager ) )
1454-
return;
1455-
1456-
if ( enable )
1457-
{
1458-
mStyleManager = new QgsMapLayerStyleManager( this );
1459-
}
1460-
else
1461-
{
1462-
delete mStyleManager;
1463-
mStyleManager = 0;
1464-
}
1465-
}
1466-
14671449
QgsMapLayerStyleManager* QgsMapLayer::styleManager() const
14681450
{
14691451
return mStyleManager;

src/core/qgsmaplayer.h

-9
Original file line numberDiff line numberDiff line change
@@ -388,17 +388,8 @@ class CORE_EXPORT QgsMapLayer : public QObject
388388
*/
389389
QgsMapLayerLegend* legend() const;
390390

391-
/**
392-
* Enable or disable layer's style manager. When disabled (default), the styleManager() will return null pointer.
393-
* By enabling the style manager will be created with one default style (same as the layer's active style).
394-
* By disabling the style manager all associated styles will be lost (only the layer's active style will stay).
395-
* @note added in 2.8
396-
*/
397-
void enableStyleManager( bool enable = true );
398-
399391
/**
400392
* Get access to the layer's style manager. Style manager allows switching between multiple styles.
401-
* If the style manager is not enabled, null pointer will be returned.
402393
* @note added in 2.8
403394
*/
404395
QgsMapLayerStyleManager* styleManager() const;

src/core/qgsmaplayerstylemanager.cpp

+25-12
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@
2525
QgsMapLayerStyleManager::QgsMapLayerStyleManager( QgsMapLayer* layer )
2626
: mLayer( layer )
2727
{
28-
QgsMapLayerStyle defaultStyle;
29-
defaultStyle.readFromLayer( mLayer );
30-
mStyles.insert( QString(), defaultStyle );
28+
reset();
29+
}
30+
31+
void QgsMapLayerStyleManager::reset()
32+
{
33+
mStyles.insert( QString(), QgsMapLayerStyle() ); // insert entry for the default current style
34+
mCurrentStyle.clear();
3135
}
3236

3337
void QgsMapLayerStyleManager::readXml( const QDomElement& mgrElement )
@@ -49,8 +53,6 @@ void QgsMapLayerStyleManager::readXml( const QDomElement& mgrElement )
4953

5054
void QgsMapLayerStyleManager::writeXml( QDomElement& mgrElement ) const
5155
{
52-
const_cast<QgsMapLayerStyleManager*>( this )->syncCurrentStyle();
53-
5456
QDomDocument doc = mgrElement.ownerDocument();
5557
mgrElement.setAttribute( "current", mCurrentStyle );
5658

@@ -70,8 +72,13 @@ QStringList QgsMapLayerStyleManager::styles() const
7072

7173
QgsMapLayerStyle QgsMapLayerStyleManager::style( const QString& name ) const
7274
{
73-
if ( name == mCurrentStyle ) // make sure it is sync'ed
74-
const_cast<QgsMapLayerStyleManager*>( this )->syncCurrentStyle();
75+
if ( name == mCurrentStyle )
76+
{
77+
// current style's entry is always kept invalid - get the style data from layer's properties
78+
QgsMapLayerStyle curr;
79+
curr.readFromLayer( mLayer );
80+
return curr;
81+
}
7582

7683
return mStyles.value( name );
7784
}
@@ -128,17 +135,14 @@ bool QgsMapLayerStyleManager::setCurrentStyle( const QString& name )
128135
if ( mCurrentStyle == name )
129136
return true; // nothing to do
130137

131-
syncCurrentStyle(); // sync before unloading it
138+
mStyles[mCurrentStyle].readFromLayer( mLayer ); // sync before unloading it
132139
mCurrentStyle = name;
133140
mStyles[mCurrentStyle].writeToLayer( mLayer );
141+
mStyles[mCurrentStyle].clear(); // current style does not keep any stored data
134142
mLayer->triggerRepaint();
135143
return true;
136144
}
137145

138-
void QgsMapLayerStyleManager::syncCurrentStyle()
139-
{
140-
mStyles[mCurrentStyle].readFromLayer( mLayer );
141-
}
142146

143147
// -----
144148

@@ -151,6 +155,11 @@ bool QgsMapLayerStyle::isValid() const
151155
return !mXmlData.isEmpty();
152156
}
153157

158+
void QgsMapLayerStyle::clear()
159+
{
160+
mXmlData.clear();
161+
}
162+
154163
QString QgsMapLayerStyle::dump() const
155164
{
156165
return mXmlData;
@@ -195,6 +204,10 @@ void QgsMapLayerStyle::readXml( const QDomElement& styleElement )
195204

196205
void QgsMapLayerStyle::writeXml( QDomElement& styleElement ) const
197206
{
207+
// the currently selected style has no content stored here (layer has all the information inside)
208+
if ( !isValid() )
209+
return;
210+
198211
QDomDocument docX;
199212
docX.setContent( mXmlData );
200213
styleElement.appendChild( docX.documentElement() );

src/core/qgsmaplayerstylemanager.h

+10-7
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ class CORE_EXPORT QgsMapLayerStyle
4242
//! Tell whether the style is valid (i.e. there is something stored in it)
4343
bool isValid() const;
4444

45+
//! Remove any stored style data (will get invalid)
46+
void clear();
47+
4548
//! Return information about the style - for debugging purposes only
4649
QString dump() const;
4750

@@ -70,10 +73,11 @@ class CORE_EXPORT QgsMapLayerStyle
7073
* record them in the currently active style without any extra effort required.
7174
*
7275
* When an instance is created, it creates "default" style (with empty name) recorded from the associated map layer
73-
* and it is set as the current style.
76+
* and it is set as the current style. The instance must always contain at least one style (which is the current).
7477
*
75-
* The instance must always contain at least one style. If no extra styles are wanted, the style manager should get
76-
* disabled in QgsMapLayer instance.
78+
* The style which is marked as current has no style data stored in its entry. This is to avoid duplication
79+
* of data as all data is stored in map layer and can be retrieved easily. Also when saving, the entry for
80+
* the current style will be saved with no data because everything is already saved by the map layer itself.
7781
*
7882
* @note added in 2.8
7983
*/
@@ -83,6 +87,9 @@ class CORE_EXPORT QgsMapLayerStyleManager
8387
//! Construct a style manager associated with a map layer (must not be null)
8488
QgsMapLayerStyleManager( QgsMapLayer* layer );
8589

90+
//! Reset the style manager to a basic state - with one default style which is set as current
91+
void reset();
92+
8693
//! Read configuration (for project loading)
8794
void readXml( const QDomElement& mgrElement );
8895
//! Write configuration (for project saving)
@@ -109,10 +116,6 @@ class CORE_EXPORT QgsMapLayerStyleManager
109116
//! @return true on success
110117
bool setCurrentStyle( const QString& name );
111118

112-
private:
113-
void syncCurrentStyle();
114-
void ensureCurrentInSync() const;
115-
116119
private:
117120
QgsMapLayer* mLayer;
118121
QMap<QString, QgsMapLayerStyle> mStyles;

tests/src/core/testqgsmaplayerstylemanager.cpp

-17
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ class TestQgsMapLayerStyleManager : public QObject
1818
void init();// will be called before each testfunction is executed.
1919
void cleanup();// will be called after every testfunction.
2020

21-
void testEnabled();
2221
void testDefault();
2322
void testStyle();
2423
void testReadWrite();
@@ -50,23 +49,8 @@ void TestQgsMapLayerStyleManager::cleanup()
5049
QgsMapLayerRegistry::instance()->removeAllMapLayers();
5150
}
5251

53-
void TestQgsMapLayerStyleManager::testEnabled()
54-
{
55-
QVERIFY( !mVL->styleManager() );
56-
57-
mVL->enableStyleManager( false );
58-
QVERIFY( !mVL->styleManager() );
59-
60-
mVL->enableStyleManager();
61-
QVERIFY( mVL->styleManager() );
62-
63-
mVL->enableStyleManager( false );
64-
QVERIFY( !mVL->styleManager() );
65-
}
66-
6752
void TestQgsMapLayerStyleManager::testDefault()
6853
{
69-
mVL->enableStyleManager();
7054
QgsMapLayerStyleManager* mgr = mVL->styleManager();
7155
QVERIFY( mgr );
7256

@@ -168,7 +152,6 @@ void TestQgsMapLayerStyleManager::testSwitchingStyles()
168152
{
169153
_setVLColor( mVL, Qt::red );
170154

171-
mVL->enableStyleManager();
172155
mVL->styleManager()->addStyleFromLayer( "s1" );
173156
mVL->styleManager()->setCurrentStyle( "s1" );
174157

0 commit comments

Comments
 (0)