Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix support for setCacheImage() to enforce refresh of a layer
  • Loading branch information
wonder-sk committed Mar 25, 2014
1 parent f53576d commit 9e42c5b
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 37 deletions.
9 changes: 5 additions & 4 deletions python/core/qgsmaplayer.sip
Expand Up @@ -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 */
Expand Down Expand Up @@ -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/;
Expand All @@ -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 */
Expand Down
6 changes: 6 additions & 0 deletions src/core/qgsmaplayer.cpp
Expand Up @@ -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()
Expand Down
11 changes: 5 additions & 6 deletions src/core/qgsmaplayer.h
Expand Up @@ -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 */
Expand Down Expand Up @@ -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() {}

Expand All @@ -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 */
Expand Down
47 changes: 41 additions & 6 deletions src/core/qgsmaprenderercache.cpp
@@ -1,6 +1,8 @@

#include "qgsmaprenderercache.h"

#include "qgsmaplayerregistry.h"
#include "qgsmaplayer.h"

QgsMapRendererCache::QgsMapRendererCache()
{
Expand All @@ -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();
}

Expand All @@ -24,20 +41,26 @@ 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;
}

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 )
Expand All @@ -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() ) );
}
}
17 changes: 14 additions & 3 deletions src/core/qgsmaprenderercache.h
Expand Up @@ -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
*/
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsmaprendererjob.cpp
Expand Up @@ -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() );
Expand Down
16 changes: 2 additions & 14 deletions src/gui/qgsmapcanvas.cpp
Expand Up @@ -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 )
{
Expand All @@ -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 )
{
Expand Down Expand Up @@ -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()
{
Expand Down
3 changes: 0 additions & 3 deletions src/gui/qgsmapcanvas.h
Expand Up @@ -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
Expand Down

0 comments on commit 9e42c5b

Please sign in to comment.