Skip to content
Permalink
Browse files

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
  • Loading branch information
nyalldawson committed Mar 5, 2017
1 parent 8a050de commit 4d8f886b389dee83d35d26fae22951df9544828c
@@ -134,8 +134,9 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QWidget

QgsFeatureRequest r;
bool needsGeom = false;
QgsAttributeTableFilterModel::FilterMode initialMode = static_cast< QgsAttributeTableFilterModel::FilterMode>( settings.value( QStringLiteral( "/qgis/attributeTableBehavior" ), QgsAttributeTableFilterModel::ShowAll ).toInt() );
if ( mLayer->geometryType() != QgsWkbTypes::NullGeometry &&
settings.value( QStringLiteral( "/qgis/attributeTableBehavior" ), QgsAttributeTableFilterModel::ShowAll ).toInt() == QgsAttributeTableFilterModel::ShowVisible )
initialMode == QgsAttributeTableFilterModel::ShowVisible )
{
QgsMapCanvas *mc = QgisApp::instance()->mapCanvas();
QgsRectangle extent( mc->mapSettings().mapToLayerCoordinates( layer, mc->extent() ) );
@@ -147,6 +148,11 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *layer, QWidget
mActionShowAllFilter->setText( tr( "Show All Features In Initial Canvas Extent" ) );
needsGeom = true;
}
else if ( initialMode == QgsAttributeTableFilterModel::ShowSelected )
{
if ( theLayer->selectedFeatureCount() > 0 )
r.setFilterFids( theLayer->selectedFeatureIds() );
}
if ( !needsGeom )
r.setFlags( QgsFeatureRequest::NoGeometry );

@@ -70,6 +70,8 @@ QgsDualView::QgsDualView( QWidget *parent )

void QgsDualView::init( QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const QgsFeatureRequest &request, const QgsAttributeEditorContext &context )
{
mMapCanvas = mapCanvas;

if ( !layer )
return;

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

void QgsDualView::setFilterMode( QgsAttributeTableFilterModel::FilterMode filterMode )
{
bool needsGeometry = filterMode == QgsAttributeTableFilterModel::ShowVisible;
if ( mFilterModel->filterMode() == filterMode )
return;

// cleanup any existing connections
switch ( mFilterModel->filterMode() )
{
case QgsAttributeTableFilterModel::ShowVisible:
disconnect( mMapCanvas, &QgsMapCanvas::extentsChanged, this, &QgsDualView::extentChanged );
break;

case QgsAttributeTableFilterModel::ShowAll:
case QgsAttributeTableFilterModel::ShowEdited:
case QgsAttributeTableFilterModel::ShowFilteredList:
break;

case QgsAttributeTableFilterModel::ShowSelected:
disconnect( masterModel()->layer(), &QgsVectorLayer::selectionChanged, this, &QgsDualView::updateSelectedFeatures );
break;
}

QgsFeatureRequest r = mMasterModel->request();
bool needsGeometry = filterMode == QgsAttributeTableFilterModel::ShowVisible;

if ( !needsGeometry )
r.setFlags( r.flags() | QgsFeatureRequest::NoGeometry );
else
r.setFlags( r.flags() & ~( QgsFeatureRequest::NoGeometry ) );

switch ( filterMode )
{
case QgsAttributeTableFilterModel::ShowVisible:
connect( mMapCanvas, &QgsMapCanvas::extentsChanged, this, &QgsDualView::extentChanged );
r.setFilterFids( QgsFeatureIds() );
r.disableFilter();
if ( mMapCanvas )
{
QgsRectangle rect = mMapCanvas->mapSettings().mapToLayerCoordinates( mLayer, mMapCanvas->extent() );
r.setFilterRect( rect );
}
break;

case QgsAttributeTableFilterModel::ShowAll:
case QgsAttributeTableFilterModel::ShowEdited:
case QgsAttributeTableFilterModel::ShowFilteredList:
r.setFilterFids( QgsFeatureIds() );
r.disableFilter();
break;

case QgsAttributeTableFilterModel::ShowSelected:
connect( masterModel()->layer(), &QgsVectorLayer::selectionChanged, this, &QgsDualView::updateSelectedFeatures );
if ( masterModel()->layer()->selectedFeatureCount() > 0 )
r.setFilterFids( masterModel()->layer()->selectedFeatureIds() );
else
r.disableFilter();
break;
}

mMasterModel->setRequest( r );
whileBlocking( mLayerCache )->setCacheGeometry( needsGeometry );
mMasterModel->loadLayer();

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

void QgsDualView::updateSelectedFeatures()
{
QgsFeatureRequest r = mMasterModel->request();
if ( masterModel()->layer()->selectedFeatureCount() > 0 )
r.setFilterFids( masterModel()->layer()->selectedFeatureIds() );
else
r.disableFilter();
mMasterModel->setRequest( r );
mMasterModel->loadLayer();
}

void QgsDualView::extentChanged()
{
QgsFeatureRequest r = mMasterModel->request();
if ( mMapCanvas )
{
QgsRectangle rect = mMapCanvas->mapSettings().mapToLayerCoordinates( mLayer, mMapCanvas->extent() );
r.setFilterRect( rect );
}
mMasterModel->setRequest( r );
mMasterModel->loadLayer();
}

void QgsDualView::featureFormAttributeChanged()
{
mFeatureList->setCurrentFeatureEdited( true );
@@ -297,6 +297,10 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas

void sortByPreviewExpression();

void updateSelectedFeatures();

void extentChanged();

/**
* Will be called whenever the currently shown feature form changes.
* Will forward this signal to the feature list to visually represent
@@ -343,6 +347,7 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
QString mDisplayExpression;
QgsAttributeTableConfig mConfig;
QScrollArea *mAttributeEditorScrollArea = nullptr;
QgsMapCanvas *mMapCanvas = nullptr;

friend class TestQgsDualView;
};

0 comments on commit 4d8f886

Please sign in to comment.
You can’t perform that action at this time.