diff --git a/src/gui/editorwidgets/qgsrelationreferencewidget.cpp b/src/gui/editorwidgets/qgsrelationreferencewidget.cpp index dc016f30df63..3796fa0dd329 100644 --- a/src/gui/editorwidgets/qgsrelationreferencewidget.cpp +++ b/src/gui/editorwidgets/qgsrelationreferencewidget.cpp @@ -814,6 +814,29 @@ void QgsRelationReferenceWidget::filterChanged() Q_ASSERT( scb ); + QgsFeature f; + QgsFeatureIds featureIds; + QString filterExpression; + + Q_FOREACH ( QComboBox *cb, mFilterComboBoxes ) + { + if ( cb->currentIndex() != 0 ) + { + const QString fieldName = cb->property( "Field" ).toString(); + + if ( cb->currentText() == nullValue.toString() ) + { + filters << QStringLiteral( "\"%1\" IS NULL" ).arg( fieldName ); + } + else + { + filters << QgsExpression::createFieldEqualityExpression( fieldName, cb->currentText() ); + } + attrs << mReferencedLayer->fields().lookupField( fieldName ); + } + } + + bool filtered = false; if ( mChainFilters ) { QComboBox *ccb = nullptr; @@ -834,6 +857,9 @@ void QgsRelationReferenceWidget::filterChanged() } else { + const QString fieldName = cb->property( "Field" ).toString(); + filtered = true; + cb->blockSignals( true ); cb->clear(); cb->addItem( cb->property( "FieldAlias" ).toString() ); @@ -843,8 +869,29 @@ void QgsRelationReferenceWidget::filterChanged() QStringList texts; Q_FOREACH ( const QString &txt, mFilterCache[ccb->property( "Field" ).toString()][ccb->currentText()] ) { - texts << txt; + QStringList filtersAttrs = filters; + filtersAttrs << QgsExpression::createFieldEqualityExpression( fieldName, txt ); + QString expression = filtersAttrs.join( QStringLiteral( " AND " ) ); + + QgsAttributeList subset = attrs; + subset << mReferencedLayer->fields().lookupField( fieldName ); + + QgsFeatureIterator it( mMasterModel->layerCache()->getFeatures( QgsFeatureRequest().setFilterExpression( expression ).setSubsetOfAttributes( subset ) ) ); + + bool found = false; + while ( it.nextFeature( f ) ) + { + if ( !featureIds.contains( f.id() ) ) + featureIds << f.id(); + + found = true; + } + + // item is only provided if at least 1 feature exists + if ( found ) + texts << txt; } + texts.sort(); cb->addItems( texts ); @@ -856,34 +903,16 @@ void QgsRelationReferenceWidget::filterChanged() } } - Q_FOREACH ( QComboBox *cb, mFilterComboBoxes ) + if ( !mChainFilters || ( mChainFilters && !filtered ) ) { - if ( cb->currentIndex() != 0 ) - { - const QString fieldName = cb->property( "Field" ).toString(); - - if ( cb->currentText() == nullValue.toString() ) - { - filters << QStringLiteral( "\"%1\" IS NULL" ).arg( fieldName ); - } - else - { - filters << QgsExpression::createFieldEqualityExpression( fieldName, cb->currentText() ); - } - attrs << mReferencedLayer->fields().lookupField( fieldName ); - } - } - - QString filterExpression = filters.join( QStringLiteral( " AND " ) ); + filterExpression = filters.join( QStringLiteral( " AND " ) ); - QgsFeatureIterator it( mMasterModel->layerCache()->getFeatures( QgsFeatureRequest().setFilterExpression( filterExpression ).setSubsetOfAttributes( attrs ) ) ); + QgsFeatureIterator it( mMasterModel->layerCache()->getFeatures( QgsFeatureRequest().setFilterExpression( filterExpression ).setSubsetOfAttributes( attrs ) ) ); - QgsFeature f; - QgsFeatureIds featureIds; - - while ( it.nextFeature( f ) ) - { - featureIds << f.id(); + while ( it.nextFeature( f ) ) + { + featureIds << f.id(); + } } mFilterModel->setFilteredFeatures( featureIds );