544 changes: 327 additions & 217 deletions src/core/symbology-ng/qgsrulebasedrendererv2.cpp

Large diffs are not rendered by default.

130 changes: 79 additions & 51 deletions src/core/symbology-ng/qgsrulebasedrendererv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,34 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
{
public:


// TODO: use QVarLengthArray instead of QList

// rendering job: a feature to be rendered with a particular symbol
// (both f, symbol are _not_ owned by this class)
struct RenderJob
{
RenderJob( QgsFeature* _f, QgsSymbolV2* _s ) : f( _f ), symbol( _s ) {}
QgsFeature* f;
QgsSymbolV2* symbol;
};

// render level: a list of jobs to be drawn at particular level
// (jobs are owned by this class)
struct RenderLevel
{
RenderLevel( int z ): zIndex( z ) {}
~RenderLevel() { foreach( RenderJob* j, jobs ) delete j; }
int zIndex;
QList<RenderJob*> jobs;
};

// rendering queue: a list of rendering levels
typedef QList<RenderLevel> RenderQueue;

class Rule;
typedef QList<Rule*> RuleList;

/**
This class keeps data about a rules for rule-based renderer.
A rule consists of a symbol, filter expression and range of scales.
Expand All @@ -47,29 +75,50 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
//! 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( const Rule& other );
//Rule( const Rule& other );
~Rule();
QString dump() const;
QStringList needsFields() const;
QSet<QString> usedAttributes();
QgsSymbolV2List symbols();
QgsLegendSymbolList legendSymbolItems();
bool isFilterOK( QgsFeature& f ) const;
bool isScaleOK( double scale ) const;

QgsSymbolV2* symbol() { return mSymbol; }
QString label() const { return mLabel; }
bool dependsOnScale() const { return mScaleMinDenom != 0 || mScaleMaxDenom != 0; }
int scaleMinDenom() const { return mScaleMinDenom; }
int scaleMaxDenom() const { return mScaleMaxDenom; }
QgsExpression* filter() const { return mFilter; }
QString filterExpression() const { return mFilterExp; }
QString label() const { return mLabel; }
QString description() const { return mDescription; }

void setLabel( QString label ) { mLabel = label; }
void setScaleMinDenom( int scaleMinDenom ) { mScaleMinDenom = scaleMinDenom; }
void setScaleMaxDenom( int scaleMaxDenom ) { mScaleMaxDenom = scaleMaxDenom; }
void setFilterExpression( QString filterExp ) { mFilterExp = filterExp; initFilter(); }
void setLabel( QString label ) { mLabel = label; }
void setDescription( QString description ) { mDescription = description; }

Rule& operator=( const Rule& other );
//Rule& operator=( const Rule& other );
//! clone this rule, return new instance
Rule* clone() const;

QDomElement save( QDomDocument& doc, QgsSymbolV2Map& symbolMap );

//! prepare the rule for rendering and its children (build active children array)
bool startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer );
//! get all used z-levels from this rule and children
QSet<int> collectZLevels();
//! assign normalized z-levels [0..N-1] for this rule's symbol for quick access during rendering
void setNormZLevels( const QMap<int, int>& zLevelsToNormLevels );

void renderFeature( QgsFeature* featPtr, QgsRenderContext& context, RenderQueue& renderQueue );

void stopRender( QgsRenderContext& context );

static Rule* create( QDomElement& ruleElem, QgsSymbolV2Map& symbolMap );

RuleList& children() { return mChildren; }

protected:

Expand All @@ -78,43 +127,24 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
QgsSymbolV2* mSymbol;
int mScaleMinDenom, mScaleMaxDenom;
QString mFilterExp, mLabel, mDescription;
bool mElseRule;
RuleList mChildren;

// temporary
QgsExpression* mFilter;
public: // TODO
QList<int> mSymbolNormZLevels; // normalized
};

// TODO: use QVarLengthArray instead of QList

// rendering job: a feature to be rendered with a particular symbol
struct RenderJob
{
RenderJob( QgsFeature* _f, QgsSymbolV2* _s ) : f( _f ), symbol( _s ) {}
QgsFeature* f;
QgsSymbolV2* symbol;
};

// render level: a list of jobs to be drawn at particular level
struct RenderLevel
{
RenderLevel( int z ): zIndex( z ) {}
int zIndex;
QList<RenderJob*> jobs;
};

// rendering queue: a list of rendering levels and jobs
struct RenderQueue
{
QList<RenderLevel> levels;
// temporary while rendering
QList<int> mSymbolNormZLevels;
RuleList mActiveChildren;
};

/////

static QgsFeatureRendererV2* create( QDomElement& element );

//! Constructor. Takes ownership of the default symbol.
QgsRuleBasedRendererV2( QgsSymbolV2* defaultSymbol );
//! Constructor. Adds default rule if the symbol is not null (and takes ownership of it)
QgsRuleBasedRendererV2( QgsSymbolV2* defaultSymbol = NULL );

~QgsRuleBasedRendererV2();

//! return symbol for current feature. Should not be used individually: there could be more symbols for a feature
virtual QgsSymbolV2* symbolForFeature( QgsFeature& feature );
Expand Down Expand Up @@ -146,43 +176,41 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2

/////

Rule* rootRule() { return mRootRule; }


//! return the total number of rules
int ruleCount();
//! get reference to rule at index (valid indexes: 0...count-1)
Rule& ruleAt( int index );
//! add rule to the end of the list of rules
void addRule( const Rule& rule );
//! insert rule to a specific position of the list of rules
void insertRule( int index, const Rule& rule );
//! modify the rule at a specific position of the list of rules
void updateRuleAt( int index, const Rule& rule );
Rule* ruleAt( int index );
//! add rule to the end of the list of rules. takes ownership
void addRule( Rule* rule );
//! insert rule to a specific position of the list of rules. takes ownership
void insertRule( int index, Rule* rule );
//! modify the rule at a specific position of the list of rules. takes ownership
void updateRuleAt( int index, 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 );


//////

//! take a rule and create a list of new rules based on the categories from categorized symbol renderer
static QList<Rule> refineRuleCategories( Rule& initialRule, QgsCategorizedSymbolRendererV2* r );
static RuleList refineRuleCategories( Rule* initialRule, QgsCategorizedSymbolRendererV2* r );
//! take a rule and create a list of new rules based on the ranges from graduated symbol renderer
static QList<Rule> refineRuleRanges( Rule& initialRule, QgsGraduatedSymbolRendererV2* r );
static RuleList refineRuleRanges( Rule* initialRule, QgsGraduatedSymbolRendererV2* r );
//! take a rule and create a list of new rules with intervals of scales given by the passed scale denominators
static QList<Rule> refineRuleScales( Rule& initialRule, QList<int> scales );
static RuleList refineRuleScales( Rule* initialRule, QList<int> scales );

protected:
//! the list of rules
QList<Rule> mRules;
//! the default symbol, used for the first rule with no filter
QgsSymbolV2* mDefaultSymbol;
//! the root node with hierarchical list of rules
Rule* mRootRule;

// temporary
QList<Rule*> mCurrentRules;
QgsSymbolV2* mCurrentSymbol;

RenderQueue mRenderQueue;
QList<QgsFeature*> mCurrentFeatures;
//QList<RenderJob*> mCurrentRenderJobs;
};

#endif // QGSRULEBASEDRENDERERV2_H
117 changes: 63 additions & 54 deletions src/gui/symbology-ng/qgsrulebasedrendererv2widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,16 +110,21 @@ void QgsRuleBasedRendererV2Widget::setGrouping()

void QgsRuleBasedRendererV2Widget::addRule()
{
QgsRuleBasedRendererV2::Rule newrule( QgsSymbolV2::defaultSymbol( mLayer->geometryType() ) );
QgsSymbolV2* s = QgsSymbolV2::defaultSymbol( mLayer->geometryType() );
QgsRuleBasedRendererV2::Rule* newrule = new QgsRuleBasedRendererV2::Rule( s );

QgsRendererRulePropsDialog dlg( newrule, mLayer, mStyle );
if ( dlg.exec() )
{
// add rule
dlg.updateRuleFromGui();
mRenderer->addRule( dlg.rule() );
mRenderer->addRule( newrule ); // takes ownership
treeRules->populateRules();
}
else
{
delete newrule;
}
}


Expand All @@ -136,17 +141,21 @@ void QgsRuleBasedRendererV2Widget::editRule()
QMessageBox::information( this, tr( "Edit rule" ), tr( "Groups of rules cannot be edited." ) );
return;
}
QgsRuleBasedRendererV2::Rule& rule = mRenderer->ruleAt( rule_index );
QgsRuleBasedRendererV2::Rule* rule = mRenderer->ruleAt( rule_index )->clone();

QgsRendererRulePropsDialog dlg( rule, mLayer, mStyle );
if ( dlg.exec() )
{
// update rule
dlg.updateRuleFromGui();
mRenderer->updateRuleAt( rule_index, dlg.rule() );
mRenderer->updateRuleAt( rule_index, rule );

treeRules->populateRules();
}
else
{
delete rule;
}
}

void QgsRuleBasedRendererV2Widget::removeRule()
Expand Down Expand Up @@ -245,10 +254,10 @@ void QgsRuleBasedRendererV2Widget::refineRule( int type )
if ( rule_index < 0 )
return;

QgsRuleBasedRendererV2::Rule& initialRule = mRenderer->ruleAt( rule_index );
QgsRuleBasedRendererV2::Rule* initialRule = mRenderer->ruleAt( rule_index );


QList<QgsRuleBasedRendererV2::Rule> refinedRules;
QgsRuleBasedRendererV2::RuleList refinedRules;
if ( type == 0 ) // categories
refinedRules = refineRuleCategoriesGui( initialRule );
else if ( type == 1 ) // ranges
Expand Down Expand Up @@ -286,7 +295,7 @@ void QgsRuleBasedRendererV2Widget::refineRuleScales()
refineRule( 2 );
}

QList<QgsRuleBasedRendererV2::Rule> QgsRuleBasedRendererV2Widget::refineRuleCategoriesGui( QgsRuleBasedRendererV2::Rule& initialRule )
QgsRuleBasedRendererV2::RuleList QgsRuleBasedRendererV2Widget::refineRuleCategoriesGui( QgsRuleBasedRendererV2::Rule* initialRule )
{
QDialog dlg;
dlg.setWindowTitle( tr( "Refine a rule to categories" ) );
Expand All @@ -300,15 +309,15 @@ QList<QgsRuleBasedRendererV2::Rule> QgsRuleBasedRendererV2Widget::refineRuleCate
dlg.setLayout( l );

if ( !dlg.exec() )
return QList<QgsRuleBasedRendererV2::Rule>();
return QgsRuleBasedRendererV2::RuleList();

// create new rules
QgsCategorizedSymbolRendererV2* r = static_cast<QgsCategorizedSymbolRendererV2*>( w->renderer() );
return QgsRuleBasedRendererV2::refineRuleCategories( initialRule, r );
}


QList<QgsRuleBasedRendererV2::Rule> QgsRuleBasedRendererV2Widget::refineRuleRangesGui( QgsRuleBasedRendererV2::Rule& initialRule )
QgsRuleBasedRendererV2::RuleList QgsRuleBasedRendererV2Widget::refineRuleRangesGui( QgsRuleBasedRendererV2::Rule* initialRule )
{
QDialog dlg;
dlg.setWindowTitle( tr( "Refine a rule to ranges" ) );
Expand All @@ -322,20 +331,20 @@ QList<QgsRuleBasedRendererV2::Rule> QgsRuleBasedRendererV2Widget::refineRuleRang
dlg.setLayout( l );

if ( !dlg.exec() )
return QList<QgsRuleBasedRendererV2::Rule>();
return QgsRuleBasedRendererV2::RuleList();

// create new rules
QgsGraduatedSymbolRendererV2* r = static_cast<QgsGraduatedSymbolRendererV2*>( w->renderer() );
return QgsRuleBasedRendererV2::refineRuleRanges( initialRule, r );
}

QList<QgsRuleBasedRendererV2::Rule> QgsRuleBasedRendererV2Widget::refineRuleScalesGui( QgsRuleBasedRendererV2::Rule& initialRule )
QgsRuleBasedRendererV2::RuleList QgsRuleBasedRendererV2Widget::refineRuleScalesGui( QgsRuleBasedRendererV2::Rule* initialRule )
{
QString txt = QInputDialog::getText( this,
tr( "Scale refinement" ),
tr( "Please enter scale denominators at which will split the rule, separate them by commas (e.g. 1000,5000):" ) );
if ( txt.isEmpty() )
return QList<QgsRuleBasedRendererV2::Rule>();
return QgsRuleBasedRendererV2::RuleList();

QList<int> scales;
bool ok;
Expand Down Expand Up @@ -367,7 +376,7 @@ QList<QgsSymbolV2*> QgsRuleBasedRendererV2Widget::selectedSymbols()
int priority = ( *it )->data( 0, Qt::UserRole + 1 ).toInt();
if ( priority < mRenderer->ruleCount() )
{
symbolList.append( mRenderer->ruleAt( priority ).symbol() );
symbolList.append( mRenderer->ruleAt( priority )->symbol() );
}
}

Expand All @@ -385,23 +394,23 @@ void QgsRuleBasedRendererV2Widget::refreshSymbolView()

///////////

QgsRendererRulePropsDialog::QgsRendererRulePropsDialog( const QgsRuleBasedRendererV2::Rule& rule, QgsVectorLayer* layer, QgsStyleV2* style )
QgsRendererRulePropsDialog::QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style )
: mRule( rule ), mLayer( layer )
{
setupUi( this );

editFilter->setText( mRule.filterExpression() );
editLabel->setText( mRule.label() );
editDescription->setText( mRule.description() );
editFilter->setText( mRule->filterExpression() );
editLabel->setText( mRule->label() );
editDescription->setText( mRule->description() );

if ( mRule.dependsOnScale() )
if ( mRule->dependsOnScale() )
{
groupScale->setChecked( true );
spinMinScale->setValue( rule.scaleMinDenom() );
spinMaxScale->setValue( rule.scaleMaxDenom() );
spinMinScale->setValue( rule->scaleMinDenom() );
spinMaxScale->setValue( rule->scaleMaxDenom() );
}

QgsSymbolV2SelectorDialog* symbolSel = new QgsSymbolV2SelectorDialog( mRule.symbol(), style, mLayer, this, true );
QgsSymbolV2SelectorDialog* symbolSel = new QgsSymbolV2SelectorDialog( mRule->symbol(), style, mLayer, this, true );
QVBoxLayout* l = new QVBoxLayout;
l->addWidget( symbolSel );
groupSymbol->setLayout( l );
Expand Down Expand Up @@ -458,11 +467,11 @@ void QgsRendererRulePropsDialog::testFilter()

void QgsRendererRulePropsDialog::updateRuleFromGui()
{
mRule.setFilterExpression( editFilter->text() );
mRule.setLabel( editLabel->text() );
mRule.setDescription( editDescription->text() );
mRule.setScaleMinDenom( groupScale->isChecked() ? spinMinScale->value() : 0 );
mRule.setScaleMaxDenom( groupScale->isChecked() ? spinMaxScale->value() : 0 );
mRule->setFilterExpression( editFilter->text() );
mRule->setLabel( editLabel->text() );
mRule->setDescription( editDescription->text() );
mRule->setScaleMinDenom( groupScale->isChecked() ? spinMinScale->value() : 0 );
mRule->setScaleMaxDenom( groupScale->isChecked() ? spinMaxScale->value() : 0 );
}

////////
Expand Down Expand Up @@ -530,10 +539,10 @@ void QgsRendererRulesTreeWidget::populateRules()
// TODO: use a custom model and implement custom sorting
for ( int i = 0; i < mR->ruleCount(); ++i )
{
QgsRuleBasedRendererV2::Rule& rule = mR->ruleAt( i );
QgsRuleBasedRendererV2::Rule* rule = mR->ruleAt( i );

mLongestMinDenom = qMax( mLongestMinDenom, formatScale( rule.scaleMinDenom() ).size() );
mLongestMaxDenom = qMax( mLongestMaxDenom, formatScale( rule.scaleMaxDenom() ).size() );
mLongestMinDenom = qMax( mLongestMinDenom, formatScale( rule->scaleMinDenom() ).size() );
mLongestMaxDenom = qMax( mLongestMaxDenom, formatScale( rule->scaleMaxDenom() ).size() );
}


Expand All @@ -554,24 +563,24 @@ void QgsRendererRulesTreeWidget::populateRulesNoGrouping()

for ( int i = 0; i < mR->ruleCount(); ++i )
{
QgsRuleBasedRendererV2::Rule& rule = mR->ruleAt( i );
QgsRuleBasedRendererV2::Rule* rule = mR->ruleAt( i );

QTreeWidgetItem* item = new QTreeWidgetItem;

QString txtLabel = rule.label();
QString txtLabel = rule->label();
item->setText( 0, txtLabel );
item->setData( 0, Qt::UserRole + 1, i );
item->setIcon( 0, QgsSymbolLayerV2Utils::symbolPreviewIcon( rule.symbol(), QSize( 16, 16 ) ) );
item->setIcon( 0, QgsSymbolLayerV2Utils::symbolPreviewIcon( rule->symbol(), QSize( 16, 16 ) ) );

QString txtRule = rule.filterExpression();
QString txtRule = rule->filterExpression();
if ( txtRule.isEmpty() )
txtRule = tr( "(no filter)" );
item->setText( 1, txtRule );

if ( rule.dependsOnScale() )
if ( rule->dependsOnScale() )
{
item->setText( 2, formatScale( rule.scaleMinDenom(), mLongestMinDenom ) );
item->setText( 3, formatScale( rule.scaleMaxDenom(), mLongestMaxDenom ) );
item->setText( 2, formatScale( rule->scaleMinDenom(), mLongestMinDenom ) );
item->setText( 3, formatScale( rule->scaleMaxDenom(), mLongestMaxDenom ) );
item->setTextAlignment( 2, Qt::AlignRight );
item->setTextAlignment( 3, Qt::AlignRight );
}
Expand All @@ -598,14 +607,14 @@ void QgsRendererRulesTreeWidget::populateRulesGroupByScale()

for ( int i = 0; i < mR->ruleCount(); ++i )
{
QgsRuleBasedRendererV2::Rule& rule = mR->ruleAt( i );
QgsRuleBasedRendererV2::Rule* rule = mR->ruleAt( i );

QPair<int, int> scale = qMakePair( rule.scaleMinDenom(), rule.scaleMaxDenom() );
QPair<int, int> scale = qMakePair( rule->scaleMinDenom(), rule->scaleMaxDenom() );
if ( ! scale_items.contains( scale ) )
{
QString txt;
if ( rule.dependsOnScale() )
txt = tr( "scale " ) + formatScaleRange( rule.scaleMinDenom(), rule.scaleMaxDenom() );
if ( rule->dependsOnScale() )
txt = tr( "scale " ) + formatScaleRange( rule->scaleMinDenom(), rule->scaleMaxDenom() );
else
txt = tr( "any scale" );

Expand All @@ -621,25 +630,25 @@ void QgsRendererRulesTreeWidget::populateRulesGroupByScale()
scale_item->setFirstColumnSpanned( true );
}

QString filter = rule.filterExpression();
QString filter = rule->filterExpression();

QTreeWidgetItem* item = new QTreeWidgetItem( scale_items[scale] );

QString txtLabel = rule.label();
QString txtLabel = rule->label();
item->setText( 0, txtLabel );
item->setData( 0, Qt::UserRole + 1, i );
item->setIcon( 0, QgsSymbolLayerV2Utils::symbolPreviewIcon( rule.symbol(), QSize( 16, 16 ) ) );
item->setIcon( 0, QgsSymbolLayerV2Utils::symbolPreviewIcon( rule->symbol(), QSize( 16, 16 ) ) );

QString txtRule = rule.filterExpression();
QString txtRule = rule->filterExpression();
if ( txtRule.isEmpty() )
txtRule = tr( "(no filter)" );
item->setText( 1, txtRule );

if ( rule.dependsOnScale() )
if ( rule->dependsOnScale() )
{
// Displaying scales is redundant here, but keeping them allows to keep constant the layout and width of all columns when switching to one of the two other views
item->setText( 2, formatScale( rule.scaleMinDenom(), mLongestMinDenom ) );
item->setText( 3, formatScale( rule.scaleMaxDenom(), mLongestMaxDenom ) );
item->setText( 2, formatScale( rule->scaleMinDenom(), mLongestMinDenom ) );
item->setText( 3, formatScale( rule->scaleMaxDenom(), mLongestMaxDenom ) );
item->setTextAlignment( 2, Qt::AlignRight );
item->setTextAlignment( 3, Qt::AlignRight );
}
Expand All @@ -664,9 +673,9 @@ void QgsRendererRulesTreeWidget::populateRulesGroupByFilter()

for ( int i = 0; i < mR->ruleCount(); ++i )
{
QgsRuleBasedRendererV2::Rule& rule = mR->ruleAt( i );
QgsRuleBasedRendererV2::Rule* rule = mR->ruleAt( i );

QString filter = rule.filterExpression();
QString filter = rule->filterExpression();
if ( ! filter_items.contains( filter ) )
{
QTreeWidgetItem* filter_item = new QTreeWidgetItem;
Expand All @@ -683,10 +692,10 @@ void QgsRendererRulesTreeWidget::populateRulesGroupByFilter()

QTreeWidgetItem* item = new QTreeWidgetItem( filter_items[filter] );

QString txtLabel = rule.label();
QString txtLabel = rule->label();
item->setText( 0, txtLabel );
item->setData( 0, Qt::UserRole + 1, i );
item->setIcon( 0, QgsSymbolLayerV2Utils::symbolPreviewIcon( rule.symbol(), QSize( 16, 16 ) ) );
item->setIcon( 0, QgsSymbolLayerV2Utils::symbolPreviewIcon( rule->symbol(), QSize( 16, 16 ) ) );

// Displaying filter is redundant here, but keeping it allows to keep constant the layout and width of all columns when switching to one of the two other views
item->setText( 1, filter );
Expand All @@ -695,10 +704,10 @@ void QgsRendererRulesTreeWidget::populateRulesGroupByFilter()
//item->setBackground( 1, Qt::lightGray );
//item->setBackground( 3, Qt::lightGray );

if ( rule.dependsOnScale() )
if ( rule->dependsOnScale() )
{
item->setText( 2, formatScale( rule.scaleMinDenom(), mLongestMinDenom ) );
item->setText( 3, formatScale( rule.scaleMaxDenom(), mLongestMaxDenom ) );
item->setText( 2, formatScale( rule->scaleMinDenom(), mLongestMinDenom ) );
item->setText( 3, formatScale( rule->scaleMaxDenom(), mLongestMaxDenom ) );
item->setTextAlignment( 2, Qt::AlignRight );
item->setTextAlignment( 3, Qt::AlignRight );
}
Expand Down
12 changes: 6 additions & 6 deletions src/gui/symbology-ng/qgsrulebasedrendererv2widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ class GUI_EXPORT QgsRuleBasedRendererV2Widget : public QgsRendererV2Widget, priv
protected:

void refineRule( int type );
QList<QgsRuleBasedRendererV2::Rule> refineRuleCategoriesGui( QgsRuleBasedRendererV2::Rule& initialRule );
QList<QgsRuleBasedRendererV2::Rule> refineRuleRangesGui( QgsRuleBasedRendererV2::Rule& initialRule );
QList<QgsRuleBasedRendererV2::Rule> refineRuleScalesGui( QgsRuleBasedRendererV2::Rule& initialRule );
QgsRuleBasedRendererV2::RuleList refineRuleCategoriesGui( QgsRuleBasedRendererV2::Rule* initialRule );
QgsRuleBasedRendererV2::RuleList refineRuleRangesGui( QgsRuleBasedRendererV2::Rule* initialRule );
QgsRuleBasedRendererV2::RuleList refineRuleScalesGui( QgsRuleBasedRendererV2::Rule* initialRule );

QList<QgsSymbolV2*> selectedSymbols();
void refreshSymbolView();
Expand All @@ -113,17 +113,17 @@ class GUI_EXPORT QgsRendererRulePropsDialog : public QDialog, private Ui::QgsRen
Q_OBJECT

public:
QgsRendererRulePropsDialog( const QgsRuleBasedRendererV2::Rule& rule, QgsVectorLayer* layer, QgsStyleV2* style );
QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style );

void updateRuleFromGui();
const QgsRuleBasedRendererV2::Rule& rule() { return mRule; }
QgsRuleBasedRendererV2::Rule* rule() { return mRule; }

public slots:
void testFilter();
void buildExpression();

protected:
QgsRuleBasedRendererV2::Rule mRule;
QgsRuleBasedRendererV2::Rule* mRule; // borrowed
QgsVectorLayer* mLayer;
QgsStyleV2* mStyle;
};
Expand Down