75 bool &filterSupportedflag, |
73 bool &filterSupportedflag, |
76 QContactManager::Error* error) |
74 QContactManager::Error* error) |
77 { |
75 { |
78 Q_UNUSED(filterSupportedflag); |
76 Q_UNUSED(filterSupportedflag); |
79 //Check if any invalid filter is passed |
77 //Check if any invalid filter is passed |
80 if(!filterSupported(filter) ) |
78 if (!filterSupported(filter) ) { |
81 { |
|
82 *error = QContactManager::NotSupportedError; |
79 *error = QContactManager::NotSupportedError; |
83 return QList<QContactLocalId>(); |
80 return QList<QContactLocalId>(); |
84 } |
81 } |
85 QList<QContactLocalId> idList; |
82 QList<QContactLocalId> idList; |
86 QContactDetailFilter detailFilter(filter); |
83 QContactDetailFilter detailFilter(filter); |
87 QString sqlQuery; |
84 QString sqlQuery; |
88 //Check for phonenumber. Special handling needed |
85 //Check for phonenumber. Special handling needed |
89 if( (detailFilter.detailDefinitionName() == QContactPhoneNumber::DefinitionName ) && |
86 if ( (detailFilter.detailDefinitionName() == QContactPhoneNumber::DefinitionName ) && |
90 (detailFilter.detailFieldName() != QContactPhoneNumber::FieldSubTypes)) |
87 (detailFilter.detailFieldName() != QContactPhoneNumber::FieldSubTypes)) { |
91 { |
|
92 //Handle phonenumber ... |
88 //Handle phonenumber ... |
93 idList = HandlePhonenumberDetailFilter(filter); |
89 createMatchPhoneNumberQuery(filter,sqlQuery,error); |
|
90 if (*error == QContactManager::NoError) { |
|
91 //fetch the contacts |
|
92 idList = m_srvConnection.searchContacts(sqlQuery, error); |
|
93 } |
94 |
94 |
95 } |
95 } |
96 else if (detailFilter.matchFlags() == QContactFilter::MatchKeypadCollation) |
96 else if (detailFilter.matchFlags() == QContactFilter::MatchKeypadCollation) { |
97 { |
|
98 //predictive search filter |
97 //predictive search filter |
99 idList = HandlePredictiveSearchFilter(filter,error); |
98 idList = HandlePredictiveSearchFilter(filter,error); |
100 } |
99 } |
101 |
100 |
102 // handle other cases |
101 // handle other cases |
103 else |
102 else { |
104 { |
|
105 createSelectQuery(filter,sqlQuery,error); |
103 createSelectQuery(filter,sqlQuery,error); |
106 QString sortQuery = m_dbInfo.getSortQuery(sortOrders, sqlQuery, error); |
104 QString sortQuery = m_dbInfo.getSortQuery(sortOrders, sqlQuery, error); |
107 |
105 |
108 if(*error == QContactManager::NoError) |
106 if (*error == QContactManager::NoError) { |
109 { |
|
110 //fetch the contacts |
107 //fetch the contacts |
111 idList = m_srvConnection.searchContacts(sortQuery, error); |
108 idList = m_srvConnection.searchContacts(sortQuery, error); |
112 } |
109 } |
113 } |
110 } |
114 |
|
115 return idList; |
111 return idList; |
116 |
112 } |
117 |
|
118 |
|
119 } |
|
120 |
|
121 |
113 |
122 bool CntFilterDetail::filterSupported(const QContactFilter& filter) |
114 bool CntFilterDetail::filterSupported(const QContactFilter& filter) |
123 { |
115 { |
124 bool result = false; |
116 bool result = false; |
125 if(QContactFilter::ContactDetailFilter == filter.type()) |
117 if (QContactFilter::ContactDetailFilter == filter.type()) { |
126 { |
|
127 result = true; |
118 result = true; |
128 } |
119 } |
129 |
|
130 return result; |
120 return result; |
131 } |
121 } |
132 |
122 |
133 void CntFilterDetail::createSelectQuery(const QContactFilter& filter, |
123 void CntFilterDetail::createSelectQuery(const QContactFilter& filter, |
134 QString& sqlQuery, |
124 QString& sqlQuery, |
135 QContactManager::Error* error) |
125 QContactManager::Error* error) |
136 |
126 |
137 { |
127 { |
138 if(!filterSupported(filter) ) |
128 if (!filterSupported(filter)) { |
139 { |
129 *error = QContactManager::NotSupportedError; |
140 *error = QContactManager::NotSupportedError; |
130 return; |
141 return; |
131 } |
142 } |
132 QContactDetailFilter detailFilter(filter); |
143 QContactDetailFilter detailFilter(filter); |
133 //display label |
144 //display label |
134 if (detailFilter.detailDefinitionName() == QContactDisplayLabel::DefinitionName) { |
145 if (detailFilter.detailDefinitionName() == QContactDisplayLabel::DefinitionName) |
135 CntFilterDetailDisplayLabel displayLabelFilter; |
146 { |
136 displayLabelFilter.createSelectQuery(filter, sqlQuery, error); |
147 CntFilterDetailDisplayLabel displayLabelFilter; |
137 } |
148 displayLabelFilter.createSelectQuery(filter, sqlQuery, error); |
138 //type |
|
139 else if (detailFilter.detailDefinitionName() == QContactType::DefinitionName) { |
|
140 if (detailFilter.value().toString() == QContactType::TypeContact) |
|
141 sqlQuery = "SELECT contact_id FROM contact WHERE (type_flags>>24)=0"; |
|
142 else if (detailFilter.value().toString() == QContactType::TypeGroup) |
|
143 sqlQuery = "SELECT contact_id FROM contact WHERE (type_flags>>24)=3"; |
|
144 } |
|
145 else if (detailFilter.detailDefinitionName() == QContactGuid::DefinitionName) { |
|
146 if (detailFilter.detailFieldName() == QContactGuid::FieldGuid) { |
|
147 QStringList fullGuidValue = detailFilter.value().toString().split('-'); |
|
148 if (fullGuidValue.count() == 3) { |
|
149 QString localGuidValue = fullGuidValue.at(1); |
|
150 sqlQuery = "SELECT contact_id FROM contact WHERE guid_string = '" + localGuidValue + '\''; |
|
151 } |
149 } |
152 } |
150 |
153 } |
151 //type |
154 //everything else |
152 else if(detailFilter.detailDefinitionName() == QContactType::DefinitionName) |
155 else { |
153 { |
156 QString tableName; |
154 if(detailFilter.value().toString() == QContactType::TypeContact) |
157 QString sqlWhereClause; |
155 sqlQuery = "SELECT contact_id FROM contact WHERE (type_flags>>24)=0"; |
158 getTableNameWhereClause(detailFilter,tableName,sqlWhereClause,error); |
156 else if(detailFilter.value().toString() == QContactType::TypeGroup) |
159 //Create the sql query |
157 sqlQuery = "SELECT contact_id FROM contact WHERE (type_flags>>24)=3"; |
160 sqlQuery += "SELECT DISTINCT contact_id FROM " + tableName + " WHERE " + sqlWhereClause; |
158 } |
161 } |
159 else if(detailFilter.detailDefinitionName() == QContactGuid::DefinitionName) |
162 } |
160 { |
|
161 if(detailFilter.detailFieldName() == QContactGuid::FieldGuid) |
|
162 { |
|
163 QStringList fullGuidValue = detailFilter.value().toString().split('-'); |
|
164 if (fullGuidValue.count() == 3) { |
|
165 QString localGuidValue = fullGuidValue.at(1); |
|
166 sqlQuery = "SELECT contact_id FROM contact WHERE guid_string = '" + localGuidValue + '\''; |
|
167 } |
|
168 } |
|
169 } |
|
170 //everything else |
|
171 else |
|
172 { |
|
173 QString tableName; |
|
174 QString sqlWhereClause; |
|
175 getTableNameWhereClause(detailFilter,tableName,sqlWhereClause,error); |
|
176 //Create the sql query |
|
177 sqlQuery += "SELECT DISTINCT contact_id FROM " + tableName + " WHERE " + sqlWhereClause; |
|
178 } |
|
179 } |
|
180 |
|
181 |
163 |
182 /*! |
164 /*! |
183 * Updates match flage for columns. |
165 * Updates match flags for columns. |
184 */ |
166 */ |
185 void CntFilterDetail::updateForMatchFlag( const QContactDetailFilter& filter, |
167 void CntFilterDetail::updateForMatchFlag(const QContactDetailFilter& filter, |
186 QString& fieldToUpdate , |
168 QString& fieldToUpdate , |
187 QContactManager::Error* error) const |
169 QContactManager::Error* error) const |
188 { |
170 { |
189 // Modify the filed depending on the query |
171 // Modify the filed depending on the query |
190 switch(filter.matchFlags()) |
172 switch (filter.matchFlags()) { |
191 { |
173 case QContactFilter::MatchExactly: { |
192 case QContactFilter::MatchExactly: |
174 // Pattern for MatchExactly: |
193 { |
175 // " ='xyz'" |
194 // Pattern for MatchExactly: |
176 fieldToUpdate = " ='" |
195 // " ='xyz'" |
177 + filter.value().toString() + '\''; |
196 fieldToUpdate = " ='" |
178 *error = QContactManager::NoError; |
197 + filter.value().toString() + '\''; |
179 break; |
198 *error = QContactManager::NoError; |
180 } |
199 break; |
181 case QContactFilter::MatchContains: { |
200 } |
182 // Pattern for MatchContains: |
201 case QContactFilter::MatchContains: |
183 // " LIKE '%xyz%'" |
202 { |
184 fieldToUpdate = " LIKE '%" + filter.value().toString() + "%'" ; |
203 // Pattern for MatchContains: |
185 *error = QContactManager::NoError; |
204 // " LIKE '%xyz%'" |
186 break; |
205 fieldToUpdate = " LIKE '%" + filter.value().toString() + "%'" ; |
187 } |
206 *error = QContactManager::NoError; |
188 case QContactFilter::MatchStartsWith: { |
207 break; |
189 // Pattern for MatchStartsWith: |
208 } |
190 // " LIKE 'xyz%'" |
209 case QContactFilter::MatchStartsWith: |
191 fieldToUpdate = " LIKE '" + filter.value().toString() + "%'" ; |
210 { |
192 *error = QContactManager::NoError; |
211 // Pattern for MatchStartsWith: |
193 break; |
212 // " LIKE 'xyz%'" |
194 } |
213 fieldToUpdate = " LIKE '" + filter.value().toString() + "%'" ; |
195 case QContactFilter::MatchEndsWith: { |
214 *error = QContactManager::NoError; |
196 // Pattern for MatchEndsWith: |
215 break; |
197 // " LIKE '%xyz'" |
216 } |
198 fieldToUpdate = " LIKE '%" + filter.value().toString() + '\'' ; |
217 case QContactFilter::MatchEndsWith: |
199 *error = QContactManager::NoError; |
218 { |
200 break; |
219 // Pattern for MatchEndsWith: |
201 } |
220 // " LIKE '%xyz'" |
202 case QContactFilter::MatchFixedString: { |
221 fieldToUpdate = " LIKE '%" + filter.value().toString() + '\'' ; |
203 *error = QContactManager::NotSupportedError; |
222 *error = QContactManager::NoError; |
204 break; |
223 break; |
205 } |
224 } |
206 case QContactFilter::MatchCaseSensitive: { |
225 case QContactFilter::MatchFixedString: |
207 *error = QContactManager::NotSupportedError; |
226 { |
208 break; |
227 *error = QContactManager::NotSupportedError; |
209 } |
228 break; |
210 default: { |
229 } |
211 *error = QContactManager::NotSupportedError; |
230 case QContactFilter::MatchCaseSensitive: |
212 break; |
231 { |
213 } |
232 *error = QContactManager::NotSupportedError; |
214 } |
233 break; |
215 } |
234 } |
216 |
235 default: |
217 void CntFilterDetail::getTableNameWhereClause(const QContactDetailFilter& detailfilter, |
236 { |
218 QString& tableName, |
237 *error = QContactManager::NotSupportedError; |
219 QString& sqlWhereClause , |
238 break; |
220 QContactManager::Error* error) const |
239 } |
|
240 } |
|
241 |
|
242 } |
|
243 |
|
244 void CntFilterDetail::getTableNameWhereClause( const QContactDetailFilter& detailfilter, |
|
245 QString& tableName, |
|
246 QString& sqlWhereClause , |
|
247 QContactManager::Error* error) const |
|
248 { |
221 { |
249 //Get the table name and the column name |
222 //Get the table name and the column name |
250 QString columnName; |
223 QString columnName; |
251 bool isSubType; |
224 bool isSubType; |
252 |
225 |
253 m_dbInfo.getDbTableAndColumnName(detailfilter.detailDefinitionName(), detailfilter.detailFieldName(), tableName, columnName, isSubType); |
226 m_dbInfo.getDbTableAndColumnName(detailfilter.detailDefinitionName(), detailfilter.detailFieldName(), tableName, columnName, isSubType); |
254 |
227 |
255 // return if tableName is empty |
228 // return if tableName is empty |
256 if(tableName.isEmpty()) |
229 if (tableName.isEmpty()) { |
257 { |
|
258 *error = QContactManager::NotSupportedError; |
230 *error = QContactManager::NotSupportedError; |
259 return; |
231 return; |
260 } |
232 } |
261 |
233 |
262 //check columnName |
234 //check columnName |
263 if(columnName.isEmpty()) |
235 if (columnName.isEmpty()) { |
264 { |
|
265 *error = QContactManager::NotSupportedError; |
236 *error = QContactManager::NotSupportedError; |
266 return; |
237 return; |
267 } |
238 } |
268 else if (isSubType) |
239 else if (isSubType) { |
269 { |
|
270 sqlWhereClause += columnName; |
240 sqlWhereClause += columnName; |
271 sqlWhereClause += " NOT NULL "; |
241 sqlWhereClause += " NOT NULL "; |
272 } |
242 } |
273 else |
243 else { |
274 { |
|
275 sqlWhereClause += ' ' + columnName + ' '; |
244 sqlWhereClause += ' ' + columnName + ' '; |
276 QString fieldToUpdate; |
245 QString fieldToUpdate; |
277 //Update the value depending on the match flag |
246 //Update the value depending on the match flag |
278 updateForMatchFlag(detailfilter,fieldToUpdate,error); |
247 updateForMatchFlag(detailfilter,fieldToUpdate,error); |
279 sqlWhereClause += fieldToUpdate; |
248 sqlWhereClause += fieldToUpdate; |
280 } |
249 } |
281 } |
250 } |
282 |
251 |
283 QList<QContactLocalId> CntFilterDetail::HandlePredictiveSearchFilter(const QContactFilter& filter,QContactManager::Error* error) |
252 QList<QContactLocalId> CntFilterDetail::HandlePredictiveSearchFilter(const QContactFilter& filter, |
284 { |
253 QContactManager::Error* error) |
285 |
254 { |
286 QString sqlQuery; |
255 QString sqlQuery; |
287 |
256 |
288 if(filter.type() == QContactFilter::ContactDetailFilter){ |
257 if (filter.type() == QContactFilter::ContactDetailFilter) { |
289 const QContactDetailFilter detailFilter(filter); |
258 const QContactDetailFilter detailFilter(filter); |
290 if( detailFilter.matchFlags() == QContactFilter::MatchKeypadCollation ){ |
259 if (detailFilter.matchFlags() == QContactFilter::MatchKeypadCollation) { |
291 CntSqlSearch sqlSearch; |
260 CntSqlSearch sqlSearch; |
292 //convert string to numeric format |
261 //convert string to numeric format |
293 QString pattern = detailFilter.value().toString(); |
262 QString pattern = detailFilter.value().toString(); |
294 sqlQuery = sqlSearch.CreatePredictiveSearch(pattern); |
263 sqlQuery = sqlSearch.CreatePredictiveSearch(pattern); |
295 return m_srvConnection.searchContacts(sqlQuery, error); |
264 return m_srvConnection.searchContacts(sqlQuery, error); |
296 } |
265 } |
297 else |
266 else { |
298 { |
|
299 return QList<QContactLocalId>(); |
267 return QList<QContactLocalId>(); |
300 } |
268 } |
301 } |
269 } |
302 else |
270 else { |
303 { |
|
304 return QList<QContactLocalId>(); |
271 return QList<QContactLocalId>(); |
305 } |
272 } |
306 } |
273 } |
307 |
274 |
308 QList<QContactLocalId> CntFilterDetail::HandlePhonenumberDetailFilter(const QContactFilter& filter) |
275 /* |
309 { |
276 * Creates an sql query to fetch contact item IDs for all the contact items |
310 QList<QContactLocalId> matches; |
277 * which may contain the specified telephone number in a telephone, fax |
311 QContactDetailFilter detailFilter(filter); |
278 * or SMS type field. |
312 // Phone numbers need separate handling |
279 * |
313 |
280 * The comparison method used is not exact. The number is compared starting from |
314 QString number((detailFilter.value()).toString()); |
281 * the right side of the number and the method returns an array of candidate |
315 TPtrC commPtr(reinterpret_cast<const TUint16*>(number.utf16())); |
282 * matches. Punctuation (e.g. spaces) and other alphabetic characters are ignored |
316 |
283 * when comparing. |
317 TInt matchLength(KDefaultMatchLength); |
284 */ |
318 // no need to propagate error, we can use the default match length |
285 void CntFilterDetail::createMatchPhoneNumberQuery( |
319 TRAP_IGNORE(getMatchLengthL(matchLength)); |
286 const QContactFilter& filter, |
320 int actualLength = number.length(); |
287 QString& sqlQuery, |
321 |
288 QContactManager::Error* error) |
322 //call the search |
289 |
323 CContactIdArray* idArray(0); |
290 { |
324 TInt err = searchPhoneNumbers(idArray, commPtr, matchLength); |
291 if (!filterSupported(filter) ) { |
325 if( idArray && (err == KErrNone)){ |
292 *error = QContactManager::NotSupportedError; |
326 // copy the matching contact ids |
293 return; |
327 for(int i(0); i < idArray->Count(); i++) { |
294 } |
328 matches.append(QContactLocalId((*idArray)[i])); |
295 |
329 } |
296 QContactDetailFilter detailFilter(filter); |
330 delete idArray; |
297 QString number((detailFilter.value()).toString()); |
331 } |
298 TPtrC numberPtr(reinterpret_cast<const TUint16*>(number.utf16())); |
332 else{ |
299 |
333 //CntSymbianTransformError::transformError(err, error); |
300 TInt matchLengthFromRight(KDefaultMatchLength); |
334 } |
301 // no need to propagate error, we can use the default match length |
335 |
302 TRAP_IGNORE(getMatchLengthL(matchLengthFromRight)); |
336 |
303 |
337 |
304 TInt numLowerDigits = matchLengthFromRight; |
338 return matches; |
305 TInt numUpperDigits = 0; |
339 |
306 |
340 } |
307 if (numLowerDigits > KLowerSevenDigits) { |
|
308 // New style matching. |
|
309 numLowerDigits = KLowerSevenDigits; |
|
310 numUpperDigits = matchLengthFromRight - KLowerSevenDigits; |
|
311 } |
|
312 |
|
313 TMatch phoneDigits = createPaddedPhoneDigits( |
|
314 numberPtr, numLowerDigits, numUpperDigits, error); |
|
315 |
|
316 if (*error == QContactManager::NoError) { |
|
317 // select fields for contacts that match phone lookup |
|
318 // SELECT contact_id FROM comm_addr |
|
319 // WHERE value = [value string] AND type = [type value]; |
|
320 // |
|
321 QString type = QString(" type = %1").arg(CntDbInfo::EPhoneNumber); |
|
322 QString value = QString(" value = %1").arg(phoneDigits.iLowerSevenDigits); |
|
323 QString extraValue = QString(" extra_value = %1").arg(phoneDigits.iUpperDigits); |
|
324 QString whereClause = " WHERE" + value + " AND" + type; |
|
325 if (matchLengthFromRight <= KLowerSevenDigits) { |
|
326 // Matching 7 or less digits... |
|
327 sqlQuery = "SELECT contact_id FROM comm_addr" + whereClause; |
|
328 } |
|
329 else { |
|
330 // Checking the upper digits... |
|
331 whereClause += " AND" + extraValue; |
|
332 sqlQuery = "SELECT contact_id FROM comm_addr" + whereClause; |
|
333 } |
|
334 } |
|
335 } |
341 /* |
336 /* |
342 * Get the match length setting. Digits to be used in matching (counted from |
337 * Get the match length setting. Digits to be used in matching (counted from |
343 * right). |
338 * right). |
344 */ |
339 */ |
345 void CntFilterDetail::getMatchLengthL(TInt& matchLength) |
340 bool CntFilterDetail::getMatchLengthL(TInt& matchLength) |
346 { |
341 { |
347 //Get number of digits used to match |
342 //Get number of digits used to match |
|
343 bool result = false; |
348 CRepository* repository = CRepository::NewL(KCRUidTelConfiguration); |
344 CRepository* repository = CRepository::NewL(KCRUidTelConfiguration); |
349 CleanupStack::PushL(repository); |
345 TInt err = repository->Get(KTelMatchDigits, matchLength); |
350 User::LeaveIfError(repository->Get(KTelMatchDigits, matchLength)); |
346 delete repository; |
351 CleanupStack::PopAndDestroy(repository); |
347 |
|
348 result = (err == KErrNone); |
|
349 return result; |
352 } |
350 } |
353 |
351 |
354 /* |
352 /* |
355 * Find contacts based on a phone number. |
353 * Convert the supplied string to a matchable phone number. |
356 * \a idArray On return contains the ids of the contacts that match the phonenumber. |
354 * |
357 * \a phoneNumber The phone number to match |
355 * \param text Descriptor containing phone number. |
358 * \a matchLength Match length; digits from right. |
356 * \param lowerMatchlength Number of least significant phone digits to use. |
|
357 * \param upperMatchLength Number of most significant phone digits to use. |
|
358 * \param error Qt error code. |
|
359 * \return The hash code(s) to use when matching the supplied phone number. |
359 */ |
360 */ |
360 TInt CntFilterDetail::searchPhoneNumbers( |
361 CntFilterDetail::TMatch CntFilterDetail::createPaddedPhoneDigits( |
361 CContactIdArray*& idArray, |
362 const TDesC& number, |
362 const TDesC& phoneNumber, |
363 const TInt numLowerDigits, |
363 const TInt matchLength) |
364 const TInt numUpperDigits, |
364 { |
365 QContactManager::Error* error) |
365 CContactIdArray* idArrayTmp(0); |
366 { |
366 TRAPD( err, idArrayTmp = m_contactdatabase.MatchPhoneNumberL(phoneNumber, matchLength)); |
367 TMatch phoneNumber = createPhoneMatchNumber( |
367 if(err == KErrNone){ |
368 number, numLowerDigits, numUpperDigits, error); |
368 idArray = idArrayTmp; |
369 if (*error == QContactManager::NoError) { |
369 } |
370 if (phoneNumber.iNumLowerDigits + phoneNumber.iUpperDigits == 0) { |
370 return 0; |
371 // No digits, do nothing |
371 } |
372 } |
|
373 else if (phoneNumber.iNumLowerDigits < KLowerSevenDigits) { |
|
374 // Only the lower-digits hash is used, pad out the number to |
|
375 // KLowerSevenDigits. |
|
376 TInt pad = KLowerSevenDigits - phoneNumber.iNumLowerDigits; |
|
377 phoneNumber.iLowerSevenDigits = TMatch::padOutPhoneMatchNumber(phoneNumber.iLowerSevenDigits,pad); |
|
378 } |
|
379 else if (phoneNumber.iNumUpperDigits < (KMaxPhoneMatchLength - KLowerSevenDigits) ) { |
|
380 // The lower-digits hash is full, pad out the upper hash if less than 15 |
|
381 // digits total. |
|
382 TInt pad = KMaxPhoneMatchLength - KLowerSevenDigits - phoneNumber.iNumUpperDigits; |
|
383 phoneNumber.iUpperDigits = TMatch::padOutPhoneMatchNumber(phoneNumber.iUpperDigits,pad); |
|
384 } |
|
385 } |
|
386 return phoneNumber; |
|
387 } |
|
388 |
|
389 /* |
|
390 * Returns the hash code(s) to use when matching the supplied phone number. If the |
|
391 * number supplied has more actual phone digits (i.e. not including spaces) than |
|
392 * KLowerSevenDigits, a second hash is generated to hold the remaining most |
|
393 * significant phone digits. Removes the non-digit characters. |
|
394 |
|
395 * \param text Descriptor containing contacts phone number field. |
|
396 * \param lowerMatchlength Number of least significant phone digits to use. |
|
397 * \param upperMatchLength Number of most significant phone digits to use. |
|
398 * \param error Qt error code. |
|
399 * \return The hash code(s) to use when matching the supplied phone number. |
|
400 */ |
|
401 CntFilterDetail::TMatch CntFilterDetail::createPhoneMatchNumber( |
|
402 const TDesC& text, |
|
403 TInt lowerMatchLength, |
|
404 TInt upperMatchLength, |
|
405 QContactManager::Error* error) |
|
406 { |
|
407 const TInt KBufLength = KCntMaxTextFieldLength+1; |
|
408 TBuf<KBufLength> buf; |
|
409 |
|
410 if (text.Length() <= KBufLength) { |
|
411 buf = text; |
|
412 } |
|
413 else { |
|
414 buf = text.Right(KBufLength); |
|
415 } |
|
416 TMatch::stripOutNonDigitChars(buf); |
|
417 |
|
418 TMatch phoneNumber; |
|
419 if (buf.Length() == 0) { |
|
420 *error = QContactManager::BadArgumentError; |
|
421 return phoneNumber; |
|
422 } |
|
423 |
|
424 // Generate a hash for the upper digits only if the phone number string is |
|
425 // large enough and more than 7 digits are to be matched. |
|
426 TInt phoneNumberlength = buf.Length(); |
|
427 if ((phoneNumberlength > KLowerSevenDigits) && (upperMatchLength > 0)) { |
|
428 TPtrC upperPart = buf.Left(phoneNumberlength - KLowerSevenDigits); |
|
429 phoneNumber.iUpperDigits = TMatch::createHash(upperPart, |
|
430 upperMatchLength, phoneNumber.iNumUpperDigits); |
|
431 } |
|
432 // Generate a hash of the lower digits. |
|
433 phoneNumber.iLowerSevenDigits = TMatch::createHash(buf, |
|
434 lowerMatchLength, phoneNumber.iNumLowerDigits); |
|
435 |
|
436 return phoneNumber; |
|
437 } |
|
438 |
|
439 //CntFilterDetail::TMatch constructor. |
|
440 CntFilterDetail::TMatch::TMatch() |
|
441 : |
|
442 iLowerSevenDigits(0), |
|
443 iUpperDigits(0), |
|
444 iNumLowerDigits(0), |
|
445 iNumUpperDigits(0) |
|
446 { |
|
447 } |
|
448 |
|
449 /* |
|
450 * Generates a hash value by reversing the matchLength least significant digits, |
|
451 * ignoring non-digits and zeroes at the end of the number. Returns error if no phone |
|
452 * digits are supplied. |
|
453 |
|
454 * \param phoneNumberString A descriptor containing a phone number. |
|
455 * \param matchLength The number of digits from the right of the phone number to use. |
|
456 * \param numPhoneDigits The number of digits found in the phone number string. |
|
457 * \param error Qt error code.* |
|
458 * \return An integer representation of the phone number string in reverse. |
|
459 */ |
|
460 TInt32 CntFilterDetail::TMatch::createHash( |
|
461 const TDesC& phoneNumberString, |
|
462 TInt matchLength, |
|
463 TInt& numPhoneDigits) |
|
464 { |
|
465 TInt phoneNumberLength = phoneNumberString.Length(); |
|
466 TInt startIndex = 0; |
|
467 if (phoneNumberLength > matchLength) { |
|
468 startIndex = phoneNumberLength - matchLength; |
|
469 } |
|
470 |
|
471 numPhoneDigits = 0; |
|
472 TUint reversedDigits = 0; |
|
473 TInt mult = 1; |
|
474 |
|
475 for (TInt chrIndex = startIndex; (numPhoneDigits < matchLength) && (chrIndex < phoneNumberLength); chrIndex++) { |
|
476 TChar chr = phoneNumberString[chrIndex]; |
|
477 if (chr.IsDigit()) { |
|
478 reversedDigits += (chr.GetNumericValue()) * mult; |
|
479 mult = mult * 10; |
|
480 ++numPhoneDigits; |
|
481 } |
|
482 } |
|
483 return reversedDigits ; |
|
484 } |
|
485 |
|
486 void CntFilterDetail::TMatch::stripOutNonDigitChars(TDes& text) |
|
487 { |
|
488 for (TInt chrPos = 0; chrPos < text.Length(); ++chrPos) { |
|
489 TChar chr = text[chrPos]; |
|
490 if (!chr.IsDigit()) { |
|
491 text.Delete(chrPos, 1); |
|
492 --chrPos; |
|
493 } |
|
494 } |
|
495 } |
|
496 |
|
497 TInt32 CntFilterDetail::TMatch::padOutPhoneMatchNumber(TInt32& phoneNumber, |
|
498 TInt padOutLength) |
|
499 { |
|
500 TInt32 result(phoneNumber); |
|
501 const TInt KMult(10); |
|
502 for (TInt i = 0; i < padOutLength; ++i) { |
|
503 result *= KMult; |
|
504 } |
|
505 phoneNumber = result; |
|
506 return result; |
|
507 } |