Drag'n'drop for rules, rule does not need a symbol

This commit is contained in:
Martin Dobias 2012-01-23 20:59:28 +01:00
parent 245e76daa4
commit 0c5e591a86
6 changed files with 273 additions and 142 deletions

View File

@ -106,6 +106,12 @@ QgsSymbolV2List QgsRuleBasedRendererV2::Rule::symbols()
return lst;
}
void QgsRuleBasedRendererV2::Rule::setSymbol( QgsSymbolV2* sym )
{
delete mSymbol;
mSymbol = sym;
}
QgsLegendSymbolList QgsRuleBasedRendererV2::Rule::legendSymbolItems()
{
QgsLegendSymbolList lst;
@ -534,18 +540,11 @@ QgsFeatureRendererV2* QgsRuleBasedRendererV2::create( QDomElement& element )
void QgsRuleBasedRendererV2::refineRuleCategories( QgsRuleBasedRendererV2::Rule* initialRule, QgsCategorizedSymbolRendererV2* r )
{
RuleList rules;
foreach( const QgsRendererCategoryV2& cat, r->categories() )
{
QString newfilter = QString( "%1 = '%2'" ).arg( r->classAttribute() ).arg( cat.value().toString() );
QString filter = initialRule->filterExpression();
QString label = initialRule->label();
QString description = initialRule->description();
if ( filter.isEmpty() )
filter = newfilter;
else
filter = QString( "(%1) AND (%2)" ).arg( filter ).arg( newfilter );
initialRule->appendChild( new Rule( cat.symbol()->clone(), initialRule->scaleMinDenom(), initialRule->scaleMaxDenom(), filter, label, description ) );
QString filter = QString( "%1 = '%2'" ).arg( r->classAttribute() ).arg( cat.value().toString() );
QString label = filter;
initialRule->appendChild( new Rule( cat.symbol()->clone(), 0, 0, filter, label ) );
}
}
@ -553,15 +552,9 @@ void QgsRuleBasedRendererV2::refineRuleRanges( QgsRuleBasedRendererV2::Rule* ini
{
foreach( const QgsRendererRangeV2& rng, r->ranges() )
{
QString newfilter = QString( "%1 >= '%2' AND %1 <= '%3'" ).arg( r->classAttribute() ).arg( rng.lowerValue() ).arg( rng.upperValue() );
QString filter = initialRule->filterExpression();
QString label = initialRule->label();
QString description = initialRule->description();
if ( filter.isEmpty() )
filter = newfilter;
else
filter = QString( "(%1) AND (%2)" ).arg( filter ).arg( newfilter );
initialRule->appendChild( new Rule( rng.symbol()->clone(), initialRule->scaleMinDenom(), initialRule->scaleMaxDenom(), filter, label, description ) );
QString filter = QString( "%1 >= '%2' AND %1 <= '%3'" ).arg( r->classAttribute() ).arg( rng.lowerValue() ).arg( rng.upperValue() );
QString label = filter;
initialRule->appendChild( new Rule( rng.symbol()->clone(), 0, 0, filter, label ) );
}
}
@ -570,9 +563,6 @@ void QgsRuleBasedRendererV2::refineRuleScales( QgsRuleBasedRendererV2::Rule* ini
qSort( scales ); // make sure the scales are in ascending order
int oldScale = initialRule->scaleMinDenom();
int maxDenom = initialRule->scaleMaxDenom();
QString filter = initialRule->filterExpression();
QString label = initialRule->label();
QString description = initialRule->description();
QgsSymbolV2* symbol = initialRule->symbol();
foreach( int scale, scales )
{
@ -580,11 +570,11 @@ void QgsRuleBasedRendererV2::refineRuleScales( QgsRuleBasedRendererV2::Rule* ini
continue; // jump over the first scales out of the interval
if ( maxDenom != 0 && maxDenom <= scale )
break; // ignore the latter scales out of the interval
initialRule->appendChild( new Rule( symbol->clone(), oldScale, scale, filter, label, description ) );
initialRule->appendChild( new Rule( symbol->clone(), oldScale, scale, QString(), QString( "%1 - %2" ).arg( oldScale ).arg( scale ) ) );
oldScale = scale;
}
// last rule
initialRule->appendChild( new Rule( symbol->clone(), oldScale, maxDenom, filter, label, description ) );
initialRule->appendChild( new Rule( symbol->clone(), oldScale, maxDenom, QString(), QString( "%1 - %2" ).arg( oldScale ).arg( maxDenom ) ) );
}
QString QgsRuleBasedRendererV2::dump()

View File

@ -93,6 +93,8 @@ class CORE_EXPORT QgsRuleBasedRendererV2 : public QgsFeatureRendererV2
QString filterExpression() const { return mFilterExp; }
QString description() const { return mDescription; }
//! set a new symbol (or NULL). Deletes old symbol.
void setSymbol( QgsSymbolV2* sym );
void setLabel( QString label ) { mLabel = label; }
void setScaleMinDenom( int scaleMinDenom ) { mScaleMinDenom = scaleMinDenom; }
void setScaleMaxDenom( int scaleMaxDenom ) { mScaleMaxDenom = scaleMaxDenom; }

View File

@ -70,8 +70,6 @@ QgsRuleBasedRendererV2Widget::QgsRuleBasedRendererV2Widget( QgsVectorLayer* laye
btnAddRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyAdd.png" ) ) );
btnEditRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyEdit.png" ) ) );
btnRemoveRule->setIcon( QIcon( QgsApplication::iconPath( "symbologyRemove.png" ) ) );
btnMoveUp->setIcon( QIcon( QgsApplication::iconPath( "symbologyUp.png" ) ) );
btnMoveDown->setIcon( QIcon( QgsApplication::iconPath( "symbologyDown.png" ) ) );
connect( viewRules, SIGNAL( doubleClicked( const QModelIndex & ) ), this, SLOT( editRule( const QModelIndex & ) ) );
@ -81,8 +79,6 @@ QgsRuleBasedRendererV2Widget::QgsRuleBasedRendererV2Widget( QgsVectorLayer* laye
connect( btnAddRule, SIGNAL( clicked() ), this, SLOT( addRule() ) );
connect( btnEditRule, SIGNAL( clicked() ), this, SLOT( editRule() ) );
connect( btnRemoveRule, SIGNAL( clicked() ), this, SLOT( removeRule() ) );
connect( btnMoveUp, SIGNAL( clicked() ), this, SLOT( moveUp() ) );
connect( btnMoveDown, SIGNAL( clicked() ), this, SLOT( moveDown() ) );
connect( btnRenderingOrder, SIGNAL( clicked() ), this, SLOT( setRenderingOrder() ) );
}
@ -105,8 +101,6 @@ void QgsRuleBasedRendererV2Widget::addRule()
QgsRendererRulePropsDialog dlg( newrule, mLayer, mStyle );
if ( dlg.exec() )
{
dlg.updateRuleFromGui();
QgsRuleBasedRendererV2::Rule* current = currentRule();
if ( current )
{
@ -133,7 +127,7 @@ QgsRuleBasedRendererV2::Rule* QgsRuleBasedRendererV2Widget::currentRule()
QModelIndex idx = sel->currentIndex();
if ( !idx.isValid() )
return NULL;
return static_cast<QgsRuleBasedRendererV2::Rule*>( idx.internalPointer() );
return mModel->ruleForIndex( idx );
}
void QgsRuleBasedRendererV2Widget::editRule()
@ -145,43 +139,27 @@ void QgsRuleBasedRendererV2Widget::editRule( const QModelIndex& index )
{
if ( !index.isValid() )
return;
QgsRuleBasedRendererV2::Rule* rule = static_cast<QgsRuleBasedRendererV2::Rule*>( index.internalPointer() );
QgsRuleBasedRendererV2::Rule* rule = mModel->ruleForIndex( index );
QgsRendererRulePropsDialog dlg( rule, mLayer, mStyle );
if ( dlg.exec() )
{
// update rule
dlg.updateRuleFromGui();
// model should know about the change and emit dataChanged signal for the view
mModel->updateRule( index );
mModel->updateRule( index.parent(), index.row() );
}
}
void QgsRuleBasedRendererV2Widget::removeRule()
{
QModelIndex index = viewRules->selectionModel()->currentIndex();
if ( !index.isValid() )
return;
mModel->removeRule( index );
QItemSelection sel = viewRules->selectionModel()->selection();
foreach( QItemSelectionRange range, sel )
{
if ( range.isValid() )
mModel->removeRows( range.top(), range.bottom() - range.top() + 1, range.parent() );
}
}
void QgsRuleBasedRendererV2Widget::moveUp()
{
// TODO: solve directly by drag'n'drop
}
void QgsRuleBasedRendererV2Widget::moveDown()
{
// TODO: solve directly by drag'n'drop
}
#include "qgscategorizedsymbolrendererv2.h"
#include "qgscategorizedsymbolrendererv2widget.h"
#include "qgsgraduatedsymbolrendererv2.h"
@ -196,19 +174,18 @@ void QgsRuleBasedRendererV2Widget::refineRule( int type )
if ( !index.isValid() )
return;
QgsRuleBasedRendererV2::Rule* initialRule = static_cast<QgsRuleBasedRendererV2::Rule*>( index.internalPointer() );
if ( type == 0 ) // categories
refineRuleCategoriesGui( initialRule );
refineRuleCategoriesGui( index );
else if ( type == 1 ) // ranges
refineRuleRangesGui( initialRule );
refineRuleRangesGui( index );
else // scales
refineRuleScalesGui( initialRule );
refineRuleScalesGui( index );
// TODO: set initial rule's symbol to NULL (?)
// TODO: let model know things have changed
mModel->updateRule( index );
// update model
//mModel->updateRule( index.parent(), index.row() );
}
void QgsRuleBasedRendererV2Widget::refineRuleCategories()
@ -226,8 +203,10 @@ void QgsRuleBasedRendererV2Widget::refineRuleScales()
refineRule( 2 );
}
void QgsRuleBasedRendererV2Widget::refineRuleCategoriesGui( QgsRuleBasedRendererV2::Rule* initialRule )
void QgsRuleBasedRendererV2Widget::refineRuleCategoriesGui( const QModelIndex& index )
{
QgsRuleBasedRendererV2::Rule* initialRule = mModel->ruleForIndex( index );
QDialog dlg;
dlg.setWindowTitle( tr( "Refine a rule to categories" ) );
QVBoxLayout* l = new QVBoxLayout();
@ -244,12 +223,16 @@ void QgsRuleBasedRendererV2Widget::refineRuleCategoriesGui( QgsRuleBasedRenderer
// create new rules
QgsCategorizedSymbolRendererV2* r = static_cast<QgsCategorizedSymbolRendererV2*>( w->renderer() );
mModel->willAddRules( index, r->categories().count() );
QgsRuleBasedRendererV2::refineRuleCategories( initialRule, r );
mModel->finishedAddingRules();
}
void QgsRuleBasedRendererV2Widget::refineRuleRangesGui( QgsRuleBasedRendererV2::Rule* initialRule )
void QgsRuleBasedRendererV2Widget::refineRuleRangesGui( const QModelIndex& index )
{
QgsRuleBasedRendererV2::Rule* initialRule = mModel->ruleForIndex( index );
QDialog dlg;
dlg.setWindowTitle( tr( "Refine a rule to ranges" ) );
QVBoxLayout* l = new QVBoxLayout();
@ -266,11 +249,22 @@ void QgsRuleBasedRendererV2Widget::refineRuleRangesGui( QgsRuleBasedRendererV2::
// create new rules
QgsGraduatedSymbolRendererV2* r = static_cast<QgsGraduatedSymbolRendererV2*>( w->renderer() );
mModel->willAddRules( index, r->ranges().count() );
QgsRuleBasedRendererV2::refineRuleRanges( initialRule, r );
mModel->finishedAddingRules();
}
void QgsRuleBasedRendererV2Widget::refineRuleScalesGui( QgsRuleBasedRendererV2::Rule* initialRule )
void QgsRuleBasedRendererV2Widget::refineRuleScalesGui( const QModelIndex& index )
{
QgsRuleBasedRendererV2::Rule* initialRule = mModel->ruleForIndex( index );
if ( initialRule->symbol() == NULL )
{
QMessageBox::warning( this, tr( "Scale refinement" ), tr( "Parent rule must have a symbol for this operation." ) );
return;
}
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):" ) );
@ -288,7 +282,9 @@ void QgsRuleBasedRendererV2Widget::refineRuleScalesGui( QgsRuleBasedRendererV2::
QMessageBox::information( this, tr( "Error" ), QString( tr( "\"%1\" is not valid scale denominator, ignoring it." ) ).arg( item ) );
}
mModel->willAddRules( index, scales.count() + 1 );
QgsRuleBasedRendererV2::refineRuleScales( initialRule, scales );
mModel->finishedAddingRules();
}
QList<QgsSymbolV2*> QgsRuleBasedRendererV2Widget::selectedSymbols()
@ -304,8 +300,7 @@ QList<QgsSymbolV2*> QgsRuleBasedRendererV2Widget::selectedSymbols()
foreach( QItemSelectionRange range, sel )
{
QModelIndex parent = range.parent();
QgsRuleBasedRendererV2::Rule* parentRule = !parent.isValid() ? mRenderer->rootRule() :
static_cast<QgsRuleBasedRendererV2::Rule*>( parent.internalPointer() );
QgsRuleBasedRendererV2::Rule* parentRule = mModel->ruleForIndex( parent );
QgsRuleBasedRendererV2::RuleList& children = parentRule->children();
for ( int row = range.top(); row <= range.bottom(); row++ )
{
@ -341,10 +336,13 @@ void QgsRuleBasedRendererV2Widget::setRenderingOrder()
///////////
QgsRendererRulePropsDialog::QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style )
: mRule( rule ), mLayer( layer )
: mRule( rule ), mLayer( layer ), mSymbolSelector( NULL ), mSymbol( NULL )
{
setupUi( this );
connect( buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) );
connect( buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
editFilter->setText( mRule->filterExpression() );
editLabel->setText( mRule->label() );
editDescription->setText( mRule->description() );
@ -356,15 +354,31 @@ QgsRendererRulePropsDialog::QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::
spinMaxScale->setValue( rule->scaleMaxDenom() );
}
QgsSymbolV2SelectorDialog* symbolSel = new QgsSymbolV2SelectorDialog( mRule->symbol(), style, mLayer, this, true );
if ( mRule->symbol() )
{
groupSymbol->setChecked( true );
mSymbol = mRule->symbol()->clone(); // use a clone!
}
else
{
groupSymbol->setChecked( false );
mSymbol = QgsSymbolV2::defaultSymbol( mLayer->geometryType() );
}
mSymbolSelector = new QgsSymbolV2SelectorDialog( mSymbol, style, mLayer, this, true );
QVBoxLayout* l = new QVBoxLayout;
l->addWidget( symbolSel );
l->addWidget( mSymbolSelector );
groupSymbol->setLayout( l );
connect( btnExpressionBuilder, SIGNAL( clicked() ), this, SLOT( buildExpression() ) );
connect( btnTestFilter, SIGNAL( clicked() ), this, SLOT( testFilter() ) );
}
QgsRendererRulePropsDialog::~QgsRendererRulePropsDialog()
{
delete mSymbol;
}
void QgsRendererRulePropsDialog::buildExpression()
{
QgsSearchQueryBuilder dlg( mLayer, this );
@ -411,13 +425,16 @@ void QgsRendererRulePropsDialog::testFilter()
QMessageBox::information( this, tr( "Filter" ), tr( "Filter returned %n feature(s)", "number of filtered features", count ) );
}
void QgsRendererRulePropsDialog::updateRuleFromGui()
void QgsRendererRulePropsDialog::accept()
{
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->setSymbol( groupSymbol->isChecked() ? mSymbol->clone() : NULL );
QDialog::accept();
}
////////
@ -450,9 +467,11 @@ QgsRuleBasedRendererV2Model::QgsRuleBasedRendererV2Model( QgsRuleBasedRendererV2
Qt::ItemFlags QgsRuleBasedRendererV2Model::flags( const QModelIndex &index ) const
{
if ( !index.isValid() )
return 0;
return Qt::ItemIsDropEnabled;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable |
Qt::ItemIsEditable |
Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
}
QVariant QgsRuleBasedRendererV2Model::data( const QModelIndex &index, int role ) const
@ -460,7 +479,7 @@ QVariant QgsRuleBasedRendererV2Model::data( const QModelIndex &index, int role )
if ( !index.isValid() )
return QVariant();
QgsRuleBasedRendererV2::Rule* rule = static_cast<QgsRuleBasedRendererV2::Rule*>( index.internalPointer() );
QgsRuleBasedRendererV2::Rule* rule = ruleForIndex( index );
if ( role == Qt::DisplayRole )
{
@ -509,14 +528,10 @@ QVariant QgsRuleBasedRendererV2Model::headerData( int section, Qt::Orientation o
int QgsRuleBasedRendererV2Model::rowCount( const QModelIndex &parent ) const
{
QgsRuleBasedRendererV2::Rule* parentRule;
if ( parent.column() > 0 )
return 0;
if ( !parent.isValid() )
parentRule = mR->rootRule();
else
parentRule = static_cast<QgsRuleBasedRendererV2::Rule*>( parent.internalPointer() );
QgsRuleBasedRendererV2::Rule* parentRule = ruleForIndex( parent );
return parentRule->children().count();
}
@ -531,12 +546,7 @@ QModelIndex QgsRuleBasedRendererV2Model::index( int row, int column, const QMode
if ( !hasIndex( row, column, parent ) )
return QModelIndex();
QgsRuleBasedRendererV2::Rule* parentRule;
if ( !parent.isValid() )
parentRule = mR->rootRule();
else
parentRule = static_cast<QgsRuleBasedRendererV2::Rule*>( parent.internalPointer() );
QgsRuleBasedRendererV2::Rule* parentRule = ruleForIndex( parent );
QgsRuleBasedRendererV2::Rule* childRule = parentRule->children()[row];
if ( childRule )
@ -550,7 +560,7 @@ QModelIndex QgsRuleBasedRendererV2Model::parent( const QModelIndex &index ) cons
if ( !index.isValid() )
return QModelIndex();
QgsRuleBasedRendererV2::Rule* childRule = static_cast<QgsRuleBasedRendererV2::Rule*>( index.internalPointer() );
QgsRuleBasedRendererV2::Rule* childRule = ruleForIndex( index );
QgsRuleBasedRendererV2::Rule* parentRule = childRule->parent();
if ( parentRule == mR->rootRule() )
@ -566,7 +576,7 @@ bool QgsRuleBasedRendererV2Model::setData( const QModelIndex & index, const QVar
if ( !index.isValid() || role != Qt::EditRole )
return false;
QgsRuleBasedRendererV2::Rule* rule = static_cast<QgsRuleBasedRendererV2::Rule*>( index.internalPointer() );
QgsRuleBasedRendererV2::Rule* rule = ruleForIndex( index );
switch ( index.column() )
{
@ -590,29 +600,164 @@ bool QgsRuleBasedRendererV2Model::setData( const QModelIndex & index, const QVar
return true;
}
Qt::DropActions QgsRuleBasedRendererV2Model::supportedDropActions() const
{
return Qt::MoveAction; // | Qt::CopyAction
}
QStringList QgsRuleBasedRendererV2Model::mimeTypes() const
{
QStringList types;
types << "application/vnd.text.list";
return types;
}
QMimeData *QgsRuleBasedRendererV2Model::mimeData( const QModelIndexList &indexes ) const
{
QMimeData *mimeData = new QMimeData();
QByteArray encodedData;
QDataStream stream( &encodedData, QIODevice::WriteOnly );
foreach( const QModelIndex &index, indexes )
{
// each item consists of several columns - let's add it with just first one
if ( !index.isValid() || index.column() != 0 )
continue;
QgsRuleBasedRendererV2::Rule* rule = ruleForIndex( index );
QDomDocument doc;
QgsSymbolV2Map symbols;
QDomElement rootElem = doc.createElement( "rule_mime" );
QDomElement rulesElem = rule->save( doc, symbols );
rootElem.appendChild( rulesElem );
QDomElement symbolsElem = QgsSymbolLayerV2Utils::saveSymbols( symbols, "symbols", doc );
rootElem.appendChild( symbolsElem );
doc.appendChild( rootElem );
stream << doc.toString( -1 );
}
mimeData->setData( "application/vnd.text.list", encodedData );
return mimeData;
}
bool QgsRuleBasedRendererV2Model::dropMimeData( const QMimeData *data,
Qt::DropAction action, int row, int column, const QModelIndex &parent )
{
if ( action == Qt::IgnoreAction )
return true;
if ( !data->hasFormat( "application/vnd.text.list" ) )
return false;
if ( column > 0 )
return false;
QByteArray encodedData = data->data( "application/vnd.text.list" );
QDataStream stream( &encodedData, QIODevice::ReadOnly );
int rows = 0;
if ( row == -1 )
{
// the item was dropped at a parent - we may decide where to put the items - let's append them
row = rowCount( parent );
}
while ( !stream.atEnd() )
{
QString text;
stream >> text;
QDomDocument doc;
if ( !doc.setContent( text ) )
continue;
QDomElement rootElem = doc.documentElement();
if ( rootElem.tagName() != "rule_mime" )
continue;
QDomElement symbolsElem = rootElem.firstChildElement( "symbols" );
if ( symbolsElem.isNull() )
continue;
QgsSymbolV2Map symbolMap = QgsSymbolLayerV2Utils::loadSymbols( symbolsElem );
QDomElement ruleElem = rootElem.firstChildElement( "rule" );
QgsRuleBasedRendererV2::Rule* rule = QgsRuleBasedRendererV2::Rule::create( ruleElem, symbolMap );
insertRule( parent, row + rows, rule );
++rows;
}
return true;
}
QgsRuleBasedRendererV2::Rule* QgsRuleBasedRendererV2Model::ruleForIndex( const QModelIndex& index ) const
{
if ( index.isValid() )
return static_cast<QgsRuleBasedRendererV2::Rule*>( index.internalPointer() );
return mR->rootRule();
}
bool QgsRuleBasedRendererV2Model::removeRows( int row, int count, const QModelIndex & parent )
{
QgsRuleBasedRendererV2::Rule* parentRule = ruleForIndex( parent );
if ( row < 0 || row >= parentRule->children().count() )
return false;
QgsDebugMsg( QString( "Called: row %1 count %2 parent ~~%3~~" ).arg( row ).arg( count ).arg( parentRule->dump() ) );
emit beginRemoveRows( parent, row, row + count - 1 );
for ( int i = 0; i < count; i++ )
{
QgsRuleBasedRendererV2::Rule* r = parentRule->children()[row];
parentRule->removeChild( r );
}
emit endRemoveRows();
return true;
}
void QgsRuleBasedRendererV2Model::insertRule( const QModelIndex& parent, int before, QgsRuleBasedRendererV2::Rule* newrule )
{
beginInsertRows( parent, before, before );
QgsRuleBasedRendererV2::Rule* parentRule = parent.isValid() ?
static_cast<QgsRuleBasedRendererV2::Rule*>( parent.internalPointer() ) : mR->rootRule();
QgsDebugMsg( QString( "insert before %1 rule: %2" ).arg( before ).arg( newrule->dump() ) );
QgsRuleBasedRendererV2::Rule* parentRule = ruleForIndex( parent );
parentRule->insertChild( before, newrule );
endInsertRows();
}
void QgsRuleBasedRendererV2Model::updateRule( const QModelIndex& index )
void QgsRuleBasedRendererV2Model::updateRule( const QModelIndex& parent, int row )
{
emit dataChanged( index, index );
emit dataChanged( index( row, 0, parent ),
index( row, columnCount( parent ), parent ) );
}
void QgsRuleBasedRendererV2Model::removeRule( const QModelIndex& index )
{
if ( !index.isValid() )
return;
beginRemoveRows( index.parent(), index.row(), index.row() );
QgsRuleBasedRendererV2::Rule* rule = static_cast<QgsRuleBasedRendererV2::Rule*>( index.internalPointer() );
QgsRuleBasedRendererV2::Rule* rule = ruleForIndex( index );
rule->parent()->removeChild( rule );
endRemoveRows();
}
void QgsRuleBasedRendererV2Model::willAddRules( const QModelIndex& parent, int count )
{
int row = rowCount( parent ); // only consider appending
beginInsertRows( parent, row, row + count - 1 );
}
void QgsRuleBasedRendererV2Model::finishedAddingRules()
{
emit endInsertRows();
}

View File

@ -48,14 +48,28 @@ class QgsRuleBasedRendererV2Model : public QAbstractItemModel
//! provide parent model index
virtual QModelIndex parent( const QModelIndex &index ) const;
// editing support
virtual bool setData( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole );
// drag'n'drop support
Qt::DropActions supportedDropActions() const;
QStringList mimeTypes() const;
QMimeData *mimeData( const QModelIndexList &indexes ) const;
bool dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent );
bool removeRows( int row, int count, const QModelIndex & parent = QModelIndex() );
// new methods
QgsRuleBasedRendererV2::Rule* ruleForIndex( const QModelIndex& index ) const;
void insertRule( const QModelIndex& parent, int before, QgsRuleBasedRendererV2::Rule* newrule );
void updateRule( const QModelIndex& index );
void updateRule( const QModelIndex& parent, int row );
void removeRule( const QModelIndex& index );
void willAddRules( const QModelIndex& parent, int count ); // call beginInsertRows
void finishedAddingRules(); // call endInsertRows
protected:
QgsRuleBasedRendererV2* mR;
};
@ -84,8 +98,6 @@ class GUI_EXPORT QgsRuleBasedRendererV2Widget : public QgsRendererV2Widget, priv
void editRule();
void editRule( const QModelIndex& index );
void removeRule();
void moveUp();
void moveDown();
void refineRuleScales();
void refineRuleCategories();
@ -96,9 +108,9 @@ class GUI_EXPORT QgsRuleBasedRendererV2Widget : public QgsRendererV2Widget, priv
protected:
void refineRule( int type );
void refineRuleCategoriesGui( QgsRuleBasedRendererV2::Rule* initialRule );
void refineRuleRangesGui( QgsRuleBasedRendererV2::Rule* initialRule );
void refineRuleScalesGui( QgsRuleBasedRendererV2::Rule* initialRule );
void refineRuleCategoriesGui( const QModelIndex& index );
void refineRuleRangesGui( const QModelIndex& index );
void refineRuleScalesGui( const QModelIndex& index );
QgsRuleBasedRendererV2::Rule* currentRule();
@ -123,18 +135,22 @@ class GUI_EXPORT QgsRendererRulePropsDialog : public QDialog, private Ui::QgsRen
public:
QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style );
~QgsRendererRulePropsDialog();
void updateRuleFromGui();
QgsRuleBasedRendererV2::Rule* rule() { return mRule; }
public slots:
void testFilter();
void buildExpression();
void accept();
protected:
QgsRuleBasedRendererV2::Rule* mRule; // borrowed
QgsVectorLayer* mLayer;
QgsStyleV2* mStyle;
QgsSymbolV2SelectorDialog* mSymbolSelector;
QgsSymbolV2* mSymbol; // a clone of original symbol
};

View File

@ -156,6 +156,9 @@
<property name="title">
<string>Symbol</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
@ -182,38 +185,5 @@
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QgsRendererRulePropsDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QgsRendererRulePropsDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>

View File

@ -42,18 +42,17 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="btnMoveUp">
<property name="text">
<string>Move up</string>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnMoveDown">
<property name="text">
<string>Move down</string>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</widget>
</spacer>
</item>
</layout>
</item>
@ -78,6 +77,15 @@
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="dragEnabled">
<bool>true</bool>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::InternalMove</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>