|
1 /* |
|
2 * Copyright (c) 2006 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: Searches contact using email address as search filter from address books. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "MuiuContactAddressMatcher.h" |
|
20 #include <data_caging_path_literals.hrh> // KDC_RESOURCE_FILES_DIR |
|
21 #include <muiu_internal.rsg> // R_MUIU_PHONENUMBER_MATCH_INTEREST |
|
22 #include <eikenv.h> |
|
23 #include <coemain.h> |
|
24 #include <basched.h> // KLeaveExit |
|
25 #include <bautils.h> // BaflUtils |
|
26 #include <contactmatcher.h> |
|
27 #include <CVPbkContactManager.h> |
|
28 #include <CVPbkContactLinkArray.h> |
|
29 #include <MVPbkStoreContact.h> |
|
30 #include <CVPbkFieldTypeSelector.h> |
|
31 #include <VPbkContactViewFilterBuilder.h> |
|
32 #include <MVPbkContactFieldTextData.h> |
|
33 #include <CVPbkFieldTypeRefsList.h> |
|
34 #include <TVPbkFieldVersitProperty.h> |
|
35 #include <AiwServiceHandler.h> |
|
36 #include <finditemmenu.h> |
|
37 #include <e32base.h> |
|
38 #include <AknWaitDialog.h> |
|
39 #include <aknnotewrappers.h> // CAknInformationNote |
|
40 #include <StringLoader.h> |
|
41 |
|
42 #include "MuiuMsvUiServiceUtilities.h" |
|
43 |
|
44 |
|
45 |
|
46 // Constants |
|
47 // Resource file |
|
48 _LIT( KMuiuInternalResourceFileName, "muiu_internal.rsc" ); |
|
49 |
|
50 |
|
51 // --------------------------------------------------------------------------- |
|
52 // CMuiuContactAddressMatcher::NewL |
|
53 // --------------------------------------------------------------------------- |
|
54 // |
|
55 CMuiuContactAddressMatcher* CMuiuContactAddressMatcher::NewL( |
|
56 CEikonEnv& aEikonEnv ) |
|
57 { |
|
58 CMuiuContactAddressMatcher* self = |
|
59 new( ELeave ) CMuiuContactAddressMatcher( aEikonEnv ); |
|
60 CleanupStack::PushL( self ); |
|
61 self->ConstructL(); |
|
62 |
|
63 CleanupStack::Pop( self ); |
|
64 return self; |
|
65 } |
|
66 |
|
67 // --------------------------------------------------------------------------- |
|
68 // CMuiuContactAddressMatcher::CMuiuContactAddressMatcher |
|
69 // --------------------------------------------------------------------------- |
|
70 // |
|
71 CMuiuContactAddressMatcher::CMuiuContactAddressMatcher( |
|
72 CEikonEnv& aEikonEnv ): |
|
73 CActive( EPriorityStandard ), |
|
74 iEikEnv( aEikonEnv ), |
|
75 iResourceOffset( KErrNotFound ) |
|
76 { |
|
77 CActiveScheduler::Add( this ); |
|
78 } |
|
79 |
|
80 // --------------------------------------------------------------------------- |
|
81 // CMuiuContactAddressMatcher::ConstructL |
|
82 // --------------------------------------------------------------------------- |
|
83 // |
|
84 inline void CMuiuContactAddressMatcher::ConstructL() |
|
85 { |
|
86 iServiceHandler = CAiwServiceHandler::NewL(); |
|
87 |
|
88 iContactMatcher = CContactMatcher::NewL( &iEikEnv.FsSession() ); |
|
89 |
|
90 //Changed to open only default stores. |
|
91 //Opening of all stores caused |
|
92 //frequent jamming. |
|
93 iContactMatcher->OpenDefaultMatchStoresL(); |
|
94 |
|
95 iContactLinks = CVPbkContactLinkArray::NewL(); |
|
96 iChangedLinks = CVPbkContactLinkArray::NewL(); |
|
97 |
|
98 //Idle object is needed because we can't |
|
99 //call callback method straight from HandleNotifyL(). |
|
100 //It causes KErrInUse leave. |
|
101 iIdle = CIdle::NewL(CActive::EPriorityIdle); |
|
102 |
|
103 if ( !iEikEnv.IsResourceAvailableL( R_MUIU_PHONENUMBER_MATCH_INTEREST ) ) |
|
104 { |
|
105 TFileName fileName; |
|
106 TParse parse; |
|
107 parse.Set( KMuiuInternalResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL ); |
|
108 fileName = parse.FullName(); |
|
109 BaflUtils::NearestLanguageFile( iEikEnv.FsSession(), fileName ); |
|
110 iResourceOffset = iEikEnv.AddResourceFileL( fileName ); |
|
111 } |
|
112 |
|
113 iServiceHandler->AttachL( R_MUIU_PHONENUMBER_MATCH_INTEREST ); |
|
114 } |
|
115 |
|
116 |
|
117 // --------------------------------------------------------------------------- |
|
118 // CMuiuContactAddressMatcher::~CMuiuContactAddressMatcher |
|
119 // --------------------------------------------------------------------------- |
|
120 // |
|
121 CMuiuContactAddressMatcher::~CMuiuContactAddressMatcher() |
|
122 { |
|
123 Cancel(); |
|
124 // delete link arrays first to avoid access violations: |
|
125 delete iContactLinks; |
|
126 delete iChangedLinks; |
|
127 // doesn't matter really if detaching fails |
|
128 if( iServiceHandler ) |
|
129 { |
|
130 TRAP_IGNORE( iServiceHandler->DetachL( R_MUIU_PHONENUMBER_MATCH_INTEREST ) ); |
|
131 } |
|
132 delete iContactMatcher; |
|
133 delete iIdle; |
|
134 delete iServiceHandler; |
|
135 if ( iResourceOffset != KErrNotFound ) |
|
136 { |
|
137 iEikEnv.DeleteResourceFile( iResourceOffset ); |
|
138 } |
|
139 } |
|
140 |
|
141 // ---------------------------------------------------------------------------- |
|
142 // CMuiuContactAddressMatcher::FindContactL |
|
143 // ---------------------------------------------------------------------------- |
|
144 // |
|
145 TBool CMuiuContactAddressMatcher::FindContactL( |
|
146 const TDesC& aMailAddress, |
|
147 TCallBack aCallBack ) |
|
148 { |
|
149 if ( !MsvUiServiceUtilities::IsValidEmailAddressL( aMailAddress ) ) |
|
150 { |
|
151 return EFalse; |
|
152 } |
|
153 |
|
154 if ( !IsActive() ) |
|
155 { |
|
156 iCallBack = aCallBack; |
|
157 // reset old data |
|
158 iContactLinks->ResetAndDestroy(); |
|
159 iChangedLinks->ResetAndDestroy(); |
|
160 |
|
161 const MVPbkFieldTypeList& fieldTypes = iContactMatcher->FieldTypes(); |
|
162 iContactMatcher->MatchDataL( aMailAddress, |
|
163 fieldTypes, |
|
164 *iContactLinks, |
|
165 iStatus ); |
|
166 SetActive(); |
|
167 |
|
168 // dialog sets iWaitDialog to NULL when it gets deleted |
|
169 if (!iWaitDialog ) |
|
170 { |
|
171 iWaitDialog = new( ELeave ) CAknWaitDialog( |
|
172 ( REINTERPRET_CAST( CEikDialog**, &iWaitDialog ) ), ETrue ); |
|
173 } |
|
174 iWaitDialog->ExecuteLD( R_MUIU_MATCHING_ADDRESS_WAIT_NOTE ); |
|
175 } |
|
176 else |
|
177 { |
|
178 User::Leave( KErrInUse ); |
|
179 } |
|
180 return ETrue; |
|
181 } |
|
182 |
|
183 |
|
184 //---------------------------------------------------------------------------- |
|
185 // CMuiuContactAddressMatcher::GetAddressL() |
|
186 // Returns NULL pointer if no data is found |
|
187 //---------------------------------------------------------------------------- |
|
188 HBufC* CMuiuContactAddressMatcher::GetAddressL() const |
|
189 { |
|
190 ASSERT( !IsActive() ); |
|
191 |
|
192 HBufC* text( NULL ); |
|
193 if ( iChangedLinks->Count() > 0 ) |
|
194 { |
|
195 ASSERT( iChangedLinks->Count() == 1 ); // single item fetch -> 1 |
|
196 MVPbkStoreContact* storeContact = NULL; |
|
197 MVPbkStoreContactField* selectedField = NULL; |
|
198 const MVPbkContactLink& link = iChangedLinks->At( 0 ); |
|
199 iContactMatcher->GetStoreContactL( link, &storeContact ); |
|
200 storeContact->PushL(); |
|
201 MVPbkStoreContactFieldCollection& fieldCollection = |
|
202 storeContact->Fields(); |
|
203 selectedField = fieldCollection.RetrieveField( link ); |
|
204 if ( selectedField ) |
|
205 { |
|
206 // Set field data |
|
207 const MVPbkContactFieldTextData* textData = |
|
208 &MVPbkContactFieldTextData::Cast( selectedField->FieldData() ); |
|
209 text = textData->Text().AllocL(); |
|
210 } |
|
211 CleanupStack::PopAndDestroy( storeContact ); |
|
212 } |
|
213 iChangedLinks->ResetAndDestroy(); |
|
214 return text; |
|
215 } |
|
216 //---------------------------------------------------------------------------- |
|
217 // CMuiuContactAddressMatcher::GetNameL() |
|
218 // Returns NULL pointer if no data is found |
|
219 //---------------------------------------------------------------------------- |
|
220 HBufC* CMuiuContactAddressMatcher::GetNameL() const |
|
221 { |
|
222 MVPbkStoreContact* storeContact = NULL; |
|
223 HBufC* name( NULL ); |
|
224 |
|
225 ASSERT(iContactMatcher); // should exist |
|
226 |
|
227 if(iContactLinks->Count() > 0) |
|
228 { |
|
229 //We should have only one contact link. |
|
230 iContactMatcher->GetStoreContactL( iContactLinks->At(0), &storeContact ); |
|
231 storeContact->PushL(); |
|
232 |
|
233 MVPbkStoreContactFieldCollection& fieldCollection = |
|
234 storeContact->Fields(); |
|
235 |
|
236 name = iContactMatcher->GetNameL(fieldCollection); |
|
237 |
|
238 CleanupStack::PopAndDestroy( storeContact ); |
|
239 } |
|
240 iContactLinks->ResetAndDestroy(); |
|
241 return name; |
|
242 } |
|
243 |
|
244 // ---------------------------------------------------------------------------- |
|
245 // CMuiuContactAddressMatcher::DoCancel() |
|
246 // From CActive |
|
247 // ---------------------------------------------------------------------------- |
|
248 // |
|
249 void CMuiuContactAddressMatcher::DoCancel() |
|
250 { |
|
251 if ( iContactMatcher ) |
|
252 { |
|
253 iContactMatcher->CancelOperation(); |
|
254 } |
|
255 } |
|
256 |
|
257 // ---------------------------------------------------------------------------- |
|
258 // CMuiuContactAddressMatcher::RunL() |
|
259 // From CActive |
|
260 // ---------------------------------------------------------------------------- |
|
261 // |
|
262 void CMuiuContactAddressMatcher::RunL() |
|
263 { |
|
264 // We need to delete excess matches, otherwise Fetch AIW may |
|
265 // continue with next match when user presses Cancel. |
|
266 DeleteExcessMatchesL( *iContactLinks ); |
|
267 if( iContactLinks->Count() == 0) |
|
268 { |
|
269 HBufC* string = StringLoader::LoadLC( R_MUIU_QTN_PHOB_NOTE_NO_NUMBER, &iEikEnv ); |
|
270 CAknInformationNote* note = new ( ELeave ) CAknInformationNote( ETrue ); |
|
271 note->ExecuteLD( *string ); |
|
272 CleanupStack::PopAndDestroy( string ); |
|
273 // Deleting wait dialog in the beginning of the function causes |
|
274 // info note to flicker |
|
275 if ( iWaitDialog ) |
|
276 { |
|
277 iWaitDialog->ProcessFinishedL(); // deletes the dialog |
|
278 } |
|
279 |
|
280 //We can't call iCallBack straight away, |
|
281 //because it triggers events that cause KErrInUse leave. |
|
282 iIdle->Start(iCallBack); |
|
283 } |
|
284 else |
|
285 { |
|
286 if ( iWaitDialog ) |
|
287 { |
|
288 iWaitDialog->ProcessFinishedL(); // deletes the dialog |
|
289 } |
|
290 CVPbkFieldTypeSelector* filter = CreateFilterLC( ); |
|
291 TAiwSingleItemSelectionDataV3 selectionData = SelectionData( *filter); |
|
292 ExecuteSingleItemFetchL( selectionData, *iContactLinks ); |
|
293 CleanupStack::PopAndDestroy( filter ); |
|
294 } |
|
295 } |
|
296 |
|
297 // ---------------------------------------------------------------------------- |
|
298 // CMuiuContactAddressMatcher::RunError |
|
299 // From CActive |
|
300 // ---------------------------------------------------------------------------- |
|
301 // |
|
302 TInt CMuiuContactAddressMatcher::RunError( TInt aError ) |
|
303 { |
|
304 if( aError == KLeaveExit ) |
|
305 { |
|
306 return aError; |
|
307 } |
|
308 else |
|
309 { |
|
310 return KErrNone; |
|
311 } |
|
312 } |
|
313 |
|
314 // ---------------------------------------------------------------------------- |
|
315 // CMuiuContactAddressMatcher::HandleNotifyL |
|
316 // From MAiwNotifyCallback |
|
317 // ---------------------------------------------------------------------------- |
|
318 // |
|
319 TInt CMuiuContactAddressMatcher::HandleNotifyL( |
|
320 TInt /*aCmdId*/, |
|
321 TInt aEventId, |
|
322 CAiwGenericParamList& aEventParamList, |
|
323 const CAiwGenericParamList& /*aInParamList*/ ) |
|
324 { |
|
325 TInt retVal( KErrNone ); |
|
326 if ( aEventId == KAiwEventCompleted ) |
|
327 { |
|
328 TInt index( 0 ); |
|
329 const TAiwGenericParam* param = |
|
330 aEventParamList.FindFirst( index, EGenericParamContactLinkArray ); |
|
331 if ( param ) |
|
332 { |
|
333 TPtrC8 contactLinks = param->Value().AsData(); |
|
334 if ( contactLinks.Length() > 0 ) |
|
335 { |
|
336 CVPbkContactLinkArray* links = CVPbkContactLinkArray::NewLC( |
|
337 contactLinks, iContactMatcher->GetContactStoresL() ); |
|
338 CleanupStack::Pop();//links |
|
339 iChangedLinks->ResetAndDestroy(); |
|
340 delete iChangedLinks; |
|
341 iChangedLinks = links; |
|
342 } |
|
343 else |
|
344 { |
|
345 retVal = KErrArgument; |
|
346 } |
|
347 } |
|
348 } |
|
349 //Notify waiter always, even if error. |
|
350 //We can't call iCallBack straight away, |
|
351 //because it triggers events that cause KErrInUse leave. |
|
352 iIdle->Start(iCallBack); |
|
353 return retVal; |
|
354 } |
|
355 |
|
356 //---------------------------------------------------------------------------- |
|
357 // CMuiuContactAddressMatcher::DeleteExcessMatches() |
|
358 //---------------------------------------------------------------------------- |
|
359 void CMuiuContactAddressMatcher::DeleteExcessMatchesL( |
|
360 CVPbkContactLinkArray& aLinks ) const |
|
361 { |
|
362 // It may be that first contact has not phone number but others has. |
|
363 TInt count = aLinks.Count(); |
|
364 // Search for first contact that has phone number |
|
365 for (TInt i=0 ; i < count ; i++ ) |
|
366 { |
|
367 MVPbkStoreContact* storeContact = NULL; |
|
368 const MVPbkContactLink& link = aLinks.At( i ); |
|
369 iContactMatcher->GetStoreContactL( link, &storeContact ); |
|
370 storeContact->PushL(); |
|
371 if ( storeContact |
|
372 && iContactMatcher->ContactHasFieldOfTypeL( EAiwPhoneNumberSelect, *storeContact ) == KErrNotFound ) |
|
373 { |
|
374 aLinks.Delete( i-- ); |
|
375 count = aLinks.Count(); |
|
376 } |
|
377 else if ( !storeContact ) |
|
378 { |
|
379 // is this possible? |
|
380 aLinks.Delete( i-- ); |
|
381 count = aLinks.Count(); |
|
382 } |
|
383 else |
|
384 { |
|
385 CleanupStack::PopAndDestroy( storeContact ); |
|
386 break; |
|
387 } |
|
388 CleanupStack::PopAndDestroy( storeContact ); |
|
389 } |
|
390 |
|
391 TInt k( aLinks.Count() - 1 ); |
|
392 // delete all but link at index 0 |
|
393 while ( k > 0 ) |
|
394 { |
|
395 aLinks.Delete( k-- ); |
|
396 } |
|
397 } |
|
398 |
|
399 //---------------------------------------------------------------------------- |
|
400 // CMuiuContactAddressMatcher::CreateFilterLC() |
|
401 //---------------------------------------------------------------------------- |
|
402 CVPbkFieldTypeSelector* CMuiuContactAddressMatcher::CreateFilterLC( ) const |
|
403 { |
|
404 CVPbkContactManager& contactMgr = iContactMatcher->GetContactManager(); |
|
405 CVPbkFieldTypeSelector* contactViewFilter = |
|
406 CVPbkFieldTypeSelector::NewL( contactMgr.FieldTypes() ); |
|
407 CleanupStack::PushL( contactViewFilter ); |
|
408 |
|
409 // Append the filter object with suitable criteria |
|
410 VPbkContactViewFilterBuilder::BuildContactViewFilterL( |
|
411 *contactViewFilter, EVPbkContactViewFilterPhoneNumber, contactMgr ); |
|
412 |
|
413 //VPbkContactViewFilterBuilder::BuildContactViewFilterL( |
|
414 // *contactViewFilter, EVPbkContactViewFilterEmail, contactMgr ); |
|
415 |
|
416 return contactViewFilter; |
|
417 } |
|
418 |
|
419 //---------------------------------------------------------------------------- |
|
420 // CMuiuContactAddressMatcher::SelectionData() |
|
421 //---------------------------------------------------------------------------- |
|
422 TAiwSingleItemSelectionDataV3 |
|
423 CMuiuContactAddressMatcher::SelectionData( |
|
424 CVPbkFieldTypeSelector& aFilter ) const |
|
425 { |
|
426 TAiwAddressSelectType addressSelectType( EAiwAllItemsSelect ); |
|
427 addressSelectType = EAiwPhoneNumberSelect; |
|
428 |
|
429 TAiwSingleItemSelectionDataV3 selData; |
|
430 selData.SetAddressSelectType( addressSelectType ) |
|
431 .SetFetchFilter( &aFilter ); |
|
432 return selData; |
|
433 } |
|
434 |
|
435 //---------------------------------------------------------------------------- |
|
436 // CMuiuContactAddressMatcher::ExecuteSingleItemFetchL() |
|
437 //---------------------------------------------------------------------------- |
|
438 void CMuiuContactAddressMatcher::ExecuteSingleItemFetchL( |
|
439 TAiwSingleItemSelectionDataV3 aData, |
|
440 const CVPbkContactLinkArray& aLinks ) |
|
441 { |
|
442 CAiwGenericParamList& inParamList = iServiceHandler->InParamListL(); |
|
443 inParamList.AppendL( |
|
444 TAiwGenericParam( EGenericParamContactSelectionData, |
|
445 TAiwVariant( TAiwSingleItemSelectionDataV3Pckg( aData ) ) ) ); |
|
446 |
|
447 //Contacts that matched search |
|
448 HBufC8* packedLinks = aLinks.PackLC(); |
|
449 |
|
450 inParamList.AppendL( TAiwGenericParam( EGenericParamContactLinkArray, |
|
451 TAiwVariant( *packedLinks ) ) ); |
|
452 |
|
453 iServiceHandler->ExecuteServiceCmdL( KAiwCmdSelect, |
|
454 inParamList, |
|
455 iServiceHandler->OutParamListL(), |
|
456 0, |
|
457 this ); |
|
458 CleanupStack::PopAndDestroy( packedLinks ); |
|
459 } |
|
460 |
|
461 // End of File |
|
462 |