Skip to content

Commit ce22316

Browse files
author
Hugo Mercier
authoredJul 27, 2017
Merge pull request #4932 from pblottiere/bugfix_chainfilter2
Fixes relation reference widget when filters are reset
2 parents 5c82a85 + 5a62029 commit ce22316

File tree

3 files changed

+57
-14
lines changed

3 files changed

+57
-14
lines changed
 

‎src/gui/editorwidgets/qgsrelationreferencewidget.cpp

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -811,7 +811,7 @@ void QgsRelationReferenceWidget::filterChanged()
811811
{
812812
QVariant nullValue = QgsApplication::nullRepresentation();
813813

814-
QStringList filters;
814+
QMap<QString, QString> filters;
815815
QgsAttributeList attrs;
816816

817817
QComboBox *scb = qobject_cast<QComboBox *>( sender() );
@@ -822,6 +822,11 @@ void QgsRelationReferenceWidget::filterChanged()
822822
QgsFeatureIds featureIds;
823823
QString filterExpression;
824824

825+
// comboboxes have to be disabled before building filters
826+
if ( mChainFilters )
827+
disableChainedComboBoxes( scb );
828+
829+
// build filters
825830
Q_FOREACH ( QComboBox *cb, mFilterComboBoxes )
826831
{
827832
if ( cb->currentIndex() != 0 )
@@ -830,11 +835,11 @@ void QgsRelationReferenceWidget::filterChanged()
830835

831836
if ( cb->currentText() == nullValue.toString() )
832837
{
833-
filters << QStringLiteral( "\"%1\" IS NULL" ).arg( fieldName );
838+
filters[fieldName] = QStringLiteral( "\"%1\" IS NULL" ).arg( fieldName );
834839
}
835840
else
836841
{
837-
filters << QgsExpression::createFieldEqualityExpression( fieldName, cb->currentText() );
842+
filters[fieldName] = QgsExpression::createFieldEqualityExpression( fieldName, cb->currentText() );
838843
}
839844
attrs << mReferencedLayer->fields().lookupField( fieldName );
840845
}
@@ -854,12 +859,7 @@ void QgsRelationReferenceWidget::filterChanged()
854859
continue;
855860
}
856861

857-
if ( ccb->currentIndex() == 0 )
858-
{
859-
cb->setCurrentIndex( 0 );
860-
cb->setEnabled( false );
861-
}
862-
else
862+
if ( ccb->currentIndex() != 0 )
863863
{
864864
const QString fieldName = cb->property( "Field" ).toString();
865865
filtered = true;
@@ -873,9 +873,9 @@ void QgsRelationReferenceWidget::filterChanged()
873873
QStringList texts;
874874
Q_FOREACH ( const QString &txt, mFilterCache[ccb->property( "Field" ).toString()][ccb->currentText()] )
875875
{
876-
QStringList filtersAttrs = filters;
877-
filtersAttrs << QgsExpression::createFieldEqualityExpression( fieldName, txt );
878-
QString expression = filtersAttrs.join( QStringLiteral( " AND " ) );
876+
QMap<QString, QString> filtersAttrs = filters;
877+
filtersAttrs[fieldName] = QgsExpression::createFieldEqualityExpression( fieldName, txt );
878+
QString expression = filtersAttrs.values().join( QStringLiteral( " AND " ) );
879879

880880
QgsAttributeList subset = attrs;
881881
subset << mReferencedLayer->fields().lookupField( fieldName );
@@ -909,9 +909,13 @@ void QgsRelationReferenceWidget::filterChanged()
909909

910910
if ( !mChainFilters || ( mChainFilters && !filtered ) )
911911
{
912-
filterExpression = filters.join( QStringLiteral( " AND " ) );
912+
filterExpression = filters.values().join( QStringLiteral( " AND " ) );
913+
914+
QgsFeatureRequest req = QgsFeatureRequest().setSubsetOfAttributes( attrs );
915+
if ( !filterExpression.isEmpty() )
916+
req.setFilterExpression( filterExpression );
913917

914-
QgsFeatureIterator it( mMasterModel->layerCache()->getFeatures( QgsFeatureRequest().setFilterExpression( filterExpression ).setSubsetOfAttributes( attrs ) ) );
918+
QgsFeatureIterator it( mMasterModel->layerCache()->getFeatures( req ) );
915919

916920
while ( it.nextFeature( f ) )
917921
{
@@ -951,3 +955,28 @@ void QgsRelationReferenceWidget::updateAddEntryButton()
951955
mAddEntryButton->setVisible( mAllowAddFeatures );
952956
mAddEntryButton->setEnabled( mReferencedLayer && mReferencedLayer->isEditable() );
953957
}
958+
959+
void QgsRelationReferenceWidget::disableChainedComboBoxes( const QComboBox *scb )
960+
{
961+
QComboBox *ccb = nullptr;
962+
Q_FOREACH ( QComboBox *cb, mFilterComboBoxes )
963+
{
964+
if ( !ccb )
965+
{
966+
if ( cb == scb )
967+
{
968+
ccb = cb;
969+
}
970+
971+
continue;
972+
}
973+
974+
if ( ccb->currentIndex() == 0 )
975+
{
976+
cb->setCurrentIndex( 0 );
977+
cb->setEnabled( false );
978+
}
979+
else
980+
ccb = cb;
981+
}
982+
}

‎src/gui/editorwidgets/qgsrelationreferencewidget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ class GUI_EXPORT QgsRelationReferenceWidget : public QWidget
185185
private:
186186
void highlightFeature( QgsFeature f = QgsFeature(), CanvasExtent canvasExtent = Fixed );
187187
void updateAttributeEditorFrame( const QgsFeature &feature );
188+
void disableChainedComboBoxes( const QComboBox *cb );
188189

189190
// initialized
190191
QgsAttributeEditorContext mEditorContext;

‎tests/src/gui/testqgsrelationreferencewidget.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,19 @@ void TestQgsRelationReferenceWidget::testChainFilter()
166166
// "material" == 'iron' AND "diameter" == '120' AND "raccord" = 'collar'
167167
}
168168
}
169+
170+
// set the filter for "raccord" and then reset filter for "diameter". As
171+
// chain filter is activated, the filter on "raccord" field should be reset
172+
cbs[2]->setCurrentIndex( cbs[2]->findText( "brides" ) );
173+
cbs[1]->setCurrentIndex( cbs[1]->findText( "diameter" ) );
174+
175+
// combobox should propose NULL, 10 and 11 because the filter is now:
176+
// "material" == 'iron'
177+
QCOMPARE( w.mComboBox->count(), 3 );
178+
179+
// if there's no filter at all, all features' id should be proposed
180+
cbs[0]->setCurrentIndex( cbs[0]->findText( "material" ) );
181+
QCOMPARE( w.mComboBox->count(), 4 );
169182
}
170183

171184
QGSTEST_MAIN( TestQgsRelationReferenceWidget )

0 commit comments

Comments
 (0)
Please sign in to comment.