Skip to content

Commit dcbe0d3

Browse files
committedOct 7, 2015
Fix legends are empty if presets used with filtered legend (fix #13300)
1 parent 8f04d22 commit dcbe0d3

File tree

10 files changed

+537
-322
lines changed

10 files changed

+537
-322
lines changed
 

‎python/core/symbology-ng/qgssymbollayerv2utils.sip

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ class QgsSymbolLayerV2Utils
103103
static QgsSymbolLayerV2* loadSymbolLayer( QDomElement& element ) /Factory/;
104104
static QDomElement saveSymbol( const QString& symbolName, QgsSymbolV2* symbol, QDomDocument& doc );
105105

106+
/** Returns a string representing the symbol. Can be used to test for equality
107+
* between symbols.
108+
* @note added in QGIS 2.12
109+
*/
110+
static QString symbolProperties( QgsSymbolV2* symbol );
111+
106112
static bool createSymbolLayerV2ListFromSld( QDomElement& element, QGis::GeometryType geomType, QgsSymbolLayerV2List &layers );
107113

108114
static QgsSymbolLayerV2* createFillLayerFromSld( QDomElement &element );

‎src/core/composer/qgscomposerlegend.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -537,14 +537,22 @@ void QgsComposerLegend::mapLayerStyleOverridesChanged()
537537
return;
538538

539539
// map's style has been changed, so make sure to update the legend here
540+
if ( mLegendFilterByMap )
541+
{
542+
// legend is being filtered by map, so we need to re run the hit test too
543+
// as the style overrides may also have affected the visible symbols
544+
updateFilterByMap();
545+
}
546+
else
547+
{
548+
mLegendModel2->setLayerStyleOverrides( mComposerMap->layerStyleOverrides() );
540549

541-
mLegendModel2->setLayerStyleOverrides( mComposerMap->layerStyleOverrides() );
542-
543-
Q_FOREACH ( QgsLayerTreeLayer* nodeLayer, mLegendModel2->rootGroup()->findLayers() )
544-
mLegendModel2->refreshLayerLegend( nodeLayer );
550+
Q_FOREACH ( QgsLayerTreeLayer* nodeLayer, mLegendModel2->rootGroup()->findLayers() )
551+
mLegendModel2->refreshLayerLegend( nodeLayer );
545552

546-
adjustBoxSize();
547-
update();
553+
adjustBoxSize();
554+
update();
555+
}
548556
}
549557

550558
void QgsComposerLegend::updateFilterByMap()

‎src/core/layertree/qgslayertreemodel.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@ void QgsLayerTreeModel::setLegendFilterByMap( const QgsMapSettings* settings )
562562
if ( settings && settings->hasValidSettings() )
563563
{
564564
mLegendFilterByMapSettings.reset( new QgsMapSettings( *settings ) );
565+
mLegendFilterByMapSettings->setLayerStyleOverrides( mLayerStyleOverrides );
565566
mLegendFilterByMapHitTest.reset( new QgsMapHitTest( *mLegendFilterByMapSettings ) );
566567
mLegendFilterByMapHitTest->run();
567568
}
@@ -1030,7 +1031,7 @@ QList<QgsLayerTreeModelLegendNode*> QgsLayerTreeModel::filterLegendNodes( const
10301031
{
10311032
if ( QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( node->layerNode()->layer() ) )
10321033
{
1033-
if ( mLegendFilterByMapHitTest->symbolsForLayer( vl ).contains( ruleKey ) )
1034+
if ( mLegendFilterByMapHitTest->symbolVisible( ruleKey, vl ) )
10341035
filtered << node;
10351036
}
10361037
}

‎src/core/qgsmaphittest.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
#include "qgsmaplayerregistry.h"
44
#include "qgsrendercontext.h"
5+
#include "qgsmaplayerstylemanager.h"
56
#include "qgsrendererv2.h"
67
#include "qgspointdisplacementrenderer.h"
78
#include "qgsvectorlayer.h"
8-
9+
#include "qgssymbollayerv2utils.h"
910

1011
QgsMapHitTest::QgsMapHitTest( const QgsMapSettings& settings )
1112
: mSettings( settings )
@@ -50,9 +51,20 @@ void QgsMapHitTest::run()
5051
painter.end();
5152
}
5253

54+
bool QgsMapHitTest::symbolVisible( QgsSymbolV2* symbol, QgsVectorLayer* layer ) const
55+
{
56+
if ( !symbol || !layer || !mHitTest.contains( layer ) )
57+
return false;
58+
59+
return mHitTest.value( layer ).contains( QgsSymbolLayerV2Utils::symbolProperties( symbol ) );
60+
}
5361

5462
void QgsMapHitTest::runHitTestLayer( QgsVectorLayer* vl, SymbolV2Set& usedSymbols, QgsRenderContext& context )
5563
{
64+
bool hasStyleOverride = mSettings.layerStyleOverrides().contains( vl->id() );
65+
if ( hasStyleOverride )
66+
vl->styleManager()->setOverrideStyle( mSettings.layerStyleOverrides().value( vl->id() ) );
67+
5668
QgsFeatureRendererV2* r = vl->rendererV2();
5769
bool moreSymbolsPerFeature = r->capabilities() & QgsFeatureRendererV2::MoreSymbolsPerFeature;
5870
r->startRender( context, vl->fields() );
@@ -63,13 +75,25 @@ void QgsMapHitTest::runHitTestLayer( QgsVectorLayer* vl, SymbolV2Set& usedSymbol
6375
while ( fi.nextFeature( f ) )
6476
{
6577
context.expressionContext().setFeature( f );
78+
79+
//make sure we store string representation of symbol, not pointer
80+
//otherwise layer style override changes will delete original symbols and leave hanging pointers
6681
if ( moreSymbolsPerFeature )
6782
{
6883
Q_FOREACH ( QgsSymbolV2* s, r->originalSymbolsForFeature( f, context ) )
69-
usedSymbols.insert( s );
84+
{
85+
usedSymbols.insert( QgsSymbolLayerV2Utils::symbolProperties( s ) );
86+
}
7087
}
7188
else
72-
usedSymbols.insert( r->originalSymbolForFeature( f, context ) );
89+
{
90+
QgsSymbolV2* s = r->originalSymbolForFeature( f, context );
91+
usedSymbols.insert( QgsSymbolLayerV2Utils::symbolProperties( s ) );
92+
}
7393
}
7494
r->stopRender( context );
95+
96+
if ( hasStyleOverride )
97+
vl->styleManager()->restoreOverrideStyle();
7598
}
99+

‎src/core/qgsmaphittest.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,24 @@ class CORE_EXPORT QgsMapHitTest
2222

2323
void run();
2424

25-
QSet<QgsSymbolV2*> symbolsForLayer( QgsVectorLayer* layer ) const { return mHitTest[layer]; }
25+
/** Tests whether a symbol is visible for a specified layer.
26+
* @param symbol symbol to find
27+
* @param layer vector layer
28+
* @note added in QGIS 2.12
29+
*/
30+
bool symbolVisible( QgsSymbolV2* symbol, QgsVectorLayer* layer ) const;
2631

2732
protected:
2833

29-
typedef QSet<QgsSymbolV2*> SymbolV2Set;
34+
typedef QSet<QString> SymbolV2Set;
3035
typedef QMap<QgsVectorLayer*, SymbolV2Set> HitTest;
3136

37+
/** Runs test for visible symbols within a layer
38+
* @param vl vector layer
39+
* @param usedSymbols set for storage of visible symbols
40+
* @param context render context
41+
* @note added in QGIS 2.12
42+
*/
3243
void runHitTestLayer( QgsVectorLayer* vl, SymbolV2Set& usedSymbols, QgsRenderContext& context );
3344

3445
QgsMapSettings mSettings;

‎src/core/symbology-ng/qgssymbollayerv2utils.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,15 @@ QDomElement QgsSymbolLayerV2Utils::saveSymbol( const QString& name, QgsSymbolV2*
10351035
return symEl;
10361036
}
10371037

1038+
QString QgsSymbolLayerV2Utils::symbolProperties( QgsSymbolV2* symbol )
1039+
{
1040+
QDomDocument doc( "qgis-symbol-definition" );
1041+
QDomElement symbolElem = saveSymbol( "symbol", symbol, doc );
1042+
QString props;
1043+
QTextStream stream( &props );
1044+
symbolElem.save( stream, -1 );
1045+
return props;
1046+
}
10381047

10391048
bool QgsSymbolLayerV2Utils::createSymbolLayerV2ListFromSld( QDomElement& element,
10401049
QGis::GeometryType geomType,

‎src/core/symbology-ng/qgssymbollayerv2utils.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,12 @@ class CORE_EXPORT QgsSymbolLayerV2Utils
157157
static QgsSymbolLayerV2* loadSymbolLayer( QDomElement& element );
158158
static QDomElement saveSymbol( const QString& symbolName, QgsSymbolV2* symbol, QDomDocument& doc );
159159

160+
/** Returns a string representing the symbol. Can be used to test for equality
161+
* between symbols.
162+
* @note added in QGIS 2.12
163+
*/
164+
static QString symbolProperties( QgsSymbolV2* symbol );
165+
160166
static bool createSymbolLayerV2ListFromSld( QDomElement& element, QGis::GeometryType geomType, QgsSymbolLayerV2List &layers );
161167

162168
static QgsSymbolLayerV2* createFillLayerFromSld( QDomElement &element );

‎tests/src/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ ADD_QGIS_TEST(spatialindextest testqgsspatialindex.cpp)
165165
ADD_QGIS_TEST(statisticalsummarytest testqgsstatisticalsummary.cpp)
166166
ADD_QGIS_TEST(stringutilstest testqgsstringutils.cpp)
167167
ADD_QGIS_TEST(stylev2test testqgsstylev2.cpp)
168+
ADD_QGIS_TEST(symbolv2test testqgssymbolv2.cpp)
168169
ADD_QGIS_TEST(vectordataprovidertest testqgsvectordataprovider.cpp)
169170
ADD_QGIS_TEST(vectorlayercachetest testqgsvectorlayercache.cpp )
170171
ADD_QGIS_TEST(vectorlayerjoinbuffer testqgsvectorlayerjoinbuffer.cpp )

‎tests/src/core/testqgsstylev2.cpp

Lines changed: 0 additions & 310 deletions
Large diffs are not rendered by default.

‎tests/src/core/testqgssymbolv2.cpp

Lines changed: 459 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.