Skip to content

Commit

Permalink
Support overriden layer styles also in the composer legend
Browse files Browse the repository at this point in the history
  • Loading branch information
wonder-sk committed May 26, 2015
1 parent ea64d32 commit 205daae
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 3 deletions.
6 changes: 6 additions & 0 deletions python/core/composer/qgscomposermap.sip
Expand Up @@ -755,6 +755,12 @@ class QgsComposerMap : QgsComposerItem
/**Is emitted when the map has been prepared for atlas rendering, just before actual rendering*/
void preparedForAtlas();

/** Emitted when layer style overrides are changed... a means to let
* associated legend items know they should update
* @note added in 2.10
*/
void layerStyleOverridesChanged();

public slots:

/**Forces an update of the cached map image*/
Expand Down
7 changes: 7 additions & 0 deletions python/core/layertree/qgslayertreemodel.sip
Expand Up @@ -142,6 +142,13 @@ class QgsLayerTreeModel : QAbstractItemModel
//! @note added in 2.6
void legendMapViewData( double *mapUnitsPerPixel /Out/, int *dpi /Out/, double *scale /Out/ );

//! Get map of map layer style overrides (key: layer ID, value: style name) where a different style should be used instead of the current one
//! @note added in 2.10
QMap<QString, QString> layerStyleOverrides() const;
//! Set map of map layer style overrides (key: layer ID, value: style name) where a different style should be used instead of the current one
//! @note added in 2.10
void setLayerStyleOverrides( const QMap<QString, QString>& overrides );

//! Return true if index represents a legend node (instead of layer node)
//! @deprecated use index2legendNode()
bool isIndexSymbologyNode( const QModelIndex& index ) const /Deprecated/;
Expand Down
24 changes: 24 additions & 0 deletions src/core/composer/qgscomposerlegend.cpp
Expand Up @@ -510,6 +510,7 @@ void QgsComposerLegend::setComposerMap( const QgsComposerMap* map )
disconnect( mComposerMap, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
disconnect( mComposerMap, SIGNAL( itemChanged() ), this, SLOT( updateFilterByMap() ) );
disconnect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( updateFilterByMap() ) );
disconnect( mComposerMap, SIGNAL( layerStyleOverridesChanged() ), this, SLOT( mapLayerStyleOverridesChanged() ) );
}

mComposerMap = map;
Expand All @@ -519,6 +520,7 @@ void QgsComposerLegend::setComposerMap( const QgsComposerMap* map )
QObject::connect( map, SIGNAL( destroyed( QObject* ) ), this, SLOT( invalidateCurrentMap() ) );
QObject::connect( map, SIGNAL( itemChanged() ), this, SLOT( updateFilterByMap() ) );
QObject::connect( map, SIGNAL( extentChanged() ), this, SLOT( updateFilterByMap() ) );
QObject::connect( map, SIGNAL( layerStyleOverridesChanged() ), this, SLOT( mapLayerStyleOverridesChanged() ) );
}

updateFilterByMap();
Expand All @@ -529,11 +531,33 @@ void QgsComposerLegend::invalidateCurrentMap()
setComposerMap( 0 );
}

void QgsComposerLegend::mapLayerStyleOverridesChanged()
{
if ( !mComposerMap )
return;

// map's style has been changed, so make sure to update the legend here

mLegendModel2->setLayerStyleOverrides( mComposerMap->layerStyleOverrides() );

foreach ( QgsLayerTreeLayer* nodeLayer, mLegendModel2->rootGroup()->findLayers() )
mLegendModel2->refreshLayerLegend( nodeLayer );

adjustBoxSize();
update();
}

void QgsComposerLegend::updateFilterByMap()
{
if ( isRemoved() )
return;

if ( mComposerMap )
mLegendModel2->setLayerStyleOverrides( mComposerMap->layerStyleOverrides() );
else
mLegendModel2->setLayerStyleOverrides( QMap<QString, QString>() );


if ( mComposerMap && mLegendFilterByMap )
{
int dpi = mComposition->printResolution();
Expand Down
3 changes: 3 additions & 0 deletions src/core/composer/qgscomposerlegend.h
Expand Up @@ -186,6 +186,9 @@ class CORE_EXPORT QgsComposerLegend : public QgsComposerItem
private slots:
void updateFilterByMap();

//! update legend in case style of associated map has changed
void mapLayerStyleOverridesChanged();

private:
QgsComposerLegend(); //forbidden

Expand Down
11 changes: 11 additions & 0 deletions src/core/composer/qgscomposermap.cpp
Expand Up @@ -1529,6 +1529,17 @@ void QgsComposerMap::storeCurrentLayerSet()
}
}


void QgsComposerMap::setLayerStyleOverrides(const QMap<QString, QString>& overrides)
{
if ( overrides == mLayerStyleOverrides )
return;

mLayerStyleOverrides = overrides;
emit layerStyleOverridesChanged(); // associated legends may listen to this
}


void QgsComposerMap::storeCurrentLayerStyles()
{
mLayerStyleOverrides.clear();
Expand Down
8 changes: 7 additions & 1 deletion src/core/composer/qgscomposermap.h
Expand Up @@ -255,7 +255,7 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
/**Getter for stored overrides of styles for layers. @note added in 2.8 */
QMap<QString, QString> layerStyleOverrides() const { return mLayerStyleOverrides; }
/**Setter for stored overrides of styles for layers. @note added in 2.8 */
void setLayerStyleOverrides( const QMap<QString, QString>& overrides ) { mLayerStyleOverrides = overrides; }
void setLayerStyleOverrides( const QMap<QString, QString>& overrides );
/**Stores the current layer styles into style overrides. @note added in 2.8 */
void storeCurrentLayerStyles();

Expand Down Expand Up @@ -794,6 +794,12 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
/**Is emitted when the map has been prepared for atlas rendering, just before actual rendering*/
void preparedForAtlas();

/** Emitted when layer style overrides are changed... a means to let
* associated legend items know they should update
* @note added in 2.10
*/
void layerStyleOverridesChanged();

public slots:

/**Forces an update of the cached map image*/
Expand Down
21 changes: 20 additions & 1 deletion src/core/layertree/qgslayertreemodel.cpp
Expand Up @@ -24,6 +24,7 @@
#include "qgsdataitem.h"
#include "qgsmaphittest.h"
#include "qgsmaplayerlegend.h"
#include "qgsmaplayerstylemanager.h"
#include "qgspluginlayer.h"
#include "qgsrasterlayer.h"
#include "qgsrendererv2.h"
Expand Down Expand Up @@ -602,6 +603,16 @@ void QgsLayerTreeModel::legendMapViewData( double* mapUnitsPerPixel, int* dpi, d
if ( scale ) *scale = mLegendMapViewScale;
}

QMap<QString, QString> QgsLayerTreeModel::layerStyleOverrides() const
{
return mLayerStyleOverrides;
}

void QgsLayerTreeModel::setLayerStyleOverrides( const QMap<QString, QString>& overrides )
{
mLayerStyleOverrides = overrides;
}

void QgsLayerTreeModel::nodeWillAddChildren( QgsLayerTreeNode* node, int indexFrom, int indexTo )
{
Q_ASSERT( node );
Expand Down Expand Up @@ -1064,10 +1075,15 @@ void QgsLayerTreeModel::addLegendToLayer( QgsLayerTreeLayer* nodeL )
if ( !nodeL->layer() )
return;

QgsMapLayerLegend* layerLegend = nodeL->layer()->legend();
QgsMapLayer* ml = nodeL->layer();
QgsMapLayerLegend* layerLegend = ml->legend();
if ( !layerLegend )
return;

bool hasStyleOverride = mLayerStyleOverrides.contains( ml->id() );
if ( hasStyleOverride )
ml->styleManager()->setOverrideStyle( mLayerStyleOverrides.value( ml->id() ) );

QList<QgsLayerTreeModelLegendNode*> lstNew = layerLegend->createLayerTreeModelLegendNodes( nodeL );

// apply filtering defined in layer node's custom properties (reordering, filtering, custom labels)
Expand Down Expand Up @@ -1099,6 +1115,9 @@ void QgsLayerTreeModel::addLegendToLayer( QgsLayerTreeLayer* nodeL )
mLegend[nodeL] = data;

if ( ! isEmbedded ) endInsertRows();

if ( hasStyleOverride )
ml->styleManager()->restoreOverrideStyle();
}


Expand Down
11 changes: 11 additions & 0 deletions src/core/layertree/qgslayertreemodel.h
Expand Up @@ -164,6 +164,13 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel
//! @note added in 2.6
void legendMapViewData( double *mapUnitsPerPixel, int *dpi, double *scale );

//! Get map of map layer style overrides (key: layer ID, value: style name) where a different style should be used instead of the current one
//! @note added in 2.10
QMap<QString, QString> layerStyleOverrides() const;
//! Set map of map layer style overrides (key: layer ID, value: style name) where a different style should be used instead of the current one
//! @note added in 2.10
void setLayerStyleOverrides( const QMap<QString, QString>& overrides );

//! Return true if index represents a legend node (instead of layer node)
//! @deprecated use index2legendNode()
Q_DECL_DEPRECATED bool isIndexSymbologyNode( const QModelIndex& index ) const;
Expand Down Expand Up @@ -269,6 +276,10 @@ class CORE_EXPORT QgsLayerTreeModel : public QAbstractItemModel

void tryBuildLegendTree( LayerLegendData& data );

//! Overrides of map layers' styles: key = layer ID, value = style XML.
//! This allows to show legend that is different from the current style of layers
QMap<QString, QString> mLayerStyleOverrides;

//! Per layer data about layer's legend nodes
QMap<QgsLayerTreeLayer*, LayerLegendData> mLegend;

Expand Down
7 changes: 6 additions & 1 deletion src/core/qgsmaplayerstylemanager.cpp
Expand Up @@ -166,6 +166,7 @@ bool QgsMapLayerStyleManager::setOverrideStyle( const QString& styleDef )
if ( mOverriddenOriginalStyle )
return false; // cannot override the style more than once!

mLayer->blockSignals( true );
if ( mStyles.contains( styleDef ) )
{
mOverriddenOriginalStyle = new QgsMapLayerStyle;
Expand All @@ -183,16 +184,20 @@ bool QgsMapLayerStyleManager::setOverrideStyle( const QString& styleDef )
QgsMapLayerStyle overrideStyle( styleDef );
overrideStyle.writeToLayer( mLayer );
}
mLayer->blockSignals( false );

return false;
return true;
}

bool QgsMapLayerStyleManager::restoreOverrideStyle()
{
if ( !mOverriddenOriginalStyle )
return false;

mLayer->blockSignals( true );
mOverriddenOriginalStyle->writeToLayer( mLayer );
mLayer->blockSignals( false );

delete mOverriddenOriginalStyle;
mOverriddenOriginalStyle = 0;
return true;
Expand Down

1 comment on commit 205daae

@wonder-sk
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code has been funded by Tuscany Region (Italy) - SITA (CIG: 6002233F59) and commissioned to Gis3W s.a.s.

Please sign in to comment.