1 /*
2     Copyright 2006 Kevin Ottens <ervin@kde.org>
3 
4     This library is free software; you can redistribute it and/or
5     modify it under the terms of the GNU Lesser General Public
6     License as published by the Free Software Foundation; either
7     version 2.1 of the License, or (at your option) version 3, or any
8     later version accepted by the membership of KDE e.V. (or its
9     successor approved by the membership of KDE e.V.), which shall
10     act as a proxy defined in Section 6 of version 3 of the license.
11 
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Lesser General Public License for more details.
16 
17     You should have received a copy of the GNU Lesser General Public
18     License along with this library. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #ifndef SOLID_PREDICATE_H
22 #define SOLID_PREDICATE_H
23 
24 #include <QVariant>
25 #include <QSet>
26 
27 #include <solid-lite/solid_export.h>
28 
29 #include <solid-lite/deviceinterface.h>
30 
31 namespace Solid
32 {
33     class Device;
34 
35     /**
36      * This class implements predicates for devices.
37      *
38      * A predicate is a logical condition that a given device can match or not.
39      * It's a constraint about the value a property must have in a given device
40      * interface, or any combination (conjunction, disjunction) of such
41      * constraints.
42      *
43      * FIXME: Add an example.
44      */
45     class SOLID_EXPORT Predicate
46     {
47     public:
48         /**
49          * The comparison operator which can be used for matching within the predicate.
50          *
51          * - Equals, the property and the value will match for strict equality
52          * - Mask, the property and the value will match if the bitmasking is not null
53          */
54         enum ComparisonOperator { Equals, Mask };
55 
56         /**
57          * The predicate type which controls how the predicate is handled
58          *
59          * - PropertyCheck, the predicate contains a comparison that needs to be matched using a ComparisonOperator
60          * - Conjunction, the two contained predicates need to be true for this predicate to be true
61          * - Disjunction, either of the two contained predicates may be true for this predicate to be true
62          * - InterfaceCheck, the device type is compared
63          */
64         enum Type { PropertyCheck, Conjunction, Disjunction, InterfaceCheck };
65 
66         /**
67          * Constructs an invalid predicate.
68          */
69         Predicate();
70 
71         /**
72          * Copy constructor.
73          *
74          * @param other the predicate to copy
75          */
76         Predicate(const Predicate &other);
77 
78         /**
79          * Constructs a predicate matching the value of a property in
80          * a given device interface.
81          *
82          * @param ifaceType the device interface type the device must have
83          * @param property the property name of the device interface
84          * @param value the value the property must have to make the device match
85          * @param compOperator the operator to apply between the property and the value when matching
86          */
87         Predicate(const DeviceInterface::Type &ifaceType,
88                    const QString &property, const QVariant &value,
89                    ComparisonOperator compOperator = Equals);
90 
91         /**
92          * Constructs a predicate matching the value of a property in
93          * a given device interface.
94          *
95          * @param ifaceName the name of the device interface the device must have
96          * @param property the property name of the device interface
97          * @param value the value the property must have to make the device match
98          * @param compOperator the operator to apply between the property and the value when matching
99          */
100         Predicate(const QString &ifaceName,
101                    const QString &property, const QVariant &value,
102                    ComparisonOperator compOperator = Equals);
103 
104         /**
105          * Constructs a predicate matching devices being of a particular device interface
106          *
107          * @param ifaceType the device interface the device must have
108          */
109         explicit Predicate(const DeviceInterface::Type &ifaceType);
110 
111         /**
112          * Constructs a predicate matching devices being of a particular device interface
113          *
114          * @param ifaceName the name of the device interface the device must have
115          */
116         explicit Predicate(const QString &ifaceName);
117 
118         /**
119          * Destroys a Predicate object.
120          */
121         ~Predicate();
122 
123 
124         /**
125          * Assignement operator.
126          *
127          * @param other the predicate to assign
128          * @return this predicate after having assigned 'other' to it
129          */
130         Predicate &operator=(const Predicate &other);
131 
132 
133         /**
134          * 'And' operator.
135          *
136          * @param other the second operand
137          * @return a new 'and' predicate having 'this' and 'other' as operands
138          */
139         Predicate operator &(const Predicate &other);
140 
141         /**
142          * 'AndEquals' operator.
143          *
144          * @param other the second operand
145          * @return assigns to 'this' a new 'and' predicate having 'this' and 'other' as operands
146          */
147         Predicate &operator &=(const Predicate &other);
148 
149         /**
150          * 'Or' operator.
151          *
152          * @param other the second operand
153          * @return a new 'or' predicate having 'this' and 'other' as operands
154          */
155         Predicate operator|(const Predicate &other);
156 
157         /**
158          * 'OrEquals' operator.
159          *
160          * @param other the second operand
161          * @return assigns to 'this' a new 'or' predicate having 'this' and 'other' as operands
162          */
163         Predicate &operator|=(const Predicate &other);
164 
165         /**
166          * Indicates if the predicate is valid.
167          *
168          * Predicate() is the only invalid predicate.
169          *
170          * @return true if the predicate is valid, false otherwise
171          */
172         bool isValid() const;
173 
174         /**
175          * Checks if a device matches the predicate.
176          *
177          * @param device the device to match against the predicate
178          * @return true if the given device matches the predicate, false otherwise
179          */
180         bool matches(const Device &device) const;
181 
182         /**
183          * Retrieves the device interface types used in this predicate.
184          *
185          * @return all the device interface types used in this predicate
186          */
187         QSet<DeviceInterface::Type> usedTypes() const;
188 
189         /**
190          * Converts the predicate to its string form.
191          *
192          * @return a string representation of the predicate
193          */
194         QString toString() const;
195 
196         /**
197          * Converts a string to a predicate.
198          *
199          * @param predicate the string to convert
200          * @return a new valid predicate if the given string is syntactically
201          * correct, Predicate() otherwise
202          */
203         static Predicate fromString(const QString &predicate);
204 
205         /**
206         * Retrieves the predicate type, used to determine how to handle the predicate
207         *
208         * @since 4.4
209         * @return the predicate type
210         */
211         Type type() const;
212 
213         /**
214          * Retrieves the interface type.
215          *
216          * @note This is only valid for InterfaceCheck and PropertyCheck types
217          * @since 4.4
218          * @return a device interface type used by the predicate
219          */
220         DeviceInterface::Type interfaceType() const;
221 
222         /**
223          * Retrieves the property name used when retrieving the value to compare against
224          *
225          * @note This is only valid for the PropertyCheck type
226          * @since 4.4
227          * @return a property name
228          */
229         QString propertyName() const;
230 
231         /**
232          * Retrieves the value used when comparing a devices property to see if it matches the predicate
233          *
234          * @note This is only valid for the PropertyCheck type
235          * @since 4.4
236          * @return the value used
237          */
238         QVariant matchingValue() const;
239 
240         /**
241          * Retrieves the comparison operator used to compare a property's value
242          *
243          * @since 4.4
244          * @note This is only valid for Conjunction and Disjunction types
245          * @return the comparison operator used
246          */
247         ComparisonOperator comparisonOperator() const;
248 
249         /**
250          * A smaller, inner predicate which is the first to appear and is compared with the second one
251          *
252          * @since 4.4
253          * @note This is only valid for Conjunction and Disjunction types
254          * @return The predicate used for the first operand
255          */
256         Predicate firstOperand() const;
257 
258         /**
259          * A smaller, inner predicate which is the second to appear and is compared with the first one
260          *
261          * @since 4.4
262          * @note This is only valid for Conjunction and Disjunction types
263          * @return The predicate used for the second operand
264          */
265         Predicate secondOperand() const;
266 
267     private:
268         class Private;
269         Private * const d;
270     };
271 }
272 
273 #endif
274