|
1 /* |
|
2 * Copyright (c) 2005-2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: A high level class for matching phone numbers from stores. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDES |
|
20 #include <CVPbkPhoneNumberMatchStrategy.h> |
|
21 |
|
22 #include <CVPbkContactManager.h> |
|
23 #include <CVPbkContactLinkArray.h> |
|
24 #include <MVPbkContactOperation.h> |
|
25 #include <MVPbkContactStoreList.h> |
|
26 #include <MVPbkContactStore.h> |
|
27 #include <MVPbkContactStoreProperties.h> |
|
28 #include <MVPbkContactLink.h> |
|
29 #include <MVPbkStoreContact.h> |
|
30 #include <MVPbkSingleContactOperationObserver.h> |
|
31 #include <RLocalizedResourceFile.h> |
|
32 #include <VPbkDataCaging.hrh> |
|
33 #include <VPbkEng.rsg> |
|
34 #include <VPbkFieldTypeSelectors.rsg> |
|
35 #include <CVPbkFieldTypeSelector.h> |
|
36 #include <CVPbkFieldFilter.h> |
|
37 #include <barsread.h> |
|
38 #include <MVPbkContactFieldTextData.h> |
|
39 #include <CVPbkContactStoreUriArray.h> |
|
40 |
|
41 #include "CVPbkPhoneNumberSequentialMatchStrategy.h" |
|
42 #include "CVPbkPhoneNumberParallelMatchStrategy.h" |
|
43 |
|
44 // CONSTANTS |
|
45 const TInt KMagicNumber = -1; |
|
46 |
|
47 NONSHARABLE_CLASS(CVPbkPhoneNumberMatchStrategyImpl) : |
|
48 public CActive, |
|
49 public MVPbkContactFindObserver, |
|
50 public MVPbkSingleContactOperationObserver |
|
51 { |
|
52 public: // Construction |
|
53 static CVPbkPhoneNumberMatchStrategyImpl* NewL( |
|
54 CVPbkPhoneNumberMatchStrategy& aParent, |
|
55 const CVPbkPhoneNumberMatchStrategy::TConfig& aConfig, |
|
56 CVPbkContactManager& aContactManager, |
|
57 MVPbkContactFindObserver& aObserver); |
|
58 ~CVPbkPhoneNumberMatchStrategyImpl(); |
|
59 |
|
60 public: // Interface |
|
61 void MatchL(const TDesC& aPhoneNumber); |
|
62 TInt MaxMatchDigits() const; |
|
63 TArray<MVPbkContactStore*> StoresToMatch() const; |
|
64 |
|
65 private: // From CActive |
|
66 void RunL(); |
|
67 void DoCancel(); |
|
68 TInt RunError(TInt aError); |
|
69 |
|
70 private: // From MVPbkContactFindObserver |
|
71 void FindCompleteL(MVPbkContactLinkArray* aResults); |
|
72 void FindFailed(TInt aError); |
|
73 |
|
74 private: // From MVPbkSingleContactOperationObserver |
|
75 void VPbkSingleContactOperationComplete( |
|
76 MVPbkContactOperationBase& aOperation, |
|
77 MVPbkStoreContact* aContact); |
|
78 void VPbkSingleContactOperationFailed( |
|
79 MVPbkContactOperationBase& aOperation, |
|
80 TInt aError); |
|
81 |
|
82 private: // Implementation |
|
83 CVPbkPhoneNumberMatchStrategyImpl(CVPbkPhoneNumberMatchStrategy& aParent); |
|
84 void ConstructL( |
|
85 const CVPbkPhoneNumberMatchStrategy::TConfig& aConfig, |
|
86 CVPbkContactManager& aContactManager, |
|
87 MVPbkContactFindObserver& aObserver); |
|
88 |
|
89 /** |
|
90 * Searches for a store that has given URI from the list of |
|
91 * stores that the contact manager has. |
|
92 * @param aUriPtr URI of the store to search for. |
|
93 * @return The store with aUriPtr, or NULL if store was not found. |
|
94 */ |
|
95 MVPbkContactStore* FindStoreL( |
|
96 const TVPbkContactStoreUriPtr& aUriPtr); |
|
97 |
|
98 /** |
|
99 * Issues new request to be handled in RunL. |
|
100 */ |
|
101 void IssueRequest(); |
|
102 |
|
103 MVPbkContactLink* IsValidResultLC(MVPbkStoreContact* aContact); |
|
104 |
|
105 /** |
|
106 * Creates name tokens array |
|
107 * @param aContact which is checking, RPointerArray reference |
|
108 */ |
|
109 void CreateNameTokensArrayL( MVPbkStoreContact* aContact, RPointerArray <HBufC>& aNameTokensArray ); |
|
110 |
|
111 /** |
|
112 * Check if contact already exists in results array |
|
113 * @param aContact which is checking |
|
114 * @return True if contact exist or if array was empty. |
|
115 */ |
|
116 TBool CheckContactDuplicationL( MVPbkStoreContact* aContact ); |
|
117 |
|
118 /** |
|
119 * Gets contact's field value |
|
120 * @param aContact to get field's value from |
|
121 * @param aFieldType: EVPbkVersitNameN for Last Name |
|
122 * EVPbkVersitNameFN for First Name |
|
123 * @return Pointer descriptor with field's value. |
|
124 */ |
|
125 TPtrC NameFieldValueL( MVPbkStoreContact* aContact, TVPbkFieldTypeName aFieldType ); |
|
126 |
|
127 private: // Data |
|
128 CVPbkPhoneNumberMatchStrategy& iParent; |
|
129 /// Ref: The contact manager instance to be used for searching. |
|
130 CVPbkContactManager* iContactManager; |
|
131 /// Ref: Observer for the searching process. |
|
132 MVPbkContactFindObserver* iObserver; |
|
133 /// Own: The find operation that is currently ongoing. |
|
134 MVPbkContactOperationBase* iOperation; |
|
135 /// Maximum number of matched digits. |
|
136 TInt iMaxMatchDigits; |
|
137 /// Flags to configure matching process, @see TVPbkPhoneNumberMatchFlags |
|
138 TUint32 iMatchFlags; |
|
139 |
|
140 /// Own: Array of stores that are used in matching. |
|
141 RPointerArray<MVPbkContactStore> iStoresToMatch; |
|
142 /// Own: Phone number that is being matched. |
|
143 HBufC* iPhoneNumber; |
|
144 /// Own: Intermediate results of the matching process. |
|
145 CVPbkContactLinkArray* iWorkingResults; |
|
146 /// Own: Final results of the matching process. |
|
147 CVPbkContactLinkArray* iResults; |
|
148 /// iWorkingResults index of current contact retrieval |
|
149 TInt iCurrentContact; |
|
150 |
|
151 /// Own: Currently retrieved contact |
|
152 MVPbkStoreContact* iStoreContact; |
|
153 /// Own: Field type selector |
|
154 CVPbkFieldTypeSelector* iFieldTypeSelector; |
|
155 /// Own: A filtered and sorted collection of Virtual Phonebook contact fields. |
|
156 CVPbkFieldFilter* iFieldFilter; |
|
157 |
|
158 /// Active object states |
|
159 enum TState { EMatch, ERemoveDuplicates, ERefineSearch, EComplete }; |
|
160 /// Active object current state |
|
161 TState iState; |
|
162 |
|
163 /// Own: First Name field type selector |
|
164 CVPbkFieldTypeSelector* iFirstNameSelector; |
|
165 /// Own: Last Name field type selector |
|
166 CVPbkFieldTypeSelector* iLastNameSelector; |
|
167 /// Own: Array of tokens gotten from first and last name fields of first matched contact |
|
168 RPointerArray <HBufC> iNameTokensArray; |
|
169 /// Own: Array of tokens gotten from first and last name fields of contact |
|
170 RPointerArray <HBufC> iTempNameTokensArray; |
|
171 /// Indicates if all contact in iResult are the same |
|
172 TBool iDoubledContacts; |
|
173 }; |
|
174 |
|
175 CVPbkPhoneNumberMatchStrategyImpl::CVPbkPhoneNumberMatchStrategyImpl( |
|
176 CVPbkPhoneNumberMatchStrategy& aParent) : |
|
177 CActive(CActive::EPriorityIdle), |
|
178 iParent(aParent) |
|
179 { |
|
180 CActiveScheduler::Add(this); |
|
181 } |
|
182 |
|
183 inline void CVPbkPhoneNumberMatchStrategyImpl::ConstructL( |
|
184 const CVPbkPhoneNumberMatchStrategy::TConfig& aConfig, |
|
185 CVPbkContactManager& aContactManager, |
|
186 MVPbkContactFindObserver& aObserver) |
|
187 { |
|
188 iContactManager = &aContactManager; |
|
189 iObserver = &aObserver; |
|
190 |
|
191 iMaxMatchDigits = aConfig.iMaxMatchDigits; |
|
192 iMatchFlags = aConfig.iMatchFlags; |
|
193 |
|
194 const TInt uriCount = aConfig.iUriPriorities.Count(); |
|
195 for (TInt i = 0; i < uriCount; ++i) |
|
196 { |
|
197 MVPbkContactStore* store = FindStoreL(aConfig.iUriPriorities[i]); |
|
198 if (store) |
|
199 { |
|
200 iStoresToMatch.AppendL(store); |
|
201 } |
|
202 } |
|
203 |
|
204 VPbkEngUtils::RLocalizedResourceFile resFile; |
|
205 resFile.OpenLC(iContactManager->FsSession(), |
|
206 KVPbkRomFileDrive, |
|
207 KDC_RESOURCE_FILES_DIR, |
|
208 KVPbkFieldTypeSelectorsResFileName); |
|
209 HBufC8* selectorBuf = resFile.AllocReadLC(R_VPBK_PHONE_NUMBER_SELECTOR); |
|
210 TResourceReader resReader; |
|
211 resReader.SetBuffer(selectorBuf); |
|
212 |
|
213 iFieldTypeSelector = CVPbkFieldTypeSelector::NewL(resReader, iContactManager->FieldTypes()); |
|
214 |
|
215 CleanupStack::PopAndDestroy( selectorBuf ); |
|
216 |
|
217 if ( iMatchFlags & CVPbkPhoneNumberMatchStrategy::EVPbkDuplicatedContactsMatchFlag ) |
|
218 { |
|
219 HBufC8* firstNameSelectorBuf = resFile.AllocReadLC( R_VPBK_FIRST_NAME_SELECTOR ); |
|
220 resReader.SetBuffer( firstNameSelectorBuf ); |
|
221 iFirstNameSelector = CVPbkFieldTypeSelector::NewL( resReader, iContactManager->FieldTypes() ); |
|
222 CleanupStack::PopAndDestroy( firstNameSelectorBuf ); |
|
223 |
|
224 HBufC8* lastNameSelectorBuf = resFile.AllocReadLC( R_VPBK_LAST_NAME_SELECTOR ); |
|
225 resReader.SetBuffer( lastNameSelectorBuf ); |
|
226 iLastNameSelector = CVPbkFieldTypeSelector::NewL( resReader, iContactManager->FieldTypes() ); |
|
227 CleanupStack::PopAndDestroy( lastNameSelectorBuf ); |
|
228 } |
|
229 |
|
230 CleanupStack::PopAndDestroy( &resFile ); |
|
231 } |
|
232 |
|
233 CVPbkPhoneNumberMatchStrategyImpl* CVPbkPhoneNumberMatchStrategyImpl::NewL( |
|
234 CVPbkPhoneNumberMatchStrategy& aParent, |
|
235 const CVPbkPhoneNumberMatchStrategy::TConfig& aConfig, |
|
236 CVPbkContactManager& aContactManager, |
|
237 MVPbkContactFindObserver& aObserver) |
|
238 { |
|
239 CVPbkPhoneNumberMatchStrategyImpl* self = |
|
240 new(ELeave) CVPbkPhoneNumberMatchStrategyImpl(aParent); |
|
241 CleanupStack::PushL(self); |
|
242 self->ConstructL(aConfig, aContactManager, aObserver); |
|
243 CleanupStack::Pop(self); |
|
244 return self; |
|
245 } |
|
246 |
|
247 CVPbkPhoneNumberMatchStrategyImpl::~CVPbkPhoneNumberMatchStrategyImpl() |
|
248 { |
|
249 Cancel(); |
|
250 |
|
251 delete iFieldFilter; |
|
252 delete iFieldTypeSelector; |
|
253 delete iWorkingResults; |
|
254 delete iResults; |
|
255 delete iStoreContact; |
|
256 delete iPhoneNumber; |
|
257 delete iOperation; |
|
258 delete iFirstNameSelector; |
|
259 delete iLastNameSelector; |
|
260 iNameTokensArray.ResetAndDestroy(); |
|
261 iTempNameTokensArray.ResetAndDestroy(); |
|
262 iStoresToMatch.Close(); |
|
263 } |
|
264 |
|
265 void CVPbkPhoneNumberMatchStrategyImpl::MatchL(const TDesC& aPhoneNumber) |
|
266 { |
|
267 HBufC* phoneNumber = aPhoneNumber.AllocL(); |
|
268 delete iPhoneNumber; |
|
269 iPhoneNumber = phoneNumber; |
|
270 |
|
271 if ( iWorkingResults ) |
|
272 { |
|
273 iWorkingResults->ResetAndDestroy(); |
|
274 } |
|
275 if ( iResults ) |
|
276 { |
|
277 iResults->ResetAndDestroy(); |
|
278 } |
|
279 iCurrentContact = KMagicNumber; |
|
280 |
|
281 if ( iMatchFlags & CVPbkPhoneNumberMatchStrategy::EVPbkDuplicatedContactsMatchFlag ) |
|
282 { |
|
283 iDoubledContacts = ETrue; |
|
284 } |
|
285 else |
|
286 { |
|
287 iDoubledContacts = EFalse; |
|
288 } |
|
289 iState = EMatch; |
|
290 IssueRequest(); |
|
291 } |
|
292 |
|
293 |
|
294 void CVPbkPhoneNumberMatchStrategyImpl::IssueRequest() |
|
295 { |
|
296 TRequestStatus* status = &iStatus; |
|
297 User::RequestComplete(status, KErrNone); |
|
298 SetActive(); |
|
299 } |
|
300 |
|
301 void CVPbkPhoneNumberMatchStrategyImpl::RunL() |
|
302 { |
|
303 switch (iState) |
|
304 { |
|
305 case EMatch: |
|
306 { |
|
307 MVPbkContactOperation* operation = iParent.CreateFindOperationLC(*iPhoneNumber); |
|
308 if (operation) |
|
309 { |
|
310 operation->StartL(); |
|
311 CleanupStack::Pop(); // operation |
|
312 delete iOperation; |
|
313 iOperation = operation; |
|
314 } |
|
315 else |
|
316 { |
|
317 // all needed operations are done if any |
|
318 iState = ERemoveDuplicates; |
|
319 IssueRequest(); |
|
320 } |
|
321 break; |
|
322 } |
|
323 case ERemoveDuplicates: |
|
324 { |
|
325 const TInt count = iWorkingResults ? iWorkingResults->Count() : 0; |
|
326 CVPbkContactLinkArray* results = CVPbkContactLinkArray::NewLC(); |
|
327 for (TInt i = 0; i < count; ++i) |
|
328 { |
|
329 MVPbkContactLink* link = iWorkingResults->At(i).CloneLC(); |
|
330 if (results->Find(*link) == KErrNotFound) |
|
331 { |
|
332 results->AppendL(link); |
|
333 CleanupStack::Pop(); // link |
|
334 } |
|
335 else |
|
336 { |
|
337 CleanupStack::PopAndDestroy(); // link |
|
338 } |
|
339 } |
|
340 CleanupStack::Pop(results); |
|
341 delete iWorkingResults; |
|
342 iWorkingResults = results; |
|
343 iState = ERefineSearch; |
|
344 iCurrentContact = 0; |
|
345 IssueRequest(); |
|
346 break; |
|
347 } |
|
348 case ERefineSearch: |
|
349 { |
|
350 if (!iResults) |
|
351 { |
|
352 iResults = CVPbkContactLinkArray::NewL(); |
|
353 } |
|
354 if ( iDoubledContacts ) |
|
355 { |
|
356 iDoubledContacts = CheckContactDuplicationL( iStoreContact ); |
|
357 } |
|
358 |
|
359 MVPbkContactLink* result = IsValidResultLC( iStoreContact ); |
|
360 if ( result ) |
|
361 { |
|
362 iResults->AppendL( result ); |
|
363 CleanupStack::Pop(); // MVPbkContactLink |
|
364 } |
|
365 delete iStoreContact; |
|
366 iStoreContact = NULL; |
|
367 |
|
368 const TInt count = iWorkingResults ? iWorkingResults->Count() : 0; |
|
369 if (iCurrentContact < count && |
|
370 !( iResults->Count() > 0 && |
|
371 (iMatchFlags & CVPbkPhoneNumberMatchStrategy::EVPbkStopOnFirstMatchFlag))) |
|
372 { |
|
373 const MVPbkContactLink& link = iWorkingResults->At(iCurrentContact); |
|
374 delete iOperation; |
|
375 iOperation = NULL; |
|
376 iOperation = iContactManager->RetrieveContactL(link, *this); |
|
377 ++iCurrentContact; |
|
378 } |
|
379 else |
|
380 { |
|
381 iState = EComplete; |
|
382 IssueRequest(); |
|
383 } |
|
384 break; |
|
385 } |
|
386 case EComplete: |
|
387 { |
|
388 iNameTokensArray.ResetAndDestroy(); |
|
389 iTempNameTokensArray.ResetAndDestroy(); |
|
390 if ( iDoubledContacts && iResults->Count() ) |
|
391 { |
|
392 CVPbkContactLinkArray* results = CVPbkContactLinkArray::NewLC(); |
|
393 MVPbkContactLink* link = iResults->At(0).CloneLC(); // first element |
|
394 results->AppendL( link ); |
|
395 CleanupStack::Pop( 2, results ); // results, link |
|
396 delete iResults; |
|
397 iResults = results; |
|
398 } |
|
399 CVPbkContactLinkArray* results = iResults; |
|
400 iResults = NULL; |
|
401 iObserver->FindCompleteL( results ); |
|
402 break; |
|
403 } |
|
404 default: |
|
405 { |
|
406 // This case should not be possible |
|
407 User::Leave( KErrArgument ); |
|
408 break; |
|
409 } |
|
410 } |
|
411 } |
|
412 |
|
413 void CVPbkPhoneNumberMatchStrategyImpl::DoCancel() |
|
414 { |
|
415 } |
|
416 |
|
417 TInt CVPbkPhoneNumberMatchStrategyImpl::RunError(TInt aError) |
|
418 { |
|
419 iObserver->FindFailed(aError); |
|
420 return KErrNone; |
|
421 } |
|
422 |
|
423 inline MVPbkContactStore* CVPbkPhoneNumberMatchStrategyImpl::FindStoreL( |
|
424 const TVPbkContactStoreUriPtr& aUriPtr) |
|
425 { |
|
426 const TInt storeCount = iContactManager->ContactStoresL().Count(); |
|
427 for (TInt i = 0; i < storeCount; ++i) |
|
428 { |
|
429 MVPbkContactStore& store = iContactManager->ContactStoresL().At(i); |
|
430 if (store.StoreProperties().Uri().Compare( |
|
431 aUriPtr, |
|
432 TVPbkContactStoreUriPtr::EContactStoreUriAllComponents) == 0) |
|
433 { |
|
434 return &store; |
|
435 } |
|
436 } |
|
437 return NULL; |
|
438 } |
|
439 |
|
440 void CVPbkPhoneNumberMatchStrategyImpl::FindCompleteL(MVPbkContactLinkArray* aResults) |
|
441 { |
|
442 // This function called by operation which is created in |
|
443 // iParent.CreateFindOperationLC |
|
444 if (aResults) |
|
445 { |
|
446 CleanupDeletePushL( aResults ); // Take ownership |
|
447 |
|
448 if (!iWorkingResults) |
|
449 { |
|
450 iWorkingResults = CVPbkContactLinkArray::NewL(); |
|
451 } |
|
452 const TInt count = aResults->Count(); |
|
453 for (TInt i = 0; i < count; ++i) |
|
454 { |
|
455 MVPbkContactLink* link = aResults->At(i).CloneLC(); |
|
456 iWorkingResults->AppendL(link); |
|
457 CleanupStack::Pop(); // link |
|
458 } |
|
459 |
|
460 CleanupStack::PopAndDestroy(); // aResults |
|
461 } |
|
462 IssueRequest(); |
|
463 } |
|
464 |
|
465 void CVPbkPhoneNumberMatchStrategyImpl::FindFailed(TInt aError) |
|
466 { |
|
467 iObserver->FindFailed(aError); |
|
468 } |
|
469 |
|
470 void CVPbkPhoneNumberMatchStrategyImpl::VPbkSingleContactOperationComplete( |
|
471 MVPbkContactOperationBase& aOperation, |
|
472 MVPbkStoreContact* aContact) |
|
473 { |
|
474 if (iOperation == &aOperation) |
|
475 { |
|
476 delete iOperation; |
|
477 iOperation = NULL; |
|
478 |
|
479 iStoreContact = aContact; |
|
480 IssueRequest(); |
|
481 } |
|
482 } |
|
483 |
|
484 void CVPbkPhoneNumberMatchStrategyImpl::VPbkSingleContactOperationFailed( |
|
485 MVPbkContactOperationBase& aOperation, |
|
486 TInt aError) |
|
487 { |
|
488 if (iOperation == &aOperation) |
|
489 { |
|
490 delete iOperation; |
|
491 iOperation = NULL; |
|
492 |
|
493 iObserver->FindFailed(aError); |
|
494 } |
|
495 } |
|
496 |
|
497 TInt CVPbkPhoneNumberMatchStrategyImpl::MaxMatchDigits() const |
|
498 { |
|
499 return iMaxMatchDigits; |
|
500 } |
|
501 |
|
502 TArray<MVPbkContactStore*> CVPbkPhoneNumberMatchStrategyImpl::StoresToMatch() const |
|
503 { |
|
504 return iStoresToMatch.Array(); |
|
505 } |
|
506 |
|
507 MVPbkContactLink* CVPbkPhoneNumberMatchStrategyImpl::IsValidResultLC( |
|
508 MVPbkStoreContact* aContact) |
|
509 { |
|
510 MVPbkContactLink* result = NULL; |
|
511 |
|
512 if (!(iMatchFlags & CVPbkPhoneNumberMatchStrategy::EVPbkExactMatchFlag)) |
|
513 { |
|
514 // If exact match is not needed we will accept the contact as valid |
|
515 // if it is not NULL |
|
516 if ( aContact ) |
|
517 { |
|
518 result = aContact->CreateLinkLC(); |
|
519 } |
|
520 } |
|
521 else if (aContact) |
|
522 { |
|
523 TPtrC matchedNumber = iPhoneNumber->Des(). |
|
524 Right(Min(iPhoneNumber->Length(), iMaxMatchDigits)); |
|
525 |
|
526 CVPbkFieldFilter::TConfig config(aContact->Fields(), iFieldTypeSelector); |
|
527 if (!iFieldFilter) |
|
528 { |
|
529 iFieldFilter = CVPbkFieldFilter::NewL(config); |
|
530 } |
|
531 else |
|
532 { |
|
533 iFieldFilter->ResetL(config); |
|
534 } |
|
535 const TInt count = iFieldFilter->FieldCount(); |
|
536 for (TInt i = 0; i < count; ++i) |
|
537 { |
|
538 MVPbkContactFieldData& data = iFieldFilter->FieldAt(i).FieldData(); |
|
539 if (data.DataType() == EVPbkFieldStorageTypeText) |
|
540 { |
|
541 const TDesC& dataText = MVPbkContactFieldTextData::Cast(data).Text(); |
|
542 TPtrC dataTextPtr = dataText.Right(Min(dataText.Length(), iMaxMatchDigits)); |
|
543 if (dataTextPtr == matchedNumber) |
|
544 { |
|
545 result = iFieldFilter->FieldAt(i).CreateLinkLC(); |
|
546 break; |
|
547 } |
|
548 } |
|
549 } |
|
550 } |
|
551 return result; |
|
552 } |
|
553 |
|
554 TBool CVPbkPhoneNumberMatchStrategyImpl::CheckContactDuplicationL( |
|
555 MVPbkStoreContact* aContact ) |
|
556 { |
|
557 |
|
558 if ( !aContact ) |
|
559 { |
|
560 return ETrue; |
|
561 } |
|
562 |
|
563 if ( aContact && iCurrentContact == 1 ) |
|
564 { |
|
565 CreateNameTokensArrayL( aContact, iNameTokensArray ); |
|
566 return ETrue; |
|
567 } |
|
568 else |
|
569 { |
|
570 iTempNameTokensArray.ResetAndDestroy(); |
|
571 CreateNameTokensArrayL( aContact, iTempNameTokensArray ); |
|
572 TInt count = iNameTokensArray.Count(); |
|
573 if ( iNameTokensArray.Count() != iTempNameTokensArray.Count() ) |
|
574 { |
|
575 return EFalse; |
|
576 } |
|
577 else |
|
578 { |
|
579 TInt result = 0; |
|
580 for ( TInt i = 0; i < count; i++ ) |
|
581 { |
|
582 HBufC* token = iNameTokensArray[i]; |
|
583 TInt tempCount = iTempNameTokensArray.Count(); |
|
584 for ( TInt j = 0; j < tempCount; j++ ) |
|
585 { |
|
586 result = token->Compare( *( iTempNameTokensArray[j] ) ); |
|
587 if ( !result ) |
|
588 { |
|
589 HBufC* removedToken = iTempNameTokensArray[j]; |
|
590 iTempNameTokensArray.Remove( j ); |
|
591 delete removedToken; |
|
592 break; |
|
593 } |
|
594 } |
|
595 if ( result ) |
|
596 { |
|
597 return EFalse; |
|
598 } |
|
599 } |
|
600 } |
|
601 return ETrue; |
|
602 } |
|
603 } |
|
604 |
|
605 void CVPbkPhoneNumberMatchStrategyImpl::CreateNameTokensArrayL( MVPbkStoreContact* aContact, |
|
606 RPointerArray <HBufC>& aNameTokensArray ) |
|
607 { |
|
608 TPtrC firstName = NameFieldValueL( aContact, EVPbkVersitNameFN ); |
|
609 TLex lexer; |
|
610 lexer.Assign( firstName ); |
|
611 |
|
612 TPtrC ptr; |
|
613 TInt len = 0; |
|
614 while( ETrue ) |
|
615 { |
|
616 ptr.Set( lexer.NextToken() ); |
|
617 |
|
618 len = ptr.Length(); |
|
619 if ( len ) |
|
620 { |
|
621 HBufC* token = ptr.AllocLC(); |
|
622 aNameTokensArray.AppendL( token ); |
|
623 CleanupStack::Pop( token ); |
|
624 } |
|
625 else |
|
626 { |
|
627 break; |
|
628 } |
|
629 } |
|
630 |
|
631 TPtrC lastName = NameFieldValueL( aContact, EVPbkVersitNameN ); |
|
632 |
|
633 lexer.Assign( lastName ); |
|
634 |
|
635 len = 0; |
|
636 while( ETrue ) |
|
637 { |
|
638 ptr.Set( lexer.NextToken() ); |
|
639 |
|
640 len = ptr.Length(); |
|
641 if ( len ) |
|
642 { |
|
643 HBufC* token = ptr.AllocLC(); |
|
644 aNameTokensArray.AppendL( token ); |
|
645 CleanupStack::Pop( token ); |
|
646 } |
|
647 else |
|
648 { |
|
649 break; |
|
650 } |
|
651 } |
|
652 } |
|
653 |
|
654 TPtrC CVPbkPhoneNumberMatchStrategyImpl::NameFieldValueL( |
|
655 MVPbkStoreContact* aContact, TVPbkFieldTypeName aFieldType ) |
|
656 { |
|
657 if ( aContact ) |
|
658 { |
|
659 CVPbkFieldFilter::TConfig config( aContact->Fields() ); |
|
660 if ( aFieldType == EVPbkVersitNameFN ) |
|
661 { |
|
662 config.iFieldSelector = iFirstNameSelector; |
|
663 } |
|
664 else if ( aFieldType == EVPbkVersitNameN ) |
|
665 { |
|
666 config.iFieldSelector = iLastNameSelector; |
|
667 } |
|
668 else |
|
669 { |
|
670 return KNullDesC(); |
|
671 } |
|
672 |
|
673 if (!iFieldFilter) |
|
674 { |
|
675 iFieldFilter = CVPbkFieldFilter::NewL(config); |
|
676 } |
|
677 else |
|
678 { |
|
679 iFieldFilter->ResetL(config); |
|
680 } |
|
681 const TInt count = iFieldFilter->FieldCount(); |
|
682 for (TInt i = 0; i < count; ++i) |
|
683 { |
|
684 MVPbkContactFieldData& data = iFieldFilter->FieldAt(i).FieldData(); |
|
685 if (data.DataType() == EVPbkFieldStorageTypeText) |
|
686 { |
|
687 return MVPbkContactFieldTextData::Cast(data).Text(); |
|
688 } |
|
689 } |
|
690 return KNullDesC(); |
|
691 } |
|
692 else |
|
693 { |
|
694 return KNullDesC(); |
|
695 } |
|
696 } |
|
697 |
|
698 CVPbkPhoneNumberMatchStrategy::CVPbkPhoneNumberMatchStrategy() |
|
699 { |
|
700 } |
|
701 |
|
702 EXPORT_C CVPbkPhoneNumberMatchStrategy* CVPbkPhoneNumberMatchStrategy::NewL( |
|
703 const TConfig& aConfig, |
|
704 CVPbkContactManager& aContactManager, |
|
705 MVPbkContactFindObserver& aObserver) |
|
706 { |
|
707 if (aConfig.iMatchMode == EVPbkSequentialMatch) |
|
708 { |
|
709 return CVPbkPhoneNumberSequentialMatchStrategy::NewL(aConfig, aContactManager, aObserver); |
|
710 } |
|
711 else |
|
712 { |
|
713 return CVPbkPhoneNumberParallelMatchStrategy::NewL(aConfig, aContactManager, aObserver); |
|
714 } |
|
715 } |
|
716 |
|
717 CVPbkPhoneNumberMatchStrategy::~CVPbkPhoneNumberMatchStrategy() |
|
718 { |
|
719 delete iImpl; |
|
720 } |
|
721 |
|
722 EXPORT_C void CVPbkPhoneNumberMatchStrategy::MatchL(const TDesC& aPhoneNumber) |
|
723 { |
|
724 InitMatchingL(); |
|
725 |
|
726 iImpl->MatchL(aPhoneNumber); |
|
727 } |
|
728 |
|
729 void CVPbkPhoneNumberMatchStrategy::BaseConstructL( |
|
730 const TConfig& aConfig, |
|
731 CVPbkContactManager& aContactManager, |
|
732 MVPbkContactFindObserver& aObserver) |
|
733 { |
|
734 iImpl = CVPbkPhoneNumberMatchStrategyImpl::NewL( |
|
735 *this, aConfig, aContactManager, aObserver); |
|
736 } |
|
737 |
|
738 MVPbkContactFindObserver& CVPbkPhoneNumberMatchStrategy::FindObserver() const |
|
739 { |
|
740 return *iImpl; |
|
741 } |
|
742 |
|
743 TInt CVPbkPhoneNumberMatchStrategy::MaxMatchDigits() const |
|
744 { |
|
745 return iImpl->MaxMatchDigits(); |
|
746 } |
|
747 |
|
748 TArray<MVPbkContactStore*> CVPbkPhoneNumberMatchStrategy::StoresToMatch() const |
|
749 { |
|
750 return iImpl->StoresToMatch(); |
|
751 } |
|
752 |
|
753 // End of File |