Skip to content
Permalink
Browse files

Merge pull request #6843 from pblottiere/bugfix_refrel

[bugfix] Fixes regression in relation reference widget with 'chain filter' option
  • Loading branch information
m-kuhn committed May 17, 2018
2 parents d5cec14 + 7d6518f commit 7b53273f1f841ccb64ca06c5b7ec1939261e465a
@@ -56,6 +56,14 @@ the the value to match the typed text against.
%Docstring
An additional expression to further restrict the available features.
This can be used to integrate additional spatial or other constraints.
%End

int nullIndex() const;
%Docstring
Returns the current index of the NULL value, or -1 if NULL values are
not allowed.

.. versionadded:: 3.2
%End

void setFilterExpression( const QString &filterExpression );
@@ -119,6 +127,13 @@ The index of the currently selected item.

signals:

void modelUpdated();
%Docstring
The underlying model has been updated.

.. versionadded:: 3.2
%End

void sourceLayerChanged();
%Docstring
The layer from which features should be listed.
@@ -145,6 +145,7 @@ QgsRelationReferenceWidget::QgsRelationReferenceWidget( QWidget *parent )
connect( mRemoveFKButton, &QAbstractButton::clicked, this, &QgsRelationReferenceWidget::deleteForeignKey );
connect( mAddEntryButton, &QAbstractButton::clicked, this, &QgsRelationReferenceWidget::addEntry );
connect( mComboBox, &QComboBox::editTextChanged, this, &QgsRelationReferenceWidget::updateAddEntryButton );
connect( mComboBox, &QgsFeatureListComboBox::modelUpdated, this, &QgsRelationReferenceWidget::updateIndex );
}

QgsRelationReferenceWidget::~QgsRelationReferenceWidget()
@@ -155,6 +156,38 @@ QgsRelationReferenceWidget::~QgsRelationReferenceWidget()
delete mMapTool;
}

void QgsRelationReferenceWidget::updateIndex()
{
if ( mChainFilters && mComboBox->count() > 0 )
{
int index = -1;

// uninitialized filter
if ( ! mFilterComboBoxes.isEmpty()
&& mFilterComboBoxes[0]->currentIndex() == 0 && mAllowNull )
{
index = mComboBox->nullIndex();
}
else if ( mComboBox->count() > mComboBox->nullIndex() )
{
index = mComboBox->nullIndex() + 1;
}
else if ( mAllowNull )
{
index = mComboBox->nullIndex();
}
else
{
index = 0;
}

if ( mComboBox->count() > index )
{
mComboBox->setCurrentIndex( index );
}
}
}

void QgsRelationReferenceWidget::setRelation( const QgsRelation &relation, bool allowNullValue )
{
mAllowNull = allowNullValue;
@@ -184,6 +184,12 @@ class GUI_EXPORT QgsRelationReferenceWidget : public QWidget
void addEntry();
void updateAddEntryButton();

/**
* Updates the FK index as soon as the underlying model is updated when
* the chainFilter option is activated.
*/
void updateIndex();

private:
void highlightFeature( QgsFeature f = QgsFeature(), CanvasExtent canvasExtent = Fixed );
void updateAttributeEditorFrame( const QgsFeature &feature );
@@ -259,7 +259,11 @@ void QgsValueRelationWidgetWrapper::populate( )
else if ( mTableWidget )
{
if ( mCache.size() > 0 )
mTableWidget->setRowCount( ( mCache.size() + config( QStringLiteral( "NofColumns" ) ).toInt() - 1 ) / config( QStringLiteral( "NofColumns" ) ).toInt() );
{
const int nofCols = config( QStringLiteral( "NofColumns" ) ).toInt();
const int denom = nofCols != 0 ? nofCols : 1;
mTableWidget->setRowCount( ( mCache.size() + nofCols - 1 ) / denom );
}
else
mTableWidget->setRowCount( 1 );
if ( config( QStringLiteral( "NofColumns" ) ).toInt() > 0 )
@@ -46,6 +46,7 @@ QgsFeatureListComboBox::QgsFeatureListComboBox( QWidget *parent )
connect( mCompleter, static_cast<void( QCompleter::* )( const QModelIndex & )>( &QCompleter::activated ), this, &QgsFeatureListComboBox::onActivated );
connect( mModel, &QgsFeatureFilterModel::beginUpdate, this, &QgsFeatureListComboBox::storeLineEditState );
connect( mModel, &QgsFeatureFilterModel::endUpdate, this, &QgsFeatureListComboBox::restoreLineEditState );
connect( mModel, &QgsFeatureFilterModel::endUpdate, this, &QgsFeatureListComboBox::modelUpdated );
connect( mModel, &QgsFeatureFilterModel::dataChanged, this, &QgsFeatureListComboBox::onDataChanged );

connect( this, static_cast<void( QgsFeatureListComboBox::* )( int )>( &QgsFeatureListComboBox::currentIndexChanged ), this, &QgsFeatureListComboBox::onCurrentIndexChanged );
@@ -136,6 +137,18 @@ void QgsFeatureListComboBox::restoreLineEditState()
mLineEditState.restore( mLineEdit );
}

int QgsFeatureListComboBox::nullIndex() const
{
int index = -1;

if ( allowNull() )
{
index = findText( tr( "NULL" ) );
}

return index;
}

void QgsFeatureListComboBox::onDataChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles )
{
Q_UNUSED( roles )
@@ -82,6 +82,14 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox
*/
QString filterExpression() const;

/**
* Returns the current index of the NULL value, or -1 if NULL values are
* not allowed.
*
* \since QGIS 3.2
*/
int nullIndex() const;

/**
* An additional expression to further restrict the available features.
* This can be used to integrate additional spatial or other constraints.
@@ -141,6 +149,13 @@ class GUI_EXPORT QgsFeatureListComboBox : public QComboBox

signals:

/**
* The underlying model has been updated.
*
* \since QGIS 3.2
*/
void modelUpdated();

/**
* The layer from which features should be listed.
*/
@@ -185,12 +185,36 @@ void TestQgsRelationReferenceWidget::testChainFilter()

// 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( QStringLiteral( "brides" ) ) );
cbs[1]->setCurrentIndex( cbs[1]->findText( QStringLiteral( "diameter" ) ) );

QEventLoop loop;
connect( qobject_cast<QgsFeatureFilterModel *>( w.mComboBox->model() ), &QgsFeatureFilterModel::filterJobCompleted, &loop, &QEventLoop::quit );

cbs[0]->setCurrentIndex( 0 );
loop.exec();
QCOMPARE( w.mComboBox->currentText(), QString( "NULL" ) );

cbs[0]->setCurrentIndex( cbs[0]->findText( "iron" ) );
loop.exec();
QCOMPARE( w.mComboBox->currentText(), QString( "10" ) );

cbs[0]->setCurrentIndex( cbs[0]->findText( "steel" ) );
loop.exec();
QCOMPARE( w.mComboBox->currentText(), QString( "12" ) );

cbs[0]->setCurrentIndex( cbs[0]->findText( "iron" ) );
loop.exec();
QCOMPARE( w.mComboBox->currentText(), QString( "10" ) );

cbs[1]->setCurrentIndex( cbs[1]->findText( "120" ) );
loop.exec();
QCOMPARE( w.mComboBox->currentText(), QString( "10" ) );

cbs[2]->setCurrentIndex( cbs[2]->findText( QStringLiteral( "brides" ) ) );
loop.exec();
QCOMPARE( w.mComboBox->currentText(), QString( "10" ) );

cbs[1]->setCurrentIndex( cbs[1]->findText( QStringLiteral( "diameter" ) ) );
loop.exec();
QCOMPARE( w.mComboBox->currentText(), QString( "10" ) );

// combobox should propose NULL, 10 and 11 because the filter is now:
// "material" == 'iron'
@@ -200,6 +224,7 @@ void TestQgsRelationReferenceWidget::testChainFilter()
cbs[0]->setCurrentIndex( cbs[0]->findText( QStringLiteral( "material" ) ) );
loop.exec();
QCOMPARE( w.mComboBox->count(), 4 );
QCOMPARE( w.mComboBox->currentText(), QString( "NULL" ) );
}

void TestQgsRelationReferenceWidget::testChainFilterRefreshed()

0 comments on commit 7b53273

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