|
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <s32std.h> |
|
17 #include <f32file.h> |
|
18 |
|
19 #include <cntdef.h> |
|
20 #include <cntitem.h> |
|
21 #include <cntfield.h> |
|
22 #include <cntfldst.h> |
|
23 #include <cntdb.h> |
|
24 |
|
25 #include "CNTSTD.H" |
|
26 #include "CNTPROF.H" |
|
27 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
28 #include "cntfieldheader.h" |
|
29 #endif |
|
30 |
|
31 |
|
32 EXPORT_C CContactItemFieldSet* CContactItemFieldSet::NewL() |
|
33 /** Allocates and constructs a new field set. |
|
34 |
|
35 @return Pointer to the newly created field set. */ |
|
36 { // static |
|
37 CContactItemFieldSet* self=CContactItemFieldSet::NewLC(); |
|
38 CleanupStack::Pop(); // self |
|
39 return self; |
|
40 } |
|
41 |
|
42 EXPORT_C CContactItemFieldSet* CContactItemFieldSet::NewLC() |
|
43 /** Allocates and constructs a new field set. |
|
44 |
|
45 @return Pointer to the newly created field set. This is left on the cleanup |
|
46 stack. */ |
|
47 { // static |
|
48 CContactItemFieldSet* self=new(ELeave) CContactItemFieldSet; |
|
49 CleanupStack::PushL(self); |
|
50 self->ConstructL(); |
|
51 return self; |
|
52 } |
|
53 |
|
54 EXPORT_C CContactItemFieldSet::~CContactItemFieldSet() |
|
55 /** The destructor frees all resources owned by the field set, prior to its destruction. */ |
|
56 { |
|
57 if (iFields) |
|
58 { |
|
59 iFields->ResetAndDestroy(); |
|
60 delete iFields; |
|
61 } |
|
62 } |
|
63 |
|
64 CContactItemFieldSet::CContactItemFieldSet() |
|
65 {} |
|
66 |
|
67 void CContactItemFieldSet::ConstructL() |
|
68 { |
|
69 iFields=new(ELeave) CArrayPtrFlat<CContactItemField>(4); |
|
70 } |
|
71 |
|
72 const CContactItemField* CContactItemFieldSet::FindById(TInt aId) const |
|
73 { |
|
74 const CContactItemField* field=NULL; |
|
75 for (TInt ii=0;ii<iFields->Count();ii++) |
|
76 { |
|
77 field=iFields->At(ii); |
|
78 if (field->Id()==aId) |
|
79 return(field); |
|
80 } |
|
81 return(NULL); |
|
82 } |
|
83 |
|
84 EXPORT_C TInt CContactItemFieldSet::FindNext(TFieldType aFieldType,TInt aStartPos) const |
|
85 /** Finds the next field in the field set with the specified field type. |
|
86 |
|
87 @param aFieldType The field type of interest. |
|
88 @param aStartPos The index within the field set array at which to start the |
|
89 search. By default set to KContactFieldSetSearchAll, to find the first field. |
|
90 Must be a valid array index, or the function raises a panic. |
|
91 @return If found, the index of the field within the field set, or KErrNotFound |
|
92 if not found. */ |
|
93 { |
|
94 return(FindNext(aFieldType,KUidContactFieldMatchAll,aStartPos)); |
|
95 } |
|
96 |
|
97 EXPORT_C TInt CContactItemFieldSet::FindNext(TFieldType aFieldType,TUid aMapping,TInt aStartPos) const |
|
98 /** Finds the next field in the field set containing both the content type mapping |
|
99 and the field type specified. |
|
100 |
|
101 @param aFieldType The field type of interest. |
|
102 @param aMapping The content type mapping of interest. |
|
103 @param aStartPos The index within the array at which to start the search. By |
|
104 default set to KContactFieldSetSearchAll, to find the first field. Must be |
|
105 a valid array index, or the function raises a panic. |
|
106 @return If found, the index of the field within the field set, or KErrNotFound |
|
107 if not found. */ |
|
108 { |
|
109 const TInt count=iFields->Count(); |
|
110 TInt pos=(aStartPos==KContactFieldSetSearchAll? 0 : aStartPos); |
|
111 TInt ii=KErrNotFound; |
|
112 for (ii=pos;ii<count;ii++) |
|
113 { |
|
114 const CContentType& contentType=(*iFields)[ii]->ContentType(); |
|
115 if (contentType.Mapping()==KUidContactFieldMatchAll || aMapping==KUidContactFieldMatchAll || contentType.Mapping()==aMapping) |
|
116 if (aFieldType==KUidContactFieldMatchAll || contentType.ContainsFieldType(aFieldType)) |
|
117 return ii; |
|
118 } |
|
119 return KErrNotFound; |
|
120 } |
|
121 |
|
122 void CContactItemFieldSet::SetFieldId(CContactItemField& aField) |
|
123 { |
|
124 TInt id=iFields->Count(); |
|
125 TInt count=iFields->Count(); |
|
126 FOREVER |
|
127 { |
|
128 TInt loop=0; |
|
129 for(;loop<count;loop++) |
|
130 if ((*iFields)[loop]->Id()==id) |
|
131 break; |
|
132 if (loop==count) |
|
133 { |
|
134 aField.SetId(id); |
|
135 break; |
|
136 } |
|
137 id++; |
|
138 } |
|
139 } |
|
140 |
|
141 EXPORT_C CContactItemFieldSet& CContactItemFieldSet::AddL(CContactItemField& aField) |
|
142 /** Appends a field to the field set. The field set takes ownership of the field. |
|
143 |
|
144 @param aField Reference to the field to add to the field set. The field's |
|
145 ID is updated. |
|
146 @return Reference to the current field set. */ |
|
147 { |
|
148 __ASSERT_DEBUG(&aField!=NULL,Panic(ECntPanicNullPointer)); |
|
149 SetFieldId(aField); |
|
150 iFields->AppendL(&aField); |
|
151 return (*this); |
|
152 } |
|
153 |
|
154 EXPORT_C void CContactItemFieldSet::Remove(TInt aIndex) |
|
155 /** Removes a field from the field set. |
|
156 |
|
157 @param aIndex The index of the field to delete. Must be a valid index within |
|
158 the field set or the function raises a panic. */ |
|
159 { |
|
160 delete (*iFields)[aIndex]; |
|
161 iFields->Delete(aIndex); |
|
162 } |
|
163 |
|
164 EXPORT_C void CContactItemFieldSet::Move(TInt aFrom, TInt aTo) |
|
165 /** Changes a field's position within the field set. |
|
166 |
|
167 Both indexes specified must be valid (i.e. between zero and Count()-1 inclusive), |
|
168 or the function raises a panic. |
|
169 |
|
170 @param aFrom The index of the field to move. |
|
171 @param aTo The index of the new position within the field set. */ |
|
172 { |
|
173 CContactItemField *moveField=(*iFields)[aFrom]; |
|
174 if (aFrom<aTo) |
|
175 { |
|
176 for(TInt loop=aFrom;loop<aTo;loop++) |
|
177 (*iFields)[loop]=(*iFields)[loop+1]; |
|
178 } |
|
179 else |
|
180 { |
|
181 for(TInt loop=aFrom;loop>aTo;loop--) |
|
182 (*iFields)[loop]=(*iFields)[loop-1]; |
|
183 } |
|
184 (*iFields)[aTo]=moveField; |
|
185 } |
|
186 |
|
187 EXPORT_C void CContactItemFieldSet::InsertL(TInt aIndex,CContactItemField& aField) |
|
188 /** Inserts a field into the field set. |
|
189 |
|
190 @param aIndex The position in the field set at which to insert the field. |
|
191 If equal to or greater than the number of elements in the field set, the field |
|
192 is appended to the field set. |
|
193 @param aField Reference to the field to add to the field set. The field's ID |
|
194 is updated. */ |
|
195 { |
|
196 __ASSERT_DEBUG(&aField!=NULL,Panic(ECntPanicNullPointer)); |
|
197 SetFieldId(aField); |
|
198 TInt count=iFields->Count(); |
|
199 if (count>aIndex) |
|
200 iFields->InsertL(aIndex,&aField); |
|
201 else |
|
202 iFields->AppendL(&aField); |
|
203 } |
|
204 |
|
205 /** |
|
206 |
|
207 Find and return the index of the best matched template field. The method uses a matching algorithm which compares the content type of the template fields with that of the incoming contact item. |
|
208 |
|
209 Matching Algorithm Steps: |
|
210 ======================== |
|
211 |
|
212 The algorithm is based on a scoring mechanism counting 'hits' and 'misses' in order to find the best possible field match within the fieldset of the template. |
|
213 |
|
214 1. Loop through all the contact item fields of the template. |
|
215 |
|
216 For each template field: |
|
217 |
|
218 2. Perform a strict, or exact, match between the vCard mappings of the template field and the field to be matched. |
|
219 3. If the vCard mappings match exactly, compare User Flags values and amend the overall score accordingly. |
|
220 4. Loop through all the field types (TFieldType array) stored as part of the content type of the field to be matched. |
|
221 |
|
222 For each field type of the field to be matched: |
|
223 |
|
224 5. Loop through the field types of the iterated template field to find a field type match. Amend the 'hits' and 'misses' count accordingly. |
|
225 6. Calculate the overall score weighing the 'hits' and 'misses' count. |
|
226 7. Amend the overall score count in order to account for special cases (e.g. user defined fields) |
|
227 8. Compare the overall score with the best score. If score > current best score, replace the 'bestScore' count and 'bestMatch' index. |
|
228 |
|
229 9. Return the 'bestMatch' field index of the template field. |
|
230 |
|
231 @param aContentType The content type of the field to find a match for. |
|
232 @param aUserFlags The user flags of the field to find a match for. |
|
233 @param aExactMatch Boolean to indicate an exact field match within the template. |
|
234 |
|
235 @return The index of the best matched template field, if found, else KErrNotFound. |
|
236 |
|
237 */ |
|
238 |
|
239 TInt CContactItemFieldSet::MatchTemplateField(const CContentType& aContentType,TUint aUserFlags,TBool &aExactMatch) const |
|
240 { |
|
241 const TInt count=Count(); |
|
242 TInt bestScore=5; // Has to be better than one or fail the match |
|
243 TInt bestMatch=KErrNotFound; |
|
244 TInt contentTypeCount=aContentType.FieldTypeCount(); |
|
245 |
|
246 // Loop through all the template fields to find the best field match |
|
247 for (TInt ii=0;ii<count;ii++) |
|
248 { |
|
249 const CContactItemField& field=*(*iFields)[ii]; |
|
250 const CContentType &fieldContentType=field.ContentType(); |
|
251 |
|
252 // Strict matching executed on the vCard mappings in order to avoid matching non-related fields e.g. Fax and Address fields. |
|
253 // NOTE: The vCard mappings are intended to match the vCard PROPERTY (e.g. TEL in TEL;HOME;FAX:01234), wherein the field is to be exported into a vCard. |
|
254 if (fieldContentType.Mapping()==aContentType.Mapping()) |
|
255 { |
|
256 TInt score=fieldContentType.Mapping()==KUidContactFieldVCardMapUnusedN?0:100; |
|
257 TInt hits=0; |
|
258 TInt misses=0; |
|
259 |
|
260 // The criteria for an exact match of the User Flags has been changed |
|
261 // from a mandatory requirement to a preference within the scoring system |
|
262 if (aUserFlags==0 || field.UserFlags()==aUserFlags) |
|
263 { |
|
264 ++score; |
|
265 } |
|
266 |
|
267 // NOTE: A common Field Types array stores BOTH the Field Type in addition to the Extra Mappings |
|
268 // |
|
269 // A. Field Type = Contact item field's type defined internally |
|
270 // B. Extra Mappings = Refer to the vCard PARAMETERS (e.g. FAX and HOME in TEL;HOME;FAX:01234) |
|
271 // |
|
272 // The Field Type and Extra Mappings are defined as part of the FIELD structure within the template (cntmodel.rss) |
|
273 // |
|
274 // C. Field Types array = A (Field Type, first element) + B (Extra Mappings, all elements after the first element) |
|
275 |
|
276 // Loop through the incoming contact item field's Field Types (C) |
|
277 for(TInt contactFieldTypeLoop=0; contactFieldTypeLoop < contentTypeCount; ++contactFieldTypeLoop) |
|
278 { |
|
279 // Match EACH of the incoming contact item field's Field Types (C) within the template field's Field Types (C) |
|
280 if(ContainsFieldTypeMapping(fieldContentType,aContentType.FieldType(contactFieldTypeLoop))) |
|
281 { |
|
282 ++hits; |
|
283 } |
|
284 else |
|
285 { |
|
286 ++misses; |
|
287 } |
|
288 } |
|
289 |
|
290 |
|
291 misses+=fieldContentType.FieldTypeCount()-hits; |
|
292 score+=10*hits-5*misses; |
|
293 |
|
294 if (!field.UserAddedField()) |
|
295 { |
|
296 score+=3; // Non-user added field takes priority over user added fields |
|
297 } |
|
298 |
|
299 if (fieldContentType.ContainsFieldType(KUidContactFieldVCardMapWORK)) |
|
300 { |
|
301 score+=1; // Work fields take priority over home fields |
|
302 } |
|
303 |
|
304 if (score>bestScore) |
|
305 { |
|
306 aExactMatch=(misses==0); |
|
307 bestScore=score; |
|
308 bestMatch=ii; |
|
309 } |
|
310 } |
|
311 } |
|
312 return bestMatch; |
|
313 } |
|
314 |
|
315 // Attempt to find a contact item field type within the Field Types array (Field Types array = Field Type (internal) + Extra Mappings) of the base contact item. |
|
316 // NOTE: This function does not include the base contact item field's vCard mapping whilst looking for the Field Type |
|
317 TBool CContactItemFieldSet::ContainsFieldTypeMapping(const CContentType& aBaseFieldContentType, const TFieldType& aContactFieldType) const |
|
318 { |
|
319 // Loop through all the template Field Types to attempt to match the individual Field Type of the incoming contact item's field |
|
320 for(TInt templateFieldTypeLoop=0; templateFieldTypeLoop < aBaseFieldContentType.FieldTypeCount(); ++templateFieldTypeLoop) |
|
321 { |
|
322 if(aBaseFieldContentType.FieldType(templateFieldTypeLoop) == aContactFieldType) |
|
323 { |
|
324 return ETrue; |
|
325 } |
|
326 } |
|
327 return EFalse; |
|
328 } |
|
329 |
|
330 /** |
|
331 @internalTechnology |
|
332 */ |
|
333 EXPORT_C TStreamId CContactItemFieldSet::StoreL(CStreamStore& aStore,const CContactItem* aTemplate,RWriteStream& aTextStream,CStreamStore& aBlobStore,CContactTables* aTables) |
|
334 { |
|
335 const TInt count=Count(); |
|
336 for (TInt ii=0;ii<count;ii++) |
|
337 { |
|
338 CContactItemField* field=(*iFields)[ii]; |
|
339 if (aTemplate) |
|
340 { |
|
341 const CContactItemFieldSet& templateFields = aTemplate->CardFields(); |
|
342 field->UpdateFieldFlags(templateFields); |
|
343 } |
|
344 else |
|
345 { |
|
346 field->SetLabelUnspecified(EFalse); |
|
347 } |
|
348 } |
|
349 return StoreL(aStore,aTextStream,aBlobStore,aTables); |
|
350 } |
|
351 |
|
352 EXPORT_C TStreamId CContactItemFieldSet::StoreL(CStreamStore& aStore,RWriteStream& aTextStream,CStreamStore& aBlobStore) |
|
353 /** Stores the field set to a stream store. |
|
354 @internalTechnology |
|
355 @param aStore Stream store to which the field set is written. |
|
356 @param aTextStream Stream to which data stored in text fields (with a storage |
|
357 type of KStorageTypeText) is written. |
|
358 @param aBlobStore Stream store to which data stored in non-text fields is written. |
|
359 @return The ID of the stream store. */ |
|
360 { |
|
361 //Overloaded to maintain SC. |
|
362 return (StoreL(aStore,aTextStream,aBlobStore,NULL)); |
|
363 } |
|
364 |
|
365 /* |
|
366 Store all contact fields in this field set into given header and data stores. |
|
367 |
|
368 In SQLite data schema, contact field data is saved in the stream store (aStore) as: |
|
369 |
|
370 contact-item-field-set = number-of-fields *field |
|
371 ; <field> repeated <number-of-fields> times |
|
372 |
|
373 field = contact-field-atts [ stream-id ] field-id template-id [ hint-value *mapping *additional-field ] [ label-length [ label ] ] |
|
374 ; 1st optional part is there if the contact field is NOT stored as text. |
|
375 ; if the field uses the template's content type, the 2nd optional part is left out |
|
376 ; <additional-field> is repeated a number of times as specified by <number-of-additional-fields> inside hint-value |
|
377 ; mapping is there if vcard-mapping-id-mask in hint-valute is set |
|
378 ; 3rd optional part is there if there is a label which overrides the template label. <label> is left out if <label-length> is zero |
|
379 |
|
380 contact-field-atts = attrib-store |
|
381 |
|
382 attrib-store = attribs field-type extended-attribs |
|
383 ; 32 bits -- order is endian-dependent |
|
384 |
|
385 attribs = 14BIT |
|
386 ; 14 bitfields: Hidden, ReadOnly, Synchronize, Disabled, |
|
387 ; 4 user-defined fields, OverRidesLabel, UsesTemplateData, |
|
388 ; UserAddedField, Template, LabelUnspecified and Deleted (in that order), |
|
389 |
|
390 field-type = 4BIT ; 0..16 |
|
391 extended-attribs = 8BIT |
|
392 ; 8 bitfields: Private, SpeedDial, EUserDefinedFilter and |
|
393 ; EUserDefinedFilter1-4(in that order) |
|
394 |
|
395 hint-value = vcard-mapping-id-mask *number-of-additional-fields *hint-value |
|
396 ; 32 bits -- order is endian-dependent |
|
397 ; hint-value and number-of-additional-fields is there if UsesTemplateData is NOT set in attribs |
|
398 vcard-mapping-id-mask= 1BIT |
|
399 number-of-additional-fields = 7BIT |
|
400 hint-value = 24BIT |
|
401 |
|
402 mapping = Int32 |
|
403 field-id =UInt32 |
|
404 template-id =UInt32 |
|
405 stream-id =UInt32 |
|
406 label-length = Int32 |
|
407 label = Descriptor |
|
408 |
|
409 @param aStore the stream store for data header |
|
410 @param aTextStream the stream to store text data |
|
411 @param aBlobStore the stream store for blob data |
|
412 |
|
413 @return stream id the data header stored in aStore. |
|
414 */ |
|
415 |
|
416 TStreamId CContactItemFieldSet::StoreL(CStreamStore& aStore, RWriteStream& aTextStream, CStreamStore& aBlobStore, CContactTables* /*aTables*/) |
|
417 { |
|
418 CArrayFix<TInt>* fullFields = new(ELeave) CArrayFixFlat<TInt>(4); |
|
419 CleanupStack::PushL(fullFields); // push here to make cleanup easier |
|
420 |
|
421 CArrayFix<TFieldHeader>* fieldHeader = new(ELeave) CArrayFixFlat<TFieldHeader>(5); |
|
422 CleanupStack::PushL(fieldHeader); |
|
423 |
|
424 TInt textFieldIndex = 0; |
|
425 |
|
426 const TInt KCount = Count(); |
|
427 for(TInt ii = 0; ii < KCount; ++ii) |
|
428 { |
|
429 // find all non-empty fields |
|
430 CContactItemField* field = (*iFields)[ii]; |
|
431 |
|
432 if (!field->IsDeleted()) |
|
433 { |
|
434 // only save non-empty content in the blob |
|
435 fullFields->AppendL(ii); // save for later |
|
436 |
|
437 //Add the text storage field data from the field to the blob |
|
438 fieldHeader->AppendL(field->StoreL(aTextStream, aBlobStore, textFieldIndex)); |
|
439 if (field->StorageType() == KStorageTypeText) |
|
440 { |
|
441 ++textFieldIndex; |
|
442 } |
|
443 } |
|
444 } |
|
445 |
|
446 // adjust the hint values for non-empty fields only |
|
447 RStoreWriteStream rootStream; |
|
448 TStreamId streamId = rootStream.CreateLC(aStore); |
|
449 |
|
450 const TInt KHintCount = fieldHeader->Count(); |
|
451 rootStream << TCardinality(KHintCount); |
|
452 |
|
453 for (TInt ii = 0; ii < KHintCount; ++ii) |
|
454 { |
|
455 CContactItemField* field=(*iFields)[(*fullFields)[ii]]; |
|
456 field->PopulateStoreL(rootStream, ii, *fieldHeader); |
|
457 } |
|
458 |
|
459 rootStream.CommitL(); |
|
460 aStore.CommitL(); |
|
461 |
|
462 CleanupStack::PopAndDestroy(3, fullFields); // rootStream, fieldHeader, fullFields |
|
463 return streamId; |
|
464 } |
|
465 |
|
466 HBufC* CContactItemFieldSet::LoadTextStreamLC(RReadStream& aStream) |
|
467 { |
|
468 TInt maxlen=0; |
|
469 if (aStream.Source()) |
|
470 maxlen=aStream.Source()->SizeL(); |
|
471 maxlen=maxlen/2; |
|
472 HBufC* textStream=HBufC::NewLC(maxlen); |
|
473 if (maxlen) |
|
474 { |
|
475 TPtr des=textStream->Des(); |
|
476 aStream.ReadL(des,maxlen); |
|
477 } |
|
478 return(textStream); |
|
479 } |
|
480 |
|
481 void CContactItemFieldSet::RestoreAndAddTemplateL(CStreamStore& aStore, TStreamId aId,CStreamStore* aBlobStore,const CContactItemViewDef& aViewDef, |
|
482 const CContactItem* aTemplate,RReadStream& aReadStream,CContactTables* aContactsTable,RArray<TInt>* aEmailIdArray) |
|
483 { |
|
484 if (aViewDef.Use()==CContactItemViewDef::EIncludeFields && aViewDef.Count()==0) |
|
485 return; // zzz temp kludge, fix this properly |
|
486 if (aTemplate) |
|
487 { |
|
488 CContactItemFieldSet *original=CContactItemFieldSet::NewLC(); |
|
489 original->RestoreL(aStore,aId,aBlobStore,aViewDef,aTemplate,aReadStream,aContactsTable,aEmailIdArray); |
|
490 TInt count=original->Count(); |
|
491 for(TInt loop=0;loop<count;loop++) |
|
492 { |
|
493 CContactItemField* additionalField=CContactItemField::NewLC((*original)[loop]); |
|
494 AddL(*additionalField); |
|
495 CleanupStack::Pop(); // additionalField |
|
496 } |
|
497 CleanupStack::PopAndDestroy(); // original |
|
498 } |
|
499 else |
|
500 RestoreL(aStore,aId,aBlobStore,aViewDef,NULL,aReadStream,aContactsTable,aEmailIdArray); |
|
501 } |
|
502 |
|
503 /** |
|
504 Restores the field set using a view definition. |
|
505 @internalTechnology |
|
506 @param aStore Store from which to restore the field set. |
|
507 @param anId The root stream ID of aStore. |
|
508 @param aBlobStore If specified, the stream store from which data stored in |
|
509 non-text fields is read. |
|
510 @param aViewDef The view definition to use. |
|
511 @param aReadStream Read stream from which data stored in text fields (with |
|
512 a storage type of KStorageTypeText) is read. |
|
513 */ |
|
514 EXPORT_C void CContactItemFieldSet::RestoreL(CStreamStore& aStore, TStreamId anId,CStreamStore* aBlobStore,const CContactItemViewDef& aViewDef,RReadStream& aReadStream) |
|
515 { |
|
516 //THIS FUNCTION IS TO BE REMOVED.... |
|
517 RestoreL(aStore,anId,aBlobStore,aViewDef,NULL,aReadStream,NULL,NULL); |
|
518 } |
|
519 |
|
520 |
|
521 void CContactItemFieldSet::RestoreL(CStreamStore& aStore, TStreamId anId, CStreamStore* aBlobStore,const CContactItemViewDef& aViewDef,const CContactItem* aTemplate,RReadStream& aReadStream,CContactTables* /*aContactsTable*/, RArray<TInt>* /*aEmailIdArray*/) |
|
522 // Overloaded looks in the Contacts Table for cetain fields. |
|
523 { |
|
524 const TBool includeFields=aViewDef.Use()==CContactItemViewDef::EIncludeFields; |
|
525 if (includeFields && aViewDef.Count()==0) |
|
526 return; |
|
527 RStoreReadStream stream; |
|
528 stream.OpenLC(aStore,anId); |
|
529 TCardinality fieldCount; |
|
530 stream>>fieldCount; |
|
531 TStreamId nestedId; |
|
532 TInt textFieldIndex=0; |
|
533 HBufC *textStream=CContactItemFieldSet::LoadTextStreamLC(aReadStream); |
|
534 |
|
535 for (TInt ii=0; ii<fieldCount; ++ii) |
|
536 { |
|
537 CContactItemField* field=CContactItemField::NewLC(); |
|
538 nestedId=field->RestoreFieldTypesL(stream,aTemplate?&(aTemplate->CardFields()):NULL); |
|
539 const CContentType &type=field->ContentType(); |
|
540 TBool fieldDefined=aViewDef.MatchesAll() || (aViewDef.Find(type)!=KErrNotFound); |
|
541 if (!((fieldDefined&&includeFields) || (!fieldDefined&&!includeFields)) || |
|
542 (field->IsHidden() && aViewDef.Mode()==CContactItemViewDef::EMaskHiddenFields) |
|
543 ) |
|
544 { |
|
545 if (field->StorageType()==KStorageTypeText) |
|
546 textFieldIndex++; |
|
547 CleanupStack::PopAndDestroy(); // field |
|
548 } |
|
549 else |
|
550 { |
|
551 if (field->StorageType()==KStorageTypeText) // restore from text stream |
|
552 { |
|
553 // restore text from contacts table. |
|
554 TPtrC textPtr; |
|
555 if(textPtr.Length()) |
|
556 { |
|
557 field->TextStorage()->SetTextL(textPtr); |
|
558 } |
|
559 else |
|
560 { |
|
561 field->RestoreTextL(textStream,textFieldIndex); |
|
562 } |
|
563 iFields->AppendL(field); |
|
564 CleanupStack::Pop(); // field |
|
565 textFieldIndex++; |
|
566 } |
|
567 else if (aBlobStore) |
|
568 { |
|
569 field->RestoreDataL(*aBlobStore, nestedId); |
|
570 iFields->AppendL(field); |
|
571 CleanupStack::Pop(); // field |
|
572 } |
|
573 else |
|
574 { |
|
575 CleanupStack::PopAndDestroy(); // field |
|
576 } |
|
577 } |
|
578 } |
|
579 CleanupStack::PopAndDestroy(2); // textStream,stream |
|
580 } |
|
581 |
|
582 /** |
|
583 The overload that doesn't use dangerous CContactItemFieldSet::LoadTextStreamLC(aReadStream) method. |
|
584 LoadTextStreamLC relies on the stream to know its size, but now all types of streams support this functionality. |
|
585 In order to avoid calling LoadTextStreamLC, aTextBuf is already loaded in HBufC in the caller function. |
|
586 The caller function had access to the table and can use ColLength() API to get the lebgth of the field. |
|
587 @internalTechnology |
|
588 */ |
|
589 EXPORT_C void CContactItemFieldSet::RestoreL(CStreamStore& aStore, TStreamId anId, CStreamStore* aBlobStore,const CContactItemViewDef& aViewDef,const CContactItem* aTemplate,HBufC* aTextBuf) |
|
590 { |
|
591 const TBool includeFields=aViewDef.Use()==CContactItemViewDef::EIncludeFields; |
|
592 if (includeFields && aViewDef.Count()==0) |
|
593 return; |
|
594 RStoreReadStream stream; |
|
595 stream.OpenLC(aStore,anId); |
|
596 TCardinality fieldCount; |
|
597 stream>>fieldCount; |
|
598 TStreamId nestedId; |
|
599 TInt textFieldIndex=0; |
|
600 |
|
601 for (TInt ii=0;ii<fieldCount;ii++) |
|
602 { |
|
603 CContactItemField* field=CContactItemField::NewLC(); |
|
604 nestedId=field->RestoreFieldTypesL(stream,aTemplate?&(aTemplate->CardFields()):NULL); |
|
605 const CContentType &type=field->ContentType(); |
|
606 TBool fieldDefined=aViewDef.MatchesAll() || (aViewDef.Find(type)!=KErrNotFound); |
|
607 if (!((fieldDefined&&includeFields) || (!fieldDefined&&!includeFields)) || |
|
608 (field->IsHidden() && aViewDef.Mode()==CContactItemViewDef::EMaskHiddenFields) |
|
609 ) |
|
610 { |
|
611 if (field->StorageType()==KStorageTypeText) |
|
612 textFieldIndex++; |
|
613 CleanupStack::PopAndDestroy(field); |
|
614 } |
|
615 else |
|
616 { |
|
617 if (field->StorageType()==KStorageTypeText) // restore from text stream |
|
618 { |
|
619 // restore text from contacts table. |
|
620 TPtrC textPtr; |
|
621 if(textPtr.Length()) |
|
622 { |
|
623 field->TextStorage()->SetTextL(textPtr); |
|
624 } |
|
625 else |
|
626 { |
|
627 field->RestoreTextL(aTextBuf,textFieldIndex); |
|
628 } |
|
629 |
|
630 if (aTemplate) |
|
631 { |
|
632 AddL(*field); |
|
633 } |
|
634 else |
|
635 { |
|
636 iFields->AppendL(field); |
|
637 } |
|
638 |
|
639 CleanupStack::Pop(field); |
|
640 textFieldIndex++; |
|
641 } |
|
642 else if (aBlobStore) |
|
643 { |
|
644 field->RestoreDataL(*aBlobStore, nestedId); |
|
645 |
|
646 if (aTemplate) |
|
647 { |
|
648 AddL(*field); |
|
649 } |
|
650 else |
|
651 { |
|
652 iFields->AppendL(field); |
|
653 } |
|
654 |
|
655 CleanupStack::Pop(field); |
|
656 } |
|
657 else |
|
658 { |
|
659 CleanupStack::PopAndDestroy(field); |
|
660 } |
|
661 } |
|
662 } |
|
663 CleanupStack::PopAndDestroy(&stream); |
|
664 } |
|
665 |
|
666 |
|
667 |
|
668 EXPORT_C void CContactItemFieldSet::UpdateFieldL(const CContactItemField &aField, TInt aMatchCount) |
|
669 /** Updates a field in the field set. The field whose content type matches aField's |
|
670 content type is replaced by aField. The second parameter is used to identify |
|
671 which matching field is updated. Specify 1 to update the first matching field, |
|
672 2 for the second and so on. If there is no field in the field set which matches |
|
673 aField's content type, then aField is appended to the field set. |
|
674 |
|
675 @param aField The new field information. |
|
676 @param aMatchCount Identifies which matching field in the field set should |
|
677 be updated. */ |
|
678 { |
|
679 const CContentType &newContentType=aField.ContentType(); |
|
680 TInt fieldPos=0; |
|
681 for(;fieldPos<iFields->Count();fieldPos++) |
|
682 { |
|
683 if (newContentType==(*iFields)[fieldPos]->ContentType()) |
|
684 { |
|
685 --aMatchCount; |
|
686 if (aMatchCount==0) |
|
687 { |
|
688 Remove(fieldPos); |
|
689 break; |
|
690 } |
|
691 } |
|
692 } |
|
693 if (aField.Storage()->IsFull()) |
|
694 { |
|
695 CContactItemField* field=CContactItemField::NewLC(aField); |
|
696 InsertL(fieldPos,*field); |
|
697 CleanupStack::Pop(); // field |
|
698 } |
|
699 } |
|
700 |
|
701 |
|
702 EXPORT_C void CContactItemFieldSet::UpdateFieldSyncL(const CContactItemField& aField, TInt aMatchCount) |
|
703 /** |
|
704 * Updates a field in the field set. |
|
705 * Searches the set for a matching field. Deletes the matching set's field if any. |
|
706 * Adds the aField to the set anyway. |
|
707 * Uses the IsEqualForSyncUpdate() function to compare two CContentType objects, |
|
708 * rather than the default equals operator. |
|
709 * Takes care to hold the PREF, VoiceDial, and SpeedDial properties in the updated field. |
|
710 * |
|
711 * @param aField Specifies both the type of the field to update and the updated field's value. |
|
712 * @param aMatchCount Gives the offset of the matching field to update in the order of the set |
|
713 * (i.e. 1, means update the first matching field in the set; |
|
714 * 2, means update the second matching field in the set). |
|
715 */ |
|
716 { |
|
717 TBool mustAddFieldTypePREF=EFalse; |
|
718 TBool mustAddFieldTypeVoiceDial=EFalse; |
|
719 TUid voiceDialUid=KNullUid; |
|
720 |
|
721 const CContentType& newContentType=aField.ContentType(); |
|
722 TInt fieldPos=0; |
|
723 for(;fieldPos<iFields->Count();fieldPos++) |
|
724 { |
|
725 if ((*iFields)[fieldPos]->ContentType().IsEqualForSyncUpdate(newContentType)) |
|
726 { |
|
727 --aMatchCount; |
|
728 if (aMatchCount==0) |
|
729 { |
|
730 const CContentType& contentType=(*iFields)[fieldPos]->ContentType(); |
|
731 |
|
732 if (contentType.Mapping().iUid==KIntContactFieldVCardMapTEL) |
|
733 { |
|
734 for(TInt loop=0;loop<contentType.FieldTypeCount();loop++) |
|
735 { |
|
736 if (contentType.FieldType(loop).iUid>=KUidSpeedDialOneValue && contentType.FieldType(loop).iUid<=KUidSpeedDialNineValue) |
|
737 { |
|
738 voiceDialUid.iUid=contentType.FieldType(loop).iUid; |
|
739 break; //only one speed dial property allowed for a field |
|
740 } |
|
741 } |
|
742 |
|
743 if (contentType.ContainsFieldType(KUidContactsVoiceDialField)) |
|
744 { |
|
745 mustAddFieldTypeVoiceDial=ETrue; |
|
746 } |
|
747 } |
|
748 |
|
749 if (contentType.ContainsFieldType(KUidContactFieldVCardMapPREF) && !newContentType.ContainsFieldType(KUidContactFieldVCardMapPREF)) |
|
750 { |
|
751 mustAddFieldTypePREF=ETrue; |
|
752 } |
|
753 break; |
|
754 } |
|
755 } |
|
756 } |
|
757 if (aField.Storage()->IsFull()) |
|
758 { |
|
759 if( fieldPos<iFields->Count() ) |
|
760 { |
|
761 Remove(fieldPos);//if updating with full field, then remove old field first |
|
762 } |
|
763 CContactItemField* field=CContactItemField::NewLC(aField); |
|
764 if (mustAddFieldTypePREF) |
|
765 { |
|
766 field->AddFieldTypeL(KUidContactFieldVCardMapPREF); |
|
767 } |
|
768 |
|
769 if (mustAddFieldTypeVoiceDial) |
|
770 { |
|
771 field->AddFieldTypeL(KUidContactsVoiceDialField); |
|
772 } |
|
773 |
|
774 if (voiceDialUid!=KNullUid) |
|
775 { |
|
776 field->AddFieldTypeL(voiceDialUid); |
|
777 } |
|
778 |
|
779 InsertL(fieldPos,*field); |
|
780 CleanupStack::Pop(field); |
|
781 } |
|
782 else if( fieldPos < iFields->Count() ) |
|
783 { |
|
784 (*iFields)[fieldPos]->ResetStore();//if updating with empty field, just reset the field |
|
785 } |
|
786 } |
|
787 |
|
788 |
|
789 |
|
790 TInt CContactItemFieldSet::FieldText(TFieldType aFieldType, TDes &aText, TInt aStartPosition) const |
|
791 { |
|
792 TInt fieldPos=FindNext(aFieldType, aStartPosition); |
|
793 if (fieldPos!=KErrNotFound) |
|
794 (*iFields)[fieldPos]->GetFieldText(aText); |
|
795 return fieldPos; |
|
796 } |
|
797 |
|
798 /** Get the first non-empty text field*/ |
|
799 void CContactItemFieldSet::NonZeroFieldText(TFieldType aFieldType, TDes &aText) const |
|
800 { |
|
801 TInt fieldPos=-1; |
|
802 do |
|
803 { |
|
804 fieldPos=FindNext(aFieldType,fieldPos+1); |
|
805 if (fieldPos==KErrNotFound) |
|
806 break; |
|
807 (*iFields)[fieldPos]->GetFieldText(aText); |
|
808 } while(aText.Length()==0); |
|
809 } |
|
810 |
|
811 |
|
812 /** |
|
813 Part of the system template update implementation. |
|
814 This could be used for a generic update method at a later stage. |
|
815 @since 7.0 |
|
816 @internalTechnology |
|
817 */ |
|
818 CArrayFix<TFieldHeader>* CContactItemFieldSet::ConstructFieldHeaderArrayLC(RWriteStream& aTextStream, CStreamStore& aBlobStore) |
|
819 { |
|
820 CArrayFix<TFieldHeader>* retval = new(ELeave) CArrayFixFlat<TFieldHeader>(5); |
|
821 CleanupStack::PushL(retval); |
|
822 CContactItemField* field = NULL; |
|
823 TPtrC textPointer; |
|
824 HBufC* buffer = NULL; |
|
825 TInt counter = 0; |
|
826 TInt maxFields = 0; |
|
827 TInt textFieldIndex = 0; |
|
828 |
|
829 maxFields = Count(); |
|
830 for (counter=0;counter < maxFields; counter++) |
|
831 { |
|
832 field = (*iFields)[counter]; |
|
833 if (!field->IsDeleted() ) |
|
834 { |
|
835 if (field->StorageType()==KStorageTypeText) |
|
836 { |
|
837 textPointer.Set(field->TextStorage()->Text()); |
|
838 buffer = textPointer.AllocLC(); |
|
839 } // if |
|
840 |
|
841 retval->AppendL(field->StoreL(aTextStream,aBlobStore,textFieldIndex)); |
|
842 |
|
843 if (buffer && buffer->Length() > 0 ) |
|
844 { |
|
845 field->TextStorage()->SetTextL(*buffer); |
|
846 } |
|
847 |
|
848 if (buffer) |
|
849 { |
|
850 CleanupStack::PopAndDestroy(buffer); |
|
851 buffer = NULL; |
|
852 } |
|
853 |
|
854 if (field->StorageType()==KStorageTypeText) |
|
855 { |
|
856 textFieldIndex++; |
|
857 } |
|
858 }//if |
|
859 } // for |
|
860 |
|
861 return retval; |
|
862 } |
|
863 |
|
864 |
|
865 |
|
866 /* |
|
867 * Iterate through the fields. |
|
868 * If the current field matches the field we are inserting from the template |
|
869 * return the position of the match. |
|
870 * |
|
871 * @param aSystemTemplateFields System template fieldset |
|
872 * @param aStartIndex Field to start from |
|
873 * @param aField Template field |
|
874 * @return KErrNotFound, if no field matching the template field in the fieldset, |
|
875 * else returns position of match in fieldset |
|
876 */ |
|
877 |
|
878 TInt CContactItemFieldSet::FieldTypeCount(const CContactItemFieldSet& aSystemTemplateFields, TInt aStartIndex, const CContactItemField& aField) const |
|
879 { |
|
880 const TInt fieldSetCount = Count(); |
|
881 for (TInt ii=aStartIndex;ii<fieldSetCount;ii++) |
|
882 { |
|
883 const CContactItemField& field=*((*iFields)[ii]); |
|
884 TInt tfId = field.TemplateFieldId(); |
|
885 if(tfId==KNullFieldId) |
|
886 { |
|
887 if (field.ContentType()==aField.ContentType()) |
|
888 return(ii); |
|
889 } |
|
890 else |
|
891 { |
|
892 const CContactItemField* sysField=aSystemTemplateFields.FindById(tfId); |
|
893 if (sysField->ContentType()==aField.ContentType()) |
|
894 return(ii); |
|
895 } |
|
896 } |
|
897 return KErrNotFound; |
|
898 } |
|
899 |
|
900 void CContactItemFieldSet::InternalizeL(RReadStream& aStream) |
|
901 /** Internalises a CContactItemFieldSet object from a read stream. |
|
902 @param aStream Stream from which the object should be internalised. */ |
|
903 { |
|
904 TInt fieldCount = aStream.ReadInt32L(); // Number of fields. |
|
905 |
|
906 for(TInt index=0; index<fieldCount; ++index) |
|
907 { |
|
908 CContactItemField* currentField = CContactItemField::NewLC(); |
|
909 currentField->InternalizeL(aStream); |
|
910 iFields->AppendL(currentField); |
|
911 CleanupStack::Pop(currentField); |
|
912 } |
|
913 |
|
914 } |
|
915 |
|
916 void CContactItemFieldSet::ExternalizeL(RWriteStream& aStream) const |
|
917 /** Externalises a CContactItemFieldSet object to a write stream. |
|
918 @param aStream Stream to which the object should be externalised. */ |
|
919 { |
|
920 TInt fieldCount = Count(); // Number of fields. |
|
921 aStream.WriteInt32L(fieldCount); |
|
922 for(TInt index=0; index<fieldCount; ++index) |
|
923 { |
|
924 (*iFields)[index]->ExternalizeL(aStream); |
|
925 |
|
926 } |
|
927 } |
|
928 |
|
929 |
|
930 /* |
|
931 * Constructor. |
|
932 * This is marked as private because CContactItem is an abstract base class. |
|
933 */ |
|
934 CContactItem::CContactItem() |
|
935 { |
|
936 } |
|
937 |
|
938 /** Constructs a new contact item based on a RReadStream. |
|
939 @param aStream RReadStream containing object to internalize. |
|
940 @return Pointer to the newly created CContactItem. This is left on the cleanup stack. |
|
941 @internalTechnology |
|
942 */ |
|
943 CContactItem* CContactItem::NewLC(RReadStream& aStream) |
|
944 { // static |
|
945 TUid ContactItemType; |
|
946 ContactItemType.iUid = aStream.ReadInt32L(); |
|
947 |
|
948 CContactItem* item = NewLC(ContactItemType); |
|
949 item->InternalizeL(aStream); |
|
950 |
|
951 return item; |
|
952 } |
|
953 |
|
954 /** Constructs a new contact item. |
|
955 |
|
956 @return Pointer to the newly created CContactItem. This is left on the cleanup stack. |
|
957 @internalTechnology |
|
958 */ |
|
959 EXPORT_C CContactItem* CContactItem::NewLC(TUid aType) |
|
960 { // static |
|
961 CContactItem* item=NULL; |
|
962 |
|
963 switch(aType.iUid) |
|
964 { |
|
965 case KUidContactCardValue: |
|
966 item = CContactCard::NewLC(); |
|
967 break; |
|
968 |
|
969 case KUidContactGroupValue: |
|
970 item = CContactGroup::NewLC(); |
|
971 break; |
|
972 |
|
973 case KUidContactOwnCardValue: |
|
974 item = CContactOwnCard::NewLC(); |
|
975 break; |
|
976 |
|
977 case KUidContactICCEntryValue: |
|
978 item=CContactICCEntry::NewL(); |
|
979 CleanupStack::PushL(item); |
|
980 break; |
|
981 |
|
982 case KUidContactTemplateValue: |
|
983 item = CContactTemplate::NewLC(); |
|
984 break; |
|
985 |
|
986 case KUidContactCardTemplateValue: |
|
987 item = CContactCardTemplate::NewLC(); |
|
988 break; |
|
989 |
|
990 default: |
|
991 User::Leave(KErrNotSupported); |
|
992 break; |
|
993 |
|
994 } |
|
995 |
|
996 return item; |
|
997 } |
|
998 |
|
999 /* |
|
1000 * Second-phase construction. |
|
1001 * Set template ID on which this contact item is based as KNullContactId. |
|
1002 */ |
|
1003 void CContactItem::ConstructL() |
|
1004 { |
|
1005 iFieldSet=CContactItemFieldSet::NewL(); |
|
1006 SetTemplateRefId(KNullContactId); |
|
1007 } |
|
1008 |
|
1009 /* |
|
1010 * Second-phase construction overload. |
|
1011 */ |
|
1012 void CContactItem::ConstructL(const CContactItem* aTemplate) |
|
1013 { |
|
1014 ConstructL(); |
|
1015 |
|
1016 const TUid type = Type(); |
|
1017 if (type==KUidContactCardTemplate || type==KUidContactOwnCard || type==KUidContactGroup) |
|
1018 { |
|
1019 SetTemplateRefId(KNullContactId); |
|
1020 } |
|
1021 else if (aTemplate->TemplateRefId()==KNullContactId) // can only be template |
|
1022 {//record the contacts template |
|
1023 SetTemplateRefId(aTemplate->Id()); |
|
1024 } |
|
1025 |
|
1026 const CContactItemFieldSet& fieldSet=aTemplate->CardFields(); |
|
1027 const TInt fieldCount = fieldSet.Count(); |
|
1028 for(TInt loop=0;loop<fieldCount;loop++) |
|
1029 { |
|
1030 const CContactItemField& templateField=fieldSet[loop]; |
|
1031 if (!templateField.IsTemplateLabelField()) |
|
1032 { |
|
1033 CContactItemField* field=CContactItemField::NewLC(templateField); |
|
1034 AddFieldL(*field); |
|
1035 CleanupStack::Pop(field); |
|
1036 field->CopyStorageL(templateField); |
|
1037 } |
|
1038 } |
|
1039 } |
|
1040 |
|
1041 EXPORT_C CContactItem::~CContactItem() |
|
1042 /** The destructor frees all resources owned by the contact item, prior to its |
|
1043 destruction. */ |
|
1044 { |
|
1045 delete iFieldSet; |
|
1046 delete iGuid; |
|
1047 } |
|
1048 |
|
1049 EXPORT_C TContactItemId CContactItem::Id() const |
|
1050 /** Gets the contact item's ID. |
|
1051 |
|
1052 @return The contact item's ID. */ |
|
1053 { |
|
1054 return iId; |
|
1055 } |
|
1056 |
|
1057 /** |
|
1058 Sets the contact item's ID. |
|
1059 |
|
1060 @internalTechnology |
|
1061 @released |
|
1062 */ |
|
1063 EXPORT_C void CContactItem::SetId(TContactItemId aId) |
|
1064 { |
|
1065 iId = aId; |
|
1066 } |
|
1067 |
|
1068 /** |
|
1069 Returns the contact item's attributes. |
|
1070 |
|
1071 @return contact item's attributes |
|
1072 |
|
1073 @internalTechnology |
|
1074 @released |
|
1075 */ |
|
1076 EXPORT_C TUint32 CContactItem::Attributes() const |
|
1077 { |
|
1078 return iAttributes; |
|
1079 } |
|
1080 |
|
1081 /** |
|
1082 Sest the contact item's attributes. |
|
1083 |
|
1084 @internalTechnology |
|
1085 @released |
|
1086 */ |
|
1087 EXPORT_C void CContactItem::SetAttributes(TUint32 aAttributes) |
|
1088 { |
|
1089 iAttributes = aAttributes; |
|
1090 } |
|
1091 |
|
1092 /** |
|
1093 Sest the contact item's access count. |
|
1094 |
|
1095 @internalTechnology |
|
1096 @released |
|
1097 */ |
|
1098 EXPORT_C void CContactItem::SetAccessCount(TUint32 aAccessCount) |
|
1099 { |
|
1100 iAccessCount = aAccessCount; |
|
1101 } |
|
1102 |
|
1103 /** |
|
1104 Sest the contact item's creation time. |
|
1105 |
|
1106 @internalTechnology |
|
1107 @released |
|
1108 */ |
|
1109 EXPORT_C void CContactItem::SetCreationDate(const TTime& aTime) |
|
1110 { |
|
1111 iCreationDate = aTime.Int64(); |
|
1112 } |
|
1113 |
|
1114 EXPORT_C TContactItemId CContactItem::TemplateRefId() const |
|
1115 /** Gets the ID of the template which was used to create this contact item. |
|
1116 |
|
1117 @return The ID of the template on which this item is based. KNullContactId |
|
1118 if the item is not based on a template. */ |
|
1119 { |
|
1120 return iTemplateRefId; |
|
1121 } |
|
1122 |
|
1123 EXPORT_C TTime CContactItem::LastModified() const |
|
1124 /** Gets the contact item's last modified date/time. |
|
1125 |
|
1126 @return The contact item's last modified date/time. */ |
|
1127 { |
|
1128 return iLastModified; |
|
1129 } |
|
1130 |
|
1131 EXPORT_C void CContactItem::SetLastModified(const TTime& aLastModified) |
|
1132 /** Sets the last modified date/time value stored in the local copy of the contact |
|
1133 item. This value is returned by LastModified() for this copy of the item. |
|
1134 |
|
1135 This function has no effect on the item's last modified date/time which is |
|
1136 stored in the database; this is always the date/time the contact was last |
|
1137 committed. |
|
1138 |
|
1139 This function is provided for use when synchronising |
|
1140 contact items. |
|
1141 |
|
1142 @param aLastModified The contact item's last modified date/time. */ |
|
1143 { |
|
1144 iLastModified=aLastModified.Int64(); |
|
1145 } |
|
1146 |
|
1147 EXPORT_C void CContactItem::SetHidden(TBool aHidden) |
|
1148 /** Sets the contact item's hidden attribute. Hidden means that the item is not |
|
1149 displayed if the view definition excludes hidden fields. |
|
1150 |
|
1151 @param aHidden ETrue to set the hidden attribute for the item, EFalse to unset |
|
1152 it. */ |
|
1153 { |
|
1154 if (aHidden) |
|
1155 iAttributes|=EHidden; |
|
1156 else |
|
1157 iAttributes&=~EHidden; |
|
1158 } |
|
1159 EXPORT_C void CContactItem::SetSystem(TBool aSystem) |
|
1160 /** Sets the contact item's system attribute. Note that the system attribute is |
|
1161 not currently used in the contacts model. |
|
1162 |
|
1163 @param aSystem ETrue to set the system attribute, EFalse to unset it. */ |
|
1164 { |
|
1165 if (aSystem) |
|
1166 iAttributes|=ESystem; |
|
1167 else |
|
1168 iAttributes&=~ESystem; |
|
1169 } |
|
1170 |
|
1171 EXPORT_C void CContactItem::SetDeleted(TBool aDeleted) |
|
1172 /** Sets the value of the contact item's Is deleted attribute. |
|
1173 |
|
1174 If the attribute is set, this means that an attempt has been made to delete |
|
1175 the contact item, but because the item's access count is greater than zero, |
|
1176 its data persists and the item is just marked as deleted. |
|
1177 |
|
1178 @param aDeleted ETrue to set the Is deleted attribute. EFalse to unset it. */ |
|
1179 { |
|
1180 if (aDeleted) |
|
1181 iAttributes|=EDeleted; |
|
1182 else |
|
1183 iAttributes&=~EDeleted; |
|
1184 } |
|
1185 |
|
1186 EXPORT_C TBool CContactItem::IsHidden() |
|
1187 /** Gets the value of the contact item's hidden attribute. Hidden means that the |
|
1188 item is not displayed if the view definition excludes hidden fields. |
|
1189 |
|
1190 @return ETrue if hidden, EFalse if not. */ |
|
1191 { return iAttributes&EHidden; } |
|
1192 |
|
1193 EXPORT_C TBool CContactItem::IsSystem() |
|
1194 /** Gets the value of the contact item's system attribute. Note that the system |
|
1195 attribute is not currently used in the contacts model. |
|
1196 |
|
1197 @return ETrue if system, EFalse if not. */ |
|
1198 { return iAttributes&ESystem; } |
|
1199 |
|
1200 EXPORT_C TBool CContactItem::IsDeleted() const |
|
1201 /** Gets the value of the Is deleted attribute as set by SetDeleted(). |
|
1202 |
|
1203 @return ETrue if deleted, EFalse if not. */ |
|
1204 { return iAttributes&EDeleted; } |
|
1205 |
|
1206 EXPORT_C void CContactItem::SetTemplateRefId(TContactItemId aUid) |
|
1207 /** Sets the ID of the template on which this contact item is based. |
|
1208 |
|
1209 @param aUid The ID of the template on which this item is based. */ |
|
1210 { |
|
1211 iTemplateRefId=aUid; |
|
1212 } |
|
1213 |
|
1214 EXPORT_C void CContactItem::AddFieldL(CContactItemField& aField) |
|
1215 /** Appends a field to the contact item's field set. The contact item takes ownership |
|
1216 of the field. |
|
1217 |
|
1218 @param aField The field to append to the contact item's field set. */ |
|
1219 { |
|
1220 __ASSERT_DEBUG(&aField!=NULL,Panic(ECntPanicNullPointer)); |
|
1221 if (this->Type()==KUidContactCardTemplate) |
|
1222 aField.SetTemplateField(ETrue); |
|
1223 else |
|
1224 aField.SetTemplateField(EFalse); |
|
1225 iFieldSet->AddL(aField); |
|
1226 } |
|
1227 |
|
1228 EXPORT_C void CContactItem::RemoveField(TInt aFieldPos) |
|
1229 /** Removes a field from the contact item's field set. A panic occurs if the specified |
|
1230 field does not exist in the field set. |
|
1231 |
|
1232 @param aFieldPos Index within the field set of the field to remove. */ |
|
1233 { |
|
1234 if (!(*iFieldSet)[aFieldPos].IsTemplateLabelField()) |
|
1235 iFieldSet->Remove(aFieldPos); |
|
1236 } |
|
1237 |
|
1238 EXPORT_C void CContactItem::InsertFieldL(CContactItemField& aField,TInt aFieldPos) |
|
1239 /** Inserts a field into the contact item's field set. The contact item takes ownership |
|
1240 of the field. |
|
1241 |
|
1242 @param aField The field to insert into the contact item's field set. |
|
1243 @param aFieldPos The position in the field set at which to insert the field. |
|
1244 If this value is greater than the total number of fields, it is appended. |
|
1245 The position is relative to zero, i.e. zero implies that the element is inserted |
|
1246 at the beginning of the array. */ |
|
1247 { |
|
1248 if (this->Type()==KUidContactCardTemplate) |
|
1249 aField.SetTemplateField(ETrue); |
|
1250 iFieldSet->InsertL(aFieldPos,aField); |
|
1251 } |
|
1252 |
|
1253 EXPORT_C void CContactItem::UpdateFieldSet(CContactItemFieldSet* aNewFieldSet) |
|
1254 /** Replaces the contact item's field set. |
|
1255 |
|
1256 @param aNewFieldSet The new field set with which to replace the existing one. */ |
|
1257 { |
|
1258 delete iFieldSet; |
|
1259 iFieldSet = NULL; |
|
1260 iFieldSet=aNewFieldSet; |
|
1261 } |
|
1262 |
|
1263 TContactItemId CContactItem::Agent() |
|
1264 { |
|
1265 TContactItemId fieldindex=iFieldSet->FindNext(KUidContactFieldMatchAll,KUidContactFieldVCardMapAGENT); |
|
1266 if (fieldindex!=KErrNotFound) |
|
1267 return(TContactItemId( |
|
1268 (*iFieldSet)[fieldindex].AgentStorage()->Value())); |
|
1269 else |
|
1270 return KNullContactId; |
|
1271 } |
|
1272 |
|
1273 EXPORT_C CContactItemFieldSet& CContactItem::CardFields() const |
|
1274 /** Gets a reference to the contact item's field set. |
|
1275 |
|
1276 @return A reference to the contact item's field set. */ |
|
1277 { |
|
1278 return *iFieldSet; |
|
1279 } |
|
1280 |
|
1281 |
|
1282 EXPORT_C void CContactItem::SetUidStringL(TDesC& aString) |
|
1283 /** Sets the item's UID string. This replaces any existing string. Contact items have |
|
1284 a globally unique identifier, stored as a descriptor which is provided for |
|
1285 vCard support. It is a combination of the database's unique identifier (see |
|
1286 CContactDatabase::MachineId()), the contact item ID and the date/time of the |
|
1287 contact item's creation. |
|
1288 |
|
1289 @param aString The contact item's UID string. */ |
|
1290 { |
|
1291 HBufC* guid=aString.AllocL(); |
|
1292 if (iGuid) |
|
1293 delete iGuid; |
|
1294 iGuid=guid; |
|
1295 } |
|
1296 |
|
1297 EXPORT_C TPtrC CContactItem::UidStringL(TInt64 aMachineUniqueId) const |
|
1298 /** Returns a descriptor which contains the item's UID string. Contact items have |
|
1299 a globally unique identifier, stored as a descriptor. This is provided for |
|
1300 vCard support. It is a combination of the database's unique identifier, the |
|
1301 contact item ID and the date/time of the contact item's creation. |
|
1302 |
|
1303 @param aMachineUniqueId The database's unique identifier. This can be retrieved |
|
1304 using CContactDatabase::MachineId(). |
|
1305 @return The item's UID string. */ |
|
1306 { |
|
1307 TPtrC guid; |
|
1308 if (iGuid) |
|
1309 { |
|
1310 if (GuidIsCompressed()) |
|
1311 CONST_CAST(CContactItem &,*this).MakeUidStringL(aMachineUniqueId); |
|
1312 guid.Set(*iGuid); |
|
1313 } |
|
1314 return guid; |
|
1315 } |
|
1316 |
|
1317 void CContactItem::MakeUidStringL(TInt64 aMachineUniqueId) |
|
1318 { |
|
1319 HBufC* guid = NULL; |
|
1320 if (iGuid->Length()) |
|
1321 guid=ContactGuid::CreateGuidLC(iGuid->Des(),iId,aMachineUniqueId); // pass creation time |
|
1322 else |
|
1323 guid=ContactGuid::CreateGuidLC(iId, aMachineUniqueId); |
|
1324 delete iGuid; |
|
1325 iGuid=guid; |
|
1326 iAttributes&=~(ECompressedGuid); |
|
1327 CleanupStack::Pop(); // iGuid |
|
1328 } |
|
1329 |
|
1330 /** |
|
1331 @internalTechnology |
|
1332 */ |
|
1333 EXPORT_C void CContactItem::SetHasCompressedGuid(TBool aCompressed) |
|
1334 { |
|
1335 if (aCompressed) |
|
1336 iAttributes|=ECompressedGuid; |
|
1337 else |
|
1338 iAttributes&=~(ECompressedGuid); |
|
1339 } |
|
1340 |
|
1341 |
|
1342 TBool CContactItem::GuidIsCompressed() const |
|
1343 {return iAttributes&ECompressedGuid;} |
|
1344 |
|
1345 |
|
1346 |
|
1347 /** |
|
1348 Part of the system template update implementation. |
|
1349 This could be used for a generic update method at a later stage. |
|
1350 @since 7.0 |
|
1351 @internalTechnology |
|
1352 */ |
|
1353 TInt CContactItem::NumberOfFieldsToStore() const |
|
1354 { |
|
1355 TInt retval = 0, counter = 0; |
|
1356 const TInt max = iFieldSet->Count(); |
|
1357 for (counter = 0; counter < max; counter++) |
|
1358 { |
|
1359 if ( ! (*iFieldSet)[counter].IsDeleted() ) retval++; |
|
1360 } |
|
1361 return retval; |
|
1362 } |
|
1363 |
|
1364 /** |
|
1365 Part of the system template update implementation. |
|
1366 This could be used for a generic update method at a later stage. |
|
1367 @since 7.0 |
|
1368 @internalTechnology |
|
1369 */ |
|
1370 TStreamId CContactItem::PopulateStoreL(CStreamStore& aStore, CArrayFix<TFieldHeader>& aFieldHeaderArray) const |
|
1371 { |
|
1372 RStoreWriteStream rootStream; |
|
1373 TInt counter = 0; |
|
1374 TStreamId streamId = rootStream.CreateLC(aStore); |
|
1375 const TInt hintCount = aFieldHeaderArray.Count(); |
|
1376 |
|
1377 rootStream <<TCardinality(NumberOfFieldsToStore()); |
|
1378 |
|
1379 for (counter = 0;counter < hintCount; counter++) |
|
1380 { |
|
1381 (*iFieldSet)[counter].PopulateStoreL(rootStream, counter, aFieldHeaderArray); |
|
1382 } |
|
1383 rootStream.CommitL(); |
|
1384 aStore.CommitL(); |
|
1385 CleanupStack::PopAndDestroy(&rootStream); |
|
1386 return streamId; |
|
1387 } |
|
1388 |
|
1389 |
|
1390 void CContactItem::AddLabelFieldL() |
|
1391 { |
|
1392 TInt pos = iFieldSet->Find(KUidContactFieldTemplateLabel); |
|
1393 if (pos==KErrNotFound) // !HasItemLabelField() |
|
1394 { |
|
1395 CContactItemField* labelField = CContactItemField::NewLC(KStorageTypeText); |
|
1396 labelField->AddFieldTypeL(KUidContactFieldTemplateLabel); |
|
1397 if (Type()==KUidContactGroup) |
|
1398 { |
|
1399 _LIT(KGroupLabel,"Group Label"); |
|
1400 labelField->SetLabelL(KGroupLabel); |
|
1401 } |
|
1402 else if (Type()==KUidContactCardTemplate) |
|
1403 { |
|
1404 _LIT(KTemplateLabel,"Template Label"); |
|
1405 labelField->SetLabelL(KTemplateLabel); |
|
1406 } |
|
1407 // field needs to be first in the list |
|
1408 // bug in stream retrieval of fields |
|
1409 InsertFieldL(*labelField,0); |
|
1410 CleanupStack::Pop(); // labelField |
|
1411 } |
|
1412 else if (pos!=0) |
|
1413 { |
|
1414 iFieldSet->Move(pos,0); |
|
1415 } |
|
1416 } |
|
1417 |
|
1418 |
|
1419 /** |
|
1420 Restore fields from the template to the contact item. |
|
1421 @param aTemplateFields Fields to add |
|
1422 @param aViewDef View definition to use |
|
1423 @internalTechnology |
|
1424 */ |
|
1425 EXPORT_C void CContactItem::RestoreTemplateFieldsL(const CContactItemFieldSet& aSystemTemplateFields, const CContactItemFieldSet& aTemplateFields, const CContactItemViewDef& aViewDef) |
|
1426 { |
|
1427 TInt insertPos=0; |
|
1428 const TInt templateFieldCount=aTemplateFields.Count(); |
|
1429 for (TInt ii=0;ii<templateFieldCount;ii++) |
|
1430 { |
|
1431 const CContactItemField& templateField=aTemplateFields[ii]; |
|
1432 TInt fieldPos=iFieldSet->FieldTypeCount(aSystemTemplateFields, insertPos, templateField); |
|
1433 if (fieldPos<0 && ((aViewDef.Mode()==CContactItemViewDef::EMaskHiddenFields && !templateField.IsHidden()) |
|
1434 || (aViewDef.Mode()==CContactItemViewDef::EIncludeHiddenFields)) |
|
1435 && (!templateField.ContentType().ContainsFieldType(KUidContactFieldTemplateLabel))) |
|
1436 { |
|
1437 CContactItemField* field = CContactItemField::NewLC(templateField); |
|
1438 field->SetTemplateField(EFalse); //make sure it isn't set as a template field |
|
1439 field->SetOverRidesLabel(EFalse); |
|
1440 iFieldSet->InsertL(insertPos++,*field); |
|
1441 CleanupStack::Pop(field); |
|
1442 } |
|
1443 else |
|
1444 { |
|
1445 while(fieldPos>=0) |
|
1446 { |
|
1447 iFieldSet->Move(fieldPos,insertPos++); //move the field to the correct position |
|
1448 fieldPos=iFieldSet->FieldTypeCount(aSystemTemplateFields, insertPos, templateField); |
|
1449 } |
|
1450 } |
|
1451 } |
|
1452 } |
|
1453 |
|
1454 |
|
1455 |
|
1456 void CContactItem::ClearFieldContent() |
|
1457 { |
|
1458 for (TInt i=0;i<iFieldSet->Count();i++) |
|
1459 { |
|
1460 CContactItemField& field=(*iFieldSet)[i]; |
|
1461 if (!field.IsTemplateLabelField()) |
|
1462 field.ResetStore(); |
|
1463 } |
|
1464 } |
|
1465 |
|
1466 void CContactItem::InternalizeL(RReadStream& aStream) |
|
1467 /** Internalises a CContactItem object from a read stream. |
|
1468 @param aStream Stream from which the object should be internalised. */ |
|
1469 { |
|
1470 |
|
1471 delete iFieldSet; |
|
1472 iFieldSet = NULL; |
|
1473 iFieldSet=CContactItemFieldSet::NewL(); |
|
1474 iFieldSet->InternalizeL(aStream); |
|
1475 |
|
1476 iAttributes = aStream.ReadUint32L(); |
|
1477 |
|
1478 iId = aStream.ReadInt32L(); |
|
1479 |
|
1480 iTemplateRefId = aStream.ReadInt32L(); |
|
1481 |
|
1482 TInt64 tempInt64; |
|
1483 aStream >> tempInt64; |
|
1484 iLastModified = TTime(tempInt64); |
|
1485 |
|
1486 aStream >> tempInt64; |
|
1487 iCreationDate = TTime(tempInt64); |
|
1488 |
|
1489 iAccessCount = aStream.ReadUint32L(); |
|
1490 |
|
1491 if (iGuid) |
|
1492 { |
|
1493 delete iGuid; |
|
1494 iGuid = NULL; |
|
1495 } |
|
1496 |
|
1497 const TInt length=aStream.ReadInt32L(); |
|
1498 if (length) |
|
1499 { |
|
1500 iGuid=HBufC::NewL(aStream,length); |
|
1501 } |
|
1502 |
|
1503 } |
|
1504 |
|
1505 void CContactItem::ExternalizeL(RWriteStream& aStream) const |
|
1506 /** Externalises a CContactItem object to a write stream. |
|
1507 @param aStream Stream to which the object should be externalised. */ |
|
1508 { |
|
1509 aStream.WriteInt32L(Type().iUid); |
|
1510 |
|
1511 iFieldSet->ExternalizeL(aStream); |
|
1512 |
|
1513 aStream.WriteUint32L(iAttributes); |
|
1514 |
|
1515 aStream.WriteInt32L(iId); |
|
1516 |
|
1517 aStream.WriteInt32L(iTemplateRefId); |
|
1518 |
|
1519 aStream << iLastModified.Int64(); |
|
1520 |
|
1521 aStream << iCreationDate.Int64(); |
|
1522 |
|
1523 aStream.WriteUint32L(iAccessCount); |
|
1524 |
|
1525 if(iGuid) |
|
1526 { |
|
1527 |
|
1528 const TInt length=iGuid->Length(); |
|
1529 aStream.WriteInt32L(length); |
|
1530 if (length) |
|
1531 { |
|
1532 aStream << *(iGuid); |
|
1533 } |
|
1534 } |
|
1535 else |
|
1536 { |
|
1537 aStream.WriteInt32L(0); |
|
1538 } |
|
1539 |
|
1540 } |
|
1541 |
|
1542 |
|
1543 // |
|
1544 // class CContactCardTemplate |
|
1545 // |
|
1546 |
|
1547 EXPORT_C CContactCardTemplate* CContactCardTemplate::NewL() |
|
1548 { // static |
|
1549 /** Allocates and constructs a new Contact Card Template . |
|
1550 @return Pointer to the newly created Contact Card Template. */ |
|
1551 CContactCardTemplate* card=CContactCardTemplate::NewLC(); |
|
1552 CleanupStack::Pop(); // card |
|
1553 return card; |
|
1554 } |
|
1555 |
|
1556 EXPORT_C CContactCardTemplate* CContactCardTemplate::NewLC() |
|
1557 { // static |
|
1558 /** Allocates and constructs a new Contact Card Template . |
|
1559 @return Pointer to the newly created Contact Card Template. This is left on the cleanup stack. */ |
|
1560 CContactCardTemplate* card=new(ELeave) CContactCardTemplate; |
|
1561 CleanupStack::PushL(card); |
|
1562 card->ConstructL(); |
|
1563 return card; |
|
1564 } |
|
1565 |
|
1566 EXPORT_C CContactCardTemplate* CContactCardTemplate::NewL(const CContactItem *aTemplate) |
|
1567 { |
|
1568 /** Allocates and constructs a new Contact Card Template . |
|
1569 @param aTemplate Pointer to the template whose field set and field data are copied into the new contact card template |
|
1570 @return Pointer to the newly created Contact Card Template. */ |
|
1571 |
|
1572 CContactCardTemplate* card=CContactCardTemplate::NewLC(aTemplate); |
|
1573 CleanupStack::Pop(); // card |
|
1574 return card; |
|
1575 } |
|
1576 |
|
1577 EXPORT_C CContactCardTemplate* CContactCardTemplate::NewLC(const CContactItem *aTemplate) |
|
1578 { // static |
|
1579 /** Allocates and constructs a new Contact Card Template . |
|
1580 @param aTemplate Pointer to the template whose field set and field data are copied into the new contact card template |
|
1581 @return Pointer to the newly created Contact Card Template. This is left on the cleanup stack. */ |
|
1582 |
|
1583 CContactCardTemplate* card=new(ELeave) CContactCardTemplate; |
|
1584 CleanupStack::PushL(card); |
|
1585 card->ConstructL(aTemplate); |
|
1586 return card; |
|
1587 } |
|
1588 |
|
1589 EXPORT_C void CContactCardTemplate::SetTemplateLabelL(const TDesC& aLabel) |
|
1590 /** Changes the label for a contact card template. The label is initialised when |
|
1591 the template is created. The template label is stored in a text field in the |
|
1592 template. This field has a unique content type mapping of KUidContactFieldTemplateLabel. |
|
1593 By default, this field is the first field in the field set; it must not be |
|
1594 moved from this position. |
|
1595 |
|
1596 @param aLabel The new template label. |
|
1597 @leave KErrNotFound Indicates there is no template label field in the template. */ |
|
1598 { |
|
1599 CContactItemFieldSet& labelFields = this->CardFields(); |
|
1600 // find label field |
|
1601 TInt pos = labelFields.Find(KUidContactFieldTemplateLabel); |
|
1602 if (pos==KErrNotFound) |
|
1603 User::Leave(pos); |
|
1604 labelFields[pos].TextStorage()->SetTextL(aLabel); |
|
1605 } |
|
1606 |
|
1607 EXPORT_C TPtrC CContactCardTemplate::GetTemplateLabelL() |
|
1608 /** Gets the label for a contact card template. |
|
1609 |
|
1610 @leave KErrNotFound Indicates there is no template label field in the template. |
|
1611 |
|
1612 @return The template label. */ |
|
1613 { |
|
1614 CContactItemFieldSet& labelFields = this->CardFields(); |
|
1615 // find |
|
1616 TInt pos = labelFields.Find(KUidContactFieldTemplateLabel); |
|
1617 if (pos==KErrNotFound) |
|
1618 User::Leave(pos); |
|
1619 return(labelFields[pos].TextStorage()->Text()); |
|
1620 } |
|
1621 |
|
1622 EXPORT_C TBool CContactCardTemplate::HasItemLabelField() |
|
1623 { |
|
1624 /** Tests whether a Template label field is present. |
|
1625 @return ETrue if Template Label Field is present, EFalse otherwise. */ |
|
1626 CContactItemFieldSet& labelFields = this->CardFields(); |
|
1627 TInt pos = labelFields.Find(KUidContactFieldTemplateLabel); |
|
1628 if (pos==KErrNotFound) |
|
1629 return EFalse; |
|
1630 return ETrue; |
|
1631 } |
|
1632 |
|
1633 EXPORT_C TUid CContactCardTemplate::Type() const |
|
1634 { |
|
1635 return KUidContactCardTemplate; |
|
1636 } |
|
1637 |
|
1638 CContactCardTemplate::CContactCardTemplate() |
|
1639 { |
|
1640 } |
|
1641 |
|
1642 // |
|
1643 // CContactItemPlusGroup |
|
1644 // |
|
1645 |
|
1646 /** |
|
1647 @internalComponent |
|
1648 */ |
|
1649 CContactItemPlusGroup::CContactItemPlusGroup() |
|
1650 {} |
|
1651 |
|
1652 EXPORT_C CContactItemPlusGroup::~CContactItemPlusGroup() |
|
1653 /** |
|
1654 Frees the array of group IDs to which the derived class object |
|
1655 belongs. |
|
1656 Frees the array of contact item IDs which identify the groups to |
|
1657 which the derived class object belongs, prior to its destruction. */ |
|
1658 |
|
1659 { |
|
1660 delete iGroups; |
|
1661 } |
|
1662 |
|
1663 EXPORT_C const CContactIdArray* CContactItemPlusGroup::GroupsJoined() const |
|
1664 /** Returns a pointer to a list of contact item IDs which identify the groups to |
|
1665 which the derived class object belongs. |
|
1666 |
|
1667 @return A pointer to the array of groups IDs to which the derived class object |
|
1668 belongs. NULL if the object is not a member of any groups. */ |
|
1669 { |
|
1670 return(iGroups); |
|
1671 } |
|
1672 |
|
1673 EXPORT_C CContactIdArray* CContactItemPlusGroup::GroupsJoinedLC() const |
|
1674 /** Returns a pointer to a list of contact item IDs which identify the groups to |
|
1675 which the derived class object belongs. |
|
1676 |
|
1677 @return A pointer to a copy of the array of groups IDs to which the derived |
|
1678 class object belongs. This array is empty if the object is not a member of |
|
1679 any groups. The caller takes ownership of this object, so is responsible for |
|
1680 its deletion. */ |
|
1681 { |
|
1682 CContactIdArray* copy=NULL; |
|
1683 if (iGroups) |
|
1684 copy=CContactIdArray::NewLC(iGroups); |
|
1685 else |
|
1686 copy=CContactIdArray::NewLC(); |
|
1687 return copy; |
|
1688 } |
|
1689 |
|
1690 void CContactItemPlusGroup::InternalizeL(RReadStream& aStream) |
|
1691 /** Internalises a CContactItemPlusGroup object from a read stream. |
|
1692 @param aStream Stream from which the object should be internalised. */ |
|
1693 { |
|
1694 // Call Parent InternalizeL to internalize all members. |
|
1695 CContactItem::InternalizeL(aStream); |
|
1696 |
|
1697 if (iGroups) |
|
1698 { |
|
1699 delete iGroups; |
|
1700 iGroups = NULL; |
|
1701 } |
|
1702 |
|
1703 // TBool CheckIfExists = aStream.ReadInt32L(); |
|
1704 if (aStream.ReadInt32L()) |
|
1705 { |
|
1706 iGroups = CContactIdArray::NewL(); |
|
1707 iGroups->InternalizeL(aStream); |
|
1708 } |
|
1709 |
|
1710 } |
|
1711 |
|
1712 void CContactItemPlusGroup::ExternalizeL(RWriteStream& aStream) const |
|
1713 /** Externalises a CContactItemPlusGroup object to a write stream. |
|
1714 @param aStream Stream to which the object should be externalised. */ |
|
1715 { |
|
1716 // Call Parent ExternalizeL to externalize all members. |
|
1717 CContactItem::ExternalizeL(aStream); |
|
1718 if(iGroups) |
|
1719 { |
|
1720 aStream.WriteInt32L(1); |
|
1721 iGroups->ExternalizeL(aStream); |
|
1722 } |
|
1723 else |
|
1724 { |
|
1725 aStream.WriteInt32L(0); // Empty group |
|
1726 } |
|
1727 |
|
1728 } |
|
1729 |
|
1730 /** |
|
1731 Resets groups. |
|
1732 |
|
1733 @internalTechnology |
|
1734 @released |
|
1735 */ |
|
1736 EXPORT_C void CContactItemPlusGroup::ResetGroups() |
|
1737 { |
|
1738 delete iGroups; |
|
1739 iGroups = NULL; |
|
1740 } |
|
1741 |
|
1742 /** |
|
1743 Sets groups. |
|
1744 |
|
1745 @internalTechnology |
|
1746 @released |
|
1747 */ |
|
1748 EXPORT_C void CContactItemPlusGroup::SetGroups(CContactIdArray* aGroups) |
|
1749 { |
|
1750 iGroups = aGroups; |
|
1751 } |
|
1752 |
|
1753 // |
|
1754 // class CContactCard |
|
1755 // |
|
1756 |
|
1757 EXPORT_C CContactCard::~CContactCard() |
|
1758 /** Frees all resources owned by the contact card, prior to its |
|
1759 destruction. */ |
|
1760 { |
|
1761 } |
|
1762 |
|
1763 EXPORT_C CContactCard* CContactCard::NewL() |
|
1764 /** Allocates and constructs a new contact card. |
|
1765 |
|
1766 @return Pointer to the newly created contact card. */ |
|
1767 { // static |
|
1768 CContactCard* card=CContactCard::NewLC(); |
|
1769 CleanupStack::Pop(); // card |
|
1770 return card; |
|
1771 } |
|
1772 |
|
1773 EXPORT_C CContactCard* CContactCard::NewLC() |
|
1774 /** Allocates and constructs a new contact card. |
|
1775 |
|
1776 @return Pointer to the newly created contact card. This is left on the |
|
1777 cleanup stack.*/ |
|
1778 { // static |
|
1779 CContactCard* card=new(ELeave) CContactCard; |
|
1780 CleanupStack::PushL(card); |
|
1781 card->ConstructL(); |
|
1782 return card; |
|
1783 } |
|
1784 |
|
1785 EXPORT_C CContactCard* CContactCard::NewL(const CContactItem *aTemplate) |
|
1786 /** Allocates and constructs a new contact card whose field set is seeded from |
|
1787 a template. |
|
1788 |
|
1789 @param aTemplate Pointer to the template whose field set and field data are |
|
1790 copied into the new contact card. |
|
1791 @return Pointer to the newly created contact card. */ |
|
1792 { |
|
1793 CContactCard* card=CContactCard::NewLC(aTemplate); |
|
1794 CleanupStack::Pop(); // card |
|
1795 return card; |
|
1796 } |
|
1797 |
|
1798 EXPORT_C CContactCard* CContactCard::NewLC(const CContactItem *aTemplate) |
|
1799 /** Allocates and constructs a new contact card whose field set is seeded from |
|
1800 a template. |
|
1801 |
|
1802 @param aTemplate Pointer to the template whose field set and field data are |
|
1803 copied into the new contact card. |
|
1804 @return Pointer to the newly created contact card. This is left on the cleanup stack. */ |
|
1805 { // static |
|
1806 CContactCard* card=new(ELeave) CContactCard; |
|
1807 CleanupStack::PushL(card); |
|
1808 card->ConstructL(aTemplate); |
|
1809 return card; |
|
1810 } |
|
1811 |
|
1812 EXPORT_C TUid CContactCard::Type() const |
|
1813 /** Implements CContactItem::Type(). |
|
1814 |
|
1815 @return KUidContactCard. */ |
|
1816 { |
|
1817 return KUidContactCard; |
|
1818 } |
|
1819 |
|
1820 EXPORT_C CContactIdArray* CContactCard::GroupsJoinedLC() const |
|
1821 /** Returns a pointer to a list of contact item IDs which identify the groups to |
|
1822 which this contact card belongs. |
|
1823 |
|
1824 @return A pointer to a copy of the array of groups IDs to which this contact |
|
1825 card belongs. This array is empty if the card is not a member of any groups. |
|
1826 The caller takes ownership of this object, so is responsible for its deletion. */ |
|
1827 { |
|
1828 return(CContactItemPlusGroup::GroupsJoinedLC()); |
|
1829 } |
|
1830 |
|
1831 CContactCard::CContactCard() |
|
1832 { |
|
1833 } |
|
1834 |
|
1835 // |
|
1836 // class CContactOwnCard |
|
1837 // |
|
1838 |
|
1839 EXPORT_C CContactOwnCard::~CContactOwnCard() |
|
1840 /** Frees all resources owned by the own card, prior to its destruction. */ |
|
1841 { |
|
1842 } |
|
1843 |
|
1844 EXPORT_C CContactOwnCard* CContactOwnCard::NewL() |
|
1845 /** Allocates and constructs a new own card. |
|
1846 |
|
1847 Note: own cards should normally be constructed using the factory functions provided |
|
1848 in class CContactDatabase, for example CreateOwnCardL(). |
|
1849 |
|
1850 @return Pointer to the newly created own card. */ |
|
1851 { // static |
|
1852 CContactOwnCard* card=CContactOwnCard::NewLC(); |
|
1853 CleanupStack::Pop(); // card |
|
1854 return card; |
|
1855 } |
|
1856 |
|
1857 EXPORT_C CContactOwnCard* CContactOwnCard::NewLC() |
|
1858 /** Allocates and constructs a new own card. |
|
1859 |
|
1860 Note: own cards should normally be constructed using the factory functions provided |
|
1861 in class CContactDatabase, for example CreateOwnCardL(). |
|
1862 |
|
1863 @return Pointer to the newly created own card. This is left on the cleanup stack. */ |
|
1864 { // static |
|
1865 CContactOwnCard* card=new(ELeave) CContactOwnCard; |
|
1866 CleanupStack::PushL(card); |
|
1867 card->ConstructL(); |
|
1868 return card; |
|
1869 } |
|
1870 |
|
1871 EXPORT_C CContactOwnCard* CContactOwnCard::NewL(const CContactItem *aTemplate) |
|
1872 /** Allocates and constructs a new own card whose field set is seeded from a template. |
|
1873 |
|
1874 Note: own cards should normally be constructed using the factory functions provided |
|
1875 in class CContactDatabase, for example CreateOwnCardL(). |
|
1876 |
|
1877 @param aTemplate Pointer to the template whose field set and field data are |
|
1878 copied into the new own card. |
|
1879 @return Pointer to the newly created own card. */ |
|
1880 { |
|
1881 CContactOwnCard* card=CContactOwnCard::NewLC(aTemplate); |
|
1882 CleanupStack::Pop(); // card |
|
1883 return card; |
|
1884 } |
|
1885 |
|
1886 EXPORT_C CContactOwnCard* CContactOwnCard::NewLC(const CContactItem *aTemplate) |
|
1887 /** Allocates and constructs a new own card whose field set is seeded from a template. |
|
1888 |
|
1889 Note: own cards should normally be constructed using the factory functions provided |
|
1890 in class CContactDatabase, for example CreateOwnCardL(). |
|
1891 |
|
1892 @param aTemplate Pointer to the template whose field set and field data are |
|
1893 copied into the new own card. |
|
1894 @return Pointer to the newly created own card. This is left on the cleanup stack. */ |
|
1895 { // static |
|
1896 CContactOwnCard* card=new(ELeave) CContactOwnCard; |
|
1897 CleanupStack::PushL(card); |
|
1898 card->ConstructL(aTemplate); |
|
1899 return card; |
|
1900 } |
|
1901 |
|
1902 EXPORT_C TUid CContactOwnCard::Type() const |
|
1903 /** Implements CContactItem::Type(). |
|
1904 |
|
1905 @return KUidContactOwnCard. */ |
|
1906 { |
|
1907 return KUidContactOwnCard; |
|
1908 } |
|
1909 |
|
1910 EXPORT_C CContactIdArray* CContactOwnCard::GroupsJoinedLC() const |
|
1911 /** Returns a pointer to a list of contact item IDs which identify the groups to |
|
1912 which the current own card belongs. |
|
1913 |
|
1914 @return A pointer to a copy of the array of groups IDs to which this own card |
|
1915 belongs. This array is empty if the own card is not a member of any groups. |
|
1916 The caller takes ownership of this object, so is responsible for its deletion. */ |
|
1917 { |
|
1918 return(CContactItemPlusGroup::GroupsJoinedLC()); |
|
1919 } |
|
1920 |
|
1921 /* |
|
1922 * Own card. |
|
1923 * |
|
1924 * An own card is a contact card which contains information about the |
|
1925 * device's owner. This can be sent to another compatible electronic |
|
1926 * device as a vCard. The contact database recognises a single own card |
|
1927 * referred to as the current own card; its ID is returned by |
|
1928 * <code>CContactDatabase::OwnCardId()</code>. Like a contact card, an |
|
1929 * own card can be a member of one or more contact card groups. The own |
|
1930 * card type is identified by a UID of <code>KUidContactOwnCard</code>, |
|
1931 * as returned by <code>Type()</code>.Own cards can be constructed using |
|
1932 * either <code>CContactDatabase::CreateOwnCardLC()</code> or |
|
1933 * <code>CreateOwnCardL()</code>. These functions create an own card, |
|
1934 * based on the system template, add it to the database, set it as the |
|
1935 * database's current own card and return a pointer to it. To change the |
|
1936 * database's current own card, use |
|
1937 * <code>CContactDatabase::SetOwnCardL()</code>. |
|
1938 * |
|
1939 * @since 5.2 |
|
1940 */ |
|
1941 CContactOwnCard::CContactOwnCard() |
|
1942 { |
|
1943 } |
|
1944 |
|
1945 // |
|
1946 // class CContactGroup |
|
1947 // |
|
1948 EXPORT_C CContactGroup* CContactGroup::NewL() |
|
1949 /** Allocates and constructs a new default contact card group. The group has no label and |
|
1950 its list of members is NULL. |
|
1951 |
|
1952 Contact groups should be constructed using the factory functions provided |
|
1953 in class CContactDatabase, for example CreateContactGroupL(). |
|
1954 |
|
1955 @return Pointer to the new contact card group. */ |
|
1956 { // static |
|
1957 CContactGroup* group=CContactGroup::NewLC(); |
|
1958 CleanupStack::Pop(); |
|
1959 return group; |
|
1960 } |
|
1961 |
|
1962 EXPORT_C CContactGroup* CContactGroup::NewLC() |
|
1963 /** Allocates and constructs a new default contact card group. |
|
1964 |
|
1965 The group has no label and its list of members is NULL. |
|
1966 |
|
1967 Contact groups should be constructed using the factory functions provided |
|
1968 in class CContactDatabase, for example CreateContactGroupLC(). |
|
1969 |
|
1970 @return Pointer to the new contact card group. This is left on the cleanup stack.*/ |
|
1971 { |
|
1972 CContactGroup* group=new(ELeave) CContactGroup; |
|
1973 CleanupStack::PushL(group); |
|
1974 group->ConstructL(); |
|
1975 return group; |
|
1976 } |
|
1977 |
|
1978 CContactGroup::CContactGroup() |
|
1979 { |
|
1980 } |
|
1981 |
|
1982 EXPORT_C CContactGroup::~CContactGroup() |
|
1983 /** The destructor frees all resources owned by the contact group, prior to its |
|
1984 destruction. */ |
|
1985 { |
|
1986 delete iItems; |
|
1987 } |
|
1988 |
|
1989 EXPORT_C TUid CContactGroup::Type() const |
|
1990 /** Implements CContactItem::Type(). |
|
1991 |
|
1992 @return KUidContactGroup. */ |
|
1993 { |
|
1994 return KUidContactGroup; |
|
1995 } |
|
1996 |
|
1997 EXPORT_C CContactIdArray* CContactGroup::ItemsContainedLC() const |
|
1998 /** Returns a pointer to a copy of the group's list of members. |
|
1999 |
|
2000 @return Pointer to a copy of the group's list of members. This is left on |
|
2001 the cleanup stack. */ |
|
2002 { |
|
2003 if (iItems) |
|
2004 { |
|
2005 CContactIdArray* copy = CContactIdArray::NewLC(iItems); |
|
2006 return copy; |
|
2007 } |
|
2008 else |
|
2009 { |
|
2010 // iItems is NULL |
|
2011 CleanupStack::PushL(iItems); |
|
2012 return NULL; |
|
2013 } |
|
2014 } |
|
2015 |
|
2016 EXPORT_C const CContactIdArray* CContactGroup::ItemsContained() const |
|
2017 /** Returns a constant pointer to the group's list of members. |
|
2018 |
|
2019 @return Pointer to the group's list of members. */ |
|
2020 { |
|
2021 return iItems; |
|
2022 } |
|
2023 |
|
2024 EXPORT_C TBool CContactGroup::IsSystem() const |
|
2025 /** Tests the value of the group's system attribute. |
|
2026 |
|
2027 The system attribute is not currently used in the Contacts Model API. |
|
2028 |
|
2029 @return ETrue if system, EFalse if not. */ |
|
2030 { |
|
2031 return iAttributes&ESystem; |
|
2032 } |
|
2033 |
|
2034 EXPORT_C void CContactGroup::SetSystem(TBool aSystem) |
|
2035 /** Sets the value of the group's system attribute. |
|
2036 |
|
2037 The system attribute is not currently used in the Contacts Model API. |
|
2038 |
|
2039 @param aSystem ETrue to set the system attribute, EFalse to unset it. */ |
|
2040 { |
|
2041 if (aSystem) |
|
2042 iAttributes|=ESystem; |
|
2043 else |
|
2044 iAttributes&=~ESystem; |
|
2045 } |
|
2046 |
|
2047 EXPORT_C TBool CContactGroup::ContainsItem(TContactItemId aContactId) |
|
2048 /** Tests whether a contact item is a member of the group. |
|
2049 |
|
2050 @param aContactId The ID of the contact item to test. |
|
2051 @return ETrue if the item is a member of the group, EFalse if not. */ |
|
2052 { |
|
2053 if (iItems && iItems->Count()) |
|
2054 { |
|
2055 TInt index=iItems->Find(aContactId); |
|
2056 if (index==KErrNotFound) |
|
2057 return EFalse; |
|
2058 } |
|
2059 else |
|
2060 return EFalse; |
|
2061 return ETrue; |
|
2062 } |
|
2063 |
|
2064 EXPORT_C void CContactGroup::SetGroupLabelL(const TDesC& aLabel) |
|
2065 /** Sets the group label, replacing any existing one. |
|
2066 |
|
2067 @param aLabel The new group label. |
|
2068 @leave KErrNotFound The group has no label field (of type KUidContactFieldTemplateLabel). */ |
|
2069 { |
|
2070 CContactItemFieldSet& labelFields = this->CardFields(); |
|
2071 // find label field |
|
2072 TInt pos = labelFields.Find(KUidContactFieldTemplateLabel); |
|
2073 if (pos==KErrNotFound) |
|
2074 User::Leave(pos); |
|
2075 labelFields[pos].TextStorage()->SetTextL(aLabel); |
|
2076 } |
|
2077 |
|
2078 EXPORT_C TPtrC CContactGroup::GetGroupLabelL() |
|
2079 /** Gets the group label. |
|
2080 |
|
2081 @leave KErrNotFound The group has no label field (of type KUidContactFieldTemplateLabel). |
|
2082 |
|
2083 @return The new group label. */ |
|
2084 { |
|
2085 CContactItemFieldSet& labelFields = this->CardFields(); |
|
2086 // find |
|
2087 TInt pos = labelFields.Find(KUidContactFieldTemplateLabel); |
|
2088 if (pos==KErrNotFound) |
|
2089 User::Leave(pos); |
|
2090 return(labelFields[pos].TextStorage()->Text()); |
|
2091 } |
|
2092 |
|
2093 EXPORT_C TBool CContactGroup::HasItemLabelField() |
|
2094 /** Tests whether the group has a label field (of type KUidContactFieldTemplateLabel). |
|
2095 |
|
2096 @return ETrue if the group has a label field. EFalse if not. */ |
|
2097 { |
|
2098 CContactItemFieldSet& labelFields = this->CardFields(); |
|
2099 TInt pos = labelFields.Find(KUidContactFieldTemplateLabel); |
|
2100 if (pos==KErrNotFound) |
|
2101 return EFalse; |
|
2102 return ETrue; |
|
2103 } |
|
2104 |
|
2105 EXPORT_C CContactIdArray* CContactGroup::GroupsJoinedLC()const |
|
2106 /** Returns a pointer to a list of contact groups to which the current group belongs |
|
2107 (a contact group can belong to other groups). |
|
2108 |
|
2109 @return A pointer to a copy of the array of groups IDs to which this group |
|
2110 belongs. This array is empty if the group is not a member of any other groups. |
|
2111 The caller takes ownership of this object, so is responsible for its deletion. */ |
|
2112 { |
|
2113 return(CContactItemPlusGroup::GroupsJoinedLC()); |
|
2114 } |
|
2115 |
|
2116 |
|
2117 /** |
|
2118 Adds a contact with the given Id to the group. This method doesn't make any changes to the database. |
|
2119 The change should be persisted by means of CContactDatabase::CommitContactL() API. |
|
2120 |
|
2121 @param aContactId The Id of the contact being added to the group. |
|
2122 @leave KErrAlreadyExists The contact is already a member of this group. |
|
2123 |
|
2124 @internalTechnology |
|
2125 */ |
|
2126 EXPORT_C void CContactGroup::AddContactL(TContactItemId aContactId) |
|
2127 { |
|
2128 if (!iItems) |
|
2129 { |
|
2130 iItems = CContactIdArray::NewL(); //No need to push on the stack because it is a member |
|
2131 } |
|
2132 if (iItems->Find(aContactId) == KErrNotFound) |
|
2133 { |
|
2134 iItems->AddL(aContactId); |
|
2135 } |
|
2136 else |
|
2137 { |
|
2138 User::Leave(KErrAlreadyExists); |
|
2139 } |
|
2140 } |
|
2141 |
|
2142 /** |
|
2143 Removes a contact with the given Id from the group. This method doesn't make any changes to the database. |
|
2144 The change should be persisted by means of CContactDatabase::CommitContactL() API. |
|
2145 |
|
2146 @param aContactId The Id of the contact being removed from the group. |
|
2147 @leave KErrNotFound The contact is not a member of this group. |
|
2148 |
|
2149 @internalTechnology |
|
2150 */ |
|
2151 EXPORT_C void CContactGroup::RemoveContactL(TContactItemId aContactId) |
|
2152 { |
|
2153 TInt arrIndex(0); |
|
2154 if (!iItems || KErrNotFound == (arrIndex = iItems->Find(aContactId))) |
|
2155 { //If array is empty of the contact ID is not found |
|
2156 User::Leave(KErrNotFound); |
|
2157 } |
|
2158 iItems->Remove(arrIndex); |
|
2159 } |
|
2160 |
|
2161 void CContactGroup::InternalizeL(RReadStream& aStream) |
|
2162 /** Internalises a CContactGroup object from a read stream. |
|
2163 @param aStream Stream from which the object should be internalised. */ |
|
2164 { |
|
2165 // Call Parent InternalizeL to internalize all members. |
|
2166 CContactItemPlusGroup::InternalizeL(aStream); |
|
2167 |
|
2168 if (iItems) |
|
2169 { |
|
2170 delete iItems; |
|
2171 iItems = NULL; |
|
2172 } |
|
2173 |
|
2174 const TBool iItemsExists=aStream.ReadInt32L(); |
|
2175 if (iItemsExists) |
|
2176 { |
|
2177 iItems = CContactIdArray::NewL(); |
|
2178 iItems->InternalizeL(aStream); |
|
2179 } |
|
2180 |
|
2181 } |
|
2182 |
|
2183 void CContactGroup::ExternalizeL(RWriteStream& aStream) const |
|
2184 /** Externalises a CContactGroup object to a write stream. |
|
2185 @param aStream Stream to which the object should be externalised. */ |
|
2186 { |
|
2187 // Call Parent ExternalizeL to externalize all members. |
|
2188 CContactItemPlusGroup::ExternalizeL(aStream); |
|
2189 |
|
2190 if(iItems) |
|
2191 { |
|
2192 aStream.WriteInt32L(1); |
|
2193 iItems->ExternalizeL(aStream); |
|
2194 } |
|
2195 |
|
2196 else |
|
2197 { |
|
2198 aStream.WriteInt32L(0); |
|
2199 } |
|
2200 } |
|
2201 |
|
2202 /** |
|
2203 Resets items. |
|
2204 |
|
2205 @internalTechnology |
|
2206 @released |
|
2207 */ |
|
2208 EXPORT_C void CContactGroup::ResetItems() |
|
2209 { |
|
2210 delete iItems; |
|
2211 iItems = NULL; |
|
2212 } |
|
2213 |
|
2214 /** |
|
2215 Sets groups. |
|
2216 |
|
2217 @internalTechnology |
|
2218 @released |
|
2219 */ |
|
2220 EXPORT_C void CContactGroup::SetItems(CContactIdArray* aItems) |
|
2221 { |
|
2222 iItems = aItems; |
|
2223 } |
|
2224 |
|
2225 // |
|
2226 // class CContactTemplate |
|
2227 // |
|
2228 |
|
2229 EXPORT_C CContactTemplate* CContactTemplate::NewL() |
|
2230 /** Allocates and constructs a new default system template. |
|
2231 |
|
2232 @return Pointer to the newly created system template. */ |
|
2233 { // static |
|
2234 CContactTemplate* item=CContactTemplate::NewLC(); |
|
2235 CleanupStack::Pop(); // item |
|
2236 return item; |
|
2237 } |
|
2238 |
|
2239 EXPORT_C CContactTemplate* CContactTemplate::NewLC() |
|
2240 /** Allocates and constructs a new default system template. |
|
2241 |
|
2242 @return Pointer to the newly created system template. This is left on the cleanup stack.*/ |
|
2243 { // static |
|
2244 CContactTemplate* item=new(ELeave) CContactTemplate; |
|
2245 CleanupStack::PushL(item); |
|
2246 item->ConstructL(); |
|
2247 return item; |
|
2248 } |
|
2249 |
|
2250 EXPORT_C CContactTemplate* CContactTemplate::NewL(const CContactItem *aTemplate) |
|
2251 /** Allocates and constructs a new system template seeded from another one. |
|
2252 |
|
2253 @param aTemplate The contact template to copy. |
|
2254 @return Pointer to the newly created system template. */ |
|
2255 { |
|
2256 CContactTemplate* item=CContactTemplate::NewLC(aTemplate); |
|
2257 CleanupStack::Pop(); // item |
|
2258 return item; |
|
2259 } |
|
2260 |
|
2261 EXPORT_C CContactTemplate* CContactTemplate::NewLC(const CContactItem *aTemplate) |
|
2262 /** Allocates and constructs a new system template seeded from another one. |
|
2263 |
|
2264 @param aTemplate The contact template to copy. |
|
2265 @return Pointer to the newly created system template. This is left on the cleanup stack.*/ |
|
2266 { |
|
2267 CContactTemplate* item=new(ELeave) CContactTemplate; |
|
2268 CleanupStack::PushL(item); |
|
2269 item->ConstructL(aTemplate); |
|
2270 return item; |
|
2271 } |
|
2272 |
|
2273 EXPORT_C TUid CContactTemplate::Type() const |
|
2274 /** Implements CContactItem::Type(). |
|
2275 |
|
2276 @return KUidContactTemplate. */ |
|
2277 { |
|
2278 return KUidContactTemplate; |
|
2279 } |
|
2280 |
|
2281 CContactTemplate::CContactTemplate() |
|
2282 { |
|
2283 } |
|
2284 |
|
2285 |
|
2286 EXPORT_C CContactICCEntry::~CContactICCEntry() |
|
2287 /** Empty destructor. */ |
|
2288 { |
|
2289 } |
|
2290 |
|
2291 |
|
2292 /** Allocates and constructs a new ICC entry. |
|
2293 |
|
2294 @param The contact template to use. |
|
2295 @return Pointer to newly created CContactICCEntry. |
|
2296 @publishedAll |
|
2297 @released |
|
2298 */ |
|
2299 EXPORT_C CContactICCEntry* CContactICCEntry::NewL(const CContactItem& aTemplate) |
|
2300 { |
|
2301 CContactICCEntry* entry = new (ELeave) CContactICCEntry(); |
|
2302 CleanupStack::PushL(entry); |
|
2303 entry->ConstructL(&aTemplate); |
|
2304 CleanupStack::Pop(entry); |
|
2305 return entry; |
|
2306 } |
|
2307 |
|
2308 /* |
|
2309 * Allocates and constructs a new ICC entry. |
|
2310 * Not exported - only used by CNTMODEL code. |
|
2311 * |
|
2312 * @return Pointer to newly created CContactEntry |
|
2313 * @since 7.0 |
|
2314 */ |
|
2315 CContactICCEntry* CContactICCEntry::NewL() |
|
2316 { |
|
2317 CContactICCEntry* entry = new (ELeave) CContactICCEntry(); |
|
2318 CleanupStack::PushL(entry); |
|
2319 entry->ConstructL(); |
|
2320 CleanupStack::Pop(entry); |
|
2321 return entry; |
|
2322 } |
|
2323 |
|
2324 TUid CContactICCEntry::Type() const |
|
2325 /** Implements CContactItem::Type(). |
|
2326 |
|
2327 @return KUidContactICCEntry. */ |
|
2328 { |
|
2329 return KUidContactICCEntry; |
|
2330 } |
|
2331 |
|
2332 CContactICCEntry::CContactICCEntry() |
|
2333 { |
|
2334 } |
|
2335 |
|
2336 |
|
2337 EXPORT_C TContactItemId ContactGuid::IsLocalContactUidString(const TDesC& aString, TInt64 aMachineUniqueId) |
|
2338 /** Tests whether a contact item was created in the database with the unique ID |
|
2339 specified. If so, the item's contact item ID is returned. If not, returns |
|
2340 KErrNotFound. |
|
2341 |
|
2342 @param aString The contact item's UID string. Use CContactItem::UidStringL() |
|
2343 to get a pointer to the item's UID string. |
|
2344 @param aMachineUniqueId The database's unique ID. This can be found by calling |
|
2345 CContactDatabase::MachineId(). |
|
2346 @return KErrNotFound if the database ID specified is not found in the UID string. |
|
2347 Otherwise, the contact item's contact item ID. */ |
|
2348 { // static |
|
2349 TLex lex(aString); |
|
2350 TInt ii=0; |
|
2351 TChar c; |
|
2352 TInt64 pos=KErrNotFound; |
|
2353 // check machine id |
|
2354 c=lex.Peek(); |
|
2355 if (c==KUidStringSeparator) |
|
2356 ; |
|
2357 else |
|
2358 { |
|
2359 lex.Val(pos,EHex); |
|
2360 if ((TInt64)pos!=aMachineUniqueId) |
|
2361 return (KErrNotFound); |
|
2362 } |
|
2363 for(;;) |
|
2364 { |
|
2365 c=lex.Get(); |
|
2366 if (c) |
|
2367 { |
|
2368 if (c==KUidStringSeparator) |
|
2369 { |
|
2370 ii++; |
|
2371 } |
|
2372 else |
|
2373 { |
|
2374 if (ii==2) // extract the field id |
|
2375 { |
|
2376 lex.UnGet(); |
|
2377 lex.Val(pos); |
|
2378 break; |
|
2379 } |
|
2380 } |
|
2381 } |
|
2382 else //EOS |
|
2383 break; |
|
2384 } |
|
2385 return I64INT(pos); |
|
2386 } |
|
2387 |
|
2388 /** |
|
2389 @internalTechnology |
|
2390 */ |
|
2391 EXPORT_C TBool ContactGuid::GetCreationDate(TDes& aString, TInt64 aMachineUniqueId) |
|
2392 { // static |
|
2393 if (ContactGuid::IsLocalContactUidString(aString,aMachineUniqueId)>=0) |
|
2394 { |
|
2395 const TInt startPos=aString.Locate(TChar(KUidStringSeparator)); |
|
2396 if (startPos!=KErrNotFound) |
|
2397 { |
|
2398 TInt endPos=aString.Length(); |
|
2399 while (--endPos>startPos) |
|
2400 { |
|
2401 if (aString[endPos]==KUidStringSeparator) |
|
2402 { |
|
2403 aString=aString.Left(endPos); |
|
2404 aString=aString.Right(aString.Length()-startPos-1); |
|
2405 return ETrue; |
|
2406 } |
|
2407 } |
|
2408 } |
|
2409 } |
|
2410 return EFalse; |
|
2411 } |
|
2412 |
|
2413 HBufC* ContactGuid::CreateGuidLC(const TDesC& aCreationDate,TContactItemId aId, TInt64 aMachineUniqueId) |
|
2414 { // static |
|
2415 HBufC* guid=HBufC::NewLC(KUidStringLength); |
|
2416 TPtr ptr=guid->Des(); |
|
2417 ptr.AppendFormat(_L("%08x"),I64HIGH(aMachineUniqueId)); |
|
2418 ptr.AppendFormat(_L("%08x"),I64LOW(aMachineUniqueId)); |
|
2419 ptr.Append(KUidStringSeparator); |
|
2420 ptr.Append(aCreationDate); |
|
2421 ptr.Append(KUidStringSeparator); |
|
2422 TBuf<20> localId; |
|
2423 localId.Num((TInt)aId); |
|
2424 ptr.Append(localId); |
|
2425 return guid; |
|
2426 } |
|
2427 |
|
2428 HBufC* ContactGuid::CreateGuidLC(const TTime& aCreationDate,TContactItemId aId, TInt64 aMachineUniqueId) |
|
2429 { // static |
|
2430 TBuf<32> time; |
|
2431 TInt64 num=aCreationDate.Int64(); |
|
2432 time.AppendFormat(_L("%08x"),(TInt32)I64HIGH(num)); |
|
2433 time.AppendFormat(_L("%08x"),(TInt32)I64LOW(num)); |
|
2434 return ContactGuid::CreateGuidLC(time,aId,aMachineUniqueId); |
|
2435 } |
|
2436 |
|
2437 HBufC* ContactGuid::CreateGuidLC(TContactItemId aId, TInt64 aMachineUniqueId) |
|
2438 { // static |
|
2439 TTime time; |
|
2440 time.UniversalTime(); |
|
2441 return ContactGuid::CreateGuidLC(time,aId,aMachineUniqueId); |
|
2442 } |