Skip to content

Commit 9d11354

Browse files
committed
Merge patch for symbollevels in rule based renderer also to master (patch provided by Mayeul Kauffmann)
1 parent b0b28f5 commit 9d11354

9 files changed

Lines changed: 293 additions & 15 deletions

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 & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,19 @@ QgsRuleBasedRendererV2::QgsRuleBasedRendererV2( QgsSymbolV2* defaultSymbol )
128128

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

135146
void QgsRuleBasedRendererV2::renderFeature( QgsFeature& feature,
@@ -205,6 +216,10 @@ QgsFeatureRendererV2* QgsRuleBasedRendererV2::clone()
205216
QgsSymbolV2* s = mDefaultSymbol->clone();
206217
QgsRuleBasedRendererV2* r = new QgsRuleBasedRendererV2( s );
207218
r->mRules = mRules;
219+
r->setUsingSymbolLevels( usingSymbolLevels() );
220+
r->setUsingFirstRule( usingFirstRule() );
221+
setUsingFirstRule( usingFirstRule() );
222+
setUsingSymbolLevels( usingSymbolLevels() );
208223
return r;
209224
}
210225

@@ -224,6 +239,8 @@ QDomElement QgsRuleBasedRendererV2::save( QDomDocument& doc )
224239
{
225240
QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
226241
rendererElem.setAttribute( "type", "RuleRenderer" );
242+
rendererElem.setAttribute( "symbollevels", ( mUsingSymbolLevels ? "1" : "0" ) );
243+
rendererElem.setAttribute( "firstrule", ( mUsingFirstRule ? "1" : "0" ) );
227244

228245
QDomElement rulesElem = doc.createElement( "rules" );
229246

@@ -351,6 +368,12 @@ void QgsRuleBasedRendererV2::removeRuleAt( int index )
351368
mRules.removeAt( index );
352369
}
353370

371+
void QgsRuleBasedRendererV2::swapRules( int index1, int index2 )
372+
{
373+
mRules.swap( index1, index2 );
374+
}
375+
376+
354377
#include "qgscategorizedsymbolrendererv2.h"
355378
#include "qgsgraduatedsymbolrendererv2.h"
356379

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;
@@ -130,6 +131,8 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
130131
void updateRuleAt( int index, const Rule& rule );
131132
//! remove the rule at the specified index
132133
void removeRuleAt( int index );
134+
//! swap the two rules specified by the indices
135+
void swapRules( int index1, int index2);
133136

134137
//////
135138

@@ -150,6 +153,7 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
150153
QList<Rule*> mCurrentRules;
151154
QgsFieldMap mCurrentFields;
152155
QgsSymbolV2* mCurrentSymbol;
156+
153157
};
154158

155159
#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

@@ -173,6 +188,99 @@ void QgsRuleBasedRendererV2Widget::removeRule()
173188
}
174189

175190

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

604+
// Priority (Id): add 1 to rule number and convert to string
605+
item->setText( 4, QString("%1").arg( i+1, 4 ) );
606+
item->setTextAlignment (4, Qt::AlignRight);
496607
lst << item;
497608
}
498609

@@ -557,6 +668,11 @@ void QgsRendererRulesTreeWidget::populateRulesGroupByScale()
557668

558669
//item->setBackground( 1, Qt::lightGray );
559670
//item->setBackground( 3, Qt::lightGray );
671+
672+
// Priority (Id): add 1 to rule number and convert to string
673+
item->setText( 4, QString("%1").arg( i+1, 4 ) );
674+
item->setTextAlignment (4, Qt::AlignRight);
675+
560676
}
561677
addTopLevelItems( scale_items.values() );
562678
}
@@ -608,6 +724,10 @@ void QgsRendererRulesTreeWidget::populateRulesGroupByFilter()
608724
item->setTextAlignment( 2, Qt::AlignRight );
609725
item->setTextAlignment( 3, Qt::AlignRight );
610726
}
727+
728+
// Priority (Id): add 1 to rule number and convert to string
729+
item->setText( 4, QString("%1").arg( i+1, 4 ) );
730+
item->setTextAlignment (4, Qt::AlignRight);
611731
}
612732

613733
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 );

0 commit comments

Comments
 (0)