Skip to content

Commit 829f99b

Browse files
committedJan 7, 2015
Initial core work on multiple styles per layer
1 parent b905f6b commit 829f99b

9 files changed

+546
-0
lines changed
 

‎src/app/qgsapplayertreeviewmenuprovider.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ QMenu* QgsAppLayerTreeViewMenuProvider::createContextMenu()
6161
{
6262
QgsMapLayer* layer = QgsLayerTree::toLayer( node )->layer();
6363

64+
addStyleManagerStuff( menu, layer );
65+
6466
menu->addAction( actions->actionZoomToLayer( mCanvas, menu ) );
6567
menu->addAction( actions->actionShowInOverview( menu ) );
6668

@@ -319,3 +321,91 @@ void QgsAppLayerTreeViewMenuProvider::addCustomLayerActions( QMenu* menu, QgsMap
319321
menu->addSeparator();
320322
}
321323
}
324+
325+
#include <QInputDialog>
326+
#include "qgsmapcanvas.h"
327+
#include "qgsmaplayerstylemanager.h"
328+
void QgsAppLayerTreeViewMenuProvider::addStyleManagerStuff( QMenu* menu, QgsMapLayer* layer )
329+
{
330+
layer->enableStyleManager();
331+
QMenu* m = new QMenu( tr( "Styles" ) );
332+
m->addAction( "Add", this, SLOT( addStyle() ) );
333+
QMenu* mRemove = m->addMenu( "Remove" );
334+
m->addSeparator();
335+
336+
QgsMapLayerStyleManager* mgr = layer->styleManager();
337+
foreach ( QString name, mgr->styles() )
338+
{
339+
bool active = name == mgr->currentStyle();
340+
if ( name.isEmpty() )
341+
name = "(default)";
342+
QAction* a = m->addAction( name, this, SLOT( useStyle() ) );
343+
a->setCheckable( true );
344+
a->setChecked( active );
345+
346+
mRemove->addAction( name, this, SLOT( removeStyle() ) );
347+
}
348+
349+
menu->addMenu( m );
350+
}
351+
352+
void QgsAppLayerTreeViewMenuProvider::addStyle()
353+
{
354+
QgsMapLayer* layer = mView->currentLayer();
355+
if ( !layer )
356+
return;
357+
358+
bool ok;
359+
QString text = QInputDialog::getText( 0, tr( "New style" ),
360+
tr( "Style name:" ), QLineEdit::Normal,
361+
"newstyle", &ok );
362+
if ( !ok || text.isEmpty() )
363+
return;
364+
365+
bool res = layer->styleManager()->addStyleFromLayer( text );
366+
qDebug( "ADD: %d", res );
367+
368+
if ( res ) // make it active!
369+
layer->styleManager()->setCurrentStyle( text );
370+
}
371+
372+
void QgsAppLayerTreeViewMenuProvider::useStyle()
373+
{
374+
QgsMapLayer* layer = mView->currentLayer();
375+
if ( !layer )
376+
return;
377+
378+
QAction* a = qobject_cast<QAction*>( sender() );
379+
if ( !a )
380+
return;
381+
QString name = a->text();
382+
if ( name == "(default)" )
383+
name.clear();
384+
385+
bool res = layer->styleManager()->setCurrentStyle( name );
386+
qDebug( "USE: %d", res );
387+
388+
layer->triggerRepaint();
389+
}
390+
391+
void QgsAppLayerTreeViewMenuProvider::removeStyle()
392+
{
393+
QgsMapLayer* layer = mView->currentLayer();
394+
if ( !layer )
395+
return;
396+
397+
QAction* a = qobject_cast<QAction*>( sender() );
398+
if ( !a )
399+
return;
400+
QString name = a->text();
401+
if ( name == "(default)" )
402+
name.clear();
403+
404+
bool needsRefresh = ( layer->styleManager()->currentStyle() == name );
405+
406+
bool res = layer->styleManager()->removeStyle( name );
407+
qDebug( "DEL: %d", res );
408+
409+
if ( needsRefresh )
410+
layer->triggerRepaint();
411+
}

‎src/app/qgsapplayertreeviewmenuprovider.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,17 @@ class QgsAppLayerTreeViewMenuProvider : public QObject, public QgsLayerTreeViewM
3636
void removeLegendLayerActionsForLayer( QgsMapLayer* layer );
3737
QList< LegendLayerAction > legendLayerActions( QgsMapLayer::LayerType type ) const;
3838

39+
protected slots:
40+
void addStyle();
41+
void useStyle();
42+
void removeStyle();
3943

4044
protected:
4145

4246
void addCustomLayerActions( QMenu* menu, QgsMapLayer* layer );
4347

48+
void addStyleManagerStuff( QMenu* menu, QgsMapLayer* layer );
49+
4450
QgsLayerTreeView* mView;
4551
QgsMapCanvas* mCanvas;
4652

‎src/core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ SET(QGIS_CORE_SRCS
106106
qgsmaplayer.cpp
107107
qgsmaplayerlegend.cpp
108108
qgsmaplayerregistry.cpp
109+
qgsmaplayerstylemanager.cpp
109110
qgsmaprenderer.cpp
110111
qgsmaprenderercache.cpp
111112
qgsmaprenderercustompainterjob.cpp
@@ -495,6 +496,7 @@ SET(QGIS_CORE_HDRS
495496
qgsmaplayer.h
496497
qgsmaplayerlegend.h
497498
qgsmaplayerregistry.h
499+
qgsmaplayerstylemanager.h
498500
qgsmaprenderer.h
499501
qgsmaprenderercache.h
500502
qgsmaprenderercustompainterjob.h

‎src/core/qgsmaplayer.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "qgscoordinatereferencesystem.h"
3737
#include "qgsapplication.h"
3838
#include "qgsmaplayerlegend.h"
39+
#include "qgsmaplayerstylemanager.h"
3940
#include "qgsproject.h"
4041
#include "qgspluginlayerregistry.h"
4142
#include "qgsprojectfiletransform.h"
@@ -55,6 +56,7 @@ QgsMapLayer::QgsMapLayer( QgsMapLayer::LayerType type,
5556
mLayerType( type ),
5657
mBlendMode( QPainter::CompositionMode_SourceOver ) // Default to normal blending
5758
, mLegend( 0 )
59+
, mStyleManager( 0 )
5860
{
5961
mCRS = new QgsCoordinateReferenceSystem();
6062

@@ -1424,6 +1426,27 @@ QgsMapLayerLegend*QgsMapLayer::legend() const
14241426
return mLegend;
14251427
}
14261428

1429+
void QgsMapLayer::enableStyleManager( bool enable )
1430+
{
1431+
if ( ( enable && mStyleManager ) || ( !enable && !mStyleManager ) )
1432+
return;
1433+
1434+
if ( enable )
1435+
{
1436+
mStyleManager = new QgsMapLayerStyleManager( this );
1437+
}
1438+
else
1439+
{
1440+
delete mStyleManager;
1441+
mStyleManager = 0;
1442+
}
1443+
}
1444+
1445+
QgsMapLayerStyleManager* QgsMapLayer::styleManager() const
1446+
{
1447+
return mStyleManager;
1448+
}
1449+
14271450
void QgsMapLayer::clearCacheImage()
14281451
{
14291452
emit repaintRequested();

‎src/core/qgsmaplayer.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class QgsRenderContext;
3636
class QgsCoordinateReferenceSystem;
3737
class QgsMapLayerLegend;
3838
class QgsMapLayerRenderer;
39+
class QgsMapLayerStyleManager;
3940

4041
class QDomDocument;
4142
class QKeyEvent;
@@ -387,6 +388,21 @@ class CORE_EXPORT QgsMapLayer : public QObject
387388
*/
388389
QgsMapLayerLegend* legend() const;
389390

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+
399+
/**
400+
* 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.
402+
* @note added in 2.8
403+
*/
404+
QgsMapLayerStyleManager* styleManager() const;
405+
390406
/**Returns the minimum scale denominator at which the layer is visible.
391407
* Scale based visibility is only used if hasScaleBasedVisibility is true.
392408
* @returns minimum scale denominator at which the layer will render
@@ -621,6 +637,9 @@ class CORE_EXPORT QgsMapLayer : public QObject
621637

622638
//! Controller of legend items of this layer
623639
QgsMapLayerLegend* mLegend;
640+
641+
//! Manager of multiple styles available for a layer (may be null)
642+
QgsMapLayerStyleManager* mStyleManager;
624643
};
625644

626645
#endif

‎src/core/qgsmaplayerstylemanager.cpp

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
#include "qgsmaplayerstylemanager.h"
2+
3+
#include "qgsmaplayer.h"
4+
5+
#include <QDomElement>
6+
#include <QTemporaryFile>
7+
#include <QTextStream>
8+
9+
QgsMapLayerStyleManager::QgsMapLayerStyleManager( QgsMapLayer* layer )
10+
: mLayer( layer )
11+
{
12+
QgsMapLayerStyle defaultStyle;
13+
defaultStyle.loadFromLayer( mLayer );
14+
mStyles.insert( QString(), defaultStyle );
15+
}
16+
17+
void QgsMapLayerStyleManager::readXml( const QDomElement& mgrElement )
18+
{
19+
mCurrentStyle = mgrElement.attribute( "current" );
20+
21+
mStyles.clear();
22+
QDomElement ch = mgrElement.firstChildElement( "map-layer-style" );
23+
while ( !ch.isNull() )
24+
{
25+
QString name = ch.attribute( "name" );
26+
QgsMapLayerStyle style;
27+
style.readXml( ch );
28+
mStyles.insert( name, style );
29+
30+
ch = ch.nextSiblingElement( "map-layer-style" );
31+
}
32+
}
33+
34+
void QgsMapLayerStyleManager::writeXml( QDomElement& mgrElement ) const
35+
{
36+
const_cast<QgsMapLayerStyleManager*>( this )->syncCurrentStyle();
37+
38+
QDomDocument doc = mgrElement.ownerDocument();
39+
mgrElement.setAttribute( "current", mCurrentStyle );
40+
41+
foreach ( const QString& name, styles() )
42+
{
43+
QDomElement ch = doc.createElement( "map-layer-style" );
44+
ch.setAttribute( "name", name );
45+
mStyles[name].writeXml( ch );
46+
mgrElement.appendChild( ch );
47+
}
48+
}
49+
50+
QStringList QgsMapLayerStyleManager::styles() const
51+
{
52+
return mStyles.keys();
53+
}
54+
55+
QgsMapLayerStyle QgsMapLayerStyleManager::style( const QString& name ) const
56+
{
57+
if ( name == mCurrentStyle ) // make sure it is sync'ed
58+
const_cast<QgsMapLayerStyleManager*>( this )->syncCurrentStyle();
59+
60+
return mStyles.value( name );
61+
}
62+
63+
bool QgsMapLayerStyleManager::addStyle( const QString& name, const QgsMapLayerStyle& style )
64+
{
65+
if ( mStyles.contains( name ) )
66+
return false;
67+
if ( !style.isValid() )
68+
return false;
69+
70+
mStyles.insert( name, style );
71+
return true;
72+
}
73+
74+
bool QgsMapLayerStyleManager::addStyleFromLayer( const QString& name )
75+
{
76+
QgsMapLayerStyle style;
77+
style.loadFromLayer( mLayer );
78+
return addStyle( name, style );
79+
}
80+
81+
bool QgsMapLayerStyleManager::removeStyle( const QString& name )
82+
{
83+
if ( !mStyles.contains( name ) )
84+
return false;
85+
if ( mStyles.count() == 1 )
86+
return false; // cannot remove the last one
87+
88+
// change to a different style if this one is the current
89+
if ( mCurrentStyle == name )
90+
{
91+
QStringList keys = mStyles.keys();
92+
QString newCurrent = keys[0];
93+
if ( newCurrent == name )
94+
newCurrent = keys[1]; // there must be at least one more
95+
setCurrentStyle( newCurrent );
96+
}
97+
98+
mStyles.remove( name );
99+
return true;
100+
}
101+
102+
QString QgsMapLayerStyleManager::currentStyle() const
103+
{
104+
return mCurrentStyle;
105+
}
106+
107+
bool QgsMapLayerStyleManager::setCurrentStyle( const QString& name )
108+
{
109+
if ( !mStyles.contains( name ) )
110+
return false;
111+
112+
if ( mCurrentStyle == name )
113+
return true; // nothing to do
114+
115+
syncCurrentStyle(); // sync before unloading it
116+
mCurrentStyle = name;
117+
mStyles[mCurrentStyle].applyToLayer( mLayer );
118+
return true;
119+
}
120+
121+
void QgsMapLayerStyleManager::syncCurrentStyle()
122+
{
123+
mStyles[mCurrentStyle].loadFromLayer( mLayer );
124+
}
125+
126+
// -----
127+
128+
QgsMapLayerStyle::QgsMapLayerStyle()
129+
{
130+
}
131+
132+
bool QgsMapLayerStyle::isValid() const
133+
{
134+
return !mXmlData.isEmpty();
135+
}
136+
137+
QString QgsMapLayerStyle::dump() const
138+
{
139+
return mXmlData;
140+
}
141+
142+
void QgsMapLayerStyle::loadFromLayer( QgsMapLayer* layer )
143+
{
144+
QString errorMsg;
145+
QDomDocument doc;
146+
layer->exportNamedStyle( doc, errorMsg );
147+
if ( !errorMsg.isEmpty() )
148+
{
149+
qDebug( " ERR: %s", errorMsg.toAscii().data() );
150+
return;
151+
}
152+
153+
QTextStream stream( &mXmlData );
154+
doc.save( stream, 0 );
155+
}
156+
157+
void QgsMapLayerStyle::applyToLayer( QgsMapLayer* layer ) const
158+
{
159+
// QgsMapLayer does not have a importNamedStyle() method - working it around like this
160+
QTemporaryFile f;
161+
f.open();
162+
f.write( mXmlData );
163+
f.flush();
164+
165+
bool res;
166+
QString status = layer->loadNamedStyle( f.fileName(), res );
167+
qDebug( "APPLY: %s", status.toAscii().data() );
168+
if ( !res )
169+
qDebug( " APPLY ERR!" );
170+
}
171+
172+
void QgsMapLayerStyle::readXml( const QDomElement& styleElement )
173+
{
174+
QTextStream stream( &mXmlData );
175+
styleElement.firstChildElement().save( stream, 0 );
176+
}
177+
178+
void QgsMapLayerStyle::writeXml( QDomElement& styleElement ) const
179+
{
180+
QDomDocument docX;
181+
docX.setContent( mXmlData );
182+
styleElement.appendChild( docX.documentElement() );
183+
}

‎src/core/qgsmaplayerstylemanager.h

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#ifndef QGSMAPLAYERSTYLEMANAGER_H
2+
#define QGSMAPLAYERSTYLEMANAGER_H
3+
4+
5+
class QgsMapLayer;
6+
7+
8+
#include <QByteArray>
9+
#include <QMap>
10+
#include <QStringList>
11+
12+
class QDomElement;
13+
14+
/** stores style information (renderer, transparency, labeling, diagrams etc.) applicable to a map layer */
15+
class QgsMapLayerStyle
16+
{
17+
public:
18+
QgsMapLayerStyle(); // consutrct invalid style
19+
20+
bool isValid() const;
21+
22+
QString dump() const; // for debugging only
23+
24+
void loadFromLayer( QgsMapLayer* layer );
25+
void applyToLayer( QgsMapLayer* layer ) const;
26+
27+
void readXml( const QDomElement& styleElement );
28+
void writeXml( QDomElement& styleElement ) const;
29+
30+
private:
31+
QByteArray mXmlData;
32+
};
33+
34+
35+
/** Management of styles for use with one map layer */
36+
class QgsMapLayerStyleManager
37+
{
38+
public:
39+
QgsMapLayerStyleManager( QgsMapLayer* layer );
40+
41+
void readXml( const QDomElement& mgrElement );
42+
void writeXml( QDomElement& mgrElement ) const;
43+
44+
QStringList styles() const;
45+
QgsMapLayerStyle style( const QString& name ) const;
46+
47+
bool addStyle( const QString& name, const QgsMapLayerStyle& style );
48+
//! Add style by cloning the current one
49+
bool addStyleFromLayer( const QString& name );
50+
bool removeStyle( const QString& name );
51+
52+
QString currentStyle() const;
53+
bool setCurrentStyle( const QString& name ); // applies to the mLayer! (+ sync previous style)
54+
55+
private:
56+
void syncCurrentStyle();
57+
void ensureCurrentInSync() const;
58+
59+
private:
60+
QgsMapLayer* mLayer;
61+
QMap<QString, QgsMapLayerStyle> mStyles;
62+
QString mCurrentStyle;
63+
};
64+
65+
#endif // QGSMAPLAYERSTYLEMANAGER_H

‎tests/src/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,4 @@ ADD_QGIS_TEST(maptopixeltest testqgsmaptopixel.cpp)
142142
ADD_QGIS_TEST(networkcontentfetcher testqgsnetworkcontentfetcher.cpp )
143143
ADD_QGIS_TEST(legendrenderertest testqgslegendrenderer.cpp )
144144
ADD_QGIS_TEST(vectorlayerjoinbuffer testqgsvectorlayerjoinbuffer.cpp )
145+
ADD_QGIS_TEST(maplayerstylemanager testqgsmaplayerstylemanager.cpp )
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
2+
#include <QtTest/QtTest>
3+
#include <QObject>
4+
5+
#include "qgsapplication.h"
6+
#include "qgsmaplayerregistry.h"
7+
#include "qgsmaplayerstylemanager.h"
8+
#include "qgssinglesymbolrendererv2.h"
9+
#include "qgsvectorlayer.h"
10+
11+
12+
class TestQgsMapLayerStyleManager : public QObject
13+
{
14+
Q_OBJECT
15+
private slots:
16+
void initTestCase();// will be called before the first testfunction is executed.
17+
void cleanupTestCase();// will be called after the last testfunction was executed.
18+
void init();// will be called before each testfunction is executed.
19+
void cleanup();// will be called after every testfunction.
20+
21+
void testEnabled();
22+
void testDefault();
23+
void testStyle();
24+
void testReadWrite();
25+
26+
private:
27+
QgsVectorLayer* mVL;
28+
};
29+
30+
void TestQgsMapLayerStyleManager::initTestCase()
31+
{
32+
QgsApplication::init();
33+
QgsApplication::initQgis();
34+
}
35+
36+
void TestQgsMapLayerStyleManager::cleanupTestCase()
37+
{
38+
QgsApplication::exitQgis();
39+
}
40+
41+
void TestQgsMapLayerStyleManager::init()
42+
{
43+
mVL = new QgsVectorLayer( "LineString", "Line Layer", "memory" );
44+
QgsMapLayerRegistry::instance()->addMapLayer( mVL );
45+
}
46+
47+
void TestQgsMapLayerStyleManager::cleanup()
48+
{
49+
QgsMapLayerRegistry::instance()->removeAllMapLayers();
50+
}
51+
52+
void TestQgsMapLayerStyleManager::testEnabled()
53+
{
54+
QVERIFY( !mVL->styleManager() );
55+
56+
mVL->enableStyleManager( false );
57+
QVERIFY( !mVL->styleManager() );
58+
59+
mVL->enableStyleManager();
60+
QVERIFY( mVL->styleManager() );
61+
62+
mVL->enableStyleManager( false );
63+
QVERIFY( !mVL->styleManager() );
64+
}
65+
66+
void TestQgsMapLayerStyleManager::testDefault()
67+
{
68+
mVL->enableStyleManager();
69+
QgsMapLayerStyleManager* mgr = mVL->styleManager();
70+
QVERIFY( mgr );
71+
72+
QCOMPARE( mgr->styles().count(), 1 );
73+
QCOMPARE( mgr->style( QString() ).isValid(), true );
74+
}
75+
76+
void TestQgsMapLayerStyleManager::testStyle()
77+
{
78+
QgsLineSymbolV2* sym1 = new QgsLineSymbolV2();
79+
sym1->setColor( Qt::magenta );
80+
QgsLineSymbolV2* sym2 = new QgsLineSymbolV2();
81+
sym2->setColor( Qt::red );
82+
83+
QgsMapLayerStyle st;
84+
QCOMPARE( st.isValid(), false );
85+
86+
mVL->setRendererV2( new QgsSingleSymbolRendererV2( sym1 ) );
87+
88+
QgsMapLayerStyle st1;
89+
st1.loadFromLayer( mVL );
90+
QCOMPARE( st1.isValid(), true );
91+
92+
qDebug( "CNT-1: %s", st1.dump().toAscii().data() );
93+
94+
mVL->setRendererV2( new QgsSingleSymbolRendererV2( sym2 ) );
95+
96+
QgsMapLayerStyle st2;
97+
st2.loadFromLayer( mVL );
98+
99+
qDebug( "CNT-2: %s", st2.dump().toAscii().data() );
100+
101+
st1.applyToLayer( mVL );
102+
103+
QgsSingleSymbolRendererV2* r1 = dynamic_cast<QgsSingleSymbolRendererV2*>( mVL->rendererV2() );
104+
QVERIFY( r1 );
105+
QCOMPARE( r1->symbol()->color(), QColor( Qt::magenta ) );
106+
107+
st2.applyToLayer( mVL );
108+
109+
QgsSingleSymbolRendererV2* r2 = dynamic_cast<QgsSingleSymbolRendererV2*>( mVL->rendererV2() );
110+
QVERIFY( r2 );
111+
QCOMPARE( r2->symbol()->color(), QColor( Qt::red ) );
112+
}
113+
114+
115+
void TestQgsMapLayerStyleManager::testReadWrite()
116+
{
117+
QgsSingleSymbolRendererV2* r0 = dynamic_cast<QgsSingleSymbolRendererV2*>( mVL->rendererV2() );
118+
r0->symbol()->setColor( Qt::red );
119+
120+
// create and populate the manager with one more style
121+
122+
QgsMapLayerStyleManager sm0( mVL );
123+
124+
sm0.addStyleFromLayer( "blue" );
125+
sm0.setCurrentStyle( "blue" );
126+
QgsSingleSymbolRendererV2* r1 = dynamic_cast<QgsSingleSymbolRendererV2*>( mVL->rendererV2() );
127+
r1->symbol()->setColor( Qt::blue );
128+
129+
// read and write
130+
131+
QDomDocument doc;
132+
QDomElement mgrElem = doc.createElement( "map-layer-style-manager" );
133+
doc.appendChild( mgrElem );
134+
sm0.writeXml( mgrElem );
135+
136+
QString xml;
137+
QTextStream ts(&xml);
138+
doc.save(ts, 2);
139+
qDebug("%s", xml.toAscii().data());
140+
141+
QgsMapLayerStyleManager sm1( mVL );
142+
sm1.readXml( mgrElem );
143+
144+
QCOMPARE( sm1.styles().count(), 2 );
145+
QCOMPARE( sm1.style(QString()).isValid(), true );
146+
QCOMPARE( sm1.style("blue").isValid(), true );
147+
QCOMPARE( sm1.currentStyle(), QString("blue") );
148+
149+
// now use the default style - the symbol should get red color
150+
sm1.setCurrentStyle( QString() );
151+
152+
QgsSingleSymbolRendererV2* r2 = dynamic_cast<QgsSingleSymbolRendererV2*>( mVL->rendererV2() );
153+
QCOMPARE( r2->symbol()->color(), QColor( Qt::red ) );
154+
}
155+
156+
QTEST_MAIN( TestQgsMapLayerStyleManager )
157+
#include "testqgsmaplayerstylemanager.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.