88 * All the other filtering flags fallback to the generic filtering done |
88 * All the other filtering flags fallback to the generic filtering done |
89 * in QContactManagerEngine (expected to be done by to the caller). Contacts |
89 * in QContactManagerEngine (expected to be done by to the caller). Contacts |
90 * are sorted only if the sort order is supported by contacts database. See |
90 * are sorted only if the sort order is supported by contacts database. See |
91 * CntSymbianSorterDbms::filterSupportLevel for the list of supported sort |
91 * CntSymbianSorterDbms::filterSupportLevel for the list of supported sort |
92 * orders. |
92 * orders. |
|
93 * |
|
94 * Using detail filter with match flag MatchPhoneNumber is implemented by the |
|
95 * contact model "phone number match" that filters by comparing the search |
|
96 * string characters (digits) starting from the rightmost digit. The detail |
|
97 * filter value must be at least 7 digits, otherwise an error code |
|
98 * NotSupportedError is given. The actual digit count that is used is 7 to 15 |
|
99 * digits, depending on the configuration of the device. |
93 * |
100 * |
94 * \a filter The QContactFilter to be used. |
101 * \a filter The QContactFilter to be used. |
95 * \a sortOrders The sort orders to be used. If the sort orders are not |
102 * \a sortOrders The sort orders to be used. If the sort orders are not |
96 * supported by contacts database this parameter is ignored and sorting needs |
103 * supported by contacts database this parameter is ignored and sorting needs |
97 * to be done by the caller. |
104 * to be done by the caller. |
99 */ |
106 */ |
100 QList<QContactLocalId> CntSymbianFilter::contacts( |
107 QList<QContactLocalId> CntSymbianFilter::contacts( |
101 const QContactFilter &filter, |
108 const QContactFilter &filter, |
102 const QList<QContactSortOrder> &sortOrders, |
109 const QList<QContactSortOrder> &sortOrders, |
103 bool &filterSupportedFlag, |
110 bool &filterSupportedFlag, |
104 QContactManager::Error &error) |
111 QContactManager::Error* error) |
105 { |
112 { |
106 QList<QContactLocalId> result; |
113 QList<QContactLocalId> result; |
107 |
114 |
108 // No need to proceed if some of the filters in the chain is not supported |
115 // No need to proceed if some of the filters in the chain is not supported |
109 if(!filterSupportedFlag) return result; |
116 if(!filterSupportedFlag) return result; |
132 // an intersection filter |
139 // an intersection filter |
133 } else if (filter.type() == QContactFilter::ContactDetailFilter |
140 } else if (filter.type() == QContactFilter::ContactDetailFilter |
134 && (static_cast<const QContactDetailFilter &>(filter)).value().type() == QVariant::StringList) { |
141 && (static_cast<const QContactDetailFilter &>(filter)).value().type() == QVariant::StringList) { |
135 QStringList values = (static_cast<const QContactDetailFilter &>(filter)).value().toStringList(); |
142 QStringList values = (static_cast<const QContactDetailFilter &>(filter)).value().toStringList(); |
136 QContactIntersectionFilter intersectionFilter; |
143 QContactIntersectionFilter intersectionFilter; |
137 foreach(QString value, values) { |
144 foreach(const QString& value, values) { |
138 QContactDetailFilter detailFilter = filter; |
145 QContactDetailFilter detailFilter = filter; |
139 detailFilter.setValue(value); |
146 detailFilter.setValue(value); |
140 intersectionFilter.append(detailFilter); |
147 intersectionFilter.append(detailFilter); |
141 } |
148 } |
142 // The resulting filter is handled with a recursive function call |
149 // The resulting filter is handled with a recursive function call |
143 result = contacts(intersectionFilter, sortOrders, filterSupportedFlag, error); |
150 result = contacts(intersectionFilter, sortOrders, filterSupportedFlag, error); |
144 } else { |
151 } else { |
145 if (filterSupportLevel(filter) == Supported) { |
152 FilterSupport filterSupport = filterSupportLevel(filter); |
|
153 if (filterSupport == Supported) { |
146 filterSupportedFlag = true; |
154 filterSupportedFlag = true; |
147 // Filter supported, use as the result directly |
155 // Filter supported, use as the result directly |
148 result = filterContacts(filter, error); |
156 result = filterContacts(filter, error); |
149 } else if (filterSupportLevel(filter) == SupportedPreFilterOnly) { |
157 } else if (filterSupport == SupportedPreFilterOnly) { |
150 // Filter only does pre-filtering, the caller is responsible of |
158 // Filter only does pre-filtering, the caller is responsible of |
151 // removing possible false positives after filtering |
159 // removing possible false positives after filtering |
152 filterSupportedFlag = false; |
160 filterSupportedFlag = false; |
153 result = filterContacts(filter, error); |
161 result = filterContacts(filter, error); |
|
162 } else if (filterSupport == IllegalFilter) { |
|
163 // Don't do filtering; fail with an error |
|
164 filterSupportedFlag = false; |
|
165 *error = QContactManager::NotSupportedError; |
154 } else { |
166 } else { |
155 // Don't do filtering here, return all contact ids and tell the |
167 // Don't do filtering here, return all contact ids and tell the |
156 // caller to do slow filtering |
168 // caller to do slow filtering |
157 filterSupportedFlag = false; |
169 filterSupportedFlag = false; |
158 result = filterContacts(QContactInvalidFilter(), error); |
170 result = filterContacts(QContactInvalidFilter(), error); |
223 |
235 |
224 // Phone numbers |
236 // Phone numbers |
225 if (defName == QContactPhoneNumber::DefinitionName) { |
237 if (defName == QContactPhoneNumber::DefinitionName) { |
226 |
238 |
227 if (matchFlags == QContactFilter::MatchPhoneNumber) { |
239 if (matchFlags == QContactFilter::MatchPhoneNumber) { |
228 return Supported; |
240 if (detailFilter.value().canConvert(QVariant::String)) { |
229 } |
241 if (detailFilter.value().toString().length() >= 7) { |
230 |
242 return Supported; |
231 if (matchFlags == QContactFilter::MatchExactly || |
243 } else { |
232 matchFlags == QContactFilter::MatchEndsWith || |
244 // It is a feature of Symbian contact model that phone |
233 matchFlags == QContactFilter::MatchFixedString) { |
245 // number match requires at least 7 digits. In case of |
234 return SupportedPreFilterOnly; |
246 // phone number match it is best to give an error as a |
|
247 // result because the phone number match logic would |
|
248 // not be much of use with less than 7 digit matching. |
|
249 // It would give false positives too often. |
|
250 return IllegalFilter; |
|
251 } |
|
252 } |
|
253 } else if (matchFlags == QContactFilter::MatchExactly |
|
254 || matchFlags == QContactFilter::MatchEndsWith |
|
255 || matchFlags == QContactFilter::MatchFixedString) { |
|
256 if (detailFilter.value().canConvert(QVariant::String)) { |
|
257 // It is a feature of Symbian contact model that phone |
|
258 // number match requires at least 7 digits |
|
259 if (detailFilter.value().toString().length() >= 7) { |
|
260 return SupportedPreFilterOnly; |
|
261 } |
|
262 } |
235 } |
263 } |
236 // Names |
264 // Names |
237 } else if (defName == QContactName::DefinitionName |
265 } else if (defName == QContactName::DefinitionName |
238 || defName == QContactNickname::DefinitionName |
266 || defName == QContactNickname::DefinitionName |
239 || defName == QContactEmailAddress::DefinitionName) { |
267 || defName == QContactEmailAddress::DefinitionName) { |
274 return NotSupported; |
302 return NotSupported; |
275 } |
303 } |
276 |
304 |
277 QList<QContactLocalId> CntSymbianFilter::filterContacts( |
305 QList<QContactLocalId> CntSymbianFilter::filterContacts( |
278 const QContactFilter& filter, |
306 const QContactFilter& filter, |
279 QContactManager::Error& error) |
307 QContactManager::Error* error) |
280 { |
308 { |
281 QList<QContactLocalId> matches; |
309 QList<QContactLocalId> matches; |
282 CContactIdArray* idArray(0); |
310 CContactIdArray* idArray(0); |
283 |
311 |
284 if (filter.type() == QContactFilter::InvalidFilter ){ |
312 if (filter.type() == QContactFilter::InvalidFilter) { |
285 TTime epoch(0); |
313 TTime epoch(0); |
286 idArray = m_contactDatabase.ContactsChangedSinceL(epoch); // return all contacts |
314 idArray = m_contactDatabase.ContactsChangedSinceL(epoch); // return all contacts |
287 } else if(filterSupportLevel(filter) == NotSupported) { |
315 } else if(filterSupportLevel(filter) == NotSupported) { |
288 error = QContactManager::NotSupportedError; |
316 *error = QContactManager::NotSupportedError; |
289 } else if (filter.type() == QContactFilter::ContactDetailFilter) { |
317 } else if (filter.type() == QContactFilter::ContactDetailFilter) { |
290 const QContactDetailFilter &detailFilter = static_cast<const QContactDetailFilter &>(filter); |
318 const QContactDetailFilter &detailFilter = static_cast<const QContactDetailFilter &>(filter); |
291 |
319 |
292 // Phone numbers |
320 // Phone numbers |
293 if (detailFilter.detailDefinitionName() == QContactPhoneNumber::DefinitionName) { |
321 if (detailFilter.detailDefinitionName() == QContactPhoneNumber::DefinitionName) { |
325 // for filtering with display label |
353 // for filtering with display label |
326 if (detailFilter.detailDefinitionName() == QContactDisplayLabel::DefinitionName |
354 if (detailFilter.detailDefinitionName() == QContactDisplayLabel::DefinitionName |
327 && detailFilter.matchFlags() == QContactFilter::MatchStartsWith) { |
355 && detailFilter.matchFlags() == QContactFilter::MatchStartsWith) { |
328 |
356 |
329 // Remove false positives |
357 // Remove false positives |
330 for(TInt i(0); i < idArray->Count(); i++) { |
358 for(TInt i(0); i < idArray->Count(); ++i) { |
331 CContactItem* contactItem = m_contactDatabase.ReadContactLC((*idArray)[i]); |
359 CContactItem* contactItem = m_contactDatabase.ReadContactLC((*idArray)[i]); |
332 const CContactItemFieldSet& fieldSet(contactItem->CardFields()); |
360 const CContactItemFieldSet& fieldSet(contactItem->CardFields()); |
333 if(isFalsePositive(fieldSet, KUidContactFieldGivenName, namePtr) |
361 if(isFalsePositive(fieldSet, KUidContactFieldGivenName, namePtr) |
334 && isFalsePositive(fieldSet, KUidContactFieldFamilyName, namePtr) |
362 && isFalsePositive(fieldSet, KUidContactFieldFamilyName, namePtr) |
335 && isFalsePositive(fieldSet, KUidContactFieldCompanyName, namePtr) |
363 && isFalsePositive(fieldSet, KUidContactFieldCompanyName, namePtr) |
403 // TODO: Refactor to use the transform classes |
431 // TODO: Refactor to use the transform classes |
404 // Names |
432 // Names |
405 if(detailFilter.detailDefinitionName() == QContactName::DefinitionName) { |
433 if(detailFilter.detailDefinitionName() == QContactName::DefinitionName) { |
406 if(detailFilter.detailFieldName() == QContactName::FieldPrefix) { |
434 if(detailFilter.detailFieldName() == QContactName::FieldPrefix) { |
407 tempFieldDef->AppendL(KUidContactFieldPrefixName); |
435 tempFieldDef->AppendL(KUidContactFieldPrefixName); |
408 } else if(detailFilter.detailFieldName() == QContactName::FieldFirst) { |
436 } else if(detailFilter.detailFieldName() == QContactName::FieldFirstName) { |
409 tempFieldDef->AppendL(KUidContactFieldGivenName); |
437 tempFieldDef->AppendL(KUidContactFieldGivenName); |
410 } else if(detailFilter.detailFieldName() == QContactName::FieldMiddle) { |
438 } else if(detailFilter.detailFieldName() == QContactName::FieldMiddleName) { |
411 tempFieldDef->AppendL(KUidContactFieldAdditionalName); |
439 tempFieldDef->AppendL(KUidContactFieldAdditionalName); |
412 } else if(detailFilter.detailFieldName() == QContactName::FieldLast) { |
440 } else if(detailFilter.detailFieldName() == QContactName::FieldLastName) { |
413 tempFieldDef->AppendL(KUidContactFieldFamilyName); |
441 tempFieldDef->AppendL(KUidContactFieldFamilyName); |
414 } else if(detailFilter.detailFieldName() == QContactName::FieldSuffix) { |
442 } else if(detailFilter.detailFieldName() == QContactName::FieldSuffix) { |
415 tempFieldDef->AppendL(KUidContactFieldSuffixName); |
443 tempFieldDef->AppendL(KUidContactFieldSuffixName); |
416 } else { |
444 } else { |
417 // default to all name fields |
445 // default to all name fields |