Fix support for setCacheImage() to enforce refresh of a layer

This commit is contained in:
Martin Dobias 2014-03-25 18:55:51 +01:00
parent f53576dd96
commit 9e42c5bc7f
8 changed files with 74 additions and 37 deletions

View File

@ -209,12 +209,12 @@ class QgsMapLayer : QObject
Layer definitions can be used to load a layer and styling all from a single file.
*/
QDomDocument asLayerDefinition ( );
QDomDocument asLayerDefinition( );
/** Creates a new layer from a layer defininition document
*/
static QgsMapLayer* fromLayerDefinition( QDomDocument& document );
static QgsMapLayer* fromLayerDefinitionFile(const QString qlrfile );
static QgsMapLayer* fromLayerDefinitionFile( const QString qlrfile );
/** Set a custom property for layer. Properties are stored in a map and saved in project file.
* @note Added in v1.4 */
@ -355,7 +355,7 @@ class QgsMapLayer : QObject
/** @deprecated since 2.4 - returns NULL */
QImage *cacheImage() /Deprecated/;
/** @deprecated since 2.4 - does nothing */
/** @deprecated since 2.4 - caches listen to repaintRequested() signal to invalidate the cached image */
void setCacheImage( QImage * thepImage /Transfer/ ) /Deprecated/;
/** @deprecated since 2.4 - does nothing */
virtual void onCacheImageDelete() /Deprecated/;
@ -377,7 +377,8 @@ class QgsMapLayer : QObject
void toggleScaleBasedVisibility( bool theVisibilityFlag );
bool hasScaleBasedVisibility() const;
/** @deprecated since 2.4 - does nothing */
/** Clear cached image
* @deprecated in 2.4 - caches listen to repaintRequested() signal to invalidate the cached image */
void clearCacheImage() /Deprecated/;
/** \brief Obtain Metadata for this layer */

View File

@ -1402,8 +1402,14 @@ void QgsMapLayer::setValid( bool valid )
mValid = valid;
}
void QgsMapLayer::setCacheImage( QImage * )
{
emit repaintRequested();
}
void QgsMapLayer::clearCacheImage()
{
emit repaintRequested();
}
QString QgsMapLayer::metadata()

View File

@ -222,12 +222,12 @@ class CORE_EXPORT QgsMapLayer : public QObject
Layer definitions can be used to load a layer and styling all from a single file.
*/
QDomDocument asLayerDefinition ( );
QDomDocument asLayerDefinition( );
/** Creates a new layer from a layer defininition document
*/
static QgsMapLayer* fromLayerDefinition( QDomDocument& document );
static QgsMapLayer* fromLayerDefinitionFile(const QString qlrfile );
static QgsMapLayer* fromLayerDefinitionFile( const QString qlrfile );
/** Set a custom property for layer. Properties are stored in a map and saved in project file.
* @note Added in v1.4 */
@ -370,8 +370,8 @@ class CORE_EXPORT QgsMapLayer : public QObject
/** @deprecated since 2.4 - returns NULL */
Q_DECL_DEPRECATED QImage *cacheImage() { return 0; }
/** @deprecated since 2.4 - does nothing */
Q_DECL_DEPRECATED void setCacheImage( QImage * ) {}
/** @deprecated since 2.4 - caches listen to repaintRequested() signal to invalidate the cached image */
Q_DECL_DEPRECATED void setCacheImage( QImage * );
/** @deprecated since 2.4 - does nothing */
Q_DECL_DEPRECATED virtual void onCacheImageDelete() {}
@ -393,8 +393,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
bool hasScaleBasedVisibility() const;
/** Clear cached image
* added in 1.5 */
//! @deprecated in 2.4 - does nothing
* @deprecated in 2.4 - caches listen to repaintRequested() signal to invalidate the cached image */
Q_DECL_DEPRECATED void clearCacheImage();
/** \brief Obtain Metadata for this layer */

View File

@ -1,6 +1,8 @@
#include "qgsmaprenderercache.h"
#include "qgsmaplayerregistry.h"
#include "qgsmaplayer.h"
QgsMapRendererCache::QgsMapRendererCache()
{
@ -10,8 +12,23 @@ QgsMapRendererCache::QgsMapRendererCache()
void QgsMapRendererCache::clear()
{
QMutexLocker lock( &mMutex );
clearInternal();
}
void QgsMapRendererCache::clearInternal()
{
mExtent.setMinimal();
mScale = 0;
// make sure we are disconnected from all layers
foreach ( QString layerId, mCachedImages.keys() )
{
QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( layerId );
if ( layer )
{
disconnect( layer, SIGNAL( repaintRequested() ), this, SLOT( layerRequestedRepaint() ) );
}
}
mCachedImages.clear();
}
@ -24,13 +41,12 @@ bool QgsMapRendererCache::init( QgsRectangle extent, double scale )
scale == mScale )
return true;
clearInternal();
// set new params
mExtent = extent;
mScale = scale;
// invalidate cache
mCachedImages.clear();
return false;
}
@ -38,6 +54,13 @@ void QgsMapRendererCache::setCacheImage( QString layerId, const QImage& img )
{
QMutexLocker lock( &mMutex );
mCachedImages[layerId] = img;
// connect to the layer to listen to layer's repaintRequested() signals
QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( layerId );
if ( layer )
{
connect( layer, SIGNAL( repaintRequested() ), this, SLOT( layerRequestedRepaint() ) );
}
}
QImage QgsMapRendererCache::cacheImage( QString layerId )
@ -46,10 +69,22 @@ QImage QgsMapRendererCache::cacheImage( QString layerId )
return mCachedImages.value( layerId );
}
void QgsMapRendererCache::layerDataChanged()
void QgsMapRendererCache::layerRequestedRepaint()
{
// TODO!
qDebug( "nothing here yet" );
QgsMapLayer* layer = qobject_cast<QgsMapLayer*>( sender() );
if ( layer )
clearCacheImage( layer->id() );
}
void QgsMapRendererCache::clearCacheImage( QString layerId )
{
QMutexLocker lock( &mMutex );
mCachedImages.remove( layerId );
QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( layerId );
if ( layer )
{
disconnect( layer, SIGNAL( repaintRequested() ), this, SLOT( layerRequestedRepaint() ) );
}
}

View File

@ -11,7 +11,11 @@
/**
* This class is responsible for keeping cache of rendered images of individual layers.
*
* The class is thread-safe (multiple classes can access the same instance safely).
* Once a layer has rendered image stored in the cache (using setCacheImage(...)),
* the cache listens to repaintRequested() signals from layer. If triggered, the cache
* removes the rendered image (and disconnects from the layer).
*
* The class is thread-safe (multiple classes can access the same instance safely).
*
* @note added in 2.4
*/
@ -35,9 +39,16 @@ class CORE_EXPORT QgsMapRendererCache : public QObject
//! get cached image for the specified layer ID. Returns null image if it is not cached.
QImage cacheImage( QString layerId );
public slots:
//! remove layer from the cache
void clearCacheImage( QString layerId );
protected slots:
//! remove layer (that emitted the signal) from the cache
void layerDataChanged();
void layerRequestedRepaint();
protected:
//! invalidate cache contents (without locking)
void clearInternal();
protected:
QMutex mMutex;

View File

@ -589,7 +589,7 @@ LayerRenderJobs QgsMapRendererJob::prepareJobs( QPainter* painter, QgsPalLabelin
{
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
if ( vl->isEditable() || ( labelingEngine && labelingEngine->willUseLayer( vl ) ) )
mCache->setCacheImage( ml->id(), QImage() );
mCache->clearCacheImage( ml->id() );
}
layerJobs.append( LayerRenderJob() );

View File

@ -380,7 +380,7 @@ void QgsMapCanvas::setLayerSet( QList<QgsMapCanvasLayer> &layers )
// Add check if vector layer when disconnecting from selectionChanged slot
// Ticket #811 - racicot
QgsMapLayer *currentLayer = layer( i );
disconnect( currentLayer, SIGNAL( repaintRequested() ), this, SLOT( layerRequestedRepaint() ) );
disconnect( currentLayer, SIGNAL( repaintRequested() ), this, SLOT( refresh() ) );
QgsVectorLayer *isVectLyr = qobject_cast<QgsVectorLayer *>( currentLayer );
if ( isVectLyr )
{
@ -395,7 +395,7 @@ void QgsMapCanvas::setLayerSet( QList<QgsMapCanvasLayer> &layers )
// Add check if vector layer when connecting to selectionChanged slot
// Ticket #811 - racicot
QgsMapLayer *currentLayer = layer( i );
connect( currentLayer, SIGNAL( repaintRequested() ), this, SLOT( layerRequestedRepaint() ) );
connect( currentLayer, SIGNAL( repaintRequested() ), this, SLOT( refresh() ) );
QgsVectorLayer *isVectLyr = qobject_cast<QgsVectorLayer *>( currentLayer );
if ( isVectLyr )
{
@ -681,18 +681,6 @@ void QgsMapCanvas::refreshMap()
mMapUpdateTimer.start();
}
void QgsMapCanvas::layerRequestedRepaint()
{
// make sure to clear the cached image
if ( mCache )
{
QgsMapLayer* layer = qobject_cast<QgsMapLayer*>( sender() );
if ( layer )
mCache->setCacheImage( layer->id(), QImage() );
}
refresh();
}
void QgsMapCanvas::rendererJobFinished()
{

View File

@ -382,9 +382,6 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
void refreshMap();
//! Layer says something has changed that affects its appearance
void layerRequestedRepaint();
signals:
/** Let the owner know how far we are with render operations */
//! @deprecated since 2.4 - already unused in 2.0 anyway