Support overriden layer styles also in the composer legend

This commit is contained in:
Martin Dobias 2015-05-26 18:53:57 +07:00
parent ea64d32131
commit 205daae008
9 changed files with 95 additions and 3 deletions

View File

@ -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*/

View File

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

View File

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

View File

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

View File

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

View File

@ -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();
@ -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*/

View File

@ -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"
@ -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 );
@ -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)
@ -1099,6 +1115,9 @@ void QgsLayerTreeModel::addLegendToLayer( QgsLayerTreeLayer* nodeL )
mLegend[nodeL] = data;
if ( ! isEmbedded ) endInsertRows();
if ( hasStyleOverride )
ml->styleManager()->restoreOverrideStyle();
}

View File

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

View File

@ -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;
@ -183,8 +184,9 @@ bool QgsMapLayerStyleManager::setOverrideStyle( const QString& styleDef )
QgsMapLayerStyle overrideStyle( styleDef );
overrideStyle.writeToLayer( mLayer );
}
mLayer->blockSignals( false );
return false;
return true;
}
bool QgsMapLayerStyleManager::restoreOverrideStyle()
@ -192,7 +194,10 @@ bool QgsMapLayerStyleManager::restoreOverrideStyle()
if ( !mOverriddenOriginalStyle )
return false;
mLayer->blockSignals( true );
mOverriddenOriginalStyle->writeToLayer( mLayer );
mLayer->blockSignals( false );
delete mOverriddenOriginalStyle;
mOverriddenOriginalStyle = 0;
return true;