Skip to content

Commit 6574e69

Browse files
committed
Fixes value relation widget 0 indexed related items
Fixes #19981 - Value relation, value 0 = NULL
1 parent bb0c629 commit 6574e69

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

src/gui/editorwidgets/qgsvaluerelationwidgetwrapper.cpp

+17-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,23 @@ void QgsValueRelationWidgetWrapper::setValue( const QVariant &value )
179179
}
180180
else if ( mComboBox )
181181
{
182-
mComboBox->setCurrentIndex( mComboBox->findData( value ) );
182+
// findData fails to tell a 0 from a NULL
183+
// See: "Value relation, value 0 = NULL" - https://issues.qgis.org/issues/19981
184+
int idx = -1; // default to not found
185+
for ( int i = 0; i < mComboBox->count(); i++ )
186+
{
187+
QVariant v( mComboBox->itemData( i ) );
188+
if ( ( v.isNull() && !value.isNull() ) || ( !v.isNull() && value.isNull() ) )
189+
{
190+
continue;
191+
}
192+
if ( v == value )
193+
{
194+
idx = i;
195+
break;
196+
}
197+
}
198+
mComboBox->setCurrentIndex( idx );
183199
}
184200
else if ( mLineEdit )
185201
{

tests/src/gui/testqgsvaluerelationwidgetwrapper.cpp

+57
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ class TestQgsValueRelationWidgetWrapper : public QObject
4242
void testScrollBarUnlocked();
4343
void testDrillDown();
4444
void testDrillDownMulti();
45+
//! Checks that a related value of 0 is not interpreted as a NULL
46+
void testZeroIndexInRelatedTable();
4547
};
4648

4749
void TestQgsValueRelationWidgetWrapper::initTestCase()
@@ -200,6 +202,7 @@ void TestQgsValueRelationWidgetWrapper::testDrillDown()
200202
// Check null is selected
201203
QCOMPARE( w_municipality.mComboBox->count(), 3 );
202204
QCOMPARE( w_municipality.mComboBox->itemText( 0 ), QStringLiteral( "(no selection)" ) );
205+
QVERIFY( w_municipality.value().isNull() );
203206
QCOMPARE( w_municipality.value().toString(), QString() );
204207

205208
// Check order by value false
@@ -311,5 +314,59 @@ void TestQgsValueRelationWidgetWrapper::testDrillDownMulti()
311314

312315
}
313316

317+
void TestQgsValueRelationWidgetWrapper::testZeroIndexInRelatedTable()
318+
{
319+
// findData fails to tell a 0 from a NULL
320+
// See: "Value relation, value 0 = NULL" - https://issues.qgis.org/issues/19981
321+
322+
// create a vector layer
323+
QgsVectorLayer vl1( QStringLiteral( "Polygon?crs=epsg:4326&field=pk:int&field=province:int&field=municipality:string" ), QStringLiteral( "vl1" ), QStringLiteral( "memory" ) );
324+
QgsVectorLayer vl2( QStringLiteral( "Point?crs=epsg:4326&field=pk:int&field=fk_province:int&field=fk_municipality:int" ), QStringLiteral( "vl2" ), QStringLiteral( "memory" ) );
325+
QgsProject::instance()->addMapLayer( &vl1, false, false );
326+
QgsProject::instance()->addMapLayer( &vl2, false, false );
327+
328+
// insert some features
329+
QgsFeature f1( vl1.fields() );
330+
f1.setAttribute( QStringLiteral( "pk" ), 0 ); // !!! Notice: pk 0
331+
f1.setAttribute( QStringLiteral( "province" ), 123 );
332+
f1.setAttribute( QStringLiteral( "municipality" ), QStringLiteral( "Some Place By The River" ) );
333+
f1.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POLYGON(( 0 0, 0 1, 1 1, 1 0, 0 0 ))" ) ) );
334+
QVERIFY( f1.isValid() );
335+
QgsFeature f2( vl1.fields() );
336+
f2.setAttribute( QStringLiteral( "pk" ), 2 );
337+
f2.setAttribute( QStringLiteral( "province" ), 245 );
338+
f2.setAttribute( QStringLiteral( "municipality" ), QStringLiteral( "Dreamland By The Clouds" ) );
339+
f2.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POLYGON(( 1 0, 1 1, 2 1, 2 0, 1 0 ))" ) ) );
340+
QVERIFY( f2.isValid() );
341+
QVERIFY( vl1.dataProvider()->addFeatures( QgsFeatureList() << f1 << f2 ) );
342+
343+
QgsFeature f3( vl2.fields() );
344+
f3.setAttribute( QStringLiteral( "fk_province" ), 123 );
345+
f3.setAttribute( QStringLiteral( "fk_municipality" ), QStringLiteral( "0" ) );
346+
f3.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POINT( 0.5 0.5)" ) ) );
347+
QVERIFY( f3.isValid() );
348+
QVERIFY( f3.geometry().isGeosValid() );
349+
QVERIFY( vl2.dataProvider()->addFeature( f3 ) );
350+
351+
// build a value relation widget wrapper for municipality
352+
QgsValueRelationWidgetWrapper w_municipality( &vl2, vl2.fields().indexOf( QStringLiteral( "fk_municipality" ) ), nullptr, nullptr );
353+
QVariantMap cfg_municipality;
354+
cfg_municipality.insert( QStringLiteral( "Layer" ), vl1.id() );
355+
cfg_municipality.insert( QStringLiteral( "Key" ), QStringLiteral( "pk" ) );
356+
cfg_municipality.insert( QStringLiteral( "Value" ), QStringLiteral( "municipality" ) );
357+
cfg_municipality.insert( QStringLiteral( "AllowMulti" ), false );
358+
cfg_municipality.insert( QStringLiteral( "NofColumns" ), 1 );
359+
cfg_municipality.insert( QStringLiteral( "AllowNull" ), true );
360+
cfg_municipality.insert( QStringLiteral( "OrderByValue" ), false );
361+
cfg_municipality.insert( QStringLiteral( "UseCompleter" ), false );
362+
w_municipality.setConfig( cfg_municipality );
363+
w_municipality.widget();
364+
w_municipality.setEnabled( true );
365+
366+
w_municipality.setValue( 0 );
367+
QCOMPARE( w_municipality.mComboBox->currentIndex(), 1 );
368+
QCOMPARE( w_municipality.mComboBox->currentText(), QStringLiteral( "Some Place By The River" ) );
369+
}
370+
314371
QGSTEST_MAIN( TestQgsValueRelationWidgetWrapper )
315372
#include "testqgsvaluerelationwidgetwrapper.moc"

0 commit comments

Comments
 (0)