From bc035216c5f54621d3417cfc6e5b3517522d55c2 Mon Sep 17 00:00:00 2001 From: uclaros Date: Mon, 7 Oct 2024 14:36:02 +0300 Subject: [PATCH] Revert #3543 and use QgsFeatureRequest::setOrderBy instead --- app/CMakeLists.txt | 2 - app/featuresmodel.cpp | 43 ++--- app/featuresmodel.h | 18 -- app/featuresproxymodel.cpp | 48 ------ app/featuresproxymodel.h | 47 ------ app/main.cpp | 2 - .../editors/MMFormValueRelationEditor.qml | 12 +- app/qml/layers/MMFeaturesListPage.qml | 10 +- app/test/testmodels.cpp | 154 +++++++++--------- app/test/testmodels.h | 4 +- app/valuerelationfeaturesmodel.cpp | 14 +- app/valuerelationfeaturesmodel.h | 1 - 12 files changed, 106 insertions(+), 249 deletions(-) delete mode 100644 app/featuresproxymodel.cpp delete mode 100644 app/featuresproxymodel.h diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index f371e92eb..b96c77c27 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -52,7 +52,6 @@ set(MM_SRCS compass.cpp featurelayerpair.cpp featuresmodel.cpp - featuresproxymodel.cpp fieldsmodel.cpp guidelinecontroller.cpp identifykit.cpp @@ -136,7 +135,6 @@ set(MM_HDRS enumhelper.h featurelayerpair.h featuresmodel.h - featuresproxymodel.h fieldsmodel.h guidelinecontroller.h identifykit.h diff --git a/app/featuresmodel.cpp b/app/featuresmodel.cpp index 9571c92ff..a4fef0fa8 100644 --- a/app/featuresmodel.cpp +++ b/app/featuresmodel.cpp @@ -141,7 +141,6 @@ QVariant FeaturesModel::data( const QModelIndex &index, int role ) const case LayerName: return pair.layer() ? pair.layer()->name() : QString(); case LayerIcon: return pair.layer() ? InputUtils::loadIconFromLayer( pair.layer() ) : QString(); case Qt::DisplayRole: return featureTitle( pair ); - case SortValue: return sortValue( pair ); } return QVariant(); @@ -178,13 +177,6 @@ QVariant FeaturesModel::featureTitle( const FeatureLayerPair &featurePair ) cons return title; } -QVariant FeaturesModel::sortValue( const FeatureLayerPair &featurePair ) const -{ - mExpressionContext.setFeature( featurePair.feature() ); - QVariant result = mSortExpression.evaluate( &mExpressionContext ); - return result; -} - QString FeaturesModel::searchResultPair( const FeatureLayerPair &pair ) const { if ( mSearchExpression.isEmpty() ) @@ -259,6 +251,20 @@ void FeaturesModel::setupFeatureRequest( QgsFeatureRequest &request ) request.setFilterExpression( buildSearchExpression() ); } + if ( mLayer && !mLayer->attributeTableConfig().sortExpression().isEmpty() ) + { + // get a context with global, project and layer scopes + // QGIS docs are not very clear, but this context is also used for evaluation of the request's 'order by' expressions too + QgsExpressionContext context = mLayer->createExpressionContext(); + request.setExpressionContext( context ); + request.setOrderBy( QgsFeatureRequest::OrderBy( + { + QgsFeatureRequest::OrderByClause( + mLayer->attributeTableConfig().sortExpression(), + mLayer->attributeTableConfig().sortOrder() == Qt::AscendingOrder ) + } ) ); + } + request.setLimit( FEATURES_LIMIT ); } @@ -288,7 +294,6 @@ QHash FeaturesModel::roleNames() const roleNames[SearchResult] = QStringLiteral( "SearchResult" ).toLatin1(); roleNames[LayerName] = QStringLiteral( "LayerName" ).toLatin1(); roleNames[LayerIcon] = QStringLiteral( "LayerIcon" ).toLatin1(); - roleNames[SortValue] = QStringLiteral( "SortValue" ).toLatin1(); return roleNames; } @@ -361,8 +366,6 @@ void FeaturesModel::setLayer( QgsVectorLayer *newLayer ) } mLayer = newLayer; - mExpressionContext = mLayer->createExpressionContext(); - setupSorting(); emit layerChanged( mLayer ); if ( mLayer ) @@ -383,21 +386,3 @@ QgsVectorLayer *FeaturesModel::layer() const { return mLayer; } - -void FeaturesModel::setupSorting() -{ - mSortExpressionString = mLayer ? mLayer->attributeTableConfig().sortExpression() : QString(); - mSortOrder = mLayer ? mLayer->attributeTableConfig().sortOrder() : Qt::AscendingOrder; - mSortExpression = QgsExpression( mSortExpressionString ); - mSortExpression.prepare( &mExpressionContext ); -} - -bool FeaturesModel::sortingEnabled() const -{ - return !mSortExpressionString.isEmpty(); -} - -Qt::SortOrder FeaturesModel::sortOrder() const -{ - return mSortOrder; -} diff --git a/app/featuresmodel.h b/app/featuresmodel.h index e47d5c8c5..1f1912cd0 100644 --- a/app/featuresmodel.h +++ b/app/featuresmodel.h @@ -64,7 +64,6 @@ class FeaturesModel : public QAbstractListModel SearchResult, // pair of attribute and its value by which the feature was found, empty if search expression is empty LayerName, LayerIcon, - SortValue, }; Q_ENUM( ModelRoles ); @@ -118,15 +117,6 @@ class FeaturesModel : public QAbstractListModel int layerFeaturesCount() const; - //! Populates the sort expression and sort order for the model - virtual void setupSorting(); - - //! Returns true if there is a sort expression set for the model - bool sortingEnabled() const; - - //! Returns the order in witch the model should be sorted - Qt::SortOrder sortOrder() const; - signals: void featuresLimitChanged( int featuresLimit ); @@ -149,11 +139,6 @@ class FeaturesModel : public QAbstractListModel virtual QVariant featureTitle( const FeatureLayerPair &featurePair ) const; - QString mSortExpressionString; - mutable QgsExpression mSortExpression; - mutable QgsExpressionContext mExpressionContext; - Qt::SortOrder mSortOrder = Qt::AscendingOrder; - private slots: void onFutureFinished(); @@ -166,9 +151,6 @@ class FeaturesModel : public QAbstractListModel //! Returns found attribute and its value from search expression for feature QString searchResultPair( const FeatureLayerPair &feat ) const; - //! Evaluates the sort expression and returns the value used for this feature when sorting the model - QVariant sortValue( const FeatureLayerPair &featurePair ) const; - const int FEATURES_LIMIT = 10000; //!< Number of maximum features loaded from layer FeatureLayerPairs mFeatures; diff --git a/app/featuresproxymodel.cpp b/app/featuresproxymodel.cpp deleted file mode 100644 index a91664e7a..000000000 --- a/app/featuresproxymodel.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include "featuresproxymodel.h" - -FeaturesProxyModel::FeaturesProxyModel( QObject *parent ) : QSortFilterProxyModel( parent ) -{ - setSortRole( FeaturesModel::SortValue ); - setSortCaseSensitivity( Qt::CaseInsensitive ); -} - -void FeaturesProxyModel::updateSorting() -{ - // don't sort if there is no sort expression for the layer - if ( mModel->sortingEnabled() ) - { - sort( 0, mModel->sortOrder() ); - } - else - { - invalidate(); - } -} - -FeaturesModel *FeaturesProxyModel::featuresSourceModel() const -{ - return mModel; -} - -void FeaturesProxyModel::setFeaturesSourceModel( FeaturesModel *sourceModel ) -{ - if ( mModel == sourceModel ) - return; - - if ( mModel ) - disconnect( mModel, nullptr, this, nullptr ); - - mModel = sourceModel; - setSourceModel( mModel ); - mModel->setupSorting(); - connect( mModel, &FeaturesModel::fetchingResultsChanged, this, [ = ]( bool pending ) { if ( !pending ) updateSorting(); } ); -} diff --git a/app/featuresproxymodel.h b/app/featuresproxymodel.h deleted file mode 100644 index 3f3d537ef..000000000 --- a/app/featuresproxymodel.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#ifndef FEATURESPROXYMODEL_H -#define FEATURESPROXYMODEL_H - -#include -#include - -#include "featuresmodel.h" - -/** - * \brief The FeaturesProxyModel class used as a proxy sort model for the \see FeaturesModel class. - * - * FeaturesProxyModel is a QML type with required property of FeatureSourceModel. Without source model, this model does nothing (is not initialized). - * After setting source model, this model starts sorting if sortingEnabled() returns true for the source model. - */ -class FeaturesProxyModel : public QSortFilterProxyModel -{ - Q_OBJECT - - Q_PROPERTY( FeaturesModel *featuresSourceModel READ featuresSourceModel WRITE setFeaturesSourceModel ) - - public: - explicit FeaturesProxyModel( QObject *parent = nullptr ); - ~FeaturesProxyModel() override {}; - - FeaturesModel *featuresSourceModel() const; - - public slots: - void setFeaturesSourceModel( FeaturesModel *sourceModel ); - - private: - void updateSorting(); - - FeaturesModel *mModel = nullptr; // not owned by this, needs to be set in order to proxy model to work - - friend class TestModels; -}; - -#endif // FEATURESPROXYMODEL_H diff --git a/app/main.cpp b/app/main.cpp index 2fcd9b137..d0c35cd24 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -91,7 +91,6 @@ #include "position/positionkit.h" #include "scalebarkit.h" #include "featuresmodel.h" -#include "featuresproxymodel.h" #include "relationfeaturesmodel.h" #include "relationreferencefeaturesmodel.h" #include "fieldvalidator.h" @@ -327,7 +326,6 @@ void initDeclarative() qmlRegisterType< MapThemesModel >( "mm", 1, 0, "MapThemesModel" ); qmlRegisterType< GuidelineController >( "mm", 1, 0, "GuidelineController" ); qmlRegisterType< FeaturesModel >( "mm", 1, 0, "FeaturesModel" ); - qmlRegisterType< FeaturesProxyModel >( "mm", 1, 0, "FeaturesProxyModel" ); qmlRegisterType< RelationFeaturesModel >( "mm", 1, 0, "RelationFeaturesModel" ); qmlRegisterType< ValueRelationFeaturesModel >( "mm", 1, 0, "ValueRelationFeaturesModel" ); qmlRegisterType< RelationReferenceFeaturesModel >( "mm", 1, 0, "RelationReferenceFeaturesModel" ); diff --git a/app/qml/form/editors/MMFormValueRelationEditor.qml b/app/qml/form/editors/MMFormValueRelationEditor.qml index 41c4b31a3..e98643ed2 100644 --- a/app/qml/form/editors/MMFormValueRelationEditor.qml +++ b/app/qml/form/editors/MMFormValueRelationEditor.qml @@ -76,15 +76,11 @@ MMFormComboboxBaseEditor { valueRole: "FeatureId" textRole: "FeatureTitle" - list.model: MM.FeaturesProxyModel { - id: vrDropdownProxyModel + list.model: MM.ValueRelationFeaturesModel { + id: vrDropdownModel - featuresSourceModel: MM.ValueRelationFeaturesModel { - id: vrDropdownModel - - config: root._fieldConfig - pair: root._fieldFeatureLayerPair - } + config: root._fieldConfig + pair: root._fieldFeatureLayerPair } onSearchTextChanged: ( searchText ) => vrDropdownModel.searchExpression = searchText diff --git a/app/qml/layers/MMFeaturesListPage.qml b/app/qml/layers/MMFeaturesListPage.qml index 41c5012c8..5b162c87d 100644 --- a/app/qml/layers/MMFeaturesListPage.qml +++ b/app/qml/layers/MMFeaturesListPage.qml @@ -55,14 +55,10 @@ MMComponents.MMPage { topMargin: __style.spacing20 } - model: MM.FeaturesProxyModel { - id: featuresProxyModel + model: MM.FeaturesModel { + id: featuresModel - featuresSourceModel: MM.FeaturesModel { - id: featuresModel - - layer: root.selectedLayer - } + layer: root.selectedLayer } clip: true diff --git a/app/test/testmodels.cpp b/app/test/testmodels.cpp index 844fd07ba..8b682cb6e 100644 --- a/app/test/testmodels.cpp +++ b/app/test/testmodels.cpp @@ -10,7 +10,6 @@ #include "testmodels.h" #include "testutils.h" #include "featuresmodel.h" -#include "featuresproxymodel.h" #include "valuerelationfeaturesmodel.h" #include "projectsmodel.h" #include "projectsproxymodel.h" @@ -58,10 +57,9 @@ void TestModels::testFeaturesModel() QCOMPARE( title, QStringLiteral( "First" ) ); } -void TestModels::testFeaturesProxyModel() +void TestModels::testFeaturesModelSorted() { FeaturesModel model; - FeaturesProxyModel proxy; QSignalSpy spy( &model, &FeaturesModel::fetchingResultsChanged ); @@ -75,62 +73,58 @@ void TestModels::testFeaturesProxyModel() conf.setSortExpression( QStringLiteral( "Name" ) ); layer->setAttributeTableConfig( conf ); - proxy.setFeaturesSourceModel( &model ); model.setLayer( layer ); model.reloadFeatures(); spy.wait(); - QCOMPARE( proxy.rowCount(), layer->dataProvider()->featureCount() ); - QCOMPARE( proxy.data( proxy.index( 0, 0 ), FeaturesModel::SortValue ), QLatin1String( "A1" ) ); - QCOMPARE( proxy.data( proxy.index( 1, 0 ), FeaturesModel::SortValue ), QLatin1String( "A2" ) ); - QCOMPARE( proxy.data( proxy.index( 2, 0 ), FeaturesModel::SortValue ), QLatin1String( "B1" ) ); - QCOMPARE( proxy.data( proxy.index( 3, 0 ), FeaturesModel::SortValue ), QLatin1String( "B2" ) ); - QCOMPARE( proxy.data( proxy.index( 4, 0 ), FeaturesModel::SortValue ), QLatin1String( "C1" ) ); - QCOMPARE( proxy.data( proxy.index( 5, 0 ), FeaturesModel::SortValue ), QLatin1String( "C2" ) ); - QCOMPARE( proxy.data( proxy.index( 6, 0 ), FeaturesModel::SortValue ), QLatin1String( "D1" ) ); - QCOMPARE( proxy.data( proxy.index( 7, 0 ), FeaturesModel::SortValue ), QLatin1String( "D2" ) ); - QCOMPARE( proxy.data( proxy.index( 8, 0 ), FeaturesModel::SortValue ), QLatin1String( "VERYBIG" ) ); - - // filter the fModel (this is not proxy model filtering) - // and reverse sort order + QCOMPARE( model.rowCount(), layer->dataProvider()->featureCount() ); + QCOMPARE( model.data( model.index( 0, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "A1" ) ); + QCOMPARE( model.data( model.index( 1, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "A2" ) ); + QCOMPARE( model.data( model.index( 2, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "B1" ) ); + QCOMPARE( model.data( model.index( 3, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "B2" ) ); + QCOMPARE( model.data( model.index( 4, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "C1" ) ); + QCOMPARE( model.data( model.index( 5, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "C2" ) ); + QCOMPARE( model.data( model.index( 6, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "D1" ) ); + QCOMPARE( model.data( model.index( 7, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "D2" ) ); + QCOMPARE( model.data( model.index( 8, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "VERYBIG" ) ); + + // filter the model and reverse sort order conf.setSortOrder( Qt::DescendingOrder ); layer->setAttributeTableConfig( conf ); - model.setupSorting(); model.setSearchExpression( QStringLiteral( "D" ) ); spy.wait(); - QCOMPARE( proxy.rowCount(), 2 ); - QCOMPARE( proxy.data( proxy.index( 0, 0 ), FeaturesModel::SortValue ), QLatin1String( "D2" ) ); - QCOMPARE( proxy.data( proxy.index( 1, 0 ), FeaturesModel::SortValue ), QLatin1String( "D1" ) ); + QCOMPARE( model.rowCount(), 2 ); + QCOMPARE( model.data( model.index( 0, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "D2" ) ); + QCOMPARE( model.data( model.index( 1, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "D1" ) ); // disable sorting and filtering // should get all items with default ordering conf.setSortExpression( QString() ); layer->setAttributeTableConfig( conf ); - model.setupSorting(); model.setSearchExpression( QString() ); spy.wait(); - QCOMPARE( proxy.rowCount(), layer->dataProvider()->featureCount() ); - QCOMPARE( proxy.data( proxy.index( 0, 0 ), FeaturesModel::FeatureId ), 1 ); - QCOMPARE( proxy.data( proxy.index( 1, 0 ), FeaturesModel::FeatureId ), 2 ); - QCOMPARE( proxy.data( proxy.index( 2, 0 ), FeaturesModel::FeatureId ), 3 ); - QCOMPARE( proxy.data( proxy.index( 3, 0 ), FeaturesModel::FeatureId ), 4 ); - QCOMPARE( proxy.data( proxy.index( 4, 0 ), FeaturesModel::FeatureId ), 5 ); - QCOMPARE( proxy.data( proxy.index( 5, 0 ), FeaturesModel::FeatureId ), 6 ); - QCOMPARE( proxy.data( proxy.index( 6, 0 ), FeaturesModel::FeatureId ), 7 ); - QCOMPARE( proxy.data( proxy.index( 7, 0 ), FeaturesModel::FeatureId ), 8 ); - QCOMPARE( proxy.data( proxy.index( 8, 0 ), FeaturesModel::FeatureId ), 100000000 ); + QCOMPARE( model.rowCount(), layer->dataProvider()->featureCount() ); + QCOMPARE( model.data( model.index( 0, 0 ), FeaturesModel::ModelRoles::FeatureId ), 1 ); + QCOMPARE( model.data( model.index( 1, 0 ), FeaturesModel::ModelRoles::FeatureId ), 2 ); + QCOMPARE( model.data( model.index( 2, 0 ), FeaturesModel::ModelRoles::FeatureId ), 3 ); + QCOMPARE( model.data( model.index( 3, 0 ), FeaturesModel::ModelRoles::FeatureId ), 4 ); + QCOMPARE( model.data( model.index( 4, 0 ), FeaturesModel::ModelRoles::FeatureId ), 5 ); + QCOMPARE( model.data( model.index( 5, 0 ), FeaturesModel::ModelRoles::FeatureId ), 6 ); + QCOMPARE( model.data( model.index( 6, 0 ), FeaturesModel::ModelRoles::FeatureId ), 7 ); + QCOMPARE( model.data( model.index( 7, 0 ), FeaturesModel::ModelRoles::FeatureId ), 8 ); + QCOMPARE( model.data( model.index( 8, 0 ), FeaturesModel::ModelRoles::FeatureId ), 100000000 ); } -void TestModels::testFeaturesProxyModelWithValueRelation() +void TestModels::testValueRelationFeaturesModel() { QString projectDir = TestUtils::testDataDir() + "/project_value_relations"; QString projectName = "proj.qgz"; @@ -151,8 +145,6 @@ void TestModels::testFeaturesProxyModelWithValueRelation() FeatureLayerPair pair( f, mainLayer ); ValueRelationFeaturesModel model; - FeaturesProxyModel proxy; - proxy.setFeaturesSourceModel( &model ); QSignalSpy spy( &model, &FeaturesModel::fetchingResultsChanged ); @@ -171,78 +163,86 @@ void TestModels::testFeaturesProxyModelWithValueRelation() QCOMPARE( model.rowCount(), 9 ); QCOMPARE( model.layer()->id(), subsubLayer->id() ); - QCOMPARE( proxy.rowCount(), 9 ); - QCOMPARE( proxy.data( proxy.index( 0, 0 ), FeaturesModel::FeatureId ), 1 ); - QCOMPARE( proxy.data( proxy.index( 1, 0 ), FeaturesModel::FeatureId ), 2 ); - QCOMPARE( proxy.data( proxy.index( 2, 0 ), FeaturesModel::FeatureId ), 3 ); - QCOMPARE( proxy.data( proxy.index( 3, 0 ), FeaturesModel::FeatureId ), 4 ); - QCOMPARE( proxy.data( proxy.index( 4, 0 ), FeaturesModel::FeatureId ), 5 ); - QCOMPARE( proxy.data( proxy.index( 5, 0 ), FeaturesModel::FeatureId ), 6 ); - QCOMPARE( proxy.data( proxy.index( 6, 0 ), FeaturesModel::FeatureId ), 7 ); - QCOMPARE( proxy.data( proxy.index( 7, 0 ), FeaturesModel::FeatureId ), 8 ); - QCOMPARE( proxy.data( proxy.index( 8, 0 ), FeaturesModel::FeatureId ), 100000000 ); + QCOMPARE( model.rowCount(), 9 ); + QCOMPARE( model.data( model.index( 0, 0 ), FeaturesModel::ModelRoles::FeatureId ), 1 ); + QCOMPARE( model.data( model.index( 1, 0 ), FeaturesModel::ModelRoles::FeatureId ), 2 ); + QCOMPARE( model.data( model.index( 2, 0 ), FeaturesModel::ModelRoles::FeatureId ), 3 ); + QCOMPARE( model.data( model.index( 3, 0 ), FeaturesModel::ModelRoles::FeatureId ), 4 ); + QCOMPARE( model.data( model.index( 4, 0 ), FeaturesModel::ModelRoles::FeatureId ), 5 ); + QCOMPARE( model.data( model.index( 5, 0 ), FeaturesModel::ModelRoles::FeatureId ), 6 ); + QCOMPARE( model.data( model.index( 6, 0 ), FeaturesModel::ModelRoles::FeatureId ), 7 ); + QCOMPARE( model.data( model.index( 7, 0 ), FeaturesModel::ModelRoles::FeatureId ), 8 ); + QCOMPARE( model.data( model.index( 8, 0 ), FeaturesModel::ModelRoles::FeatureId ), 100000000 ); // enable order by value for the value relation model.reset(); config[ QStringLiteral( "OrderByValue" ) ] = true; model.setConfig( config ); - model.setupSorting(); model.setPair( pair ); spy.wait(); - QCOMPARE( proxy.rowCount(), 9 ); - QCOMPARE( proxy.data( proxy.index( 0, 0 ), FeaturesModel::SortValue ), QLatin1String( "A1" ) ); - QCOMPARE( proxy.data( proxy.index( 1, 0 ), FeaturesModel::SortValue ), QLatin1String( "A2" ) ); - QCOMPARE( proxy.data( proxy.index( 2, 0 ), FeaturesModel::SortValue ), QLatin1String( "B1" ) ); - QCOMPARE( proxy.data( proxy.index( 3, 0 ), FeaturesModel::SortValue ), QLatin1String( "B2" ) ); - QCOMPARE( proxy.data( proxy.index( 4, 0 ), FeaturesModel::SortValue ), QLatin1String( "C1" ) ); - QCOMPARE( proxy.data( proxy.index( 5, 0 ), FeaturesModel::SortValue ), QLatin1String( "C2" ) ); - QCOMPARE( proxy.data( proxy.index( 6, 0 ), FeaturesModel::SortValue ), QLatin1String( "D1" ) ); - QCOMPARE( proxy.data( proxy.index( 7, 0 ), FeaturesModel::SortValue ), QLatin1String( "D2" ) ); - QCOMPARE( proxy.data( proxy.index( 8, 0 ), FeaturesModel::SortValue ), QLatin1String( "VERYBIG" ) ); - - // add a search expression to base model + QCOMPARE( model.rowCount(), 9 ); + QCOMPARE( model.data( model.index( 0, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "A1" ) ); + QCOMPARE( model.data( model.index( 1, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "A2" ) ); + QCOMPARE( model.data( model.index( 2, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "B1" ) ); + QCOMPARE( model.data( model.index( 3, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "B2" ) ); + QCOMPARE( model.data( model.index( 4, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "C1" ) ); + QCOMPARE( model.data( model.index( 5, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "C2" ) ); + QCOMPARE( model.data( model.index( 6, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "D1" ) ); + QCOMPARE( model.data( model.index( 7, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "D2" ) ); + QCOMPARE( model.data( model.index( 8, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "VERYBIG" ) ); + + // add a search expression to model model.setSearchExpression( QStringLiteral( "D" ) ); spy.wait(); QCOMPARE( model.rowCount(), 2 ); - QCOMPARE( proxy.rowCount(), 2 ); - QCOMPARE( proxy.data( proxy.index( 0, 0 ), FeaturesModel::SortValue ), QLatin1String( "D1" ) ); - QCOMPARE( proxy.data( proxy.index( 1, 0 ), FeaturesModel::SortValue ), QLatin1String( "D2" ) ); + QCOMPARE( model.rowCount(), 2 ); + QCOMPARE( model.data( model.index( 0, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "D1" ) ); + QCOMPARE( model.data( model.index( 1, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "D2" ) ); - // add a filter expression to the base model + // add a filter expression to the model config[ QStringLiteral( "FilterExpression" ) ] = "subFk = 1"; model.setConfig( config ); - model.setupSorting(); model.setSearchExpression( QString() ); spy.wait(); QCOMPARE( model.rowCount(), 2 ); - QCOMPARE( proxy.data( proxy.index( 0, 0 ), FeaturesModel::SortValue ), QLatin1String( "A1" ) ); - QCOMPARE( proxy.data( proxy.index( 1, 0 ), FeaturesModel::SortValue ), QLatin1String( "A2" ) ); + QCOMPARE( model.data( model.index( 0, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "A1" ) ); + QCOMPARE( model.data( model.index( 1, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "A2" ) ); - // remove filters and sorting + // remove sorting model.reset(); config.remove( QStringLiteral( "OrderByValue" ) ); + model.setConfig( config ); + model.setPair( pair ); + + spy.wait(); + + QCOMPARE( model.rowCount(), 2 ); + QCOMPARE( model.data( model.index( 0, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "A2" ) ); + QCOMPARE( model.data( model.index( 1, 0 ), FeaturesModel::ModelRoles::FeatureTitle ), QLatin1String( "A1" ) ); + + // remove filters + model.reset(); config.remove( QStringLiteral( "FilterExpression" ) ); model.setConfig( config ); - model.setupSorting(); model.setPair( pair ); spy.wait(); - QCOMPARE( proxy.rowCount(), 9 ); - QCOMPARE( proxy.data( proxy.index( 0, 0 ), FeaturesModel::FeatureId ), 1 ); - QCOMPARE( proxy.data( proxy.index( 1, 0 ), FeaturesModel::FeatureId ), 2 ); - QCOMPARE( proxy.data( proxy.index( 2, 0 ), FeaturesModel::FeatureId ), 3 ); - QCOMPARE( proxy.data( proxy.index( 3, 0 ), FeaturesModel::FeatureId ), 4 ); - QCOMPARE( proxy.data( proxy.index( 4, 0 ), FeaturesModel::FeatureId ), 5 ); - QCOMPARE( proxy.data( proxy.index( 5, 0 ), FeaturesModel::FeatureId ), 6 ); - QCOMPARE( proxy.data( proxy.index( 6, 0 ), FeaturesModel::FeatureId ), 7 ); - QCOMPARE( proxy.data( proxy.index( 7, 0 ), FeaturesModel::FeatureId ), 8 ); - QCOMPARE( proxy.data( proxy.index( 8, 0 ), FeaturesModel::FeatureId ), 100000000 ); + QCOMPARE( model.rowCount(), 9 ); + QCOMPARE( model.data( model.index( 0, 0 ), FeaturesModel::ModelRoles::FeatureId ), 1 ); + QCOMPARE( model.data( model.index( 1, 0 ), FeaturesModel::ModelRoles::FeatureId ), 2 ); + QCOMPARE( model.data( model.index( 2, 0 ), FeaturesModel::ModelRoles::FeatureId ), 3 ); + QCOMPARE( model.data( model.index( 3, 0 ), FeaturesModel::ModelRoles::FeatureId ), 4 ); + QCOMPARE( model.data( model.index( 4, 0 ), FeaturesModel::ModelRoles::FeatureId ), 5 ); + QCOMPARE( model.data( model.index( 5, 0 ), FeaturesModel::ModelRoles::FeatureId ), 6 ); + QCOMPARE( model.data( model.index( 6, 0 ), FeaturesModel::ModelRoles::FeatureId ), 7 ); + QCOMPARE( model.data( model.index( 7, 0 ), FeaturesModel::ModelRoles::FeatureId ), 8 ); + QCOMPARE( model.data( model.index( 8, 0 ), FeaturesModel::ModelRoles::FeatureId ), 100000000 ); } void TestModels::testProjectsModel() diff --git a/app/test/testmodels.h b/app/test/testmodels.h index d66b1ba37..4c3e41991 100644 --- a/app/test/testmodels.h +++ b/app/test/testmodels.h @@ -23,8 +23,8 @@ class TestModels : public QObject void cleanup(); // will be called after every testfunction. void testFeaturesModel(); - void testFeaturesProxyModel(); - void testFeaturesProxyModelWithValueRelation(); + void testFeaturesModelSorted(); + void testValueRelationFeaturesModel(); void testProjectsModel(); void testProjectsProxyModel(); diff --git a/app/valuerelationfeaturesmodel.cpp b/app/valuerelationfeaturesmodel.cpp index 84d955edc..6ce4e65ae 100644 --- a/app/valuerelationfeaturesmodel.cpp +++ b/app/valuerelationfeaturesmodel.cpp @@ -40,6 +40,12 @@ void ValueRelationFeaturesModel::setupFeatureRequest( QgsFeatureRequest &request request.setExpressionContext( filterContext ); } } + + if ( mConfig.value( QStringLiteral( "OrderByValue" ) ).toBool() ) + { + // replace any existing order by clause with our value field + request.setOrderBy( QgsFeatureRequest::OrderBy( { QgsFeatureRequest::OrderByClause( mTitleField ) } ) ); + } } void ValueRelationFeaturesModel::setup() @@ -207,11 +213,3 @@ void ValueRelationFeaturesModel::setConfig( const QVariantMap &newConfig ) setup(); } - -void ValueRelationFeaturesModel::setupSorting() -{ - const bool orderByValue = mConfig.value( QStringLiteral( "OrderByValue" ) ).toBool(); - mSortExpressionString = orderByValue ? mTitleField : QString(); - mSortExpression = QgsExpression( mSortExpressionString ); - mSortExpression.prepare( &mExpressionContext ); -} diff --git a/app/valuerelationfeaturesmodel.h b/app/valuerelationfeaturesmodel.h index 2c660efeb..7a1d178bd 100644 --- a/app/valuerelationfeaturesmodel.h +++ b/app/valuerelationfeaturesmodel.h @@ -37,7 +37,6 @@ class ValueRelationFeaturesModel : public FeaturesModel void reset() override; void setupFeatureRequest( QgsFeatureRequest &request ) override; QVariant featureTitle( const FeatureLayerPair &pair ) const override; - void setupSorting() override; Q_INVOKABLE QVariant convertToKey( const QVariant &id ); Q_INVOKABLE QVariant convertToQgisType( const QVariantList &featureIds ); // feature id -> key