Skip to content
Permalink
Browse files

Merge pull request #4932 from pblottiere/bugfix_chainfilter2

Fixes relation reference widget when filters are reset
  • Loading branch information
Hugo Mercier
Hugo Mercier committed Jul 27, 2017
2 parents 5c82a85 + 5a62029 commit ce223160d23f0fb1ae35b552fba67bdbbb90a48a
@@ -811,7 +811,7 @@ void QgsRelationReferenceWidget::filterChanged()
{
QVariant nullValue = QgsApplication::nullRepresentation();

QStringList filters;
QMap<QString, QString> filters;
QgsAttributeList attrs;

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

// comboboxes have to be disabled before building filters
if ( mChainFilters )
disableChainedComboBoxes( scb );

// build filters
Q_FOREACH ( QComboBox *cb, mFilterComboBoxes )
{
if ( cb->currentIndex() != 0 )
@@ -830,11 +835,11 @@ void QgsRelationReferenceWidget::filterChanged()

if ( cb->currentText() == nullValue.toString() )
{
filters << QStringLiteral( "\"%1\" IS NULL" ).arg( fieldName );
filters[fieldName] = QStringLiteral( "\"%1\" IS NULL" ).arg( fieldName );
}
else
{
filters << QgsExpression::createFieldEqualityExpression( fieldName, cb->currentText() );
filters[fieldName] = QgsExpression::createFieldEqualityExpression( fieldName, cb->currentText() );
}
attrs << mReferencedLayer->fields().lookupField( fieldName );
}
@@ -854,12 +859,7 @@ void QgsRelationReferenceWidget::filterChanged()
continue;
}

if ( ccb->currentIndex() == 0 )
{
cb->setCurrentIndex( 0 );
cb->setEnabled( false );
}
else
if ( ccb->currentIndex() != 0 )
{
const QString fieldName = cb->property( "Field" ).toString();
filtered = true;
@@ -873,9 +873,9 @@ void QgsRelationReferenceWidget::filterChanged()
QStringList texts;
Q_FOREACH ( const QString &txt, mFilterCache[ccb->property( "Field" ).toString()][ccb->currentText()] )
{
QStringList filtersAttrs = filters;
filtersAttrs << QgsExpression::createFieldEqualityExpression( fieldName, txt );
QString expression = filtersAttrs.join( QStringLiteral( " AND " ) );
QMap<QString, QString> filtersAttrs = filters;
filtersAttrs[fieldName] = QgsExpression::createFieldEqualityExpression( fieldName, txt );
QString expression = filtersAttrs.values().join( QStringLiteral( " AND " ) );

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

if ( !mChainFilters || ( mChainFilters && !filtered ) )
{
filterExpression = filters.join( QStringLiteral( " AND " ) );
filterExpression = filters.values().join( QStringLiteral( " AND " ) );

QgsFeatureRequest req = QgsFeatureRequest().setSubsetOfAttributes( attrs );
if ( !filterExpression.isEmpty() )
req.setFilterExpression( filterExpression );

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

while ( it.nextFeature( f ) )
{
@@ -951,3 +955,28 @@ void QgsRelationReferenceWidget::updateAddEntryButton()
mAddEntryButton->setVisible( mAllowAddFeatures );
mAddEntryButton->setEnabled( mReferencedLayer && mReferencedLayer->isEditable() );
}

void QgsRelationReferenceWidget::disableChainedComboBoxes( const QComboBox *scb )
{
QComboBox *ccb = nullptr;
Q_FOREACH ( QComboBox *cb, mFilterComboBoxes )
{
if ( !ccb )
{
if ( cb == scb )
{
ccb = cb;
}

continue;
}

if ( ccb->currentIndex() == 0 )
{
cb->setCurrentIndex( 0 );
cb->setEnabled( false );
}
else
ccb = cb;
}
}
@@ -185,6 +185,7 @@ class GUI_EXPORT QgsRelationReferenceWidget : public QWidget
private:
void highlightFeature( QgsFeature f = QgsFeature(), CanvasExtent canvasExtent = Fixed );
void updateAttributeEditorFrame( const QgsFeature &feature );
void disableChainedComboBoxes( const QComboBox *cb );

// initialized
QgsAttributeEditorContext mEditorContext;
@@ -166,6 +166,19 @@ void TestQgsRelationReferenceWidget::testChainFilter()
// "material" == 'iron' AND "diameter" == '120' AND "raccord" = 'collar'
}
}

// set the filter for "raccord" and then reset filter for "diameter". As
// chain filter is activated, the filter on "raccord" field should be reset
cbs[2]->setCurrentIndex( cbs[2]->findText( "brides" ) );
cbs[1]->setCurrentIndex( cbs[1]->findText( "diameter" ) );

// combobox should propose NULL, 10 and 11 because the filter is now:
// "material" == 'iron'
QCOMPARE( w.mComboBox->count(), 3 );

// if there's no filter at all, all features' id should be proposed
cbs[0]->setCurrentIndex( cbs[0]->findText( "material" ) );
QCOMPARE( w.mComboBox->count(), 4 );
}

QGSTEST_MAIN( TestQgsRelationReferenceWidget )

0 comments on commit ce22316

Please sign in to comment.
You can’t perform that action at this time.