Skip to content

Commit ddc76e2

Browse files
authoredSep 13, 2016
Merge pull request #3475 from m-kuhn/visibilityTab218
[Feature] conditional visibility for tabs and groupboxes (backport)
2 parents ee9c684 + 39f7c04 commit ddc76e2

28 files changed

+1098
-16
lines changed
 

‎python/core/core.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
%Include qgsobjectcustomproperties.sip
102102
%Include qgsofflineediting.sip
103103
%Include qgsogcutils.sip
104+
%Include qgsoptionalexpression.sip
104105
%Include qgsowsconnection.sip
105106
%Include qgspaintenginehack.sip
106107
%Include qgspallabeling.sip

‎python/core/qgseditformconfig.sip

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,20 @@ class QgsAttributeEditorContainer : QgsAttributeEditorElement
179179
*/
180180
void setColumnCount( int columnCount );
181181

182+
/**
183+
* An expression that controls the visibility of this container.
184+
*
185+
* @note Added in QGIS 2.18
186+
*/
187+
QgsOptionalExpression visibilityExpression() const;
188+
189+
/**
190+
* An expression that controls the visibility of this container.
191+
*
192+
* @note Added in QGIS 2.18
193+
*/
194+
void setVisibilityExpression( const QgsOptionalExpression& visibilityExpression );
195+
182196
};
183197

184198
/**

‎python/core/qgsexpression.sip

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,23 @@ class QgsExpression
1212
* loop in which this expression is used.
1313
*/
1414
QgsExpression( const QString& expr );
15+
/**
16+
* Create an empty expression.
17+
*
18+
* @note Added in QGIS 2.18
19+
*/
20+
QgsExpression();
21+
1522
~QgsExpression();
1623

24+
/**
25+
* Checks if this expression is valid.
26+
* A valid expression could be parsed but does not necessarily evaluate properly.
27+
*
28+
* @note Added in QGIS 2.18
29+
*/
30+
bool isValid() const;
31+
1732
//! Returns true if an error occurred when parsing the input expression
1833
bool hasParserError() const;
1934
//! Returns parser error
@@ -135,6 +150,13 @@ class QgsExpression
135150

136151
double scale();
137152

153+
/**
154+
* Set the expression string, will reset the whole internal structure.
155+
*
156+
* @note Added in QGIS 2.18
157+
*/
158+
void setExpression( const QString& expression );
159+
138160
//! Return the original, unmodified expression string.
139161
//! If there was none supplied because it was constructed by sole
140162
//! API calls, dump() will be used to create one instead.

‎python/core/qgsoptionalexpression.sip

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/***************************************************************************
2+
qgsoptionalexpression.sip - QgsOptionalExpression
3+
4+
---------------------
5+
begin : 8.9.2016
6+
copyright : (C) 2016 by Matthias Kuhn
7+
email : matthias@opengis.ch
8+
***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
17+
/**
18+
* \ingroup core
19+
*
20+
* QgsOptionalExpression is a container for an expression with an additional enabled/disabled flag.
21+
*
22+
* @note Added in QGIS 3.0
23+
*/
24+
class QgsOptionalExpression
25+
{
26+
%TypeHeaderCode
27+
#include <qgsoptionalexpression.h>
28+
%End
29+
public:
30+
/**
31+
* A QgsOptionalExpression is disabled by default if default constructed.
32+
*/
33+
QgsOptionalExpression();
34+
35+
/**
36+
* A QgsOptionalExpression is enabled by default if constructed with an expression.
37+
*/
38+
QgsOptionalExpression( const QgsExpression& data );
39+
40+
/**
41+
* A QgsOptionalExptression constructed with enabled status and data
42+
*/
43+
QgsOptionalExpression( const QgsExpression& data, bool enabled );
44+
45+
/**
46+
* Compare this QgsOptionalExptression to another one.
47+
*
48+
* This will compare the enabled flag and call the == operator
49+
* of the contained class.
50+
*
51+
* @note Added in QGIS 3.0
52+
*/
53+
bool operator== ( const QgsOptionalExpression& other ) const;
54+
operator bool () const;
55+
56+
/**
57+
* Check if this optional is enabled
58+
*
59+
* @note Added in QGIS 3.0
60+
*/
61+
bool enabled() const;
62+
63+
/**
64+
* Set if this optional is enabled
65+
*
66+
* @note Added in QGIS 3.0
67+
*/
68+
void setEnabled( bool enabled );
69+
70+
/**
71+
* Access the payload data
72+
*
73+
* @note Added in QGIS 3.0
74+
*/
75+
QgsExpression data() const;
76+
77+
/**
78+
* Set the payload data
79+
*
80+
* @note Added in QGIS 3.0
81+
*/
82+
void setData( const QgsExpression& data );
83+
};

‎python/gui/gui.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@
160160
%Include qgssourceselectdialog.sip
161161
%Include qgssublayersdialog.sip
162162
%Include qgssvgannotationitem.sip
163+
%Include qgstabwidget.sip
163164
%Include qgstablewidgetitem.sip
164165
%Include qgstextannotationitem.sip
165166
%Include qgstrackedvectorlayertools.sip

‎python/gui/qgsfieldexpressionwidget.sip

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,17 @@ class QgsFieldExpressionWidget : QWidget
5353
*/
5454
QString asExpression() const;
5555

56+
/**
57+
* Returns the currently selected field or expression. If a field is currently selected, the returned
58+
* value will be converted to a valid expression referencing this field (ie enclosing the field name with
59+
* appropriate quotations).
60+
*
61+
* Alias for asExpression()
62+
*
63+
* @note added in QGIS 2.18
64+
*/
65+
QString expression() const;
66+
5667
//! Returns the currently used layer
5768
QgsVectorLayer* layer() const;
5869

@@ -90,6 +101,14 @@ class QgsFieldExpressionWidget : QWidget
90101
//! sets the current field or expression in the widget
91102
void setField( const QString &fieldName );
92103

104+
/**
105+
* Sets the current expression text and if applicable also the field.
106+
* Alias for setField.
107+
*
108+
* @note Added in QGIS 2.18
109+
*/
110+
void setExpression( const QString& expression );
111+
93112
protected slots:
94113
//! open the expression dialog to edit the current or add a new expression
95114
void editExpression();

‎python/gui/qgstabwidget.sip

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/***************************************************************************
2+
qgstabwidget.sip - QgsTabWidget
3+
4+
---------------------
5+
begin : 8.9.2016
6+
copyright : (C) 2016 by Matthias Kuhn
7+
email : matthias@opengis.ch
8+
***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
17+
/** \ingroup gui
18+
* The QgsTabWidget class is the same as the QTabWidget but with additional methods to
19+
* temporarily hide/show tabs.
20+
*
21+
* @note Added in QGIS 2.18
22+
*/
23+
class QgsTabWidget : QTabWidget
24+
{
25+
%TypeHeaderCode
26+
#include <qgstabwidget.h>
27+
%End
28+
29+
public:
30+
/**
31+
* Create a new QgsTabWidget with the optionally provided parent.
32+
*
33+
* @note Added in QGIS 2.18
34+
*/
35+
QgsTabWidget( QWidget *parent = nullptr );
36+
37+
/**
38+
* Hides the tab with the given widget
39+
*
40+
* @note Added in QGIS 2.18
41+
*/
42+
void hideTab( QWidget* tab );
43+
44+
/**
45+
* Shows the tab with the given widget
46+
*
47+
* @note Added in QGIS 2.18
48+
*/
49+
void showTab( QWidget* tab );
50+
51+
/**
52+
* Control the visibility for the tab with the given widget.
53+
*
54+
* @note Added in QGIS 2.18
55+
*/
56+
void setTabVisible( QWidget* tab, bool visible );
57+
58+
/**
59+
* Returns the index of the tab with the given widget.
60+
* This index is not the same as the one provided to insertTab and removeTab
61+
* since these methods are not aware of hidden tabs.
62+
*
63+
* @note Added in QGIS 2.18
64+
*/
65+
int realTabIndex( QWidget* widget );
66+
67+
/**
68+
* Is called internally whenever a new tab has been inserted.
69+
*
70+
* Is used to keep track of currently available and visible tabs.
71+
*
72+
* @note Added in QGIS 2.18
73+
*/
74+
virtual void tabInserted( int index );
75+
76+
/**
77+
* Is called internally whenever a tab has been removed.
78+
*
79+
* Is used to keep track of currently available and visible tabs.
80+
*
81+
* @note Added in QGIS 2.18
82+
*/
83+
virtual void tabRemoved( int index );
84+
};

‎src/app/qgsfieldsproperties.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "qgsrelationmanager.h"
2929
#include "qgsvectordataprovider.h"
3030
#include "qgsvectorlayer.h"
31+
#include "qgsfieldexpressionwidget.h"
3132

3233
#include <QTreeWidgetItem>
3334
#include <QWidget>
@@ -73,7 +74,7 @@ QgsFieldsProperties::QgsFieldsProperties( QgsVectorLayer *layer, QWidget* parent
7374
// tab and group display
7475
mAddItemButton->setEnabled( false );
7576

76-
mDesignerTree = new DesignerTree( mAttributesTreeFrame );
77+
mDesignerTree = new DesignerTree( mLayer, mAttributesTreeFrame );
7778
mDesignerListLayout->addWidget( mDesignerTree );
7879
mDesignerTree->setHeaderLabels( QStringList() << tr( "Label" ) );
7980

@@ -155,7 +156,7 @@ void QgsFieldsProperties::onAttributeSelectionChanged()
155156
updateButtons();
156157
}
157158

158-
QTreeWidgetItem *QgsFieldsProperties::loadAttributeEditorTreeItem( QgsAttributeEditorElement* const widgetDef, QTreeWidgetItem* parent )
159+
QTreeWidgetItem* QgsFieldsProperties::loadAttributeEditorTreeItem( QgsAttributeEditorElement* const widgetDef, QTreeWidgetItem* parent )
159160
{
160161
QTreeWidgetItem* newWidget = nullptr;
161162
switch ( widgetDef->type() )
@@ -188,6 +189,7 @@ QTreeWidgetItem *QgsFieldsProperties::loadAttributeEditorTreeItem( QgsAttributeE
188189

189190
itemData.setColumnCount( container->columnCount() );
190191
itemData.setShowAsGroupBox( container->isGroupBox() );
192+
itemData.setVisibilityExpression( container->visibilityExpression() );
191193
newWidget = mDesignerTree->addItem( parent, itemData );
192194

193195
Q_FOREACH ( QgsAttributeEditorElement* wdg, container->children() )
@@ -901,6 +903,7 @@ QgsAttributeEditorElement* QgsFieldsProperties::createAttributeEditorWidget( QTr
901903
QgsAttributeEditorContainer* container = new QgsAttributeEditorContainer( item->text( 0 ), parent );
902904
container->setColumnCount( itemData.columnCount() );
903905
container->setIsGroupBox( forceGroup ? true : itemData.showAsGroupBox() );
906+
container->setVisibilityExpression( itemData.visibilityExpression() );
904907

905908
for ( int t = 0; t < item->childCount(); t++ )
906909
{
@@ -1124,8 +1127,9 @@ QTreeWidgetItem* DesignerTree::addContainer( QTreeWidgetItem* parent, const QStr
11241127
return newItem;
11251128
}
11261129

1127-
DesignerTree::DesignerTree( QWidget* parent )
1130+
DesignerTree::DesignerTree( QgsVectorLayer* layer, QWidget* parent )
11281131
: QTreeWidget( parent )
1132+
, mLayer( layer )
11291133
{
11301134
connect( this, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( onItemDoubleClicked( QTreeWidgetItem*, int ) ) );
11311135
}
@@ -1303,11 +1307,22 @@ void DesignerTree::onItemDoubleClicked( QTreeWidgetItem* item, int column )
13031307
QCheckBox* showAsGroupBox = nullptr;
13041308
QLineEdit* title = new QLineEdit( itemData.name() );
13051309
QSpinBox* columnCount = new QSpinBox();
1310+
QGroupBox* visibilityExpressionGroupBox = new QGroupBox( tr( "Control visibility by expression " ) );
1311+
visibilityExpressionGroupBox->setCheckable( true );
1312+
visibilityExpressionGroupBox->setChecked( itemData.visibilityExpression().enabled() );
1313+
visibilityExpressionGroupBox->setLayout( new QGridLayout );
1314+
QgsFieldExpressionWidget* visibilityExpressionWidget = new QgsFieldExpressionWidget;
1315+
visibilityExpressionWidget->setLayer( mLayer );
1316+
visibilityExpressionWidget->setExpressionDialogTitle( tr( "Visibility expression" ) );
1317+
visibilityExpressionWidget->setExpression( itemData.visibilityExpression()->expression() );
1318+
visibilityExpressionGroupBox->layout()->addWidget( visibilityExpressionWidget );
1319+
13061320
columnCount->setRange( 1, 5 );
13071321
columnCount->setValue( itemData.columnCount() );
13081322

13091323
layout->addRow( tr( "Title" ), title );
13101324
layout->addRow( tr( "Column count" ), columnCount );
1325+
layout->addWidget( visibilityExpressionGroupBox );
13111326

13121327
if ( !item->parent() )
13131328
{
@@ -1331,6 +1346,11 @@ void DesignerTree::onItemDoubleClicked( QTreeWidgetItem* item, int column )
13311346
itemData.setName( title->text() );
13321347
itemData.setShowLabel( showLabelCheckbox->isChecked() );
13331348

1349+
QgsOptionalExpression visibilityExpression;
1350+
visibilityExpression.setData( QgsExpression( visibilityExpressionWidget->expression() ) );
1351+
visibilityExpression.setEnabled( visibilityExpressionGroupBox->isChecked() );
1352+
itemData.setVisibilityExpression( visibilityExpression );
1353+
13341354
item->setData( 0, QgsFieldsProperties::DesignerTreeRole, itemData.asQVariant() );
13351355
item->setText( 0, title->text() );
13361356
}
@@ -1401,3 +1421,13 @@ void QgsFieldsProperties::DesignerTreeItemData::setShowLabel( bool showLabel )
14011421
{
14021422
mShowLabel = showLabel;
14031423
}
1424+
1425+
QgsOptionalExpression QgsFieldsProperties::DesignerTreeItemData::visibilityExpression() const
1426+
{
1427+
return mVisibilityExpression;
1428+
}
1429+
1430+
void QgsFieldsProperties::DesignerTreeItemData::setVisibilityExpression( const QgsOptionalExpression& visibilityExpression )
1431+
{
1432+
mVisibilityExpression = visibilityExpression;
1433+
}

0 commit comments

Comments
 (0)
Please sign in to comment.