Skip to content

Commit

Permalink
Merge pull request #9260 from elpaso/form-background-color
Browse files Browse the repository at this point in the history
Add bg color option to form containers
  • Loading branch information
elpaso committed Feb 25, 2019
2 parents 77f500b + 94b5fed commit a615a3b
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 11 deletions.
17 changes: 16 additions & 1 deletion python/core/auto_generated/qgsattributeeditorelement.sip.in
Expand Up @@ -130,12 +130,13 @@ 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

: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


Expand Down Expand Up @@ -222,6 +223,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

};
Expand Down
2 changes: 1 addition & 1 deletion python/gui/auto_generated/qgscollapsiblegroupbox.sip.in
Expand Up @@ -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

Expand Down
28 changes: 27 additions & 1 deletion src/app/qgsattributesformproperties.cpp
Expand Up @@ -21,6 +21,7 @@
#include "qgsfieldcombobox.h"
#include "qgsqmlwidgetwrapper.h"
#include "qgsapplication.h"
#include "qgscolorbutton.h"

QgsAttributesFormProperties::QgsAttributesFormProperties( QgsVectorLayer *layer, QWidget *parent )
: QWidget( parent )
Expand Down Expand Up @@ -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 );

Expand Down Expand Up @@ -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++ )
{
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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( "Container Background Color" ) );
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 );

Expand All @@ -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() ) );
Expand Down Expand Up @@ -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;
}

7 changes: 6 additions & 1 deletion src/app/qgsattributesformproperties.h
Expand Up @@ -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; }
Expand Down Expand Up @@ -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;
Expand All @@ -134,6 +138,7 @@ class APP_EXPORT QgsAttributesFormProperties : public QWidget, private Ui_QgsAtt
QgsOptionalExpression mVisibilityExpression;
RelationEditorConfiguration mRelationEditorConfiguration;
QmlElementEditorConfiguration mQmlElementEditorConfiguration;
QColor mBackgroundColor;
};


Expand Down
10 changes: 10 additions & 0 deletions src/core/qgsattributeeditorelement.cpp
Expand Up @@ -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<QgsAttributeEditorElement *> QgsAttributeEditorContainer::findElements( QgsAttributeEditorElement::AttributeEditorType type ) const
{
QList<QgsAttributeEditorElement *> results;
Expand Down
18 changes: 17 additions & 1 deletion src/core/qgsattributeeditorelement.h
Expand Up @@ -19,6 +19,7 @@
#include "qgis_core.h"
#include "qgsrelation.h"
#include "qgsoptionalexpression.h"
#include <QColor>

class QgsRelationManager;

Expand Down Expand Up @@ -173,11 +174,13 @@ 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 )
QgsAttributeEditorContainer( const QString &name, QgsAttributeEditorElement *parent, const QColor &backgroundColor = QColor() )
: QgsAttributeEditorElement( AeTypeContainer, name, parent )
, mIsGroupBox( true )
, mColumnCount( 1 )
, mBackgroundColor( backgroundColor )
{}


Expand Down Expand Up @@ -265,6 +268,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;
Expand All @@ -273,6 +288,7 @@ class CORE_EXPORT QgsAttributeEditorContainer : public QgsAttributeEditorElement
QList<QgsAttributeEditorElement *> mChildren;
int mColumnCount;
QgsOptionalExpression mVisibilityExpression;
QColor mBackgroundColor;
};

/**
Expand Down
7 changes: 5 additions & 2 deletions src/core/qgseditformconfig.cpp
Expand Up @@ -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 )
Expand Down Expand Up @@ -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();
Expand Down
10 changes: 10 additions & 0 deletions src/gui/qgsattributeform.cpp
Expand Up @@ -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;
Expand All @@ -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 );

Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgscollapsiblegroupbox.h
Expand Up @@ -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
*/

Expand Down
24 changes: 21 additions & 3 deletions tests/src/python/test_qgseditformconfig.py
Expand Up @@ -20,11 +20,14 @@
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
Expand Down Expand Up @@ -84,14 +87,16 @@ def testFormUi(self):
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)
Expand Down Expand Up @@ -140,6 +145,19 @@ def testLabelOnTop(self):
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()

0 comments on commit a615a3b

Please sign in to comment.