Skip to content

Commit

Permalink
Add more flexible/understandable api for setting layer tree legend fi…
Browse files Browse the repository at this point in the history
…lters

And update existing broken tests which are incorrectly showing
symbols which should not be visible in the legend
  • Loading branch information
nyalldawson committed Mar 26, 2023
1 parent efee735 commit 1742934
Show file tree
Hide file tree
Showing 18 changed files with 593 additions and 152 deletions.
7 changes: 7 additions & 0 deletions python/core/auto_additions/qgis.py
Expand Up @@ -2619,6 +2619,13 @@
# --
Qgis.LayerTreeInsertionMethod.baseClass = Qgis
# monkey patching scoped based enum
Qgis.LayerTreeFilterFlag.SkipVisibilityCheck.__doc__ = "If set, the standard visibility check should be skipped"
Qgis.LayerTreeFilterFlag.__doc__ = 'Layer tree filter flags.\n\n.. versionadded:: 3.32\n\n' + '* ``SkipVisibilityCheck``: ' + Qgis.LayerTreeFilterFlag.SkipVisibilityCheck.__doc__
# --
Qgis.LayerTreeFilterFlag.baseClass = Qgis
Qgis.LayerTreeFilterFlags.baseClass = Qgis
LayerTreeFilterFlags = Qgis # dirty hack since SIP seems to introduce the flags in module
# monkey patching scoped based enum
Qgis.ActionType.Invalid.__doc__ = "Invalid"
Qgis.ActionType.MapLayerAction.__doc__ = "Standard actions (defined by core or plugins), corresponds to QgsMapLayerAction class."
Qgis.ActionType.AttributeAction.__doc__ = "Custom actions (manually defined in layer properties), corresponds to QgsAction class."
Expand Down
130 changes: 130 additions & 0 deletions python/core/auto_generated/layertree/qgslayertreefiltersettings.sip.in
@@ -0,0 +1,130 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/layertree/qgslayertreefiltersettings.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsLayerTreeFilterSettings
{
%Docstring(signature="appended")
Contains settings relating to filtering the contents of :py:class:`QgsLayerTreeModel` and views.

.. versionadded:: 3.32
%End

%TypeHeaderCode
#include "qgslayertreefiltersettings.h"
%End
public:

explicit QgsLayerTreeFilterSettings( const QgsMapSettings &settings );
%Docstring
Constructor for QgsLayerTreeFilterSettings, using the specified map ``settings``.
%End

~QgsLayerTreeFilterSettings();

QgsLayerTreeFilterSettings( const QgsLayerTreeFilterSettings &other );
%Docstring
Copy constructor.
%End


void setMapSettings( const QgsMapSettings &settings );
%Docstring
Sets the map ``settings`` used to filter the legend content.

.. seealso:: :py:func:`mapSettings`
%End

QgsMapSettings &mapSettings();
%Docstring
Returns the map settings used to filter the legend content.

.. seealso:: :py:func:`setMapSettings`
%End

QMap<QString, QString> layerFilterExpressions() const;
%Docstring
Returns the map of layer IDs to legend filter expression.

.. seealso:: :py:func:`layerFilterExpression`

.. seealso:: :py:func:`setLayerFilterExpressions`
%End

void setLayerFilterExpressions( const QMap<QString, QString> &expressions );
%Docstring
Sets the map of layer IDs to legend filter expression.

.. seealso:: :py:func:`layerFilterExpressions`
%End

QString layerFilterExpression( const QString &layerId ) const;
%Docstring
Returns the filter expression to use for the layer with the specified
``layerId``, or an empty string if no expression is set for the layer.

.. seealso:: :py:func:`layerFilterExpressions`

.. seealso:: :py:func:`setLayerFilterExpressions`
%End

QgsGeometry filterPolygon() const;
%Docstring
Returns the optional filter polygon, used when testing for symbols to show in
the legend.

The CRS of the polygon will match the destination CRS of :py:func:`~QgsLayerTreeFilterSettings.mapSettings`.

If not set then the filter visibility extent will use the extent of :py:func:`~QgsLayerTreeFilterSettings.mapSettings`.

.. seealso:: :py:func:`setFilterPolygon`
%End

void setFilterPolygon( const QgsGeometry &polygon );
%Docstring
Sets the optional filter ``polygon``, used when testing for symbols to show in
the legend.

The CRS of the polygon must match the destination CRS of :py:func:`~QgsLayerTreeFilterSettings.mapSettings`.

If not set then the filter visibility extent will use the extent of :py:func:`~QgsLayerTreeFilterSettings.mapSettings`.

.. seealso:: :py:func:`filterPolygon`
%End

Qgis::LayerTreeFilterFlags flags() const;
%Docstring
Returns the filter flags.

.. seealso:: :py:func:`setFlags`
%End

void setFlags( Qgis::LayerTreeFilterFlags flags );
%Docstring
Sets the filter ``flags``.

.. seealso:: :py:func:`flags`
%End

QList<QgsMapLayer *> layers() const;
%Docstring
Returns the layers which should be shown in the legend.
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/layertree/qgslayertreefiltersettings.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
20 changes: 20 additions & 0 deletions python/core/auto_generated/layertree/qgslayertreemodel.sip.in
Expand Up @@ -280,6 +280,26 @@ Filter display of legend nodes for given map settings
Returns the current map settings used for the current legend filter (or ``None`` if none is enabled)

.. versionadded:: 2.14
%End

void setFilterSettings( const QgsLayerTreeFilterSettings *settings = 0 );
%Docstring
Sets the filter ``settings`` to use to filter legend nodes.

Set to ``None`` to disable legend filter.

.. seealso:: :py:func:`filterSettings`

.. versionadded:: 3.32
%End

const QgsLayerTreeFilterSettings *filterSettings() const;
%Docstring
Returns the filter settings to use to filter legend nodes. May be ``None``.

.. seealso:: :py:func:`setFilterSettings`

.. versionadded:: 3.32
%End

void setLegendMapViewData( double mapUnitsPerPixel, int dpi, double scale );
Expand Down
10 changes: 10 additions & 0 deletions python/core/auto_generated/qgis.sip.in
Expand Up @@ -1613,6 +1613,14 @@ The development version
OptimalInInsertionGroup,
};

enum class LayerTreeFilterFlag
{
SkipVisibilityCheck,
};

typedef QFlags<Qgis::LayerTreeFilterFlag> LayerTreeFilterFlags;


enum class ActionType
{
Invalid,
Expand Down Expand Up @@ -2031,6 +2039,8 @@ QFlags<Qgis::SettingsTreeNodeOption> operator|(Qgis::SettingsTreeNodeOption f1,

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

QFlags<Qgis::LayerTreeFilterFlag> operator|(Qgis::LayerTreeFilterFlag f1, QFlags<Qgis::LayerTreeFilterFlag> f2);




Expand Down
23 changes: 9 additions & 14 deletions python/core/auto_generated/qgsmaphittest.sip.in
Expand Up @@ -35,6 +35,13 @@ will be visible on the map - this is useful for content based legend.
QgsMapHitTest( const QgsMapSettings &settings, const QgsMapHitTest::LayerFilterExpression &layerFilterExpression );
%Docstring
Constructor version used with only expressions to filter symbols (no extent or polygon intersection)
%End

QgsMapHitTest( const QgsLayerTreeFilterSettings &settings );
%Docstring
Constructor based off layer tree filter ``settings``.

.. versionadded:: 3.32
%End

void run();
Expand Down Expand Up @@ -92,21 +99,9 @@ Executes a QgsMapHitTest in a background thread.
%End
public:

QgsMapHitTestTask( const QgsMapSettings &settings, const QgsGeometry &polygon = QgsGeometry(), const QgsMapHitTest::LayerFilterExpression &layerFilterExpression = QgsMapHitTest::LayerFilterExpression() );
QgsMapHitTestTask( const QgsLayerTreeFilterSettings &settings );
%Docstring
Constructor for QgsMapHitTestTask, filtering by a visible geometry.

:param settings: Map settings used to evaluate symbols
:param polygon: Polygon geometry to refine the hit test
:param layerFilterExpression: Expression string for each layer id to evaluate in order to refine the symbol selection
%End

QgsMapHitTestTask( const QgsMapSettings &settings, const QgsMapHitTest::LayerFilterExpression &layerFilterExpression );
%Docstring
Constructor for QgsMapHitTestTask, filtering by expressions.

:param settings: Map settings used to evaluate symbols
:param layerFilterExpression: Expression string for each layer id to evaluate in order to refine the symbol selection
Constructor for QgsMapHitTestTask, using the specified filter ``settings``.
%End


Expand Down
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -380,6 +380,7 @@
%Include auto_generated/layertree/qgscolorramplegendnode.sip
%Include auto_generated/layertree/qgscolorramplegendnodesettings.sip
%Include auto_generated/layertree/qgslayertree.sip
%Include auto_generated/layertree/qgslayertreefiltersettings.sip
%Include auto_generated/layertree/qgslayertreegroup.sip
%Include auto_generated/layertree/qgslayertreelayer.sip
%Include auto_generated/layertree/qgslayertreemodel.sip
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -160,6 +160,7 @@ set(QGIS_CORE_SRCS

layertree/qgscolorramplegendnode.cpp
layertree/qgscolorramplegendnodesettings.cpp
layertree/qgslayertreefiltersettings.cpp
layertree/qgslayertreegroup.cpp
layertree/qgslayertreelayer.cpp
layertree/qgslayertreemodel.cpp
Expand Down Expand Up @@ -1455,6 +1456,7 @@ set(QGIS_CORE_HDRS
layertree/qgscolorramplegendnode.h
layertree/qgscolorramplegendnodesettings.h
layertree/qgslayertree.h
layertree/qgslayertreefiltersettings.h
layertree/qgslayertreegroup.h
layertree/qgslayertreelayer.h
layertree/qgslayertreemodel.h
Expand Down
91 changes: 91 additions & 0 deletions src/core/layertree/qgslayertreefiltersettings.cpp
@@ -0,0 +1,91 @@
/***************************************************************************
qgslayertreefiltersettings.cpp
--------------------------------------
Date : March 2023
Copyright : (C) 2023 by Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgslayertreefiltersettings.h"
#include "qgsmapsettings.h"

QgsLayerTreeFilterSettings::QgsLayerTreeFilterSettings( const QgsMapSettings &settings )
: mMapSettings( std::make_unique<QgsMapSettings>( settings ) )
{}

QgsLayerTreeFilterSettings::~QgsLayerTreeFilterSettings() = default;

QgsLayerTreeFilterSettings::QgsLayerTreeFilterSettings( const QgsLayerTreeFilterSettings &other )
: mLayerFilterExpressions( other.mLayerFilterExpressions )
, mMapSettings( other.mMapSettings ? new QgsMapSettings( *other.mMapSettings ) : nullptr )
, mFilterPolygon( other.mFilterPolygon )
, mFlags( other.mFlags )
{

}

QgsLayerTreeFilterSettings &QgsLayerTreeFilterSettings::operator=( const QgsLayerTreeFilterSettings &other )
{
mLayerFilterExpressions = other.mLayerFilterExpressions;
mMapSettings.reset( other.mMapSettings ? new QgsMapSettings( *other.mMapSettings ) : nullptr );
mFilterPolygon = other.mFilterPolygon;
mFlags = other.mFlags;
return *this;
}

void QgsLayerTreeFilterSettings::setMapSettings( const QgsMapSettings &settings )
{
mMapSettings.reset( new QgsMapSettings( settings ) );
}

QgsMapSettings &QgsLayerTreeFilterSettings::mapSettings()
{
return *mMapSettings.get();
}

QMap<QString, QString> QgsLayerTreeFilterSettings::layerFilterExpressions() const
{
return mLayerFilterExpressions;
}

void QgsLayerTreeFilterSettings::setLayerFilterExpressions( const QMap<QString, QString> &expressions )
{
mLayerFilterExpressions = expressions;
}

QString QgsLayerTreeFilterSettings::layerFilterExpression( const QString &layerId ) const
{
return mLayerFilterExpressions.value( layerId );
}

QgsGeometry QgsLayerTreeFilterSettings::filterPolygon() const
{
return mFilterPolygon;
}

void QgsLayerTreeFilterSettings::setFilterPolygon( const QgsGeometry &newFilterPolygon )
{
mFilterPolygon = newFilterPolygon;
}

Qgis::LayerTreeFilterFlags QgsLayerTreeFilterSettings::flags() const
{
return mFlags;
}

void QgsLayerTreeFilterSettings::setFlags( Qgis::LayerTreeFilterFlags flags )
{
mFlags = flags;
}

QList<QgsMapLayer *> QgsLayerTreeFilterSettings::layers() const
{
return mMapSettings->layers( true );
}

0 comments on commit 1742934

Please sign in to comment.