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

(cherry-picked from 4d8f886)
  • Loading branch information
nyalldawson committed Mar 7, 2017
1 parent 9365673 commit 9bbd593cc2d4f2916c397ecb34e43e2b585b3193
@@ -132,8 +132,9 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid

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

@@ -48,6 +48,7 @@ QgsDualView::QgsDualView( QWidget* parent )
, mProgressDlg( nullptr )
, mFeatureSelectionManager( nullptr )
, mAttributeEditorScrollArea( nullptr )
, mMapCanvas( nullptr )
{
setupUi( this );

@@ -69,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;

@@ -235,15 +238,67 @@ 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, SIGNAL(extentsChanged()), this, SLOT(extentChanged()) );
break;

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

case QgsAttributeTableFilterModel::ShowSelected:
disconnect( masterModel()->layer(), SIGNAL(selectionChanged()), this,
SLOT(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, SIGNAL(extentsChanged()), this, SLOT(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(), SIGNAL(selectionChanged()), this, SLOT(updateSelectedFeatures()) );
if ( masterModel()->layer()->selectedFeatureCount() > 0 )
r.setFilterFids( masterModel()->layer()->selectedFeaturesIds() );
else
r.disableFilter();
break;
}

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

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

void QgsDualView::updateSelectedFeatures()
{
QgsFeatureRequest r = mMasterModel->request();
if ( masterModel()->layer()->selectedFeatureCount() > 0 )
r.setFilterFids( masterModel()->layer()->selectedFeaturesIds() );
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 );
@@ -294,6 +294,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
@@ -338,6 +342,7 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
QString mDisplayExpression;
QgsAttributeTableConfig mConfig;
QScrollArea* mAttributeEditorScrollArea;
QgsMapCanvas *mMapCanvas;

friend class TestQgsDualView;
};

0 comments on commit 9bbd593

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