diff --git a/src/gui/qgsattributeform.cpp b/src/gui/qgsattributeform.cpp index 4c81d689dc7b..a255cbe9d528 100644 --- a/src/gui/qgsattributeform.cpp +++ b/src/gui/qgsattributeform.cpp @@ -1036,6 +1036,19 @@ void QgsAttributeForm::onAttributeChanged( const QVariant &value, const QVariant mCurrentFormFeature.setAttribute( eww->field().name(), value ); + // Update other widgets pointing to the same field, required to happen now to insure + // currentFormValuesFeature() gets the right value when processing constraints + const QList formEditorWidgets = mFormEditorWidgets.values( eww->fieldIdx() ); + for ( QgsAttributeFormEditorWidget *formEditorWidget : formEditorWidgets ) + { + if ( formEditorWidget->editorWidget() == eww ) + continue; + + // formEditorWidget and eww points to the same field, so block signals + // as there is no need to handle valueChanged again for each duplicate + whileBlocking( formEditorWidget->editorWidget() )->setValue( value ); + } + switch ( mMode ) { case QgsAttributeEditorContext::SingleEditMode: @@ -1091,19 +1104,6 @@ void QgsAttributeForm::onAttributeChanged( const QVariant &value, const QVariant break; } - // Update other widgets pointing to the same field, required to happen now to insure - // currentFormValuesFeature() gets the right value when processing constraints - const QList formEditorWidgets = mFormEditorWidgets.values( eww->fieldIdx() ); - for ( QgsAttributeFormEditorWidget *formEditorWidget : formEditorWidgets ) - { - if ( formEditorWidget->editorWidget() == eww ) - continue; - - // formEditorWidget and eww points to the same field, so block signals - // as there is no need to handle valueChanged again for each duplicate - whileBlocking( formEditorWidget->editorWidget() )->setValue( value ); - } - updateConstraints( eww ); // Update dependent fields (only if form is not initializing) diff --git a/tests/src/gui/testqgsdualview.cpp b/tests/src/gui/testqgsdualview.cpp index aa05d6d75bd3..49976a28a187 100644 --- a/tests/src/gui/testqgsdualview.cpp +++ b/tests/src/gui/testqgsdualview.cpp @@ -21,6 +21,9 @@ #include #include #include "qgsattributeform.h" +#include "qgsattributeeditorcontainer.h" +#include "qgsattributeeditorfield.h" +#include "qgsattributeformeditorwidget.h" #include #include "qgsfeatureiterator.h" #include @@ -58,6 +61,8 @@ class TestQgsDualView : public QObject void testAttributeFormSharedValueScanning(); void testNoGeom(); + void testDuplicateField(); + #ifdef WITH_QTWEBKIT void testHtmlWidget_data(); void testHtmlWidget(); @@ -404,5 +409,46 @@ void TestQgsDualView::testHtmlWidget() } #endif +void TestQgsDualView::testDuplicateField() +{ + // test updating same field appearing in different widget + + // make a temporary vector layer + const QString def = QStringLiteral( "Point?field=col0:integer" ); + QgsVectorLayer *layer = new QgsVectorLayer( def, QStringLiteral( "test" ), QStringLiteral( "memory" ) ); + layer->setEditorWidgetSetup( 0, QgsEditorWidgetSetup( QStringLiteral( "Range" ), QVariantMap() ) ); + + // add same field twice so they get synced + QgsEditFormConfig editFormConfig = layer->editFormConfig(); + editFormConfig.clearTabs(); + editFormConfig.invisibleRootContainer()->addChildElement( new QgsAttributeEditorField( "col0", 0, editFormConfig.invisibleRootContainer() ) ); + editFormConfig.invisibleRootContainer()->addChildElement( new QgsAttributeEditorField( "col0", 0, editFormConfig.invisibleRootContainer() ) ); + editFormConfig.setLayout( Qgis::AttributeFormLayout::DragAndDrop ); + layer->setEditFormConfig( editFormConfig ); + + // add a feature to the vector layer + QgsFeature ft( layer->dataProvider()->fields(), 1 ); + ft.setAttribute( QStringLiteral( "col0" ), 1 ); + layer->dataProvider()->addFeature( ft ); + + QgsDualView dualView; + dualView.init( layer, mCanvas ); + + layer->startEditing(); + + const QList formEditorWidgets = dualView.mAttributeForm->mFormEditorWidgets.values( 0 ); + + formEditorWidgets[0]->editorWidget()->setValues( 20, QVariantList() ); + ft = layer->getFeature( ft.id() ); + QCOMPARE( ft.attribute( QStringLiteral( "col0" ) ).toInt(), 20 ); + + formEditorWidgets[1]->editorWidget()->setValues( 21, QVariantList() ); + ft = layer->getFeature( ft.id() ); + QCOMPARE( ft.attribute( QStringLiteral( "col0" ) ).toInt(), 21 ); + + layer->rollBack(); +} + + QGSTEST_MAIN( TestQgsDualView ) #include "testqgsdualview.moc"