Skip to content

Commit

Permalink
Merge pull request #3475 from m-kuhn/visibilityTab218
Browse files Browse the repository at this point in the history
[Feature] conditional visibility for tabs and groupboxes (backport)
  • Loading branch information
m-kuhn committed Sep 13, 2016
2 parents ee9c684 + 39f7c04 commit ddc76e2
Show file tree
Hide file tree
Showing 28 changed files with 1,098 additions and 16 deletions.
1 change: 1 addition & 0 deletions python/core/core.sip
Expand Up @@ -101,6 +101,7 @@
%Include qgsobjectcustomproperties.sip
%Include qgsofflineediting.sip
%Include qgsogcutils.sip
%Include qgsoptionalexpression.sip
%Include qgsowsconnection.sip
%Include qgspaintenginehack.sip
%Include qgspallabeling.sip
Expand Down
14 changes: 14 additions & 0 deletions python/core/qgseditformconfig.sip
Expand Up @@ -179,6 +179,20 @@ class QgsAttributeEditorContainer : QgsAttributeEditorElement
*/
void setColumnCount( int columnCount );

/**
* An expression that controls the visibility of this container.
*
* @note Added in QGIS 2.18
*/
QgsOptionalExpression visibilityExpression() const;

/**
* An expression that controls the visibility of this container.
*
* @note Added in QGIS 2.18
*/
void setVisibilityExpression( const QgsOptionalExpression& visibilityExpression );

};

/**
Expand Down
22 changes: 22 additions & 0 deletions python/core/qgsexpression.sip
Expand Up @@ -12,8 +12,23 @@ class QgsExpression
* loop in which this expression is used.
*/
QgsExpression( const QString& expr );
/**
* Create an empty expression.
*
* @note Added in QGIS 2.18
*/
QgsExpression();

~QgsExpression();

/**
* Checks if this expression is valid.
* A valid expression could be parsed but does not necessarily evaluate properly.
*
* @note Added in QGIS 2.18
*/
bool isValid() const;

//! Returns true if an error occurred when parsing the input expression
bool hasParserError() const;
//! Returns parser error
Expand Down Expand Up @@ -135,6 +150,13 @@ class QgsExpression

double scale();

/**
* Set the expression string, will reset the whole internal structure.
*
* @note Added in QGIS 2.18
*/
void setExpression( const QString& expression );

//! Return the original, unmodified expression string.
//! If there was none supplied because it was constructed by sole
//! API calls, dump() will be used to create one instead.
Expand Down
83 changes: 83 additions & 0 deletions python/core/qgsoptionalexpression.sip
@@ -0,0 +1,83 @@
/***************************************************************************
qgsoptionalexpression.sip - QgsOptionalExpression

---------------------
begin : 8.9.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

/**
* \ingroup core
*
* QgsOptionalExpression is a container for an expression with an additional enabled/disabled flag.
*
* @note Added in QGIS 3.0
*/
class QgsOptionalExpression
{
%TypeHeaderCode
#include <qgsoptionalexpression.h>
%End
public:
/**
* A QgsOptionalExpression is disabled by default if default constructed.
*/
QgsOptionalExpression();

/**
* A QgsOptionalExpression is enabled by default if constructed with an expression.
*/
QgsOptionalExpression( const QgsExpression& data );

/**
* A QgsOptionalExptression constructed with enabled status and data
*/
QgsOptionalExpression( const QgsExpression& data, bool enabled );

/**
* Compare this QgsOptionalExptression to another one.
*
* This will compare the enabled flag and call the == operator
* of the contained class.
*
* @note Added in QGIS 3.0
*/
bool operator== ( const QgsOptionalExpression& other ) const;
operator bool () const;

/**
* Check if this optional is enabled
*
* @note Added in QGIS 3.0
*/
bool enabled() const;

/**
* Set if this optional is enabled
*
* @note Added in QGIS 3.0
*/
void setEnabled( bool enabled );

/**
* Access the payload data
*
* @note Added in QGIS 3.0
*/
QgsExpression data() const;

/**
* Set the payload data
*
* @note Added in QGIS 3.0
*/
void setData( const QgsExpression& data );
};
1 change: 1 addition & 0 deletions python/gui/gui.sip
Expand Up @@ -160,6 +160,7 @@
%Include qgssourceselectdialog.sip
%Include qgssublayersdialog.sip
%Include qgssvgannotationitem.sip
%Include qgstabwidget.sip
%Include qgstablewidgetitem.sip
%Include qgstextannotationitem.sip
%Include qgstrackedvectorlayertools.sip
Expand Down
19 changes: 19 additions & 0 deletions python/gui/qgsfieldexpressionwidget.sip
Expand Up @@ -53,6 +53,17 @@ class QgsFieldExpressionWidget : QWidget
*/
QString asExpression() const;

/**
* Returns the currently selected field or expression. If a field is currently selected, the returned
* value will be converted to a valid expression referencing this field (ie enclosing the field name with
* appropriate quotations).
*
* Alias for asExpression()
*
* @note added in QGIS 2.18
*/
QString expression() const;

//! Returns the currently used layer
QgsVectorLayer* layer() const;

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

/**
* Sets the current expression text and if applicable also the field.
* Alias for setField.
*
* @note Added in QGIS 2.18
*/
void setExpression( const QString& expression );

protected slots:
//! open the expression dialog to edit the current or add a new expression
void editExpression();
Expand Down
84 changes: 84 additions & 0 deletions python/gui/qgstabwidget.sip
@@ -0,0 +1,84 @@
/***************************************************************************
qgstabwidget.sip - QgsTabWidget

---------------------
begin : 8.9.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

/** \ingroup gui
* The QgsTabWidget class is the same as the QTabWidget but with additional methods to
* temporarily hide/show tabs.
*
* @note Added in QGIS 2.18
*/
class QgsTabWidget : QTabWidget
{
%TypeHeaderCode
#include <qgstabwidget.h>
%End

public:
/**
* Create a new QgsTabWidget with the optionally provided parent.
*
* @note Added in QGIS 2.18
*/
QgsTabWidget( QWidget *parent = nullptr );

/**
* Hides the tab with the given widget
*
* @note Added in QGIS 2.18
*/
void hideTab( QWidget* tab );

/**
* Shows the tab with the given widget
*
* @note Added in QGIS 2.18
*/
void showTab( QWidget* tab );

/**
* Control the visibility for the tab with the given widget.
*
* @note Added in QGIS 2.18
*/
void setTabVisible( QWidget* tab, bool visible );

/**
* Returns the index of the tab with the given widget.
* This index is not the same as the one provided to insertTab and removeTab
* since these methods are not aware of hidden tabs.
*
* @note Added in QGIS 2.18
*/
int realTabIndex( QWidget* widget );

/**
* Is called internally whenever a new tab has been inserted.
*
* Is used to keep track of currently available and visible tabs.
*
* @note Added in QGIS 2.18
*/
virtual void tabInserted( int index );

/**
* Is called internally whenever a tab has been removed.
*
* Is used to keep track of currently available and visible tabs.
*
* @note Added in QGIS 2.18
*/
virtual void tabRemoved( int index );
};
36 changes: 33 additions & 3 deletions src/app/qgsfieldsproperties.cpp
Expand Up @@ -28,6 +28,7 @@
#include "qgsrelationmanager.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"
#include "qgsfieldexpressionwidget.h"

#include <QTreeWidgetItem>
#include <QWidget>
Expand Down Expand Up @@ -73,7 +74,7 @@ QgsFieldsProperties::QgsFieldsProperties( QgsVectorLayer *layer, QWidget* parent
// tab and group display
mAddItemButton->setEnabled( false );

mDesignerTree = new DesignerTree( mAttributesTreeFrame );
mDesignerTree = new DesignerTree( mLayer, mAttributesTreeFrame );
mDesignerListLayout->addWidget( mDesignerTree );
mDesignerTree->setHeaderLabels( QStringList() << tr( "Label" ) );

Expand Down Expand Up @@ -155,7 +156,7 @@ void QgsFieldsProperties::onAttributeSelectionChanged()
updateButtons();
}

QTreeWidgetItem *QgsFieldsProperties::loadAttributeEditorTreeItem( QgsAttributeEditorElement* const widgetDef, QTreeWidgetItem* parent )
QTreeWidgetItem* QgsFieldsProperties::loadAttributeEditorTreeItem( QgsAttributeEditorElement* const widgetDef, QTreeWidgetItem* parent )
{
QTreeWidgetItem* newWidget = nullptr;
switch ( widgetDef->type() )
Expand Down Expand Up @@ -188,6 +189,7 @@ QTreeWidgetItem *QgsFieldsProperties::loadAttributeEditorTreeItem( QgsAttributeE

itemData.setColumnCount( container->columnCount() );
itemData.setShowAsGroupBox( container->isGroupBox() );
itemData.setVisibilityExpression( container->visibilityExpression() );
newWidget = mDesignerTree->addItem( parent, itemData );

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

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

DesignerTree::DesignerTree( QWidget* parent )
DesignerTree::DesignerTree( QgsVectorLayer* layer, QWidget* parent )
: QTreeWidget( parent )
, mLayer( layer )
{
connect( this, SIGNAL( itemDoubleClicked( QTreeWidgetItem*, int ) ), this, SLOT( onItemDoubleClicked( QTreeWidgetItem*, int ) ) );
}
Expand Down Expand Up @@ -1303,11 +1307,22 @@ void DesignerTree::onItemDoubleClicked( QTreeWidgetItem* item, int column )
QCheckBox* showAsGroupBox = nullptr;
QLineEdit* title = new QLineEdit( itemData.name() );
QSpinBox* columnCount = new QSpinBox();
QGroupBox* visibilityExpressionGroupBox = new QGroupBox( tr( "Control visibility by expression " ) );
visibilityExpressionGroupBox->setCheckable( true );
visibilityExpressionGroupBox->setChecked( itemData.visibilityExpression().enabled() );
visibilityExpressionGroupBox->setLayout( new QGridLayout );
QgsFieldExpressionWidget* visibilityExpressionWidget = new QgsFieldExpressionWidget;
visibilityExpressionWidget->setLayer( mLayer );
visibilityExpressionWidget->setExpressionDialogTitle( tr( "Visibility expression" ) );
visibilityExpressionWidget->setExpression( itemData.visibilityExpression()->expression() );
visibilityExpressionGroupBox->layout()->addWidget( visibilityExpressionWidget );

columnCount->setRange( 1, 5 );
columnCount->setValue( itemData.columnCount() );

layout->addRow( tr( "Title" ), title );
layout->addRow( tr( "Column count" ), columnCount );
layout->addWidget( visibilityExpressionGroupBox );

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

QgsOptionalExpression visibilityExpression;
visibilityExpression.setData( QgsExpression( visibilityExpressionWidget->expression() ) );
visibilityExpression.setEnabled( visibilityExpressionGroupBox->isChecked() );
itemData.setVisibilityExpression( visibilityExpression );

item->setData( 0, QgsFieldsProperties::DesignerTreeRole, itemData.asQVariant() );
item->setText( 0, title->text() );
}
Expand Down Expand Up @@ -1401,3 +1421,13 @@ void QgsFieldsProperties::DesignerTreeItemData::setShowLabel( bool showLabel )
{
mShowLabel = showLabel;
}

QgsOptionalExpression QgsFieldsProperties::DesignerTreeItemData::visibilityExpression() const
{
return mVisibilityExpression;
}

void QgsFieldsProperties::DesignerTreeItemData::setVisibilityExpression( const QgsOptionalExpression& visibilityExpression )
{
mVisibilityExpression = visibilityExpression;
}

0 comments on commit ddc76e2

Please sign in to comment.