|
1 /* |
|
2 * Copyright (c) 2002-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: The virtual phonebook contact |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include "CContact.h" |
|
21 #include <cntitem.h> |
|
22 #include <babitflags.h> |
|
23 |
|
24 #include <VPbkError.h> |
|
25 #include <MVPbkContactObserver.h> |
|
26 #include <TVPbkFieldTypeMapping.h> |
|
27 #include <MVPbkFieldType.h> |
|
28 #include <MVPbkContactStoreProperties.h> |
|
29 #include <CVPbkContactLinkArray.h> |
|
30 #include <CVPbkContactFieldCollection.h> |
|
31 #include <MVPbkStoreContactProperties.h> |
|
32 |
|
33 #include "CContactStore.h" |
|
34 #include "CFieldTypeMap.h" |
|
35 #include "TNewContactField.h" |
|
36 #include "CViewContact.h" |
|
37 #include "CContactLink.h" |
|
38 |
|
39 namespace VPbkCntModel { |
|
40 |
|
41 // ======== LOCAL CLASSES ======== |
|
42 |
|
43 /** |
|
44 * Internal store contact properties class, |
|
45 * use CContactItem to implement MVPbkStoreContactProperties methods |
|
46 * |
|
47 */ |
|
48 class CVPbkStoreContactProperties : |
|
49 public CBase, |
|
50 public MVPbkStoreContactProperties |
|
51 { |
|
52 public: |
|
53 static CVPbkStoreContactProperties* NewL( |
|
54 CContactItem& aContactItem, |
|
55 CContactDatabase& aContactDb ); |
|
56 |
|
57 ~CVPbkStoreContactProperties(); |
|
58 protected: // MVPbkStoreContactProperties |
|
59 TTime LastModifiedL() const; |
|
60 TPtrC GuidL() const; |
|
61 private: |
|
62 CVPbkStoreContactProperties( |
|
63 CContactItem& aContactItem, |
|
64 CContactDatabase& aContactDb ); |
|
65 |
|
66 private: |
|
67 CContactItem& iContactItem; |
|
68 CContactDatabase& iContactDb; |
|
69 }; |
|
70 |
|
71 CVPbkStoreContactProperties* CVPbkStoreContactProperties::NewL( |
|
72 CContactItem& aContactItem, |
|
73 CContactDatabase& aContactDb ) |
|
74 { |
|
75 CVPbkStoreContactProperties* self = new(ELeave) CVPbkStoreContactProperties( |
|
76 aContactItem, |
|
77 aContactDb ); |
|
78 return self; |
|
79 } |
|
80 |
|
81 CVPbkStoreContactProperties::CVPbkStoreContactProperties( |
|
82 CContactItem& aContactItem, |
|
83 CContactDatabase& aContactDb ) : |
|
84 iContactItem( aContactItem ), |
|
85 iContactDb( aContactDb ) |
|
86 { |
|
87 } |
|
88 |
|
89 CVPbkStoreContactProperties::~CVPbkStoreContactProperties() |
|
90 { |
|
91 } |
|
92 |
|
93 TTime CVPbkStoreContactProperties::LastModifiedL() const |
|
94 { |
|
95 return iContactItem.LastModified(); |
|
96 } |
|
97 |
|
98 TPtrC CVPbkStoreContactProperties::GuidL() const |
|
99 { |
|
100 return iContactItem.UidStringL(iContactDb.MachineId()); |
|
101 } |
|
102 // ======== LOCAL FUNCTIONS ======== |
|
103 |
|
104 TInt FindMatchingField( const MVPbkBaseContactFieldCollection& aFields, |
|
105 const MVPbkFieldType* aFieldType, |
|
106 const MVPbkFieldTypeList& aMasterFieldTypeList ) |
|
107 { |
|
108 TInt result = KErrNotFound; |
|
109 |
|
110 const TInt fieldCount = aFields.FieldCount(); |
|
111 const TInt maxMatchPriority = aMasterFieldTypeList.MaxMatchPriority(); |
|
112 for ( TInt matchPriority = 0; matchPriority <= maxMatchPriority; |
|
113 ++matchPriority ) |
|
114 { |
|
115 for ( TInt i = 0; i < fieldCount; ++i ) |
|
116 { |
|
117 const MVPbkFieldType* fieldType = |
|
118 aFields.FieldAt( i ).MatchFieldType( matchPriority ); |
|
119 if ( fieldType && fieldType->IsSame(*aFieldType) ) |
|
120 { |
|
121 result = i; |
|
122 break; |
|
123 } |
|
124 } |
|
125 } |
|
126 |
|
127 return result; |
|
128 } |
|
129 |
|
130 // ======== MEMBER FUNCTIONS ======== |
|
131 |
|
132 inline CContact::CContact( |
|
133 CContactStore& aParentStore, |
|
134 CContactItem& aContactItem, |
|
135 TBool aIsNewContact ) : |
|
136 iIsNewContact( aIsNewContact ), |
|
137 iFields( *this, aContactItem.CardFields() ), |
|
138 iParentStore( aParentStore ), |
|
139 iLastUpdatedGroupContactId( KNullContactId ) |
|
140 { |
|
141 } |
|
142 |
|
143 inline void CContact::ConstructL() |
|
144 { |
|
145 } |
|
146 |
|
147 CContact* CContact::NewL( |
|
148 CContactStore& aParentStore, |
|
149 CContactItem* aContactItem, |
|
150 TBool aIsNewContact /* = EFalse */) |
|
151 { |
|
152 CContact* self = new(ELeave) CContact( aParentStore, *aContactItem, |
|
153 aIsNewContact ); |
|
154 CleanupStack::PushL( self ); |
|
155 self->ConstructL(); |
|
156 CleanupStack::Pop( self ); |
|
157 // Potentially leaving initialisation is done; take parameter ownership now |
|
158 self->iContactItem = aContactItem; |
|
159 return self; |
|
160 } |
|
161 |
|
162 CContact::~CContact() |
|
163 { |
|
164 // Incase there was a problem when updating the time stamps of contacts |
|
165 // belonging to a group we need to make sure the contact is unlocked by |
|
166 // closing it. Symbian documentation says that despite the trailing L |
|
167 // in the function's name, CloseContactL cannot leave. Also specifying |
|
168 // a contact item that is not open, or cannot be found, is harmless. |
|
169 if ( iLastUpdatedGroupContactId != KNullContactId ) |
|
170 { |
|
171 iParentStore.NativeDatabase().CloseContactL( iLastUpdatedGroupContactId ); |
|
172 } |
|
173 |
|
174 iParentStore.ContactDestroyed( iContactItem, iModified ); |
|
175 delete iContactItem; |
|
176 delete iAddedContacts; |
|
177 } |
|
178 |
|
179 void CContact::SetContact( CContactItem* aContactItem ) |
|
180 { |
|
181 if ( aContactItem && aContactItem != iContactItem ) |
|
182 { |
|
183 delete iContactItem; |
|
184 iContactItem = aContactItem; |
|
185 iFields.SetContact( *this, iContactItem->CardFields() ); |
|
186 } |
|
187 } |
|
188 |
|
189 const CFieldTypeMap& CContact::FieldTypeMap() const |
|
190 { |
|
191 return iParentStore.FieldTypeMap(); |
|
192 } |
|
193 |
|
194 MVPbkObjectHierarchy& CContact::ParentObject() const |
|
195 { |
|
196 return iParentStore; |
|
197 } |
|
198 |
|
199 const MVPbkStoreContactFieldCollection& CContact::Fields() const |
|
200 { |
|
201 return iFields; |
|
202 } |
|
203 |
|
204 TBool CContact::IsSame( const MVPbkStoreContact& aOtherContact ) const |
|
205 { |
|
206 if ( &iParentStore == &aOtherContact.ContactStore() ) |
|
207 { |
|
208 return ( iContactItem->Id() == |
|
209 static_cast<const CContact&>(aOtherContact).iContactItem->Id() ); |
|
210 } |
|
211 return EFalse; |
|
212 } |
|
213 |
|
214 TBool CContact::IsSame( const MVPbkViewContact& aOtherContact ) const |
|
215 { |
|
216 return aOtherContact.IsSame( *this, &ContactStore() ); |
|
217 } |
|
218 |
|
219 MVPbkContactLink* CContact::CreateLinkLC() const |
|
220 { |
|
221 return iParentStore.CreateLinkLC( iContactItem->Id() ); |
|
222 } |
|
223 |
|
224 void CContact::LockL(MVPbkContactObserver& aObserver) const |
|
225 { |
|
226 iParentStore.LockContactL( *this, aObserver ); |
|
227 } |
|
228 |
|
229 void CContact::DeleteL(MVPbkContactObserver& aObserver) const |
|
230 { |
|
231 iParentStore.NativeDatabase().CloseContactL( iContactItem->Id() ); |
|
232 iParentStore.DeleteContactL( iContactItem->Id(), aObserver ); |
|
233 } |
|
234 |
|
235 TBool CContact::MatchContactStore(const TDesC& aContactStoreUri) const |
|
236 { |
|
237 return iParentStore.MatchContactStore( aContactStoreUri ); |
|
238 } |
|
239 |
|
240 TBool CContact::MatchContactStoreDomain( const TDesC& aContactStoreDomain ) const |
|
241 { |
|
242 return iParentStore.MatchContactStoreDomain( aContactStoreDomain ); |
|
243 } |
|
244 |
|
245 MVPbkContactBookmark* CContact::CreateBookmarkLC() const |
|
246 { |
|
247 return iParentStore.CreateBookmarkLC( iContactItem->Id() ); |
|
248 } |
|
249 |
|
250 MVPbkContactStore& CContact::ParentStore() const |
|
251 { |
|
252 return iParentStore; |
|
253 } |
|
254 |
|
255 MVPbkStoreContactFieldCollection& CContact::Fields() |
|
256 { |
|
257 return iFields; |
|
258 } |
|
259 |
|
260 MVPbkStoreContactField* CContact::CreateFieldLC( const MVPbkFieldType& |
|
261 aFieldType ) const |
|
262 { |
|
263 // Match the field type to the Contact Db's system template |
|
264 CContactItemField* newField = iParentStore.CreateFieldLC( aFieldType ); |
|
265 if ( !newField ) |
|
266 { |
|
267 User::Leave( KErrNotSupported ); |
|
268 } |
|
269 |
|
270 // Create a wrapper for the newly created field |
|
271 TNewContactField* fieldWrapper = |
|
272 new(ELeave) TNewContactField( const_cast<CContact&>(*this), newField ); |
|
273 CleanupStack::Pop( newField ); |
|
274 CleanupDeletePushL( fieldWrapper ); |
|
275 |
|
276 // Return the wrapper |
|
277 return fieldWrapper; |
|
278 } |
|
279 |
|
280 TInt CContact::AddFieldL( MVPbkStoreContactField* aField ) |
|
281 { |
|
282 __ASSERT_ALWAYS( aField, VPbkError::Panic( VPbkError::ENullContactField ) ); |
|
283 __ASSERT_ALWAYS( &aField->ParentContact() == this, |
|
284 VPbkError::Panic(VPbkError::EInvalidContactField) ); |
|
285 // Test that the client doesn't pass an existing field of this contact as |
|
286 // a new one |
|
287 __ASSERT_ALWAYS( aField != iFields.FieldPointer(), |
|
288 VPbkError::Panic(VPbkError::EInvalidContactField) ); |
|
289 |
|
290 // After all the checks the field can be cast back to the wrapper that was |
|
291 // created in CreateFieldLC |
|
292 TNewContactField* fieldWrapper = static_cast<TNewContactField*>( aField ); |
|
293 |
|
294 // Add the Contact Model field to the contact item |
|
295 iContactItem->AddFieldL( *fieldWrapper->NativeField() ); |
|
296 // Field added succesfully, release wrapper's ownership |
|
297 fieldWrapper->ReleaseNativeField(); |
|
298 |
|
299 // Delete fieldWrapper. This function must not leave after deletion |
|
300 // of fieldWrapper because CreateFieldLC has put fieldWrapper |
|
301 // into the cleanup stack and client pops it after this function |
|
302 delete fieldWrapper; |
|
303 // The field is appended to the contact -> return the last field index |
|
304 return iContactItem->CardFields().Count() - 1; |
|
305 } |
|
306 |
|
307 void CContact::RemoveField(TInt aIndex) |
|
308 { |
|
309 __ASSERT_ALWAYS( aIndex >= 0 && aIndex < iFields.FieldCount(), |
|
310 VPbkError::Panic(VPbkError::EInvalidFieldIndex) ); |
|
311 __ASSERT_ALWAYS( !iParentStore.StoreProperties().ReadOnly(), |
|
312 VPbkError::Panic(VPbkError::EInvalidAccessToReadOnlyContact ) ); |
|
313 |
|
314 iContactItem->RemoveField( aIndex ); |
|
315 } |
|
316 |
|
317 void CContact::RemoveAllFields() |
|
318 { |
|
319 __ASSERT_ALWAYS( !iParentStore.StoreProperties().ReadOnly(), |
|
320 VPbkError::Panic(VPbkError::EInvalidAccessToReadOnlyContact ) ); |
|
321 |
|
322 iContactItem->CardFields().Reset(); |
|
323 } |
|
324 |
|
325 void CContact::CommitL( MVPbkContactObserver& aObserver ) const |
|
326 { |
|
327 iParentStore.CommitContactL( *this, aObserver ); |
|
328 } |
|
329 |
|
330 MVPbkContactLinkArray* CContact::GroupsJoinedLC() const |
|
331 { |
|
332 CVPbkContactLinkArray* result = CVPbkContactLinkArray::NewLC(); |
|
333 |
|
334 if ( iContactItem->Type() == KUidContactCard ) |
|
335 { |
|
336 CContactCard* contactCard = static_cast<CContactCard*>( iContactItem ); |
|
337 CContactIdArray* groups = contactCard->GroupsJoinedLC(); |
|
338 const TInt count = groups->Count(); |
|
339 for ( TInt i = 0; i < count; ++i ) |
|
340 { |
|
341 MVPbkContactLink* link = iParentStore.CreateLinkLC( (*groups)[i] ); |
|
342 result->AppendL( link ); |
|
343 CleanupStack::Pop(); // link |
|
344 } |
|
345 CleanupStack::PopAndDestroy( groups ); |
|
346 } |
|
347 |
|
348 return result; |
|
349 } |
|
350 |
|
351 TInt CContact::MaxNumberOfFieldL( const MVPbkFieldType& aType ) const |
|
352 { |
|
353 if ( iParentStore.StoreProperties().SupportedFields().ContainsSame(aType) ) |
|
354 { |
|
355 return KVPbkStoreContactUnlimitedNumber; |
|
356 } |
|
357 return 0; |
|
358 } |
|
359 |
|
360 MVPbkContactGroup* CContact::Group() |
|
361 { |
|
362 MVPbkContactGroup* result = NULL; |
|
363 |
|
364 if ( iContactItem->Type() == KUidContactGroup ) |
|
365 { |
|
366 result = this; |
|
367 } |
|
368 |
|
369 return result; |
|
370 } |
|
371 |
|
372 void CContact::SetGroupLabelL( const TDesC& aLabel ) |
|
373 { |
|
374 TVPbkFieldTypeMapping typeMapping; |
|
375 typeMapping.SetNonVersitType( EVPbkNonVersitTypeGenericLabel ); |
|
376 const MVPbkFieldType* labelType = |
|
377 typeMapping.FindMatch( iParentStore.MasterFieldTypeList() ); |
|
378 |
|
379 TInt labelFieldIndex = FindMatchingField( Fields(), |
|
380 labelType, |
|
381 iParentStore.MasterFieldTypeList() ); |
|
382 |
|
383 // Update the timestamp of the all contacts that belong to the group. |
|
384 // This is needed for synch service as it checks the timestamps of contacts |
|
385 // and get's the group information from the vCard of a contact. |
|
386 UpdateTimeStampOfAllContactsInGroupL(); |
|
387 |
|
388 if ( labelFieldIndex != KErrNotFound ) |
|
389 { |
|
390 // field already exists |
|
391 MVPbkStoreContactField& labelField = Fields().FieldAt( labelFieldIndex ); |
|
392 MVPbkContactFieldTextData::Cast( labelField.FieldData()).SetTextL(aLabel ); |
|
393 } |
|
394 else |
|
395 { |
|
396 // field does not exist => add it |
|
397 MVPbkStoreContactField* labelField = CreateFieldLC( *labelType ); |
|
398 MVPbkContactFieldTextData::Cast( labelField->FieldData() ).SetTextL( aLabel ); |
|
399 AddFieldL( labelField ); |
|
400 CleanupStack::Pop(); // labelField |
|
401 } |
|
402 } |
|
403 |
|
404 TPtrC CContact::GroupLabel() const |
|
405 { |
|
406 TVPbkFieldTypeMapping typeMapping; |
|
407 typeMapping.SetNonVersitType( EVPbkNonVersitTypeGenericLabel ); |
|
408 const MVPbkFieldType* labelType = |
|
409 typeMapping.FindMatch( iParentStore.MasterFieldTypeList() ); |
|
410 |
|
411 TInt labelFieldIndex = FindMatchingField( Fields(), |
|
412 labelType, |
|
413 iParentStore.MasterFieldTypeList() ); |
|
414 |
|
415 if ( labelFieldIndex != KErrNotFound ) |
|
416 { |
|
417 const MVPbkBaseContactField& labelField = Fields().FieldAt( labelFieldIndex ); |
|
418 return MVPbkContactFieldTextData::Cast(labelField.FieldData()).Text(); |
|
419 } |
|
420 else |
|
421 { |
|
422 return KNullDesC(); |
|
423 } |
|
424 } |
|
425 |
|
426 // -------------------------------------------------------------------------- |
|
427 // CContact::UpdateTimeStampOfAllContactsInGroupL |
|
428 // -------------------------------------------------------------------------- |
|
429 // |
|
430 void CContact::UpdateTimeStampOfAllContactsInGroupL( ) |
|
431 { |
|
432 MVPbkContactLinkArray* contactsInGroup = ItemsContainedLC(); |
|
433 |
|
434 // Loop through all contacts in the group and update time stamps |
|
435 for (TInt i=0; i < contactsInGroup->Count(); i++ ) |
|
436 { |
|
437 UpdateTimeStampOfContactInGroupL( contactsInGroup->At(i) ); |
|
438 } |
|
439 |
|
440 CleanupStack::PopAndDestroy(); // contactsInGroup |
|
441 } |
|
442 |
|
443 // -------------------------------------------------------------------------- |
|
444 // CContact::UpdateTimeStampOfContactInGroupL |
|
445 // -------------------------------------------------------------------------- |
|
446 // |
|
447 void CContact::UpdateTimeStampOfContactInGroupL(const MVPbkContactLink& aContactLink ) |
|
448 { |
|
449 const CContactLink& link = static_cast<const CContactLink&>( aContactLink ); |
|
450 |
|
451 // Store the id of currently processed contact in the group |
|
452 iLastUpdatedGroupContactId = link.ContactId(); |
|
453 |
|
454 // Try to open the contact for editing and then commit. |
|
455 // This will update the timestamp of the contact. |
|
456 // In case of a leave, we will make sure in the destructor that the |
|
457 // contact is unlocked (see CContact::~CContact). |
|
458 CContactItem* contact = |
|
459 iParentStore.NativeDatabase().OpenContactL( link.ContactId() ); |
|
460 CleanupStack::PushL(contact); |
|
461 |
|
462 iParentStore.NativeDatabase().CommitContactL(*contact); |
|
463 CleanupStack::PopAndDestroy(contact); |
|
464 |
|
465 // No need to store the id anymore. |
|
466 iLastUpdatedGroupContactId = KNullContactId; |
|
467 } |
|
468 |
|
469 void CContact::AddContactL( const MVPbkContactLink& aContactLink ) |
|
470 { |
|
471 // We have to maintain iAddedContacts ID array here because |
|
472 // the AddContactToGroup(id, id) method does not update |
|
473 // the native contact group we have in hand. It updates the |
|
474 // database only. So, in the ItemsContainedLC function |
|
475 // we have to know both the group members in the database |
|
476 // and the group members that have been added after this group |
|
477 // has been read from database |
|
478 const CContactLink& link = static_cast<const CContactLink&>( aContactLink ); |
|
479 |
|
480 // Read the contact so that |
|
481 // AddContactToGroupL(CContactItem &aItem, CContactItem &aGroup) |
|
482 // can be used. |
|
483 CContactItem* contact = |
|
484 iParentStore.NativeDatabase().ReadContactLC( link.ContactId() ); |
|
485 |
|
486 if ( !iAddedContacts ) |
|
487 { |
|
488 iAddedContacts = CContactIdArray::NewL(); |
|
489 } |
|
490 if ( iAddedContacts->Find( link.ContactId() ) == KErrNotFound ) |
|
491 { |
|
492 iAddedContacts->AddL( link.ContactId() ); |
|
493 } |
|
494 |
|
495 // Use AddContactToGroupL(CContactItem &aItem, CContactItem &aGroup) |
|
496 // instead of |
|
497 // AddContactToGroupL(TContactItemId aItemId, TContactItemId aGroupId) |
|
498 // because otherwise the member iContactItem won't be updated and commiting |
|
499 // it would loose the information about added contact |
|
500 TRAPD( err1, iParentStore.NativeDatabase().AddContactToGroupL( |
|
501 *contact, *iContactItem ) ); |
|
502 if ( err1 != KErrNone ) |
|
503 { |
|
504 iAddedContacts->Remove( iAddedContacts->Count() - 1 ); |
|
505 User::Leave( err1 ); |
|
506 } |
|
507 |
|
508 // Update the timestamp of the added contact. This is needed for |
|
509 // synch service as it checks the timestamps of contacts and get's the group |
|
510 // information from the vCard of a contact. |
|
511 TRAPD( err2, UpdateTimeStampOfContactInGroupL( aContactLink ) ); |
|
512 if ( err2 != KErrNone ) |
|
513 { |
|
514 iAddedContacts->Remove( iAddedContacts->Count() - 1 ); |
|
515 iParentStore.NativeDatabase().RemoveContactFromGroupL( |
|
516 *contact, *iContactItem ); |
|
517 User::Leave( err2 ); |
|
518 } |
|
519 CleanupStack::PopAndDestroy( contact ); |
|
520 } |
|
521 |
|
522 void CContact::RemoveContactL( const MVPbkContactLink& aContactLink ) |
|
523 { |
|
524 const CContactLink& link = static_cast<const CContactLink&>( aContactLink ); |
|
525 |
|
526 // Read the contact so that |
|
527 // RemoveContactFromGroupL(CContactItem &aItem, CContactItem &aGroup) |
|
528 // can be used. |
|
529 CContactItem* contact = |
|
530 iParentStore.NativeDatabase().ReadContactLC( link.ContactId() ); |
|
531 |
|
532 // First update the timestamp of the removed contact. This is needed for |
|
533 // synch service as it checks the timestamps of contacts and get's the group |
|
534 // information from the vCard of a contact. If updating fails this function |
|
535 // will leave and contact won't be removed from the group. |
|
536 UpdateTimeStampOfContactInGroupL(aContactLink); |
|
537 |
|
538 TInt index = KErrNotFound; |
|
539 if ( iAddedContacts ) |
|
540 { |
|
541 index = iAddedContacts->Find( link.ContactId() ); |
|
542 } |
|
543 |
|
544 // Use RemoveContactFromGroupL(CContactItem &aItem, CContactItem &aGroup) |
|
545 // instead of |
|
546 // RemoveContactFromGroupL(TContactItemId aItemId, TContactItemId aGroupId) |
|
547 // because otherwise the member iContactItem won't be updated and commiting |
|
548 // it would loose the information about removed contact |
|
549 iParentStore.NativeDatabase().RemoveContactFromGroupL( |
|
550 *contact, *iContactItem ); |
|
551 if ( index != KErrNotFound ) |
|
552 { |
|
553 iAddedContacts->Remove( index ); |
|
554 } |
|
555 CleanupStack::PopAndDestroy( contact ); |
|
556 } |
|
557 |
|
558 MVPbkContactLinkArray* CContact::ItemsContainedLC() const |
|
559 { |
|
560 CVPbkContactLinkArray* result = CVPbkContactLinkArray::NewLC(); |
|
561 TInt i; |
|
562 |
|
563 const CContactGroup* thisGroup = static_cast<const CContactGroup*>( iContactItem ); |
|
564 // 1. append the IDs found in the group |
|
565 const CContactIdArray* contacts = thisGroup->ItemsContained(); |
|
566 const TInt count = ( contacts ? contacts->Count() : 0 ); |
|
567 for ( i = 0; i < count; ++i ) |
|
568 { |
|
569 MVPbkContactLink* link = iParentStore.CreateLinkLC( (*contacts)[i] ); |
|
570 result->AppendL( link ); |
|
571 CleanupStack::Pop(); // link |
|
572 } |
|
573 // 2. append the IDs in iAddedContacts |
|
574 const TInt addedCount = ( iAddedContacts ? iAddedContacts->Count() : 0 ); |
|
575 for ( i = 0; i < addedCount; ++i ) |
|
576 { |
|
577 // add the contact if the iAddedContact[i] was not in contacts already |
|
578 if ( !contacts || |
|
579 contacts->Find( (*iAddedContacts)[i]) == KErrNotFound ) |
|
580 { |
|
581 MVPbkContactLink* link = iParentStore.CreateLinkLC( (*iAddedContacts)[i] ); |
|
582 result->AppendL( link ); |
|
583 CleanupStack::Pop(); // link |
|
584 } |
|
585 } |
|
586 return result; |
|
587 } |
|
588 |
|
589 TAny* CContact::StoreContactExtension(TUid aExtensionUid) |
|
590 { |
|
591 if( aExtensionUid == KMVPbkStoreContactExtension2Uid ) |
|
592 return static_cast<MVPbkStoreContact2*>( this ); |
|
593 return NULL; |
|
594 } |
|
595 |
|
596 MVPbkStoreContactProperties* CContact::PropertiesL() const |
|
597 { |
|
598 return CVPbkStoreContactProperties::NewL( *iContactItem, iParentStore.NativeDatabase() ); |
|
599 } |
|
600 |
|
601 void CContact::SetAsOwnL(MVPbkContactObserver& aObserver) const |
|
602 { |
|
603 iParentStore.SetAsOwnL( *this, aObserver ); |
|
604 } |
|
605 |
|
606 TAny* CContact::BaseContactExtension( TUid aExtensionUid ) |
|
607 { |
|
608 if( aExtensionUid == KVPbkBaseContactExtension2Uid ) |
|
609 return static_cast<MVPbkBaseContact2*>( this ); |
|
610 return NULL; |
|
611 } |
|
612 |
|
613 TBool CContact::IsOwnContact( TInt& aError ) const |
|
614 { |
|
615 aError = KErrNone; |
|
616 return ( iContactItem->Type() == KUidContactOwnCard ); |
|
617 } |
|
618 |
|
619 |
|
620 } // namespace VPbkCntModel |
|
621 |
|
622 // end of file |