|
46 | 46 | QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayerCache *layerCache, QObject *parent )
|
47 | 47 | : QAbstractTableModel( parent )
|
48 | 48 | , mLayerCache( layerCache )
|
49 |
| - , mFieldCount( 0 ) |
50 |
| - , mSortFieldIndex( -1 ) |
51 |
| - , mExtraColumns( 0 ) |
52 | 49 | {
|
53 | 50 | mExpressionContext.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( layerCache->layer() ) );
|
54 | 51 |
|
@@ -168,7 +165,8 @@ bool QgsAttributeTableModel::removeRows( int row, int count, const QModelIndex &
|
168 | 165 | // clean old references
|
169 | 166 | for ( int i = row; i < row + count; i++ )
|
170 | 167 | {
|
171 |
| - mSortCache.remove( mRowIdMap[i] ); |
| 168 | + for ( SortCache &cache : mSortCaches ) |
| 169 | + cache.sortCache.remove( mRowIdMap[i] ); |
172 | 170 | mIdRowMap.remove( mRowIdMap[i] );
|
173 | 171 | mRowIdMap.remove( i );
|
174 | 172 | }
|
@@ -214,18 +212,21 @@ void QgsAttributeTableModel::featureAdded( QgsFeatureId fid, bool resettingModel
|
214 | 212 |
|
215 | 213 | if ( featOk && mFeatureRequest.acceptFeature( mFeat ) )
|
216 | 214 | {
|
217 |
| - if ( mSortFieldIndex >= 0 ) |
| 215 | + for ( SortCache &cache : mSortCaches ) |
218 | 216 | {
|
219 |
| - QgsFieldFormatter *fieldFormatter = mFieldFormatters.at( mSortFieldIndex ); |
220 |
| - const QVariant &widgetCache = mAttributeWidgetCaches.at( mSortFieldIndex ); |
221 |
| - const QVariantMap &widgetConfig = mWidgetConfigs.at( mSortFieldIndex ); |
222 |
| - QVariant sortValue = fieldFormatter->representValue( layer(), mSortFieldIndex, widgetConfig, widgetCache, mFeat.attribute( mSortFieldIndex ) ); |
223 |
| - mSortCache.insert( mFeat.id(), sortValue ); |
224 |
| - } |
225 |
| - else if ( mSortCacheExpression.isValid() ) |
226 |
| - { |
227 |
| - mExpressionContext.setFeature( mFeat ); |
228 |
| - mSortCache[mFeat.id()] = mSortCacheExpression.evaluate( &mExpressionContext ); |
| 217 | + if ( cache.sortFieldIndex >= 0 ) |
| 218 | + { |
| 219 | + QgsFieldFormatter *fieldFormatter = mFieldFormatters.at( cache.sortFieldIndex ); |
| 220 | + const QVariant &widgetCache = mAttributeWidgetCaches.at( cache.sortFieldIndex ); |
| 221 | + const QVariantMap &widgetConfig = mWidgetConfigs.at( cache.sortFieldIndex ); |
| 222 | + QVariant sortValue = fieldFormatter->representValue( layer(), cache.sortFieldIndex, widgetConfig, widgetCache, mFeat.attribute( cache.sortFieldIndex ) ); |
| 223 | + cache.sortCache.insert( mFeat.id(), sortValue ); |
| 224 | + } |
| 225 | + else if ( cache.sortCacheExpression.isValid() ) |
| 226 | + { |
| 227 | + mExpressionContext.setFeature( mFeat ); |
| 228 | + cache.sortCache[mFeat.id()] = cache.sortCacheExpression.evaluate( &mExpressionContext ); |
| 229 | + } |
229 | 230 | }
|
230 | 231 |
|
231 | 232 | // Skip if the fid is already in the map (do not add twice)!
|
@@ -258,8 +259,15 @@ void QgsAttributeTableModel::editCommandEnded()
|
258 | 259 |
|
259 | 260 | void QgsAttributeTableModel::attributeDeleted( int idx )
|
260 | 261 | {
|
261 |
| - if ( mSortCacheAttributes.contains( idx ) ) |
262 |
| - prefetchSortData( QString() ); |
| 262 | + int cacheIndex = 0; |
| 263 | + for ( const SortCache &cache : mSortCaches ) |
| 264 | + { |
| 265 | + if ( cache.sortCacheAttributes.contains( idx ) ) |
| 266 | + { |
| 267 | + prefetchSortData( QString(), cacheIndex ); |
| 268 | + } |
| 269 | + cacheIndex++; |
| 270 | + } |
263 | 271 | }
|
264 | 272 |
|
265 | 273 | void QgsAttributeTableModel::layerDeleted()
|
@@ -287,23 +295,26 @@ void QgsAttributeTableModel::attributeValueChanged( QgsFeatureId fid, int idx, c
|
287 | 295 | {
|
288 | 296 | QgsDebugMsgLevel( QString( "(%4) fid: %1, idx: %2, value: %3" ).arg( fid ).arg( idx ).arg( value.toString() ).arg( mFeatureRequest.filterType() ), 3 );
|
289 | 297 |
|
290 |
| - if ( mSortCacheAttributes.contains( idx ) ) |
| 298 | + for ( SortCache &cache : mSortCaches ) |
291 | 299 | {
|
292 |
| - if ( mSortFieldIndex == -1 ) |
| 300 | + if ( cache.sortCacheAttributes.contains( idx ) ) |
293 | 301 | {
|
294 |
| - if ( loadFeatureAtId( fid ) ) |
| 302 | + if ( cache.sortFieldIndex == -1 ) |
295 | 303 | {
|
296 |
| - mExpressionContext.setFeature( mFeat ); |
297 |
| - mSortCache[fid] = mSortCacheExpression.evaluate( &mExpressionContext ); |
| 304 | + if ( loadFeatureAtId( fid ) ) |
| 305 | + { |
| 306 | + mExpressionContext.setFeature( mFeat ); |
| 307 | + cache.sortCache[fid] = cache.sortCacheExpression.evaluate( &mExpressionContext ); |
| 308 | + } |
| 309 | + } |
| 310 | + else |
| 311 | + { |
| 312 | + QgsFieldFormatter *fieldFormatter = mFieldFormatters.at( cache.sortFieldIndex ); |
| 313 | + const QVariant &widgetCache = mAttributeWidgetCaches.at( cache.sortFieldIndex ); |
| 314 | + const QVariantMap &widgetConfig = mWidgetConfigs.at( cache.sortFieldIndex ); |
| 315 | + QVariant sortValue = fieldFormatter->representValue( layer(), cache.sortFieldIndex, widgetConfig, widgetCache, value ); |
| 316 | + cache.sortCache.insert( fid, sortValue ); |
298 | 317 | }
|
299 |
| - } |
300 |
| - else |
301 |
| - { |
302 |
| - QgsFieldFormatter *fieldFormatter = mFieldFormatters.at( mSortFieldIndex ); |
303 |
| - const QVariant &widgetCache = mAttributeWidgetCaches.at( mSortFieldIndex ); |
304 |
| - const QVariantMap &widgetConfig = mWidgetConfigs.at( mSortFieldIndex ); |
305 |
| - QVariant sortValue = fieldFormatter->representValue( layer(), mSortFieldIndex, widgetConfig, widgetCache, value ); |
306 |
| - mSortCache.insert( fid, sortValue ); |
307 | 318 | }
|
308 | 319 | }
|
309 | 320 | // No filter request: skip all possibly heavy checks
|
@@ -389,8 +400,11 @@ void QgsAttributeTableModel::loadAttributes()
|
389 | 400 | mFieldCount = attributes.size();
|
390 | 401 | mAttributes = attributes;
|
391 | 402 |
|
392 |
| - if ( mSortFieldIndex >= mAttributes.count() ) |
393 |
| - mSortFieldIndex = -1; |
| 403 | + for ( SortCache &cache : mSortCaches ) |
| 404 | + { |
| 405 | + if ( cache.sortFieldIndex >= mAttributes.count() ) |
| 406 | + cache.sortFieldIndex = -1; |
| 407 | + } |
394 | 408 |
|
395 | 409 | if ( ins )
|
396 | 410 | {
|
@@ -626,9 +640,13 @@ QVariant QgsAttributeTableModel::data( const QModelIndex &index, int role ) cons
|
626 | 640 | if ( role == FieldIndexRole )
|
627 | 641 | return fieldId;
|
628 | 642 |
|
629 |
| - if ( role == SortRole ) |
| 643 | + if ( role >= SortRole ) |
630 | 644 | {
|
631 |
| - return mSortCache[rowId]; |
| 645 | + unsigned long cacheIndex = role - SortRole; |
| 646 | + if ( cacheIndex < mSortCaches.size() ) |
| 647 | + return mSortCaches.at( cacheIndex ).sortCache.value( rowId ); |
| 648 | + else |
| 649 | + return QVariant(); |
632 | 650 | }
|
633 | 651 |
|
634 | 652 | QgsField field = layer()->fields().at( fieldId );
|
@@ -819,75 +837,90 @@ void QgsAttributeTableModel::prefetchColumnData( int column )
|
819 | 837 | }
|
820 | 838 | }
|
821 | 839 |
|
822 |
| -void QgsAttributeTableModel::prefetchSortData( const QString &expressionString ) |
| 840 | +void QgsAttributeTableModel::prefetchSortData( const QString &expressionString, unsigned long cacheIndex ) |
823 | 841 | {
|
824 |
| - mSortCache.clear(); |
825 |
| - mSortCacheAttributes.clear(); |
826 |
| - mSortFieldIndex = -1; |
| 842 | + if ( cacheIndex >= mSortCaches.size() ) |
| 843 | + { |
| 844 | + mSortCaches.resize( cacheIndex + 1 ); |
| 845 | + } |
| 846 | + SortCache &cache = mSortCaches[cacheIndex]; |
| 847 | + cache.sortCache.clear(); |
| 848 | + cache.sortCacheAttributes.clear(); |
| 849 | + cache.sortFieldIndex = -1; |
827 | 850 | if ( !expressionString.isEmpty() )
|
828 |
| - mSortCacheExpression = QgsExpression( expressionString ); |
| 851 | + cache.sortCacheExpression = QgsExpression( expressionString ); |
829 | 852 | else
|
830 | 853 | {
|
831 | 854 | // no sorting
|
832 |
| - mSortCacheExpression = QgsExpression(); |
| 855 | + cache.sortCacheExpression = QgsExpression(); |
833 | 856 | return;
|
834 | 857 | }
|
835 | 858 |
|
836 | 859 | QgsFieldFormatter *fieldFormatter = nullptr;
|
837 | 860 | QVariant widgetCache;
|
838 | 861 | QVariantMap widgetConfig;
|
839 | 862 |
|
840 |
| - if ( mSortCacheExpression.isField() ) |
| 863 | + if ( cache.sortCacheExpression.isField() ) |
841 | 864 | {
|
842 |
| - QString fieldName = static_cast<const QgsExpressionNodeColumnRef *>( mSortCacheExpression.rootNode() )->name(); |
843 |
| - mSortFieldIndex = mLayerCache->layer()->fields().lookupField( fieldName ); |
| 865 | + QString fieldName = static_cast<const QgsExpressionNodeColumnRef *>( cache.sortCacheExpression.rootNode() )->name(); |
| 866 | + cache.sortFieldIndex = mLayerCache->layer()->fields().lookupField( fieldName ); |
844 | 867 | }
|
845 | 868 |
|
846 |
| - if ( mSortFieldIndex == -1 ) |
| 869 | + if ( cache.sortFieldIndex == -1 ) |
847 | 870 | {
|
848 |
| - mSortCacheExpression.prepare( &mExpressionContext ); |
| 871 | + cache.sortCacheExpression.prepare( &mExpressionContext ); |
| 872 | + |
| 873 | + const QSet<QString> &referencedColumns = cache.sortCacheExpression.referencedColumns(); |
849 | 874 |
|
850 |
| - Q_FOREACH ( const QString &col, mSortCacheExpression.referencedColumns() ) |
| 875 | + for ( const QString &col : referencedColumns ) |
851 | 876 | {
|
852 |
| - mSortCacheAttributes.append( mLayerCache->layer()->fields().lookupField( col ) ); |
| 877 | + cache.sortCacheAttributes.append( mLayerCache->layer()->fields().lookupField( col ) ); |
853 | 878 | }
|
854 | 879 | }
|
855 | 880 | else
|
856 | 881 | {
|
857 |
| - mSortCacheAttributes.append( mSortFieldIndex ); |
| 882 | + cache.sortCacheAttributes.append( cache.sortFieldIndex ); |
858 | 883 |
|
859 |
| - widgetCache = mAttributeWidgetCaches.at( mSortFieldIndex ); |
860 |
| - widgetConfig = mWidgetConfigs.at( mSortFieldIndex ); |
861 |
| - fieldFormatter = mFieldFormatters.at( mSortFieldIndex ); |
| 884 | + widgetCache = mAttributeWidgetCaches.at( cache.sortFieldIndex ); |
| 885 | + widgetConfig = mWidgetConfigs.at( cache.sortFieldIndex ); |
| 886 | + fieldFormatter = mFieldFormatters.at( cache.sortFieldIndex ); |
862 | 887 | }
|
863 | 888 |
|
864 | 889 | QgsFeatureRequest request = QgsFeatureRequest( mFeatureRequest )
|
865 | 890 | .setFlags( QgsFeatureRequest::NoGeometry )
|
866 |
| - .setSubsetOfAttributes( mSortCacheAttributes ); |
| 891 | + .setSubsetOfAttributes( cache.sortCacheAttributes ); |
867 | 892 | QgsFeatureIterator it = mLayerCache->getFeatures( request );
|
868 | 893 |
|
869 | 894 | QgsFeature f;
|
870 | 895 | while ( it.nextFeature( f ) )
|
871 | 896 | {
|
872 |
| - if ( mSortFieldIndex == -1 ) |
| 897 | + if ( cache.sortFieldIndex == -1 ) |
873 | 898 | {
|
874 | 899 | mExpressionContext.setFeature( f );
|
875 |
| - mSortCache.insert( f.id(), mSortCacheExpression.evaluate( &mExpressionContext ) ); |
| 900 | + cache.sortCache.insert( f.id(), cache.sortCacheExpression.evaluate( &mExpressionContext ) ); |
876 | 901 | }
|
877 | 902 | else
|
878 | 903 | {
|
879 |
| - QVariant sortValue = fieldFormatter->sortValue( layer(), mSortFieldIndex, widgetConfig, widgetCache, f.attribute( mSortFieldIndex ) ); |
880 |
| - mSortCache.insert( f.id(), sortValue ); |
| 904 | + QVariant sortValue = fieldFormatter->sortValue( layer(), cache.sortFieldIndex, widgetConfig, widgetCache, f.attribute( cache.sortFieldIndex ) ); |
| 905 | + cache.sortCache.insert( f.id(), sortValue ); |
881 | 906 | }
|
882 | 907 | }
|
883 | 908 | }
|
884 | 909 |
|
885 | 910 | QString QgsAttributeTableModel::sortCacheExpression() const
|
886 | 911 | {
|
887 |
| - if ( mSortCacheExpression.isValid() ) |
888 |
| - return mSortCacheExpression.expression(); |
| 912 | + Q_ASSERT( !mSortCaches.empty() ); |
| 913 | + |
| 914 | + QString expressionString; |
| 915 | + |
| 916 | + const QgsExpression &expression = mSortCaches.begin()->sortCacheExpression; |
| 917 | + |
| 918 | + if ( expression.isValid() ) |
| 919 | + expressionString = expression.expression(); |
889 | 920 | else
|
890 |
| - return QString(); |
| 921 | + expressionString = QString(); |
| 922 | + |
| 923 | + return expressionString; |
891 | 924 | }
|
892 | 925 |
|
893 | 926 | void QgsAttributeTableModel::setRequest( const QgsFeatureRequest &request )
|
|
0 commit comments