Skip to content

Commit 7ccaa3d

Browse files
committed
[FEATURE][API] Add flexible framework for custom "validity checks"
Adds a new interface QgsAbstractValidityCheck which defines a single "check" which can be performed on a given QgsValidityCheckContext. A new application-wide QgsValidityCheckRegistry registers and manages instances of all known checks, and allows running of all registered checks of a specific type at once. Initially the framework is focused toward print layout validity checks, but the interface has been designed to be generic enough to allow alternative types of validity checks (e.g. project save validity checks, processing model validity checks, etc.). The API is designed to be used both by internal validity checks and also to be extended by custom, organisation-specific validity checks. E.g., for print layout validity checks we could have:
1 parent ac6e674 commit 7ccaa3d

25 files changed

+1397
-0
lines changed

doc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ IF(WITH_APIDOC)
7878
${CMAKE_SOURCE_DIR}/src/core/raster
7979
${CMAKE_SOURCE_DIR}/src/core/scalebar
8080
${CMAKE_SOURCE_DIR}/src/core/symbology
81+
${CMAKE_SOURCE_DIR}/src/core/validity
8182
${CMAKE_SOURCE_DIR}/src/gui
8283
${CMAKE_SOURCE_DIR}/src/gui/auth
8384
${CMAKE_SOURCE_DIR}/src/gui/attributetable

python/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ INCLUDE_DIRECTORIES(
116116
${CMAKE_SOURCE_DIR}/src/core/raster
117117
${CMAKE_SOURCE_DIR}/src/core/scalebar
118118
${CMAKE_SOURCE_DIR}/src/core/symbology
119+
${CMAKE_SOURCE_DIR}/src/core/validity
119120
${CMAKE_SOURCE_DIR}/src/plugins
120121

121122
${CMAKE_BINARY_DIR} # qgsconfig.h, qgsversion.h

python/core/auto_generated/qgsapplication.sip.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,13 @@ Returns the application's image cache, used for caching resampled versions of ra
668668
Returns the application's network content registry used for fetching temporary files during QGIS session
669669

670670
.. versionadded:: 3.2
671+
%End
672+
673+
static QgsValidityCheckRegistry *validityCheckRegistry();
674+
%Docstring
675+
Returns the application's validity check registry, used for managing validity checks.
676+
677+
.. versionadded:: 3.6
671678
%End
672679

673680
static QgsSymbolLayerRegistry *symbolLayerRegistry();
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/core/validity/qgsabstractvaliditycheck.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
class QgsValidityCheckResult
12+
{
13+
%Docstring
14+
Represents an individual result from a validity check run by a QgsAbstractValidityCheck subclass.
15+
16+
Results can either be warnings or critical errors, as dictated by the type member. Critical error
17+
are errors which are serious enough to prevent an operation from proceeding, while a warning
18+
result will be communicated to users, but not prevent them from proceeding.
19+
20+
.. versionadded:: 3.6
21+
%End
22+
23+
%TypeHeaderCode
24+
#include "qgsabstractvaliditycheck.h"
25+
%End
26+
public:
27+
28+
enum Type
29+
{
30+
Warning,
31+
Critical,
32+
};
33+
34+
Type type;
35+
36+
QString title;
37+
38+
QString detailedDescription;
39+
40+
QString checkId;
41+
42+
};
43+
44+
45+
class QgsAbstractValidityCheck : QObject
46+
{
47+
%Docstring
48+
Abstract base class for individual validity checks.
49+
50+
Validity checks represent objects which can run a test using a :py:class:`QgsValidityCheckContext`, and return
51+
the results of the check via QgsValidityCheckResult objects.
52+
53+
Checks can be used for many different use cases, e.g. validating a layout's contents before allowing
54+
an export to occur, or validating the contents of a Processing model (and warning if required plugin based
55+
providers are not available or if compulsory algorithm parameters have not been populated).
56+
57+
Subclasses must indicate the type of check the represent via the checkType() method. When checks are performed,
58+
all the registered checks with a matching check type are performed sequentially. The check type also
59+
dictates the subclass of the QgsValidityCheckContext which is given to the subclass' runCheck method.
60+
61+
Checks must be registered in the application's :py:class:`QgsValidityCheckRegistry`, which is accessible via
62+
:py:func:`QgsApplication.validityCheckRegistry()`
63+
64+
.. seealso:: :py:class:`QgsValidityCheckRegistry`
65+
66+
.. versionadded:: 3.6
67+
%End
68+
69+
%TypeHeaderCode
70+
#include "qgsabstractvaliditycheck.h"
71+
%End
72+
public:
73+
74+
enum Type
75+
{
76+
TypeLayoutCheck,
77+
TypeUserCheck,
78+
};
79+
80+
virtual QString id() const = 0;
81+
%Docstring
82+
Returns the unique ID of the check.
83+
%End
84+
85+
virtual int checkType() const = 0;
86+
%Docstring
87+
Returns the type of the check.
88+
%End
89+
90+
virtual QString name() const = 0;
91+
%Docstring
92+
Returns the name of the check.
93+
%End
94+
95+
virtual QList< QgsValidityCheckResult > runCheck( const QgsValidityCheckContext *context, QgsFeedback *feedback ) const = 0;
96+
%Docstring
97+
Runs the check and returns a list of results. If the check is "passed" and no warnings or errors are generated,
98+
then an empty list should be returned.
99+
100+
The ``context`` argument gives the wider in which the check is being run.
101+
%End
102+
103+
};
104+
105+
106+
107+
108+
/************************************************************************
109+
* This file has been generated automatically from *
110+
* *
111+
* src/core/validity/qgsabstractvaliditycheck.h *
112+
* *
113+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
114+
************************************************************************/
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/core/validity/qgsvaliditycheckcontext.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
11+
class QgsValidityCheckContext
12+
{
13+
%Docstring
14+
Base class for validity check contexts.
15+
16+
QgsAbstractValidityCheck subclasses are passed a QgsValidityCheckContext subclass which
17+
encapsulates the context around that particular check type. For instance, a QgsAbstractValidityCheck
18+
of the QgsAbstractValidityCheck.TypeLayoutCheck type will be passed a QgsLayoutValidityCheckContext
19+
context, containing a reference to the QgsLayout to be checked.
20+
21+
.. versionadded:: 3.6
22+
%End
23+
24+
%TypeHeaderCode
25+
#include "qgsvaliditycheckcontext.h"
26+
%End
27+
public:
28+
29+
};
30+
31+
class QgsLayoutValidityCheckContext : QgsValidityCheckContext
32+
{
33+
%Docstring
34+
Validity check context for print layout validation.
35+
36+
QgsLayoutValidityCheckContext are passed to QgsAbstractValidityCheck subclasses which
37+
indicate they are of the QgsAbstractValidityCheck.TypeLayoutCheck type.
38+
39+
.. versionadded:: 3.6
40+
%End
41+
42+
%TypeHeaderCode
43+
#include "qgsvaliditycheckcontext.h"
44+
%End
45+
public:
46+
47+
QgsLayoutValidityCheckContext( QgsLayout *layout );
48+
%Docstring
49+
Constructor for QgsLayoutValidityCheckContext for the specified ``layout``.
50+
%End
51+
52+
QgsLayout *layout;
53+
54+
};
55+
/************************************************************************
56+
* This file has been generated automatically from *
57+
* *
58+
* src/core/validity/qgsvaliditycheckcontext.h *
59+
* *
60+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
61+
************************************************************************/
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/************************************************************************
2+
* This file has been generated automatically from *
3+
* *
4+
* src/core/validity/qgsvaliditycheckregistry.h *
5+
* *
6+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
7+
************************************************************************/
8+
9+
10+
class QgsValidityCheckRegistry
11+
{
12+
%Docstring
13+
This class keeps a list of QgsAbstractValidityCheck checks which can be used when
14+
performing validity checks.
15+
16+
QgsValidityCheckRegistry is not usually directly created, but rather accessed through
17+
:py:func:`QgsApplication.validityCheckRegistry()`
18+
19+
.. versionadded:: 3.6
20+
%End
21+
22+
%TypeHeaderCode
23+
#include "qgsvaliditycheckregistry.h"
24+
%End
25+
public:
26+
27+
QgsValidityCheckRegistry();
28+
29+
~QgsValidityCheckRegistry();
30+
31+
32+
QList<QgsAbstractValidityCheck *> checks() const;
33+
%Docstring
34+
Returns the list of available checks.
35+
%End
36+
37+
QList<QgsAbstractValidityCheck *> checks( int type ) const;
38+
%Docstring
39+
Returns the list of all available checks of the matching ``type``.
40+
%End
41+
42+
void addCheck( QgsAbstractValidityCheck *check /Transfer/ );
43+
%Docstring
44+
Adds a ``check`` to the registry. Ownership of the check
45+
is transferred to the registry.
46+
%End
47+
48+
void removeCheck( QgsAbstractValidityCheck *check );
49+
%Docstring
50+
Removes a ``check`` from the registry.
51+
The check object is automatically deleted.
52+
%End
53+
54+
QList< QgsValidityCheckResult > runChecks( int type, const QgsValidityCheckContext *context, QgsFeedback *feedback ) const;
55+
%Docstring
56+
Runs all checks of the specified ``type`` and returns a list of results.
57+
58+
If all checks are "passed" and no warnings or errors are generated, then
59+
an empty list will be returned.
60+
61+
The ``context`` argument gives the wider in which the check is being run.
62+
63+
The ``feedback`` argument is used to give progress reports and to support
64+
cancelation of long-running checks.
65+
%End
66+
67+
private:
68+
QgsValidityCheckRegistry( const QgsValidityCheckRegistry &rh );
69+
};
70+
71+
/************************************************************************
72+
* This file has been generated automatically from *
73+
* *
74+
* src/core/validity/qgsvaliditycheckregistry.h *
75+
* *
76+
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
77+
************************************************************************/

python/core/core_auto.sip

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,8 @@
305305
%Include auto_generated/fieldformatter/qgsvaluemapfieldformatter.sip
306306
%Include auto_generated/fieldformatter/qgsvaluerelationfieldformatter.sip
307307
%Include auto_generated/geocms/geonode/qgsgeonodeconnection.sip
308+
%Include auto_generated/validity/qgsvaliditycheckcontext.sip
309+
%Include auto_generated/validity/qgsvaliditycheckregistry.sip
308310
%Include auto_generated/gps/qgsqtlocationconnection.sip
309311
%Include auto_generated/gps/qgsgpsconnectionregistry.sip
310312
%Include auto_generated/qgsabstractcontentcache.sip
@@ -452,6 +454,7 @@
452454
%Include auto_generated/layertree/qgslayertreemodellegendnode.sip
453455
%Include auto_generated/layertree/qgslayertreenode.sip
454456
%Include auto_generated/layertree/qgslayertreeregistrybridge.sip
457+
%Include auto_generated/validity/qgsabstractvaliditycheck.sip
455458
%Include auto_generated/qgsuserprofilemanager.sip
456459
%Include auto_generated/symbology/qgsarrowsymbollayer.sip
457460
%Include auto_generated/qgsuserprofile.sip

0 commit comments

Comments
 (0)