[styledock] Inline edit panel for rules

This commit is contained in:
Nathan Woodrow 2016-06-21 14:46:45 +10:00
parent 82e2add045
commit 1072d9681e
4 changed files with 294 additions and 180 deletions

View File

@ -100,6 +100,27 @@ class QgsRuleBasedRendererV2Widget : QgsRendererV2Widget
/////// ///////
class QgsRendererRulePropsWidget: QgsPanelWidget
{
%TypeHeaderCode
#include <qgsrulebasedrendererv2widget.h>
%End
public:
QgsRendererRulePropsWidget( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style, QWidget* parent /TransferThis/ = 0, QgsMapCanvas* mapCanvas = 0 );
~QgsRendererRulePropsWidget();
QgsRuleBasedRendererV2::Rule* rule();
public slots:
void testFilter();
void buildExpression();
void accept();
void apply() override;
virtual void setDockMode( bool dockMode);
};
class QgsRendererRulePropsDialog : QDialog class QgsRendererRulePropsDialog : QDialog
{ {
%TypeHeaderCode %TypeHeaderCode

View File

@ -25,6 +25,7 @@
#include "qgslogger.h" #include "qgslogger.h"
#include "qstring.h" #include "qstring.h"
#include "qgssinglesymbolrendererv2.h" #include "qgssinglesymbolrendererv2.h"
#include "qgspanelwidget.h"
#include <QKeyEvent> #include <QKeyEvent>
#include <QMenu> #include <QMenu>
@ -176,15 +177,15 @@ void QgsRuleBasedRendererV2Widget::editRule( const QModelIndex& index )
{ {
if ( !index.isValid() ) if ( !index.isValid() )
return; return;
QgsRuleBasedRendererV2::Rule* rule = mModel->ruleForIndex( index ); QgsRuleBasedRendererV2::Rule* rule = mModel->ruleForIndex( index );
QgsRendererRulePropsDialog dlg( rule, mLayer, mStyle, this, mMapCanvas ); QgsRendererRulePropsWidget* widget = new QgsRendererRulePropsWidget( rule, mLayer, mStyle, this, mMapCanvas);
if ( dlg.exec() ) widget->setDockMode( true );
{ widget->setPanelTitle(tr("Edit rule"));
// model should know about the change and emit dataChanged signal for the view connect( widget, SIGNAL(panelAccepted(QgsPanelWidget*)), this, SLOT(ruleWidgetPanelAccepted(QgsPanelWidget*)));
mModel->updateRule( index.parent(), index.row() ); connect( widget, SIGNAL(widgetChanged()), this, SLOT(liveUpdateRuleFromPanel()));
mModel->clearFeatureCounts(); openPanel(widget);
}
} }
void QgsRuleBasedRendererV2Widget::removeRule() void QgsRuleBasedRendererV2Widget::removeRule()
@ -490,6 +491,22 @@ void QgsRuleBasedRendererV2Widget::paste()
mModel->dropMimeData( mime, Qt::CopyAction, index.row(), index.column(), index.parent() ); mModel->dropMimeData( mime, Qt::CopyAction, index.row(), index.column(), index.parent() );
} }
void QgsRuleBasedRendererV2Widget::ruleWidgetPanelAccepted(QgsPanelWidget *panel)
{
QgsRendererRulePropsWidget* widget = qobject_cast<QgsRendererRulePropsWidget*>( panel );
widget->apply();
// model should know about the change and emit dataChanged signal for the view
QModelIndex index = viewRules->selectionModel()->currentIndex();
mModel->updateRule( index.parent(), index.row() );
mModel->clearFeatureCounts();
}
void QgsRuleBasedRendererV2Widget::liveUpdateRuleFromPanel()
{
ruleWidgetPanelAccepted( qobject_cast<QgsPanelWidget*>(sender()));
}
void QgsRuleBasedRendererV2Widget::countFeatures() void QgsRuleBasedRendererV2Widget::countFeatures()
{ {
@ -592,8 +609,8 @@ void QgsRuleBasedRendererV2Widget::selectedRulesChanged()
/////////// ///////////
QgsRendererRulePropsDialog::QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style, QWidget* parent , QgsMapCanvas* mapCanvas ) QgsRendererRulePropsWidget::QgsRendererRulePropsWidget( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style, QWidget* parent , QgsMapCanvas* mapCanvas )
: QDialog( parent ) : QgsPanelWidget( parent )
, mRule( rule ) , mRule( rule )
, mLayer( layer ) , mLayer( layer )
, mSymbolSelector( nullptr ) , mSymbolSelector( nullptr )
@ -601,12 +618,6 @@ QgsRendererRulePropsDialog::QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::
, mMapCanvas( mapCanvas ) , mMapCanvas( mapCanvas )
{ {
setupUi( this ); setupUi( this );
#ifdef Q_OS_MAC
setWindowModality( Qt::WindowModal );
#endif
connect( buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) );
connect( buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
editFilter->setText( mRule->filterExpression() ); editFilter->setText( mRule->filterExpression() );
editFilter->setToolTip( mRule->filterExpression() ); editFilter->setToolTip( mRule->filterExpression() );
@ -636,8 +647,11 @@ QgsRendererRulePropsDialog::QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::
mSymbol = QgsSymbolV2::defaultSymbol( mLayer->geometryType() ); mSymbol = QgsSymbolV2::defaultSymbol( mLayer->geometryType() );
} }
mSymbolSelector = new QgsSymbolV2SelectorDialog( mSymbol, style, mLayer, this, true ); mSymbolSelector = new QgsSymbolV2SelectorWidget( mSymbol, style, mLayer, this );
mSymbolSelector->setMapCanvas( mMapCanvas ); mSymbolSelector->setMapCanvas( mMapCanvas );
connect(mSymbolSelector, SIGNAL(widgetChanged()), this, SIGNAL(widgetChanged()));
connect( mSymbolSelector, SIGNAL(showPanel(QgsPanelWidget*)), this, SLOT(openPanel(QgsPanelWidget*)));
QVBoxLayout* l = new QVBoxLayout; QVBoxLayout* l = new QVBoxLayout;
l->addWidget( mSymbolSelector ); l->addWidget( mSymbolSelector );
groupSymbol->setLayout( l ); groupSymbol->setLayout( l );
@ -645,18 +659,58 @@ QgsRendererRulePropsDialog::QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::
connect( btnExpressionBuilder, SIGNAL( clicked() ), this, SLOT( buildExpression() ) ); connect( btnExpressionBuilder, SIGNAL( clicked() ), this, SLOT( buildExpression() ) );
connect( btnTestFilter, SIGNAL( clicked() ), this, SLOT( testFilter() ) ); connect( btnTestFilter, SIGNAL( clicked() ), this, SLOT( testFilter() ) );
}
QgsRendererRulePropsWidget::~QgsRendererRulePropsWidget()
{
}
QgsRendererRulePropsDialog::QgsRendererRulePropsDialog(QgsRuleBasedRendererV2::Rule *rule, QgsVectorLayer *layer, QgsStyleV2 *style, QWidget *parent, QgsMapCanvas *mapCanvas)
: QDialog(parent)
{
#ifdef Q_OS_MAC
setWindowModality( Qt::WindowModal );
#endif
this->setLayout(new QVBoxLayout());
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
mPropsWidget = new QgsRendererRulePropsWidget(rule, layer, style, this, mapCanvas);
this->layout()->addWidget(mPropsWidget);
this->layout()->addWidget(buttonBox);
connect( buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) );
connect( buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
QSettings settings; QSettings settings;
restoreGeometry( settings.value( "/Windows/QgsRendererRulePropsDialog/geometry" ).toByteArray() ); restoreGeometry( settings.value( "/Windows/QgsRendererRulePropsDialog/geometry" ).toByteArray() );
} }
QgsRendererRulePropsDialog::~QgsRendererRulePropsDialog() QgsRendererRulePropsDialog::~QgsRendererRulePropsDialog()
{ {
delete mSymbol;
QSettings settings; QSettings settings;
settings.setValue( "/Windows/QgsRendererRulePropsDialog/geometry", saveGeometry() ); settings.setValue( "/Windows/QgsRendererRulePropsDialog/geometry", saveGeometry() );
} }
void QgsRendererRulePropsDialog::testFilter()
{
mPropsWidget->testFilter();
}
void QgsRendererRulePropsDialog::buildExpression() void QgsRendererRulePropsDialog::buildExpression()
{
mPropsWidget->buildExpression();
}
void QgsRendererRulePropsDialog::accept()
{
mPropsWidget->apply();
QDialog::accept();
}
void QgsRendererRulePropsWidget::buildExpression()
{ {
QgsExpressionContext context; QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope() context << QgsExpressionContextUtils::globalScope()
@ -679,7 +733,7 @@ void QgsRendererRulePropsDialog::buildExpression()
editFilter->setText( dlg.expressionText() ); editFilter->setText( dlg.expressionText() );
} }
void QgsRendererRulePropsDialog::testFilter() void QgsRendererRulePropsWidget::testFilter()
{ {
QgsExpression filter( editFilter->text() ); QgsExpression filter( editFilter->text() );
if ( filter.hasParserError() ) if ( filter.hasParserError() )
@ -731,7 +785,7 @@ void QgsRendererRulePropsDialog::testFilter()
QMessageBox::information( this, tr( "Filter" ), tr( "Filter returned %n feature(s)", "number of filtered features", count ) ); QMessageBox::information( this, tr( "Filter" ), tr( "Filter returned %n feature(s)", "number of filtered features", count ) );
} }
void QgsRendererRulePropsDialog::accept() void QgsRendererRulePropsWidget::apply()
{ {
mRule->setFilterExpression( editFilter->text() ); mRule->setFilterExpression( editFilter->text() );
mRule->setLabel( editLabel->text() ); mRule->setLabel( editLabel->text() );
@ -740,8 +794,12 @@ void QgsRendererRulePropsDialog::accept()
mRule->setScaleMinDenom( groupScale->isChecked() ? mScaleRangeWidget->minimumScaleDenom() : 0 ); mRule->setScaleMinDenom( groupScale->isChecked() ? mScaleRangeWidget->minimumScaleDenom() : 0 );
mRule->setScaleMaxDenom( groupScale->isChecked() ? mScaleRangeWidget->maximumScaleDenom() : 0 ); mRule->setScaleMaxDenom( groupScale->isChecked() ? mScaleRangeWidget->maximumScaleDenom() : 0 );
mRule->setSymbol( groupSymbol->isChecked() ? mSymbol->clone() : nullptr ); mRule->setSymbol( groupSymbol->isChecked() ? mSymbol->clone() : nullptr );
}
QDialog::accept(); void QgsRendererRulePropsWidget::setDockMode(bool dockMode)
{
QgsPanelWidget::setDockMode( dockMode );
mSymbolSelector->setDockMode( true );
} }
//////// ////////

View File

@ -155,6 +155,10 @@ class GUI_EXPORT QgsRuleBasedRendererV2Widget : public QgsRendererV2Widget, priv
protected slots: protected slots:
void copy() override; void copy() override;
void paste() override; void paste() override;
private slots:
void ruleWidgetPanelAccepted( QgsPanelWidget* panel);
void liveUpdateRuleFromPanel();
}; };
/////// ///////
@ -162,8 +166,64 @@ class GUI_EXPORT QgsRuleBasedRendererV2Widget : public QgsRendererV2Widget, priv
#include <QDialog> #include <QDialog>
#include "ui_qgsrendererrulepropsdialogbase.h" #include "ui_qgsrendererrulepropsdialogbase.h"
#include "qgssymbolv2selectordialog.h"
class GUI_EXPORT QgsRendererRulePropsDialog : public QDialog, private Ui::QgsRendererRulePropsDialog class GUI_EXPORT QgsRendererRulePropsWidget : public QgsPanelWidget, private Ui::QgsRendererRulePropsWidget
{
Q_OBJECT
public:
/**
* Widget to edit the details of a rule based renderer rule.
* @param rule The rule to edit.
* @param layer The layer used to pull layer related information.
* @param style The active QGIS style.
* @param parent The parent widget.
* @param mapCanvas The map canvas object.
*/
QgsRendererRulePropsWidget( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style, QWidget* parent = nullptr, QgsMapCanvas* mapCanvas = nullptr );
~QgsRendererRulePropsWidget();
/**
* Return the current set rule.
* @return The current rule.
*/
QgsRuleBasedRendererV2::Rule* rule() { return mRule; }
public slots:
/**
* Test the filter that is set in the widget
*/
void testFilter();
/**
* Open the expression builder widget to check if the
*/
void buildExpression();
/**
* Apply any changes from the widget to the set rule.
*/
void apply() override;
/**
* Set the widget in dock mode.
* @param dockMode True for dock mode.
*/
virtual void setDockMode( bool dockMode);
protected:
QgsRuleBasedRendererV2::Rule* mRule; // borrowed
QgsVectorLayer* mLayer;
QgsSymbolV2SelectorWidget* mSymbolSelector;
QgsSymbolV2* mSymbol; // a clone of original symbol
QgsMapCanvas* mMapCanvas;
};
class GUI_EXPORT QgsRendererRulePropsDialog : public QDialog
{ {
Q_OBJECT Q_OBJECT
@ -171,21 +231,16 @@ class GUI_EXPORT QgsRendererRulePropsDialog : public QDialog, private Ui::QgsRen
QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style, QWidget* parent = nullptr, QgsMapCanvas* mapCanvas = nullptr ); QgsRendererRulePropsDialog( QgsRuleBasedRendererV2::Rule* rule, QgsVectorLayer* layer, QgsStyleV2* style, QWidget* parent = nullptr, QgsMapCanvas* mapCanvas = nullptr );
~QgsRendererRulePropsDialog(); ~QgsRendererRulePropsDialog();
QgsRuleBasedRendererV2::Rule* rule() { return mRule; } QgsRuleBasedRendererV2::Rule* rule() { return mPropsWidget->rule(); }
public slots: public slots:
void testFilter(); void testFilter();
void buildExpression(); void buildExpression();
void accept() override; void accept() override;
protected: private:
QgsRuleBasedRendererV2::Rule* mRule; // borrowed QgsRendererRulePropsWidget* mPropsWidget;
QgsVectorLayer* mLayer; QDialogButtonBox* buttonBox;
QgsSymbolV2SelectorDialog* mSymbolSelector;
QgsSymbolV2* mSymbol; // a clone of original symbol
QgsMapCanvas* mMapCanvas;
}; };

View File

@ -1,150 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>QgsRendererRulePropsDialog</class> <class>QgsRendererRulePropsWidget</class>
<widget class="QDialog" name="QgsRendererRulePropsDialog"> <widget class="QWidget" name="QgsRendererRulePropsWidget">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>489</width> <width>376</width>
<height>261</height> <height>155</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Rule properties</string> <string>Form</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy"> <property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum> <enum>QFormLayout::ExpandingFieldsGrow</enum>
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label_1"> <widget class="QLabel" name="label_1">
<property name="text"> <property name="text">
<string>Label</string> <string>Label</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QLineEdit" name="editLabel"/> <widget class="QLineEdit" name="editLabel"/>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="label_5">
<property name="text"> <property name="text">
<string>Filter</string> <string>Filter</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>
<widget class="QLineEdit" name="editFilter"/> <widget class="QLineEdit" name="editFilter"/>
</item> </item>
<item> <item>
<widget class="QPushButton" name="btnExpressionBuilder"> <widget class="QPushButton" name="btnExpressionBuilder">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed"> <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="text"> <property name="text">
<string>...</string> <string>...</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QPushButton" name="btnTestFilter"> <widget class="QPushButton" name="btnTestFilter">
<property name="text"> <property name="text">
<string>Test</string> <string>Test</string>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
<string>Description</string> <string>Description</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QLineEdit" name="editDescription"/> <widget class="QLineEdit" name="editDescription"/>
</item> </item>
</layout> </layout>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="groupScale"> <widget class="QGroupBox" name="groupScale">
<property name="title"> <property name="title">
<string>Scale range</string> <string>Scale range</string>
</property> </property>
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="checked"> <property name="checked">
<bool>false</bool> <bool>false</bool>
</property> </property>
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
<widget class="QgsScaleRangeWidget" name="mScaleRangeWidget" native="true"> <widget class="QgsScaleRangeWidget" name="mScaleRangeWidget" native="true">
<property name="toolTip"> <property name="toolTip">
<string/> <string/>
</property> </property>
<property name="whatsThis"> <property name="whatsThis">
<string/> <string/>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QGroupBox" name="groupSymbol"> <widget class="QGroupBox" name="groupSymbol">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding"> <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="title"> <property name="title">
<string>Symbol</string> <string>Symbol</string>
</property> </property>
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>
<item> </layout>
<widget class="QDialogButtonBox" name="buttonBox"> </widget>
<property name="orientation"> <customwidgets>
<enum>Qt::Horizontal</enum> <customwidget>
</property> <class>QgsScaleRangeWidget</class>
<property name="standardButtons"> <extends>QWidget</extends>
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> <header>qgsscalerangewidget.h</header>
</property> </customwidget>
</widget> </customwidgets>
</item> <resources/>
</layout> <connections/>
</widget> </ui>
<customwidgets>
<customwidget>
<class>QgsScaleRangeWidget</class>
<extends>QWidget</extends>
<header>qgsscalerangewidget.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>editLabel</tabstop>
<tabstop>editFilter</tabstop>
<tabstop>btnExpressionBuilder</tabstop>
<tabstop>btnTestFilter</tabstop>
<tabstop>editDescription</tabstop>
<tabstop>groupScale</tabstop>
<tabstop>groupSymbol</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>