Skip to content

Commit 1742934

Browse files
committedMar 26, 2023
Add more flexible/understandable api for setting layer tree legend filters
And update existing broken tests which are incorrectly showing symbols which should not be visible in the legend
1 parent efee735 commit 1742934

18 files changed

+593
-152
lines changed
 

‎python/core/auto_additions/qgis.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2619,6 +2619,13 @@
26192619
# --
26202620
Qgis.LayerTreeInsertionMethod.baseClass = Qgis
26212621
# monkey patching scoped based enum
2622+
Qgis.LayerTreeFilterFlag.SkipVisibilityCheck.__doc__ = "If set, the standard visibility check should be skipped"
2623+
Qgis.LayerTreeFilterFlag.__doc__ = 'Layer tree filter flags.\n\n.. versionadded:: 3.32\n\n' + '* ``SkipVisibilityCheck``: ' + Qgis.LayerTreeFilterFlag.SkipVisibilityCheck.__doc__
2624+
# --
2625+
Qgis.LayerTreeFilterFlag.baseClass = Qgis
2626+
Qgis.LayerTreeFilterFlags.baseClass = Qgis
2627+
LayerTreeFilterFlags = Qgis # dirty hack since SIP seems to introduce the flags in module
2628+
# monkey patching scoped based enum
26222629
Qgis.ActionType.Invalid.__doc__ = "Invalid"
26232630
Qgis.ActionType.MapLayerAction.__doc__ = "Standard actions (defined by core or plugins), corresponds to QgsMapLayerAction class."
26242631
Qgis.ActionType.AttributeAction.__doc__ = "Custom actions (manually defined in layer properties), corresponds to QgsAction class."
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/core/layertree/qgslayertreefiltersettings.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
12+
13+
class QgsLayerTreeFilterSettings
14+
{
15+
%Docstring(signature="appended")
16+
Contains settings relating to filtering the contents of :py:class:`QgsLayerTreeModel` and views.
17+
18+
.. versionadded:: 3.32
19+
%End
20+
21+
%TypeHeaderCode
22+
#include "qgslayertreefiltersettings.h"
23+
%End
24+
public:
25+
26+
explicit QgsLayerTreeFilterSettings( const QgsMapSettings &settings );
27+
%Docstring
28+
Constructor for QgsLayerTreeFilterSettings, using the specified map ``settings``.
29+
%End
30+
31+
~QgsLayerTreeFilterSettings();
32+
33+
QgsLayerTreeFilterSettings( const QgsLayerTreeFilterSettings &other );
34+
%Docstring
35+
Copy constructor.
36+
%End
37+
38+
39+
void setMapSettings( const QgsMapSettings &settings );
40+
%Docstring
41+
Sets the map ``settings`` used to filter the legend content.
42+
43+
.. seealso:: :py:func:`mapSettings`
44+
%End
45+
46+
QgsMapSettings &mapSettings();
47+
%Docstring
48+
Returns the map settings used to filter the legend content.
49+
50+
.. seealso:: :py:func:`setMapSettings`
51+
%End
52+
53+
QMap<QString, QString> layerFilterExpressions() const;
54+
%Docstring
55+
Returns the map of layer IDs to legend filter expression.
56+
57+
.. seealso:: :py:func:`layerFilterExpression`
58+
59+
.. seealso:: :py:func:`setLayerFilterExpressions`
60+
%End
61+
62+
void setLayerFilterExpressions( const QMap<QString, QString> &expressions );
63+
%Docstring
64+
Sets the map of layer IDs to legend filter expression.
65+
66+
.. seealso:: :py:func:`layerFilterExpressions`
67+
%End
68+
69+
QString layerFilterExpression( const QString &layerId ) const;
70+
%Docstring
71+
Returns the filter expression to use for the layer with the specified
72+
``layerId``, or an empty string if no expression is set for the layer.
73+
74+
.. seealso:: :py:func:`layerFilterExpressions`
75+
76+
.. seealso:: :py:func:`setLayerFilterExpressions`
77+
%End
78+
79+
QgsGeometry filterPolygon() const;
80+
%Docstring
81+
Returns the optional filter polygon, used when testing for symbols to show in
82+
the legend.
83+
84+
The CRS of the polygon will match the destination CRS of :py:func:`~QgsLayerTreeFilterSettings.mapSettings`.
85+
86+
If not set then the filter visibility extent will use the extent of :py:func:`~QgsLayerTreeFilterSettings.mapSettings`.
87+
88+
.. seealso:: :py:func:`setFilterPolygon`
89+
%End
90+
91+
void setFilterPolygon( const QgsGeometry &polygon );
92+
%Docstring
93+
Sets the optional filter ``polygon``, used when testing for symbols to show in
94+
the legend.
95+
96+
The CRS of the polygon must match the destination CRS of :py:func:`~QgsLayerTreeFilterSettings.mapSettings`.
97+
98+
If not set then the filter visibility extent will use the extent of :py:func:`~QgsLayerTreeFilterSettings.mapSettings`.
99+
100+
.. seealso:: :py:func:`filterPolygon`
101+
%End
102+
103+
Qgis::LayerTreeFilterFlags flags() const;
104+
%Docstring
105+
Returns the filter flags.
106+
107+
.. seealso:: :py:func:`setFlags`
108+
%End
109+
110+
void setFlags( Qgis::LayerTreeFilterFlags flags );
111+
%Docstring
112+
Sets the filter ``flags``.
113+
114+
.. seealso:: :py:func:`flags`
115+
%End
116+
117+
QList<QgsMapLayer *> layers() const;
118+
%Docstring
119+
Returns the layers which should be shown in the legend.
120+
%End
121+
122+
};
123+
124+
/************************************************************************
125+
* This file has been generated automatically from *
126+
* *
127+
* src/core/layertree/qgslayertreefiltersettings.h *
128+
* *
129+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
130+
************************************************************************/

‎python/core/auto_generated/layertree/qgslayertreemodel.sip.in

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,26 @@ Filter display of legend nodes for given map settings
280280
Returns the current map settings used for the current legend filter (or ``None`` if none is enabled)
281281

282282
.. versionadded:: 2.14
283+
%End
284+
285+
void setFilterSettings( const QgsLayerTreeFilterSettings *settings = 0 );
286+
%Docstring
287+
Sets the filter ``settings`` to use to filter legend nodes.
288+
289+
Set to ``None`` to disable legend filter.
290+
291+
.. seealso:: :py:func:`filterSettings`
292+
293+
.. versionadded:: 3.32
294+
%End
295+
296+
const QgsLayerTreeFilterSettings *filterSettings() const;
297+
%Docstring
298+
Returns the filter settings to use to filter legend nodes. May be ``None``.
299+
300+
.. seealso:: :py:func:`setFilterSettings`
301+
302+
.. versionadded:: 3.32
283303
%End
284304

285305
void setLegendMapViewData( double mapUnitsPerPixel, int dpi, double scale );

‎python/core/auto_generated/qgis.sip.in

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,6 +1613,14 @@ The development version
16131613
OptimalInInsertionGroup,
16141614
};
16151615

1616+
enum class LayerTreeFilterFlag
1617+
{
1618+
SkipVisibilityCheck,
1619+
};
1620+
1621+
typedef QFlags<Qgis::LayerTreeFilterFlag> LayerTreeFilterFlags;
1622+
1623+
16161624
enum class ActionType
16171625
{
16181626
Invalid,
@@ -2031,6 +2039,8 @@ QFlags<Qgis::SettingsTreeNodeOption> operator|(Qgis::SettingsTreeNodeOption f1,
20312039

20322040
QFlags<Qgis::ScriptLanguageCapability> operator|(Qgis::ScriptLanguageCapability f1, QFlags<Qgis::ScriptLanguageCapability> f2);
20332041

2042+
QFlags<Qgis::LayerTreeFilterFlag> operator|(Qgis::LayerTreeFilterFlag f1, QFlags<Qgis::LayerTreeFilterFlag> f2);
2043+
20342044

20352045

20362046

‎python/core/auto_generated/qgsmaphittest.sip.in

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ will be visible on the map - this is useful for content based legend.
3535
QgsMapHitTest( const QgsMapSettings &settings, const QgsMapHitTest::LayerFilterExpression &layerFilterExpression );
3636
%Docstring
3737
Constructor version used with only expressions to filter symbols (no extent or polygon intersection)
38+
%End
39+
40+
QgsMapHitTest( const QgsLayerTreeFilterSettings &settings );
41+
%Docstring
42+
Constructor based off layer tree filter ``settings``.
43+
44+
.. versionadded:: 3.32
3845
%End
3946

4047
void run();
@@ -92,21 +99,9 @@ Executes a QgsMapHitTest in a background thread.
9299
%End
93100
public:
94101

95-
QgsMapHitTestTask( const QgsMapSettings &settings, const QgsGeometry &polygon = QgsGeometry(), const QgsMapHitTest::LayerFilterExpression &layerFilterExpression = QgsMapHitTest::LayerFilterExpression() );
102+
QgsMapHitTestTask( const QgsLayerTreeFilterSettings &settings );
96103
%Docstring
97-
Constructor for QgsMapHitTestTask, filtering by a visible geometry.
98-
99-
:param settings: Map settings used to evaluate symbols
100-
:param polygon: Polygon geometry to refine the hit test
101-
:param layerFilterExpression: Expression string for each layer id to evaluate in order to refine the symbol selection
102-
%End
103-
104-
QgsMapHitTestTask( const QgsMapSettings &settings, const QgsMapHitTest::LayerFilterExpression &layerFilterExpression );
105-
%Docstring
106-
Constructor for QgsMapHitTestTask, filtering by expressions.
107-
108-
:param settings: Map settings used to evaluate symbols
109-
:param layerFilterExpression: Expression string for each layer id to evaluate in order to refine the symbol selection
104+
Constructor for QgsMapHitTestTask, using the specified filter ``settings``.
110105
%End
111106

112107

‎python/core/core_auto.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@
380380
%Include auto_generated/layertree/qgscolorramplegendnode.sip
381381
%Include auto_generated/layertree/qgscolorramplegendnodesettings.sip
382382
%Include auto_generated/layertree/qgslayertree.sip
383+
%Include auto_generated/layertree/qgslayertreefiltersettings.sip
383384
%Include auto_generated/layertree/qgslayertreegroup.sip
384385
%Include auto_generated/layertree/qgslayertreelayer.sip
385386
%Include auto_generated/layertree/qgslayertreemodel.sip

‎src/core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ set(QGIS_CORE_SRCS
160160

161161
layertree/qgscolorramplegendnode.cpp
162162
layertree/qgscolorramplegendnodesettings.cpp
163+
layertree/qgslayertreefiltersettings.cpp
163164
layertree/qgslayertreegroup.cpp
164165
layertree/qgslayertreelayer.cpp
165166
layertree/qgslayertreemodel.cpp
@@ -1455,6 +1456,7 @@ set(QGIS_CORE_HDRS
14551456
layertree/qgscolorramplegendnode.h
14561457
layertree/qgscolorramplegendnodesettings.h
14571458
layertree/qgslayertree.h
1459+
layertree/qgslayertreefiltersettings.h
14581460
layertree/qgslayertreegroup.h
14591461
layertree/qgslayertreelayer.h
14601462
layertree/qgslayertreemodel.h
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/***************************************************************************
2+
qgslayertreefiltersettings.cpp
3+
--------------------------------------
4+
Date : March 2023
5+
Copyright : (C) 2023 by Nyall Dawson
6+
Email : nyall dot dawson at gmail dot com
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgslayertreefiltersettings.h"
17+
#include "qgsmapsettings.h"
18+
19+
QgsLayerTreeFilterSettings::QgsLayerTreeFilterSettings( const QgsMapSettings &settings )
20+
: mMapSettings( std::make_unique<QgsMapSettings>( settings ) )
21+
{}
22+
23+
QgsLayerTreeFilterSettings::~QgsLayerTreeFilterSettings() = default;
24+
25+
QgsLayerTreeFilterSettings::QgsLayerTreeFilterSettings( const QgsLayerTreeFilterSettings &other )
26+
: mLayerFilterExpressions( other.mLayerFilterExpressions )
27+
, mMapSettings( other.mMapSettings ? new QgsMapSettings( *other.mMapSettings ) : nullptr )
28+
, mFilterPolygon( other.mFilterPolygon )
29+
, mFlags( other.mFlags )
30+
{
31+
32+
}
33+
34+
QgsLayerTreeFilterSettings &QgsLayerTreeFilterSettings::operator=( const QgsLayerTreeFilterSettings &other )
35+
{
36+
mLayerFilterExpressions = other.mLayerFilterExpressions;
37+
mMapSettings.reset( other.mMapSettings ? new QgsMapSettings( *other.mMapSettings ) : nullptr );
38+
mFilterPolygon = other.mFilterPolygon;
39+
mFlags = other.mFlags;
40+
return *this;
41+
}
42+
43+
void QgsLayerTreeFilterSettings::setMapSettings( const QgsMapSettings &settings )
44+
{
45+
mMapSettings.reset( new QgsMapSettings( settings ) );
46+
}
47+
48+
QgsMapSettings &QgsLayerTreeFilterSettings::mapSettings()
49+
{
50+
return *mMapSettings.get();
51+
}
52+
53+
QMap<QString, QString> QgsLayerTreeFilterSettings::layerFilterExpressions() const
54+
{
55+
return mLayerFilterExpressions;
56+
}
57+
58+
void QgsLayerTreeFilterSettings::setLayerFilterExpressions( const QMap<QString, QString> &expressions )
59+
{
60+
mLayerFilterExpressions = expressions;
61+
}
62+
63+
QString QgsLayerTreeFilterSettings::layerFilterExpression( const QString &layerId ) const
64+
{
65+
return mLayerFilterExpressions.value( layerId );
66+
}
67+
68+
QgsGeometry QgsLayerTreeFilterSettings::filterPolygon() const
69+
{
70+
return mFilterPolygon;
71+
}
72+
73+
void QgsLayerTreeFilterSettings::setFilterPolygon( const QgsGeometry &newFilterPolygon )
74+
{
75+
mFilterPolygon = newFilterPolygon;
76+
}
77+
78+
Qgis::LayerTreeFilterFlags QgsLayerTreeFilterSettings::flags() const
79+
{
80+
return mFlags;
81+
}
82+
83+
void QgsLayerTreeFilterSettings::setFlags( Qgis::LayerTreeFilterFlags flags )
84+
{
85+
mFlags = flags;
86+
}
87+
88+
QList<QgsMapLayer *> QgsLayerTreeFilterSettings::layers() const
89+
{
90+
return mMapSettings->layers( true );
91+
}

0 commit comments

Comments
 (0)
Please sign in to comment.