Skip to content

Commit 1072d96

Browse files
committed
[styledock] Inline edit panel for rules
1 parent 82e2add commit 1072d96

File tree

4 files changed

+290
-176
lines changed

4 files changed

+290
-176
lines changed

python/gui/symbology-ng/qgsrulebasedrendererv2widget.sip

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,27 @@ class QgsRuleBasedRendererV2Widget : QgsRendererV2Widget
100100

101101
///////
102102

103+
class QgsRendererRulePropsWidget: QgsPanelWidget
104+
{
105+
%TypeHeaderCode
106+
#include <qgsrulebasedrendererv2widget.h>
107+
%End
108+
109+
public:
110+
QgsRendererRulePropsWidget( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style, QWidget* parent /TransferThis/ = 0, QgsMapCanvas* mapCanvas = 0 );
111+
~QgsRendererRulePropsWidget();
112+
113+
QgsRuleBasedRendererV2::Rule* rule();
114+
115+
public slots:
116+
void testFilter();
117+
void buildExpression();
118+
void accept();
119+
void apply() override;
120+
virtual void setDockMode( bool dockMode);
121+
};
122+
123+
103124
class QgsRendererRulePropsDialog : QDialog
104125
{
105126
%TypeHeaderCode

src/gui/symbology-ng/qgsrulebasedrendererv2widget.cpp

Lines changed: 78 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "qgslogger.h"
2626
#include "qstring.h"
2727
#include "qgssinglesymbolrendererv2.h"
28+
#include "qgspanelwidget.h"
2829

2930
#include <QKeyEvent>
3031
#include <QMenu>
@@ -176,15 +177,15 @@ void QgsRuleBasedRendererV2Widget::editRule( const QModelIndex& index )
176177
{
177178
if ( !index.isValid() )
178179
return;
180+
179181
QgsRuleBasedRendererV2::Rule* rule = mModel->ruleForIndex( index );
180182

181-
QgsRendererRulePropsDialog dlg( rule, mLayer, mStyle, this, mMapCanvas );
182-
if ( dlg.exec() )
183-
{
184-
// model should know about the change and emit dataChanged signal for the view
185-
mModel->updateRule( index.parent(), index.row() );
186-
mModel->clearFeatureCounts();
187-
}
183+
QgsRendererRulePropsWidget* widget = new QgsRendererRulePropsWidget( rule, mLayer, mStyle, this, mMapCanvas);
184+
widget->setDockMode( true );
185+
widget->setPanelTitle(tr("Edit rule"));
186+
connect( widget, SIGNAL(panelAccepted(QgsPanelWidget*)), this, SLOT(ruleWidgetPanelAccepted(QgsPanelWidget*)));
187+
connect( widget, SIGNAL(widgetChanged()), this, SLOT(liveUpdateRuleFromPanel()));
188+
openPanel(widget);
188189
}
189190

190191
void QgsRuleBasedRendererV2Widget::removeRule()
@@ -490,6 +491,22 @@ void QgsRuleBasedRendererV2Widget::paste()
490491
mModel->dropMimeData( mime, Qt::CopyAction, index.row(), index.column(), index.parent() );
491492
}
492493

494+
void QgsRuleBasedRendererV2Widget::ruleWidgetPanelAccepted(QgsPanelWidget *panel)
495+
{
496+
QgsRendererRulePropsWidget* widget = qobject_cast<QgsRendererRulePropsWidget*>( panel );
497+
widget->apply();
498+
499+
// model should know about the change and emit dataChanged signal for the view
500+
QModelIndex index = viewRules->selectionModel()->currentIndex();
501+
mModel->updateRule( index.parent(), index.row() );
502+
mModel->clearFeatureCounts();
503+
}
504+
505+
void QgsRuleBasedRendererV2Widget::liveUpdateRuleFromPanel()
506+
{
507+
ruleWidgetPanelAccepted( qobject_cast<QgsPanelWidget*>(sender()));
508+
}
509+
493510

494511
void QgsRuleBasedRendererV2Widget::countFeatures()
495512
{
@@ -592,21 +609,15 @@ void QgsRuleBasedRendererV2Widget::selectedRulesChanged()
592609

593610
///////////
594611

595-
QgsRendererRulePropsDialog::QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style, QWidget* parent , QgsMapCanvas* mapCanvas )
596-
: QDialog( parent )
612+
QgsRendererRulePropsWidget::QgsRendererRulePropsWidget( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style, QWidget* parent , QgsMapCanvas* mapCanvas )
613+
: QgsPanelWidget( parent )
597614
, mRule( rule )
598615
, mLayer( layer )
599616
, mSymbolSelector( nullptr )
600617
, mSymbol( nullptr )
601618
, mMapCanvas( mapCanvas )
602619
{
603620
setupUi( this );
604-
#ifdef Q_OS_MAC
605-
setWindowModality( Qt::WindowModal );
606-
#endif
607-
608-
connect( buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) );
609-
connect( buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
610621

611622
editFilter->setText( mRule->filterExpression() );
612623
editFilter->setToolTip( mRule->filterExpression() );
@@ -636,27 +647,70 @@ QgsRendererRulePropsDialog::QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::
636647
mSymbol = QgsSymbolV2::defaultSymbol( mLayer->geometryType() );
637648
}
638649

639-
mSymbolSelector = new QgsSymbolV2SelectorDialog( mSymbol, style, mLayer, this, true );
650+
mSymbolSelector = new QgsSymbolV2SelectorWidget( mSymbol, style, mLayer, this );
640651
mSymbolSelector->setMapCanvas( mMapCanvas );
652+
connect(mSymbolSelector, SIGNAL(widgetChanged()), this, SIGNAL(widgetChanged()));
653+
connect( mSymbolSelector, SIGNAL(showPanel(QgsPanelWidget*)), this, SLOT(openPanel(QgsPanelWidget*)));
654+
641655
QVBoxLayout* l = new QVBoxLayout;
642656
l->addWidget( mSymbolSelector );
643657
groupSymbol->setLayout( l );
644658

645659
connect( btnExpressionBuilder, SIGNAL( clicked() ), this, SLOT( buildExpression() ) );
646660
connect( btnTestFilter, SIGNAL( clicked() ), this, SLOT( testFilter() ) );
647661

662+
}
663+
664+
QgsRendererRulePropsWidget::~QgsRendererRulePropsWidget()
665+
{
666+
667+
}
668+
669+
QgsRendererRulePropsDialog::QgsRendererRulePropsDialog(QgsRuleBasedRendererV2::Rule *rule, QgsVectorLayer *layer, QgsStyleV2 *style, QWidget *parent, QgsMapCanvas *mapCanvas)
670+
: QDialog(parent)
671+
{
672+
673+
#ifdef Q_OS_MAC
674+
setWindowModality( Qt::WindowModal );
675+
#endif
676+
this->setLayout(new QVBoxLayout());
677+
678+
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
679+
mPropsWidget = new QgsRendererRulePropsWidget(rule, layer, style, this, mapCanvas);
680+
681+
this->layout()->addWidget(mPropsWidget);
682+
this->layout()->addWidget(buttonBox);
683+
684+
connect( buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) );
685+
connect( buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
686+
648687
QSettings settings;
649688
restoreGeometry( settings.value( "/Windows/QgsRendererRulePropsDialog/geometry" ).toByteArray() );
650689
}
651690

652691
QgsRendererRulePropsDialog::~QgsRendererRulePropsDialog()
653692
{
654-
delete mSymbol;
655693
QSettings settings;
656694
settings.setValue( "/Windows/QgsRendererRulePropsDialog/geometry", saveGeometry() );
657695
}
658696

697+
void QgsRendererRulePropsDialog::testFilter()
698+
{
699+
mPropsWidget->testFilter();
700+
}
701+
659702
void QgsRendererRulePropsDialog::buildExpression()
703+
{
704+
mPropsWidget->buildExpression();
705+
}
706+
707+
void QgsRendererRulePropsDialog::accept()
708+
{
709+
mPropsWidget->apply();
710+
QDialog::accept();
711+
}
712+
713+
void QgsRendererRulePropsWidget::buildExpression()
660714
{
661715
QgsExpressionContext context;
662716
context << QgsExpressionContextUtils::globalScope()
@@ -679,7 +733,7 @@ void QgsRendererRulePropsDialog::buildExpression()
679733
editFilter->setText( dlg.expressionText() );
680734
}
681735

682-
void QgsRendererRulePropsDialog::testFilter()
736+
void QgsRendererRulePropsWidget::testFilter()
683737
{
684738
QgsExpression filter( editFilter->text() );
685739
if ( filter.hasParserError() )
@@ -731,7 +785,7 @@ void QgsRendererRulePropsDialog::testFilter()
731785
QMessageBox::information( this, tr( "Filter" ), tr( "Filter returned %n feature(s)", "number of filtered features", count ) );
732786
}
733787

734-
void QgsRendererRulePropsDialog::accept()
788+
void QgsRendererRulePropsWidget::apply()
735789
{
736790
mRule->setFilterExpression( editFilter->text() );
737791
mRule->setLabel( editLabel->text() );
@@ -740,8 +794,12 @@ void QgsRendererRulePropsDialog::accept()
740794
mRule->setScaleMinDenom( groupScale->isChecked() ? mScaleRangeWidget->minimumScaleDenom() : 0 );
741795
mRule->setScaleMaxDenom( groupScale->isChecked() ? mScaleRangeWidget->maximumScaleDenom() : 0 );
742796
mRule->setSymbol( groupSymbol->isChecked() ? mSymbol->clone() : nullptr );
797+
}
743798

744-
QDialog::accept();
799+
void QgsRendererRulePropsWidget::setDockMode(bool dockMode)
800+
{
801+
QgsPanelWidget::setDockMode( dockMode );
802+
mSymbolSelector->setDockMode( true );
745803
}
746804

747805
////////

src/gui/symbology-ng/qgsrulebasedrendererv2widget.h

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,38 +155,93 @@ class GUI_EXPORT QgsRuleBasedRendererV2Widget : public QgsRendererV2Widget, priv
155155
protected slots:
156156
void copy() override;
157157
void paste() override;
158+
159+
private slots:
160+
void ruleWidgetPanelAccepted( QgsPanelWidget* panel);
161+
void liveUpdateRuleFromPanel();
158162
};
159163

160164
///////
161165

162166
#include <QDialog>
163167

164168
#include "ui_qgsrendererrulepropsdialogbase.h"
169+
#include "qgssymbolv2selectordialog.h"
165170

166-
class GUI_EXPORT QgsRendererRulePropsDialog : public QDialog, private Ui::QgsRendererRulePropsDialog
171+
class GUI_EXPORT QgsRendererRulePropsWidget : public QgsPanelWidget, private Ui::QgsRendererRulePropsWidget
167172
{
168173
Q_OBJECT
169174

170175
public:
171-
QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style, QWidget* parent = nullptr, QgsMapCanvas* mapCanvas = nullptr );
172-
~QgsRendererRulePropsDialog();
173-
176+
/**
177+
* Widget to edit the details of a rule based renderer rule.
178+
* @param rule The rule to edit.
179+
* @param layer The layer used to pull layer related information.
180+
* @param style The active QGIS style.
181+
* @param parent The parent widget.
182+
* @param mapCanvas The map canvas object.
183+
*/
184+
QgsRendererRulePropsWidget( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style, QWidget* parent = nullptr, QgsMapCanvas* mapCanvas = nullptr );
185+
~QgsRendererRulePropsWidget();
186+
187+
/**
188+
* Return the current set rule.
189+
* @return The current rule.
190+
*/
174191
QgsRuleBasedRendererV2::Rule* rule() { return mRule; }
175192

176193
public slots:
194+
195+
/**
196+
* Test the filter that is set in the widget
197+
*/
177198
void testFilter();
199+
200+
/**
201+
* Open the expression builder widget to check if the
202+
*/
178203
void buildExpression();
179-
void accept() override;
204+
205+
/**
206+
* Apply any changes from the widget to the set rule.
207+
*/
208+
void apply() override;
209+
/**
210+
* Set the widget in dock mode.
211+
* @param dockMode True for dock mode.
212+
*/
213+
virtual void setDockMode( bool dockMode);
180214

181215
protected:
182216
QgsRuleBasedRendererV2::Rule* mRule; // borrowed
183217
QgsVectorLayer* mLayer;
184218

185-
QgsSymbolV2SelectorDialog* mSymbolSelector;
219+
QgsSymbolV2SelectorWidget* mSymbolSelector;
186220
QgsSymbolV2* mSymbol; // a clone of original symbol
187221

188222
QgsMapCanvas* mMapCanvas;
189223
};
190224

191225

226+
class GUI_EXPORT QgsRendererRulePropsDialog : public QDialog
227+
{
228+
Q_OBJECT
229+
230+
public:
231+
QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style, QWidget* parent = nullptr, QgsMapCanvas* mapCanvas = nullptr );
232+
~QgsRendererRulePropsDialog();
233+
234+
QgsRuleBasedRendererV2::Rule* rule() { return mPropsWidget->rule(); }
235+
236+
public slots:
237+
void testFilter();
238+
void buildExpression();
239+
void accept() override;
240+
241+
private:
242+
QgsRendererRulePropsWidget* mPropsWidget;
243+
QDialogButtonBox* buttonBox;
244+
};
245+
246+
192247
#endif // QGSRULEBASEDRENDERERV2WIDGET_H

0 commit comments

Comments
 (0)