Skip to content

Commit 4d8f886

Browse files
committedMar 5, 2017
Move partial responsibility for filtering attribute table to
dual view master model This avoids requiring the table to load ALL features when the table is set to just display selected or visible features Dramatically improves load time of the attribute table when working with large layers, so long as the table is set to display selected features or visible features by default On behalf of Faunalia, sponsored by ENEL
1 parent 8a050de commit 4d8f886

File tree

3 files changed

+89
-2
lines changed

3 files changed

+89
-2
lines changed
 

‎src/app/qgsattributetabledialog.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,9 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QWidget
134134

135135
QgsFeatureRequest r;
136136
bool needsGeom = false;
137+
QgsAttributeTableFilterModel::FilterMode initialMode = static_cast< QgsAttributeTableFilterModel::FilterMode>( settings.value( QStringLiteral( "/qgis/attributeTableBehavior" ), QgsAttributeTableFilterModel::ShowAll ).toInt() );
137138
if ( mLayer->geometryType() != QgsWkbTypes::NullGeometry &&
138-
settings.value( QStringLiteral( "/qgis/attributeTableBehavior" ), QgsAttributeTableFilterModel::ShowAll ).toInt() == QgsAttributeTableFilterModel::ShowVisible )
139+
initialMode == QgsAttributeTableFilterModel::ShowVisible )
139140
{
140141
QgsMapCanvas *mc = QgisApp::instance()->mapCanvas();
141142
QgsRectangle extent( mc->mapSettings().mapToLayerCoordinates( layer, mc->extent() ) );
@@ -147,6 +148,11 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QWidget
147148
mActionShowAllFilter->setText( tr( "Show All Features In Initial Canvas Extent" ) );
148149
needsGeom = true;
149150
}
151+
else if ( initialMode == QgsAttributeTableFilterModel::ShowSelected )
152+
{
153+
if ( theLayer->selectedFeatureCount() > 0 )
154+
r.setFilterFids( theLayer->selectedFeatureIds() );
155+
}
150156
if ( !needsGeom )
151157
r.setFlags( QgsFeatureRequest::NoGeometry );
152158

‎src/gui/attributetable/qgsdualview.cpp

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ QgsDualView::QgsDualView( QWidget *parent )
7070

7171
void QgsDualView::init( QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const QgsFeatureRequest &request, const QgsAttributeEditorContext &context )
7272
{
73+
mMapCanvas = mapCanvas;
74+
7375
if ( !layer )
7476
return;
7577

@@ -192,15 +194,66 @@ QgsDualView::ViewMode QgsDualView::view() const
192194

193195
void QgsDualView::setFilterMode( QgsAttributeTableFilterModel::FilterMode filterMode )
194196
{
195-
bool needsGeometry = filterMode == QgsAttributeTableFilterModel::ShowVisible;
197+
if ( mFilterModel->filterMode() == filterMode )
198+
return;
199+
200+
// cleanup any existing connections
201+
switch ( mFilterModel->filterMode() )
202+
{
203+
case QgsAttributeTableFilterModel::ShowVisible:
204+
disconnect( mMapCanvas, &QgsMapCanvas::extentsChanged, this, &QgsDualView::extentChanged );
205+
break;
206+
207+
case QgsAttributeTableFilterModel::ShowAll:
208+
case QgsAttributeTableFilterModel::ShowEdited:
209+
case QgsAttributeTableFilterModel::ShowFilteredList:
210+
break;
211+
212+
case QgsAttributeTableFilterModel::ShowSelected:
213+
disconnect( masterModel()->layer(), &QgsVectorLayer::selectionChanged, this, &QgsDualView::updateSelectedFeatures );
214+
break;
215+
}
196216

197217
QgsFeatureRequest r = mMasterModel->request();
218+
bool needsGeometry = filterMode == QgsAttributeTableFilterModel::ShowVisible;
219+
198220
if ( !needsGeometry )
199221
r.setFlags( r.flags() | QgsFeatureRequest::NoGeometry );
200222
else
201223
r.setFlags( r.flags() & ~( QgsFeatureRequest::NoGeometry ) );
224+
225+
switch ( filterMode )
226+
{
227+
case QgsAttributeTableFilterModel::ShowVisible:
228+
connect( mMapCanvas, &QgsMapCanvas::extentsChanged, this, &QgsDualView::extentChanged );
229+
r.setFilterFids( QgsFeatureIds() );
230+
r.disableFilter();
231+
if ( mMapCanvas )
232+
{
233+
QgsRectangle rect = mMapCanvas->mapSettings().mapToLayerCoordinates( mLayer, mMapCanvas->extent() );
234+
r.setFilterRect( rect );
235+
}
236+
break;
237+
238+
case QgsAttributeTableFilterModel::ShowAll:
239+
case QgsAttributeTableFilterModel::ShowEdited:
240+
case QgsAttributeTableFilterModel::ShowFilteredList:
241+
r.setFilterFids( QgsFeatureIds() );
242+
r.disableFilter();
243+
break;
244+
245+
case QgsAttributeTableFilterModel::ShowSelected:
246+
connect( masterModel()->layer(), &QgsVectorLayer::selectionChanged, this, &QgsDualView::updateSelectedFeatures );
247+
if ( masterModel()->layer()->selectedFeatureCount() > 0 )
248+
r.setFilterFids( masterModel()->layer()->selectedFeatureIds() );
249+
else
250+
r.disableFilter();
251+
break;
252+
}
253+
202254
mMasterModel->setRequest( r );
203255
whileBlocking( mLayerCache )->setCacheGeometry( needsGeometry );
256+
mMasterModel->loadLayer();
204257

205258
mFilterModel->setFilterMode( filterMode );
206259
emit filterChanged();
@@ -649,6 +702,29 @@ void QgsDualView::sortByPreviewExpression()
649702
setSortExpression( mFeatureList->displayExpression(), sortOrder );
650703
}
651704

705+
void QgsDualView::updateSelectedFeatures()
706+
{
707+
QgsFeatureRequest r = mMasterModel->request();
708+
if ( masterModel()->layer()->selectedFeatureCount() > 0 )
709+
r.setFilterFids( masterModel()->layer()->selectedFeatureIds() );
710+
else
711+
r.disableFilter();
712+
mMasterModel->setRequest( r );
713+
mMasterModel->loadLayer();
714+
}
715+
716+
void QgsDualView::extentChanged()
717+
{
718+
QgsFeatureRequest r = mMasterModel->request();
719+
if ( mMapCanvas )
720+
{
721+
QgsRectangle rect = mMapCanvas->mapSettings().mapToLayerCoordinates( mLayer, mMapCanvas->extent() );
722+
r.setFilterRect( rect );
723+
}
724+
mMasterModel->setRequest( r );
725+
mMasterModel->loadLayer();
726+
}
727+
652728
void QgsDualView::featureFormAttributeChanged()
653729
{
654730
mFeatureList->setCurrentFeatureEdited( true );

‎src/gui/attributetable/qgsdualview.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
297297

298298
void sortByPreviewExpression();
299299

300+
void updateSelectedFeatures();
301+
302+
void extentChanged();
303+
300304
/**
301305
* Will be called whenever the currently shown feature form changes.
302306
* Will forward this signal to the feature list to visually represent
@@ -343,6 +347,7 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
343347
QString mDisplayExpression;
344348
QgsAttributeTableConfig mConfig;
345349
QScrollArea *mAttributeEditorScrollArea = nullptr;
350+
QgsMapCanvas *mMapCanvas = nullptr;
346351

347352
friend class TestQgsDualView;
348353
};

0 commit comments

Comments
 (0)
Please sign in to comment.