|
1 /* |
|
2 * Copyright (c) 2008 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: Implementation of the class CFscAddressSelect. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "emailtrace.h" |
|
20 #include "CFscAddressSelect.h" |
|
21 |
|
22 // Phonebook 2 |
|
23 #include "CFscSelectFieldDlg.h" |
|
24 #include "MFscControlKeyObserver.h" |
|
25 #include <MPbk2ContactNameFormatter.h> |
|
26 #include "CFscFieldPropertyArray.h" |
|
27 #include "TFscAddressSelectParams.h" |
|
28 #include <MPbk2ApplicationServices.h> |
|
29 #include <MPbk2AppUi.h> |
|
30 |
|
31 // Virtual Phonebook |
|
32 #include <CVPbkFieldFilter.h> |
|
33 #include <MVPbkStoreContactField.h> |
|
34 #include <MVPbkStoreContact.h> |
|
35 #include <CVPbkFieldTypeSelector.h> |
|
36 #include <MVPbkContactFieldData.h> |
|
37 #include <MVPbkStoreContactFieldCollection.h> |
|
38 #include <CVPbkContactManager.h> |
|
39 #include <CVPbkDefaultAttribute.h> |
|
40 |
|
41 // System includes |
|
42 #include <avkon.hrh> |
|
43 #include <aknnotewrappers.h> |
|
44 #include <StringLoader.h> |
|
45 |
|
46 #include <CVPbkContactManager.h> |
|
47 |
|
48 /// Unnamed namespace for local definitions |
|
49 namespace |
|
50 { |
|
51 |
|
52 #ifdef _DEBUG |
|
53 enum TPanicCode |
|
54 { |
|
55 EPanicPostCond_Constructor = 1, |
|
56 EPanicPreCond_ExecuteLD |
|
57 }; |
|
58 |
|
59 static void Panic(TPanicCode aReason) |
|
60 { |
|
61 _LIT(KPanicText, "CPbk2AddressSelect"); |
|
62 User::Panic(KPanicText, aReason); |
|
63 } |
|
64 #endif // _DEBUG |
|
65 const TInt KFirstField = 0; |
|
66 const TInt KDefaultTitleFormat = MPbk2ContactNameFormatter::EUseSeparator; |
|
67 |
|
68 /** |
|
69 * Returns index of given field in store contact field collection. |
|
70 * |
|
71 * @param aCollection Store contact field collection. |
|
72 * @param aField Store contact field to search for. |
|
73 * @return Index of the given field. |
|
74 */ |
|
75 inline TInt IndexOfField( |
|
76 const MVPbkStoreContactFieldCollection& aCollection, |
|
77 const MVPbkStoreContactField& aField) |
|
78 { |
|
79 TInt ret = KErrNotFound; |
|
80 const TInt count = aCollection.FieldCount(); |
|
81 |
|
82 for (TInt i = 0; i < count; ++i) |
|
83 { |
|
84 MVPbkStoreContactField* field = aCollection.FieldAtLC(i); |
|
85 if (aField.IsSame( *field) ) |
|
86 { |
|
87 ret = i; |
|
88 CleanupStack::PopAndDestroy(); // field |
|
89 break; |
|
90 } |
|
91 CleanupStack::PopAndDestroy(); // field |
|
92 } |
|
93 |
|
94 return ret; |
|
95 } |
|
96 |
|
97 } /// namespace |
|
98 |
|
99 // MODULE DATA STRUCTURES |
|
100 |
|
101 /** |
|
102 * Special field selection dialog class for CFscAddressSelect. |
|
103 * The main purpose of this class is to |
|
104 * get #include of MFscControlKeyObserver |
|
105 * away from public header cfscaddressselect.h. |
|
106 */ |
|
107 NONSHARABLE_CLASS(CFscAddressSelect::CSelectFieldDlg) : |
|
108 public CFscSelectFieldDlg, |
|
109 private MFscControlKeyObserver |
|
110 { |
|
111 public: // Construction |
|
112 |
|
113 /** |
|
114 * Constructor. |
|
115 * |
|
116 * @param aParent Parent. |
|
117 */ |
|
118 CSelectFieldDlg( CFscAddressSelect& aParent ) : |
|
119 iParent( aParent ) |
|
120 { |
|
121 SetObserver( this ); |
|
122 } |
|
123 |
|
124 private: // From MFscControlKeyObserver |
|
125 TKeyResponse FscControlKeyEventL |
|
126 ( const TKeyEvent& aKeyEvent, TEventCode aType ); |
|
127 |
|
128 private: // Data |
|
129 /// Ref: Parent |
|
130 CFscAddressSelect& iParent; |
|
131 }; |
|
132 |
|
133 // -------------------------------------------------------------------------- |
|
134 // CFscAddressSelect::CSelectFieldDlg::FscControlKeyEventL |
|
135 // -------------------------------------------------------------------------- |
|
136 // |
|
137 TKeyResponse CFscAddressSelect::CSelectFieldDlg::FscControlKeyEventL( |
|
138 const TKeyEvent& aKeyEvent, TEventCode aType) |
|
139 { |
|
140 FUNC_LOG; |
|
141 // Forward call to virtual function in CFscAddressSelect interface |
|
142 return iParent.FscControlKeyEventL(aKeyEvent, aType); |
|
143 } |
|
144 |
|
145 // -------------------------------------------------------------------------- |
|
146 // CFscAddressSelect::CFscAddressSelect |
|
147 // -------------------------------------------------------------------------- |
|
148 // |
|
149 CFscAddressSelect::CFscAddressSelect(TFscAddressSelectParams& aParams) : |
|
150 iParams(aParams) |
|
151 { |
|
152 FUNC_LOG; |
|
153 __ASSERT_DEBUG |
|
154 ( !iFieldDlg && !iDestroyedPtr, |
|
155 Panic( EPanicPostCond_Constructor ) ); |
|
156 } |
|
157 |
|
158 // -------------------------------------------------------------------------- |
|
159 // CFscAddressSelect::~CFscAddressSelect |
|
160 // -------------------------------------------------------------------------- |
|
161 // |
|
162 CFscAddressSelect::~CFscAddressSelect() |
|
163 { |
|
164 FUNC_LOG; |
|
165 // Tell ExecuteLD this object is already destroyed |
|
166 if (iDestroyedPtr) |
|
167 { |
|
168 *iDestroyedPtr = ETrue; |
|
169 } |
|
170 |
|
171 // Set eliminator pointer to NULL |
|
172 if (iSelfPtr) |
|
173 { |
|
174 *iSelfPtr = NULL; |
|
175 } |
|
176 |
|
177 delete iFieldDlg; |
|
178 delete iFieldFilter; |
|
179 delete iFieldTypeSelector; |
|
180 } |
|
181 |
|
182 // -------------------------------------------------------------------------- |
|
183 // CFscAddressSelect::NewL |
|
184 // -------------------------------------------------------------------------- |
|
185 // |
|
186 CFscAddressSelect* CFscAddressSelect::NewL |
|
187 ( TFscAddressSelectParams& aParams ) |
|
188 { |
|
189 FUNC_LOG; |
|
190 CFscAddressSelect* self = new ( ELeave ) CFscAddressSelect( aParams ); |
|
191 CleanupStack::PushL( self ); |
|
192 self->ConstructL(); |
|
193 CleanupStack::Pop( self ); |
|
194 return self; |
|
195 } |
|
196 |
|
197 // -------------------------------------------------------------------------- |
|
198 // CFscAddressSelect::ConstructL |
|
199 // -------------------------------------------------------------------------- |
|
200 // |
|
201 void CFscAddressSelect::ConstructL() |
|
202 { |
|
203 FUNC_LOG; |
|
204 // Read the resource referenced in address select resource struct |
|
205 const TInt fieldTypeSelectorRes = iParams.iResReader.ReadInt32(); |
|
206 TResourceReader selectorReader; |
|
207 CCoeEnv::Static()->CreateResourceReaderLC(selectorReader, fieldTypeSelectorRes); |
|
208 // Give that resource reader to the field type selector |
|
209 iFieldTypeSelector = CVPbkFieldTypeSelector::NewL(selectorReader, |
|
210 iParams.iContactManager.FieldTypes() ); |
|
211 CleanupStack::PopAndDestroy(); // selectorReader |
|
212 |
|
213 iNoAddressesForNamePromptResource = iParams.iResReader.ReadInt32(); |
|
214 iNoAddressesPromptResource = iParams.iResReader.ReadInt32(); |
|
215 iSoftKeyResource = iParams.iResReader.ReadInt32(); |
|
216 |
|
217 const CVPbkFieldFilter::TConfig |
|
218 config( |
|
219 const_cast<MVPbkStoreContactFieldCollection&> (iParams.iContact.Fields() ), |
|
220 iFieldTypeSelector, NULL); |
|
221 |
|
222 iFieldFilter = CVPbkFieldFilter::NewL(config); |
|
223 |
|
224 CVPbkContactManager& iContactManager = |
|
225 const_cast<CVPbkContactManager&>(iParams.iContactManager); |
|
226 iAttributeManager = &iContactManager.ContactAttributeManagerL(); |
|
227 } |
|
228 |
|
229 // -------------------------------------------------------------------------- |
|
230 // CFscAddressSelect::ExecuteLD |
|
231 // -------------------------------------------------------------------------- |
|
232 // |
|
233 MVPbkStoreContactField* CFscAddressSelect::ExecuteLD() |
|
234 { |
|
235 FUNC_LOG; |
|
236 __ASSERT_DEBUG( !iFieldDlg, Panic( EPanicPreCond_ExecuteLD ) ); |
|
237 |
|
238 // "D" function semantics |
|
239 CleanupStack::PushL( this ); |
|
240 TBool thisDestroyed = EFalse; |
|
241 // Ensure that thisDestroyed will be ETrue if this object is destroyed. |
|
242 // See in destructor how this is done. |
|
243 iDestroyedPtr = &thisDestroyed; |
|
244 |
|
245 SelectFieldL(); |
|
246 |
|
247 MVPbkStoreContactField* returnedField = NULL; |
|
248 if ( iSelectedField ) |
|
249 { |
|
250 // We cannot return iSelectedField directly since if its NULL, |
|
251 // it's value changes to 0xdedede before it is returned. |
|
252 // Therefore we must test iSelectedField before assigning it |
|
253 // to returnedField. |
|
254 returnedField = iSelectedField; |
|
255 } |
|
256 |
|
257 if ( thisDestroyed ) |
|
258 { |
|
259 // This object has already been destroyed |
|
260 CleanupStack::Pop( this ); |
|
261 returnedField = NULL; |
|
262 } |
|
263 else |
|
264 { |
|
265 CleanupStack::PopAndDestroy( this ); |
|
266 } |
|
267 |
|
268 return returnedField; |
|
269 } |
|
270 |
|
271 // -------------------------------------------------------------------------- |
|
272 // CFscAddressSelect::AttemptExitL |
|
273 // -------------------------------------------------------------------------- |
|
274 // |
|
275 void CFscAddressSelect::AttemptExitL(TBool aAccept) |
|
276 { |
|
277 FUNC_LOG; |
|
278 if (iFieldDlg) |
|
279 { |
|
280 iFieldDlg->AttemptExitL(aAccept); |
|
281 } |
|
282 } |
|
283 |
|
284 // -------------------------------------------------------------------------- |
|
285 // CFscAddressSelect::FscControlKeyEventL |
|
286 // -------------------------------------------------------------------------- |
|
287 // |
|
288 TKeyResponse CFscAddressSelect::FscControlKeyEventL |
|
289 ( const TKeyEvent& aKeyEvent, TEventCode aType ) |
|
290 { |
|
291 FUNC_LOG; |
|
292 TKeyResponse ret = EKeyWasNotConsumed; |
|
293 |
|
294 if ( aType == EEventKey && aKeyEvent.iCode == EKeyPhoneSend ) |
|
295 { |
|
296 // Event is Send key, tell field selection dialog to accept |
|
297 // current selection |
|
298 AttemptExitL( ETrue ); |
|
299 ret = EKeyWasConsumed; |
|
300 } |
|
301 else |
|
302 if ( aType == EEventKey && aKeyEvent.iCode == EKeyPhoneEnd ) |
|
303 { |
|
304 ForceExit(); |
|
305 ret = EKeyWasConsumed; |
|
306 } |
|
307 |
|
308 return ret; |
|
309 } |
|
310 |
|
311 // -------------------------------------------------------------------------- |
|
312 // CFscAddressSelect::RequestExitL |
|
313 // -------------------------------------------------------------------------- |
|
314 // |
|
315 void CFscAddressSelect::RequestExitL(TInt aCommandId) |
|
316 { |
|
317 FUNC_LOG; |
|
318 if (aCommandId == EEikBidCancel) |
|
319 { |
|
320 AttemptExitL(EFalse); |
|
321 } |
|
322 else |
|
323 if (aCommandId == EEikBidOk) |
|
324 { |
|
325 AttemptExitL(ETrue); |
|
326 } |
|
327 } |
|
328 |
|
329 // -------------------------------------------------------------------------- |
|
330 // CFscAddressSelect::ForceExit |
|
331 // -------------------------------------------------------------------------- |
|
332 // |
|
333 void CFscAddressSelect::ForceExit() |
|
334 { |
|
335 FUNC_LOG; |
|
336 TRAPD( err, AttemptExitL( EFalse ) ) |
|
337 ; |
|
338 if (err != KErrNone) |
|
339 { |
|
340 // If not nicely then use the force |
|
341 delete this; |
|
342 } |
|
343 } |
|
344 |
|
345 // -------------------------------------------------------------------------- |
|
346 // CFscAddressSelect::ResetWhenDestroyed |
|
347 // -------------------------------------------------------------------------- |
|
348 // |
|
349 void CFscAddressSelect::ResetWhenDestroyed(MFscDialogEliminator** aSelfPtr) |
|
350 { |
|
351 FUNC_LOG; |
|
352 iSelfPtr = aSelfPtr; |
|
353 } |
|
354 |
|
355 // -------------------------------------------------------------------------- |
|
356 // CFscAddressSelect::AddressField |
|
357 // Returns true if aField is an applicable address field. |
|
358 // -------------------------------------------------------------------------- |
|
359 // |
|
360 TBool CFscAddressSelect::AddressField(const MVPbkStoreContactField& aField) const |
|
361 { |
|
362 FUNC_LOG; |
|
363 TBool ret = EFalse; |
|
364 |
|
365 // Return true if field belongs to the selector |
|
366 ret = (iFieldFilter->FindField(aField) == KErrNotFound ) ? EFalse : ETrue; |
|
367 |
|
368 return ret; |
|
369 } |
|
370 |
|
371 // -------------------------------------------------------------------------- |
|
372 // CFscAddressSelect::NoAddressesL |
|
373 // Called if there are no applicable address fields in a contact passed |
|
374 // to ExecuteLD. |
|
375 // -------------------------------------------------------------------------- |
|
376 // |
|
377 void CFscAddressSelect::NoAddressesL(TFscAddressSelectParams aParams) const |
|
378 { |
|
379 FUNC_LOG; |
|
380 if ( !aParams.iSuppressWarnings) |
|
381 { |
|
382 HBufC* prompt= NULL; |
|
383 HBufC* name = aParams.iNameFormatter.GetContactTitleOrNullL( |
|
384 iParams.iContact.Fields(), KDefaultTitleFormat); |
|
385 |
|
386 if (name) |
|
387 { |
|
388 CleanupStack::PushL(name); |
|
389 prompt = StringLoader::LoadL(iNoAddressesForNamePromptResource, |
|
390 *name); |
|
391 CleanupStack::PopAndDestroy(); // name |
|
392 } |
|
393 else |
|
394 { |
|
395 prompt = StringLoader::LoadL(iNoAddressesPromptResource); |
|
396 } |
|
397 |
|
398 if (prompt) |
|
399 { |
|
400 CleanupStack::PushL(prompt); |
|
401 // This is a waiting dialog because the address select might be |
|
402 // used from the application server and the information note will |
|
403 // disappear if the application server closes before the |
|
404 // note timeout has expired, thus causing blinking |
|
405 CAknInformationNote* noteDlg = new ( ELeave ) CAknInformationNote( ETrue ); |
|
406 noteDlg->ExecuteLD( *prompt); |
|
407 CleanupStack::PopAndDestroy(); // prompt |
|
408 } |
|
409 } |
|
410 } |
|
411 |
|
412 // -------------------------------------------------------------------------- |
|
413 // CFscAddressSelect::SelectFieldL |
|
414 // -------------------------------------------------------------------------- |
|
415 // |
|
416 inline void CFscAddressSelect::SelectFieldL() |
|
417 { |
|
418 FUNC_LOG; |
|
419 // If currently focused field is an applicable field |
|
420 if (iParams.iFocusedField && AddressField( *iParams.iFocusedField) ) |
|
421 { |
|
422 // Applicable field was focused -> return field |
|
423 SetSelectedFieldL(iParams.iFocusedField); |
|
424 } |
|
425 else |
|
426 { |
|
427 TBool found = EFalse; |
|
428 // Focus is in on some other field, first check default field |
|
429 if (iParams.iDefaultPriorities && iParams.iUseDefaultDirectly |
|
430 && iParams.iDefaultPriorities->Count() > 0) |
|
431 { |
|
432 found = SelectFromDefaultFieldsL(); |
|
433 } |
|
434 |
|
435 if ( !found) |
|
436 { |
|
437 // No direct call to focused or default number, we have to |
|
438 // select from applicable fields |
|
439 SelectFromApplicableFieldsL(); |
|
440 } |
|
441 } |
|
442 } |
|
443 |
|
444 // -------------------------------------------------------------------------- |
|
445 // CFscAddressSelect::SelectFromApplicableFieldsL |
|
446 // -------------------------------------------------------------------------- |
|
447 // |
|
448 inline void CFscAddressSelect::SelectFromApplicableFieldsL() |
|
449 { |
|
450 FUNC_LOG; |
|
451 TInt indexOfDefault = IndexOfDefaultFieldL(); |
|
452 const TInt fieldCount = iFieldFilter->FieldCount(); |
|
453 |
|
454 // Different actions for different number of applicable fields found |
|
455 if (fieldCount == 0) |
|
456 { |
|
457 // No applicable addresses found |
|
458 NoAddressesL(iParams); |
|
459 } |
|
460 else |
|
461 if (fieldCount == 1) |
|
462 { |
|
463 // Exactly one applicable address found, just return it |
|
464 SetSelectedFieldL( &iFieldFilter->FieldAt(KFirstField) ); |
|
465 } |
|
466 else |
|
467 if (fieldCount > 1) |
|
468 { |
|
469 HBufC* entryTitle = iParams.iNameFormatter.GetContactTitleL( |
|
470 iParams.iContact.Fields(), KDefaultTitleFormat); |
|
471 CleanupStack::PushL(entryTitle); |
|
472 HBufC* title= NULL; |
|
473 if (iParams.iTitleResId) |
|
474 { |
|
475 if (iParams.iIncludeContactNameInPrompt) |
|
476 { |
|
477 title = StringLoader::LoadL(iParams.iTitleResId, |
|
478 *entryTitle); |
|
479 } |
|
480 else |
|
481 { |
|
482 title = StringLoader::LoadL(iParams.iTitleResId); |
|
483 } |
|
484 CleanupStack::PopAndDestroy(entryTitle); |
|
485 } |
|
486 else |
|
487 { |
|
488 title = entryTitle; // takes ownership of entryTitle |
|
489 CleanupStack::Pop(entryTitle); |
|
490 entryTitle = NULL; |
|
491 } |
|
492 |
|
493 // Run the address selection dialog |
|
494 CleanupStack::PushL(title); |
|
495 iFieldDlg = new ( ELeave ) CSelectFieldDlg( *this ); |
|
496 iFieldDlg->ResetWhenDestroyed( &iFieldDlg); |
|
497 MVPbkStoreContactField* field= NULL; |
|
498 //<cmail> |
|
499 field = iFieldDlg->ExecuteLD( *iFieldFilter, |
|
500 iParams.iContactManager, iParams.iFieldPropertyArray, |
|
501 iSoftKeyResource, *title, indexOfDefault); |
|
502 CleanupDeletePushL( field ); |
|
503 //</cmail> |
|
504 |
|
505 SetSelectedFieldL(field); |
|
506 |
|
507 CleanupStack::PopAndDestroy( 2); // field, title |
|
508 } |
|
509 } |
|
510 |
|
511 // -------------------------------------------------------------------------- |
|
512 // CFscAddressSelect::IndexOfDefaultFieldL |
|
513 // -------------------------------------------------------------------------- |
|
514 // |
|
515 inline TInt CFscAddressSelect::IndexOfDefaultFieldL() |
|
516 { |
|
517 FUNC_LOG; |
|
518 TInt ret = KErrNotFound; |
|
519 |
|
520 const MVPbkStoreContactField* field = FindDefaultFieldLC(); |
|
521 if (field) |
|
522 { |
|
523 ret = iFieldFilter->FindField( *field); |
|
524 } |
|
525 CleanupStack::PopAndDestroy(); // field |
|
526 |
|
527 return ret; |
|
528 } |
|
529 |
|
530 // -------------------------------------------------------------------------- |
|
531 // CFscAddressSelect::SelectFromDefaultFieldsL |
|
532 // -------------------------------------------------------------------------- |
|
533 // |
|
534 inline TBool CFscAddressSelect::SelectFromDefaultFieldsL() |
|
535 { |
|
536 FUNC_LOG; |
|
537 TBool found = EFalse; |
|
538 |
|
539 const MVPbkStoreContactField* field = FindDefaultFieldLC(); |
|
540 if (field) |
|
541 { |
|
542 SetSelectedFieldL(field); |
|
543 found = ETrue; |
|
544 } |
|
545 CleanupStack::PopAndDestroy(); // field |
|
546 |
|
547 return found; |
|
548 } |
|
549 |
|
550 // -------------------------------------------------------------------------- |
|
551 // CFscAddressSelect::FindDefaultFieldLC |
|
552 // -------------------------------------------------------------------------- |
|
553 // |
|
554 MVPbkStoreContactField* CFscAddressSelect::FindDefaultFieldLC() |
|
555 { |
|
556 FUNC_LOG; |
|
557 MVPbkStoreContactField* ret= NULL; |
|
558 |
|
559 // Go through the default priorities array, and |
|
560 // check does a specific default exist |
|
561 if (iParams.iDefaultPriorities) |
|
562 { |
|
563 const TInt defaultCount = iParams.iDefaultPriorities->Count(); |
|
564 |
|
565 for (TInt i=0; i<defaultCount; ++i) |
|
566 { |
|
567 TVPbkDefaultType defaultType = |
|
568 (TVPbkDefaultType) iParams.iDefaultPriorities->At(i); |
|
569 |
|
570 // Create an attribute prototype out of the attribute identifier |
|
571 CVPbkDefaultAttribute* attr = |
|
572 CVPbkDefaultAttribute::NewL(defaultType); |
|
573 CleanupStack::PushL(attr); |
|
574 |
|
575 if (iAttributeManager->HasContactAttributeL( *attr, |
|
576 iParams.iContact) ) |
|
577 { |
|
578 const MVPbkStoreContactFieldCollection& fields = |
|
579 iParams.iContact.Fields(); |
|
580 |
|
581 // Get the field with attribute |
|
582 const TInt fieldCount = fields.FieldCount(); |
|
583 for (TInt j = 0; j < fieldCount; ++j) |
|
584 { |
|
585 if (iAttributeManager->HasFieldAttributeL( *attr, |
|
586 fields.FieldAt(j) ) ) |
|
587 { |
|
588 ret = fields.FieldAtLC(j); |
|
589 CleanupStack::Pop(); // ret |
|
590 break; |
|
591 } |
|
592 } |
|
593 } |
|
594 |
|
595 CleanupStack::PopAndDestroy(attr); |
|
596 } |
|
597 } |
|
598 |
|
599 CleanupDeletePushL(ret); |
|
600 return ret; |
|
601 } |
|
602 |
|
603 // -------------------------------------------------------------------------- |
|
604 // CFscAddressSelect::SetSelectedFieldL |
|
605 // -------------------------------------------------------------------------- |
|
606 // |
|
607 inline void CFscAddressSelect::SetSelectedFieldL( |
|
608 const MVPbkStoreContactField* aField) |
|
609 { |
|
610 FUNC_LOG; |
|
611 if (aField) |
|
612 { |
|
613 const MVPbkStoreContactFieldCollection& fields = |
|
614 iParams.iContact.Fields(); |
|
615 TInt index = IndexOfField(fields, *aField); |
|
616 iSelectedField = fields.FieldAtLC(index); |
|
617 CleanupStack::Pop(); |
|
618 } |
|
619 } |
|
620 |
|
621 // End of File |
|
622 |