1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2015 The Qt Company Ltd. |
4 | ** Contact: http://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtContacts module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL21$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see http://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at http://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 or version 3 as published by the Free |
20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and |
21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the |
22 | ** following information to ensure the GNU Lesser General Public License |
23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and |
24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
25 | ** |
26 | ** As a special exception, The Qt Company gives you certain additional |
27 | ** rights. These rights are described in The Qt Company LGPL Exception |
28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
29 | ** |
30 | ** $QT_END_LICENSE$ |
31 | ** |
32 | ****************************************************************************/ |
33 | |
34 | #include "qcontactfilter.h" |
35 | #include "qcontactfilter_p.h" |
36 | |
37 | #ifndef QT_NO_DATASTREAM |
38 | #include <QtCore/qdatastream.h> |
39 | #endif |
40 | #ifndef QT_NO_DEBUG_STREAM |
41 | #include <QtCore/qdebug.h> |
42 | #endif |
43 | |
44 | #include "qcontactfilters.h" |
45 | #include "qcontactmanager.h" |
46 | |
47 | /*! |
48 | \class QContactFilter |
49 | \brief The QContactFilter class is used to select contacts made available |
50 | through a QContactManager. |
51 | |
52 | \inmodule QtContacts |
53 | |
54 | \ingroup contacts-main |
55 | |
56 | This class is used as a parameter to various functions offered by QContactManager, to allow |
57 | selection of contacts which have certain details or properties. |
58 | */ |
59 | |
60 | /*! |
61 | \enum QContactFilter::FilterType |
62 | Describes the type of the filter |
63 | \value InvalidFilter An invalid filter which matches nothing |
64 | \value ContactDetailFilter A filter which matches contacts containing one or more details of a particular definition with a particular value |
65 | \value ContactDetailRangeFilter A filter which matches contacts containing one or more details of a particular definition whose values are within a particular range |
66 | \value ChangeLogFilter A filter which matches contacts whose timestamps have been updated since some particular date and time |
67 | \value ActionFilter A filter which matches contacts for which a particular action is available, or which contain a detail with a particular value for which a particular action is available |
68 | \value RelationshipFilter A filter which matches contacts which participate in a particular type of relationship, or relationship with a specified contact |
69 | \value IntersectionFilter A filter which matches all contacts that are matched by all filters it includes |
70 | \value UnionFilter A filter which matches any contact that is matched by any of the filters it includes |
71 | \value IdFilter A filter which matches any contact whose id is contained in a particular list of contact ids |
72 | \value DefaultFilter A filter which matches everything |
73 | */ |
74 | |
75 | /*! |
76 | \enum QContactFilter::MatchFlag |
77 | Describes the semantics of matching followed by the filter |
78 | \value MatchExactly Performs QVariant-based matching , combination of MatchExactly with other flags is not supported |
79 | \value MatchContains The search term is contained in the item |
80 | \value MatchStartsWith The search term matches the start of the item |
81 | \value MatchEndsWith The search term matches the end of the item |
82 | \value MatchFixedString Performs string-based matching. String-based comparisons are case-insensitive unless the \c MatchCaseSensitive flag is also specified |
83 | \value MatchCaseSensitive The search is case sensitive |
84 | \value MatchPhoneNumber The search term is considered to be in the form of a phone number, and special processing (removing dialing prefixes, non significant |
85 | characters like '-'. ')' etc). may be performed when matching the item. |
86 | \value MatchKeypadCollation The search term is in the form of text entered by a numeric phone keypad (such as ITU-T E.161 compliant keypads). Each digit in the |
87 | search term can represent a number of alphanumeric symbols. For example, the search string "43556" would match items "HELLO", "GEKKO", "HELL6" and "43556" among others. |
88 | Accented characters and other punctuation characters may additionally be matched by the QContactManager in a way consistent with the platform. |
89 | */ |
90 | |
91 | /*! |
92 | \fn QContactFilter::operator!=(const QContactFilter& other) const |
93 | Returns true if this filter is not identical to the \a other filter. |
94 | \sa operator==() |
95 | */ |
96 | |
97 | #if !defined(Q_CC_MWERKS) |
98 | template<> QTCONTACTS_PREPEND_NAMESPACE(QContactFilterPrivate) *QSharedDataPointer<QTCONTACTS_PREPEND_NAMESPACE(QContactFilterPrivate)>::clone() |
99 | { |
100 | return d->clone(); |
101 | } |
102 | #endif |
103 | |
104 | QT_BEGIN_NAMESPACE_CONTACTS |
105 | |
106 | /*! Constructs an empty filter */ |
107 | QContactFilter::QContactFilter() |
108 | : d_ptr(0) |
109 | { |
110 | } |
111 | |
112 | /*! Constructs a new copy of \a other */ |
113 | QContactFilter::QContactFilter(const QContactFilter& other) |
114 | : d_ptr(other.d_ptr) |
115 | { |
116 | } |
117 | |
118 | /*! Assigns this filter to be \a other |
119 | */ |
120 | QContactFilter& QContactFilter::operator=(const QContactFilter& other) |
121 | { |
122 | if (this != &other) { |
123 | d_ptr = other.d_ptr; |
124 | } |
125 | return *this; |
126 | } |
127 | |
128 | /*! Cleans up the memory used by this filter */ |
129 | QContactFilter::~QContactFilter() |
130 | { |
131 | } |
132 | |
133 | /*! Returns the type of the filter */ |
134 | QContactFilter::FilterType QContactFilter::type() const |
135 | { |
136 | if (!d_ptr) |
137 | return QContactFilter::DefaultFilter; |
138 | return d_ptr->type(); |
139 | } |
140 | |
141 | /*! Returns true if the filter has the same type and criteria as \a other |
142 | */ |
143 | bool QContactFilter::operator==(const QContactFilter& other) const |
144 | { |
145 | /* A default filter is only equal to other default filters */ |
146 | if (!d_ptr) |
147 | return !other.d_ptr; |
148 | |
149 | /* Different types can't be equal */ |
150 | if (other.type() != type()) |
151 | return false; |
152 | |
153 | /* Otherwise, use the virtual op == */ |
154 | return d_ptr->compare(other: other.d_ptr); |
155 | } |
156 | |
157 | #ifndef QT_NO_DATASTREAM |
158 | /*! |
159 | * Writes \a filter to the stream \a out. |
160 | */ |
161 | QDataStream& operator<<(QDataStream& out, const QContactFilter& filter) |
162 | { |
163 | quint8 formatVersion = 1; // Version of QDataStream format for QContactDetailFilter |
164 | out << formatVersion << static_cast<quint32>(filter.type()); |
165 | if (filter.d_ptr) |
166 | filter.d_ptr->outputToStream(stream&: out, formatVersion); |
167 | return out; |
168 | } |
169 | |
170 | /*! |
171 | * Reads a contact filter from stream \a in into \a filter. |
172 | */ |
173 | QDataStream& operator>>(QDataStream& in, QContactFilter& filter) |
174 | { |
175 | filter = QContactFilter(); |
176 | quint8 formatVersion; |
177 | in >> formatVersion; |
178 | if (formatVersion == 1) { |
179 | quint32 type; |
180 | in >> type; |
181 | switch (type) { |
182 | case QContactFilter::InvalidFilter: |
183 | filter = QContactInvalidFilter(); |
184 | break; |
185 | case QContactFilter::ContactDetailFilter: |
186 | filter = QContactDetailFilter(); |
187 | break; |
188 | case QContactFilter::ContactDetailRangeFilter: |
189 | filter = QContactDetailRangeFilter(); |
190 | break; |
191 | case QContactFilter::ChangeLogFilter: |
192 | filter = QContactChangeLogFilter(); |
193 | break; |
194 | case QContactFilter::ActionFilter: |
195 | filter = QContactActionFilter(); |
196 | break; |
197 | case QContactFilter::RelationshipFilter: |
198 | filter = QContactRelationshipFilter(); |
199 | break; |
200 | case QContactFilter::IntersectionFilter: |
201 | filter = QContactIntersectionFilter(); |
202 | break; |
203 | case QContactFilter::UnionFilter: |
204 | filter = QContactUnionFilter(); |
205 | break; |
206 | case QContactFilter::IdFilter: |
207 | filter = QContactIdFilter(); |
208 | break; |
209 | case QContactFilter::DefaultFilter: |
210 | filter = QContactFilter(); |
211 | break; |
212 | } |
213 | if (filter.d_ptr) |
214 | filter.d_ptr->inputFromStream(stream&: in, formatVersion); |
215 | } else { |
216 | in.setStatus(QDataStream::ReadCorruptData); |
217 | } |
218 | return in; |
219 | } |
220 | |
221 | #endif |
222 | |
223 | #ifndef QT_NO_DEBUG_STREAM |
224 | /*! |
225 | Outputs \a filter to the debug stream \a dbg |
226 | */ |
227 | QDebug operator<<(QDebug dbg, const QContactFilter& filter) |
228 | { |
229 | dbg.nospace() << "QContactFilter(" ; |
230 | if (filter.d_ptr) |
231 | filter.d_ptr->debugStreamOut(dbg); |
232 | else |
233 | dbg.nospace() << "(null)" ; |
234 | dbg.nospace() << ")" ; |
235 | return dbg.maybeSpace(); |
236 | } |
237 | #endif |
238 | |
239 | /*! |
240 | \internal |
241 | Constructs a new filter from the given data pointer \a d |
242 | */ |
243 | QContactFilter::QContactFilter(QContactFilterPrivate *d) |
244 | : d_ptr(d) |
245 | { |
246 | |
247 | } |
248 | |
249 | /*! |
250 | \relates QContactFilter |
251 | Returns a filter which is the intersection of the \a left and \a right filters |
252 | \sa QContactIntersectionFilter |
253 | */ |
254 | const QContactFilter operator&(const QContactFilter& left, const QContactFilter& right) |
255 | { |
256 | // XXX TODO: empty intersection/union operations are not well defined yet. |
257 | //if (left.type() == QContactFilter::Intersection) { |
258 | // QContactIntersectionFilter bf(left); |
259 | // /* we can just add the right to this one */ |
260 | // bf.append(right); |
261 | // return bf; |
262 | //} |
263 | |
264 | //if (right.type() == QContactFilter::Intersection) { |
265 | // QContactIntersectionFilter bf(right); |
266 | // /* we can prepend the left to this one */ |
267 | // bf.prepend(left); |
268 | // return bf; |
269 | //} |
270 | |
271 | /* usual fallback case */ |
272 | QContactIntersectionFilter nif; |
273 | nif << left << right; |
274 | return nif; |
275 | } |
276 | |
277 | /*! |
278 | \relates QContactFilter |
279 | Returns a filter which is the union of the \a left and \a right filters |
280 | \sa QContactUnionFilter |
281 | */ |
282 | const QContactFilter operator|(const QContactFilter& left, const QContactFilter& right) |
283 | { |
284 | if (left.type() == QContactFilter::UnionFilter) { |
285 | QContactUnionFilter bf(left); |
286 | /* we can just add the right to this one */ |
287 | bf.append(filter: right); |
288 | return bf; |
289 | } |
290 | |
291 | if (right.type() == QContactFilter::UnionFilter) { |
292 | QContactUnionFilter bf(right); |
293 | /* we can prepend the left to this one */ |
294 | bf.prepend(filter: left); |
295 | return bf; |
296 | } |
297 | |
298 | /* usual fallback case */ |
299 | QContactUnionFilter nif; |
300 | nif << left << right; |
301 | return nif; |
302 | } |
303 | |
304 | QT_END_NAMESPACE_CONTACTS |
305 | |