|
| 1 | +/*************************************************************************** |
| 2 | + testqgsrelationreferencewidget.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 | +#include <QtTest/QtTest> |
| 17 | +#include <editorwidgets/core/qgseditorwidgetregistry.h> |
| 18 | +#include <qgsapplication.h> |
| 19 | +#include "qgseditorwidgetwrapper.h" |
| 20 | +#include <qgsmaplayerregistry.h> |
| 21 | +#include <editorwidgets/qgsrelationreferencewidget.h> |
| 22 | +#include <qgsproject.h> |
| 23 | +#include <qgsattributeform.h> |
| 24 | +#include <qgsrelationmanager.h> |
| 25 | +#include <attributetable/qgsattributetablefiltermodel.h> |
| 26 | + |
| 27 | +class TestQgsRelationReferenceWidget : public QObject |
| 28 | +{ |
| 29 | + Q_OBJECT |
| 30 | + public: |
| 31 | + TestQgsRelationReferenceWidget() {} |
| 32 | + |
| 33 | + private slots: |
| 34 | + void initTestCase(); // will be called before the first testfunction is executed. |
| 35 | + void cleanupTestCase(); // will be called after the last testfunction was executed. |
| 36 | + void init(); // will be called before each testfunction is executed. |
| 37 | + void cleanup(); // will be called after every testfunction. |
| 38 | + |
| 39 | + void testChainFilter(); |
| 40 | +}; |
| 41 | + |
| 42 | +void TestQgsRelationReferenceWidget::initTestCase() |
| 43 | +{ |
| 44 | + QgsApplication::init(); |
| 45 | + QgsApplication::initQgis(); |
| 46 | + QgsEditorWidgetRegistry::initEditors(); |
| 47 | +} |
| 48 | + |
| 49 | +void TestQgsRelationReferenceWidget::cleanupTestCase() |
| 50 | +{ |
| 51 | + QgsApplication::exitQgis(); |
| 52 | +} |
| 53 | + |
| 54 | +void TestQgsRelationReferenceWidget::init() |
| 55 | +{ |
| 56 | +} |
| 57 | + |
| 58 | +void TestQgsRelationReferenceWidget::cleanup() |
| 59 | +{ |
| 60 | +} |
| 61 | + |
| 62 | +void TestQgsRelationReferenceWidget::testChainFilter() |
| 63 | +{ |
| 64 | + // create layers |
| 65 | + QgsVectorLayer vl1( QString( "LineString?crs=epsg:3111&field=pk:int&field=fk:int" ), QString( "vl1" ), QString( "memory" ) ); |
| 66 | + QgsMapLayerRegistry::instance()->addMapLayer( &vl1 ); |
| 67 | + QgsVectorLayer vl2( QString( "LineString?field=pk:int&field=material:string&field=diameter:int&field=raccord:string" ), QString( "vl2" ), QString( "memory" ) ); |
| 68 | + QgsMapLayerRegistry::instance()->addMapLayer( &vl2 ); |
| 69 | + |
| 70 | + // create a relation between them |
| 71 | + QgsRelation relation; |
| 72 | + relation.setRelationId( QString( "vl1.vl2" ) ); |
| 73 | + relation.setRelationName( QString( "vl1.vl2" ) ); |
| 74 | + relation.setReferencingLayer( vl1.id() ); |
| 75 | + relation.setReferencedLayer( vl2.id() ); |
| 76 | + relation.addFieldPair( "fk", "pk" ); |
| 77 | + QVERIFY( relation.isValid() ); |
| 78 | + QgsProject::instance()->relationManager()->addRelation( relation ); |
| 79 | + |
| 80 | + // add features |
| 81 | + QgsFeature ft0( vl1.fields() ); |
| 82 | + ft0.setAttribute( QString( "pk" ), 0 ); |
| 83 | + ft0.setAttribute( QString( "fk" ), 0 ); |
| 84 | + vl1.startEditing(); |
| 85 | + vl1.addFeature( ft0 ); |
| 86 | + vl1.commitChanges(); |
| 87 | + |
| 88 | + QgsFeature ft1( vl1.fields() ); |
| 89 | + ft1.setAttribute( QString( "pk" ), 1 ); |
| 90 | + ft1.setAttribute( QString( "fk" ), 1 ); |
| 91 | + vl1.startEditing(); |
| 92 | + vl1.addFeature( ft1 ); |
| 93 | + vl1.commitChanges(); |
| 94 | + |
| 95 | + QgsFeature ft2( vl2.fields() ); |
| 96 | + ft2.setAttribute( QString( "pk" ), 10 ); |
| 97 | + ft2.setAttribute( QString( "material" ), "iron" ); |
| 98 | + ft2.setAttribute( QString( "diameter" ), 120 ); |
| 99 | + ft2.setAttribute( QString( "raccord" ), "brides" ); |
| 100 | + vl2.startEditing(); |
| 101 | + vl2.addFeature( ft2 ); |
| 102 | + vl2.commitChanges(); |
| 103 | + |
| 104 | + QgsFeature ft3( vl2.fields() ); |
| 105 | + ft3.setAttribute( QString( "pk" ), 11 ); |
| 106 | + ft3.setAttribute( QString( "material" ), "iron" ); |
| 107 | + ft3.setAttribute( QString( "diameter" ), 120 ); |
| 108 | + ft3.setAttribute( QString( "raccord" ), "sleeve" ); |
| 109 | + vl2.startEditing(); |
| 110 | + vl2.addFeature( ft3 ); |
| 111 | + vl2.commitChanges(); |
| 112 | + |
| 113 | + QgsFeature ft4( vl2.fields() ); |
| 114 | + ft4.setAttribute( QString( "pk" ), 12 ); |
| 115 | + ft4.setAttribute( QString( "material" ), "steel" ); |
| 116 | + ft4.setAttribute( QString( "diameter" ), 120 ); |
| 117 | + ft4.setAttribute( QString( "raccord" ), "collar" ); |
| 118 | + vl2.startEditing(); |
| 119 | + vl2.addFeature( ft4 ); |
| 120 | + vl2.commitChanges(); |
| 121 | + |
| 122 | + // init a relation reference widget |
| 123 | + QStringList filterFields = { "material", "diameter", "raccord" }; |
| 124 | + |
| 125 | + QgsRelationReferenceWidget w( new QWidget() ); |
| 126 | + w.setChainFilters( true ); |
| 127 | + w.setFilterFields( filterFields ); |
| 128 | + w.setRelation( relation, true ); |
| 129 | + w.init(); |
| 130 | + |
| 131 | + // check default status for comboboxes |
| 132 | + QList<QComboBox *> cbs = w.mFilterComboBoxes; |
| 133 | + QCOMPARE( cbs.count(), 3 ); |
| 134 | + Q_FOREACH ( const QComboBox *cb, cbs ) |
| 135 | + { |
| 136 | + if ( cb->currentText() == "raccord" ) |
| 137 | + QCOMPARE( cb->count(), 5 ); |
| 138 | + else if ( cb->currentText() == "material" ) |
| 139 | + QCOMPARE( cb->count(), 4 ); |
| 140 | + else if ( cb->currentText() == "diameter" ) |
| 141 | + QCOMPARE( cb->count(), 3 ); |
| 142 | + } |
| 143 | + |
| 144 | + // set first filter |
| 145 | + cbs[0]->setCurrentIndex( cbs[0]->findText( "iron" ) ); |
| 146 | + cbs[1]->setCurrentIndex( cbs[1]->findText( "120" ) ); |
| 147 | + |
| 148 | + Q_FOREACH ( const QComboBox *cb, cbs ) |
| 149 | + { |
| 150 | + if ( cb->itemText( 0 ) == "material" ) |
| 151 | + QCOMPARE( cb->count(), 4 ); |
| 152 | + else if ( cb->itemText( 0 ) == "diameter" ) |
| 153 | + QCOMPARE( cb->count(), 2 ); |
| 154 | + else if ( cb->itemText( 0 ) == "raccord" ) |
| 155 | + { |
| 156 | + QStringList items; |
| 157 | + for ( int i = 0; i < cb->count(); i++ ) |
| 158 | + items << cb->itemText( i ); |
| 159 | + |
| 160 | + QCOMPARE( cb->count(), 3 ); |
| 161 | + QCOMPARE(( bool )items.contains( "collar" ), false ); |
| 162 | + // collar should not be available in combobox as there's no existing |
| 163 | + // feature with the filter expression: |
| 164 | + // "material" == 'iron' AND "diameter" == '120' AND "raccord" = 'collar' |
| 165 | + } |
| 166 | + } |
| 167 | + |
| 168 | + // set the filter for "raccord" and then reset filter for "diameter". As |
| 169 | + // chain filter is activated, the filter on "raccord" field should be reset |
| 170 | + cbs[2]->setCurrentIndex( cbs[2]->findText( "brides" ) ); |
| 171 | + cbs[1]->setCurrentIndex( cbs[1]->findText( "diameter" ) ); |
| 172 | + |
| 173 | + // combobox should propose NULL, 10 and 11 because the filter is now: |
| 174 | + // "material" == 'iron' |
| 175 | + QCOMPARE( w.mComboBox->count(), 3 ); |
| 176 | + |
| 177 | + // if there's no filter at all, all features' id should be proposed |
| 178 | + cbs[0]->setCurrentIndex( cbs[0]->findText( "material" ) ); |
| 179 | + QCOMPARE( w.mComboBox->count(), 4 ); |
| 180 | +} |
| 181 | + |
| 182 | +QTEST_MAIN( TestQgsRelationReferenceWidget ) |
| 183 | +#include "testqgsrelationreferencewidget.moc" |
0 commit comments