1 /***************************************************************************
2 testqgsvaluerelationwidgetwrapper.cpp
3 --------------------------------------
4 Date : 21 07 2017
5 Copyright : (C) 2017 Paul Blottiere
6 Email : paul dot blottiere at oslandia dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16
17 #include "qgstest.h"
18 #include <QScrollBar>
19 #include <QSignalSpy>
20
21 #include <editorwidgets/core/qgseditorwidgetregistry.h>
22 #include <qgsapplication.h>
23 #include <qgsproject.h>
24 #include <qgsvectorlayer.h>
25 #include "qgseditorwidgetwrapper.h"
26 #include <editorwidgets/qgsvaluerelationwidgetwrapper.h>
27 #include <QTableWidget>
28 #include <QComboBox>
29 #include "qgsgui.h"
30 #include <gdal_version.h>
31 #include <nlohmann/json.hpp>
32
33 class TestQgsValueRelationWidgetWrapper : public QObject
34 {
35 Q_OBJECT
36 public:
37 TestQgsValueRelationWidgetWrapper() = default;
38
39 private:
40 QTemporaryDir tempDir;
41
42 private slots:
43 void initTestCase(); // will be called before the first testfunction is executed.
44 void cleanupTestCase(); // will be called after the last testfunction was executed.
45 void init(); // will be called before each testfunction is executed.
46 void cleanup(); // will be called after every testfunction.
47
48 void testScrollBarUnlocked();
49 void testDrillDown();
50 void testDrillDownMulti();
51 //! Checks that a related value of 0 is not interpreted as a NULL
52 void testZeroIndexInRelatedTable();
53 void testWithJsonInPostgres();
54 void testWithJsonInGPKG();
55 void testWithTextInGPKG();
56 void testWithTextInGPKGTextFk();
57 void testWithTextInGPKGWeirdTextFk();
58 void testWithJsonInSpatialite();
59 void testWithJsonInSpatialiteTextFk();
60 void testMatchLayerName();
61 //! Check that setFeature works correctly after regression #42003
62 void testRegressionGH42003();
63 };
64
initTestCase()65 void TestQgsValueRelationWidgetWrapper::initTestCase()
66 {
67 QgsApplication::init();
68 QgsApplication::initQgis();
69 QgsGui::editorWidgetRegistry()->initEditors();
70 }
71
cleanupTestCase()72 void TestQgsValueRelationWidgetWrapper::cleanupTestCase()
73 {
74 QgsApplication::exitQgis();
75 }
76
init()77 void TestQgsValueRelationWidgetWrapper::init()
78 {
79 }
80
cleanup()81 void TestQgsValueRelationWidgetWrapper::cleanup()
82 {
83
84 }
85
testScrollBarUnlocked()86 void TestQgsValueRelationWidgetWrapper::testScrollBarUnlocked()
87 {
88 // create a vector layer
89 QgsVectorLayer vl1( QStringLiteral( "LineString?crs=epsg:3111&field=pk:int&field=fk|:int" ), QStringLiteral( "vl1" ), QStringLiteral( "memory" ) );
90 QgsProject::instance()->addMapLayer( &vl1, false, false );
91
92 // build a value relation widget wrapper
93 QgsValueRelationWidgetWrapper w( &vl1, 0, nullptr, nullptr );
94
95 QVariantMap config;
96 config.insert( QStringLiteral( "AllowMulti" ), true );
97 w.setConfig( config );
98 w.widget();
99 w.setEnabled( true );
100
101 // add an item virtually
102 QTableWidgetItem item;
103 item.setText( QStringLiteral( "MyText" ) );
104 w.mTableWidget->setItem( 0, 0, &item );
105
106 QCOMPARE( w.mTableWidget->item( 0, 0 )->text(), QString( "MyText" ) );
107
108 // when the widget wrapper is enabled, the container should be enabled
109 // as well as items
110 w.setEnabled( true );
111
112 QCOMPARE( w.widget()->isEnabled(), true );
113
114 bool itemEnabled = w.mTableWidget->item( 0, 0 )->flags() & Qt::ItemIsEnabled;
115 QCOMPARE( itemEnabled, true );
116
117 // when the widget wrapper is disabled, the container should still be enabled
118 // to keep the scrollbar available but items should be disabled to avoid
119 // edition
120 w.setEnabled( false );
121
122 itemEnabled = w.mTableWidget->item( 0, 0 )->flags() & Qt::ItemIsEnabled;
123 QCOMPARE( itemEnabled, false );
124
125 QCOMPARE( w.widget()->isEnabled(), true );
126
127 // recheck after re-enabled
128 w.setEnabled( true );
129
130 QCOMPARE( w.widget()->isEnabled(), true );
131 itemEnabled = w.mTableWidget->item( 0, 0 )->flags() & Qt::ItemIsEnabled;
132 QCOMPARE( itemEnabled, true );
133 }
134
testDrillDown()135 void TestQgsValueRelationWidgetWrapper::testDrillDown()
136 {
137 // create a vector layer
138 QgsVectorLayer vl1( QStringLiteral( "Polygon?crs=epsg:4326&field=pk:int&field=province:int&field=municipality:string" ), QStringLiteral( "vl1" ), QStringLiteral( "memory" ) );
139 QgsVectorLayer vl2( QStringLiteral( "Point?crs=epsg:4326&field=pk:int&field=fk_province:int&field=fk_municipality:int" ), QStringLiteral( "vl2" ), QStringLiteral( "memory" ) );
140 QgsProject::instance()->addMapLayer( &vl1, false, false );
141 QgsProject::instance()->addMapLayer( &vl2, false, false );
142
143 // insert some features
144 QgsFeature f1( vl1.fields() );
145 f1.setAttribute( QStringLiteral( "pk" ), 1 );
146 f1.setAttribute( QStringLiteral( "province" ), 123 );
147 f1.setAttribute( QStringLiteral( "municipality" ), QStringLiteral( "Some Place By The River" ) );
148 f1.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POLYGON(( 0 0, 0 1, 1 1, 1 0, 0 0 ))" ) ) );
149 QVERIFY( f1.isValid() );
150 QgsFeature f2( vl1.fields() );
151 f2.setAttribute( QStringLiteral( "pk" ), 2 );
152 f2.setAttribute( QStringLiteral( "province" ), 245 );
153 f2.setAttribute( QStringLiteral( "municipality" ), QStringLiteral( "Dreamland By The Clouds" ) );
154 f2.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POLYGON(( 1 0, 1 1, 2 1, 2 0, 1 0 ))" ) ) );
155 QVERIFY( f2.isValid() );
156 QVERIFY( vl1.dataProvider()->addFeatures( QgsFeatureList() << f1 << f2 ) );
157
158 QgsFeature f3( vl2.fields() );
159 f3.setAttribute( QStringLiteral( "fk_province" ), 123 );
160 f3.setAttribute( QStringLiteral( "fk_municipality" ), 1 );
161 f3.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POINT( 0.5 0.5)" ) ) );
162 QVERIFY( f3.isValid() );
163 QVERIFY( f3.geometry().isGeosValid() );
164 QVERIFY( vl2.dataProvider()->addFeature( f3 ) );
165
166 // build a value relation widget wrapper for municipality
167 QgsValueRelationWidgetWrapper w_municipality( &vl2, vl2.fields().indexOf( QLatin1String( "fk_municipality" ) ), nullptr, nullptr );
168 QVariantMap cfg_municipality;
169 cfg_municipality.insert( QStringLiteral( "Layer" ), vl1.id() );
170 cfg_municipality.insert( QStringLiteral( "Key" ), QStringLiteral( "pk" ) );
171 cfg_municipality.insert( QStringLiteral( "Value" ), QStringLiteral( "municipality" ) );
172 cfg_municipality.insert( QStringLiteral( "AllowMulti" ), false );
173 cfg_municipality.insert( QStringLiteral( "NofColumns" ), 1 );
174 cfg_municipality.insert( QStringLiteral( "AllowNull" ), false );
175 cfg_municipality.insert( QStringLiteral( "OrderByValue" ), true );
176 cfg_municipality.insert( QStringLiteral( "FilterExpression" ), QStringLiteral( "\"province\" = current_value('fk_province')" ) );
177 cfg_municipality.insert( QStringLiteral( "UseCompleter" ), false );
178 w_municipality.setConfig( cfg_municipality );
179 w_municipality.widget();
180 w_municipality.setEnabled( true );
181
182 QCOMPARE( w_municipality.mCache.size(), 2 );
183 QCOMPARE( w_municipality.mComboBox->count(), 2 );
184
185 // Set a feature
186 w_municipality.setFeature( vl2.getFeature( 1 ) );
187 QCOMPARE( w_municipality.mCache.size(), 1 );
188 QCOMPARE( w_municipality.mComboBox->count(), 1 );
189
190 // check that valueChanged signal is correctly triggered
191 const QSignalSpy spy( &w_municipality, &QgsEditorWidgetWrapper::valuesChanged );
192
193 w_municipality.setFeature( f3 );
194 QCOMPARE( spy.count(), 1 );
195 QCOMPARE( w_municipality.mCache.size(), 1 );
196
197 // Check first is selected
198 QCOMPARE( w_municipality.mComboBox->count(), 1 );
199 QCOMPARE( w_municipality.mComboBox->itemText( 0 ), QStringLiteral( "Some Place By The River" ) );
200 QCOMPARE( w_municipality.value().toString(), QStringLiteral( "1" ) );
201
202 // Filter by geometry
203 cfg_municipality[ QStringLiteral( "FilterExpression" ) ] = QStringLiteral( "contains(buffer(@current_geometry, 1 ), $geometry)" );
204 w_municipality.setConfig( cfg_municipality );
205 w_municipality.setFeature( f3 );
206 QCOMPARE( w_municipality.mComboBox->count(), 1 );
207 QCOMPARE( w_municipality.mComboBox->itemText( 0 ), QStringLiteral( "Some Place By The River" ) );
208
209 // Move the point to 1.5 0.5
210 f3.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POINT( 1.5 0.5)" ) ) );
211 w_municipality.setFeature( f3 );
212 QCOMPARE( w_municipality.mComboBox->count(), 1 );
213 QCOMPARE( w_municipality.mComboBox->itemText( 0 ), QStringLiteral( "Dreamland By The Clouds" ) );
214
215 // Enlarge the buffer
216 cfg_municipality[ QStringLiteral( "FilterExpression" ) ] = QStringLiteral( "contains(buffer(@current_geometry, 3 ), $geometry)" );
217 w_municipality.setConfig( cfg_municipality );
218 w_municipality.setFeature( f3 );
219 QCOMPARE( w_municipality.mComboBox->count(), 2 );
220 QCOMPARE( w_municipality.mComboBox->itemText( 0 ), QStringLiteral( "Dreamland By The Clouds" ) );
221 QCOMPARE( w_municipality.mComboBox->itemText( 1 ), QStringLiteral( "Some Place By The River" ) );
222
223 // Check with allow null
224 cfg_municipality[QStringLiteral( "AllowNull" )] = true;
225 w_municipality.setConfig( cfg_municipality );
226 w_municipality.setFeature( QgsFeature() );
227
228 // Check null is selected
229 QCOMPARE( w_municipality.mComboBox->count(), 3 );
230 QCOMPARE( w_municipality.mComboBox->itemText( 0 ), QStringLiteral( "(no selection)" ) );
231 QVERIFY( w_municipality.value().isNull() );
232 QCOMPARE( w_municipality.value().toString(), QString() );
233
234 // Check order by value false
235 cfg_municipality[QStringLiteral( "AllowNull" )] = false;
236 cfg_municipality[QStringLiteral( "OrderByValue" )] = false;
237 w_municipality.setConfig( cfg_municipality );
238 w_municipality.setFeature( f3 );
239 QCOMPARE( w_municipality.mComboBox->itemText( 1 ), QStringLiteral( "Dreamland By The Clouds" ) );
240 QCOMPARE( w_municipality.mComboBox->itemText( 0 ), QStringLiteral( "Some Place By The River" ) );
241
242 }
243
testDrillDownMulti()244 void TestQgsValueRelationWidgetWrapper::testDrillDownMulti()
245 {
246 // create a vector layer
247 QgsVectorLayer vl1( QStringLiteral( "Polygon?crs=epsg:4326&field=pk:int&field=province:int&field=municipality:string" ), QStringLiteral( "vl1" ), QStringLiteral( "memory" ) );
248 QgsVectorLayer vl2( QStringLiteral( "Point?crs=epsg:4326&field=pk:int&field=fk_province:int&field=fk_municipality:string" ), QStringLiteral( "vl2" ), QStringLiteral( "memory" ) );
249 QgsProject::instance()->addMapLayer( &vl1, false, false );
250 QgsProject::instance()->addMapLayer( &vl2, false, false );
251
252 // insert some features
253 QgsFeature f1( vl1.fields() );
254 f1.setAttribute( QStringLiteral( "pk" ), 1 );
255 f1.setAttribute( QStringLiteral( "province" ), 123 );
256 f1.setAttribute( QStringLiteral( "municipality" ), QStringLiteral( "Some Place By The River" ) );
257 f1.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POLYGON(( 0 0, 0 1, 1 1, 1 0, 0 0 ))" ) ) );
258 QVERIFY( f1.isValid() );
259 QgsFeature f2( vl1.fields() );
260 f2.setAttribute( QStringLiteral( "pk" ), 2 );
261 f2.setAttribute( QStringLiteral( "province" ), 245 );
262 f2.setAttribute( QStringLiteral( "municipality" ), QStringLiteral( "Dreamland By The Clouds" ) );
263 f2.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POLYGON(( 1 0, 1 1, 2 1, 2 0, 1 0 ))" ) ) );
264 QVERIFY( f2.isValid() );
265 QVERIFY( vl1.dataProvider()->addFeatures( QgsFeatureList() << f1 << f2 ) );
266
267 QgsFeature f3( vl2.fields() );
268 f3.setAttribute( QStringLiteral( "fk_province" ), 123 );
269 f3.setAttribute( QStringLiteral( "fk_municipality" ), QStringLiteral( "{1}" ) );
270 f3.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POINT( 0.5 0.5)" ) ) );
271 QVERIFY( f3.isValid() );
272 QVERIFY( f3.geometry().isGeosValid() );
273 QVERIFY( vl2.dataProvider()->addFeature( f3 ) );
274
275 // build a value relation widget wrapper for municipality
276 QgsValueRelationWidgetWrapper w_municipality( &vl2, vl2.fields().indexOf( QLatin1String( "fk_municipality" ) ), nullptr, nullptr );
277 QVariantMap cfg_municipality;
278 cfg_municipality.insert( QStringLiteral( "Layer" ), vl1.id() );
279 cfg_municipality.insert( QStringLiteral( "Key" ), QStringLiteral( "pk" ) );
280 cfg_municipality.insert( QStringLiteral( "Value" ), QStringLiteral( "municipality" ) );
281 cfg_municipality.insert( QStringLiteral( "AllowMulti" ), true );
282 cfg_municipality.insert( QStringLiteral( "NofColumns" ), 1 );
283 cfg_municipality.insert( QStringLiteral( "AllowNull" ), false );
284 cfg_municipality.insert( QStringLiteral( "OrderByValue" ), true );
285 cfg_municipality.insert( QStringLiteral( "FilterExpression" ), QStringLiteral( "\"province\" = current_value('fk_province')" ) );
286 cfg_municipality.insert( QStringLiteral( "UseCompleter" ), false );
287 w_municipality.setConfig( cfg_municipality );
288 w_municipality.widget();
289 w_municipality.setEnabled( true );
290
291 QCOMPARE( w_municipality.mCache.size(), 2 );
292 QCOMPARE( w_municipality.mTableWidget->rowCount(), 2 );
293 w_municipality.setFeature( f3 );
294 QCOMPARE( w_municipality.mCache.size(), 1 );
295
296 QCOMPARE( w_municipality.mTableWidget->rowCount(), 1 );
297 QCOMPARE( w_municipality.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Some Place By The River" ) );
298 QCOMPARE( w_municipality.value(), QVariant( QStringLiteral( "{1}" ) ) );
299
300 // Filter by geometry
301 cfg_municipality[ QStringLiteral( "FilterExpression" ) ] = QStringLiteral( "contains(buffer(@current_geometry, 1 ), $geometry)" );
302 w_municipality.setConfig( cfg_municipality );
303 w_municipality.setFeature( f3 );
304 QCOMPARE( w_municipality.mTableWidget->rowCount(), 1 );
305 QCOMPARE( w_municipality.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Some Place By The River" ) );
306
307 // Move the point to 1.5 0.5
308 f3.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POINT( 1.5 0.5)" ) ) );
309 w_municipality.setFeature( f3 );
310 QCOMPARE( w_municipality.mTableWidget->rowCount(), 1 );
311 QCOMPARE( w_municipality.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Dreamland By The Clouds" ) );
312
313 // Enlarge the buffer
314 cfg_municipality[ QStringLiteral( "FilterExpression" ) ] = QStringLiteral( "contains(buffer(@current_geometry, 3 ), $geometry)" );
315 w_municipality.setConfig( cfg_municipality );
316 w_municipality.setFeature( f3 );
317 QCOMPARE( w_municipality.mTableWidget->rowCount(), 2 );
318 QCOMPARE( w_municipality.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Dreamland By The Clouds" ) );
319 QCOMPARE( w_municipality.mTableWidget->item( 0, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "2" ) );
320 QCOMPARE( w_municipality.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Some Place By The River" ) );
321 QCOMPARE( w_municipality.mTableWidget->item( 1, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "1" ) );
322 QCOMPARE( w_municipality.value(), QVariant( QStringLiteral( "{1}" ) ) );
323 QCOMPARE( w_municipality.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
324 QCOMPARE( w_municipality.mTableWidget->item( 1, 0 )->checkState(), Qt::Checked );
325 w_municipality.setValues( QStringLiteral( "{1,2}" ), QVariantList() );
326 QCOMPARE( w_municipality.value(), QVariant( QStringLiteral( "{2,1}" ) ) );
327 QCOMPARE( w_municipality.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
328 QCOMPARE( w_municipality.mTableWidget->item( 1, 0 )->checkState(), Qt::Checked );
329
330 // Check with passing a variant list
331 w_municipality.setValues( QVariantList( {1, 2} ), QVariantList() );
332 QCOMPARE( w_municipality.value(), QVariant( QStringLiteral( "{2,1}" ) ) );
333
334 // Check values are checked
335 f3.setAttribute( QStringLiteral( "fk_municipality" ), QStringLiteral( "{1,2}" ) );
336 w_municipality.setFeature( f3 );
337 QCOMPARE( w_municipality.mTableWidget->rowCount(), 2 );
338 QCOMPARE( w_municipality.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Dreamland By The Clouds" ) );
339 QCOMPARE( w_municipality.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Some Place By The River" ) );
340 QCOMPARE( w_municipality.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
341 QCOMPARE( w_municipality.mTableWidget->item( 1, 0 )->checkState(), Qt::Checked );
342 QCOMPARE( w_municipality.value(), QVariant( QStringLiteral( "{2,1}" ) ) );
343 }
344
testZeroIndexInRelatedTable()345 void TestQgsValueRelationWidgetWrapper::testZeroIndexInRelatedTable()
346 {
347 // findData fails to tell a 0 from a NULL
348 // See: "Value relation, value 0 = NULL" - https://github.com/qgis/QGIS/issues/27803
349
350 // create a vector layer
351 QgsVectorLayer vl1( QStringLiteral( "Polygon?crs=epsg:4326&field=pk:int&field=province:int&field=municipality:string" ), QStringLiteral( "vl1" ), QStringLiteral( "memory" ) );
352 QgsVectorLayer vl2( QStringLiteral( "Point?crs=epsg:4326&field=pk:int&field=fk_province:int&field=fk_municipality:int" ), QStringLiteral( "vl2" ), QStringLiteral( "memory" ) );
353 QgsProject::instance()->addMapLayer( &vl1, false, false );
354 QgsProject::instance()->addMapLayer( &vl2, false, false );
355
356 // insert some features
357 QgsFeature f1( vl1.fields() );
358 f1.setAttribute( QStringLiteral( "pk" ), 0 ); // !!! Notice: pk 0
359 f1.setAttribute( QStringLiteral( "province" ), 123 );
360 f1.setAttribute( QStringLiteral( "municipality" ), QStringLiteral( "Some Place By The River" ) );
361 f1.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POLYGON(( 0 0, 0 1, 1 1, 1 0, 0 0 ))" ) ) );
362 QVERIFY( f1.isValid() );
363 QgsFeature f2( vl1.fields() );
364 f2.setAttribute( QStringLiteral( "pk" ), 2 );
365 f2.setAttribute( QStringLiteral( "province" ), 245 );
366 f2.setAttribute( QStringLiteral( "municipality" ), QStringLiteral( "Dreamland By The Clouds" ) );
367 f2.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POLYGON(( 1 0, 1 1, 2 1, 2 0, 1 0 ))" ) ) );
368 QVERIFY( f2.isValid() );
369 QVERIFY( vl1.dataProvider()->addFeatures( QgsFeatureList() << f1 << f2 ) );
370
371 QgsFeature f3( vl2.fields() );
372 f3.setAttribute( QStringLiteral( "fk_province" ), 123 );
373 f3.setAttribute( QStringLiteral( "fk_municipality" ), QStringLiteral( "0" ) );
374 f3.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POINT( 0.5 0.5)" ) ) );
375 QVERIFY( f3.isValid() );
376 QVERIFY( f3.geometry().isGeosValid() );
377 QVERIFY( vl2.dataProvider()->addFeature( f3 ) );
378
379 // build a value relation widget wrapper for municipality
380 QgsValueRelationWidgetWrapper w_municipality( &vl2, vl2.fields().indexOf( QLatin1String( "fk_municipality" ) ), nullptr, nullptr );
381 QVariantMap cfg_municipality;
382 cfg_municipality.insert( QStringLiteral( "Layer" ), vl1.id() );
383 cfg_municipality.insert( QStringLiteral( "Key" ), QStringLiteral( "pk" ) );
384 cfg_municipality.insert( QStringLiteral( "Value" ), QStringLiteral( "municipality" ) );
385 cfg_municipality.insert( QStringLiteral( "AllowMulti" ), false );
386 cfg_municipality.insert( QStringLiteral( "NofColumns" ), 1 );
387 cfg_municipality.insert( QStringLiteral( "AllowNull" ), true );
388 cfg_municipality.insert( QStringLiteral( "OrderByValue" ), false );
389 cfg_municipality.insert( QStringLiteral( "UseCompleter" ), false );
390 w_municipality.setConfig( cfg_municipality );
391 w_municipality.widget();
392 w_municipality.setEnabled( true );
393
394 w_municipality.setValues( 0, QVariantList() );
395 QCOMPARE( w_municipality.mComboBox->currentIndex(), 1 );
396 QCOMPARE( w_municipality.mComboBox->currentText(), QStringLiteral( "Some Place By The River" ) );
397 }
398
testWithJsonInPostgres()399 void TestQgsValueRelationWidgetWrapper::testWithJsonInPostgres()
400 {
401 #ifdef ENABLE_PGTEST
402 //this is only reading
403
404 // create pg layers
405 QString dbConn = getenv( "QGIS_PGTEST_DB" );
406 if ( dbConn.isEmpty() )
407 {
408 dbConn = "service=\"qgis_test\"";
409 }
410 QgsVectorLayer *vl_json = new QgsVectorLayer( QStringLiteral( "%1 sslmode=disable key=\"pk\" table=\"qgis_test\".\"json\" sql=" ).arg( dbConn ), QStringLiteral( "json" ), QStringLiteral( "postgres" ) );
411 QgsVectorLayer *vl_authors = new QgsVectorLayer( QStringLiteral( "%1 sslmode=disable key='pk' table=\"qgis_test\".\"authors\" sql=" ).arg( dbConn ), QStringLiteral( "authors" ), QStringLiteral( "postgres" ) );
412 QVERIFY( vl_json->isValid() );
413 QVERIFY( vl_authors->isValid() );
414
415 QgsProject::instance()->addMapLayer( vl_json, false, false );
416 QgsProject::instance()->addMapLayer( vl_authors, false, false );
417
418 QCOMPARE( vl_json->fields().at( 1 ).type(), QVariant::Map );
419
420 // build a value relation widget wrapper for json field
421 QgsValueRelationWidgetWrapper w_favoriteauthors( vl_json, vl_json->fields().indexOf( QLatin1String( "jvalue" ) ), nullptr, nullptr );
422 QVariantMap cfg_favoriteauthors;
423 cfg_favoriteauthors.insert( QStringLiteral( "Layer" ), vl_authors->id() );
424 cfg_favoriteauthors.insert( QStringLiteral( "Key" ), QStringLiteral( "pk" ) );
425 cfg_favoriteauthors.insert( QStringLiteral( "Value" ), QStringLiteral( "name" ) );
426 cfg_favoriteauthors.insert( QStringLiteral( "AllowMulti" ), true );
427 cfg_favoriteauthors.insert( QStringLiteral( "NofColumns" ), 1 );
428 cfg_favoriteauthors.insert( QStringLiteral( "AllowNull" ), false );
429 cfg_favoriteauthors.insert( QStringLiteral( "OrderByValue" ), false );
430 cfg_favoriteauthors.insert( QStringLiteral( "UseCompleter" ), false );
431 w_favoriteauthors.setConfig( cfg_favoriteauthors );
432 w_favoriteauthors.widget();
433 w_favoriteauthors.setEnabled( true );
434
435 //check if set up nice
436 QCOMPARE( w_favoriteauthors.mTableWidget->rowCount(), 7 );
437 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
438 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "1" ) );
439 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
440 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "2" ) );
441 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
442 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "3" ) );
443 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
444 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "4" ) );
445 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
446 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "5" ) );
447 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
448 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "6" ) );
449
450 //check if first feature checked correctly (should be 1,2,3 and the rest is not)
451 w_favoriteauthors.setFeature( vl_json->getFeature( 1 ) );
452 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
453 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
454 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
455 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Checked );
456 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
457 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
458 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
459 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
460 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
461 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked );
462 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
463 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
464
465 // build a value relation widget wrapper for jsonb field
466 QgsValueRelationWidgetWrapper w_favoriteauthors_b( vl_json, vl_json->fields().indexOf( QLatin1String( "jbvalue" ) ), nullptr, nullptr );
467 QVariantMap cfg_favoriteauthors_b;
468 cfg_favoriteauthors_b.insert( QStringLiteral( "Layer" ), vl_authors->id() );
469 cfg_favoriteauthors_b.insert( QStringLiteral( "Key" ), QStringLiteral( "pk" ) );
470 cfg_favoriteauthors_b.insert( QStringLiteral( "Value" ), QStringLiteral( "name" ) );
471 cfg_favoriteauthors_b.insert( QStringLiteral( "AllowMulti" ), true );
472 cfg_favoriteauthors_b.insert( QStringLiteral( "NofColumns" ), 1 );
473 cfg_favoriteauthors_b.insert( QStringLiteral( "AllowNull" ), false );
474 cfg_favoriteauthors_b.insert( QStringLiteral( "OrderByValue" ), false );
475 cfg_favoriteauthors_b.insert( QStringLiteral( "UseCompleter" ), false );
476 w_favoriteauthors_b.setConfig( cfg_favoriteauthors_b );
477 w_favoriteauthors_b.widget();
478 w_favoriteauthors_b.setEnabled( true );
479
480 //check if set up nice
481 QCOMPARE( w_favoriteauthors_b.mTableWidget->rowCount(), 7 );
482 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
483 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 0, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "1" ) );
484 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
485 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 1, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "2" ) );
486 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
487 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 2, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "3" ) );
488 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
489 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 3, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "4" ) );
490 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
491 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 4, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "5" ) );
492 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
493 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 5, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "6" ) );
494
495 //check if second feature checked correctly (should be 4,5,6 and the rest is not)
496 w_favoriteauthors_b.setFeature( vl_json->getFeature( 1 ) );
497 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
498 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
499 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
500 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
501 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
502 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
503 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
504 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 3, 0 )->checkState(), Qt::Checked );
505 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
506 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
507 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
508 QCOMPARE( w_favoriteauthors_b.mTableWidget->item( 5, 0 )->checkState(), Qt::Checked );
509
510 // check value from widget wrapper
511 QCOMPARE( w_favoriteauthors_b.value().toStringList(), QStringList() << "4" << "5" << "6" );
512 #endif
513 }
514
testWithJsonInGPKG()515 void TestQgsValueRelationWidgetWrapper::testWithJsonInGPKG()
516 {
517 // create ogr gpkg layers
518 const QString myFileName( TEST_DATA_DIR ); //defined in CmakeLists.txt
519 const QString myTempDirName = tempDir.path();
520 QFile::copy( myFileName + "/provider/test_json.gpkg", myTempDirName + "/test_json.gpkg" );
521 const QString myTempFileName = myTempDirName + "/test_json.gpkg";
522 const QFileInfo myMapFileInfo( myTempFileName );
523 QgsVectorLayer *vl_json = new QgsVectorLayer( myMapFileInfo.filePath() + "|layername=foo", "test", QStringLiteral( "ogr" ) );
524 QgsVectorLayer *vl_authors = new QgsVectorLayer( myMapFileInfo.filePath() + "|layername=author", "test", QStringLiteral( "ogr" ) );
525 QVERIFY( vl_json->isValid() );
526 QVERIFY( vl_authors->isValid() );
527
528 QgsProject::instance()->addMapLayer( vl_json, false, false );
529 QgsProject::instance()->addMapLayer( vl_authors, false, false );
530 vl_json->startEditing();
531
532 // build a value relation widget wrapper for authors
533 QgsValueRelationWidgetWrapper w_favoriteauthors( vl_json, vl_json->fields().indexOf( QLatin1String( "json_content" ) ), nullptr, nullptr );
534 QVariantMap cfg_favoriteauthors;
535 cfg_favoriteauthors.insert( QStringLiteral( "Layer" ), vl_authors->id() );
536 cfg_favoriteauthors.insert( QStringLiteral( "Key" ), QStringLiteral( "fid" ) );
537 cfg_favoriteauthors.insert( QStringLiteral( "Value" ), QStringLiteral( "NAME" ) );
538 cfg_favoriteauthors.insert( QStringLiteral( "AllowMulti" ), true );
539 cfg_favoriteauthors.insert( QStringLiteral( "NofColumns" ), 1 );
540 cfg_favoriteauthors.insert( QStringLiteral( "AllowNull" ), false );
541 cfg_favoriteauthors.insert( QStringLiteral( "OrderByValue" ), false );
542 cfg_favoriteauthors.insert( QStringLiteral( "UseCompleter" ), false );
543 w_favoriteauthors.setConfig( cfg_favoriteauthors );
544 w_favoriteauthors.widget();
545 w_favoriteauthors.setEnabled( true );
546
547 //check if set up nice
548 QCOMPARE( w_favoriteauthors.mTableWidget->rowCount(), 6 );
549 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
550 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "1" ) );
551 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
552 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "2" ) );
553 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
554 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "3" ) );
555 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
556 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "4" ) );
557 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
558 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "5" ) );
559 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
560 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "6" ) );
561
562 w_favoriteauthors.setFeature( vl_json->getFeature( 1 ) );
563
564 //check if first feature checked correctly (none)
565 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
566 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
567 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
568 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
569 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
570 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
571 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
572 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
573 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
574 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked );
575 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
576 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
577
578 //check other authors
579 w_favoriteauthors.mTableWidget->item( 0, 0 )->setCheckState( Qt::Checked );
580 w_favoriteauthors.mTableWidget->item( 2, 0 )->setCheckState( Qt::Checked );
581 w_favoriteauthors.mTableWidget->item( 4, 0 )->setCheckState( Qt::Checked );
582
583 //check if first feature checked correctly 0, 2, 4 (means the fids 1, 3, 5)
584 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
585 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
586 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
587 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
588 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
589 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
590 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
591 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
592 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
593 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
594 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
595 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
596
597 //we do jump over the part with QgsAttributeForm::saveEdits
598 vl_json->changeAttributeValue( 1, 4, w_favoriteauthors.value() );
599
600 w_favoriteauthors.setFeature( vl_json->getFeature( 2 ) );
601 //check if second feature checked correctly (none)
602 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
603 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
604 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
605 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
606 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
607 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
608 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
609 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
610 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
611 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked );
612 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
613 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
614
615 w_favoriteauthors.setFeature( vl_json->getFeature( 1 ) );
616 //check if first feature checked correctly 0, 2, 4
617 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
618 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
619 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
620 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
621 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
622 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
623 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
624 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
625 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
626 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
627 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
628 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
629
630 // check if stored correctly
631 vl_json->commitChanges();
632 QVariantList expected_vl;
633 expected_vl << "1" << "3" << "5";
634
635 const QgsFeature f = vl_json->getFeature( 1 );
636 const QVariant attribute = f.attribute( QStringLiteral( "json_content" ) );
637 const QList<QVariant> value = attribute.toList();
638 QCOMPARE( value, expected_vl );
639 }
640
641 // Same test procedure like in testWithJsonInGPKG to check the non-json way of storing multi-selections into formatted strings
testWithTextInGPKG()642 void TestQgsValueRelationWidgetWrapper::testWithTextInGPKG()
643 {
644 // create ogr gpkg layers
645 const QString myFileName( TEST_DATA_DIR ); //defined in CmakeLists.txt
646 const QString myTempDirName = tempDir.path();
647 QFile::copy( myFileName + "/provider/test_json.gpkg", myTempDirName + "/test_json.gpkg" );
648 const QString myTempFileName = myTempDirName + "/test_json.gpkg";
649 const QFileInfo myMapFileInfo( myTempFileName );
650 QgsVectorLayer *vl_text = new QgsVectorLayer( myMapFileInfo.filePath() + "|layername=foo", "test", QStringLiteral( "ogr" ) );
651 QgsVectorLayer *vl_authors = new QgsVectorLayer( myMapFileInfo.filePath() + "|layername=author", "test", QStringLiteral( "ogr" ) );
652 QVERIFY( vl_text->isValid() );
653 QVERIFY( vl_authors->isValid() );
654
655 QgsProject::instance()->addMapLayer( vl_text, false, false );
656 QgsProject::instance()->addMapLayer( vl_authors, false, false );
657 vl_text->startEditing();
658
659 // build a value relation widget wrapper for authors
660 QgsValueRelationWidgetWrapper w_favoriteauthors( vl_text, vl_text->fields().indexOf( QLatin1String( "PRFEDEA" ) ), nullptr, nullptr );
661 QVariantMap cfg_favoriteauthors;
662 cfg_favoriteauthors.insert( QStringLiteral( "Layer" ), vl_authors->id() );
663 cfg_favoriteauthors.insert( QStringLiteral( "Key" ), QStringLiteral( "fid" ) );
664 cfg_favoriteauthors.insert( QStringLiteral( "Value" ), QStringLiteral( "NAME" ) );
665 cfg_favoriteauthors.insert( QStringLiteral( "AllowMulti" ), true );
666 cfg_favoriteauthors.insert( QStringLiteral( "NofColumns" ), 1 );
667 cfg_favoriteauthors.insert( QStringLiteral( "AllowNull" ), false );
668 cfg_favoriteauthors.insert( QStringLiteral( "OrderByValue" ), false );
669 cfg_favoriteauthors.insert( QStringLiteral( "UseCompleter" ), false );
670 w_favoriteauthors.setConfig( cfg_favoriteauthors );
671 w_favoriteauthors.widget();
672 w_favoriteauthors.setEnabled( true );
673
674 //check if set up nice
675 QCOMPARE( w_favoriteauthors.mTableWidget->rowCount(), 6 );
676 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
677 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "1" ) );
678 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
679 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "2" ) );
680 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
681 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "3" ) );
682 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
683 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "4" ) );
684 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
685 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "5" ) );
686 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
687 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "6" ) );
688
689 w_favoriteauthors.setFeature( vl_text->getFeature( 1 ) );
690
691 //check if first feature checked correctly (none)
692 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
693 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
694 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
695 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
696 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
697 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
698 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
699 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
700 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
701 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked );
702 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
703 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
704
705 //check other authors
706 w_favoriteauthors.mTableWidget->item( 0, 0 )->setCheckState( Qt::Checked );
707 w_favoriteauthors.mTableWidget->item( 2, 0 )->setCheckState( Qt::Checked );
708 w_favoriteauthors.mTableWidget->item( 4, 0 )->setCheckState( Qt::Checked );
709
710 //check if first feature checked correctly 0, 2, 4 (means the fids 1, 3, 5)
711 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
712 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
713 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
714 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
715 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
716 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
717 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
718 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
719 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
720 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
721 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
722 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
723
724 //we do jump over the part with QgsAttributeForm::saveEdits
725 vl_text->changeAttributeValue( 1, 3, w_favoriteauthors.value() );
726
727 w_favoriteauthors.setFeature( vl_text->getFeature( 2 ) );
728 //check if second feature checked correctly (none)
729 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
730 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
731 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
732 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
733 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
734 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
735 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
736 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
737 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
738 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked );
739 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
740 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
741
742 w_favoriteauthors.setFeature( vl_text->getFeature( 1 ) );
743 //check if first feature checked correctly 0, 2, 4
744 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
745 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
746 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
747 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
748 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
749 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
750 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
751 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
752 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
753 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
754 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
755 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
756
757 // check if stored correctly
758
759 vl_text->commitChanges();
760 const QString expected_string QStringLiteral( "{1,3,5}" );
761
762 const QgsFeature f = vl_text->getFeature( 1 );
763 const QVariant attribute = f.attribute( QStringLiteral( "PRFEDEA" ) );
764 const QString value = attribute.toString();
765 QCOMPARE( value, expected_string );
766
767 w_favoriteauthors.setFeature( vl_text->getFeature( 1 ) );
768
769 //check if first feature checked correctly 0, 2, 4 (means the fids 1, 3, 5) after the commit
770 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
771 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
772 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
773 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
774 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
775 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
776 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
777 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
778 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
779 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
780 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
781 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
782
783 //reread completely
784 QgsVectorLayer *vl_text_reread = new QgsVectorLayer( myMapFileInfo.filePath() + "|layername=foo", "test", QStringLiteral( "ogr" ) );
785 QVERIFY( vl_text_reread->isValid() );
786
787 QgsProject::instance()->addMapLayer( vl_text_reread, false, false );
788 vl_text_reread->startEditing();
789
790 // build a value relation widget wrapper for authors
791 QgsValueRelationWidgetWrapper w_favoriteauthors_reread( vl_text_reread, vl_text->fields().indexOf( QLatin1String( "PRFEDEA" ) ), nullptr, nullptr );
792 w_favoriteauthors_reread.setConfig( cfg_favoriteauthors );
793 w_favoriteauthors_reread.widget();
794 w_favoriteauthors_reread.setEnabled( true );
795
796 w_favoriteauthors_reread.setFeature( vl_text_reread->getFeature( 1 ) );
797
798 //check if first feature on new layer checked correctly 0, 2, 4 (means the fids 1, 3, 5) after the reread
799 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
800 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
801 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
802 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
803 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
804 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
805 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
806 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
807 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
808 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
809 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
810 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
811 }
812
813 // Storing of strings as key and handle the quotes
testWithTextInGPKGTextFk()814 void TestQgsValueRelationWidgetWrapper::testWithTextInGPKGTextFk()
815 {
816 // create ogr gpkg layers
817 const QString myFileName( TEST_DATA_DIR ); //defined in CmakeLists.txt
818 const QString myTempDirName = tempDir.path();
819 QFile::copy( myFileName + "/provider/test_json.gpkg", myTempDirName + "/test_json.gpkg" );
820 const QString myTempFileName = myTempDirName + "/test_json.gpkg";
821 const QFileInfo myMapFileInfo( myTempFileName );
822 QgsVectorLayer *vl_text = new QgsVectorLayer( myMapFileInfo.filePath() + "|layername=foo", "test", QStringLiteral( "ogr" ) );
823 QgsVectorLayer *vl_authors = new QgsVectorLayer( myMapFileInfo.filePath() + "|layername=author", "test", QStringLiteral( "ogr" ) );
824 QVERIFY( vl_text->isValid() );
825 QVERIFY( vl_authors->isValid() );
826
827 QgsProject::instance()->addMapLayer( vl_text, false, false );
828 QgsProject::instance()->addMapLayer( vl_authors, false, false );
829 vl_text->startEditing();
830
831 // build a value relation widget wrapper for authors
832 QgsValueRelationWidgetWrapper w_favoriteauthors( vl_text, vl_text->fields().indexOf( QLatin1String( "PRFEDEA" ) ), nullptr, nullptr );
833 QVariantMap cfg_favoriteauthors;
834 cfg_favoriteauthors.insert( QStringLiteral( "Layer" ), vl_authors->id() );
835 cfg_favoriteauthors.insert( QStringLiteral( "Key" ), QStringLiteral( "NAME" ) );
836 cfg_favoriteauthors.insert( QStringLiteral( "Value" ), QStringLiteral( "NAME" ) );
837 cfg_favoriteauthors.insert( QStringLiteral( "AllowMulti" ), true );
838 cfg_favoriteauthors.insert( QStringLiteral( "NofColumns" ), 1 );
839 cfg_favoriteauthors.insert( QStringLiteral( "AllowNull" ), false );
840 cfg_favoriteauthors.insert( QStringLiteral( "OrderByValue" ), false );
841 cfg_favoriteauthors.insert( QStringLiteral( "UseCompleter" ), false );
842 w_favoriteauthors.setConfig( cfg_favoriteauthors );
843 w_favoriteauthors.widget();
844 w_favoriteauthors.setEnabled( true );
845
846 //check if set up nice
847 QCOMPARE( w_favoriteauthors.mTableWidget->rowCount(), 6 );
848 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
849 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "Douglas Adams" ) );
850 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
851 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "Erich Gamma" ) );
852 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "John Vlissides" ) );
853 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "John Vlissides" ) );
854 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "Ken Follett" ) );
855 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "Ken Follett" ) );
856 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
857 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "Ralph Johnson" ) );
858 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Richard Helm" ) );
859 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "Richard Helm" ) );
860
861 w_favoriteauthors.setFeature( vl_text->getFeature( 1 ) );
862
863 //check if first feature checked correctly (none)
864 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
865 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
866 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
867 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
868 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "John Vlissides" ) );
869 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
870 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "Ken Follett" ) );
871 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
872 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
873 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked );
874 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Richard Helm" ) );
875 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
876
877 //check other authors 0, 2, 4 (means the names "Douglas Adams", "John Vliessides", "Ralph Johnson")
878 w_favoriteauthors.mTableWidget->item( 0, 0 )->setCheckState( Qt::Checked );
879 w_favoriteauthors.mTableWidget->item( 2, 0 )->setCheckState( Qt::Checked );
880 w_favoriteauthors.mTableWidget->item( 4, 0 )->setCheckState( Qt::Checked );
881
882 //check if first feature checked correctly 0, 2, 4 (means the names "Douglas Adams", "John Vliessides", "Ralph Johnson")
883 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
884 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
885 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
886 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
887 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "John Vlissides" ) );
888 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
889 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "Ken Follett" ) );
890 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
891 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
892 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
893 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Richard Helm" ) );
894 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
895
896 //we do jump over the part with QgsAttributeForm::saveEdits
897 vl_text->changeAttributeValue( 1, 3, w_favoriteauthors.value() );
898
899 w_favoriteauthors.setFeature( vl_text->getFeature( 2 ) );
900 //check if second feature checked correctly (none)
901 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
902 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
903 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
904 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
905 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "John Vlissides" ) );
906 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
907 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "Ken Follett" ) );
908 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
909 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
910 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked );
911 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Richard Helm" ) );
912 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
913
914 w_favoriteauthors.setFeature( vl_text->getFeature( 1 ) );
915 //check if first feature checked correctly 0, 2, 4
916 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
917 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
918 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
919 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
920 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "John Vlissides" ) );
921 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
922 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "Ken Follett" ) );
923 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
924 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
925 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
926 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Richard Helm" ) );
927 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
928
929 // check if stored correctly
930 vl_text->commitChanges();
931 QString expected_string = QStringLiteral( "{\"Douglas Adams\",\"John Vlissides\",\"Ralph Johnson\"}" );
932
933 QgsFeature f = vl_text->getFeature( 1 );
934 QVariant attribute = f.attribute( QStringLiteral( "PRFEDEA" ) );
935 QString value = attribute.toString();
936 QCOMPARE( value, expected_string );
937
938 w_favoriteauthors.setFeature( vl_text->getFeature( 1 ) );
939
940 //check if first feature checked correctly 0, 2, 4 (means the names "Douglas Adams", "John Vliessides", "Ralph Johnson") after the commit
941 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
942 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
943 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
944 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
945 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "John Vlissides" ) );
946 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
947 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "Ken Follett" ) );
948 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
949 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
950 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
951 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Richard Helm" ) );
952 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
953
954 //reread completely
955 QgsVectorLayer *vl_text_reread = new QgsVectorLayer( myMapFileInfo.filePath() + "|layername=foo", "test", QStringLiteral( "ogr" ) );
956 QVERIFY( vl_text_reread->isValid() );
957
958 QgsProject::instance()->addMapLayer( vl_text_reread, false, false );
959 vl_text_reread->startEditing();
960
961 // build a value relation widget wrapper for authors
962 QgsValueRelationWidgetWrapper w_favoriteauthors_reread( vl_text_reread, vl_text_reread->fields().indexOf( QLatin1String( "PRFEDEA" ) ), nullptr, nullptr );
963 w_favoriteauthors_reread.setConfig( cfg_favoriteauthors );
964 w_favoriteauthors_reread.widget();
965 w_favoriteauthors_reread.setEnabled( true );
966
967 w_favoriteauthors_reread.setFeature( vl_text_reread->getFeature( 1 ) );
968
969 //check if first feature on new layer checked correctly 0, 2, 4(means the names "Douglas Adams", "John Vliessides", "Ralph Johnson") after the reread
970 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
971 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
972 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
973 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
974 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "John Vlissides" ) );
975 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
976 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "Ken Follett" ) );
977 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
978 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
979 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
980 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Richard Helm" ) );
981 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
982
983 //we store data wrongly (like it has possibly been on legacy systems)
984 vl_text_reread->changeAttributeValue( 1, 3, "{Douglas Adams,John Vlissides,Ralph Johnson}" );
985
986 // check if stored correctly
987 vl_text_reread->commitChanges();
988 expected_string = QStringLiteral( "{Douglas Adams,John Vlissides,Ralph Johnson}" );
989
990 f = vl_text_reread->getFeature( 1 );
991 attribute = f.attribute( QStringLiteral( "PRFEDEA" ) );
992 value = attribute.toString();
993 QCOMPARE( value, expected_string );
994
995 w_favoriteauthors.setFeature( vl_text_reread->getFeature( 1 ) );
996
997 //check if first feature checked correctly 0, 2, 4 (means the names "Douglas Adams", "John Vlissides", "Ralph Johnson") after the commit
998 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
999 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
1000 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
1001 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
1002 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "John Vlissides" ) );
1003 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
1004 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "Ken Follett" ) );
1005 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1006 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
1007 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
1008 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Richard Helm" ) );
1009 QCOMPARE( w_favoriteauthors_reread.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
1010
1011 //reread completely
1012 QgsVectorLayer *vl_text_reread2 = new QgsVectorLayer( myMapFileInfo.filePath() + "|layername=foo", "test", QStringLiteral( "ogr" ) );
1013 QVERIFY( vl_text_reread2->isValid() );
1014
1015 QgsProject::instance()->addMapLayer( vl_text_reread2, false, false );
1016 vl_text_reread2->startEditing();
1017
1018 // build a value relation widget wrapper for authors
1019 QgsValueRelationWidgetWrapper w_favoriteauthors_reread2( vl_text_reread2, vl_text_reread2->fields().indexOf( QLatin1String( "PRFEDEA" ) ), nullptr, nullptr );
1020 w_favoriteauthors_reread2.setConfig( cfg_favoriteauthors );
1021 w_favoriteauthors_reread2.widget();
1022 w_favoriteauthors_reread2.setEnabled( true );
1023
1024 w_favoriteauthors_reread2.setFeature( vl_text_reread2->getFeature( 1 ) );
1025
1026 //check if first feature on new layer checked correctly 0, 2, 4(means the names "Douglas Adams", "John Vliessides", "Ralph Johnson") after the reread
1027 QCOMPARE( w_favoriteauthors_reread2.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
1028 QCOMPARE( w_favoriteauthors_reread2.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
1029 QCOMPARE( w_favoriteauthors_reread2.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
1030 QCOMPARE( w_favoriteauthors_reread2.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
1031 QCOMPARE( w_favoriteauthors_reread2.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "John Vlissides" ) );
1032 QCOMPARE( w_favoriteauthors_reread2.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
1033 QCOMPARE( w_favoriteauthors_reread2.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "Ken Follett" ) );
1034 QCOMPARE( w_favoriteauthors_reread2.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1035 QCOMPARE( w_favoriteauthors_reread2.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
1036 QCOMPARE( w_favoriteauthors_reread2.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
1037 QCOMPARE( w_favoriteauthors_reread2.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Richard Helm" ) );
1038 QCOMPARE( w_favoriteauthors_reread2.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
1039 }
1040
1041 // Storing of strings as key and handle the quotes
testWithTextInGPKGWeirdTextFk()1042 void TestQgsValueRelationWidgetWrapper::testWithTextInGPKGWeirdTextFk()
1043 {
1044 // create ogr gpkg layer for foo (vl_text)
1045 const QString myFileName( TEST_DATA_DIR ); //defined in CmakeLists.txt
1046 const QString myTempDirName = tempDir.path();
1047 QString myTempFileName = myTempDirName + "/test_json.gpkg";
1048 QFile::copy( myFileName + "/provider/test_json.gpkg", myTempFileName );
1049 const QFileInfo myMapFileInfoFoo( myTempFileName );
1050 QgsVectorLayer *vl_text = new QgsVectorLayer( myMapFileInfoFoo.filePath() + "|layername=foo", "test", QStringLiteral( "ogr" ) );
1051 QVERIFY( vl_text->isValid() );
1052
1053 // create ogr spatialite layer for authors with weird signs (vl_authors)
1054 myTempFileName = myTempDirName + QStringLiteral( "/valuerelation_widget_wrapper_test.spatialite.sqlite" );
1055 QFile::copy( myFileName + QStringLiteral( "/valuerelation_widget_wrapper_test.spatialite.sqlite" ),
1056 myTempFileName );
1057 const QFileInfo myMapFileInfoAuthor( myTempFileName );
1058 QgsVectorLayer *vl_authors = new QgsVectorLayer( QStringLiteral( R"(dbname='%1' table="%2")" )
1059 .arg( myMapFileInfoAuthor.filePath() ).arg( QLatin1String( "authors" ) ),
1060 QStringLiteral( "test" ),
1061 QStringLiteral( "spatialite" ) );
1062 QVERIFY( vl_authors->isValid() );
1063
1064 QgsProject::instance()->addMapLayer( vl_text, false, false );
1065 QgsProject::instance()->addMapLayer( vl_authors, false, false );
1066 vl_text->startEditing();
1067
1068 // build a value relation widget wrapper for authors
1069 QgsValueRelationWidgetWrapper w_favoriteauthors( vl_text, vl_text->fields().indexOf( QLatin1String( "PRFEDEA" ) ), nullptr, nullptr );
1070 QVariantMap cfg_favoriteauthors;
1071 cfg_favoriteauthors.insert( QStringLiteral( "Layer" ), vl_authors->id() );
1072 cfg_favoriteauthors.insert( QStringLiteral( "Key" ), QStringLiteral( "pk_text" ) );
1073 cfg_favoriteauthors.insert( QStringLiteral( "Value" ), QStringLiteral( "name" ) );
1074 cfg_favoriteauthors.insert( QStringLiteral( "AllowMulti" ), true );
1075 cfg_favoriteauthors.insert( QStringLiteral( "NofColumns" ), 1 );
1076 cfg_favoriteauthors.insert( QStringLiteral( "AllowNull" ), false );
1077 cfg_favoriteauthors.insert( QStringLiteral( "OrderByValue" ), false );
1078 cfg_favoriteauthors.insert( QStringLiteral( "UseCompleter" ), false );
1079 w_favoriteauthors.setConfig( cfg_favoriteauthors );
1080 w_favoriteauthors.widget();
1081 w_favoriteauthors.setEnabled( true );
1082
1083 //check if set up nice
1084 QCOMPARE( w_favoriteauthors.mTableWidget->rowCount(), 7 );
1085 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
1086 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "1gamma" ) );
1087 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
1088 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "2helm,comma" ) );
1089 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
1090 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "3johnson\"quote" ) );
1091 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
1092 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "4vlissides" ) );
1093 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
1094 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "5adams'singlequote" ) );
1095 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
1096 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "6follett{}" ) );
1097 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->text(), QStringLiteral( "Gabriel Garc%1a M%2rquez" ).arg( QChar( 0x00ED ) ).arg( QChar( 0x00E1 ) ) );
1098 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "7garc%1a][" ).arg( QChar( 0x00EC ) ) );
1099
1100 w_favoriteauthors.setFeature( vl_text->getFeature( 1 ) );
1101
1102 //check if first feature checked correctly (none)
1103 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
1104 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
1105 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
1106 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
1107 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
1108 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
1109 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
1110 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1111 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
1112 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked );
1113 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
1114 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
1115 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->text(), QStringLiteral( "Gabriel Garc%1a M%2rquez" ).arg( QChar( 0x00ED ) ).arg( QChar( 0x00E1 ) ) );
1116 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
1117
1118 //check authors 1,2,4,5,6 means all the super weird ones: "2helm,comma", "3johnson\"quote", "5adams'singlequote", "6follett{}", "7garcìa]["
1119 w_favoriteauthors.mTableWidget->item( 1, 0 )->setCheckState( Qt::Checked );
1120 w_favoriteauthors.mTableWidget->item( 2, 0 )->setCheckState( Qt::Checked );
1121 w_favoriteauthors.mTableWidget->item( 4, 0 )->setCheckState( Qt::Checked );
1122 w_favoriteauthors.mTableWidget->item( 5, 0 )->setCheckState( Qt::Checked );
1123 w_favoriteauthors.mTableWidget->item( 6, 0 )->setCheckState( Qt::Checked );
1124
1125 //check if first feature checked correctly 1,2,4,5,6
1126 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
1127 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
1128 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
1129 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Checked );
1130 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
1131 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
1132 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
1133 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1134 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
1135 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
1136 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
1137 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Checked );
1138 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->text(), QStringLiteral( "Gabriel Garc%1a M%2rquez" ).arg( QChar( 0x00ED ) ).arg( QChar( 0x00E1 ) ) );
1139 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Checked );
1140
1141 //we do jump over the part with QgsAttributeForm::saveEdits
1142 vl_text->changeAttributeValue( 1, 3, w_favoriteauthors.value() );
1143
1144 //check if everything set correctly
1145 QCOMPARE( w_favoriteauthors.value(), QVariant( QStringLiteral( "{\"2helm,comma\",\"3johnson\\\"quote\",\"5adams'singlequote\",\"6follett{}\",\"7garc%1a][\"}" ).arg( QChar( 0x00EC ) ) ) );
1146
1147 w_favoriteauthors.setFeature( vl_text->getFeature( 2 ) );
1148 //check if second feature checked correctly (none)
1149 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
1150 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
1151 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
1152 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
1153 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
1154 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
1155 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
1156 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1157 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
1158 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked );
1159 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
1160 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
1161 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->text(), QStringLiteral( "Gabriel Garc%1a M%2rquez" ).arg( QChar( 0x00ED ) ).arg( QChar( 0x00E1 ) ) );
1162 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
1163
1164 w_favoriteauthors.setFeature( vl_text->getFeature( 1 ) );
1165 //check if first feature checked correctly 1,2,4,5,6
1166 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
1167 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
1168 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
1169 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Checked );
1170 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
1171 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
1172 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
1173 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1174 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
1175 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
1176 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
1177 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Checked );
1178 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->text(), QStringLiteral( "Gabriel Garc%1a M%2rquez" ).arg( QChar( 0x00ED ) ).arg( QChar( 0x00E1 ) ) );
1179 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Checked );
1180
1181 // check if stored correctly
1182 vl_text->commitChanges();
1183 const QString expected_string = QStringLiteral( "{\"2helm,comma\",\"3johnson\\\"quote\",\"5adams'singlequote\",\"6follett{}\",\"7garc%1a][\"}" ).arg( QChar( 0x00EC ) );
1184
1185 const QgsFeature f = vl_text->getFeature( 1 );
1186 const QVariant attribute = f.attribute( QStringLiteral( "PRFEDEA" ) );
1187 const QString value = attribute.toString();
1188 QCOMPARE( value, expected_string );
1189
1190 //reread completely
1191 QgsVectorLayer *vl_text_reread = new QgsVectorLayer( myMapFileInfoFoo.filePath() + "|layername=foo", "test", QStringLiteral( "ogr" ) );
1192 QVERIFY( vl_text_reread->isValid() );
1193
1194 QgsProject::instance()->addMapLayer( vl_text_reread, false, false );
1195 vl_text_reread->startEditing();
1196
1197 // build a value relation widget wrapper for authors
1198 QgsValueRelationWidgetWrapper w_favoriteauthors_reread( vl_text_reread, vl_text_reread->fields().indexOf( QLatin1String( "PRFEDEA" ) ), nullptr, nullptr );
1199 w_favoriteauthors_reread.setConfig( cfg_favoriteauthors );
1200 w_favoriteauthors_reread.widget();
1201 w_favoriteauthors_reread.setEnabled( true );
1202
1203 w_favoriteauthors_reread.setFeature( vl_text_reread->getFeature( 1 ) );
1204
1205 //check if first feature on new layer checked correctly 1,2,4,5,6 after reread
1206 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
1207 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
1208 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
1209 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Checked );
1210 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
1211 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
1212 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
1213 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1214 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
1215 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
1216 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
1217 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Checked );
1218 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->text(), QStringLiteral( "Gabriel Garc%1a M%2rquez" ).arg( QChar( 0x00ED ) ).arg( QChar( 0x00E1 ) ) );
1219 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Checked );
1220 }
1221
testWithJsonInSpatialite()1222 void TestQgsValueRelationWidgetWrapper::testWithJsonInSpatialite()
1223 {
1224 const auto fk_field { QStringLiteral( "json_content" ) };
1225 // create ogr gpkg layers
1226 const QString myFileName( TEST_DATA_DIR ); //defined in CmakeLists.txt
1227 const QString myTempDirName = tempDir.path();
1228 const QString myTempFileName = myTempDirName + QStringLiteral( "/valuerelation_widget_wrapper_test.spatialite.sqlite" );
1229 QFile::copy( myFileName + QStringLiteral( "/valuerelation_widget_wrapper_test.spatialite.sqlite" ),
1230 myTempFileName );
1231 const QFileInfo myMapFileInfo( myTempFileName );
1232 QgsVectorLayer *vl_json = new QgsVectorLayer( QStringLiteral( R"(dbname='%1' table="%2")" )
1233 .arg( myMapFileInfo.filePath() ).arg( QLatin1String( "json" ) ),
1234 QStringLiteral( "test" ),
1235 QStringLiteral( "spatialite" ) );
1236 QgsVectorLayer *vl_authors = new QgsVectorLayer( QStringLiteral( R"(dbname='%1' table="%2")" )
1237 .arg( myMapFileInfo.filePath() ).arg( QLatin1String( "authors" ) ),
1238 QStringLiteral( "test" ),
1239 QStringLiteral( "spatialite" ) );
1240 const auto fk_field_idx { vl_json->fields().indexOf( fk_field ) };
1241
1242 QVERIFY( vl_json->isValid() );
1243 QVERIFY( vl_authors->isValid() );
1244
1245 QgsProject::instance()->addMapLayer( vl_json, false, false );
1246 QgsProject::instance()->addMapLayer( vl_authors, false, false );
1247 vl_json->startEditing();
1248
1249 // build a value relation widget wrapper for authors
1250 // fk_field is a json array type
1251 QgsValueRelationWidgetWrapper w_favoriteauthors( vl_json, fk_field_idx, nullptr, nullptr );
1252 QVariantMap cfg_favoriteauthors;
1253 cfg_favoriteauthors.insert( QStringLiteral( "Layer" ), vl_authors->id() );
1254 cfg_favoriteauthors.insert( QStringLiteral( "Key" ), QStringLiteral( "pk" ) );
1255 cfg_favoriteauthors.insert( QStringLiteral( "Value" ), QStringLiteral( "name" ) );
1256 cfg_favoriteauthors.insert( QStringLiteral( "AllowMulti" ), true );
1257 cfg_favoriteauthors.insert( QStringLiteral( "NofColumns" ), 1 );
1258 cfg_favoriteauthors.insert( QStringLiteral( "AllowNull" ), false );
1259 cfg_favoriteauthors.insert( QStringLiteral( "OrderByValue" ), false );
1260 cfg_favoriteauthors.insert( QStringLiteral( "UseCompleter" ), false );
1261 w_favoriteauthors.setConfig( cfg_favoriteauthors );
1262 w_favoriteauthors.widget();
1263 w_favoriteauthors.setEnabled( true );
1264
1265 //check if set up nice
1266 QCOMPARE( w_favoriteauthors.mTableWidget->rowCount(), 7 );
1267 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
1268 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "1" ) );
1269 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
1270 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "2" ) );
1271 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
1272 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "3" ) );
1273 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
1274 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "4" ) );
1275 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
1276 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "5" ) );
1277 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
1278 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "6" ) );
1279 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->text(), QStringLiteral( "Gabriel Garc%1a M%2rquez" ).arg( QChar( 0x00ED ) ).arg( QChar( 0x00E1 ) ) );
1280 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->checkState(), Qt::Unchecked );
1281
1282 /* Test data:
1283 pk: 1 [1,3]
1284 pk: 2 [2,5]
1285 pk: 3 [4,6,7]
1286 pk: 4 NULL
1287 pk: 5 blank
1288 */
1289
1290 // FEATURE 1
1291 w_favoriteauthors.setFeature( vl_json->getFeature( 1 ) );
1292 QCOMPARE( w_favoriteauthors.value(), QVariant( QVariantList( { 1, 3 } ) ) );
1293 //check if first feature checked correctly (1,3) pk
1294 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked ); // 1
1295 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked ); // 2
1296 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked ); // 3
1297 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked ); // 4
1298 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked ); // 5
1299 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked ); // 6
1300 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->checkState(), Qt::Unchecked ); // 7
1301
1302 //check other authors
1303 w_favoriteauthors.mTableWidget->item( 1, 0 )->setCheckState( Qt::Checked );
1304 w_favoriteauthors.mTableWidget->item( 4, 0 )->setCheckState( Qt::Checked );
1305
1306 //check if first feature checked correctly (1,2,3,5)
1307 QCOMPARE( w_favoriteauthors.value(), QVariant( QVariantList( {1, 2, 3, 5} ) ) );
1308 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
1309 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Checked );
1310 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
1311 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1312 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
1313 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
1314 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->checkState(), Qt::Unchecked );
1315
1316 vl_json->changeAttributeValue( 1, fk_field_idx, w_favoriteauthors.value() );
1317 // check if stored correctly
1318 vl_json->commitChanges();
1319 QVariantList expected_vl;
1320 expected_vl << "1" << "2" << "3" << "5";
1321 const QgsFeature f = vl_json->getFeature( 1 );
1322 const QVariant attribute = f.attribute( fk_field );
1323 const QList<QVariant> value = attribute.toList();
1324 QCOMPARE( value, expected_vl );
1325
1326 // FEATURE 2
1327 w_favoriteauthors.setFeature( vl_json->getFeature( 2 ) );
1328 QCOMPARE( w_favoriteauthors.value(), QVariant( QVariantList( {2, 5} ) ) );
1329 //check if second feature checked correctly
1330 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
1331 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Checked );
1332 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
1333 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1334 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
1335 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
1336 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->checkState(), Qt::Unchecked );
1337
1338 // FEATURE 4
1339 w_favoriteauthors.setFeature( vl_json->getFeature( 4 ) );
1340 // Because allowNull is false we have a NULL variant here
1341 QCOMPARE( w_favoriteauthors.value(), QVariant( QVariant::Type::List ) );
1342 cfg_favoriteauthors[ QStringLiteral( "AllowNull" ) ] = true;
1343 w_favoriteauthors.setConfig( cfg_favoriteauthors );
1344 //check if first feature checked correctly (empty list)
1345 QCOMPARE( w_favoriteauthors.value(), QVariant( QVariantList() ) );
1346 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
1347 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
1348 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
1349 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1350 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked );
1351 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
1352 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->checkState(), Qt::Unchecked );
1353 cfg_favoriteauthors[ QStringLiteral( "AllowNull" ) ] = false;
1354 w_favoriteauthors.setConfig( cfg_favoriteauthors );
1355
1356 // FEATURE 5
1357 w_favoriteauthors.setFeature( vl_json->getFeature( 5 ) );
1358 // Because allowNull is false we have a NULL variant here
1359 QCOMPARE( w_favoriteauthors.value(), QVariant( QVariant::Type::List ) );
1360
1361 cfg_favoriteauthors[ QStringLiteral( "AllowNull" ) ] = true;
1362 w_favoriteauthors.setConfig( cfg_favoriteauthors );
1363 //check if first feature checked correctly (empty list)
1364 QCOMPARE( w_favoriteauthors.value(), QVariant( QVariantList( ) ) );
1365 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
1366 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
1367 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
1368 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1369 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked );
1370 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
1371 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->checkState(), Qt::Unchecked );
1372 }
1373
1374
testWithJsonInSpatialiteTextFk()1375 void TestQgsValueRelationWidgetWrapper::testWithJsonInSpatialiteTextFk()
1376 {
1377 const auto fk_field { QStringLiteral( "json_content_text" ) };
1378 // create ogr gpkg layers
1379 const QString myFileName( TEST_DATA_DIR ); //defined in CmakeLists.txt
1380 const QString myTempDirName = tempDir.path();
1381 const QString myTempFileName = myTempDirName + QStringLiteral( "/valuerelation_widget_wrapper_test.spatialite.sqlite" );
1382 QFile::copy( myFileName + QStringLiteral( "/valuerelation_widget_wrapper_test.spatialite.sqlite" ),
1383 myTempFileName );
1384 const QFileInfo myMapFileInfo( myTempFileName );
1385 QgsVectorLayer *vl_json = new QgsVectorLayer( QStringLiteral( R"(dbname='%1' table="%2")" )
1386 .arg( myMapFileInfo.filePath() ).arg( QLatin1String( "json" ) ),
1387 QStringLiteral( "test" ),
1388 QStringLiteral( "spatialite" ) );
1389 QgsVectorLayer *vl_authors = new QgsVectorLayer( QStringLiteral( R"(dbname='%1' table="%2")" )
1390 .arg( myMapFileInfo.filePath() ).arg( QLatin1String( "authors" ) ),
1391 QStringLiteral( "test" ),
1392 QStringLiteral( "spatialite" ) );
1393 const auto fk_field_idx { vl_json->fields().indexOf( fk_field ) };
1394
1395 QVERIFY( vl_json->isValid() );
1396 QVERIFY( vl_authors->isValid() );
1397
1398 QgsProject::instance()->addMapLayer( vl_json, false, false );
1399 QgsProject::instance()->addMapLayer( vl_authors, false, false );
1400 vl_json->startEditing();
1401
1402 // build a value relation widget wrapper for authors
1403 // fk_field is a json array type
1404 QgsValueRelationWidgetWrapper w_favoriteauthors( vl_json, fk_field_idx, nullptr, nullptr );
1405 QVariantMap cfg_favoriteauthors;
1406 cfg_favoriteauthors.insert( QStringLiteral( "Layer" ), vl_authors->id() );
1407 cfg_favoriteauthors.insert( QStringLiteral( "Key" ), QStringLiteral( "pk_text" ) );
1408 cfg_favoriteauthors.insert( QStringLiteral( "Value" ), QStringLiteral( "name" ) );
1409 cfg_favoriteauthors.insert( QStringLiteral( "AllowMulti" ), true );
1410 cfg_favoriteauthors.insert( QStringLiteral( "NofColumns" ), 1 );
1411 cfg_favoriteauthors.insert( QStringLiteral( "AllowNull" ), false );
1412 cfg_favoriteauthors.insert( QStringLiteral( "OrderByValue" ), false );
1413 cfg_favoriteauthors.insert( QStringLiteral( "UseCompleter" ), false );
1414 w_favoriteauthors.setConfig( cfg_favoriteauthors );
1415 w_favoriteauthors.widget();
1416 w_favoriteauthors.setEnabled( true );
1417
1418 //check if set up nice
1419 QCOMPARE( w_favoriteauthors.mTableWidget->rowCount(), 7 );
1420 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->text(), QStringLiteral( "Erich Gamma" ) );
1421 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "1gamma" ) );
1422 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->text(), QStringLiteral( "Richard Helm" ) );
1423 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "2helm,comma" ) );
1424 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->text(), QStringLiteral( "Ralph Johnson" ) );
1425 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "3johnson\"quote" ) );
1426 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->text(), QStringLiteral( "John Vlissides" ) );
1427 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "4vlissides" ) );
1428 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->text(), QStringLiteral( "Douglas Adams" ) );
1429 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "5adams'singlequote" ) );
1430 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->text(), QStringLiteral( "Ken Follett" ) );
1431 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "6follett{}" ) );
1432 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->text(), QStringLiteral( "Gabriel Garc%1a M%2rquez" ).arg( QChar( 0x00ED ) ).arg( QChar( 0x00E1 ) ) );
1433 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->data( Qt::UserRole ).toString(), QStringLiteral( "7garc%1a][" ).arg( QChar( 0x00EC ) ) );
1434 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->checkState(), Qt::Unchecked );
1435
1436 /* Test data:
1437
1438 Keys:
1439 "1gamma"
1440 "2helm,comma"
1441 "3johnson""quote"
1442 "4vlissides"
1443 "5adams'singlequote"
1444 "6follett{}"
1445 "7garcìa]["
1446
1447 Data:
1448 1 "[1,3]" "[""1gamma"", ""3johnson\""quote""]
1449 2 "[2,5]" "[""2helm,comma"", ""5adams'singlequote""]"
1450 3 "[4,6,7]" "[""4vlissides"", ""6follett{}"" , ""7garca][""]"
1451 5
1452 7 "" ""
1453
1454 */
1455
1456 // FEATURE 1
1457 w_favoriteauthors.setFeature( vl_json->getFeature( 1 ) );
1458 QCOMPARE( w_favoriteauthors.value(), QVariant( QVariantList( { "1gamma", "3johnson\"quote" } ) ) );
1459
1460 //check if first feature checked correctly (1,3) pk
1461 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked ); // 1
1462 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked ); // 2
1463 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked ); // 3
1464 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked ); // 4
1465 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked ); // 5
1466 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked ); // 6
1467 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->checkState(), Qt::Unchecked ); // 7
1468
1469 //check other authors
1470 w_favoriteauthors.mTableWidget->item( 1, 0 )->setCheckState( Qt::Checked );
1471 w_favoriteauthors.mTableWidget->item( 4, 0 )->setCheckState( Qt::Checked );
1472
1473 //check if first feature checked correctly (1,2,3,5) ) );
1474 QCOMPARE( w_favoriteauthors.value(), QVariant( QVariantList( { "1gamma", "2helm,comma", "3johnson\"quote", "5adams'singlequote" } ) ) );
1475
1476 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Checked );
1477 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Checked );
1478 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Checked );
1479 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1480 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
1481 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
1482 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->checkState(), Qt::Unchecked );
1483
1484 vl_json->changeAttributeValue( 1, fk_field_idx, w_favoriteauthors.value() );
1485 // check if stored correctly
1486 vl_json->commitChanges();
1487 const QgsFeature f = vl_json->getFeature( 1 );
1488 const QVariant attribute = f.attribute( fk_field );
1489 const QVariantList value = attribute.toList();
1490
1491 QCOMPARE( value, QVariantList( { "1gamma", "2helm,comma", "3johnson\"quote", "5adams'singlequote" } ) );
1492
1493 // FEATURE 2
1494 w_favoriteauthors.setFeature( vl_json->getFeature( 2 ) );
1495 QCOMPARE( w_favoriteauthors.value(), QVariant( QVariantList( { "2helm,comma", "5adams'singlequote" } ) ) );
1496
1497 //check if second feature checked correctly
1498 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
1499 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Checked );
1500 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
1501 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1502 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Checked );
1503 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
1504 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->checkState(), Qt::Unchecked );
1505
1506 // FEATURE 4
1507 w_favoriteauthors.setFeature( vl_json->getFeature( 4 ) );
1508
1509 // Because allowNull is false we have a NULL variant here
1510 QCOMPARE( w_favoriteauthors.value(), QVariant( QVariant::Type::List ) );
1511 cfg_favoriteauthors[ QStringLiteral( "AllowNull" ) ] = true;
1512 w_favoriteauthors.setConfig( cfg_favoriteauthors );
1513
1514 //check if first feature checked correctly (NULL)
1515 QCOMPARE( w_favoriteauthors.value(), QVariant( QVariantList( ) ) );
1516
1517 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
1518 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
1519 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
1520 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1521 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked );
1522 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
1523 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->checkState(), Qt::Unchecked );
1524 cfg_favoriteauthors[ QStringLiteral( "AllowNull" ) ] = false;
1525 w_favoriteauthors.setConfig( cfg_favoriteauthors );
1526
1527 // FEATURE 5
1528 w_favoriteauthors.setFeature( vl_json->getFeature( 5 ) );
1529
1530 // Because allowNull is false we have a NULL variant here
1531 QCOMPARE( w_favoriteauthors.value(), QVariant( QVariant::Type::List ) );
1532 cfg_favoriteauthors[ QStringLiteral( "AllowNull" ) ] = true;
1533 w_favoriteauthors.setConfig( cfg_favoriteauthors );
1534
1535 //check if first feature checked correctly (empty list)
1536 QCOMPARE( w_favoriteauthors.value(), QVariant( QVariantList() ) );
1537
1538 QCOMPARE( w_favoriteauthors.mTableWidget->item( 0, 0 )->checkState(), Qt::Unchecked );
1539 QCOMPARE( w_favoriteauthors.mTableWidget->item( 1, 0 )->checkState(), Qt::Unchecked );
1540 QCOMPARE( w_favoriteauthors.mTableWidget->item( 2, 0 )->checkState(), Qt::Unchecked );
1541 QCOMPARE( w_favoriteauthors.mTableWidget->item( 3, 0 )->checkState(), Qt::Unchecked );
1542 QCOMPARE( w_favoriteauthors.mTableWidget->item( 4, 0 )->checkState(), Qt::Unchecked );
1543 QCOMPARE( w_favoriteauthors.mTableWidget->item( 5, 0 )->checkState(), Qt::Unchecked );
1544 QCOMPARE( w_favoriteauthors.mTableWidget->item( 6, 0 )->checkState(), Qt::Unchecked );
1545 }
1546
testMatchLayerName()1547 void TestQgsValueRelationWidgetWrapper::testMatchLayerName()
1548 {
1549 // create a vector layer
1550 QgsVectorLayer vl1( QStringLiteral( "Polygon?crs=epsg:4326&field=pk:int&field=province:int&field=municipality:string" ), QStringLiteral( "vl1" ), QStringLiteral( "memory" ) );
1551 QgsVectorLayer vl2( QStringLiteral( "Point?crs=epsg:4326&field=pk:int&field=fk_province:int&field=fk_municipality:int" ), QStringLiteral( "vl2" ), QStringLiteral( "memory" ) );
1552 QgsProject::instance()->addMapLayer( &vl1, false, false );
1553 QgsProject::instance()->addMapLayer( &vl2, false, false );
1554
1555 // insert some features
1556 QgsFeature f1( vl1.fields() );
1557 f1.setAttribute( QStringLiteral( "pk" ), 0 ); // !!! Notice: pk 0
1558 f1.setAttribute( QStringLiteral( "province" ), 123 );
1559 f1.setAttribute( QStringLiteral( "municipality" ), QStringLiteral( "Some Place By The River" ) );
1560 f1.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POLYGON(( 0 0, 0 1, 1 1, 1 0, 0 0 ))" ) ) );
1561 QVERIFY( f1.isValid() );
1562 QgsFeature f2( vl1.fields() );
1563 f2.setAttribute( QStringLiteral( "pk" ), 2 );
1564 f2.setAttribute( QStringLiteral( "province" ), 245 );
1565 f2.setAttribute( QStringLiteral( "municipality" ), QStringLiteral( "Dreamland By The Clouds" ) );
1566 f2.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POLYGON(( 1 0, 1 1, 2 1, 2 0, 1 0 ))" ) ) );
1567 QVERIFY( f2.isValid() );
1568 QVERIFY( vl1.dataProvider()->addFeatures( QgsFeatureList() << f1 << f2 ) );
1569
1570 QgsFeature f3( vl2.fields() );
1571 f3.setAttribute( QStringLiteral( "fk_province" ), 123 );
1572 f3.setAttribute( QStringLiteral( "fk_municipality" ), QStringLiteral( "0" ) );
1573 f3.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POINT( 0.5 0.5)" ) ) );
1574 QVERIFY( f3.isValid() );
1575 QVERIFY( f3.geometry().isGeosValid() );
1576 QVERIFY( vl2.dataProvider()->addFeature( f3 ) );
1577
1578 // build a value relation widget wrapper for municipality
1579 QgsValueRelationWidgetWrapper w_municipality( &vl2, vl2.fields().indexOf( QLatin1String( "fk_municipality" ) ), nullptr, nullptr );
1580 QVariantMap cfg_municipality;
1581 cfg_municipality.insert( QStringLiteral( "Layer" ), QStringLiteral( "wrong_id_here_hope_name_is_good" ) );
1582 cfg_municipality.insert( QStringLiteral( "LayerName" ), vl1.name() );
1583 cfg_municipality.insert( QStringLiteral( "Key" ), QStringLiteral( "pk" ) );
1584 cfg_municipality.insert( QStringLiteral( "Value" ), QStringLiteral( "municipality" ) );
1585 cfg_municipality.insert( QStringLiteral( "AllowMulti" ), false );
1586 cfg_municipality.insert( QStringLiteral( "NofColumns" ), 1 );
1587 cfg_municipality.insert( QStringLiteral( "AllowNull" ), true );
1588 cfg_municipality.insert( QStringLiteral( "OrderByValue" ), false );
1589 cfg_municipality.insert( QStringLiteral( "UseCompleter" ), false );
1590 w_municipality.setConfig( cfg_municipality );
1591 w_municipality.widget();
1592 w_municipality.setEnabled( true );
1593
1594 w_municipality.setValues( 0, QVariantList() );
1595 QCOMPARE( w_municipality.mComboBox->currentIndex(), 1 );
1596 QCOMPARE( w_municipality.mComboBox->currentText(), QStringLiteral( "Some Place By The River" ) );
1597 }
1598
testRegressionGH42003()1599 void TestQgsValueRelationWidgetWrapper::testRegressionGH42003()
1600 {
1601 // create a vector layer
1602 QgsVectorLayer vl1( QStringLiteral( "Polygon?crs=epsg:4326&field=pk:int&field=province:int&field=municipality:string" ), QStringLiteral( "vl1" ), QStringLiteral( "memory" ) );
1603 QgsVectorLayer vl2( QStringLiteral( "Point?crs=epsg:4326&field=pk:int&field=fk_province:int&field=fk_municipality:int" ), QStringLiteral( "vl2" ), QStringLiteral( "memory" ) );
1604 QgsProject::instance()->addMapLayer( &vl1, false, false );
1605 QgsProject::instance()->addMapLayer( &vl2, false, false );
1606
1607 // insert some features
1608 QgsFeature f1( vl1.fields() );
1609 f1.setAttribute( QStringLiteral( "pk" ), 1 );
1610 f1.setAttribute( QStringLiteral( "province" ), 123 );
1611 f1.setAttribute( QStringLiteral( "municipality" ), QStringLiteral( "Some Place By The River" ) );
1612 f1.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POLYGON(( 0 0, 0 1, 1 1, 1 0, 0 0 ))" ) ) );
1613 QVERIFY( f1.isValid() );
1614 QgsFeature f2( vl1.fields() );
1615 f2.setAttribute( QStringLiteral( "pk" ), 2 );
1616 f2.setAttribute( QStringLiteral( "province" ), 245 );
1617 f2.setAttribute( QStringLiteral( "municipality" ), QStringLiteral( "Dreamland By The Clouds" ) );
1618 f2.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POLYGON(( 1 0, 1 1, 2 1, 2 0, 1 0 ))" ) ) );
1619 QVERIFY( f2.isValid() );
1620 QVERIFY( vl1.dataProvider()->addFeatures( QgsFeatureList() << f1 << f2 ) );
1621
1622 QgsFeature f3( vl2.fields() );
1623 f3.setAttribute( QStringLiteral( "fk_province" ), 123 );
1624 f3.setAttribute( QStringLiteral( "fk_municipality" ), 1 );
1625 f3.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POINT( 0.5 0.5)" ) ) );
1626 QVERIFY( f3.isValid() );
1627 QVERIFY( f3.geometry().isGeosValid() );
1628 QVERIFY( vl2.dataProvider()->addFeature( f3 ) );
1629
1630 // build a value relation widget wrapper for municipality
1631 QgsValueRelationWidgetWrapper w_municipality( &vl2, vl2.fields().indexOf( QLatin1String( "fk_municipality" ) ), nullptr, nullptr );
1632 QVariantMap cfg_municipality;
1633 cfg_municipality.insert( QStringLiteral( "Layer" ), vl1.id() );
1634 cfg_municipality.insert( QStringLiteral( "Key" ), QStringLiteral( "pk" ) );
1635 cfg_municipality.insert( QStringLiteral( "Value" ), QStringLiteral( "municipality" ) );
1636 cfg_municipality.insert( QStringLiteral( "AllowMulti" ), false );
1637 cfg_municipality.insert( QStringLiteral( "NofColumns" ), 1 );
1638 cfg_municipality.insert( QStringLiteral( "AllowNull" ), false );
1639 cfg_municipality.insert( QStringLiteral( "OrderByValue" ), true );
1640 cfg_municipality.insert( QStringLiteral( "UseCompleter" ), false );
1641 w_municipality.setConfig( cfg_municipality );
1642 w_municipality.widget();
1643 w_municipality.setEnabled( true );
1644
1645 w_municipality.setFeature( QgsFeature( vl2.fields() ) );
1646 QCoreApplication::processEvents();
1647
1648 // Check first is selected (fid 2 because of OrderByValue)
1649 QCOMPARE( w_municipality.mComboBox->currentIndex(), 0 );
1650 QCOMPARE( w_municipality.mComboBox->count(), 2 );
1651 QCOMPARE( w_municipality.mComboBox->itemText( 0 ), QStringLiteral( "Dreamland By The Clouds" ) );
1652 QCOMPARE( w_municipality.value().toString(), QStringLiteral( "2" ) );
1653
1654 // Simulate what happens in the attribute form initialization
1655 w_municipality.setFeature( QgsFeature( vl2.fields() ) );
1656 w_municipality.setFeature( vl2.getFeature( 1 ) );
1657 QCoreApplication::processEvents();
1658
1659 // Check fid 1 is selected
1660 QCOMPARE( w_municipality.mComboBox->currentIndex(), 1 );
1661 QCOMPARE( w_municipality.mComboBox->currentText(), QStringLiteral( "Some Place By The River" ) );
1662 QCOMPARE( w_municipality.value().toString(), QStringLiteral( "1" ) );
1663
1664 }
1665
1666 QGSTEST_MAIN( TestQgsValueRelationWidgetWrapper )
1667 #include "testqgsvaluerelationwidgetwrapper.moc"
1668