1# -*- coding: utf-8 -*-
2
3"""
4***************************************************************************
5    validitycheck.py
6    ---------------------
7    Date                 : January 2019
8    Copyright            : (C) 2019 by Nyall Dawson
9    Email                : nyall dot dawson at gmail dot com
10***************************************************************************
11*                                                                         *
12*   This program is free software; you can redistribute it and/or modify  *
13*   it under the terms of the GNU General Public License as published by  *
14*   the Free Software Foundation; either version 2 of the License, or     *
15*   (at your option) any later version.                                   *
16*                                                                         *
17***************************************************************************
18"""
19from qgis._core import (
20    QgsAbstractValidityCheck,
21    QgsApplication)
22
23
24class CheckFactory:
25    """
26    Constructs QgsAbstractValidityChecks using a decorator.
27
28    To use, Python based checks should use the decorator syntax:
29
30    .. highlight:: python
31    .. code-block:: python
32        @check.register(type=QgsAbstractValidityCheck.TypeLayoutCheck)
33        def my_layout_check(context, feedback):
34            results = ...
35            return results
36
37    """
38
39    def __init__(self):
40        # unfortunately /Transfer/ annotation isn't working correct on validityCheckRegistry().addCheck(),
41        # so we manually need to store a reference to all checks we register
42        self.checks = []
43
44    def register(self, type, *args, **kwargs):
45        """
46        Implements a decorator for registering Python based checks.
47
48        :param type: check type, e.g. QgsAbstractValidityCheck.TypeLayoutCheck
49        """
50
51        def dec(f):
52            check = CheckWrapper(check_type=type, check_func=f)
53            self.checks.append(check)
54            QgsApplication.validityCheckRegistry().addCheck(check)
55
56        return dec
57
58
59class CheckWrapper(QgsAbstractValidityCheck):
60    """
61    Wrapper object used to create new validity checks from @check.
62    """
63
64    def __init__(self, check_type, check_func):
65        """
66        Initializer for CheckWrapper.
67
68        :param check_type: check type, e.g. QgsAbstractValidityCheck.TypeLayoutCheck
69        :param check_func: test function, should return a list of QgsValidityCheckResult results
70        """
71        super().__init__()
72        self._check_type = check_type
73        self._results = []
74        self._check_func = check_func
75
76    def create(self):
77        return CheckWrapper(check_type=self._check_type, check_func=self._check_func)
78
79    def id(self):
80        return self._check_func.__name__
81
82    def checkType(self):
83        return self._check_type
84
85    def prepareCheck(self, context, feedback):
86        self._results = self._check_func(context, feedback)
87        if self._results is None:
88            self._results = []
89        return True
90
91    def runCheck(self, context, feedback):
92        return self._results
93
94
95check = CheckFactory()
96