Skip to content

Commit e543ff4

Browse files
authoredMar 7, 2017
Merge pull request #4230 from nyalldawson/cache_table_218
Backport attribute table optimisations from 3.0
2 parents 2a6bceb + 8e875ed commit e543ff4

File tree

10 files changed

+328
-70
lines changed

10 files changed

+328
-70
lines changed
 

‎python/core/qgsvectorlayercache.sip

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,10 @@ class QgsVectorLayerCache : QObject
3333
*/
3434
int cacheSize();
3535

36-
/**
37-
* Enable or disable the caching of geometries
38-
*
39-
* @param cacheGeometry Enable or disable the caching of geometries
40-
*/
4136
void setCacheGeometry( bool cacheGeometry );
4237

38+
bool cacheGeometry() const;
4339

44-
/**
45-
* Set the subset of attributes to be cached
46-
*
47-
* @param attributes The attributes to be cached
48-
*/
4940
void setCacheSubsetOfAttributes( const QgsAttributeList& attributes );
5041

5142
/**

‎python/gui/attributetable/qgsdualview.sip

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,8 @@ class QgsDualView : QStackedWidget
3232
explicit QgsDualView( QWidget* parent /TransferThis/ = 0 );
3333
virtual ~QgsDualView();
3434

35-
/**
36-
* Has to be called to initialize the dual view.
37-
*
38-
* @param layer The layer which should be used to fetch features
39-
* @param mapCanvas The mapCanvas (used for the FilterMode
40-
* {@link QgsAttributeTableFilterModel::ShowVisible}
41-
* @param request Use a modified request to limit the shown features
42-
* @param context The context in which this view is shown
43-
*/
44-
void init( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas, const QgsFeatureRequest& request = QgsFeatureRequest(), const QgsAttributeEditorContext& context = QgsAttributeEditorContext() );
35+
void init( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas, const QgsFeatureRequest& request = QgsFeatureRequest(), const QgsAttributeEditorContext& context = QgsAttributeEditorContext(),
36+
bool loadFeatures = true );
4537

4638
/**
4739
* Change the current view mode.

‎src/app/qgsattributetabledialog.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,10 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
131131
mEditorContext.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() );
132132

133133
QgsFeatureRequest r;
134+
bool needsGeom = false;
135+
QgsAttributeTableFilterModel::FilterMode initialMode = static_cast< QgsAttributeTableFilterModel::FilterMode>( settings.value( QString( "/qgis/attributeTableBehaviour" ), QgsAttributeTableFilterModel::ShowAll ).toInt() );
134136
if ( mLayer->geometryType() != QGis::NoGeometry &&
135-
settings.value( "/qgis/attributeTableBehaviour", QgsAttributeTableFilterModel::ShowAll ).toInt() == QgsAttributeTableFilterModel::ShowVisible )
137+
initialMode == QgsAttributeTableFilterModel::ShowVisible )
136138
{
137139
QgsMapCanvas *mc = QgisApp::instance()->mapCanvas();
138140
QgsRectangle extent( mc->mapSettings().mapToLayerCoordinates( theLayer, mc->extent() ) );
@@ -144,10 +146,18 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
144146
delete g;
145147

146148
mActionShowAllFilter->setText( tr( "Show All Features In Initial Canvas Extent" ) );
149+
needsGeom = true;
147150
}
151+
else if ( initialMode == QgsAttributeTableFilterModel::ShowSelected )
152+
{
153+
if ( theLayer->selectedFeatureCount() > 0 )
154+
r.setFilterFids( theLayer->selectedFeaturesIds() );
155+
}
156+
if ( !needsGeom )
157+
r.setFlags( QgsFeatureRequest::NoGeometry );
148158

149159
// Initialize dual view
150-
mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, mEditorContext );
160+
mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, mEditorContext, false );
151161

152162
QgsAttributeTableConfig config = mLayer->attributeTableConfig();
153163
mMainView->setAttributeTableConfig( config );
@@ -322,7 +332,7 @@ void QgsAttributeTableDialog::updateTitle()
322332
QWidget *w = mDock ? qobject_cast<QWidget*>( mDock ) : qobject_cast<QWidget*>( this );
323333
w->setWindowTitle( tr( " %1 :: Features total: %2, filtered: %3, selected: %4%5" )
324334
.arg( mLayer->name() )
325-
.arg( mMainView->featureCount() )
335+
.arg( qMax( static_cast< long >( mMainView->featureCount() ), mLayer->featureCount() ) ) // layer count may be estimated, so use larger of the two
326336
.arg( mMainView->filteredFeatureCount() )
327337
.arg( mLayer->selectedFeatureCount() )
328338
.arg( mRubberBand ? tr( ", spatially limited" ) : "" )

‎src/core/qgsvectorlayercache.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ int QgsVectorLayerCache::cacheSize()
5858

5959
void QgsVectorLayerCache::setCacheGeometry( bool cacheGeometry )
6060
{
61-
mCacheGeometry = cacheGeometry && mLayer->hasGeometryType();
61+
bool shouldCacheGeometry = cacheGeometry && mLayer->hasGeometryType();
62+
bool mustInvalidate = shouldCacheGeometry && !mCacheGeometry; // going from no geometry -> geometry, so have to clear existing cache entries
63+
mCacheGeometry = shouldCacheGeometry;
6264
if ( cacheGeometry )
6365
{
6466
connect( mLayer, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ), SLOT( geometryChanged( QgsFeatureId, QgsGeometry& ) ) );
@@ -67,6 +69,10 @@ void QgsVectorLayerCache::setCacheGeometry( bool cacheGeometry )
6769
{
6870
disconnect( mLayer, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ), this, SLOT( geometryChanged( QgsFeatureId, QgsGeometry& ) ) );
6971
}
72+
if ( mustInvalidate )
73+
{
74+
invalidate();
75+
}
7076
}
7177

7278
void QgsVectorLayerCache::setCacheSubsetOfAttributes( const QgsAttributeList& attributes )
@@ -231,7 +237,7 @@ void QgsVectorLayerCache::attributeAdded( int field )
231237
{
232238
Q_UNUSED( field )
233239
mCachedAttributes.append( field );
234-
mCache.clear();
240+
invalidate();
235241
}
236242

237243
void QgsVectorLayerCache::attributeDeleted( int field )
@@ -267,6 +273,7 @@ void QgsVectorLayerCache::layerDeleted()
267273
void QgsVectorLayerCache::invalidate()
268274
{
269275
mCache.clear();
276+
mFullCache = false;
270277
emit invalidated();
271278
}
272279

‎src/core/qgsvectorlayercache.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,16 @@ class CORE_EXPORT QgsVectorLayerCache : public QObject
103103
* Enable or disable the caching of geometries
104104
*
105105
* @param cacheGeometry Enable or disable the caching of geometries
106+
* @see cacheGeometry()
106107
*/
107108
void setCacheGeometry( bool cacheGeometry );
108109

110+
/**
111+
* Returns true if the cache will fetch and cache feature geometries.
112+
* @note added in QGIS 3.0
113+
* @see setCacheGeometry()
114+
*/
115+
bool cacheGeometry() const { return mCacheGeometry; }
109116

110117
/**
111118
* Set the subset of attributes to be cached
@@ -131,6 +138,8 @@ class CORE_EXPORT QgsVectorLayerCache : public QObject
131138
* be used for slow data sources, be aware, that the call to this method might take a long time.
132139
*
133140
* @param fullCache True: enable full caching, False: disable full caching
141+
* @note when a cache is invalidated() (e.g. by adding an attribute to a layer) this setting
142+
* is reset. A full cache rebuild must be performed by calling setFullCache( true ) again.
134143
* @see hasFullCache()
135144
*/
136145
void setFullCache( bool fullCache );
@@ -273,7 +282,9 @@ class CORE_EXPORT QgsVectorLayerCache : public QObject
273282
void featureAdded( QgsFeatureId fid );
274283

275284
/**
276-
* The cache has been invalidated and cleared.
285+
* The cache has been invalidated and cleared. Note that when a cache is invalidated
286+
* the fullCache() setting will be cleared, and a full cache rebuild via setFullCache( true )
287+
* will need to be performed.
277288
*/
278289
void invalidated();
279290

0 commit comments

Comments
 (0)