Skip to content

Commit

Permalink
restore option to open the attribute table with only currently visibl…
Browse files Browse the repository at this point in the history
…e features

to improve performance (actually to make it usable with large tables again).

When used as initial setting in options the open attribute table will have a
fixed spatial filter to the canvas extent when it was opened.  That extent is
also highlighted to indicate the filter.

fixes #10619
  • Loading branch information
jef-n committed Feb 14, 2015
1 parent 553abbd commit 86d08b6
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 16 deletions.
29 changes: 22 additions & 7 deletions src/app/qgsattributetabledialog.cpp
Expand Up @@ -42,6 +42,7 @@
#include "qgsexpressionselectiondialog.h" #include "qgsexpressionselectiondialog.h"
#include "qgsfeaturelistmodel.h" #include "qgsfeaturelistmodel.h"
#include "qgsexpressionbuilderdialog.h" #include "qgsexpressionbuilderdialog.h"
#include "qgsrubberband.h"


class QgsAttributeTableDock : public QDockWidget class QgsAttributeTableDock : public QDockWidget
{ {
Expand All @@ -63,6 +64,7 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
: QDialog( parent, flags ) : QDialog( parent, flags )
, mDock( 0 ) , mDock( 0 )
, mLayer( theLayer ) , mLayer( theLayer )
, mRubberBand( 0 )
{ {
setupUi( this ); setupUi( this );


Expand All @@ -87,8 +89,21 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
context.setDistanceArea( *myDa ); context.setDistanceArea( *myDa );
context.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() ); context.setVectorLayerTools( QgisApp::instance()->vectorLayerTools() );


QgsFeatureRequest r;
if ( settings.value( "/qgis/attributeTableBehaviour", QgsAttributeTableFilterModel::ShowAll ).toInt() == QgsAttributeTableFilterModel::ShowVisible )
{
QgsMapCanvas *mc = QgisApp::instance()->mapCanvas();
QgsRectangle extent( mc->mapSettings().mapToLayerCoordinates( theLayer, mc->extent() ) );
r.setFilterRect( extent );

QgsGeometry *g = QgsGeometry::fromRect( extent );
mRubberBand = new QgsRubberBand( mc, true );
mRubberBand->setToGeometry( g, theLayer );
delete g;
}

// Initialize dual view // Initialize dual view
mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), QgsFeatureRequest(), context ); mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, context );


// Initialize filter gui elements // Initialize filter gui elements
mFilterActionMapper = new QSignalMapper( this ); mFilterActionMapper = new QSignalMapper( this );
Expand Down Expand Up @@ -215,6 +230,7 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
QgsAttributeTableDialog::~QgsAttributeTableDialog() QgsAttributeTableDialog::~QgsAttributeTableDialog()
{ {
delete myDa; delete myDa;
delete mRubberBand;
} }


void QgsAttributeTableDialog::updateTitle() void QgsAttributeTableDialog::updateTitle()
Expand Down Expand Up @@ -305,19 +321,17 @@ void QgsAttributeTableDialog::columnBoxInit()
} }
} }



void QgsAttributeTableDialog::updateFieldFromExpression() void QgsAttributeTableDialog::updateFieldFromExpression()
{ {

bool filtered = mMainView->filterMode() != QgsAttributeTableFilterModel::ShowAll; bool filtered = mMainView->filterMode() != QgsAttributeTableFilterModel::ShowAll;
QgsFeatureIds filteredIds = filtered ? mMainView->filteredFeatures() : QgsFeatureIds(); QgsFeatureIds filteredIds = filtered ? mMainView->filteredFeatures() : QgsFeatureIds();
this->runFieldCalculation( mLayer, mFieldCombo->currentText(), mUpdateExpressionText->currentField(), filteredIds ); runFieldCalculation( mLayer, mFieldCombo->currentText(), mUpdateExpressionText->currentField(), filteredIds );
} }


void QgsAttributeTableDialog::updateFieldFromExpressionSelected() void QgsAttributeTableDialog::updateFieldFromExpressionSelected()
{ {
QgsFeatureIds filteredIds = mLayer->selectedFeaturesIds(); QgsFeatureIds filteredIds = mLayer->selectedFeaturesIds();
this->runFieldCalculation( mLayer, mFieldCombo->currentText(), mUpdateExpressionText->currentField(), filteredIds ); runFieldCalculation( mLayer, mFieldCombo->currentText(), mUpdateExpressionText->currentField(), filteredIds );
} }


void QgsAttributeTableDialog::runFieldCalculation( QgsVectorLayer* layer, QString fieldName, QString expression, QgsFeatureIds filteredIds ) void QgsAttributeTableDialog::runFieldCalculation( QgsVectorLayer* layer, QString fieldName, QString expression, QgsFeatureIds filteredIds )
Expand All @@ -336,7 +350,8 @@ void QgsAttributeTableDialog::runFieldCalculation( QgsVectorLayer* layer, QStrin
exp.setGeomCalculator( *myDa ); exp.setGeomCalculator( *myDa );
bool useGeometry = exp.needsGeometry(); bool useGeometry = exp.needsGeometry();


QgsFeatureRequest request; QgsFeatureRequest request( mMainView->masterModel()->request() );
useGeometry |= request.filterType() == QgsFeatureRequest::FilterRect;
request.setFlags( useGeometry ? QgsFeatureRequest::NoFlags : QgsFeatureRequest::NoGeometry ); request.setFlags( useGeometry ? QgsFeatureRequest::NoFlags : QgsFeatureRequest::NoGeometry );


int rownum = 1; int rownum = 1;
Expand Down Expand Up @@ -736,7 +751,7 @@ void QgsAttributeTableDialog::setFilterExpression( QString filterString )
QApplication::setOverrideCursor( Qt::WaitCursor ); QApplication::setOverrideCursor( Qt::WaitCursor );


filterExpression.setGeomCalculator( myDa ); filterExpression.setGeomCalculator( myDa );
QgsFeatureRequest request; QgsFeatureRequest request( mMainView->masterModel()->request() );
request.setSubsetOfAttributes( filterExpression.referencedColumns(), mLayer->pendingFields() ); request.setSubsetOfAttributes( filterExpression.referencedColumns(), mLayer->pendingFields() );
if ( !fetchGeom ) if ( !fetchGeom )
{ {
Expand Down
3 changes: 3 additions & 0 deletions src/app/qgsattributetabledialog.h
Expand Up @@ -40,6 +40,7 @@ class QSignalMapper;


class QgsAttributeTableModel; class QgsAttributeTableModel;
class QgsAttributeTableFilterModel; class QgsAttributeTableFilterModel;
class QgsRubberBand;


class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttributeTableDialog class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttributeTableDialog
{ {
Expand Down Expand Up @@ -201,6 +202,8 @@ class APP_EXPORT QgsAttributeTableDialog : public QDialog, private Ui::QgsAttrib


QgsVectorLayer* mLayer; QgsVectorLayer* mLayer;
QgsFieldModel* mFieldModel; QgsFieldModel* mFieldModel;

QgsRubberBand *mRubberBand;
}; };


#endif #endif
1 change: 0 additions & 1 deletion src/app/qgsidentifyresultsdialog.cpp
Expand Up @@ -1490,7 +1490,6 @@ void QgsIdentifyResultsDialog::highlightFeature( QTreeWidgetItem *item )
if ( !featItem ) if ( !featItem )
return; return;



if ( mHighlights.contains( featItem ) ) if ( mHighlights.contains( featItem ) )
return; return;


Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsvectorlayercache.cpp
Expand Up @@ -85,7 +85,7 @@ void QgsVectorLayerCache::setFullCache( bool fullCache )
// Initialize the cache... // Initialize the cache...
QgsFeatureIterator it( new QgsCachedFeatureWriterIterator( this, QgsFeatureRequest() QgsFeatureIterator it( new QgsCachedFeatureWriterIterator( this, QgsFeatureRequest()
.setSubsetOfAttributes( mCachedAttributes ) .setSubsetOfAttributes( mCachedAttributes )
.setFlags( !mCacheGeometry ? QgsFeatureRequest::NoGeometry : QgsFeatureRequest::Flags( 0 ) ) ) ); .setFlags( mCacheGeometry ? QgsFeatureRequest::NoFlags : QgsFeatureRequest::NoGeometry ) ) );


int i = 0; int i = 0;


Expand Down
11 changes: 10 additions & 1 deletion src/gui/attributetable/qgsattributetablefiltermodel.cpp
Expand Up @@ -265,7 +265,16 @@ void QgsAttributeTableFilterModel::generateListOfVisibleFeatures()


renderer->startRender( renderContext, layer()->pendingFields() ); renderer->startRender( renderContext, layer()->pendingFields() );


QgsFeatureIterator features = masterModel()->layerCache()->getFeatures( QgsFeatureRequest().setFilterRect( rect ) ); QgsFeatureRequest r( masterModel()->request() );
if ( r.filterType() == QgsFeatureRequest::FilterRect )
{
r.setFilterRect( r.filterRect().intersect( &rect ) );
}
else
{
r.setFilterRect( rect );
}
QgsFeatureIterator features = masterModel()->layerCache()->getFeatures( r );


QgsFeature f; QgsFeature f;


Expand Down
8 changes: 7 additions & 1 deletion src/gui/attributetable/qgsattributetablemodel.cpp
Expand Up @@ -620,7 +620,8 @@ void QgsAttributeTableModel::prefetchColumnData( int column )
QStringList fldNames; QStringList fldNames;
fldNames << fields[ fieldId ].name(); fldNames << fields[ fieldId ].name();


QgsFeatureIterator it = mLayerCache->getFeatures( QgsFeatureRequest().setFlags( QgsFeatureRequest::NoGeometry ).setSubsetOfAttributes( fldNames, fields ) ); QgsFeatureRequest r( mFeatureRequest );
QgsFeatureIterator it = mLayerCache->getFeatures( r.setFlags( QgsFeatureRequest::NoGeometry ).setSubsetOfAttributes( fldNames, fields ) );


QgsFeature f; QgsFeature f;
while ( it.nextFeature( f ) ) while ( it.nextFeature( f ) )
Expand All @@ -638,3 +639,8 @@ void QgsAttributeTableModel::setRequest( const QgsFeatureRequest& request )
if ( layer() && !layer()->hasGeometryType() ) if ( layer() && !layer()->hasGeometryType() )
mFeatureRequest.setFlags( mFeatureRequest.flags() | QgsFeatureRequest::NoGeometry ); mFeatureRequest.setFlags( mFeatureRequest.flags() | QgsFeatureRequest::NoGeometry );
} }

const QgsFeatureRequest &QgsAttributeTableModel::request() const
{
return mFeatureRequest;
}
5 changes: 5 additions & 0 deletions src/gui/attributetable/qgsattributetablemodel.h
Expand Up @@ -203,6 +203,11 @@ class GUI_EXPORT QgsAttributeTableModel: public QAbstractTableModel
*/ */
void setRequest( const QgsFeatureRequest& request ); void setRequest( const QgsFeatureRequest& request );


/**
* Get the the feature request
*/
const QgsFeatureRequest &request() const;

/** /**
* Sets the context in which this table is shown. * Sets the context in which this table is shown.
* Will be forwarded to any editor widget created when editing data on this model. * Will be forwarded to any editor widget created when editing data on this model.
Expand Down
6 changes: 3 additions & 3 deletions src/gui/attributetable/qgsdualview.cpp
Expand Up @@ -66,7 +66,7 @@ void QgsDualView::init( QgsVectorLayer* layer, QgsMapCanvas* mapCanvas, const Qg


connect( mTableView, SIGNAL( willShowContextMenu( QMenu*, QModelIndex ) ), this, SLOT( viewWillShowContextMenu( QMenu*, QModelIndex ) ) ); connect( mTableView, SIGNAL( willShowContextMenu( QMenu*, QModelIndex ) ), this, SLOT( viewWillShowContextMenu( QMenu*, QModelIndex ) ) );


initLayerCache( layer ); initLayerCache( layer, request.filterType() == QgsFeatureRequest::FilterRect );
initModels( mapCanvas, request ); initModels( mapCanvas, request );


mTableView->setModel( mFilterModel ); mTableView->setModel( mFilterModel );
Expand Down Expand Up @@ -205,13 +205,13 @@ void QgsDualView::setSelectedOnTop( bool selectedOnTop )
mFilterModel->setSelectedOnTop( selectedOnTop ); mFilterModel->setSelectedOnTop( selectedOnTop );
} }


void QgsDualView::initLayerCache( QgsVectorLayer* layer ) void QgsDualView::initLayerCache( QgsVectorLayer* layer, bool cacheGeometry )
{ {
// Initialize the cache // Initialize the cache
QSettings settings; QSettings settings;
int cacheSize = settings.value( "/qgis/attributeTableRowCache", "10000" ).toInt(); int cacheSize = settings.value( "/qgis/attributeTableRowCache", "10000" ).toInt();
mLayerCache = new QgsVectorLayerCache( layer, cacheSize, this ); mLayerCache = new QgsVectorLayerCache( layer, cacheSize, this );
mLayerCache->setCacheGeometry( false ); mLayerCache->setCacheGeometry( cacheGeometry );
if ( 0 == cacheSize || 0 == ( QgsVectorDataProvider::SelectAtId & mLayerCache->layer()->dataProvider()->capabilities() ) ) if ( 0 == cacheSize || 0 == ( QgsVectorDataProvider::SelectAtId & mLayerCache->layer()->dataProvider()->capabilities() ) )
{ {
connect( mLayerCache, SIGNAL( progress( int, bool & ) ), this, SLOT( progress( int, bool & ) ) ); connect( mLayerCache, SIGNAL( progress( int, bool & ) ), this, SLOT( progress( int, bool & ) ) );
Expand Down
2 changes: 1 addition & 1 deletion src/gui/attributetable/qgsdualview.h
Expand Up @@ -215,7 +215,7 @@ class GUI_EXPORT QgsDualView : public QStackedWidget, private Ui::QgsDualViewBas
virtual void finished(); virtual void finished();


private: private:
void initLayerCache( QgsVectorLayer *layer ); void initLayerCache( QgsVectorLayer *layer, bool cacheGeometry );
void initModels( QgsMapCanvas* mapCanvas, const QgsFeatureRequest& request ); void initModels( QgsMapCanvas* mapCanvas, const QgsFeatureRequest& request );


QgsAttributeEditorContext mEditorContext; QgsAttributeEditorContext mEditorContext;
Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgshighlight.cpp
Expand Up @@ -51,7 +51,7 @@
/*! /*!
\class QgsHighlight \class QgsHighlight
\brief The QgsHighlight class provides a transparent overlay widget \brief The QgsHighlight class provides a transparent overlay widget
for highlightng features on the map. for highlighting features on the map.
*/ */
QgsHighlight::QgsHighlight( QgsMapCanvas* mapCanvas, QgsGeometry *geom, QgsMapLayer *layer ) QgsHighlight::QgsHighlight( QgsMapCanvas* mapCanvas, QgsGeometry *geom, QgsMapLayer *layer )
: QgsMapCanvasItem( mapCanvas ) : QgsMapCanvasItem( mapCanvas )
Expand Down

0 comments on commit 86d08b6

Please sign in to comment.