From c672893e9c117ce8ad7f8d8edf88f238205f2e0e Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Sun, 24 Feb 2019 13:14:32 +0100 Subject: [PATCH 1/5] Typo --- src/gui/qgscollapsiblegroupbox.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/qgscollapsiblegroupbox.h b/src/gui/qgscollapsiblegroupbox.h index f1bd36b4125..98dbe49de4f 100644 --- a/src/gui/qgscollapsiblegroupbox.h +++ b/src/gui/qgscollapsiblegroupbox.h @@ -171,7 +171,7 @@ class GUI_EXPORT QgsCollapsibleGroupBoxBasic : public QGroupBox * Holding Alt modifier key when toggling collapsed state will synchronize the toggling across other collapsible group boxes with the same syncGroup QString value * Holding Shift modifier key when attempting to toggle collapsed state will expand current group box, then collapse any others with the same syncGroup QString value * \see basic class QgsCollapsibleGroupBoxBasic which does not auto-save states - * \note To add Collapsible properties in promoted QtDesigner widgets, you can add the following "Dynamic properties" by clicking on the green + in the propreties palette: + * \note To add Collapsible properties in promoted QtDesigner widgets, you can add the following "Dynamic properties" by clicking on the green + in the properties palette: * bool collapsed, bool saveCollapsedState, bool saveCheckedState, QString syncGroup */ From 8d3f73a62a087d4842511563b15307ba4101e983 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Sun, 24 Feb 2019 13:18:29 +0100 Subject: [PATCH 2/5] [feature][needs-docs] Add bg color option to form containers Because gray is boring. --- .../qgsattributeeditorelement.sip.in | 16 ++++++++++- .../qgscollapsiblegroupbox.sip.in | 2 +- src/app/qgsattributesformproperties.cpp | 28 ++++++++++++++++++- src/app/qgsattributesformproperties.h | 7 ++++- src/core/qgsattributeeditorelement.cpp | 10 +++++++ src/core/qgsattributeeditorelement.h | 17 ++++++++++- src/core/qgseditformconfig.cpp | 7 +++-- src/gui/qgsattributeform.cpp | 10 +++++++ 8 files changed, 90 insertions(+), 7 deletions(-) diff --git a/python/core/auto_generated/qgsattributeeditorelement.sip.in b/python/core/auto_generated/qgsattributeeditorelement.sip.in index afc767d3e11..3785e22283f 100644 --- a/python/core/auto_generated/qgsattributeeditorelement.sip.in +++ b/python/core/auto_generated/qgsattributeeditorelement.sip.in @@ -130,7 +130,7 @@ attribute form if it is set to the drag and drop designer. %End public: - QgsAttributeEditorContainer( const QString &name, QgsAttributeEditorElement *parent ); + QgsAttributeEditorContainer( const QString &name, QgsAttributeEditorElement *parent, const QColor &backgroundColor = QColor() ); %Docstring Creates a new attribute editor container @@ -222,6 +222,20 @@ show or hide this container based on an expression incorporating the field value controlled by editor widgets. .. versionadded:: 3.0 +%End + + QColor backgroundColor() const; +%Docstring +backgroundColor + +:return: background color of the container + +.. versionadded:: 3.8 +%End + + void setBackgroundColor( const QColor &backgroundColor ); +%Docstring +Sets the background color to ``backgroundColor`` %End }; diff --git a/python/gui/auto_generated/qgscollapsiblegroupbox.sip.in b/python/gui/auto_generated/qgscollapsiblegroupbox.sip.in index 67defaa961e..6157ea019eb 100644 --- a/python/gui/auto_generated/qgscollapsiblegroupbox.sip.in +++ b/python/gui/auto_generated/qgscollapsiblegroupbox.sip.in @@ -134,7 +134,7 @@ Holding Shift modifier key when attempting to toggle collapsed state will expand .. note:: - To add Collapsible properties in promoted QtDesigner widgets, you can add the following "Dynamic properties" by clicking on the green + in the propreties palette: + To add Collapsible properties in promoted QtDesigner widgets, you can add the following "Dynamic properties" by clicking on the green + in the properties palette: bool collapsed, bool saveCollapsedState, bool saveCheckedState, QString syncGroup %End diff --git a/src/app/qgsattributesformproperties.cpp b/src/app/qgsattributesformproperties.cpp index 5d3c68792ba..5851210c74a 100644 --- a/src/app/qgsattributesformproperties.cpp +++ b/src/app/qgsattributesformproperties.cpp @@ -21,6 +21,7 @@ #include "qgsfieldcombobox.h" #include "qgsqmlwidgetwrapper.h" #include "qgsapplication.h" +#include "qgscolorbutton.h" QgsAttributesFormProperties::QgsAttributesFormProperties( QgsVectorLayer *layer, QWidget *parent ) : QWidget( parent ) @@ -451,6 +452,7 @@ QTreeWidgetItem *QgsAttributesFormProperties::loadAttributeEditorTreeItem( QgsAt itemData.setColumnCount( container->columnCount() ); itemData.setShowAsGroupBox( container->isGroupBox() ); + itemData.setBackgroundColor( container->backgroundColor() ); itemData.setVisibilityExpression( container->visibilityExpression() ); newWidget = tree->addItem( parent, itemData ); @@ -582,10 +584,11 @@ QgsAttributeEditorElement *QgsAttributesFormProperties::createAttributeEditorWid case DnDTreeItemData::Container: { - QgsAttributeEditorContainer *container = new QgsAttributeEditorContainer( item->text( 0 ), parent ); + QgsAttributeEditorContainer *container = new QgsAttributeEditorContainer( item->text( 0 ), parent, itemData.backgroundColor() ); container->setColumnCount( itemData.columnCount() ); container->setIsGroupBox( forceGroup ? true : itemData.showAsGroupBox() ); container->setVisibilityExpression( itemData.visibilityExpression() ); + container->setBackgroundColor( itemData.backgroundColor( ) ); for ( int t = 0; t < item->childCount(); t++ ) { @@ -1014,6 +1017,7 @@ void DnDTree::onItemDoubleClicked( QTreeWidgetItem *item, int column ) case QgsAttributesFormProperties::DnDTreeItemData::Container: { QDialog dlg; + dlg.setObjectName( QLatin1Literal( "attributeFormPropertiesContainerDialog" ) ); dlg.setWindowTitle( tr( "Configure Container" ) ); QFormLayout *layout = new QFormLayout() ; dlg.setLayout( layout ); @@ -1046,6 +1050,17 @@ void DnDTree::onItemDoubleClicked( QTreeWidgetItem *item, int column ) layout->addRow( showAsGroupBox ); } + QgsCollapsibleGroupBox *styleGroupBox = new QgsCollapsibleGroupBox( tr( "Style" ), layout->widget() ); + styleGroupBox->setObjectName( QLatin1Literal( "attributeFormPropertiesContainerStyle" ) ); + QFormLayout *customizeGroupBoxLayout = new QFormLayout( styleGroupBox ) ; + QgsColorButton *backgroundColorButton = new QgsColorButton( styleGroupBox, tr( "Select the background color for the container" ) ); + backgroundColorButton->setShowNull( true ); + backgroundColorButton->setColor( itemData.backgroundColor() ); + customizeGroupBoxLayout->addRow( new QLabel( tr( "Background color" ), styleGroupBox ), + backgroundColorButton ); + styleGroupBox->setLayout( customizeGroupBoxLayout ); + layout->addRow( styleGroupBox ); + QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel ); @@ -1060,6 +1075,7 @@ void DnDTree::onItemDoubleClicked( QTreeWidgetItem *item, int column ) itemData.setShowAsGroupBox( showAsGroupBox ? showAsGroupBox->isChecked() : true ); itemData.setName( title->text() ); itemData.setShowLabel( showLabelCheckbox->isChecked() ); + itemData.setBackgroundColor( backgroundColorButton->color() ); QgsOptionalExpression visibilityExpression; visibilityExpression.setData( QgsExpression( visibilityExpressionWidget->expression() ) ); @@ -1379,3 +1395,13 @@ void QgsAttributesFormProperties::DnDTreeItemData::setQmlElementEditorConfigurat mQmlElementEditorConfiguration = qmlElementEditorConfiguration; } +QColor QgsAttributesFormProperties::DnDTreeItemData::backgroundColor() const +{ + return mBackgroundColor; +} + +void QgsAttributesFormProperties::DnDTreeItemData::setBackgroundColor( const QColor &backgroundColor ) +{ + mBackgroundColor = backgroundColor; +} + diff --git a/src/app/qgsattributesformproperties.h b/src/app/qgsattributesformproperties.h index b54a978ce11..3d03e4fb785 100644 --- a/src/app/qgsattributesformproperties.h +++ b/src/app/qgsattributesformproperties.h @@ -88,10 +88,11 @@ class APP_EXPORT QgsAttributesFormProperties : public QWidget, private Ui_QgsAtt //do we need that DnDTreeItemData() = default; - DnDTreeItemData( Type type, const QString &name, const QString &displayName ) + DnDTreeItemData( Type type, const QString &name, const QString &displayName, const QColor &backgroundColor = QColor() ) : mType( type ) , mName( name ) , mDisplayName( displayName ) + , mBackgroundColor( backgroundColor ) {} QString name() const { return mName; } @@ -123,6 +124,9 @@ class APP_EXPORT QgsAttributesFormProperties : public QWidget, private Ui_QgsAtt QmlElementEditorConfiguration qmlElementEditorConfiguration() const; void setQmlElementEditorConfiguration( QmlElementEditorConfiguration qmlElementEditorConfiguration ); + QColor backgroundColor() const; + void setBackgroundColor( const QColor &backgroundColor ); + private: Type mType = Field; QString mName; @@ -134,6 +138,7 @@ class APP_EXPORT QgsAttributesFormProperties : public QWidget, private Ui_QgsAtt QgsOptionalExpression mVisibilityExpression; RelationEditorConfiguration mRelationEditorConfiguration; QmlElementEditorConfiguration mQmlElementEditorConfiguration; + QColor mBackgroundColor; }; diff --git a/src/core/qgsattributeeditorelement.cpp b/src/core/qgsattributeeditorelement.cpp index 8b534ea15b0..4ab73da95e4 100644 --- a/src/core/qgsattributeeditorelement.cpp +++ b/src/core/qgsattributeeditorelement.cpp @@ -39,6 +39,16 @@ void QgsAttributeEditorContainer::setVisibilityExpression( const QgsOptionalExpr mVisibilityExpression = visibilityExpression; } +QColor QgsAttributeEditorContainer::backgroundColor() const +{ + return mBackgroundColor; +} + +void QgsAttributeEditorContainer::setBackgroundColor( const QColor &backgroundColor ) +{ + mBackgroundColor = backgroundColor; +} + QList QgsAttributeEditorContainer::findElements( QgsAttributeEditorElement::AttributeEditorType type ) const { QList results; diff --git a/src/core/qgsattributeeditorelement.h b/src/core/qgsattributeeditorelement.h index 15927a9d0a6..688156dd94a 100644 --- a/src/core/qgsattributeeditorelement.h +++ b/src/core/qgsattributeeditorelement.h @@ -19,6 +19,7 @@ #include "qgis_core.h" #include "qgsrelation.h" #include "qgsoptionalexpression.h" +#include class QgsRelationManager; @@ -174,10 +175,11 @@ class CORE_EXPORT QgsAttributeEditorContainer : public QgsAttributeEditorElement * \param name The name to show as title * \param parent The parent. May be another container. */ - QgsAttributeEditorContainer( const QString &name, QgsAttributeEditorElement *parent ) + QgsAttributeEditorContainer( const QString &name, QgsAttributeEditorElement *parent, const QColor &backgroundColor = QColor() ) : QgsAttributeEditorElement( AeTypeContainer, name, parent ) , mIsGroupBox( true ) , mColumnCount( 1 ) + , mBackgroundColor( backgroundColor ) {} @@ -265,6 +267,18 @@ class CORE_EXPORT QgsAttributeEditorContainer : public QgsAttributeEditorElement */ void setVisibilityExpression( const QgsOptionalExpression &visibilityExpression ); + /** + * \brief backgroundColor + * \return background color of the container + * \since QGIS 3.8 + */ + QColor backgroundColor() const; + + /** + * Sets the background color to \a backgroundColor + */ + void setBackgroundColor( const QColor &backgroundColor ); + private: void saveConfiguration( QDomElement &elem ) const override; QString typeIdentifier() const override; @@ -273,6 +287,7 @@ class CORE_EXPORT QgsAttributeEditorContainer : public QgsAttributeEditorElement QList mChildren; int mColumnCount; QgsOptionalExpression mVisibilityExpression; + QColor mBackgroundColor; }; /** diff --git a/src/core/qgseditformconfig.cpp b/src/core/qgseditformconfig.cpp index 9e4ce27daf4..1d700f3b3bd 100644 --- a/src/core/qgseditformconfig.cpp +++ b/src/core/qgseditformconfig.cpp @@ -525,7 +525,9 @@ QgsAttributeEditorElement *QgsEditFormConfig::attributeEditorElementFromDomEleme if ( elem.tagName() == QLatin1String( "attributeEditorContainer" ) ) { - QgsAttributeEditorContainer *container = new QgsAttributeEditorContainer( context.projectTranslator()->translate( QStringLiteral( "project:layers:%1:formcontainers" ).arg( layerId ), elem.attribute( QStringLiteral( "name" ) ) ), parent ); + QColor backgroundColor( elem.attribute( QStringLiteral( "backgroundColor" ), QString() ) ); + QgsAttributeEditorContainer *container = new QgsAttributeEditorContainer( context.projectTranslator()->translate( QStringLiteral( "project:layers:%1:formcontainers" ).arg( layerId ), + elem.attribute( QStringLiteral( "name" ) ) ), parent, backgroundColor ); bool ok; int cc = elem.attribute( QStringLiteral( "columnCount" ) ).toInt( &ok ); if ( !ok ) @@ -625,7 +627,8 @@ void QgsAttributeEditorContainer::saveConfiguration( QDomElement &elem ) const elem.setAttribute( QStringLiteral( "groupBox" ), mIsGroupBox ? 1 : 0 ); elem.setAttribute( QStringLiteral( "visibilityExpressionEnabled" ), mVisibilityExpression.enabled() ? 1 : 0 ); elem.setAttribute( QStringLiteral( "visibilityExpression" ), mVisibilityExpression->expression() ); - + if ( mBackgroundColor.isValid() ) + elem.setAttribute( QStringLiteral( "backgroundColor" ), mBackgroundColor.name( ) ); Q_FOREACH ( QgsAttributeEditorElement *child, mChildren ) { QDomDocument doc = elem.ownerDocument(); diff --git a/src/gui/qgsattributeform.cpp b/src/gui/qgsattributeform.cpp index 8d63e3a8523..208957aa6fe 100644 --- a/src/gui/qgsattributeform.cpp +++ b/src/gui/qgsattributeform.cpp @@ -1707,10 +1707,12 @@ QgsAttributeForm::WidgetInfo QgsAttributeForm::createWidgetFromDef( const QgsAtt if ( columnCount <= 0 ) columnCount = 1; + QString widgetName; QWidget *myContainer = nullptr; if ( container->isGroupBox() ) { QGroupBox *groupBox = new QGroupBox( parent ); + widgetName = QStringLiteral( "QGroupBox" ); if ( container->showLabel() ) groupBox->setTitle( container->name() ); myContainer = groupBox; @@ -1727,15 +1729,23 @@ QgsAttributeForm::WidgetInfo QgsAttributeForm::createWidgetFromDef( const QgsAtt scrollArea->setWidget( myContainer ); scrollArea->setWidgetResizable( true ); scrollArea->setFrameShape( QFrame::NoFrame ); + widgetName = QStringLiteral( "QScrollArea QWidget" ); newWidgetInfo.widget = scrollArea; } else { newWidgetInfo.widget = myContainer; + widgetName = QStringLiteral( "QWidget" ); } } + if ( container->backgroundColor().isValid() ) + { + QString style {QStringLiteral( "background-color: %1;" ).arg( container->backgroundColor().name() )}; + newWidgetInfo.widget->setStyleSheet( style ); + } + QGridLayout *gbLayout = new QGridLayout(); myContainer->setLayout( gbLayout ); From 6bdabcfe883f1cf887cf2621713f3c65fb7e7c53 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Sun, 24 Feb 2019 13:29:25 +0100 Subject: [PATCH 3/5] Doc for the new backgroundColor argument --- python/core/auto_generated/qgsattributeeditorelement.sip.in | 1 + src/core/qgsattributeeditorelement.h | 1 + 2 files changed, 2 insertions(+) diff --git a/python/core/auto_generated/qgsattributeeditorelement.sip.in b/python/core/auto_generated/qgsattributeeditorelement.sip.in index 3785e22283f..4428dd6f4c9 100644 --- a/python/core/auto_generated/qgsattributeeditorelement.sip.in +++ b/python/core/auto_generated/qgsattributeeditorelement.sip.in @@ -136,6 +136,7 @@ Creates a new attribute editor container :param name: The name to show as title :param parent: The parent. May be another container. +:param backgroundColor: The optional background color of the container. %End diff --git a/src/core/qgsattributeeditorelement.h b/src/core/qgsattributeeditorelement.h index 688156dd94a..939f09550ac 100644 --- a/src/core/qgsattributeeditorelement.h +++ b/src/core/qgsattributeeditorelement.h @@ -174,6 +174,7 @@ class CORE_EXPORT QgsAttributeEditorContainer : public QgsAttributeEditorElement * * \param name The name to show as title * \param parent The parent. May be another container. + * \param backgroundColor The optional background color of the container. */ QgsAttributeEditorContainer( const QString &name, QgsAttributeEditorElement *parent, const QColor &backgroundColor = QColor() ) : QgsAttributeEditorElement( AeTypeContainer, name, parent ) From e63b2ef69ce3a8dd19ebb16e213223c45211e53d Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Mon, 25 Feb 2019 09:03:08 +0100 Subject: [PATCH 4/5] Rename container background color dialog title --- src/app/qgsattributesformproperties.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/qgsattributesformproperties.cpp b/src/app/qgsattributesformproperties.cpp index 5851210c74a..4722ed50256 100644 --- a/src/app/qgsattributesformproperties.cpp +++ b/src/app/qgsattributesformproperties.cpp @@ -1053,7 +1053,7 @@ void DnDTree::onItemDoubleClicked( QTreeWidgetItem *item, int column ) QgsCollapsibleGroupBox *styleGroupBox = new QgsCollapsibleGroupBox( tr( "Style" ), layout->widget() ); styleGroupBox->setObjectName( QLatin1Literal( "attributeFormPropertiesContainerStyle" ) ); QFormLayout *customizeGroupBoxLayout = new QFormLayout( styleGroupBox ) ; - QgsColorButton *backgroundColorButton = new QgsColorButton( styleGroupBox, tr( "Select the background color for the container" ) ); + QgsColorButton *backgroundColorButton = new QgsColorButton( styleGroupBox, tr( "Container Background Color" ) ); backgroundColorButton->setShowNull( true ); backgroundColorButton->setColor( itemData.backgroundColor() ); customizeGroupBoxLayout->addRow( new QLabel( tr( "Background color" ), styleGroupBox ), From 94b5fed57ae337500d3fecca9c87aba42f5ba102 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Mon, 25 Feb 2019 09:03:33 +0100 Subject: [PATCH 5/5] Add test case for backgroundColor serialization --- tests/src/python/test_qgseditformconfig.py | 24 +++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/src/python/test_qgseditformconfig.py b/tests/src/python/test_qgseditformconfig.py index 4b91bd465ab..ee983d7a017 100644 --- a/tests/src/python/test_qgseditformconfig.py +++ b/tests/src/python/test_qgseditformconfig.py @@ -20,11 +20,14 @@ from qgis.core import (QgsApplication, QgsVectorLayer, QgsReadWriteContext, QgsEditFormConfig, - QgsFetchedContent) + QgsFetchedContent, + QgsAttributeEditorContainer, + ) from qgis.gui import QgsGui from qgis.testing import start_app, unittest from qgis.PyQt.QtXml import QDomDocument, QDomElement +from qgis.PyQt.QtGui import QColor from utilities import unitTestDataPath import socketserver import threading @@ -84,14 +87,16 @@ class TestQgsEditFormConfig(unittest.TestCase): config.setLayout(QgsEditFormConfig.GeneratedLayout) self.assertEqual(config.layout(), QgsEditFormConfig.GeneratedLayout) - uiLocal = os.path.join(unitTestDataPath(), '/qgis_local_server/layer_attribute_form.ui') + uiLocal = os.path.join( + unitTestDataPath(), '/qgis_local_server/layer_attribute_form.ui') config.setUiForm(uiLocal) self.assertEqual(config.layout(), QgsEditFormConfig.UiFileLayout) config.setLayout(QgsEditFormConfig.GeneratedLayout) self.assertEqual(config.layout(), QgsEditFormConfig.GeneratedLayout) - uiUrl = 'http://localhost:' + str(self.port) + '/qgis_local_server/layer_attribute_form.ui' + uiUrl = 'http://localhost:' + \ + str(self.port) + '/qgis_local_server/layer_attribute_form.ui' config.setUiForm(uiUrl) self.assertEqual(config.layout(), QgsEditFormConfig.UiFileLayout) content = QgsApplication.networkContentFetcherRegistry().fetch(uiUrl) @@ -140,6 +145,19 @@ class TestQgsEditFormConfig(unittest.TestCase): self.assertFalse(config.labelOnTop(0)) self.assertFalse(config.labelOnTop(1)) + def test_backgroundColorSerialize(self): + """Test backgroundColor serialization""" + + layer = self.createLayer() + config = layer.editFormConfig() + color_name = '#ff00ff' + container = QgsAttributeEditorContainer('container name', None, QColor('#ff00ff')) + doc = QDomDocument() + element = container.toDomElement(doc) + config = QgsEditFormConfig() + container2 = config.attributeEditorElementFromDomElement(element, None, self.layer.id()) + self.assertEqual(container2.backgroundColor().name(), color_name) + if __name__ == '__main__': unittest.main()