mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-03 00:02:25 -05:00
[FEATURE] Allow overriding the legend patch size on a per-item basis
Allows users to override the symbol patch size for individual legend nodes, by double clicking the node Width and height can be individually overridden, with the node falling back to the default width or height when the override isn't set. Sponsored by SLYR
This commit is contained in:
parent
18547ec258
commit
0c64fd7907
@ -153,6 +153,30 @@ Sets the symbol patch ``shape`` to use when rendering the legend node symbol.
|
||||
|
||||
.. seealso:: :py:func:`patchShape`
|
||||
|
||||
.. versionadded:: 3.14
|
||||
%End
|
||||
|
||||
QSizeF patchSize() const;
|
||||
%Docstring
|
||||
Returns the user (overridden) size for the legend node.
|
||||
|
||||
If either the width or height are non-zero, they will be used when rendering the legend node instead of the default
|
||||
symbol width or height from :py:class:`QgsLegendSettings`.
|
||||
|
||||
.. seealso:: :py:func:`setPatchSize`
|
||||
|
||||
.. versionadded:: 3.14
|
||||
%End
|
||||
|
||||
void setPatchSize( QSizeF size );
|
||||
%Docstring
|
||||
Sets the user (overridden) ``size`` for the legend node.
|
||||
|
||||
If either the width or height are non-zero, they will be used when rendering the legend node instead of the default
|
||||
symbol width or height from :py:class:`QgsLegendSettings`.
|
||||
|
||||
.. seealso:: :py:func:`patchSize`
|
||||
|
||||
.. versionadded:: 3.14
|
||||
%End
|
||||
|
||||
|
@ -72,6 +72,30 @@ Sets some data associated with the item. Default implementation does nothing and
|
||||
virtual QString userLabel() const;
|
||||
virtual void setUserLabel( const QString &userLabel );
|
||||
|
||||
virtual QSizeF userPatchSize() const;
|
||||
%Docstring
|
||||
Returns the user (overridden) size for the legend node.
|
||||
|
||||
If either the width or height are non-zero, they will be used when rendering the legend node instead of the default
|
||||
symbol width or height from :py:class:`QgsLegendSettings`.
|
||||
|
||||
.. seealso:: :py:func:`setUserPatchSize`
|
||||
|
||||
.. versionadded:: 3.14
|
||||
%End
|
||||
|
||||
virtual void setUserPatchSize( QSizeF size );
|
||||
%Docstring
|
||||
Sets the user (overridden) ``size`` for the legend node.
|
||||
|
||||
If either the width or height are non-zero, they will be used when rendering the legend node instead of the default
|
||||
symbol width or height from :py:class:`QgsLegendSettings`.
|
||||
|
||||
.. seealso:: :py:func:`userPatchSize`
|
||||
|
||||
.. versionadded:: 3.14
|
||||
%End
|
||||
|
||||
virtual bool isScaleOK( double scale ) const;
|
||||
|
||||
virtual void invalidateMapBasedData();
|
||||
@ -100,6 +124,8 @@ Default implementation does nothing. *
|
||||
double maxSiblingSymbolWidth;
|
||||
|
||||
QgsLegendPatchShape patchShape;
|
||||
|
||||
QSizeF patchSize;
|
||||
};
|
||||
|
||||
struct ItemMetrics
|
||||
|
@ -111,6 +111,30 @@ Returns the legend patch shape for the legend node belonging to ``nodeLayer`` at
|
||||
|
||||
.. seealso:: :py:func:`setLegendNodePatchShape`
|
||||
|
||||
.. versionadded:: 3.14
|
||||
%End
|
||||
|
||||
static void setLegendNodeSymbolSize( QgsLayerTreeLayer *nodeLayer, int originalIndex, QSizeF size );
|
||||
%Docstring
|
||||
Sets the legend symbol ``size`` for the legend node belonging to ``nodeLayer`` at the specified ``originalIndex``.
|
||||
|
||||
If either the width or height are non-zero, they will be used when rendering the legend node instead of the default
|
||||
symbol width or height from :py:class:`QgsLegendSettings`.
|
||||
|
||||
.. seealso:: :py:func:`legendNodeSymbolSize`
|
||||
|
||||
.. versionadded:: 3.14
|
||||
%End
|
||||
|
||||
static QSizeF legendNodeSymbolSize( QgsLayerTreeLayer *nodeLayer, int originalIndex );
|
||||
%Docstring
|
||||
Returns the legend node symbol size for the legend node belonging to ``nodeLayer`` at the specified ``originalIndex``.
|
||||
|
||||
If either the width or height are non-zero, they will be used when rendering the legend node instead of the default
|
||||
symbol width or height from :py:class:`QgsLegendSettings`.
|
||||
|
||||
.. seealso:: :py:func:`setLegendNodeSymbolSize`
|
||||
|
||||
.. versionadded:: 3.14
|
||||
%End
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "qgslayertreeutils.h"
|
||||
#include "qgsmaplayer.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgssymbollayerutils.h"
|
||||
|
||||
|
||||
QgsLayerTreeLayer::QgsLayerTreeLayer( QgsMapLayer *layer )
|
||||
@ -40,6 +41,7 @@ QgsLayerTreeLayer::QgsLayerTreeLayer( const QgsLayerTreeLayer &other )
|
||||
, mRef( other.mRef )
|
||||
, mLayerName( other.mLayerName )
|
||||
, mPatchShape( other.mPatchShape )
|
||||
, mPatchSize( other.mPatchSize )
|
||||
{
|
||||
attachToLayer();
|
||||
}
|
||||
@ -130,6 +132,8 @@ QgsLayerTreeLayer *QgsLayerTreeLayer::readXml( QDomElement &element, const QgsRe
|
||||
nodeLayer->setPatchShape( patch );
|
||||
}
|
||||
|
||||
nodeLayer->setPatchSize( QgsSymbolLayerUtils::decodeSize( element.attribute( QStringLiteral( "patch_size" ) ) ) );
|
||||
|
||||
return nodeLayer;
|
||||
}
|
||||
|
||||
@ -164,6 +168,7 @@ void QgsLayerTreeLayer::writeXml( QDomElement &parentElement, const QgsReadWrite
|
||||
mPatchShape.writeXml( patchElem, doc, context );
|
||||
elem.appendChild( patchElem );
|
||||
}
|
||||
elem.setAttribute( QStringLiteral( "patch_size" ), QgsSymbolLayerUtils::encodeSize( mPatchSize ) );
|
||||
|
||||
writeCommonXml( elem );
|
||||
|
||||
|
@ -159,6 +159,28 @@ class CORE_EXPORT QgsLayerTreeLayer : public QgsLayerTreeNode
|
||||
*/
|
||||
void setPatchShape( const QgsLegendPatchShape &shape );
|
||||
|
||||
/**
|
||||
* Returns the user (overridden) size for the legend node.
|
||||
*
|
||||
* If either the width or height are non-zero, they will be used when rendering the legend node instead of the default
|
||||
* symbol width or height from QgsLegendSettings.
|
||||
*
|
||||
* \see setPatchSize()
|
||||
* \since QGIS 3.14
|
||||
*/
|
||||
QSizeF patchSize() const { return mPatchSize; }
|
||||
|
||||
/**
|
||||
* Sets the user (overridden) \a size for the legend node.
|
||||
*
|
||||
* If either the width or height are non-zero, they will be used when rendering the legend node instead of the default
|
||||
* symbol width or height from QgsLegendSettings.
|
||||
*
|
||||
* \see patchSize()
|
||||
* \since QGIS 3.14
|
||||
*/
|
||||
void setPatchSize( QSizeF size ) { mPatchSize = size; }
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
@ -210,6 +232,7 @@ class CORE_EXPORT QgsLayerTreeLayer : public QgsLayerTreeNode
|
||||
#endif
|
||||
|
||||
QgsLegendPatchShape mPatchShape;
|
||||
QSizeF mPatchSize;
|
||||
};
|
||||
|
||||
|
||||
|
@ -59,6 +59,13 @@ bool QgsLayerTreeModelLegendNode::setData( const QVariant &value, int role )
|
||||
return false;
|
||||
}
|
||||
|
||||
QSizeF QgsLayerTreeModelLegendNode::userPatchSize() const
|
||||
{
|
||||
if ( mEmbeddedInParent )
|
||||
return mLayerNode->patchSize();
|
||||
|
||||
return mUserSize;
|
||||
}
|
||||
|
||||
QgsLayerTreeModelLegendNode::ItemMetrics QgsLayerTreeModelLegendNode::draw( const QgsLegendSettings &settings, ItemContext *ctx )
|
||||
{
|
||||
@ -68,7 +75,7 @@ QgsLayerTreeModelLegendNode::ItemMetrics QgsLayerTreeModelLegendNode::draw( cons
|
||||
// itemHeight here is not really item height, it is only for symbol
|
||||
// vertical alignment purpose, i.e. OK take single line height
|
||||
// if there are more lines, those run under the symbol
|
||||
double itemHeight = std::max( static_cast< double >( settings.symbolSize().height() ), textHeight );
|
||||
double itemHeight = std::max( static_cast< double >( ctx && ctx->patchSize.height() > 0 ? ctx->patchSize.height() : settings.symbolSize().height() ), textHeight );
|
||||
|
||||
ItemMetrics im;
|
||||
im.symbolSize = drawSymbol( settings, ctx, itemHeight );
|
||||
@ -88,6 +95,15 @@ QSizeF QgsLayerTreeModelLegendNode::drawSymbol( const QgsLegendSettings &setting
|
||||
if ( symbolIcon.isNull() )
|
||||
return QSizeF();
|
||||
|
||||
QSizeF size = settings.symbolSize();
|
||||
if ( ctx )
|
||||
{
|
||||
if ( ctx->patchSize.width() > 0 )
|
||||
size.setWidth( ctx->patchSize.width( ) );
|
||||
if ( ctx->patchSize.height() > 0 )
|
||||
size.setHeight( ctx->patchSize.height( ) );
|
||||
}
|
||||
|
||||
if ( ctx && ctx->painter )
|
||||
{
|
||||
switch ( settings.symbolAlignment() )
|
||||
@ -96,21 +112,21 @@ QSizeF QgsLayerTreeModelLegendNode::drawSymbol( const QgsLegendSettings &setting
|
||||
default:
|
||||
symbolIcon.paint( ctx->painter,
|
||||
static_cast< int >( ctx->columnLeft ),
|
||||
static_cast< int >( ctx->top + ( itemHeight - settings.symbolSize().height() ) / 2 ),
|
||||
static_cast< int >( settings.symbolSize().width() ),
|
||||
static_cast< int >( settings.symbolSize().height() ) );
|
||||
static_cast< int >( ctx->top + ( itemHeight - size.height() ) / 2 ),
|
||||
static_cast< int >( size.width() ),
|
||||
static_cast< int >( size.height() ) );
|
||||
break;
|
||||
|
||||
case Qt::AlignRight:
|
||||
symbolIcon.paint( ctx->painter,
|
||||
static_cast< int >( ctx->columnRight - settings.symbolSize().width() ),
|
||||
static_cast< int >( ctx->top + ( itemHeight - settings.symbolSize().height() ) / 2 ),
|
||||
static_cast< int >( settings.symbolSize().width() ),
|
||||
static_cast< int >( settings.symbolSize().height() ) );
|
||||
static_cast< int >( ctx->columnRight - size.width() ),
|
||||
static_cast< int >( ctx->top + ( itemHeight - size.height() ) / 2 ),
|
||||
static_cast< int >( size.width() ),
|
||||
static_cast< int >( size.height() ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return settings.symbolSize();
|
||||
return size;
|
||||
}
|
||||
|
||||
void QgsLayerTreeModelLegendNode::exportSymbolToJson( const QgsLegendSettings &settings, const QgsRenderContext &, QJsonObject &json ) const
|
||||
@ -531,8 +547,10 @@ QSizeF QgsSymbolLegendNode::drawSymbol( const QgsLegendSettings &settings, ItemC
|
||||
}
|
||||
|
||||
//Consider symbol size for point markers
|
||||
double height = settings.symbolSize().height();
|
||||
double width = settings.symbolSize().width();
|
||||
const double desiredHeight = ctx && ctx->patchSize.height() > 0 ? ctx->patchSize.height() : settings.symbolSize().height();
|
||||
const double desiredWidth = ctx && ctx->patchSize.width() > 0 ? ctx->patchSize.width() : settings.symbolSize().width();
|
||||
double height = desiredHeight;
|
||||
double width = desiredWidth;
|
||||
|
||||
//Center small marker symbols
|
||||
double widthOffset = 0;
|
||||
@ -544,19 +562,19 @@ QSizeF QgsSymbolLegendNode::drawSymbol( const QgsLegendSettings &settings, ItemC
|
||||
double size = markerSymbol->size( *context ) / context->scaleFactor();
|
||||
height = size;
|
||||
width = size;
|
||||
if ( width < settings.symbolSize().width() )
|
||||
if ( width < desiredWidth )
|
||||
{
|
||||
widthOffset = ( settings.symbolSize().width() - width ) / 2.0;
|
||||
widthOffset = ( desiredWidth - width ) / 2.0;
|
||||
}
|
||||
if ( height < settings.symbolSize().height() )
|
||||
if ( height < desiredHeight )
|
||||
{
|
||||
heightOffset = ( settings.symbolSize().height() - height ) / 2.0;
|
||||
heightOffset = ( desiredHeight - height ) / 2.0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ctx && ctx->painter )
|
||||
{
|
||||
double currentYCoord = ctx->top + ( itemHeight - settings.symbolSize().height() ) / 2;
|
||||
double currentYCoord = ctx->top + ( itemHeight - desiredHeight ) / 2;
|
||||
QPainter *p = ctx->painter;
|
||||
|
||||
//setup painter scaling to dots so that raster symbology is drawn to scale
|
||||
@ -621,8 +639,8 @@ QSizeF QgsSymbolLegendNode::drawSymbol( const QgsLegendSettings &settings, ItemC
|
||||
p->restore();
|
||||
}
|
||||
|
||||
return QSizeF( std::max( width + 2 * widthOffset, static_cast< double >( settings.symbolSize().width() ) ),
|
||||
std::max( height + 2 * heightOffset, static_cast< double >( settings.symbolSize().height() ) ) );
|
||||
return QSizeF( std::max( width + 2 * widthOffset, static_cast< double >( desiredWidth ) ),
|
||||
std::max( height + 2 * heightOffset, static_cast< double >( desiredHeight ) ) );
|
||||
}
|
||||
|
||||
void QgsSymbolLegendNode::exportSymbolToJson( const QgsLegendSettings &settings, const QgsRenderContext &context, QJsonObject &json ) const
|
||||
@ -858,6 +876,22 @@ QVariant QgsRasterSymbolLegendNode::data( int role ) const
|
||||
|
||||
QSizeF QgsRasterSymbolLegendNode::drawSymbol( const QgsLegendSettings &settings, ItemContext *ctx, double itemHeight ) const
|
||||
{
|
||||
QSizeF size = settings.symbolSize();
|
||||
double offsetX = 0;
|
||||
if ( ctx )
|
||||
{
|
||||
if ( ctx->patchSize.width() > 0 )
|
||||
{
|
||||
if ( ctx->patchSize.width() < size.width() )
|
||||
offsetX = ( size.width() - ctx->patchSize.width() ) / 2.0;
|
||||
size.setWidth( ctx->patchSize.width() );
|
||||
}
|
||||
if ( ctx->patchSize.height() > 0 )
|
||||
{
|
||||
size.setHeight( ctx->patchSize.height() );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ctx && ctx->painter )
|
||||
{
|
||||
QColor itemColor = mColor;
|
||||
@ -885,17 +919,17 @@ QSizeF QgsRasterSymbolLegendNode::drawSymbol( const QgsLegendSettings &settings,
|
||||
{
|
||||
case Qt::AlignLeft:
|
||||
default:
|
||||
ctx->painter->drawRect( QRectF( ctx->columnLeft, ctx->top + ( itemHeight - settings.symbolSize().height() ) / 2,
|
||||
settings.symbolSize().width(), settings.symbolSize().height() ) );
|
||||
ctx->painter->drawRect( QRectF( ctx->columnLeft + offsetX, ctx->top + ( itemHeight - size.height() ) / 2,
|
||||
size.width(), size.height() ) );
|
||||
break;
|
||||
|
||||
case Qt::AlignRight:
|
||||
ctx->painter->drawRect( QRectF( ctx->columnRight - settings.symbolSize().width(), ctx->top + ( itemHeight - settings.symbolSize().height() ) / 2,
|
||||
settings.symbolSize().width(), settings.symbolSize().height() ) );
|
||||
ctx->painter->drawRect( QRectF( ctx->columnRight - size.width() - offsetX, ctx->top + ( itemHeight - size.height() ) / 2,
|
||||
size.width(), size.height() ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return settings.symbolSize();
|
||||
return size;
|
||||
}
|
||||
|
||||
void QgsRasterSymbolLegendNode::exportSymbolToJson( const QgsLegendSettings &settings, const QgsRenderContext &, QJsonObject &json ) const
|
||||
|
@ -87,6 +87,28 @@ class CORE_EXPORT QgsLayerTreeModelLegendNode : public QObject
|
||||
virtual QString userLabel() const { return mUserLabel; }
|
||||
virtual void setUserLabel( const QString &userLabel ) { mUserLabel = userLabel; }
|
||||
|
||||
/**
|
||||
* Returns the user (overridden) size for the legend node.
|
||||
*
|
||||
* If either the width or height are non-zero, they will be used when rendering the legend node instead of the default
|
||||
* symbol width or height from QgsLegendSettings.
|
||||
*
|
||||
* \see setUserPatchSize()
|
||||
* \since QGIS 3.14
|
||||
*/
|
||||
virtual QSizeF userPatchSize() const;
|
||||
|
||||
/**
|
||||
* Sets the user (overridden) \a size for the legend node.
|
||||
*
|
||||
* If either the width or height are non-zero, they will be used when rendering the legend node instead of the default
|
||||
* symbol width or height from QgsLegendSettings.
|
||||
*
|
||||
* \see userPatchSize()
|
||||
* \since QGIS 3.14
|
||||
*/
|
||||
virtual void setUserPatchSize( QSizeF size ) { mUserSize = size; }
|
||||
|
||||
virtual bool isScaleOK( double scale ) const { Q_UNUSED( scale ) return true; }
|
||||
|
||||
/**
|
||||
@ -152,6 +174,15 @@ class CORE_EXPORT QgsLayerTreeModelLegendNode : public QObject
|
||||
* \since QGIS 3.14
|
||||
*/
|
||||
QgsLegendPatchShape patchShape;
|
||||
|
||||
/**
|
||||
* Symbol patch size to render for the node.
|
||||
*
|
||||
* If either the width or height are zero, then the default width/height from QgsLegendSettings::symbolSize() should be used instead.
|
||||
*
|
||||
* \since QGIS 3.14
|
||||
*/
|
||||
QSizeF patchSize;
|
||||
};
|
||||
|
||||
struct ItemMetrics
|
||||
@ -229,6 +260,7 @@ class CORE_EXPORT QgsLayerTreeModelLegendNode : public QObject
|
||||
bool mEmbeddedInParent;
|
||||
QString mUserLabel;
|
||||
QgsLegendPatchShape mPatchShape;
|
||||
QSizeF mUserSize;
|
||||
};
|
||||
|
||||
#include "qgslegendsymbolitem.h"
|
||||
|
@ -674,8 +674,9 @@ QgsLegendRenderer::LegendComponent QgsLegendRenderer::drawSymbolItemInternal( Qg
|
||||
if ( const QgsSymbolLegendNode *symbolNode = dynamic_cast< const QgsSymbolLegendNode * >( symbolItem ) )
|
||||
ctx.patchShape = symbolNode->patchShape();
|
||||
|
||||
QgsLayerTreeModelLegendNode::ItemMetrics im = symbolItem->draw( mSettings, context ? &ctx
|
||||
: ( painter ? &ctx : nullptr ) );
|
||||
ctx.patchSize = symbolItem->userPatchSize();
|
||||
|
||||
QgsLayerTreeModelLegendNode::ItemMetrics im = symbolItem->draw( mSettings, &ctx );
|
||||
|
||||
if ( layerScope )
|
||||
delete context->expressionContext().popScope();
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "qgsrenderer.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsdiagramrenderer.h"
|
||||
|
||||
#include "qgssymbollayerutils.h"
|
||||
|
||||
QgsMapLayerLegend::QgsMapLayerLegend( QObject *parent )
|
||||
: QObject( parent )
|
||||
@ -168,6 +168,23 @@ QgsLegendPatchShape QgsMapLayerLegendUtils::legendNodePatchShape( QgsLayerTreeLa
|
||||
return shape;
|
||||
}
|
||||
|
||||
void QgsMapLayerLegendUtils::setLegendNodeSymbolSize( QgsLayerTreeLayer *nodeLayer, int originalIndex, QSizeF size )
|
||||
{
|
||||
if ( size.isValid() )
|
||||
nodeLayer->setCustomProperty( "legend/symbol-size-" + QString::number( originalIndex ), QgsSymbolLayerUtils::encodeSize( size ) );
|
||||
else
|
||||
nodeLayer->removeCustomProperty( "legend/symbol-size-" + QString::number( originalIndex ) );
|
||||
}
|
||||
|
||||
QSizeF QgsMapLayerLegendUtils::legendNodeSymbolSize( QgsLayerTreeLayer *nodeLayer, int originalIndex )
|
||||
{
|
||||
const QString size = nodeLayer->customProperty( "legend/symbol-size-" + QString::number( originalIndex ) ).toString();
|
||||
if ( size.isEmpty() )
|
||||
return QSizeF();
|
||||
else
|
||||
return QgsSymbolLayerUtils::decodeSize( size );
|
||||
}
|
||||
|
||||
void QgsMapLayerLegendUtils::applyLayerNodeProperties( QgsLayerTreeLayer *nodeLayer, QList<QgsLayerTreeModelLegendNode *> &nodes )
|
||||
{
|
||||
// handle user labels
|
||||
@ -185,6 +202,12 @@ void QgsMapLayerLegendUtils::applyLayerNodeProperties( QgsLayerTreeLayer *nodeLa
|
||||
symbolNode->setPatchShape( shape );
|
||||
}
|
||||
|
||||
const QSizeF userSize = QgsMapLayerLegendUtils::legendNodeSymbolSize( nodeLayer, i );
|
||||
if ( userSize.isValid() )
|
||||
{
|
||||
legendNode->setUserPatchSize( userSize );
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
|
@ -119,6 +119,28 @@ class CORE_EXPORT QgsMapLayerLegendUtils
|
||||
*/
|
||||
static QgsLegendPatchShape legendNodePatchShape( QgsLayerTreeLayer *nodeLayer, int originalIndex );
|
||||
|
||||
/**
|
||||
* Sets the legend symbol \a size for the legend node belonging to \a nodeLayer at the specified \a originalIndex.
|
||||
*
|
||||
* If either the width or height are non-zero, they will be used when rendering the legend node instead of the default
|
||||
* symbol width or height from QgsLegendSettings.
|
||||
*
|
||||
* \see legendNodeSymbolSize()
|
||||
* \since QGIS 3.14
|
||||
*/
|
||||
static void setLegendNodeSymbolSize( QgsLayerTreeLayer *nodeLayer, int originalIndex, QSizeF size );
|
||||
|
||||
/**
|
||||
* Returns the legend node symbol size for the legend node belonging to \a nodeLayer at the specified \a originalIndex.
|
||||
*
|
||||
* If either the width or height are non-zero, they will be used when rendering the legend node instead of the default
|
||||
* symbol width or height from QgsLegendSettings.
|
||||
*
|
||||
* \see setLegendNodeSymbolSize()
|
||||
* \since QGIS 3.14
|
||||
*/
|
||||
static QSizeF legendNodeSymbolSize( QgsLayerTreeLayer *nodeLayer, int originalIndex );
|
||||
|
||||
//! update according to layer node's custom properties (order of items, user labels for items)
|
||||
static void applyLayerNodeProperties( QgsLayerTreeLayer *nodeLayer, QList<QgsLayerTreeModelLegendNode *> &nodes );
|
||||
};
|
||||
|
@ -1001,6 +1001,7 @@ void QgsLayoutLegendWidget::resetLayerNodeToDefaults()
|
||||
}
|
||||
|
||||
nodeLayer->setPatchShape( QgsLegendPatchShape() );
|
||||
nodeLayer->setPatchSize( QSizeF() );
|
||||
|
||||
mItemTreeView->layerTreeModel()->refreshLayerLegend( nodeLayer );
|
||||
|
||||
@ -1437,7 +1438,23 @@ QgsLayoutLegendNodeWidget::QgsLayoutLegendNodeWidget( QgsLayoutItemLegend *legen
|
||||
else
|
||||
{
|
||||
currentLabel = QgsLayerTree::toGroup( mNode )->name();
|
||||
}
|
||||
|
||||
mWidthSpinBox->setClearValue( 0, tr( "Default" ) );
|
||||
mHeightSpinBox->setClearValue( 0, tr( "Default" ) );
|
||||
mWidthSpinBox->setVisible( mLegendNode || mLayer );
|
||||
mHeightSpinBox->setVisible( mLegendNode || mLayer );
|
||||
mPatchWidthLabel->setVisible( mLegendNode || mLayer );
|
||||
mPatchHeightLabel->setVisible( mLegendNode || mLayer );
|
||||
if ( mLegendNode )
|
||||
{
|
||||
mWidthSpinBox->setValue( mLegendNode->userPatchSize().width() );
|
||||
mHeightSpinBox->setValue( mLegendNode->userPatchSize().height() );
|
||||
}
|
||||
else if ( mLayer )
|
||||
{
|
||||
mWidthSpinBox->setValue( mLayer->patchSize().width() );
|
||||
mHeightSpinBox->setValue( mLayer->patchSize().height() );
|
||||
}
|
||||
|
||||
QgsLegendPatchShape patchShape;
|
||||
@ -1489,6 +1506,9 @@ QgsLayoutLegendNodeWidget::QgsLayoutLegendNodeWidget( QgsLayoutItemLegend *legen
|
||||
connect( mLabelEdit, &QPlainTextEdit::textChanged, this, &QgsLayoutLegendNodeWidget::labelChanged );
|
||||
connect( mPatchShapeButton, &QgsLegendPatchShapeButton::changed, this, &QgsLayoutLegendNodeWidget::patchChanged );
|
||||
connect( mInsertExpressionButton, &QPushButton::clicked, this, &QgsLayoutLegendNodeWidget::insertExpression );
|
||||
|
||||
connect( mWidthSpinBox, qgis::overload<double>::of( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutLegendNodeWidget::sizeChanged );
|
||||
connect( mHeightSpinBox, qgis::overload<double>::of( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutLegendNodeWidget::sizeChanged );
|
||||
}
|
||||
|
||||
void QgsLayoutLegendNodeWidget::labelChanged()
|
||||
@ -1591,4 +1611,30 @@ void QgsLayoutLegendNodeWidget::insertExpression()
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLayoutLegendNodeWidget::sizeChanged( double )
|
||||
{
|
||||
mLegend->beginCommand( tr( "Edit Legend Item" ) );
|
||||
const QSizeF size = QSizeF( mWidthSpinBox->value(), mHeightSpinBox->value() );
|
||||
|
||||
if ( mLegendNode )
|
||||
{
|
||||
QgsMapLayerLegendUtils::setLegendNodeSymbolSize( mLayer, mOriginalLegendNodeIndex, size );
|
||||
mLegend->model()->refreshLayerLegend( mLayer );
|
||||
}
|
||||
else if ( mLayer )
|
||||
{
|
||||
mLayer->setPatchSize( size );
|
||||
const QList<QgsLayerTreeModelLegendNode *> layerLegendNodes = mLegend->model()->layerLegendNodes( mLayer, false );
|
||||
for ( QgsLayerTreeModelLegendNode *node : layerLegendNodes )
|
||||
{
|
||||
QgsMapLayerLegendUtils::setLegendNodeSymbolSize( mLayer, _originalLegendNodeIndex( node ), size );
|
||||
}
|
||||
mLegend->model()->refreshLayerLegend( mLayer );
|
||||
}
|
||||
|
||||
mLegend->adjustBoxSize();
|
||||
mLegend->updateFilterByMap();
|
||||
mLegend->endCommand();
|
||||
}
|
||||
|
||||
///@endcond
|
||||
|
@ -193,6 +193,7 @@ class GUI_EXPORT QgsLayoutLegendNodeWidget: public QgsPanelWidget, private Ui::Q
|
||||
void labelChanged();
|
||||
void patchChanged();
|
||||
void insertExpression();
|
||||
void sizeChanged( double );
|
||||
|
||||
private:
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>282</height>
|
||||
<width>351</width>
|
||||
<height>381</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -26,17 +26,7 @@
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="QPlainTextEdit" name="mLabelEdit">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>150</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="4" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@ -49,43 +39,89 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="mInsertExpressionButton">
|
||||
<property name="text">
|
||||
<string>Insert an Expression…</string>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Patch</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,1">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="mPatchShapeLabel">
|
||||
<property name="text">
|
||||
<string>Shape</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QgsLegendPatchShapeButton" name="mPatchShapeButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Customize</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="mPatchWidthLabel">
|
||||
<property name="text">
|
||||
<string>Width (mm)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QgsDoubleSpinBox" name="mWidthSpinBox"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="mPatchHeightLabel">
|
||||
<property name="text">
|
||||
<string>Height (mm)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QgsDoubleSpinBox" name="mHeightSpinBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QgsLegendPatchShapeButton" name="mPatchShapeButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Customize</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="mPatchShapeLabel">
|
||||
<property name="text">
|
||||
<string>Patch shape</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Label</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QPlainTextEdit" name="mLabelEdit">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>150</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="mInsertExpressionButton">
|
||||
<property name="text">
|
||||
<string>Insert an Expression…</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsDoubleSpinBox</class>
|
||||
<extends>QDoubleSpinBox</extends>
|
||||
<header>qgsdoublespinbox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsPanelWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
@ -98,6 +134,13 @@
|
||||
<header>qgslegendpatchshapebutton.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>mLabelEdit</tabstop>
|
||||
<tabstop>mInsertExpressionButton</tabstop>
|
||||
<tabstop>mPatchShapeButton</tabstop>
|
||||
<tabstop>mWidthSpinBox</tabstop>
|
||||
<tabstop>mHeightSpinBox</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -132,6 +132,7 @@ class TestQgsLegendRenderer : public QObject
|
||||
|
||||
void testBasic();
|
||||
void testMultiline();
|
||||
void testOverrideSize();
|
||||
void testSpacing();
|
||||
void testEffects();
|
||||
void testBigMarker();
|
||||
@ -340,6 +341,34 @@ void TestQgsLegendRenderer::testMultiline()
|
||||
QVERIFY( _verifyImage( testName, mReport ) );
|
||||
}
|
||||
|
||||
void TestQgsLegendRenderer::testOverrideSize()
|
||||
{
|
||||
QString testName = QStringLiteral( "legend_override_size" );
|
||||
|
||||
QgsLayerTreeModel legendModel( mRoot );
|
||||
|
||||
legendModel.findLegendNode( mVL1->id(), QString() );
|
||||
|
||||
QgsLayerTreeLayer *layer = legendModel.rootGroup()->findLayer( mVL1 );
|
||||
layer->setPatchSize( QSizeF( 30, 0 ) );
|
||||
|
||||
QgsLayerTreeModelLegendNode *embeddedNode = legendModel.legendNodeEmbeddedInParent( layer );
|
||||
embeddedNode->setUserLabel( QString() );
|
||||
|
||||
layer = legendModel.rootGroup()->findLayer( mVL3 );
|
||||
QgsMapLayerLegendUtils::setLegendNodeSymbolSize( layer, 1, QSizeF( 0, 30 ) );
|
||||
legendModel.refreshLayerLegend( layer );
|
||||
|
||||
layer = legendModel.rootGroup()->findLayer( mRL );
|
||||
QgsMapLayerLegendUtils::setLegendNodeSymbolSize( layer, 0, QSizeF( 50, 30 ) );
|
||||
legendModel.refreshLayerLegend( layer );
|
||||
|
||||
QgsLegendSettings settings;
|
||||
_setStandardTestFont( settings, QStringLiteral( "Bold" ) );
|
||||
_renderLegend( testName, &legendModel, settings );
|
||||
QVERIFY( _verifyImage( testName, mReport ) );
|
||||
}
|
||||
|
||||
void TestQgsLegendRenderer::testSpacing()
|
||||
{
|
||||
QgsMarkerSymbol *sym = new QgsMarkerSymbol();
|
||||
|
BIN
tests/testdata/control_images/legend/expected_legend_override_size/expected_legend_override_size.png
vendored
Normal file
BIN
tests/testdata/control_images/legend/expected_legend_override_size/expected_legend_override_size.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Loading…
x
Reference in New Issue
Block a user