@@ -191,10 +191,10 @@ void QgsRelationReferenceWidget::setRelation( const QgsRelation& relation, bool
191
191
mReferencedFieldIdx = mReferencedLayer ->fieldNameIndex ( relation .fieldPairs ().at ( 0 ).second );
192
192
mReferencingFieldIdx = mReferencingLayer ->fieldNameIndex ( relation .fieldPairs ().at ( 0 ).first );
193
193
194
- QgsAttributeEditorContext context ( mEditorContext , relation , QgsAttributeEditorContext::Single, QgsAttributeEditorContext::Embed );
195
194
196
195
if ( mEmbedForm )
197
196
{
197
+ QgsAttributeEditorContext context ( mEditorContext , relation , QgsAttributeEditorContext::Single, QgsAttributeEditorContext::Embed );
198
198
mAttributeEditorFrame ->setTitle ( mReferencedLayer ->name () );
199
199
mReferencedAttributeForm = new QgsAttributeForm ( relation .referencedLayer (), QgsFeature (), context, this );
200
200
mAttributeEditorLayout ->addWidget ( mReferencedAttributeForm );
@@ -464,6 +464,10 @@ void QgsRelationReferenceWidget::init()
464
464
{
465
465
QVariantList uniqueValues;
466
466
int idx = mReferencedLayer ->fieldNameIndex ( fieldName );
467
+
468
+ if ( idx == -1 )
469
+ continue ;
470
+
467
471
QComboBox* cb = new QComboBox ();
468
472
cb->setProperty ( " Field" , fieldName );
469
473
cb->setProperty ( " FieldAlias" , mReferencedLayer ->attributeDisplayName ( idx ) );
@@ -785,13 +789,41 @@ void QgsRelationReferenceWidget::filterChanged()
785
789
{
786
790
QVariant nullValue = QSettings ().value ( " qgis/nullValue" , " NULL" );
787
791
788
- QStringList filters;
792
+ QMap<QString, QString> filters;
789
793
QgsAttributeList attrs;
790
794
791
795
QComboBox* scb = qobject_cast<QComboBox*>( sender () );
792
796
793
797
Q_ASSERT ( scb );
794
798
799
+ QgsFeature f;
800
+ QgsFeatureIds featureIds;
801
+ QString filterExpression;
802
+
803
+ // comboboxes have to be disabled before building filters
804
+ if ( mChainFilters )
805
+ disableChainedComboBoxes ( scb );
806
+
807
+ // build filters
808
+ Q_FOREACH ( QComboBox *cb, mFilterComboBoxes )
809
+ {
810
+ if ( cb->currentIndex () != 0 )
811
+ {
812
+ const QString fieldName = cb->property ( " Field" ).toString ();
813
+
814
+ if ( cb->currentText () == nullValue.toString () )
815
+ {
816
+ filters[fieldName] = QString ( " \" %1\" IS NULL" ).arg ( fieldName );
817
+ }
818
+ else
819
+ {
820
+ filters[fieldName] = QgsExpression::createFieldEqualityExpression ( fieldName, cb->currentText () );
821
+ }
822
+ attrs << mReferencedLayer ->fieldNameIndex ( fieldName );
823
+ }
824
+ }
825
+
826
+ bool filtered = false ;
795
827
if ( mChainFilters )
796
828
{
797
829
QComboBox* ccb = nullptr ;
@@ -805,13 +837,11 @@ void QgsRelationReferenceWidget::filterChanged()
805
837
continue ;
806
838
}
807
839
808
- if ( ccb->currentIndex () == 0 )
809
- {
810
- cb->setCurrentIndex ( 0 );
811
- cb->setEnabled ( false );
812
- }
813
- else
840
+ if ( ccb->currentIndex () != 0 )
814
841
{
842
+ const QString fieldName = cb->property ( " Field" ).toString ();
843
+ filtered = true ;
844
+
815
845
cb->blockSignals ( true );
816
846
cb->clear ();
817
847
cb->addItem ( cb->property ( " FieldAlias" ).toString () );
@@ -821,8 +851,30 @@ void QgsRelationReferenceWidget::filterChanged()
821
851
QStringList texts;
822
852
Q_FOREACH ( const QString& txt, mFilterCache [ccb->property ( " Field" ).toString ()][ccb->currentText ()] )
823
853
{
824
- texts << txt;
854
+ QMap<QString, QString> filtersAttrs = filters;
855
+ filtersAttrs[fieldName] = QgsExpression::createFieldEqualityExpression ( fieldName, txt );
856
+ QStringList vals = filtersAttrs.values ();
857
+ QString expression = vals.join ( QString ( " AND " ) );
858
+
859
+ QgsAttributeList subset = attrs;
860
+ subset << mReferencedLayer ->fieldNameIndex ( fieldName );
861
+
862
+ QgsFeatureIterator it ( mMasterModel ->layerCache ()->getFeatures ( QgsFeatureRequest ().setFilterExpression ( expression ).setSubsetOfAttributes ( subset ) ) );
863
+
864
+ bool found = false ;
865
+ while ( it.nextFeature ( f ) )
866
+ {
867
+ if ( !featureIds.contains ( f.id () ) )
868
+ featureIds << f.id ();
869
+
870
+ found = true ;
871
+ }
872
+
873
+ // item is only provided if at least 1 feature exists
874
+ if ( found )
875
+ texts << txt;
825
876
}
877
+
826
878
texts.sort ();
827
879
cb->addItems ( texts );
828
880
@@ -834,34 +886,21 @@ void QgsRelationReferenceWidget::filterChanged()
834
886
}
835
887
}
836
888
837
- Q_FOREACH ( QComboBox* cb, mFilterComboBoxes )
889
+ if ( ! mChainFilters || ( mChainFilters && !filtered ) )
838
890
{
839
- if ( cb->currentIndex () != 0 )
840
- {
841
- const QString fieldName = cb->property ( " Field" ).toString ();
891
+ QStringList vals = filters.values ();
892
+ filterExpression = vals.join ( QString ( " AND " ) );
842
893
843
- if ( cb->currentText () == nullValue.toString () )
844
- {
845
- filters << QString ( " \" %1\" IS NULL" ).arg ( fieldName );
846
- }
847
- else
848
- {
849
- filters << QgsExpression::createFieldEqualityExpression ( fieldName, cb->currentText () );
850
- }
851
- attrs << mReferencedLayer ->fieldNameIndex ( fieldName );
852
- }
853
- }
854
-
855
- QString filterExpression = filters.join ( " AND " );
894
+ QgsFeatureRequest req = QgsFeatureRequest ().setSubsetOfAttributes ( attrs );
895
+ if ( !filterExpression.isEmpty () )
896
+ req.setFilterExpression ( filterExpression );
856
897
857
- QgsFeatureIterator it ( mMasterModel ->layerCache ()->getFeatures ( QgsFeatureRequest (). setFilterExpression ( filterExpression ). setSubsetOfAttributes ( attrs ) ) );
898
+ QgsFeatureIterator it ( mMasterModel ->layerCache ()->getFeatures ( req ) );
858
899
859
- QgsFeature f;
860
- QgsFeatureIds featureIds;
861
-
862
- while ( it.nextFeature ( f ) )
863
- {
864
- featureIds << f.id ();
900
+ while ( it.nextFeature ( f ) )
901
+ {
902
+ featureIds << f.id ();
903
+ }
865
904
}
866
905
867
906
mFilterModel ->setFilteredFeatures ( featureIds );
@@ -896,3 +935,28 @@ void QgsRelationReferenceWidget::updateAddEntryButton()
896
935
mAddEntryButton ->setVisible ( mAllowAddFeatures );
897
936
mAddEntryButton ->setEnabled ( mReferencedLayer && mReferencedLayer ->isEditable () );
898
937
}
938
+
939
+ void QgsRelationReferenceWidget::disableChainedComboBoxes ( const QComboBox *scb )
940
+ {
941
+ QComboBox *ccb = nullptr ;
942
+ Q_FOREACH ( QComboBox *cb, mFilterComboBoxes )
943
+ {
944
+ if ( !ccb )
945
+ {
946
+ if ( cb == scb )
947
+ {
948
+ ccb = cb;
949
+ }
950
+
951
+ continue ;
952
+ }
953
+
954
+ if ( ccb->currentIndex () == 0 )
955
+ {
956
+ cb->setCurrentIndex ( 0 );
957
+ cb->setEnabled ( false );
958
+ }
959
+ else
960
+ ccb = cb;
961
+ }
962
+ }
0 commit comments