Skip to content

Commit 1c7a5b2

Browse files
committedAug 22, 2015
Add editor widget for editing QgsExpressionContextScope variables
1 parent 05b15dc commit 1c7a5b2

14 files changed

+1451
-51
lines changed
 

‎images/images.qrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@
314314
<file>themes/default/mIconClear.svg</file>
315315
<file>themes/default/mIconClose.png</file>
316316
<file>themes/default/mIconCollapse.png</file>
317+
<file>themes/default/mIconCollapseSmall.svg</file>
317318
<file>themes/default/mIconColorBox.svg</file>
318319
<file>themes/default/mIconColorPicker.svg</file>
319320
<file>themes/default/mIconColorSwatches.svg</file>
@@ -333,6 +334,7 @@
333334
<file>themes/default/mIconEditable.png</file>
334335
<file>themes/default/mIconEditableEdits.png</file>
335336
<file>themes/default/mIconExpand.png</file>
337+
<file>themes/default/mIconExpandSmall.svg</file>
336338
<file>themes/default/mIconExpression.svg</file>
337339
<file>themes/default/mIconExpressionEditorOpen.svg</file>
338340
<file>themes/default/mIconExpressionFilter.svg</file>
Lines changed: 78 additions & 0 deletions
Loading
Lines changed: 78 additions & 0 deletions
Loading

‎python/gui/gui.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@
118118
%Include qgssvgannotationitem.sip
119119
%Include qgstextannotationitem.sip
120120
%Include qgsuserinputdockwidget.sip
121+
%Include qgsvariableeditorwidget.sip
121122
%Include qgsvectorlayertools.sip
122123
%Include qgsvertexmarker.sip
123124

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/** \ingroup gui
2+
* \class QgsVariableEditorWidget
3+
* A tree based widget for editing expression context scope variables. The widget allows editing
4+
* variables from a QgsExpressionContextScope, and can optionally also show inherited
5+
* variables from a QgsExpressionContext.
6+
* \note added in QGIS 2.12
7+
*/
8+
9+
class QgsVariableEditorWidget : QWidget
10+
{
11+
%TypeHeaderCode
12+
#include <qgsvariableeditorwidget.h>
13+
%End
14+
15+
public:
16+
17+
/** Constructor for QgsVariableEditorWidget.
18+
* @param parent parent widget
19+
*/
20+
QgsVariableEditorWidget( QWidget *parent /TransferThis/ = 0 );
21+
22+
~QgsVariableEditorWidget();
23+
24+
/** Overwrites the QgsExpressionContext for the widget. Setting a context
25+
* allows the widget to show all inherited variables for the context,
26+
* and highlight any overriden variables within scopes.
27+
* @param context expression context
28+
* @see context()
29+
*/
30+
void setContext( QgsExpressionContext* context );
31+
32+
/** Returns the current expression context for the widget. QgsVariableEditorWidget widgets
33+
* are created with an empty context by default.
34+
* @see setContext()
35+
*/
36+
QgsExpressionContext* context() const;
37+
38+
/** Reloads all scopes from the editor's current context. This method should be called
39+
* after adding or removing scopes from the attached context.
40+
* @see context()
41+
*/
42+
void reloadContext();
43+
44+
/** Sets the editable scope for the widget. Only variables from the editable scope can
45+
* be modified by users.
46+
* @param scopeIndex index of current editable scope. Set to -1 to disable
47+
* editing and make the widget read-only.
48+
* @see editableScope()
49+
*/
50+
void setEditableScopeIndex( int scopeIndex );
51+
52+
/** Returns the current editable scope for the widget.
53+
* @returns editable scope, or 0 if no editable scope is set
54+
* @see setEditableScopeIndex()
55+
*/
56+
QgsExpressionContextScope* editableScope() const;
57+
58+
/** Sets the setting group for the widget. QgsVariableEditorWidget widgets with
59+
* the same setting group will synchronise their settings, eg the size
60+
* of columns in the tree widget.
61+
* @param group setting group
62+
* @see settingGroup()
63+
*/
64+
void setSettingGroup( const QString &group );
65+
66+
/** Returns the setting group for the widget. QgsVariableEditorWidget widgets with
67+
* the same setting group will synchronise their settings, eg the size
68+
* of columns in the tree widget.
69+
* @returns setting group name
70+
* @see setSettingGroup()
71+
*/
72+
QString settingGroup() const;
73+
74+
/** Returns a map variables set within the editable scope. Read only variables are not
75+
* returned. This method can be used to retrieve the variables edited an added by
76+
* users via the widget.
77+
*/
78+
QgsStringMap variablesInActiveScope() const;
79+
80+
signals:
81+
82+
/** Emitted when the user has modified a scope using the widget.
83+
*/
84+
void scopeChanged();
85+
86+
protected:
87+
88+
void showEvent( QShowEvent *event );
89+
90+
};

‎src/app/qgsoptions.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "qgscolorschemeregistry.h"
4040
#include "qgssymbollayerv2utils.h"
4141
#include "qgscolordialog.h"
42+
#include "qgsexpressioncontext.h"
4243

4344
#include <QInputDialog>
4445
#include <QFileDialog>
@@ -838,6 +839,10 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl ) :
838839
// load gdal driver list only when gdal tab is first opened
839840
mLoadedGdalDriverList = false;
840841

842+
mVariableEditor->context()->appendScope( QgsExpressionContextUtils::globalScope() );
843+
mVariableEditor->reloadContext();
844+
mVariableEditor->setEditableScopeIndex( 0 );
845+
841846
// restore window and widget geometry/state
842847
restoreOptionsBaseUi();
843848
}
@@ -1333,6 +1338,9 @@ void QgsOptions::saveOptions()
13331338
// TODO[MD] QgisApp::instance()->legend()->updateLegendItemSymbologies();
13341339
}
13351340

1341+
//save variables
1342+
QgsExpressionContextUtils::setGlobalVariables( mVariableEditor->variablesInActiveScope() );
1343+
13361344
// save app stylesheet last (in case reset becomes necessary)
13371345
if ( mStyleSheetNewOpts != mStyleSheetOldOpts )
13381346
{

‎src/app/qgsoptions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929

3030
#include <QList>
3131

32+
class QgsExpressionContext;
33+
3234
/**
3335
* \class QgsOptions
3436
* \brief Set user options and preferences

‎src/app/qgsprojectproperties.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "qgscolorschemeregistry.h"
4949
#include "qgssymbollayerv2utils.h"
5050
#include "qgscolordialog.h"
51+
#include "qgsexpressioncontext.h"
5152

5253
//qt includes
5354
#include <QInputDialog>
@@ -524,6 +525,11 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa
524525
on_cbxProjectionEnabled_toggled( myProjectionEnabled );
525526
}
526527

528+
mVariableEditor->context()->appendScope( QgsExpressionContextUtils::globalScope() );
529+
mVariableEditor->context()->appendScope( QgsExpressionContextUtils::projectScope() );
530+
mVariableEditor->reloadContext();
531+
mVariableEditor->setEditableScopeIndex( 1 );
532+
527533
projectionSelectorInitialized();
528534
restoreOptionsBaseUi();
529535
restoreState();
@@ -919,6 +925,9 @@ void QgsProjectProperties::apply()
919925

920926
QgsProject::instance()->relationManager()->setRelations( mRelationManagerDlg->relations() );
921927

928+
//save variables
929+
QgsExpressionContextUtils::setProjectVariables( mVariableEditor->variablesInActiveScope() );
930+
922931
emit refresh();
923932
}
924933

‎src/app/qgsprojectproperties.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
class QgsMapCanvas;
2727
class QgsRelationManagerDialog;
2828
class QgsStyleV2;
29+
class QgsExpressionContext;
2930

3031
/** Dialog to set project level properties
3132

‎src/gui/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ SET(QGIS_GUI_SRCS
234234
qgssvgannotationitem.cpp
235235
qgstextannotationitem.cpp
236236
qgsuserinputdockwidget.cpp
237+
qgsvariableeditorwidget.cpp
237238
qgsvertexmarker.cpp
238239
qgsunitselectionwidget.cpp
239240
)
@@ -351,6 +352,7 @@ SET(QGIS_GUI_MOC_HDRS
351352
qgssearchquerybuilder.h
352353
qgsslider.h
353354
qgssublayersdialog.h
355+
qgsvariableeditorwidget.h
354356
qgsunitselectionwidget.h
355357
qgsuserinputdockwidget.h
356358

‎src/gui/qgsvariableeditorwidget.cpp

Lines changed: 753 additions & 0 deletions
Large diffs are not rendered by default.

‎src/gui/qgsvariableeditorwidget.h

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/***************************************************************************
2+
qgsvariableeditorwidget.h
3+
-------------------------
4+
Date : April 2015
5+
Copyright : (C) 2015 by Nyall Dawson
6+
Email : nyall dot dawson at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSVARIABLEEDITORWIDGET_H
17+
#define QGSVARIABLEEDITORWIDGET_H
18+
19+
#include "qgis.h"
20+
#include <QWidget>
21+
#include <QTreeWidget>
22+
#include <QItemDelegate>
23+
24+
class QTableWidget;
25+
class QgsVariableEditorTree;
26+
class VariableEditorDelegate;
27+
class QgsExpressionContextScope;
28+
class QPushButton;
29+
class QgsExpressionContext;
30+
31+
32+
/** \ingroup gui
33+
* \class QgsVariableEditorWidget
34+
* A tree based widget for editing expression context scope variables. The widget allows editing
35+
* variables from a QgsExpressionContextScope, and can optionally also show inherited
36+
* variables from a QgsExpressionContext.
37+
* \note added in QGIS 2.12
38+
*/
39+
40+
class GUI_EXPORT QgsVariableEditorWidget : public QWidget
41+
{
42+
Q_OBJECT
43+
44+
Q_PROPERTY( QString settingGroup READ settingGroup WRITE setSettingGroup )
45+
46+
public:
47+
48+
/** Constructor for QgsVariableEditorWidget.
49+
* @param parent parent widget
50+
*/
51+
QgsVariableEditorWidget( QWidget *parent = 0 );
52+
53+
~QgsVariableEditorWidget();
54+
55+
/** Overwrites the QgsExpressionContext for the widget. Setting a context
56+
* allows the widget to show all inherited variables for the context,
57+
* and highlight any overriden variables within scopes.
58+
* @param context expression context
59+
* @see context()
60+
*/
61+
void setContext( QgsExpressionContext* context );
62+
63+
/** Returns the current expression context for the widget. QgsVariableEditorWidget widgets
64+
* are created with an empty context by default.
65+
* @see setContext()
66+
*/
67+
QgsExpressionContext* context() const { return mContext.data(); }
68+
69+
/** Reloads all scopes from the editor's current context. This method should be called
70+
* after adding or removing scopes from the attached context.
71+
* @see context()
72+
*/
73+
void reloadContext();
74+
75+
/** Sets the editable scope for the widget. Only variables from the editable scope can
76+
* be modified by users.
77+
* @param scopeIndex index of current editable scope. Set to -1 to disable
78+
* editing and make the widget read-only.
79+
* @see editableScope()
80+
*/
81+
void setEditableScopeIndex( int scopeIndex );
82+
83+
/** Returns the current editable scope for the widget.
84+
* @returns editable scope, or 0 if no editable scope is set
85+
* @see setEditableScopeIndex()
86+
*/
87+
QgsExpressionContextScope* editableScope() const;
88+
89+
/** Sets the setting group for the widget. QgsVariableEditorWidget widgets with
90+
* the same setting group will synchronise their settings, eg the size
91+
* of columns in the tree widget.
92+
* @param group setting group
93+
* @see settingGroup()
94+
*/
95+
void setSettingGroup( const QString &group ) { mSettingGroup = group; }
96+
97+
/** Returns the setting group for the widget. QgsVariableEditorWidget widgets with
98+
* the same setting group will synchronise their settings, eg the size
99+
* of columns in the tree widget.
100+
* @returns setting group name
101+
* @see setSettingGroup()
102+
*/
103+
QString settingGroup() const { return mSettingGroup; }
104+
105+
/** Returns a map variables set within the editable scope. Read only variables are not
106+
* returned. This method can be used to retrieve the variables edited an added by
107+
* users via the widget.
108+
*/
109+
QgsStringMap variablesInActiveScope() const;
110+
111+
signals:
112+
113+
/** Emitted when the user has modified a scope using the widget.
114+
*/
115+
void scopeChanged();
116+
117+
protected:
118+
119+
void showEvent( QShowEvent *event ) override;
120+
121+
private:
122+
123+
QScopedPointer<QgsExpressionContext> mContext;
124+
int mEditableScopeIndex;
125+
QgsVariableEditorTree* mTreeWidget;
126+
QPushButton* mAddButton;
127+
QPushButton* mRemoveButton;
128+
QString mSettingGroup;
129+
bool mShown;
130+
131+
QString saveKey() const;
132+
133+
private slots:
134+
135+
void on_mAddButton_clicked();
136+
void on_mRemoveButton_clicked();
137+
void selectionChanged();
138+
139+
};
140+
141+
142+
/// @cond
143+
144+
/* QgsVariableEditorTree is NOT part of the public QGIS api. It's only
145+
* public here as Qt meta objects can't be nested classes
146+
*/
147+
148+
class QgsVariableEditorTree : public QTreeWidget
149+
{
150+
Q_OBJECT
151+
152+
public:
153+
154+
enum VaribleRoles
155+
{
156+
ContextIndex = Qt::UserRole,
157+
RowBaseColor
158+
};
159+
160+
QgsVariableEditorTree( QWidget *parent = 0 );
161+
162+
QTreeWidgetItem *indexToItem( const QModelIndex &index ) const { return itemFromIndex( index ); }
163+
QModelIndex itemToIndex( QTreeWidgetItem* item ) const { return indexFromItem( item ); }
164+
QString variableNameFromItem( QTreeWidgetItem* item ) const { return item ? item->text( 0 ) : QString(); }
165+
QString variableNameFromIndex( const QModelIndex& index ) const { return variableNameFromItem( itemFromIndex( index ) ); }
166+
QgsExpressionContextScope* scopeFromItem( QTreeWidgetItem* item ) const;
167+
QTreeWidgetItem* itemFromVariable( QgsExpressionContextScope* scope, const QString& name ) const;
168+
void setEditableScopeIndex( int scopeIndex ) { mEditableScopeIndex = scopeIndex; }
169+
QgsExpressionContextScope* editableScope();
170+
void setContext( QgsExpressionContext* context ) { mContext = context; }
171+
void refreshTree();
172+
void removeItem( QTreeWidgetItem* item );
173+
void renameItem( QTreeWidgetItem *item, const QString &name );
174+
void resetTree();
175+
void emitChanged();
176+
177+
signals:
178+
179+
void scopeChanged();
180+
181+
protected:
182+
void keyPressEvent( QKeyEvent *event ) override;
183+
void mousePressEvent( QMouseEvent *event ) override;
184+
void drawRow( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const override;
185+
QColor rowColor( int index ) const;
186+
void toggleContextExpanded( QTreeWidgetItem *item );
187+
void editNext( const QModelIndex &index );
188+
189+
static QIcon mExpandIcon;
190+
191+
private:
192+
193+
VariableEditorDelegate* mEditorDelegate;
194+
int mEditableScopeIndex;
195+
QgsExpressionContext* mContext;
196+
QMap< QPair<int, QString>, QTreeWidgetItem* > mVariableToItem;
197+
QMap< int, QTreeWidgetItem* > mScopeToItem;
198+
199+
void refreshScopeItems( QgsExpressionContextScope* scope, int scopeIndex );
200+
void refreshScopeVariables( QgsExpressionContextScope* scope, int scopeIndex );
201+
};
202+
203+
/// @endcond
204+
205+
#endif //QGSVARIABLEEDITORWIDGET_H

‎src/ui/qgsoptionsbase.ui

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,15 @@
248248
<normaloff>:/images/themes/default/propertyicons/network_and_proxy.png</normaloff>:/images/themes/default/propertyicons/network_and_proxy.png</iconset>
249249
</property>
250250
</item>
251+
<item>
252+
<property name="text">
253+
<string>Variables</string>
254+
</property>
255+
<property name="icon">
256+
<iconset resource="../../images/images.qrc">
257+
<normaloff>:/images/themes/default/mIconExpression.svg</normaloff>:/images/themes/default/mIconExpression.svg</iconset>
258+
</property>
259+
</item>
251260
</widget>
252261
</item>
253262
</layout>
@@ -4826,6 +4835,26 @@
48264835
</item>
48274836
</layout>
48284837
</widget>
4838+
<widget class="QWidget" name="page">
4839+
<layout class="QVBoxLayout" name="verticalLayout_40">
4840+
<item>
4841+
<widget class="QGroupBox" name="groupBox_25">
4842+
<property name="title">
4843+
<string>Variables</string>
4844+
</property>
4845+
<layout class="QVBoxLayout" name="verticalLayout_41">
4846+
<item>
4847+
<widget class="QgsVariableEditorWidget" name="mVariableEditor">
4848+
<property name="settingGroup" stdset="0">
4849+
<string notr="true">globalOptions</string>
4850+
</property>
4851+
</widget>
4852+
</item>
4853+
</layout>
4854+
</widget>
4855+
</item>
4856+
</layout>
4857+
</widget>
48294858
</widget>
48304859
</item>
48314860
</layout>
@@ -4911,6 +4940,12 @@
49114940
<header location="global">qgsprojectionselectionwidget.h</header>
49124941
<container>1</container>
49134942
</customwidget>
4943+
<customwidget>
4944+
<class>QgsVariableEditorWidget</class>
4945+
<extends>QWidget</extends>
4946+
<header location="global">qgsvariableeditorwidget.h</header>
4947+
<container>1</container>
4948+
</customwidget>
49144949
</customwidgets>
49154950
<tabstops>
49164951
<tabstop>mOptionsListWidget</tabstop>

‎src/ui/qgsprojectpropertiesbase.ui

Lines changed: 187 additions & 51 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.