Ensure both attribute table cache & master model request respect

geometry fetching

If request needs geometry but cache isn't fetching it then cache
is bypassed. This is a performance hit, so ensure that cache
and request are always in sync wrt to fetching geoms.

On behalf of Faunalia, sponsored by ENEL
This commit is contained in:
Nyall Dawson 2017-02-20 15:18:14 +10:00
parent 5b0e84a38e
commit dadd6133e0
4 changed files with 40 additions and 11 deletions

View File

@ -33,19 +33,10 @@ class QgsVectorLayerCache : QObject
*/
int cacheSize();
/**
* Enable or disable the caching of geometries
*
* @param cacheGeometry Enable or disable the caching of geometries
*/
void setCacheGeometry( bool cacheGeometry );
bool cacheGeometry() const;
/**
* Set the subset of attributes to be cached
*
* @param attributes The attributes to be cached
*/
void setCacheSubsetOfAttributes( const QgsAttributeList& attributes );
/**

View File

@ -106,9 +106,16 @@ class CORE_EXPORT QgsVectorLayerCache : public QObject
* Enable or disable the caching of geometries
*
* @param cacheGeometry Enable or disable the caching of geometries
* @see cacheGeometry()
*/
void setCacheGeometry( bool cacheGeometry );
/**
* Returns true if the cache will fetch and cache feature geometries.
* @note added in QGIS 3.0
* @see setCacheGeometry()
*/
bool cacheGeometry() const { return mCacheGeometry; }
/**
* Set the subset of attributes to be cached

View File

@ -82,7 +82,7 @@ void QgsDualView::init( QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const Qg
connect( mTableView->horizontalHeader(), &QHeaderView::customContextMenuRequested, this, &QgsDualView::showViewHeaderMenu );
connect( mTableView, &QgsAttributeTableView::columnResized, this, &QgsDualView::tableColumnResized );
initLayerCache( !request.filterRect().isNull() );
initLayerCache( !( request.flags() & QgsFeatureRequest::NoGeometry ) || !request.filterRect().isNull() );
initModels( mapCanvas, request );
mConditionalFormatWidget->setLayer( mLayer );

View File

@ -56,6 +56,7 @@ class TestQgsDualView : public QObject
void testSort();
void testAttributeFormSharedValueScanning();
void testNoGeom();
private:
QgsMapCanvas *mCanvas = nullptr;
@ -270,5 +271,35 @@ void TestQgsDualView::testAttributeFormSharedValueScanning()
QVERIFY( mixedValueFields.isEmpty() );
}
void TestQgsDualView::testNoGeom()
{
//test that both the master model and cache for the dual view either both request geom or both don't request geom
std::unique_ptr< QgsDualView > dv( new QgsDualView() );
// request with geometry
QgsFeatureRequest req;
dv->init( mPointsLayer, mCanvas, req );
// check that both master model AND cache are using geometry
QgsAttributeTableModel* model = dv->masterModel();
QVERIFY( model->layerCache()->cacheGeometry() );
QVERIFY( !( model->request().flags() & QgsFeatureRequest::NoGeometry ) );
// request with NO geometry, but using filter rect (which should override and request geom)
req = QgsFeatureRequest().setFilterRect( QgsRectangle( 1, 2, 3, 4 ) );
dv.reset( new QgsDualView() );
dv->init( mPointsLayer, mCanvas, req );
model = dv->masterModel();
QVERIFY( model->layerCache()->cacheGeometry() );
QVERIFY( !( model->request().flags() & QgsFeatureRequest::NoGeometry ) );
// request with NO geometry
req = QgsFeatureRequest().setFlags( QgsFeatureRequest::NoGeometry );
dv.reset( new QgsDualView() );
dv->init( mPointsLayer, mCanvas, req );
model = dv->masterModel();
QVERIFY( !model->layerCache()->cacheGeometry() );
QVERIFY(( model->request().flags() & QgsFeatureRequest::NoGeometry ) );
}
QGSTEST_MAIN( TestQgsDualView )
#include "testqgsdualview.moc"