Skip to content

Commit 26fe9c7

Browse files
committedMay 10, 2011
Merge pull request #7 from mayeulk/release-1_7_0_RBR-MK
Symbol levels in Rule-Based renderer on release-1_7_0

9 files changed

+293
-14
lines changed
 

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,10 @@ QgsFeatureRendererV2* QgsFeatureRendererV2::load( QDomElement& element )
347347

348348
QgsFeatureRendererV2* r = m->createRenderer( element );
349349
if ( r )
350+
{
350351
r->setUsingSymbolLevels( element.attribute( "symbollevels", "0" ).toInt() );
351-
352+
r->setUsingFirstRule( element.attribute( "firstrule", "0" ).toInt() );
353+
}
352354
return r;
353355
}
354356

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ class CORE_EXPORT QgsFeatureRendererV2
8484
bool usingSymbolLevels() const { return mUsingSymbolLevels; }
8585
void setUsingSymbolLevels( bool usingSymbolLevels ) { mUsingSymbolLevels = usingSymbolLevels; }
8686

87+
bool usingFirstRule() const { return mUsingFirstRule; }
88+
void setUsingFirstRule( bool usingFirstRule ) { mUsingFirstRule = usingFirstRule; }
89+
90+
8791
//! create a renderer from XML element
8892
static QgsFeatureRendererV2* load( QDomElement& symbologyElem );
8993

@@ -117,6 +121,7 @@ class CORE_EXPORT QgsFeatureRendererV2
117121
QString mType;
118122

119123
bool mUsingSymbolLevels;
124+
bool mUsingFirstRule;
120125

121126
/** The current type of editing marker */
122127
int mCurrentVertexMarkerType;

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,19 @@ QgsRuleBasedRendererV2::QgsRuleBasedRendererV2( QgsSymbolV2* defaultSymbol )
128128

129129
QgsSymbolV2* QgsRuleBasedRendererV2::symbolForFeature( QgsFeature& feature )
130130
{
131-
return mCurrentSymbol;
131+
132+
if( ! usingFirstRule() )
133+
return mCurrentSymbol;
134+
135+
for ( QList<Rule*>::iterator it = mCurrentRules.begin(); it != mCurrentRules.end(); ++it )
136+
{
137+
Rule* rule = *it;
138+
139+
if ( rule->isFilterOK( mCurrentFields, feature ) )
140+
{
141+
return rule->symbol(); //works with levels but takes only first rule
142+
}
143+
}
132144
}
133145

134146
void QgsRuleBasedRendererV2::renderFeature( QgsFeature& feature,
@@ -200,6 +212,10 @@ QgsFeatureRendererV2* QgsRuleBasedRendererV2::clone()
200212
QgsSymbolV2* s = mDefaultSymbol->clone();
201213
QgsRuleBasedRendererV2* r = new QgsRuleBasedRendererV2( s );
202214
r->mRules = mRules;
215+
r->setUsingSymbolLevels( usingSymbolLevels() );
216+
r->setUsingFirstRule( usingFirstRule() );
217+
setUsingFirstRule( usingFirstRule() );
218+
setUsingSymbolLevels( usingSymbolLevels() );
203219
return r;
204220
}
205221

@@ -219,6 +235,8 @@ QDomElement QgsRuleBasedRendererV2::save( QDomDocument& doc )
219235
{
220236
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
221237
rendererElem.setAttribute( "type", "RuleRenderer" );
238+
rendererElem.setAttribute( "symbollevels", ( mUsingSymbolLevels ? "1" : "0" ) );
239+
rendererElem.setAttribute( "firstrule", ( mUsingFirstRule ? "1" : "0" ) );
222240

223241
QDomElement rulesElem = doc.createElement( "rules" );
224242

@@ -346,6 +364,12 @@ void QgsRuleBasedRendererV2::removeRuleAt( int index )
346364
mRules.removeAt( index );
347365
}
348366

367+
void QgsRuleBasedRendererV2::swapRules( int index1, int index2 )
368+
{
369+
mRules.swap( index1, index2 );
370+
}
371+
372+
349373
#include "qgscategorizedsymbolrendererv2.h"
350374
#include "qgsgraduatedsymbolrendererv2.h"
351375

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
4444
{
4545
public:
4646
//! Constructor takes ownership of the symbol
47-
Rule( QgsSymbolV2* symbol, int scaleMinDenom = 0, int scaleMaxDenom = 0, QString filterExp = QString(), QString label = QString(), QString description = QString() );
47+
Rule( QgsSymbolV2* symbol, int scaleMinDenom = 0, int scaleMaxDenom = 0, QString filterExp = QString(),
48+
QString label = QString(), QString description = QString() );
4849
Rule( const Rule& other );
4950
~Rule();
5051
QString dump() const;
@@ -127,6 +128,8 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
127128
void updateRuleAt( int index, const Rule& rule );
128129
//! remove the rule at the specified index
129130
void removeRuleAt( int index );
131+
//! swap the two rules specified by the indices
132+
void swapRules( int index1, int index2);
130133

131134
//////
132135

@@ -147,6 +150,7 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
147150
QList<Rule*> mCurrentRules;
148151
QgsFieldMap mCurrentFields;
149152
QgsSymbolV2* mCurrentSymbol;
153+
150154
};
151155

152156
#endif // QGSRULEBASEDRENDERERV2_H

‎src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,30 @@ void QgsRendererV2PropertiesDialog::showSymbolLevels()
201201
QgsSymbolV2List symbols = r->symbols();
202202

203203
QgsSymbolLevelsV2Dialog dlg( symbols, r->usingSymbolLevels(), this );
204+
connect( this, SIGNAL( forceChkUsingFirstRule() ), mActiveWidget, SLOT( forceUsingFirstRule() ), Qt::UniqueConnection );
205+
connect( this, SIGNAL( forceUncheckSymbolLevels() ), mActiveWidget, SLOT( forceNoSymbolLevels() ), Qt::UniqueConnection );
206+
204207
if ( dlg.exec() )
205208
{
206209
r->setUsingSymbolLevels( dlg.usingLevels() );
210+
211+
if ( r->type() == "RuleRenderer" )
212+
{
213+
if( dlg.usingLevels() )
214+
{
215+
r->setUsingFirstRule( true );
216+
emit forceChkUsingFirstRule();
217+
}
218+
else
219+
{
220+
emit forceUncheckSymbolLevels();
221+
}
222+
}
207223
}
224+
208225
}
209226

227+
210228
void QgsRendererV2PropertiesDialog::useOldSymbology()
211229
{
212230
int res = QMessageBox::question( this, tr( "Symbology" ),

‎src/gui/symbology-ng/qgsrendererv2propertiesdialog.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class GUI_EXPORT QgsRendererV2PropertiesDialog : public QDialog, private Ui::Qgs
3434

3535
signals:
3636
void useNewSymbology( bool );
37+
void forceChkUsingFirstRule();
38+
void forceUncheckSymbolLevels();
3739

3840
protected:
3941

‎src/gui/symbology-ng/qgsrulebasedrendererv2widget.cpp

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include "qgsapplication.h"
2323
#include "qgssearchtreenode.h"
2424
#include "qgssymbolv2selectordialog.h"
25+
#include "qgslogger.h"
26+
#include "qstring.h"
2527

2628
#include <QMenu>
2729
#include <QTreeWidgetItem>
@@ -66,17 +68,30 @@ QgsRuleBasedRendererV2Widget::QgsRuleBasedRendererV2Widget( QgsVectorLayer* laye
6668
btnAddRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.png" ) ) );
6769
btnEditRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyEdit.png" ) ) );
6870
btnRemoveRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.png" ) ) );
71+
btnIncreasePriority->setIcon( QIcon( QgsApplication::iconPath( "symbologyUp.png" ) ) );
72+
btnDecreasePriority->setIcon( QIcon( QgsApplication::iconPath( "symbologyDown.png" ) ) );
6973

7074
connect( treeRules, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( editRule() ) );
7175

7276
connect( btnAddRule, SIGNAL( clicked() ), this, SLOT( addRule() ) );
7377
connect( btnEditRule, SIGNAL( clicked() ), this, SLOT( editRule() ) );
7478
connect( btnRemoveRule, SIGNAL( clicked() ), this, SLOT( removeRule() ) );
79+
connect( btnIncreasePriority, SIGNAL( clicked() ), this, SLOT( increasePriority() ) );
80+
connect( btnDecreasePriority, SIGNAL( clicked() ), this, SLOT( decreasePriority() ) );
7581

7682
connect( radNoGrouping, SIGNAL( clicked() ), this, SLOT( setGrouping() ) );
7783
connect( radGroupFilter, SIGNAL( clicked() ), this, SLOT( setGrouping() ) );
7884
connect( radGroupScale, SIGNAL( clicked() ), this, SLOT( setGrouping() ) );
7985

86+
// Make sure buttons are always in the correct state
87+
chkUsingFirstRule->setChecked( mRenderer->usingFirstRule() );
88+
chkEnableSymbolLevels->setChecked( mRenderer->usingSymbolLevels() );
89+
// If symbol levels are used, forcefully check and gray-out the chkUsingFirstRule checkbox
90+
if (mRenderer->usingSymbolLevels() ) { forceUsingFirstRule(); }
91+
connect( chkUsingFirstRule, SIGNAL( clicked() ), this, SLOT( usingFirstRuleChanged() ));
92+
connect( chkEnableSymbolLevels, SIGNAL( clicked() ), this, SLOT( symbolLevelsEnabledChanged() ) );
93+
connect( this, SIGNAL( forceChkUsingFirstRule() ), this, SLOT( forceUsingFirstRule() ) );
94+
8095
treeRules->populateRules();
8196
}
8297

@@ -171,6 +186,99 @@ void QgsRuleBasedRendererV2Widget::removeRule()
171186
}
172187

173188

189+
void QgsRuleBasedRendererV2Widget::increasePriority()
190+
{
191+
QTreeWidgetItem * item = treeRules->currentItem();
192+
if ( ! item ) return; // No rule selected, exit
193+
int rule_index = item->data( 0, Qt::UserRole + 1 ).toInt();
194+
if ( rule_index < 0 )
195+
{
196+
return;// Group of rules selected, exit
197+
}
198+
else
199+
{
200+
if ( rule_index > 0 ) // do not increase priority of first rule
201+
{
202+
mRenderer->swapRules(rule_index, rule_index - 1);
203+
treeRules->populateRules();
204+
// TODO: find out where the moved rule goes and reselect it (at least for non-grouped display)
205+
// maybe based on the following functions :
206+
// findItems(QString(rule_index - 1), Qt::MatchExactly, 4).first.index)
207+
// setCurrentItem, setSelected, scrollToItem
208+
}
209+
}
210+
211+
}
212+
213+
214+
void QgsRuleBasedRendererV2Widget::decreasePriority()
215+
{
216+
QTreeWidgetItem * item = treeRules->currentItem();
217+
if ( ! item ) return; // No rule selected, exit
218+
int rule_index = item->data( 0, Qt::UserRole + 1 ).toInt();
219+
if ( rule_index < 0 )
220+
{
221+
return;// Group of rules selected, exit
222+
}
223+
else
224+
{
225+
if ( rule_index +1 < mRenderer->ruleCount() ) // do not increase priority of last rule
226+
{
227+
mRenderer->swapRules(rule_index, rule_index + 1);
228+
treeRules->populateRules();
229+
}
230+
}
231+
}
232+
233+
234+
void QgsRuleBasedRendererV2Widget::usingFirstRuleChanged()
235+
{
236+
if ( chkUsingFirstRule->checkState() == Qt::Checked )
237+
{
238+
mRenderer->setUsingFirstRule(true);
239+
}
240+
else
241+
{
242+
mRenderer->setUsingFirstRule(false);
243+
}
244+
245+
}
246+
247+
248+
void QgsRuleBasedRendererV2Widget::forceUsingFirstRule()
249+
{
250+
chkEnableSymbolLevels->setChecked( true );
251+
chkUsingFirstRule->setChecked( true );
252+
chkUsingFirstRule->setEnabled(false);
253+
mRenderer->setUsingFirstRule(true);
254+
}
255+
256+
257+
void QgsRuleBasedRendererV2Widget::forceNoSymbolLevels()
258+
{
259+
chkEnableSymbolLevels->setChecked( false );
260+
chkUsingFirstRule->setEnabled( true );
261+
mRenderer->setUsingSymbolLevels( false );
262+
}
263+
264+
265+
void QgsRuleBasedRendererV2Widget::symbolLevelsEnabledChanged()
266+
{
267+
if ( chkEnableSymbolLevels->checkState() == Qt::Checked )
268+
{
269+
mRenderer->setUsingSymbolLevels(true);
270+
emit forceChkUsingFirstRule();
271+
}
272+
else
273+
{
274+
mRenderer->setUsingSymbolLevels(false);
275+
chkUsingFirstRule->setEnabled(true);
276+
}
277+
}
278+
279+
280+
281+
174282
#include "qgscategorizedsymbolrendererv2.h"
175283
#include "qgscategorizedsymbolrendererv2widget.h"
176284
#include "qgsgraduatedsymbolrendererv2.h"
@@ -487,6 +595,9 @@ void QgsRendererRulesTreeWidget::populateRulesNoGrouping()
487595
//item->setBackground( 1, Qt::lightGray );
488596
//item->setBackground( 3, Qt::lightGray );
489597

598+
// Priority (Id): add 1 to rule number and convert to string
599+
item->setText( 4, QString("%1").arg( i+1, 4 ) );
600+
item->setTextAlignment (4, Qt::AlignRight);
490601
lst << item;
491602
}
492603

@@ -550,6 +661,11 @@ void QgsRendererRulesTreeWidget::populateRulesGroupByScale()
550661

551662
//item->setBackground( 1, Qt::lightGray );
552663
//item->setBackground( 3, Qt::lightGray );
664+
665+
// Priority (Id): add 1 to rule number and convert to string
666+
item->setText( 4, QString("%1").arg( i+1, 4 ) );
667+
item->setTextAlignment (4, Qt::AlignRight);
668+
553669
}
554670
addTopLevelItems( scale_items.values() );
555671
}
@@ -601,6 +717,10 @@ void QgsRendererRulesTreeWidget::populateRulesGroupByFilter()
601717
item->setTextAlignment( 2, Qt::AlignRight );
602718
item->setTextAlignment( 3, Qt::AlignRight );
603719
}
720+
721+
// Priority (Id): add 1 to rule number and convert to string
722+
item->setText( 4, QString("%1").arg( i+1, 4 ) );
723+
item->setTextAlignment (4, Qt::AlignRight);
604724
}
605725

606726
addTopLevelItems( filter_items.values() );

‎src/gui/symbology-ng/qgsrulebasedrendererv2widget.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,24 @@ class GUI_EXPORT QgsRuleBasedRendererV2Widget : public QgsRendererV2Widget, priv
7878
void addRule();
7979
void editRule();
8080
void removeRule();
81+
void increasePriority();
82+
void decreasePriority();
8183

8284
void setGrouping();
8385

8486
void refineRuleScales();
8587
void refineRuleCategories();
8688
void refineRuleRanges();
8789

90+
void usingFirstRuleChanged( );
91+
void symbolLevelsEnabledChanged();
92+
void forceNoSymbolLevels();
93+
void forceUsingFirstRule();
94+
95+
signals:
96+
97+
void forceChkUsingFirstRule();
98+
8899
protected:
89100

90101
void refineRule( int type );

‎src/ui/qgsrulebasedrendererv2widget.ui

Lines changed: 104 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>622</width>
10-
<height>273</height>
9+
<width>640</width>
10+
<height>401</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
@@ -16,6 +16,9 @@
1616
<layout class="QGridLayout" name="gridLayout">
1717
<item row="0" column="0">
1818
<widget class="QgsRendererRulesTreeWidget" name="treeRules">
19+
<property name="styleSheet">
20+
<string notr="true"/>
21+
</property>
1922
<property name="rootIsDecorated">
2023
<bool>false</bool>
2124
</property>
@@ -51,6 +54,17 @@
5154
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
5255
</property>
5356
</column>
57+
<column>
58+
<property name="text">
59+
<string>Priority</string>
60+
</property>
61+
<property name="toolTip">
62+
<string>Priority when symbol levels are enabled (only first matching rule will be applied)</string>
63+
</property>
64+
<property name="textAlignment">
65+
<set>AlignHCenter|AlignVCenter|AlignCenter</set>
66+
</property>
67+
</column>
5468
</widget>
5569
</item>
5670
<item row="0" column="1">
@@ -62,6 +76,20 @@
6276
</property>
6377
</widget>
6478
</item>
79+
<item>
80+
<widget class="QPushButton" name="btnEditRule">
81+
<property name="text">
82+
<string>Edit</string>
83+
</property>
84+
</widget>
85+
</item>
86+
<item>
87+
<widget class="QPushButton" name="btnRemoveRule">
88+
<property name="text">
89+
<string>Remove</string>
90+
</property>
91+
</widget>
92+
</item>
6593
<item>
6694
<widget class="QPushButton" name="btnRefineRule">
6795
<property name="text">
@@ -70,31 +98,96 @@
7098
</widget>
7199
</item>
72100
<item>
73-
<widget class="QPushButton" name="btnEditRule">
101+
<widget class="QPushButton" name="btnIncreasePriority">
74102
<property name="text">
75-
<string>Edit</string>
103+
<string>Increase priority</string>
76104
</property>
77105
</widget>
78106
</item>
79107
<item>
80-
<widget class="QPushButton" name="btnRemoveRule">
108+
<widget class="QPushButton" name="btnDecreasePriority">
81109
<property name="text">
82-
<string>Remove</string>
110+
<string>Decrease priority</string>
83111
</property>
84112
</widget>
85113
</item>
86114
</layout>
87115
</item>
88-
<item row="1" column="0" colspan="2">
116+
<item row="3" column="0" colspan="2">
117+
<widget class="QGroupBox" name="groupBox_2">
118+
<property name="minimumSize">
119+
<size>
120+
<width>0</width>
121+
<height>35</height>
122+
</size>
123+
</property>
124+
<property name="baseSize">
125+
<size>
126+
<width>0</width>
127+
<height>0</height>
128+
</size>
129+
</property>
130+
<property name="title">
131+
<string/>
132+
</property>
133+
<widget class="QCheckBox" name="chkEnableSymbolLevels">
134+
<property name="geometry">
135+
<rect>
136+
<x>113</x>
137+
<y>10</y>
138+
<width>231</width>
139+
<height>24</height>
140+
</rect>
141+
</property>
142+
<property name="text">
143+
<string>Enable symbol levels</string>
144+
</property>
145+
</widget>
146+
<widget class="QCheckBox" name="chkUsingFirstRule">
147+
<property name="geometry">
148+
<rect>
149+
<x>360</x>
150+
<y>10</y>
151+
<width>271</width>
152+
<height>24</height>
153+
</rect>
154+
</property>
155+
<property name="text">
156+
<string>Use only first matched rule</string>
157+
</property>
158+
</widget>
159+
<widget class="QLabel" name="label_2">
160+
<property name="geometry">
161+
<rect>
162+
<x>10</x>
163+
<y>10</y>
164+
<width>84</width>
165+
<height>24</height>
166+
</rect>
167+
</property>
168+
<property name="text">
169+
<string>Behavior</string>
170+
</property>
171+
</widget>
172+
</widget>
173+
</item>
174+
<item row="2" column="0" colspan="2">
89175
<widget class="QGroupBox" name="groupBox">
90176
<property name="title">
91-
<string>Rule grouping</string>
177+
<string notr="true"/>
92178
</property>
93179
<layout class="QHBoxLayout" name="horizontalLayout">
180+
<item>
181+
<widget class="QLabel" name="label">
182+
<property name="text">
183+
<string>Rule grouping</string>
184+
</property>
185+
</widget>
186+
</item>
94187
<item>
95188
<widget class="QRadioButton" name="radNoGrouping">
96189
<property name="text">
97-
<string>No grouping</string>
190+
<string comment="No grouping for displaying rules">None</string>
98191
</property>
99192
<property name="checked">
100193
<bool>true</bool>
@@ -104,14 +197,14 @@
104197
<item>
105198
<widget class="QRadioButton" name="radGroupFilter">
106199
<property name="text">
107-
<string>Group by filter</string>
200+
<string comment="Group rules by filter">By filter</string>
108201
</property>
109202
</widget>
110203
</item>
111204
<item>
112205
<widget class="QRadioButton" name="radGroupScale">
113206
<property name="text">
114-
<string>Group by scale</string>
207+
<string comment="Group rules by scale">By scale</string>
115208
</property>
116209
</widget>
117210
</item>

0 commit comments

Comments
 (0)
Please sign in to comment.