diff --git a/python/core/auto_generated/qgsfeaturefiltermodel.sip.in b/python/core/auto_generated/qgsfeaturefiltermodel.sip.in index 48052aeb53a..eee0546e2d7 100644 --- a/python/core/auto_generated/qgsfeaturefiltermodel.sip.in +++ b/python/core/auto_generated/qgsfeaturefiltermodel.sip.in @@ -134,6 +134,10 @@ It is normally set to the primary key of the layer. The identifier field should be a unique field that can be used to identify individual features. It is normally set to the primary key of the layer. +.. note:: + + This will also reset identifier fields to NULL + .. versionadded:: 3.10 %End @@ -166,6 +170,14 @@ still be available in the model. Allows specifying one value that does not need to match the filter criteria but will still be available in the model. +.. versionadded:: 3.10 +%End + + void setExtraIdentifierValuesToNull(); +%Docstring +Allows specifying one value that does not need to match the filter criteria but will +still be available in the model as NULL value(s). + .. versionadded:: 3.10 %End diff --git a/python/gui/auto_generated/qgsfeaturelistcombobox.sip.in b/python/gui/auto_generated/qgsfeaturelistcombobox.sip.in index 2fe32507c1b..d09ecb0ab67 100644 --- a/python/gui/auto_generated/qgsfeaturelistcombobox.sip.in +++ b/python/gui/auto_generated/qgsfeaturelistcombobox.sip.in @@ -112,6 +112,13 @@ identifierField. The identifier values of the currently selected feature. A value from the identifierFields. +.. versionadded:: 3.10 +%End + + void setIdentifierValuesToNull(); +%Docstring +Sets the identifier values of the currently selected feature to NULL value(s). + .. versionadded:: 3.10 %End diff --git a/src/core/qgsfeaturefiltermodel.cpp b/src/core/qgsfeaturefiltermodel.cpp index 573c18f5b3b..c6956f98183 100644 --- a/src/core/qgsfeaturefiltermodel.cpp +++ b/src/core/qgsfeaturefiltermodel.cpp @@ -216,7 +216,16 @@ void QgsFeatureFilterModel::updateCompleter() QVector entries = mGatherer->entries(); if ( mExtraIdentifierValueIndex == -1 ) - setExtraIdentifierValuesUnguarded( QVariantList() ); + { + QVariantList nullAttributes; + for ( const QString &fieldName : mIdentifierFields ) + { + int idx = mSourceLayer->fields().indexOf( fieldName ); + nullAttributes << QVariant( mSourceLayer->fields().at( idx ).type() ); + } + + setExtraIdentifierValuesUnguarded( nullAttributes ); + } // Only reloading the current entry? if ( mGatherer->data().toBool() ) @@ -573,7 +582,7 @@ void QgsFeatureFilterModel::setIdentifierFields( const QStringList &identifierFi mIdentifierFields = identifierFields; emit identifierFieldChanged(); - setExtraIdentifierValues( QVariantList() ); + setExtraIdentifierValuesToNull(); } void QgsFeatureFilterModel::reload() @@ -617,3 +626,18 @@ void QgsFeatureFilterModel::setExtraIdentifierValues( const QVariantList &extraI emit extraIdentifierValueChanged(); } + +void QgsFeatureFilterModel::setExtraIdentifierValuesToNull() +{ + QVariantList nullAttributes; + if ( mSourceLayer ) + { + for ( const QString &fieldName : mIdentifierFields ) + { + int idx = mSourceLayer->fields().indexOf( fieldName ); + Q_ASSERT( idx >= 0 ); + nullAttributes << QVariant( mSourceLayer->fields().at( idx ).type() ); + } + } + setExtraIdentifierValues( nullAttributes ); +} diff --git a/src/core/qgsfeaturefiltermodel.h b/src/core/qgsfeaturefiltermodel.h index 7ced0a1e4a2..0035530b09c 100644 --- a/src/core/qgsfeaturefiltermodel.h +++ b/src/core/qgsfeaturefiltermodel.h @@ -159,6 +159,7 @@ class CORE_EXPORT QgsFeatureFilterModel : public QAbstractItemModel /** * The identifier field should be a unique field that can be used to identify individual features. * It is normally set to the primary key of the layer. + * \note This will also reset identifier fields to NULL * \since QGIS 3.10 */ void setIdentifierFields( const QStringList &identifierFields ); @@ -191,6 +192,13 @@ class CORE_EXPORT QgsFeatureFilterModel : public QAbstractItemModel */ void setExtraIdentifierValues( const QVariantList &extraIdentifierValues ); + /** + * Allows specifying one value that does not need to match the filter criteria but will + * still be available in the model as NULL value(s). + * \since QGIS 3.10 + */ + void setExtraIdentifierValuesToNull(); + /** * The index at which the extra identifier value is available within the model. */ diff --git a/src/gui/editorwidgets/qgsrelationreferencewidget.cpp b/src/gui/editorwidgets/qgsrelationreferencewidget.cpp index 58e12768f13..94c4619f39a 100644 --- a/src/gui/editorwidgets/qgsrelationreferencewidget.cpp +++ b/src/gui/editorwidgets/qgsrelationreferencewidget.cpp @@ -206,6 +206,7 @@ void QgsRelationReferenceWidget::setRelation( const QgsRelation &relation, bool mReferencedField = relation.fieldPairs().at( 0 ).second; if ( mComboBox ) { + mComboBox->setSourceLayer( mReferencedLayer ); Q_NOWARN_DEPRECATED_PUSH mComboBox->setIdentifierField( mReferencedField ); Q_NOWARN_DEPRECATED_PUSH @@ -350,9 +351,7 @@ void QgsRelationReferenceWidget::deleteForeignKey() } else { - Q_NOWARN_DEPRECATED_PUSH - mComboBox->setIdentifierValue( QVariant( QVariant::Int ) ); - Q_NOWARN_DEPRECATED_POP + mComboBox->setIdentifierValuesToNull(); } mRemoveFKButton->setEnabled( false ); updateAttributeEditorFrame( QgsFeature() ); @@ -386,9 +385,7 @@ void QgsRelationReferenceWidget::showIndeterminateState() } else { - Q_NOWARN_DEPRECATED_PUSH - whileBlocking( mComboBox )->setIdentifierValue( QVariant() ); - Q_NOWARN_DEPRECATED_POP + whileBlocking( mComboBox )->setIdentifierValuesToNull(); } mRemoveFKButton->setEnabled( false ); updateAttributeEditorFrame( QgsFeature() ); diff --git a/src/gui/qgsfeaturelistcombobox.cpp b/src/gui/qgsfeaturelistcombobox.cpp index 43db5be114f..e6406cf1252 100644 --- a/src/gui/qgsfeaturelistcombobox.cpp +++ b/src/gui/qgsfeaturelistcombobox.cpp @@ -258,6 +258,11 @@ void QgsFeatureListComboBox::setIdentifierValues( const QVariantList &identifier mModel->setExtraIdentifierValues( identifierValues ); } +void QgsFeatureListComboBox::setIdentifierValuesToNull() +{ + mModel->setExtraIdentifierValuesToNull(); +} + QgsFeatureRequest QgsFeatureListComboBox::currentFeatureRequest() const { if ( mModel->extraIdentifierValues().isEmpty() ) diff --git a/src/gui/qgsfeaturelistcombobox.h b/src/gui/qgsfeaturelistcombobox.h index 2e327306fe3..cddba087466 100644 --- a/src/gui/qgsfeaturelistcombobox.h +++ b/src/gui/qgsfeaturelistcombobox.h @@ -134,6 +134,12 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox */ void setIdentifierValues( const QVariantList &identifierValues ); + /** + * Sets the identifier values of the currently selected feature to NULL value(s). + * \since QGIS 3.10 + */ + void setIdentifierValuesToNull(); + /** * Shorthand for getting a feature request to query the currently selected * feature. diff --git a/tests/src/gui/testqgsfeaturelistcombobox.cpp b/tests/src/gui/testqgsfeaturelistcombobox.cpp index 9736adc616c..df500e7c424 100644 --- a/tests/src/gui/testqgsfeaturelistcombobox.cpp +++ b/tests/src/gui/testqgsfeaturelistcombobox.cpp @@ -43,6 +43,7 @@ class TestQgsFeatureListComboBox : public QObject void testSetGetLayer(); void testSetGetForeignKey(); + void testMultipleForeignKeys(); void testAllowNull(); void testValuesAndSelection(); void nullRepresentation(); @@ -139,6 +140,23 @@ void TestQgsFeatureListComboBox::testSetGetForeignKey() Q_NOWARN_DEPRECATED_POP } +void TestQgsFeatureListComboBox::testMultipleForeignKeys() +{ + std::unique_ptr cb( new QgsFeatureListComboBox() ); + + QgsApplication::setNullRepresentation( QStringLiteral( "nope" ) ); + + QVERIFY( cb->identifierValues().isEmpty() ); + + cb->setSourceLayer( mLayer.get() ); + cb->setIdentifierFields( QStringList() << "material" << "diameter" << "raccord" ); + cb->setDisplayExpression( "\"material\" || ' ' || \"diameter\" || ' ' || \"raccord\"" ); + cb->setAllowNull( true ); + + cb->setIdentifierValues( QVariantList() << "gold" << 777 << "rush" ); + QCOMPARE( cb->identifierValues(), QVariantList() << "gold" << 777 << "rush" ); +} + void TestQgsFeatureListComboBox::testAllowNull() { //QVERIFY( false ); diff --git a/tests/src/gui/testqgsrelationreferencewidget.cpp b/tests/src/gui/testqgsrelationreferencewidget.cpp index 4fdb347084e..0f5a521d4b6 100644 --- a/tests/src/gui/testqgsrelationreferencewidget.cpp +++ b/tests/src/gui/testqgsrelationreferencewidget.cpp @@ -403,9 +403,9 @@ void TestQgsRelationReferenceWidget::testAddEntry() bool startEditing( QgsVectorLayer * ) const override {return true;} - bool stopEditing( QgsVectorLayer *, bool = true ) const override {return true;}; + bool stopEditing( QgsVectorLayer *, bool = true ) const override {return true;} - bool saveEdits( QgsVectorLayer * ) const override {return true;}; + bool saveEdits( QgsVectorLayer * ) const override {return true;} }; QgsAttributeEditorContext context;