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 "qgsfeaturelistmodel.h"
#include "qgsexpressionbuilderdialog.h"
#include "qgsrubberband.h"

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

Expand All @@ -87,8 +89,21 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
context.setDistanceArea( *myDa );
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
mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), QgsFeatureRequest(), context );
mMainView->init( mLayer, QgisApp::instance()->mapCanvas(), r, context );

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

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


void QgsAttributeTableDialog::updateFieldFromExpression()
{

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

void QgsAttributeTableDialog::updateFieldFromExpressionSelected()
{
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 )
Expand All @@ -336,7 +350,8 @@ void QgsAttributeTableDialog::runFieldCalculation( QgsVectorLayer* layer, QStrin
exp.setGeomCalculator( *myDa );
bool useGeometry = exp.needsGeometry();

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

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

filterExpression.setGeomCalculator( myDa );
QgsFeatureRequest request;
QgsFeatureRequest request( mMainView->masterModel()->request() );
request.setSubsetOfAttributes( filterExpression.referencedColumns(), mLayer->pendingFields() );
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 QgsAttributeTableFilterModel;
class QgsRubberBand;

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;
QgsFieldModel* mFieldModel;

QgsRubberBand *mRubberBand;
};

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


if ( mHighlights.contains( featItem ) )
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...
QgsFeatureIterator it( new QgsCachedFeatureWriterIterator( this, QgsFeatureRequest()
.setSubsetOfAttributes( mCachedAttributes )
.setFlags( !mCacheGeometry ? QgsFeatureRequest::NoGeometry : QgsFeatureRequest::Flags( 0 ) ) ) );
.setFlags( mCacheGeometry ? QgsFeatureRequest::NoFlags : QgsFeatureRequest::NoGeometry ) ) );

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() );

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;

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;
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;
while ( it.nextFeature( f ) )
Expand All @@ -638,3 +639,8 @@ void QgsAttributeTableModel::setRequest( const QgsFeatureRequest& request )
if ( layer() && !layer()->hasGeometryType() )
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 );

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

/**
* Sets the context in which this table is shown.
* 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 ) ) );

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

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

void QgsDualView::initLayerCache( QgsVectorLayer* layer )
void QgsDualView::initLayerCache( QgsVectorLayer* layer, bool cacheGeometry )
{
// Initialize the cache
QSettings settings;
int cacheSize = settings.value( "/qgis/attributeTableRowCache", "10000" ).toInt();
mLayerCache = new QgsVectorLayerCache( layer, cacheSize, this );
mLayerCache->setCacheGeometry( false );
mLayerCache->setCacheGeometry( cacheGeometry );
if ( 0 == cacheSize || 0 == ( QgsVectorDataProvider::SelectAtId & mLayerCache->layer()->dataProvider()->capabilities() ) )
{
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();

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

QgsAttributeEditorContext mEditorContext;
Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgshighlight.cpp
Expand Up @@ -51,7 +51,7 @@
/*!
\class QgsHighlight
\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 )
: QgsMapCanvasItem( mapCanvas )
Expand Down

0 comments on commit 86d08b6

Please sign in to comment.