--- /hometb/mk/sig/dev/r15676-backup/qgis/src/core/symbology-ng/qgsrendererv2.cpp 2011-04-07 00:51:06.740986188 +0200 +++ /hometb/mk/sig/dev/r15676-patched/qgis/src/core/symbology-ng/qgsrendererv2.cpp 2011-04-07 00:54:06.625249760 +0200 @@ -348,7 +348,7 @@ QgsFeatureRendererV2* r = m->createRenderer( element ); if ( r ) r->setUsingSymbolLevels( element.attribute( "symbollevels", "0" ).toInt() ); - + r->setUsingFirstRule( element.attribute( "firstrule", "0" ).toInt() ); return r; } --- /hometb/mk/sig/dev/r15676-backup/qgis/src/core/symbology-ng/qgsrendererv2.h 2011-04-07 00:51:06.740986188 +0200 +++ /hometb/mk/sig/dev/r15676-patched/qgis/src/core/symbology-ng/qgsrendererv2.h 2011-04-07 00:54:06.625249760 +0200 @@ -84,6 +84,10 @@ bool usingSymbolLevels() const { return mUsingSymbolLevels; } void setUsingSymbolLevels( bool usingSymbolLevels ) { mUsingSymbolLevels = usingSymbolLevels; } + bool usingFirstRule() const { return mUsingFirstRule; } + void setUsingFirstRule( bool usingFirstRule ) { mUsingFirstRule = usingFirstRule; } + + //! create a renderer from XML element static QgsFeatureRendererV2* load( QDomElement& symbologyElem ); @@ -117,6 +121,7 @@ QString mType; bool mUsingSymbolLevels; + bool mUsingFirstRule; /** The current type of editing marker */ int mCurrentVertexMarkerType; --- /hometb/mk/sig/dev/r15676-backup/qgis/src/core/symbology-ng/qgsrulebasedrendererv2.cpp 2011-04-07 00:51:06.740986188 +0200 +++ /hometb/mk/sig/dev/r15676-patched/qgis/src/core/symbology-ng/qgsrulebasedrendererv2.cpp 2011-04-07 01:50:09.157592202 +0200 @@ -128,7 +128,18 @@ QgsSymbolV2* QgsRuleBasedRendererV2::symbolForFeature( QgsFeature& feature ) { - return mCurrentSymbol; + + if( !( usingFirstRule() ) ) return mCurrentSymbol; + + for ( QList::iterator it = mCurrentRules.begin(); it != mCurrentRules.end(); ++it ) + { + Rule* rule = *it; + + if ( rule->isFilterOK( mCurrentFields, feature ) ) + { + return rule->symbol(); //works with levels but takes only first rule + } + } } void QgsRuleBasedRendererV2::renderFeature( QgsFeature& feature, @@ -200,6 +211,10 @@ QgsSymbolV2* s = mDefaultSymbol->clone(); QgsRuleBasedRendererV2* r = new QgsRuleBasedRendererV2( s ); r->mRules = mRules; + r->setUsingSymbolLevels( usingSymbolLevels() ); + r->setUsingFirstRule( usingFirstRule() ); + setUsingFirstRule( usingFirstRule() ); + setUsingSymbolLevels( usingSymbolLevels() ); return r; } @@ -219,6 +234,8 @@ { QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME ); rendererElem.setAttribute( "type", "RuleRenderer" ); + rendererElem.setAttribute( "symbollevels", ( mUsingSymbolLevels ? "1" : "0" ) ); + rendererElem.setAttribute( "firstrule", ( mUsingFirstRule ? "1" : "0" ) ); QDomElement rulesElem = doc.createElement( "rules" ); @@ -346,6 +363,12 @@ mRules.removeAt( index ); } +void QgsRuleBasedRendererV2::swapRules( int index1, int index2 ) +{ + mRules.swap( index1, index2 ); +} + + #include "qgscategorizedsymbolrendererv2.h" #include "qgsgraduatedsymbolrendererv2.h" --- /hometb/mk/sig/dev/r15676-backup/qgis/src/core/symbology-ng/qgsrulebasedrendererv2.h 2011-04-07 00:51:06.740986188 +0200 +++ /hometb/mk/sig/dev/r15676-patched/qgis/src/core/symbology-ng/qgsrulebasedrendererv2.h 2011-04-07 01:58:47.220914257 +0200 @@ -44,7 +44,8 @@ { public: //! Constructor takes ownership of the symbol - Rule( QgsSymbolV2* symbol, int scaleMinDenom = 0, int scaleMaxDenom = 0, QString filterExp = QString(), QString label = QString(), QString description = QString() ); + Rule( QgsSymbolV2* symbol, int scaleMinDenom = 0, int scaleMaxDenom = 0, QString filterExp = QString(), + QString label = QString(), QString description = QString() ); Rule( const Rule& other ); ~Rule(); QString dump() const; @@ -127,6 +128,8 @@ void updateRuleAt( int index, const Rule& rule ); //! remove the rule at the specified index void removeRuleAt( int index ); + //! swap the two rules specified by the indices + void swapRules( int index1, int index2); ////// @@ -147,6 +150,7 @@ QList mCurrentRules; QgsFieldMap mCurrentFields; QgsSymbolV2* mCurrentSymbol; + }; #endif // QGSRULEBASEDRENDERERV2_H --- /hometb/mk/sig/dev/r15676-backup/qgis/src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp 2011-04-07 00:51:05.991010106 +0200 +++ /hometb/mk/sig/dev/r15676-patched/qgis/src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp 2011-04-07 02:01:31.325619865 +0200 @@ -201,12 +201,30 @@ QgsSymbolV2List symbols = r->symbols(); QgsSymbolLevelsV2Dialog dlg( symbols, r->usingSymbolLevels(), this ); + connect( this, SIGNAL( forceChkUsingFirstRule() ), mActiveWidget, SLOT( forceUsingFirstRule() ), Qt::UniqueConnection ); + connect( this, SIGNAL( forceUncheckSymbolLevels() ), mActiveWidget, SLOT( forceNoSymbolLevels() ), Qt::UniqueConnection ); + if ( dlg.exec() ) { r->setUsingSymbolLevels( dlg.usingLevels() ); + + if ( r->type() == "RuleRenderer" ) + { + if( dlg.usingLevels() ) + { + r->setUsingFirstRule( true ); + emit forceChkUsingFirstRule(); + } + else + { + emit forceUncheckSymbolLevels(); + } + } } + } + void QgsRendererV2PropertiesDialog::useOldSymbology() { int res = QMessageBox::question( this, tr( "Symbology" ), --- /hometb/mk/sig/dev/r15676-backup/qgis/src/gui/symbology-ng/qgsrendererv2propertiesdialog.h 2011-04-07 00:51:05.991010106 +0200 +++ /hometb/mk/sig/dev/r15676-patched/qgis/src/gui/symbology-ng/qgsrendererv2propertiesdialog.h 2011-04-07 00:54:06.635249441 +0200 @@ -34,6 +34,8 @@ signals: void useNewSymbology( bool ); + void forceChkUsingFirstRule(); + void forceUncheckSymbolLevels(); protected: --- /hometb/mk/sig/dev/r15676-backup/qgis/src/gui/symbology-ng/qgsrulebasedrendererv2widget.cpp 2011-04-07 00:51:05.991010106 +0200 +++ /hometb/mk/sig/dev/r15676-patched/qgis/src/gui/symbology-ng/qgsrulebasedrendererv2widget.cpp 2011-04-07 02:03:13.592321220 +0200 @@ -22,11 +22,14 @@ #include "qgsapplication.h" #include "qgssearchtreenode.h" #include "qgssymbolv2selectordialog.h" +#include "qgslogger.h" +#include "qstring.h" #include #include #include #include +#include QgsRendererV2Widget* QgsRuleBasedRendererV2Widget::create( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer ) { @@ -66,17 +69,30 @@ btnAddRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.png" ) ) ); btnEditRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyEdit.png" ) ) ); btnRemoveRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.png" ) ) ); + btnIncreasePriority->setIcon( QIcon( QgsApplication::iconPath( "symbologyUp.png" ) ) ); + btnDecreasePriority->setIcon( QIcon( QgsApplication::iconPath( "symbologyDown.png" ) ) ); connect( treeRules, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( editRule() ) ); connect( btnAddRule, SIGNAL( clicked() ), this, SLOT( addRule() ) ); connect( btnEditRule, SIGNAL( clicked() ), this, SLOT( editRule() ) ); connect( btnRemoveRule, SIGNAL( clicked() ), this, SLOT( removeRule() ) ); + connect( btnIncreasePriority, SIGNAL( clicked() ), this, SLOT( increasePriority() ) ); + connect( btnDecreasePriority, SIGNAL( clicked() ), this, SLOT( decreasePriority() ) ); connect( radNoGrouping, SIGNAL( clicked() ), this, SLOT( setGrouping() ) ); connect( radGroupFilter, SIGNAL( clicked() ), this, SLOT( setGrouping() ) ); connect( radGroupScale, SIGNAL( clicked() ), this, SLOT( setGrouping() ) ); + // Make sure buttons are always in the correct state + chkUsingFirstRule->setChecked( mRenderer->usingFirstRule() ); + chkEnableSymbolLevels->setChecked( mRenderer->usingSymbolLevels() ); + // If symbol levels are used, forcefully check and gray-out the chkUsingFirstRule checkbox + if (mRenderer->usingSymbolLevels() ) { forceUsingFirstRule(); } + connect( chkUsingFirstRule, SIGNAL( clicked() ), this, SLOT( usingFirstRuleChanged() )); + connect( chkEnableSymbolLevels, SIGNAL( clicked() ), this, SLOT( symbolLevelsEnabledChanged() ) ); + connect( this, SIGNAL( forceChkUsingFirstRule() ), this, SLOT( forceUsingFirstRule() ) ); + treeRules->populateRules(); } @@ -171,6 +187,99 @@ } +void QgsRuleBasedRendererV2Widget::increasePriority() +{ + QTreeWidgetItem * item = treeRules->currentItem(); + if ( ! item ) return; // No rule selected, exit + int rule_index = item->data( 0, Qt::UserRole + 1 ).toInt(); + if ( rule_index < 0 ) + { + return;// Group of rules selected, exit + } + else + { + if ( rule_index > 0 ) // do not increase priority of first rule + { + mRenderer->swapRules(rule_index, rule_index - 1); + treeRules->populateRules(); + // TODO: find out where the moved rule goes and reselect it (at least for non-grouped display) + // maybe based on the following functions : + // findItems(QString(rule_index - 1), Qt::MatchExactly, 4).first.index) + // setCurrentItem, setSelected, scrollToItem + } + } + +} + + +void QgsRuleBasedRendererV2Widget::decreasePriority() +{ + QTreeWidgetItem * item = treeRules->currentItem(); + if ( ! item ) return; // No rule selected, exit + int rule_index = item->data( 0, Qt::UserRole + 1 ).toInt(); + if ( rule_index < 0 ) + { + return;// Group of rules selected, exit + } + else + { + if ( rule_index +1 < mRenderer->ruleCount() ) // do not increase priority of last rule + { + mRenderer->swapRules(rule_index, rule_index + 1); + treeRules->populateRules(); + } + } +} + + +void QgsRuleBasedRendererV2Widget::usingFirstRuleChanged() +{ + if ( chkUsingFirstRule->checkState() == Qt::Checked ) + { + mRenderer->setUsingFirstRule(true); + } + else + { + mRenderer->setUsingFirstRule(false); + } + +} + + +void QgsRuleBasedRendererV2Widget::forceUsingFirstRule() +{ + chkEnableSymbolLevels->setChecked( true ); + chkUsingFirstRule->setChecked( true ); + chkUsingFirstRule->setEnabled(false); + mRenderer->setUsingFirstRule(true); +} + + +void QgsRuleBasedRendererV2Widget::forceNoSymbolLevels() +{ + chkEnableSymbolLevels->setChecked( false ); + chkUsingFirstRule->setEnabled( true ); + mRenderer->setUsingSymbolLevels( false ); +} + + +void QgsRuleBasedRendererV2Widget::symbolLevelsEnabledChanged() +{ + if ( chkEnableSymbolLevels->checkState() == Qt::Checked ) + { + mRenderer->setUsingSymbolLevels(true); + emit forceChkUsingFirstRule(); + } + else + { + mRenderer->setUsingSymbolLevels(false); + chkUsingFirstRule->setEnabled(true); + } +} + + + + #include "qgscategorizedsymbolrendererv2.h" #include "qgscategorizedsymbolrendererv2widget.h" #include "qgsgraduatedsymbolrendererv2.h" @@ -487,7 +596,15 @@ //item->setBackground( 1, Qt::lightGray ); //item->setBackground( 3, Qt::lightGray ); + // Priority (Id): add 1 to rule number and convert to string + std::ostringstream ioss; + ioss << i+1; + std::string ruleIdx = ioss.str(); + while( ruleIdx.size() < 4 ){ ruleIdx.insert( 0, " " );} // pad to left with spaces (to fix string-based sorting) + item->setText( 4, QString(ruleIdx.c_str()) );// Insert Id in table (as 'Priority' column) + item->setTextAlignment (4, Qt::AlignRight); lst << item; + } @@ -550,6 +667,15 @@ //item->setBackground( 1, Qt::lightGray ); //item->setBackground( 3, Qt::lightGray ); + + // Priority (Id): add 1 to rule number and convert to string + std::ostringstream ioss; + ioss << i+1; + std::string ruleIdx = ioss.str(); + while( ruleIdx.size() < 4 ){ ruleIdx.insert( 0, " " );} + item->setText( 4, QString(ruleIdx.c_str()) ); + item->setTextAlignment (4, Qt::AlignRight); + } addTopLevelItems( scale_items.values() ); } @@ -601,6 +727,14 @@ item->setTextAlignment( 2, Qt::AlignRight ); item->setTextAlignment( 3, Qt::AlignRight ); } + + // Priority (Id): add 1 to rule number and convert to string + std::ostringstream ioss; + ioss << i+1; + std::string ruleIdx = ioss.str(); + while( ruleIdx.size() < 4 ){ ruleIdx.insert( 0, " " );} + item->setText( 4, QString(ruleIdx.c_str()) ); + item->setTextAlignment (4, Qt::AlignRight); } addTopLevelItems( filter_items.values() ); --- /hometb/mk/sig/dev/r15676-backup/qgis/src/gui/symbology-ng/qgsrulebasedrendererv2widget.h 2011-04-07 00:51:05.991010106 +0200 +++ /hometb/mk/sig/dev/r15676-patched/qgis/src/gui/symbology-ng/qgsrulebasedrendererv2widget.h 2011-04-07 02:04:27.439939572 +0200 @@ -78,6 +78,8 @@ void addRule(); void editRule(); void removeRule(); + void increasePriority(); + void decreasePriority(); void setGrouping(); @@ -85,6 +87,15 @@ void refineRuleCategories(); void refineRuleRanges(); + void usingFirstRuleChanged( ); + void symbolLevelsEnabledChanged(); + void forceNoSymbolLevels(); + void forceUsingFirstRule(); + + signals: + + void forceChkUsingFirstRule(); + protected: void refineRule( int type ); --- /hometb/mk/sig/dev/r15676-backup/qgis/src/ui/qgsrulebasedrendererv2widget.ui 2011-04-07 00:51:22.070497346 +0200 +++ /hometb/mk/sig/dev/r15676-patched/qgis/src/ui/qgsrulebasedrendererv2widget.ui 2011-04-07 00:54:06.635249441 +0200 @@ -6,8 +6,8 @@ 0 0 - 622 - 273 + 640 + 401 @@ -16,6 +16,9 @@ + + + false @@ -51,6 +54,17 @@ AlignHCenter|AlignVCenter|AlignCenter + + + Priority + + + Priority when symbol levels are enabled (only first matching rule will be applied) + + + AlignHCenter|AlignVCenter|AlignCenter + + @@ -63,6 +77,20 @@ + + + Edit + + + + + + + Remove + + + + Refine @@ -70,31 +98,96 @@ - + - Edit + Increase priority - + - Remove + Decrease priority - + + + + + 0 + 35 + + + + + 0 + 0 + + + + + + + + + 113 + 10 + 231 + 24 + + + + Enable symbol levels + + + + + + 360 + 10 + 271 + 24 + + + + Use only first matched rule + + + + + + 10 + 10 + 84 + 24 + + + + Behavior + + + + + - Rule grouping + + + + Rule grouping + + + + - No grouping + None true @@ -104,14 +197,14 @@ - Group by filter + By filter - Group by scale + By scale