Skip to content
Permalink
Browse files

restore option to open the attribute table with only currently visibl…

…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 86d08b6c39bad37e4c9b468f55c4c60981b60fa2
@@ -42,6 +42,7 @@
#include "qgsexpressionselectiondialog.h"
#include "qgsfeaturelistmodel.h"
#include "qgsexpressionbuilderdialog.h"
#include "qgsrubberband.h"

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

@@ -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 );
@@ -215,6 +230,7 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
QgsAttributeTableDialog::~QgsAttributeTableDialog()
{
delete myDa;
delete mRubberBand;
}

void QgsAttributeTableDialog::updateTitle()
@@ -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 )
@@ -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;
@@ -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 )
{
@@ -40,6 +40,7 @@ class QSignalMapper;

class QgsAttributeTableModel;
class QgsAttributeTableFilterModel;
class QgsRubberBand;

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

QgsVectorLayer* mLayer;
QgsFieldModel* mFieldModel;

QgsRubberBand *mRubberBand;
};

#endif
@@ -1490,7 +1490,6 @@ void QgsIdentifyResultsDialog::highlightFeature( QTreeWidgetItem *item )
if ( !featItem )
return;


if ( mHighlights.contains( featItem ) )
return;

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

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

@@ -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 ) )
@@ -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;
}
@@ -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.
@@ -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 );
@@ -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 & ) ) );
@@ -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;
@@ -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 )

0 comments on commit 86d08b6

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