diff --git a/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp b/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp index e96b1491da1d..d4174ada02d4 100644 --- a/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp +++ b/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp @@ -18,16 +18,11 @@ #include "qgis.h" #include "qgsfields.h" #include "qgsproject.h" -#include "qgsvaluerelationwidgetfactory.h" #include "qgsvectorlayer.h" #include "qgsfilterlineedit.h" -#include "qgsfeatureiterator.h" #include "qgsvaluerelationfieldformatter.h" #include "qgsattributeform.h" -#include "qgsattributes.h" -#include "qgsjsonutils.h" #include "qgspostgresstringutils.h" -#include "qgsapplication.h" #include #include @@ -347,6 +342,11 @@ bool QgsValueRelationWidgetWrapper::valid() const } void QgsValueRelationWidgetWrapper::updateValues( const QVariant &value, const QVariantList & ) +{ + updateValue( value, true ); +} + +void QgsValueRelationWidgetWrapper::updateValue( const QVariant &value, bool forceComboInsertion ) { if ( mTableWidget ) { @@ -382,7 +382,7 @@ void QgsValueRelationWidgetWrapper::updateValues( const QVariant &value, const Q if ( idx == -1 ) { // if value doesn't exist, we show it in '(...)' (just like value map widget) - if ( QgsVariantUtils::isNull( value ) ) + if ( QgsVariantUtils::isNull( value ) || !forceComboInsertion ) { mComboBox->setCurrentIndex( -1 ); } @@ -435,7 +435,7 @@ void QgsValueRelationWidgetWrapper::widgetValueChanged( const QString &attribute { populate(); // Restore value - updateValues( value( ) ); + updateValue( oldValue, false ); // If the value has changed as a result of another widget's value change, // we need to emit the signal to make sure other dependent widgets are // updated. diff --git a/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.h b/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.h index 0de56c940ab1..9524c8ff8181 100644 --- a/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.h +++ b/src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.h @@ -193,6 +193,17 @@ class GUI_EXPORT QgsValueRelationWidgetWrapper : public QgsEditorWidgetWrapper private: void updateValues( const QVariant &value, const QVariantList & = QVariantList() ) override; + /** + * Set widget wrapper value, called by updateValues() + * \param value new value to update the widget with + * \param forceComboInsertion if TRUE \a value would be inserted even if it doesn't exist in + * combobox items and would appear as '(value)', else value would not be inserted. This has + * no effects for widgets other than combobox because other widgets have different behavior: + * + * - line edit displays '(no selection)' if value doesn't exist + * - table widget would check only items existing in value + */ + void updateValue( const QVariant &value, bool forceComboInsertion ); /** * Returns the value configured in `NofColumns` or 1 if not diff --git a/tests/src/gui/testqgsvaluerelationwidgetwrapper.cpp b/tests/src/gui/testqgsvaluerelationwidgetwrapper.cpp index 7a6712763271..52d0cb3406f1 100644 --- a/tests/src/gui/testqgsvaluerelationwidgetwrapper.cpp +++ b/tests/src/gui/testqgsvaluerelationwidgetwrapper.cpp @@ -1854,7 +1854,9 @@ void TestQgsValueRelationWidgetWrapper::testMultiEditMode() cfg.insert( QStringLiteral( "AllowNull" ), false ); cfg.insert( QStringLiteral( "OrderByValue" ), false ); cfg.insert( QStringLiteral( "UseCompleter" ), false ); - cfg.insert( QStringLiteral( "FilterExpression" ), QStringLiteral( "left(\"name\",4) = current_value('firstname')" ) ); + + // we match only the 3 first character so Jhon and Jhon would work both. Useful for later tests + cfg.insert( QStringLiteral( "FilterExpression" ), QStringLiteral( "left(\"name\",3) = left(current_value('firstname'),3)" ) ); people->setEditorWidgetSetup( 1, QgsEditorWidgetSetup( QStringLiteral( "ValueRelation" ), cfg ) ); @@ -1891,6 +1893,14 @@ void TestQgsValueRelationWidgetWrapper::testMultiEditMode() QCOMPARE( valueRelationWrapper->mComboBox->model()->data( valueRelationWrapper->mComboBox->model()->index( 1, 0 ), Qt::DisplayRole ), QStringLiteral( "Jhon F. Kennedy" ) ); QCOMPARE( valueRelationWrapper->mComboBox->model()->data( valueRelationWrapper->mComboBox->model()->index( 2, 0 ), Qt::DisplayRole ), QStringLiteral( "Jhon Lennon" ) ); + valueRelationWrapper->setValues( QStringLiteral( "Jhon Lennon" ), QVariantList() ); + QCOMPARE( valueRelationWrapper->mComboBox->currentIndex(), 2 ); + QCOMPARE( valueRelationWrapper->mComboBox->currentText(), QStringLiteral( "Jhon Lennon" ) ); + + firstNameWrapper->setValues( QStringLiteral( "Jho" ), QVariantList() ); + QCOMPARE( valueRelationWrapper->mComboBox->currentIndex(), 2 ); + QCOMPARE( valueRelationWrapper->mComboBox->currentText(), QStringLiteral( "Jhon Lennon" ) ); + people->rollBack(); QgsProject::instance()->removeMapLayer( people.get() ); QgsProject::instance()->removeMapLayer( famous.get() );