From b0ce109adb11cf750a64a253468be749b9db5aed Mon Sep 17 00:00:00 2001 From: Juho Ervasti Date: Wed, 12 Feb 2025 17:10:56 +0200 Subject: [PATCH] Allow setting merge policy in the GUI --- .../qgsattributetypedialog.cpp | 58 +++++++++++++++++++ .../qgsattributetypedialog.h | 20 +++++++ .../vector/qgsattributesformproperties.cpp | 17 ++++++ src/gui/vector/qgsattributesformproperties.h | 1 + .../qgsattributetypeedit.ui | 43 +++++++++----- 5 files changed, 126 insertions(+), 13 deletions(-) diff --git a/src/gui/attributeformconfig/qgsattributetypedialog.cpp b/src/gui/attributeformconfig/qgsattributetypedialog.cpp index 2183a2c7b08..660e8f0be5e 100644 --- a/src/gui/attributeformconfig/qgsattributetypedialog.cpp +++ b/src/gui/attributeformconfig/qgsattributetypedialog.cpp @@ -126,6 +126,29 @@ QgsAttributeTypeDialog::QgsAttributeTypeDialog( QgsVectorLayer *vl, int fieldIdx mDuplicatePolicyComboBox->addItem( tr( "Remove Value" ), QVariant::fromValue( Qgis::FieldDuplicatePolicy::UnsetField ) ); connect( mDuplicatePolicyComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsAttributeTypeDialog::updateDuplicatePolicyLabel ); updateDuplicatePolicyLabel(); + + if ( mLayer->isSpatial() ) + { + mMergePolicyComboBox->addItem( tr( "Remove Value" ), QVariant::fromValue( Qgis::FieldDomainMergePolicy::UnsetField ) ); + mMergePolicyComboBox->addItem( tr( "Use Default Value" ), QVariant::fromValue( Qgis::FieldDomainMergePolicy::DefaultValue ) ); + + if ( mLayer->fields().at( mFieldIdx ).isNumeric() ) + { + mMergePolicyComboBox->addItem( tr( "Use Sum" ), QVariant::fromValue( Qgis::FieldDomainMergePolicy::Sum ) ); + + if ( mLayer->geometryType() != Qgis::GeometryType::Point ) + mMergePolicyComboBox->addItem( tr( "Use Average Weighted by Geometry" ), QVariant::fromValue( Qgis::FieldDomainMergePolicy::GeometryWeighted ) ); + } + } + else + { + mMergePolicyComboBox->setEnabled( false ); + mMergePolicyLabel->setEnabled( false ); + mMergePolicyDescriptionLabel->hide(); + } + + connect( mMergePolicyComboBox, qOverload( &QComboBox::currentIndexChanged ), this, &QgsAttributeTypeDialog::updateMergePolicyLabel ); + updateMergePolicyLabel(); } QgsAttributeTypeDialog::~QgsAttributeTypeDialog() @@ -400,6 +423,17 @@ void QgsAttributeTypeDialog::setDuplicatePolicy( Qgis::FieldDuplicatePolicy poli updateSplitPolicyLabel(); } +void QgsAttributeTypeDialog::setMergePolicy( Qgis::FieldDomainMergePolicy policy ) +{ + mMergePolicyComboBox->setCurrentIndex( mMergePolicyComboBox->findData( QVariant::fromValue( policy ) ) ); + updateMergePolicyLabel(); +} + +Qgis::FieldDomainMergePolicy QgsAttributeTypeDialog::mergePolicy() const +{ + return mMergePolicyComboBox->currentData().value(); +} + QString QgsAttributeTypeDialog::constraintExpression() const { return constraintExpressionWidget->asExpression(); @@ -537,6 +571,30 @@ void QgsAttributeTypeDialog::updateDuplicatePolicyLabel() mDuplicatePolicyDescriptionLabel->setText( QStringLiteral( "%1" ).arg( helperText ) ); } +void QgsAttributeTypeDialog::updateMergePolicyLabel() +{ + QString helperText; + switch ( mMergePolicyComboBox->currentData().value() ) + { + case Qgis::FieldDomainMergePolicy::DefaultValue: + helperText = tr( "Use default field value." ); + break; + + case Qgis::FieldDomainMergePolicy::Sum: + helperText = tr( "Sum of values." ); + break; + + case Qgis::FieldDomainMergePolicy::GeometryWeighted: + helperText = tr( "New values are computed as the weighted average of the source values." ); + break; + + case Qgis::FieldDomainMergePolicy::UnsetField: + helperText = tr( "Clears the field to an unset state." ); + break; + } + mMergePolicyDescriptionLabel->setText( QStringLiteral( "%1" ).arg( helperText ) ); +} + QStandardItem *QgsAttributeTypeDialog::currentItem() const { QStandardItemModel *widgetTypeModel = qobject_cast( mWidgetTypeComboBox->model() ); diff --git a/src/gui/attributeformconfig/qgsattributetypedialog.h b/src/gui/attributeformconfig/qgsattributetypedialog.h index 8b18c88911a..634fe115f2d 100644 --- a/src/gui/attributeformconfig/qgsattributetypedialog.h +++ b/src/gui/attributeformconfig/qgsattributetypedialog.h @@ -271,6 +271,24 @@ class GUI_EXPORT QgsAttributeTypeDialog : public QWidget, private Ui::QgsAttribu */ void setDuplicatePolicy( Qgis::FieldDuplicatePolicy policy ); + /** + * Returns the field's merge policy. + * + * \see setMergePolicy() + * + * \since QGIS 3.42 + */ + Qgis::FieldDomainMergePolicy mergePolicy() const; + + /** + * Sets the field's merge policy. + * + * \see mergePolicy() + * + * \since QGIS 3.42 + */ + void setMergePolicy( Qgis::FieldDomainMergePolicy policy ); + private slots: /** @@ -285,6 +303,8 @@ class GUI_EXPORT QgsAttributeTypeDialog : public QWidget, private Ui::QgsAttribu void updateDuplicatePolicyLabel(); + void updateMergePolicyLabel(); + private: QgsVectorLayer *mLayer = nullptr; int mFieldIdx; diff --git a/src/gui/vector/qgsattributesformproperties.cpp b/src/gui/vector/qgsattributesformproperties.cpp index 99c9af2449e..001c466f787 100644 --- a/src/gui/vector/qgsattributesformproperties.cpp +++ b/src/gui/vector/qgsattributesformproperties.cpp @@ -343,6 +343,7 @@ void QgsAttributesFormProperties::loadAttributeTypeDialogFromConfiguration( cons mAttributeTypeDialog->setUniqueEnforced( constraints.constraintStrength( QgsFieldConstraints::ConstraintUnique ) == QgsFieldConstraints::ConstraintStrengthHard ); mAttributeTypeDialog->setSplitPolicy( config.mSplitPolicy ); mAttributeTypeDialog->setDuplicatePolicy( config.mDuplicatePolicy ); + mAttributeTypeDialog->setMergePolicy( config.mMergePolicy ); QgsFieldConstraints::Constraints providerConstraints = QgsFieldConstraints::Constraints(); if ( constraints.constraintOrigin( QgsFieldConstraints::ConstraintNotNull ) == QgsFieldConstraints::ConstraintOriginProvider ) @@ -417,6 +418,7 @@ void QgsAttributesFormProperties::storeAttributeTypeDialog() cfg.mEditorWidgetConfig = mAttributeTypeDialog->editorWidgetConfig(); cfg.mSplitPolicy = mAttributeTypeDialog->splitPolicy(); cfg.mDuplicatePolicy = mAttributeTypeDialog->duplicatePolicy(); + cfg.mMergePolicy = mAttributeTypeDialog->mergePolicy(); const int fieldIndex = mAttributeTypeDialog->fieldIdx(); mLayer->setDefaultValueDefinition( fieldIndex, QgsDefaultValue( mAttributeTypeDialog->defaultValueExpression(), mAttributeTypeDialog->applyDefaultValueOnUpdate() ) ); @@ -1047,6 +1049,7 @@ void QgsAttributesFormProperties::apply() mLayer->setFieldAlias( idx, cfg.mAlias ); mLayer->setFieldSplitPolicy( idx, cfg.mSplitPolicy ); mLayer->setFieldDuplicatePolicy( idx, cfg.mDuplicatePolicy ); + mLayer->setFieldMergePolicy( idx, cfg.mMergePolicy ); } // tabs and groups @@ -1118,6 +1121,7 @@ QgsAttributesFormProperties::FieldConfig::FieldConfig( QgsVectorLayer *layer, in mEditorWidgetConfig = setup.config(); mSplitPolicy = layer->fields().at( idx ).splitPolicy(); mDuplicatePolicy = layer->fields().at( idx ).duplicatePolicy(); + mMergePolicy = layer->fields().at( idx ).mergePolicy(); } QgsAttributesFormProperties::FieldConfig::operator QVariant() @@ -2117,6 +2121,11 @@ void QgsAttributesFormProperties::copyWidgetConfiguration() duplicatePolicyElement.setAttribute( QStringLiteral( "policy" ), qgsEnumValueToKey( field.duplicatePolicy() ) ); documentElement.appendChild( duplicatePolicyElement ); + // Merge policy + QDomElement mergePolicyElement = doc.createElement( QStringLiteral( "mergePolicy" ) ); + mergePolicyElement.setAttribute( QStringLiteral( "policy" ), qgsEnumValueToKey( field.mergePolicy() ) ); + documentElement.appendChild( mergePolicyElement ); + // Default expressions QDomElement defaultElem = doc.createElement( QStringLiteral( "default" ) ); defaultElem.setAttribute( QStringLiteral( "expression" ), field.defaultValueDefinition().expression() ); @@ -2246,6 +2255,14 @@ void QgsAttributesFormProperties::pasteWidgetConfiguration() config.mDuplicatePolicy = policy; } + // Merge policy + const QDomElement mergePolicyElement = docElem.firstChildElement( QStringLiteral( "mergePolicy" ) ); + if ( !mergePolicyElement.isNull() ) + { + const Qgis::FieldDomainMergePolicy policy = qgsEnumKeyToValue( mergePolicyElement.attribute( QStringLiteral( "policy" ) ), Qgis::FieldDomainMergePolicy::DefaultValue ); + config.mMergePolicy = policy; + } + // Default expressions const QDomElement defaultElement = docElem.firstChildElement( QStringLiteral( "default" ) ); if ( !defaultElement.isNull() ) diff --git a/src/gui/vector/qgsattributesformproperties.h b/src/gui/vector/qgsattributesformproperties.h index 5500fb619bf..bc48cb6b98b 100644 --- a/src/gui/vector/qgsattributesformproperties.h +++ b/src/gui/vector/qgsattributesformproperties.h @@ -374,6 +374,7 @@ class GUI_EXPORT QgsAttributesFormProperties : public QWidget, public QgsExpress QString mComment; Qgis::FieldDomainSplitPolicy mSplitPolicy = Qgis::FieldDomainSplitPolicy::Duplicate; Qgis::FieldDuplicatePolicy mDuplicatePolicy = Qgis::FieldDuplicatePolicy::Duplicate; + Qgis::FieldDomainMergePolicy mMergePolicy = Qgis::FieldDomainMergePolicy::DefaultValue; operator QVariant(); }; diff --git a/src/ui/attributeformconfig/qgsattributetypeedit.ui b/src/ui/attributeformconfig/qgsattributetypeedit.ui index 7c46ca9b4f3..1c4ed70bea5 100644 --- a/src/ui/attributeformconfig/qgsattributetypeedit.ui +++ b/src/ui/attributeformconfig/qgsattributetypeedit.ui @@ -284,19 +284,6 @@ Policies - - - - - - - When duplicating features - - - - - - @@ -304,6 +291,9 @@ + + + @@ -314,6 +304,26 @@ + + + + + + + When merging features + + + + + + + When duplicating features + + + + + + @@ -324,6 +334,13 @@ + + + + TextLabel + + +