Skip to content
Permalink
Browse files

Merge pull request #2245 from vmora/issue13078

Fix legend symbol size when using map units (fix #13078)
  • Loading branch information
wonder-sk committed Aug 18, 2015
2 parents 7527638 + 0a93f94 commit 7d1a8d30199e2b6bf2669478f474c0911d04f6b1
@@ -1118,6 +1118,10 @@ void QgsLayerTreeModel::addLegendToLayer( QgsLayerTreeLayer* nodeL )

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

// invalidate map based data even if the data is not map-based to make sure
// the symbol sizes are computed at least once
legendInvalidateMapBasedData();
}


@@ -1299,11 +1303,41 @@ QList<QgsLayerTreeModelLegendNode*> QgsLayerTreeModel::layerLegendNodes( QgsLaye

void QgsLayerTreeModel::legendInvalidateMapBasedData()
{
// we have varying icon sizes, and we want icon to be centered and
// text to be left aligned, so we have to compute the max width of icons
//
// we do that for nodes who share a common parent
//
// we do that here because for symbols with size defined in map units
// the symbol sizes changes depends on the zoom level

foreach ( const LayerLegendData& data, mLegend )
{
QList<QgsSymbolV2LegendNode*> symbolNodes;
QMap<QString, int> widthMax;
foreach ( QgsLayerTreeModelLegendNode* legendNode, data.originalNodes )
{
QgsSymbolV2LegendNode* n = dynamic_cast<QgsSymbolV2LegendNode*>( legendNode );
if ( n )
{
const QSize sz( n->minimumIconSize() );
const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() );
widthMax[parentKey] = qMax( sz.width(), widthMax.contains( parentKey ) ? widthMax[parentKey] : 0 );
n->setIconSize( sz );
symbolNodes.append( n );
}
}
foreach ( QgsSymbolV2LegendNode* n, symbolNodes )
{
const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() );
Q_ASSERT( widthMax[parentKey] > 0 );
const int twiceMarginWidth = 2; // a one pixel margin avoids hugly rendering of icon
n->setIconSize( QSize( widthMax[parentKey] + twiceMarginWidth, n->iconSize().rheight() + twiceMarginWidth ) );
}
foreach ( QgsLayerTreeModelLegendNode* legendNode, data.originalNodes )
legendNode->invalidateMapBasedData();
}

}

// Legend nodes routines - end
@@ -159,13 +159,14 @@ Qt::ItemFlags QgsSymbolV2LegendNode::flags() const

QSize QgsSymbolV2LegendNode::minimumIconSize() const
{
QSize minSz;
QSize minSz( 16, 16 );
if ( mItem.symbol() && mItem.symbol()->type() == QgsSymbolV2::Marker )
{
QScopedPointer<QgsRenderContext> context( createTemporaryRenderContext() );
minSz = QgsImageOperation::nonTransparentImageRect(
QgsSymbolLayerV2Utils::symbolPreviewPixmap( mItem.symbol(), QSize( 512, 512 ), context.data() ).toImage(),
mIconSize,
QgsSymbolLayerV2Utils::symbolPreviewPixmap( mItem.symbol(), QSize( 512, 512 ),
context.data() ).toImage(),
minSz,
true ).size();
}
else if ( mItem.symbol() && mItem.symbol()->type() == QgsSymbolV2::Line )
@@ -174,16 +175,12 @@ QSize QgsSymbolV2LegendNode::minimumIconSize() const
minSz = QgsImageOperation::nonTransparentImageRect(
QgsSymbolLayerV2Utils::symbolPreviewPixmap( mItem.symbol(), QSize( mIconSize.width(), 512 ),
context.data() ).toImage(),
mIconSize,
minSz,
true ).size();
}
else
{
minSz = mIconSize;
}

if ( mItem.level() != 0 && !( model() && model()->testFlag( QgsLayerTreeModel::ShowLegendAsTree ) ) )
minSz.setWidth( indentSize + minSz.width() );
minSz.setWidth( mItem.level() * indentSize + minSz.width() );

return minSz;
}
@@ -199,33 +199,10 @@ QList<QgsLayerTreeModelLegendNode*> QgsDefaultVectorLayerLegend::createLayerTree
nodes.append( new QgsSimpleLegendNode( nodeLayer, r->legendClassificationAttribute() ) );
}

// we have varying icon sizes, and we want icon to be centered and
// text to be left aligned, so we have to compute the max width of icons
//
// we do that for nodes who share a common parent

QList<QgsSymbolV2LegendNode*> symbolNodes;
QMap<QString, int> widthMax;
foreach ( const QgsLegendSymbolItemV2& i, r->legendSymbolItemsV2() )
{
QgsSymbolV2LegendNode * n = new QgsSymbolV2LegendNode( nodeLayer, i );
nodes.append( n );
if ( i.symbol() )
{
const QSize sz( n->minimumIconSize() );
const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() );
widthMax[parentKey] = qMax( sz.width(), widthMax.contains( parentKey ) ? widthMax[parentKey] : 0 );
n->setIconSize( sz );
symbolNodes.append( n );
}
}

foreach ( QgsSymbolV2LegendNode* n, symbolNodes )
{
const QString parentKey( n->data( QgsLayerTreeModelLegendNode::ParentRuleKeyRole ).toString() );
Q_ASSERT( widthMax[parentKey] > 0 );
const int twiceMarginWidth = 2; // a one pixel margin avoids hugly rendering of icon
n->setIconSize( QSize( widthMax[parentKey] + twiceMarginWidth, n->iconSize().rheight() + twiceMarginWidth ) );
}

if ( nodes.count() == 1 && nodes[0]->data( Qt::EditRole ).toString().isEmpty() )

0 comments on commit 7d1a8d3

Please sign in to comment.
You can’t perform that action at this time.