Skip to content

Commit

Permalink
Merge pull request #5043 from pblottiere/bugfix_refrel
Browse files Browse the repository at this point in the history
Fixes relation reference widget by refreshing filter lists. Fixes #16400
  • Loading branch information
Hugo Mercier committed Aug 18, 2017
2 parents f0d3677 + a2914ff commit 18c1597
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 47 deletions.
20 changes: 17 additions & 3 deletions src/gui/editorwidgets/qgsrelationreferencewidget.cpp
Expand Up @@ -280,6 +280,20 @@ void QgsRelationReferenceWidget::setForeignKey( const QVariant &value )
} }
else else
{ {
QVariant nullValue = QgsApplication::nullRepresentation();

if ( mChainFilters && mFeature.isValid() && mFilterComboBoxes.count() >= mFilterFields.count() )
{
QgsFeature feature = mFeature;

for ( int i = 0; i < mFilterFields.size(); i++ )
{
QVariant v = feature.attribute( mFilterFields[i] );
QString f = v.isNull() ? nullValue.toString() : v.toString();
mFilterComboBoxes.at( i )->setCurrentIndex( mFilterComboBoxes.at( i )->findText( f ) );
}
}

int i = mComboBox->findData( mFeature.id(), QgsAttributeTableModel::FeatureIdRole ); int i = mComboBox->findData( mFeature.id(), QgsAttributeTableModel::FeatureIdRole );
if ( i == -1 && mAllowNull ) if ( i == -1 && mAllowNull )
{ {
Expand Down Expand Up @@ -971,12 +985,12 @@ void QgsRelationReferenceWidget::disableChainedComboBoxes( const QComboBox *scb
continue; continue;
} }


cb->setCurrentIndex( 0 );
if ( ccb->currentIndex() == 0 ) if ( ccb->currentIndex() == 0 )
{ {
cb->setCurrentIndex( 0 );
cb->setEnabled( false ); cb->setEnabled( false );
} }
else
ccb = cb; ccb = cb;
} }
} }
129 changes: 85 additions & 44 deletions tests/src/gui/testqgsrelationreferencewidget.cpp
Expand Up @@ -39,6 +39,12 @@ class TestQgsRelationReferenceWidget : public QObject
void cleanup(); // will be called after every testfunction. void cleanup(); // will be called after every testfunction.


void testChainFilter(); void testChainFilter();
void testChainFilterRefreshed();

private:
std::unique_ptr<QgsVectorLayer> mLayer1;
std::unique_ptr<QgsVectorLayer> mLayer2;
std::unique_ptr<QgsRelation> mRelation;
}; };


void TestQgsRelationReferenceWidget::initTestCase() void TestQgsRelationReferenceWidget::initTestCase()
Expand All @@ -55,79 +61,79 @@ void TestQgsRelationReferenceWidget::cleanupTestCase()


void TestQgsRelationReferenceWidget::init() void TestQgsRelationReferenceWidget::init()
{ {
} // create layer

mLayer1.reset( new QgsVectorLayer( QStringLiteral( "LineString?crs=epsg:3111&field=pk:int&field=fk:int" ), QStringLiteral( "vl1" ), QStringLiteral( "memory" ) ) );
void TestQgsRelationReferenceWidget::cleanup() QgsProject::instance()->addMapLayer( mLayer1.get(), false, false );
{
} mLayer2.reset( new QgsVectorLayer( QStringLiteral( "LineString?field=pk:int&field=material:string&field=diameter:int&field=raccord:string" ), QStringLiteral( "vl2" ), QStringLiteral( "memory" ) ) );

QgsProject::instance()->addMapLayer( mLayer2.get(), false, false );
void TestQgsRelationReferenceWidget::testChainFilter()
{ // create relation
// create layers mRelation.reset( new QgsRelation() );
QgsVectorLayer vl1( QStringLiteral( "LineString?crs=epsg:3111&field=pk:int&field=fk:int" ), QStringLiteral( "vl1" ), QStringLiteral( "memory" ) ); mRelation->setId( QStringLiteral( "vl1.vl2" ) );
QgsVectorLayer vl2( QStringLiteral( "LineString?field=pk:int&field=material:string&field=diameter:int&field=raccord:string" ), QStringLiteral( "vl2" ), QStringLiteral( "memory" ) ); mRelation->setName( QStringLiteral( "vl1.vl2" ) );
QgsProject::instance()->addMapLayer( &vl1, false, false ); mRelation->setReferencingLayer( mLayer1->id() );
QgsProject::instance()->addMapLayer( &vl2, false, false ); mRelation->setReferencedLayer( mLayer2->id() );

mRelation->addFieldPair( "fk", "pk" );
// create a relation between them QVERIFY( mRelation->isValid() );
QgsRelation relation; QgsProject::instance()->relationManager()->addRelation( *mRelation.get() );
relation.setId( QStringLiteral( "vl1.vl2" ) );
relation.setName( QStringLiteral( "vl1.vl2" ) );
relation.setReferencingLayer( vl1.id() );
relation.setReferencedLayer( vl2.id() );
relation.addFieldPair( "fk", "pk" );
QVERIFY( relation.isValid() );
QgsProject::instance()->relationManager()->addRelation( relation );


// add features // add features
QgsFeature ft0( vl1.fields() ); QgsFeature ft0( mLayer1->fields() );
ft0.setAttribute( QStringLiteral( "pk" ), 0 ); ft0.setAttribute( QStringLiteral( "pk" ), 0 );
ft0.setAttribute( QStringLiteral( "fk" ), 0 ); ft0.setAttribute( QStringLiteral( "fk" ), 0 );
vl1.startEditing(); mLayer1->startEditing();
vl1.addFeature( ft0 ); mLayer1->addFeature( ft0 );
vl1.commitChanges(); mLayer1->commitChanges();


QgsFeature ft1( vl1.fields() ); QgsFeature ft1( mLayer1->fields() );
ft1.setAttribute( QStringLiteral( "pk" ), 1 ); ft1.setAttribute( QStringLiteral( "pk" ), 1 );
ft1.setAttribute( QStringLiteral( "fk" ), 1 ); ft1.setAttribute( QStringLiteral( "fk" ), 1 );
vl1.startEditing(); mLayer1->startEditing();
vl1.addFeature( ft1 ); mLayer1->addFeature( ft1 );
vl1.commitChanges(); mLayer1->commitChanges();


QgsFeature ft2( vl2.fields() ); QgsFeature ft2( mLayer2->fields() );
ft2.setAttribute( QStringLiteral( "pk" ), 10 ); ft2.setAttribute( QStringLiteral( "pk" ), 10 );
ft2.setAttribute( QStringLiteral( "material" ), "iron" ); ft2.setAttribute( QStringLiteral( "material" ), "iron" );
ft2.setAttribute( QStringLiteral( "diameter" ), 120 ); ft2.setAttribute( QStringLiteral( "diameter" ), 120 );
ft2.setAttribute( QStringLiteral( "raccord" ), "brides" ); ft2.setAttribute( QStringLiteral( "raccord" ), "brides" );
vl2.startEditing(); mLayer2->startEditing();
vl2.addFeature( ft2 ); mLayer2->addFeature( ft2 );
vl2.commitChanges(); mLayer2->commitChanges();


QgsFeature ft3( vl2.fields() ); QgsFeature ft3( mLayer2->fields() );
ft3.setAttribute( QStringLiteral( "pk" ), 11 ); ft3.setAttribute( QStringLiteral( "pk" ), 11 );
ft3.setAttribute( QStringLiteral( "material" ), "iron" ); ft3.setAttribute( QStringLiteral( "material" ), "iron" );
ft3.setAttribute( QStringLiteral( "diameter" ), 120 ); ft3.setAttribute( QStringLiteral( "diameter" ), 120 );
ft3.setAttribute( QStringLiteral( "raccord" ), "sleeve" ); ft3.setAttribute( QStringLiteral( "raccord" ), "sleeve" );
vl2.startEditing(); mLayer2->startEditing();
vl2.addFeature( ft3 ); mLayer2->addFeature( ft3 );
vl2.commitChanges(); mLayer2->commitChanges();


QgsFeature ft4( vl2.fields() ); QgsFeature ft4( mLayer2->fields() );
ft4.setAttribute( QStringLiteral( "pk" ), 12 ); ft4.setAttribute( QStringLiteral( "pk" ), 12 );
ft4.setAttribute( QStringLiteral( "material" ), "steel" ); ft4.setAttribute( QStringLiteral( "material" ), "steel" );
ft4.setAttribute( QStringLiteral( "diameter" ), 120 ); ft4.setAttribute( QStringLiteral( "diameter" ), 120 );
ft4.setAttribute( QStringLiteral( "raccord" ), "collar" ); ft4.setAttribute( QStringLiteral( "raccord" ), "collar" );
vl2.startEditing(); mLayer2->startEditing();
vl2.addFeature( ft4 ); mLayer2->addFeature( ft4 );
vl2.commitChanges(); mLayer2->commitChanges();
}


void TestQgsRelationReferenceWidget::cleanup()
{
}

void TestQgsRelationReferenceWidget::testChainFilter()
{
// init a relation reference widget // init a relation reference widget
QStringList filterFields = { "material", "diameter", "raccord" }; QStringList filterFields = { "material", "diameter", "raccord" };


QgsRelationReferenceWidget w( new QWidget() ); QgsRelationReferenceWidget w( new QWidget() );
w.setChainFilters( true ); w.setChainFilters( true );
w.setFilterFields( filterFields ); w.setFilterFields( filterFields );
w.setRelation( relation, true ); w.setRelation( *mRelation, true );
w.init(); w.init();


// check default status for comboboxes // check default status for comboboxes
Expand Down Expand Up @@ -181,5 +187,40 @@ void TestQgsRelationReferenceWidget::testChainFilter()
QCOMPARE( w.mComboBox->count(), 4 ); QCOMPARE( w.mComboBox->count(), 4 );
} }


void TestQgsRelationReferenceWidget::testChainFilterRefreshed()
{
// init a relation reference widget
QStringList filterFields = { "material", "diameter", "raccord" };

QgsRelationReferenceWidget w( new QWidget() );
w.setChainFilters( true );
w.setFilterFields( filterFields );
w.setRelation( *mRelation, true );
w.init();

// check default status for comboboxes
QList<QComboBox *> cbs = w.mFilterComboBoxes;
QCOMPARE( cbs.count(), 3 );
QCOMPARE( cbs[0]->currentText(), QString( "material" ) );
QCOMPARE( cbs[1]->currentText(), QString( "diameter" ) );
QCOMPARE( cbs[2]->currentText(), QString( "raccord" ) );

// update foreign key
w.setForeignKey( QVariant( 12 ) );
QCOMPARE( cbs[0]->currentText(), QString( "steel" ) );
QCOMPARE( cbs[1]->currentText(), QString( "120" ) );
QCOMPARE( cbs[2]->currentText(), QString( "collar" ) );

w.setForeignKey( QVariant( 10 ) );
QCOMPARE( cbs[0]->currentText(), QString( "iron" ) );
QCOMPARE( cbs[1]->currentText(), QString( "120" ) );
QCOMPARE( cbs[2]->currentText(), QString( "brides" ) );

w.setForeignKey( QVariant( 11 ) );
QCOMPARE( cbs[0]->currentText(), QString( "iron" ) );
QCOMPARE( cbs[1]->currentText(), QString( "120" ) );
QCOMPARE( cbs[2]->currentText(), QString( "sleeve" ) );
}

QGSTEST_MAIN( TestQgsRelationReferenceWidget ) QGSTEST_MAIN( TestQgsRelationReferenceWidget )
#include "testqgsrelationreferencewidget.moc" #include "testqgsrelationreferencewidget.moc"

0 comments on commit 18c1597

Please sign in to comment.