Skip to content

Commit dc2f6bb

Browse files
committed
Avoid unnecessary layer reloads for attribute table
On behalf of Faunalia, sponsored by ENEL (cherry-picked from 6cd97d)
1 parent dbd6538 commit dc2f6bb

File tree

4 files changed

+37
-35
lines changed

4 files changed

+37
-35
lines changed

python/gui/attributetable/qgsdualview.sip

+2-10
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

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
157157
r.setFlags( QgsFeatureRequest::NoGeometry );
158158

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

162162
QgsAttributeTableConfig config = mLayer->attributeTableConfig();
163163
mMainView->setAttributeTableConfig( config );

src/gui/attributetable/qgsdualview.cpp

+29-22
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ QgsDualView::QgsDualView( QWidget* parent )
6868
connect( mFeatureList, SIGNAL( displayExpressionChanged( QString ) ), this, SLOT( previewExpressionChanged( QString ) ) );
6969
}
7070

71-
void QgsDualView::init( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas, const QgsFeatureRequest &request, const QgsAttributeEditorContext &context )
71+
void QgsDualView::init( QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const QgsFeatureRequest &request, const QgsAttributeEditorContext &context, bool loadFeatures )
7272
{
7373
mMapCanvas = mapCanvas;
7474

@@ -85,7 +85,7 @@ void QgsDualView::init( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas, const Qg
8585
connect( mTableView, SIGNAL( columnResized( int, int ) ), this, SLOT( tableColumnResized( int, int ) ) );
8686

8787
initLayerCache( !( request.flags() & QgsFeatureRequest::NoGeometry ) || !request.filterRect().isNull() );
88-
initModels( mapCanvas, request );
88+
initModels( mapCanvas, request, loadFeatures );
8989

9090
mConditionalFormatWidget->setLayer( mLayer );
9191

@@ -238,9 +238,6 @@ QgsDualView::ViewMode QgsDualView::view() const
238238

239239
void QgsDualView::setFilterMode( QgsAttributeTableFilterModel::FilterMode filterMode )
240240
{
241-
if ( mFilterModel->filterMode() == filterMode )
242-
return;
243-
244241
// cleanup any existing connections
245242
switch ( mFilterModel->filterMode() )
246243
{
@@ -262,17 +259,23 @@ void QgsDualView::setFilterMode( QgsAttributeTableFilterModel::FilterMode filter
262259
QgsFeatureRequest r = mMasterModel->request();
263260
bool needsGeometry = filterMode == QgsAttributeTableFilterModel::ShowVisible;
264261

262+
bool requiresTableReload = ( r.filterType() != QgsFeatureRequest::FilterNone || !r.filterRect().isNull() ) // previous request was subset
263+
|| ( needsGeometry && r.flags() & QgsFeatureRequest::NoGeometry ) // no geometry for last request
264+
|| ( mMasterModel->rowCount() == 0 ); // no features
265+
265266
if ( !needsGeometry )
266267
r.setFlags( r.flags() | QgsFeatureRequest::NoGeometry );
267268
else
268269
r.setFlags( r.flags() & ~( QgsFeatureRequest::NoGeometry ) );
270+
r.setFilterFids( QgsFeatureIds() );
271+
r.setFilterRect( QgsRectangle() );
272+
r.disableFilter();
269273

274+
// setup new connections and filter request parameters
270275
switch ( filterMode )
271276
{
272277
case QgsAttributeTableFilterModel::ShowVisible:
273278
connect( mMapCanvas, SIGNAL( extentsChanged() ), this, SLOT( extentChanged() ) );
274-
r.setFilterFids( QgsFeatureIds() );
275-
r.disableFilter();
276279
if ( mMapCanvas )
277280
{
278281
QgsRectangle rect = mMapCanvas->mapSettings().mapToLayerCoordinates( mLayer, mMapCanvas->extent() );
@@ -283,23 +286,23 @@ void QgsDualView::setFilterMode( QgsAttributeTableFilterModel::FilterMode filter
283286
case QgsAttributeTableFilterModel::ShowAll:
284287
case QgsAttributeTableFilterModel::ShowEdited:
285288
case QgsAttributeTableFilterModel::ShowFilteredList:
286-
r.setFilterFids( QgsFeatureIds() );
287-
r.disableFilter();
288289
break;
289290

290291
case QgsAttributeTableFilterModel::ShowSelected:
291292
connect( masterModel()->layer(), SIGNAL( selectionChanged() ), this, SLOT( updateSelectedFeatures() ) );
292293
if ( masterModel()->layer()->selectedFeatureCount() > 0 )
293294
r.setFilterFids( masterModel()->layer()->selectedFeaturesIds() );
294-
else
295-
r.disableFilter();
296295
break;
297296
}
298297

299-
mMasterModel->setRequest( r );
300-
whileBlocking( mLayerCache )->setCacheGeometry( needsGeometry );
301-
mMasterModel->loadLayer();
298+
if ( requiresTableReload )
299+
{
300+
mMasterModel->setRequest( r );
301+
whileBlocking( mLayerCache )->setCacheGeometry( needsGeometry );
302+
mMasterModel->loadLayer();
303+
}
302304

305+
//update filter model
303306
mFilterModel->setFilterMode( filterMode );
304307
emit filterChanged();
305308
}
@@ -318,12 +321,12 @@ void QgsDualView::initLayerCache( bool cacheGeometry )
318321
mLayerCache->setCacheGeometry( cacheGeometry );
319322
if ( 0 == cacheSize || 0 == ( QgsVectorDataProvider::SelectAtId & mLayer->dataProvider()->capabilities() ) )
320323
{
321-
connect( mLayerCache, SIGNAL(invalidated()), this, SLOT(rebuildFullLayerCache()) );
324+
connect( mLayerCache, SIGNAL( invalidated() ), this, SLOT( rebuildFullLayerCache() ) );
322325
rebuildFullLayerCache();
323326
}
324327
}
325328

326-
void QgsDualView::initModels( QgsMapCanvas* mapCanvas, const QgsFeatureRequest& request )
329+
void QgsDualView::initModels( QgsMapCanvas *mapCanvas, const QgsFeatureRequest &request, bool loadFeatures )
327330
{
328331
delete mFeatureListModel;
329332
delete mFilterModel;
@@ -339,7 +342,8 @@ void QgsDualView::initModels( QgsMapCanvas* mapCanvas, const QgsFeatureRequest&
339342

340343
connect( mConditionalFormatWidget, SIGNAL( rulesUpdated( QString ) ), mMasterModel, SLOT( fieldConditionalStyleChanged( QString ) ) );
341344

342-
mMasterModel->loadLayer();
345+
if ( loadFeatures )
346+
mMasterModel->loadLayer();
343347

344348
mFilterModel = new QgsAttributeTableFilterModel( mapCanvas, mMasterModel, mMasterModel );
345349

@@ -714,8 +718,8 @@ void QgsDualView::zoomToCurrentFeature()
714718

715719
void QgsDualView::rebuildFullLayerCache()
716720
{
717-
connect( mLayerCache, SIGNAL(progress(int,bool&)), this, SLOT(progress(int,bool&)), Qt::UniqueConnection );
718-
connect( mLayerCache, SIGNAL(finished()), this, SLOT(finished()), Qt::UniqueConnection );
721+
connect( mLayerCache, SIGNAL( progress( int, bool& ) ), this, SLOT( progress( int, bool& ) ), Qt::UniqueConnection );
722+
connect( mLayerCache, SIGNAL( finished() ), this, SLOT( finished() ), Qt::UniqueConnection );
719723

720724
mLayerCache->setFullCache( true );
721725
}
@@ -746,6 +750,9 @@ void QgsDualView::sortByPreviewExpression()
746750
void QgsDualView::updateSelectedFeatures()
747751
{
748752
QgsFeatureRequest r = mMasterModel->request();
753+
if ( r.filterType() == QgsFeatureRequest::FilterNone && r.filterRect().isNull() )
754+
return; // already requested all features
755+
749756
if ( masterModel()->layer()->selectedFeatureCount() > 0 )
750757
r.setFilterFids( masterModel()->layer()->selectedFeaturesIds() );
751758
else
@@ -757,13 +764,13 @@ void QgsDualView::updateSelectedFeatures()
757764
void QgsDualView::extentChanged()
758765
{
759766
QgsFeatureRequest r = mMasterModel->request();
760-
if ( mMapCanvas )
767+
if ( mMapCanvas && ( r.filterType() != QgsFeatureRequest::FilterNone || !r.filterRect().isNull() ) )
761768
{
762769
QgsRectangle rect = mMapCanvas->mapSettings().mapToLayerCoordinates( mLayer, mMapCanvas->extent() );
763770
r.setFilterRect( rect );
771+
mMasterModel->setRequest( r );
772+
mMasterModel->loadLayer();
764773
}
765-
mMasterModel->setRequest( r );
766-
mMasterModel->loadLayer();
767774
}
768775

769776
void QgsDualView::featureFormAttributeChanged()

src/gui/attributetable/qgsdualview.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,11 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
8080
* {@link QgsAttributeTableFilterModel::ShowVisible}
8181
* @param request Use a modified request to limit the shown features
8282
* @param context The context in which this view is shown
83+
* @param loadFeatures whether to initially load all features into the view. If set to
84+
* false, limited features can later be loaded using setFilterMode()
8385
*/
84-
void init( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas, const QgsFeatureRequest& request = QgsFeatureRequest(), const QgsAttributeEditorContext& context = QgsAttributeEditorContext() );
86+
void init( QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const QgsFeatureRequest &request = QgsFeatureRequest(), const QgsAttributeEditorContext &context = QgsAttributeEditorContext(),
87+
bool loadFeatures = true );
8588

8689
/**
8790
* Change the current view mode.
@@ -326,7 +329,7 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
326329

327330
private:
328331
void initLayerCache( bool cacheGeometry );
329-
void initModels( QgsMapCanvas* mapCanvas, const QgsFeatureRequest& request );
332+
void initModels( QgsMapCanvas* mapCanvas, const QgsFeatureRequest& request, bool loadFeatures );
330333

331334
QgsAttributeEditorContext mEditorContext;
332335
QgsAttributeTableModel* mMasterModel;

0 commit comments

Comments
 (0)