Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport release-3_38] Handle conditional visibility of data defined size legend nodes #57895

Merged
merged 1 commit into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
QgsLayerTreeModelLegendNode.LegendNodeRoles.NodeTypeRole = QgsLayerTreeModelLegendNode.CustomRole.NodeType
QgsLayerTreeModelLegendNode.NodeTypeRole.is_monkey_patched = True
QgsLayerTreeModelLegendNode.NodeTypeRole.__doc__ = "Type of node. Added in 3.16"
QgsLayerTreeModelLegendNode.CustomRole.__doc__ = "Legend node data roles\n\n.. note::\n\n Prior to QGIS 3.36 this was available as QgsLayerTreeModelLegendNode.LegendNodeRoles\n\n.. versionadded:: 3.36\n\n" + '* ``RuleKeyRole``: ' + QgsLayerTreeModelLegendNode.CustomRole.RuleKey.__doc__ + '\n' + '* ``ParentRuleKeyRole``: ' + QgsLayerTreeModelLegendNode.CustomRole.ParentRuleKey.__doc__ + '\n' + '* ``NodeTypeRole``: ' + QgsLayerTreeModelLegendNode.CustomRole.NodeType.__doc__
QgsLayerTreeModelLegendNode.IsDataDefinedSizeRole = QgsLayerTreeModelLegendNode.CustomRole.IsDataDefinedSize
QgsLayerTreeModelLegendNode.LegendNodeRoles.IsDataDefinedSizeRole = QgsLayerTreeModelLegendNode.CustomRole.IsDataDefinedSize
QgsLayerTreeModelLegendNode.IsDataDefinedSizeRole.is_monkey_patched = True
QgsLayerTreeModelLegendNode.IsDataDefinedSizeRole.__doc__ = "Set when a node is related to data defined size (title or separated legend items). Added in 3.38"
QgsLayerTreeModelLegendNode.CustomRole.__doc__ = "Legend node data roles\n\n.. note::\n\n Prior to QGIS 3.36 this was available as QgsLayerTreeModelLegendNode.LegendNodeRoles\n\n.. versionadded:: 3.36\n\n" + '* ``RuleKeyRole``: ' + QgsLayerTreeModelLegendNode.CustomRole.RuleKey.__doc__ + '\n' + '* ``ParentRuleKeyRole``: ' + QgsLayerTreeModelLegendNode.CustomRole.ParentRuleKey.__doc__ + '\n' + '* ``NodeTypeRole``: ' + QgsLayerTreeModelLegendNode.CustomRole.NodeType.__doc__ + '\n' + '* ``IsDataDefinedSizeRole``: ' + QgsLayerTreeModelLegendNode.CustomRole.IsDataDefinedSize.__doc__
# --
QgsLayerTreeModelLegendNode.CustomRole.baseClass = QgsLayerTreeModelLegendNode
QgsLayerTreeModelLegendNode.SimpleLegend = QgsLayerTreeModelLegendNode.NodeTypes.SimpleLegend
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ and customized look.
RuleKey,
ParentRuleKey,
NodeType,
IsDataDefinedSize,
};

enum NodeTypes /BaseType=IntEnum/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,24 @@ Takes ownership of the settings object.
QgsDataDefinedSizeLegend *dataDefinedSizeLegendSettings() const;
%Docstring
Returns extra information for data-defined size legend rendering. Normally it returns ``None``.
%End

void setUserData( int key, QVariant &value );
%Docstring
Adds a ``key`` - ``value`` pair to the item's user data.

.. seealso:: :py:func:`userData`

.. versionadded:: 3.38
%End

QVariant userData( int key ) const;
%Docstring
Retrieves the item's user data with the specified ``key``.

.. seealso:: :py:func:`setUserData`

.. versionadded:: 3.38
%End

};
Expand Down
6 changes: 5 additions & 1 deletion python/core/auto_additions/qgslayertreemodellegendnode.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
QgsLayerTreeModelLegendNode.LegendNodeRoles.NodeTypeRole = QgsLayerTreeModelLegendNode.CustomRole.NodeType
QgsLayerTreeModelLegendNode.NodeTypeRole.is_monkey_patched = True
QgsLayerTreeModelLegendNode.NodeTypeRole.__doc__ = "Type of node. Added in 3.16"
QgsLayerTreeModelLegendNode.CustomRole.__doc__ = "Legend node data roles\n\n.. note::\n\n Prior to QGIS 3.36 this was available as QgsLayerTreeModelLegendNode.LegendNodeRoles\n\n.. versionadded:: 3.36\n\n" + '* ``RuleKeyRole``: ' + QgsLayerTreeModelLegendNode.CustomRole.RuleKey.__doc__ + '\n' + '* ``ParentRuleKeyRole``: ' + QgsLayerTreeModelLegendNode.CustomRole.ParentRuleKey.__doc__ + '\n' + '* ``NodeTypeRole``: ' + QgsLayerTreeModelLegendNode.CustomRole.NodeType.__doc__
QgsLayerTreeModelLegendNode.IsDataDefinedSizeRole = QgsLayerTreeModelLegendNode.CustomRole.IsDataDefinedSize
QgsLayerTreeModelLegendNode.LegendNodeRoles.IsDataDefinedSizeRole = QgsLayerTreeModelLegendNode.CustomRole.IsDataDefinedSize
QgsLayerTreeModelLegendNode.IsDataDefinedSizeRole.is_monkey_patched = True
QgsLayerTreeModelLegendNode.IsDataDefinedSizeRole.__doc__ = "Set when a node is related to data defined size (title or separated legend items). Added in 3.38"
QgsLayerTreeModelLegendNode.CustomRole.__doc__ = "Legend node data roles\n\n.. note::\n\n Prior to QGIS 3.36 this was available as QgsLayerTreeModelLegendNode.LegendNodeRoles\n\n.. versionadded:: 3.36\n\n" + '* ``RuleKeyRole``: ' + QgsLayerTreeModelLegendNode.CustomRole.RuleKey.__doc__ + '\n' + '* ``ParentRuleKeyRole``: ' + QgsLayerTreeModelLegendNode.CustomRole.ParentRuleKey.__doc__ + '\n' + '* ``NodeTypeRole``: ' + QgsLayerTreeModelLegendNode.CustomRole.NodeType.__doc__ + '\n' + '* ``IsDataDefinedSizeRole``: ' + QgsLayerTreeModelLegendNode.CustomRole.IsDataDefinedSize.__doc__
# --
QgsLayerTreeModelLegendNode.CustomRole.baseClass = QgsLayerTreeModelLegendNode
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ and customized look.
RuleKey,
ParentRuleKey,
NodeType,
IsDataDefinedSize,
};

enum NodeTypes
Expand Down
18 changes: 18 additions & 0 deletions python/core/auto_generated/symbology/qgslegendsymbolitem.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,24 @@ Takes ownership of the settings object.
QgsDataDefinedSizeLegend *dataDefinedSizeLegendSettings() const;
%Docstring
Returns extra information for data-defined size legend rendering. Normally it returns ``None``.
%End

void setUserData( int key, QVariant &value );
%Docstring
Adds a ``key`` - ``value`` pair to the item's user data.

.. seealso:: :py:func:`userData`

.. versionadded:: 3.38
%End

QVariant userData( int key ) const;
%Docstring
Retrieves the item's user data with the specified ``key``.

.. seealso:: :py:func:`setUserData`

.. versionadded:: 3.38
%End

};
Expand Down
10 changes: 8 additions & 2 deletions src/core/layertree/qgslayertreemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1301,7 +1301,8 @@ QList<QgsLayerTreeModelLegendNode *> QgsLayerTreeModel::filterLegendNodes( const
{
for ( QgsLayerTreeModelLegendNode *node : std::as_const( nodes ) )
{
switch ( node->data( static_cast< int >( QgsLayerTreeModelLegendNode::CustomRole::NodeType ) ).value<QgsLayerTreeModelLegendNode::NodeTypes>() )
const QgsLayerTreeModelLegendNode::NodeTypes nodeType = node->data( static_cast< int >( QgsLayerTreeModelLegendNode::CustomRole::NodeType ) ).value<QgsLayerTreeModelLegendNode::NodeTypes>();
switch ( nodeType )
{
case QgsLayerTreeModelLegendNode::EmbeddedWidget:
filtered << node;
Expand All @@ -1316,6 +1317,7 @@ QList<QgsLayerTreeModelLegendNode *> QgsLayerTreeModel::filterLegendNodes( const
case QgsLayerTreeModelLegendNode::ColorRampLegend:
{
const QString ruleKey = node->data( static_cast< int >( QgsLayerTreeModelLegendNode::CustomRole::RuleKey ) ).toString();
const bool isDataDefinedSize = node->data( static_cast< int >( QgsLayerTreeModelLegendNode::CustomRole::IsDataDefinedSize ) ).toBool();
const bool checked = ( mFilterSettings && !( mFilterSettings->flags() & Qgis::LayerTreeFilterFlag::SkipVisibilityCheck ) )
|| node->data( Qt::CheckStateRole ).toInt() == Qt::Checked;

Expand All @@ -1324,7 +1326,11 @@ QList<QgsLayerTreeModelLegendNode *> QgsLayerTreeModel::filterLegendNodes( const
if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( node->layerNode()->layer() ) )
{
auto it = mHitTestResults.constFind( vl->id() );
if ( it != mHitTestResults.constEnd() && it->contains( ruleKey ) )
if ( it != mHitTestResults.constEnd() &&
( it->contains( ruleKey ) ||
( !it->isEmpty() && isDataDefinedSize )
)
)
{
filtered << node;
}
Expand Down
1 change: 1 addition & 0 deletions src/core/layertree/qgslayertreemodellegendnode.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class CORE_EXPORT QgsLayerTreeModelLegendNode : public QObject
RuleKey SIP_MONKEYPATCH_COMPAT_NAME( RuleKeyRole ) = Qt::UserRole, //!< Rule key of the node (QString)
ParentRuleKey SIP_MONKEYPATCH_COMPAT_NAME( ParentRuleKeyRole ), //!< Rule key of the parent legend node - for legends with tree hierarchy (QString). Added in 2.8
NodeType SIP_MONKEYPATCH_COMPAT_NAME( NodeTypeRole ), //!< Type of node. Added in 3.16
IsDataDefinedSize SIP_MONKEYPATCH_COMPAT_NAME( IsDataDefinedSizeRole ), //!< Set when a node is related to data defined size (title or separated legend items). Added in 3.38
};
Q_ENUM( CustomRole )
// *INDENT-ON*
Expand Down
5 changes: 5 additions & 0 deletions src/core/qgsdatadefinedsizelegend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "qgsdatadefinedsizelegend.h"

#include "qgslayertreemodellegendnode.h"
#include "qgsproperty.h"
#include "qgspropertytransformer.h"
#include "qgssymbollayerutils.h"
Expand Down Expand Up @@ -124,9 +125,11 @@ void QgsDataDefinedSizeLegend::updateFromSymbolAndProperty( const QgsMarkerSymbo
QgsLegendSymbolList QgsDataDefinedSizeLegend::legendSymbolList() const
{
QgsLegendSymbolList lst;
QVariant isDataDefinedSize( true );
if ( !mTitleLabel.isEmpty() )
{
QgsLegendSymbolItem title( nullptr, mTitleLabel, QString() );
title.setUserData( static_cast<int>( QgsLayerTreeModelLegendNode::CustomRole::IsDataDefinedSize ), isDataDefinedSize );
lst << title;
}

Expand All @@ -136,6 +139,7 @@ QgsLegendSymbolList QgsDataDefinedSizeLegend::legendSymbolList() const
{
QgsLegendSymbolItem i;
i.setDataDefinedSizeLegendSettings( new QgsDataDefinedSizeLegend( *this ) );
i.setUserData( static_cast<int>( QgsLayerTreeModelLegendNode::CustomRole::IsDataDefinedSize ), isDataDefinedSize );
lst << i;
break;
}
Expand All @@ -146,6 +150,7 @@ QgsLegendSymbolList QgsDataDefinedSizeLegend::legendSymbolList() const
for ( const SizeClass &cl : mSizeClasses )
{
QgsLegendSymbolItem si( mSymbol.get(), cl.label, QString() );
si.setUserData( static_cast<int>( QgsLayerTreeModelLegendNode::CustomRole::IsDataDefinedSize ), isDataDefinedSize );
QgsMarkerSymbol *s = static_cast<QgsMarkerSymbol *>( si.symbol() );
double size = cl.size;
if ( mSizeScaleTransformer )
Expand Down
11 changes: 11 additions & 0 deletions src/core/symbology/qgslegendsymbolitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ QgsLegendSymbolItem &QgsLegendSymbolItem::operator=( const QgsLegendSymbolItem &
mScaleMaxDenom = other.mScaleMaxDenom;
mLevel = other.mLevel;
mParentKey = other.mParentKey;
mUserData = other.mUserData;

return *this;
}
Expand Down Expand Up @@ -93,3 +94,13 @@ QgsDataDefinedSizeLegend *QgsLegendSymbolItem::dataDefinedSizeLegendSettings() c
{
return mDataDefinedSizeLegendSettings;
}

void QgsLegendSymbolItem::setUserData( int key, QVariant &value )
{
mUserData.insert( key, value );
}

QVariant QgsLegendSymbolItem::userData( int key ) const
{
return mUserData.value( key, QVariant() );
}
18 changes: 18 additions & 0 deletions src/core/symbology/qgslegendsymbolitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,22 @@ class CORE_EXPORT QgsLegendSymbolItem
*/
QgsDataDefinedSizeLegend *dataDefinedSizeLegendSettings() const;

/**
* Adds a \a key - \a value pair to the item's user data.
*
* \see userData()
* \since QGIS 3.38
*/
void setUserData( int key, QVariant &value );

/**
* Retrieves the item's user data with the specified \a key.
*
* \see setUserData()
* \since QGIS 3.38
*/
QVariant userData( int key ) const;

private:
//! Legend symbol -- may be NULLPTR.
QgsSymbol *mSymbol = nullptr;
Expand Down Expand Up @@ -135,6 +151,8 @@ class CORE_EXPORT QgsLegendSymbolItem
int mLevel = 0;
//! Key of the parent legend node. For legends with tree hierarchy
QString mParentKey;

QMap< int, QVariant > mUserData;
};

typedef QList< QgsLegendSymbolItem > QgsLegendSymbolList;
Expand Down
Loading
Loading