|
1 /* |
|
2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Converts properties PIM <-> vCard |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // CLASS HEADER |
|
20 #include "cpimcardpropertyconverter.h" |
|
21 |
|
22 // INTERNAL INCLUDES |
|
23 #include "pimcommon.h" |
|
24 #include "pimpanics.h" |
|
25 #include "pimversit.h" |
|
26 #include "cpimitem.h" |
|
27 #include "cpimvcardparser.h" |
|
28 #include "cpimcontactitem.h" |
|
29 #include "cpimparserproperty.h" |
|
30 #include "cpimcontactvalidator.h" |
|
31 #include "cpimvcardparserparamarray.h" |
|
32 #include "logger.h" |
|
33 |
|
34 // EXTERNAL INCLUDES |
|
35 #include <vcard.h> |
|
36 #include <cntdef.h> // parameter literals |
|
37 #include <tz.h> |
|
38 #include <tzconverter.h> |
|
39 |
|
40 // ============================ MEMBER FUNCTIONS =============================== |
|
41 |
|
42 // ----------------------------------------------------------------------------- |
|
43 // CPIMCardPropertyConverter::NewL |
|
44 // Two-phased constructor. |
|
45 // ----------------------------------------------------------------------------- |
|
46 // |
|
47 CPIMCardPropertyConverter* CPIMCardPropertyConverter::NewL( |
|
48 const CPIMContactValidator& aValidator) |
|
49 { |
|
50 JELOG2(EPim); |
|
51 CPIMCardPropertyConverter* self = |
|
52 new(ELeave) CPIMCardPropertyConverter(aValidator); |
|
53 |
|
54 return self; |
|
55 } |
|
56 |
|
57 // Destructor |
|
58 CPIMCardPropertyConverter::~CPIMCardPropertyConverter() |
|
59 { |
|
60 JELOG2(EPim); |
|
61 } |
|
62 |
|
63 // ----------------------------------------------------------------------------- |
|
64 // CPIMCardPropertyConverter::ConvertFieldL |
|
65 // Inserts a Field from a PIM Contact Item to CParserVCard as a property. |
|
66 // ----------------------------------------------------------------------------- |
|
67 // |
|
68 void CPIMCardPropertyConverter::ConvertFieldL(const CPIMItem& aItem, // item to read the field from |
|
69 CParserVCard& aParser, // parser to insert the property to. |
|
70 TPIMContactField aField) // field to convert |
|
71 { |
|
72 JELOG2(EPim); |
|
73 TInt valueCount = aItem.CountValuesL(aField); |
|
74 for (TInt i = 0; i < valueCount; i++) |
|
75 { |
|
76 switch (aField) |
|
77 { |
|
78 case EPIMContactAddr: |
|
79 { |
|
80 ConvertAddressFieldL(aItem, aParser, aField, i); |
|
81 break; |
|
82 } |
|
83 case EPIMContactBirthday: |
|
84 case EPIMContactRevision: |
|
85 case EPIMContactExtAnniversary: |
|
86 { |
|
87 ConvertDateFieldL(aItem, aParser, aField, i); |
|
88 break; |
|
89 } |
|
90 case EPIMContactEmail: |
|
91 case EPIMContactNote: |
|
92 case EPIMContactTel: |
|
93 case EPIMContactTitle: |
|
94 case EPIMContactUrl: |
|
95 case EPIMContactNickname: |
|
96 case EPIMContactExtSip: |
|
97 case EPIMContactExtDtmf: |
|
98 case EPIMContactExtWvUserId: |
|
99 case EPIMContactExtSpouse: |
|
100 case EPIMContactExtChildren: |
|
101 case EPIMContactExtAssistantName: |
|
102 case EPIMContactExtVoip: |
|
103 case EPIMContactExtPTT: |
|
104 case EPIMContactExtSWIS: |
|
105 // UID is required by VFX. Do not fix even though this is wrong |
|
106 case EPIMContactUid: |
|
107 { |
|
108 ConvertStringFieldL(aItem, aParser, aField, i); |
|
109 break; |
|
110 } |
|
111 case EPIMContactName: |
|
112 { |
|
113 ConvertNameFieldL(aItem, aParser, aField, i); |
|
114 break; |
|
115 } |
|
116 case EPIMContactOrg: |
|
117 case EPIMContactExtDepartment: |
|
118 { |
|
119 ConvertOrganisationalFieldsL(aItem, aParser, aField, i); |
|
120 break; |
|
121 } |
|
122 case EPIMContactPhoto: |
|
123 { |
|
124 ConvertPhotoFieldL(aItem, aParser, aField, i); |
|
125 break; |
|
126 } |
|
127 case EPIMContactClass: |
|
128 { |
|
129 ConvertClassFieldL(aItem, aParser, aField, i); |
|
130 break; |
|
131 } |
|
132 // PIM API vCard parser does not support converting formatted names |
|
133 // since the conversion is not unambiguous and an optional feature |
|
134 // for vCard parsers based on IMC vCard specification. Also, PIM |
|
135 // API internal specification version 4.3 does not allow |
|
136 // Contact.FORMATTED_NAME to be a supported fields in S60 implementations |
|
137 case EPIMContactFormattedName: |
|
138 case EPIMContactFormattedAddr: |
|
139 case EPIMContactPhotoUrl: |
|
140 case EPIMContactPublicKey: |
|
141 case EPIMContactPublicKeyString: |
|
142 default: |
|
143 { |
|
144 __ASSERT_DEBUG(EFalse, User::Panic(KPIMPanicCategory, |
|
145 EPIMPanicUnsupportedField)); |
|
146 return; |
|
147 } |
|
148 } |
|
149 } |
|
150 } |
|
151 |
|
152 // ----------------------------------------------------------------------------- |
|
153 // CPIMCardPropertyConverter::ConvertPropertyL |
|
154 // Inserts a proprety from a vCard to a PIM Contact Item as a field |
|
155 // ----------------------------------------------------------------------------- |
|
156 // |
|
157 CParserVCard* CPIMCardPropertyConverter::ConvertPropertyL( |
|
158 const CParserProperty& aProperty, // property to convert |
|
159 CPIMContactItem& aItem) // item to insert the field to |
|
160 { |
|
161 JELOG2(EPim); |
|
162 TUid valueTypeUid = aProperty.Uid(); |
|
163 TInt valueType = valueTypeUid.iUid; |
|
164 CParserVCard* retVal = NULL; |
|
165 |
|
166 // The following, rather ugly, cast makes it possible for us to access |
|
167 // the protected iArrayOfParams field. |
|
168 const CPIMParserProperty& property = |
|
169 static_cast<const CPIMParserProperty&>(aProperty); |
|
170 |
|
171 // CLASS field is converted before others |
|
172 if (aProperty.Name().CompareF(KVersitTokenClass) == 0) |
|
173 { |
|
174 ConvertClassPropertyL(property, aItem); |
|
175 } |
|
176 // If SOUND field holds parameter X-IRMC-N, it countains name reading fields |
|
177 else if ((aProperty.Name().CompareF(KVersitTokenSOUND) == 0) |
|
178 && (aProperty.Param(KVersitParam8NamePrn))) |
|
179 { |
|
180 ConvertNameReadingFieldL(property, aItem); |
|
181 } |
|
182 else |
|
183 { |
|
184 switch (valueType) |
|
185 { |
|
186 case KVersitPropertyBinaryUid: |
|
187 { |
|
188 ConvertPhotoPropertyL(property, aItem); |
|
189 break; |
|
190 } |
|
191 case KVersitPropertyCDesCArrayUid: |
|
192 { |
|
193 // name and address arrays |
|
194 ConvertCDesCArrayPropertyL(property, aItem); |
|
195 break; |
|
196 } |
|
197 case KVersitPropertyDateUid: |
|
198 case KVersitPropertyDateTimeUid: |
|
199 { |
|
200 // REV, BDAY, X-ANNIVERSARY |
|
201 ConvertDatePropertyL(property, aItem); |
|
202 break; |
|
203 } |
|
204 case KVersitPropertyHBufCUid: |
|
205 { |
|
206 ConvertStringPropertyL(property, aItem); |
|
207 break; |
|
208 } |
|
209 case KVCardPropertyAgentUid: |
|
210 { |
|
211 retVal = ConvertAgentPropertyL(property); |
|
212 } |
|
213 default: |
|
214 { |
|
215 // don't support, don't care |
|
216 } |
|
217 } |
|
218 } |
|
219 return retVal; |
|
220 } |
|
221 |
|
222 // ----------------------------------------------------------------------------- |
|
223 // CPIMCardPropertyConverter::CPIMCardPropertyConverter |
|
224 // C++ default constructor can NOT contain any code, that |
|
225 // might leave. |
|
226 // ----------------------------------------------------------------------------- |
|
227 // |
|
228 CPIMCardPropertyConverter::CPIMCardPropertyConverter( |
|
229 const CPIMContactValidator& aValidator) : |
|
230 iContactValidator(aValidator) |
|
231 { |
|
232 JELOG2(EPim); |
|
233 } |
|
234 |
|
235 // ----------------------------------------------------------------------------- |
|
236 // CPIMCardPropertyConverter::ConvertAgentPropertyL |
|
237 // Converts an agent property. |
|
238 // ----------------------------------------------------------------------------- |
|
239 // |
|
240 inline CParserVCard* CPIMCardPropertyConverter::ConvertAgentPropertyL( |
|
241 const CPIMParserProperty& aProperty) // property to convert |
|
242 { |
|
243 JELOG2(EPim); |
|
244 CParserPropertyValueAgent* propertyValue = |
|
245 static_cast<CParserPropertyValueAgent*>(aProperty.Value()); |
|
246 CParserVCard* value = propertyValue->Value(); |
|
247 return value; |
|
248 } |
|
249 |
|
250 // ----------------------------------------------------------------------------- |
|
251 // CPIMCardPropertyConverter::AddParamHomeAndWorkL |
|
252 // Adds parameters "HOME" and "WORK" if necessary to given property parameter |
|
253 // array. |
|
254 // ----------------------------------------------------------------------------- |
|
255 // |
|
256 void CPIMCardPropertyConverter::AddParamHomeAndWorkL(TPIMAttribute aAttributes, // checked if it contains AttrHome or AttrWork |
|
257 CPIMVCardParserParamArray& aParamArray) // array to add the parameters to |
|
258 { |
|
259 JELOG2(EPim); |
|
260 if ((aAttributes & EPIMContactAttrHome) != 0) |
|
261 { |
|
262 AddParserParameterL(aParamArray, KVersitParam8Home()); |
|
263 } |
|
264 if ((aAttributes & EPIMContactAttrWork) != 0) |
|
265 { |
|
266 AddParserParameterL(aParamArray, KVersitParam8Work()); |
|
267 } |
|
268 } |
|
269 |
|
270 // ----------------------------------------------------------------------------- |
|
271 // CPIMCardPropertyConverter::ConvertAddressFieldL |
|
272 // Converts an address field from a PIM Contact Item to CParserVCard. |
|
273 // The field is stored in the parser as a property. |
|
274 // The address values are stored in CParserPropertyValue |
|
275 // CParserProperty is created, given the value. |
|
276 // Parameters are added, and finally the property is added to parser. |
|
277 // ----------------------------------------------------------------------------- |
|
278 // |
|
279 void CPIMCardPropertyConverter::ConvertAddressFieldL(const CPIMItem& aItem, // item to convert from |
|
280 CParserVCard& aParser, // parsers to write to |
|
281 TPIMContactField aField, // field to convert |
|
282 TInt aIndex) // index to the field |
|
283 { |
|
284 JELOG2(EPim); |
|
285 // Add attributes if there are any |
|
286 TPIMAttribute attributes = aItem.getAttributes(aField, aIndex); |
|
287 CPIMVCardParserParamArray* paramArray = |
|
288 new(ELeave) CPIMVCardParserParamArray(3); |
|
289 CleanupStack::PushL(paramArray); |
|
290 AddParamHomeAndWorkL(attributes, *paramArray); |
|
291 |
|
292 const CDesCArray& itemAddrArray = aItem.GetStringArrayL(aField, aIndex); |
|
293 // Copy the array |
|
294 TInt elementCount = itemAddrArray.Count(); |
|
295 CDesCArrayFlat* addrArray = new(ELeave) CDesCArrayFlat(elementCount); |
|
296 CleanupStack::PushL(addrArray); |
|
297 for (TInt i = 0; i < elementCount; i++) |
|
298 { |
|
299 if (itemAddrArray[i].Compare(KPIMNullArrayElement) == 0) |
|
300 { |
|
301 addrArray->AppendL(KNullDesC); |
|
302 } |
|
303 else |
|
304 { |
|
305 addrArray->AppendL(itemAddrArray[i]); |
|
306 } |
|
307 } |
|
308 |
|
309 CParserPropertyValue* propertyValue = |
|
310 new(ELeave) CParserPropertyValueCDesCArray(addrArray); |
|
311 // addrArray is now owned by propertyValue |
|
312 CleanupStack::Pop(addrArray); |
|
313 AddPropertyToParserL(propertyValue, KVersitTokenADR(), paramArray, aParser); |
|
314 // The paramArray and propertyValue are popped by the previous function call |
|
315 } |
|
316 |
|
317 // ----------------------------------------------------------------------------- |
|
318 // CPIMCardPropertyConverter::ConvertNameFieldL |
|
319 // Converts a Name field from a PIM Contact Item to CParserVCard. |
|
320 // The field is stored in the parser as a property. |
|
321 // The name values are stored in CParserPropertyValue |
|
322 // CParserProperty is created, given the value. |
|
323 // Parameters are added, and finally the property is added to parser. |
|
324 // ----------------------------------------------------------------------------- |
|
325 // |
|
326 void CPIMCardPropertyConverter::ConvertNameFieldL(const CPIMItem& aItem, // item to convert from |
|
327 CParserVCard& aParser, // parsers to write to |
|
328 TPIMContactField aField, // field to convert |
|
329 TInt aIndex) // index to the field |
|
330 { |
|
331 JELOG2(EPim); |
|
332 TBool readingFieldsPresent = EFalse; |
|
333 const CDesCArray& itemNameArray = aItem.GetStringArrayL(aField, aIndex); |
|
334 TInt elementCount = itemNameArray.Count(); |
|
335 CDesCArray* readingArray = new(ELeave) CDesCArrayFlat(2); |
|
336 CleanupStack::PushL(readingArray); |
|
337 CDesCArray* nameArray = new(ELeave) CDesCArrayFlat(elementCount); |
|
338 CleanupStack::PushL(nameArray); |
|
339 |
|
340 // Names should be ordered as follows: |
|
341 // Family name, Given name, Middle name, Prefix, Suffix |
|
342 // so check TPIMContactNameElement that it is in the right order |
|
343 for (TInt i = 0; i < elementCount; i++) |
|
344 { |
|
345 // Skip extended name reading fields on here |
|
346 if (i == EPIMContactExtFamilyNameReading || i |
|
347 == EPIMContactExtGivenNameReading) |
|
348 { |
|
349 if (itemNameArray[i].Compare(KPIMNullArrayElement) != 0) |
|
350 { |
|
351 readingFieldsPresent = ETrue; |
|
352 readingArray->AppendL(itemNameArray[TPIMContactNameElement(i)]); |
|
353 } |
|
354 else |
|
355 { |
|
356 readingArray->AppendL(KNullDesC); |
|
357 } |
|
358 } |
|
359 // Replace null array elements with KNullDesC |
|
360 else if (itemNameArray[i].Compare(KPIMNullArrayElement) == 0) |
|
361 { |
|
362 nameArray->AppendL(KNullDesC); |
|
363 } |
|
364 else |
|
365 { |
|
366 nameArray->AppendL(itemNameArray[TPIMContactNameElement(i)]); |
|
367 } |
|
368 } |
|
369 CParserPropertyValue* propertyValue = |
|
370 new(ELeave) CParserPropertyValueCDesCArray(nameArray); |
|
371 // nameArray is now owned by propertyValue |
|
372 CleanupStack::Pop(nameArray); |
|
373 AddPropertyToParserL(propertyValue, KVersitTokenN(), NULL, aParser); |
|
374 // The paramArray and propertyValue are popped by the previous function call |
|
375 |
|
376 // Add name reading fields if they are present |
|
377 if (readingFieldsPresent) |
|
378 { |
|
379 // Create parameter array |
|
380 CPIMVCardParserParamArray* paramArray = |
|
381 new(ELeave) CPIMVCardParserParamArray(1); |
|
382 CleanupStack::PushL(paramArray); |
|
383 // Create pronunciation parameter and add it to the parameter array |
|
384 AddParserParameterL(*paramArray, KVersitParam8NamePrn()); |
|
385 // Create a new proprety value from the reading names array |
|
386 CParserPropertyValue* readingPropValue = |
|
387 new(ELeave) CParserPropertyValueCDesCArray(readingArray); |
|
388 // nameArray is now owned by propertyValue |
|
389 CleanupStack::Pop(paramArray); |
|
390 CleanupStack::Pop(readingArray); |
|
391 CleanupStack::PushL(paramArray); |
|
392 AddPropertyToParserL(readingPropValue, KVersitTokenSOUND(), paramArray, |
|
393 aParser); |
|
394 // The paramArray and propertyValue are popped |
|
395 // by the previous function call |
|
396 } |
|
397 else |
|
398 { |
|
399 // Clean the reading array |
|
400 CleanupStack::PopAndDestroy(readingArray); |
|
401 } |
|
402 } |
|
403 |
|
404 // ----------------------------------------------------------------------------- |
|
405 // CPIMCardPropertyConverter::ConvertCDesCArrayPropertyL |
|
406 // Converts name and address arrays from a vCard to a PIM Contact Item |
|
407 // ----------------------------------------------------------------------------- |
|
408 // |
|
409 void CPIMCardPropertyConverter::ConvertCDesCArrayPropertyL( |
|
410 const CPIMParserProperty& aProperty, // property to convert |
|
411 CPIMContactItem& aItem) // item to insert the field to |
|
412 { |
|
413 JELOG2(EPim); |
|
414 TPIMField field = aProperty.MatchContactField(); |
|
415 |
|
416 if ((field != EPIMContactAddr) && (field != EPIMContactName) && (field |
|
417 != EPIMContactOrg) && (field != EPIMContactExtChildren)) |
|
418 { |
|
419 // unsupported properties are silently discarded |
|
420 return; |
|
421 } |
|
422 |
|
423 CParserPropertyValueCDesCArray* propertyValue = |
|
424 static_cast<CParserPropertyValueCDesCArray*>(aProperty.Value()); |
|
425 const CDesCArray* value = propertyValue->Value(); |
|
426 |
|
427 // In ORG field, the Organizational name is the first item and the second |
|
428 // item is extended department name |
|
429 if (field == EPIMContactOrg) |
|
430 { |
|
431 TInt valueCount = value->Count(); |
|
432 if (valueCount >= 1) |
|
433 { |
|
434 HBufC* orgValue = value->MdcaPoint(0).AllocLC(); |
|
435 aItem.AddStringL(field, KPIMAttrNone, orgValue); |
|
436 CleanupStack::Pop(orgValue); |
|
437 // Get department from the array |
|
438 if (valueCount > 1) |
|
439 { |
|
440 HBufC* department = value->MdcaPoint(1).AllocLC(); |
|
441 aItem.AddStringL(EPIMContactExtDepartment, KPIMAttrNone, |
|
442 department); |
|
443 CleanupStack::Pop(department); |
|
444 } |
|
445 } |
|
446 return; |
|
447 } |
|
448 // Children is imported as a CDesCArray so we have to convert it here |
|
449 if (field == EPIMContactExtChildren && value->Count() >= 1) |
|
450 { |
|
451 // We are only interested about the first value |
|
452 HBufC* children = value->MdcaPoint(0).AllocLC(); |
|
453 aItem.AddStringL(field, KPIMAttrNone, children); |
|
454 CleanupStack::Pop(children); |
|
455 return; |
|
456 } |
|
457 |
|
458 // Copy the array |
|
459 TInt elementCount = value->Count(); |
|
460 CDesCArrayFlat* itemArray = new(ELeave) CDesCArrayFlat(elementCount); |
|
461 CleanupStack::PushL(itemArray); |
|
462 TInt i; |
|
463 for (i = 0; i < elementCount; i++) |
|
464 { |
|
465 itemArray->AppendL((*value)[i]); |
|
466 } |
|
467 |
|
468 // If we need more elements, add nulls |
|
469 TInt itemElementCount = iContactValidator.NumElementsL(field); |
|
470 TPtrC nullArrayElement(KPIMNullArrayElement); |
|
471 for (; i < itemElementCount; i++) |
|
472 { |
|
473 itemArray->AppendL(nullArrayElement); |
|
474 } |
|
475 |
|
476 TPIMAttribute attributes = KPIMAttrNone; |
|
477 // Usually people only have one name. However, both PIM api and |
|
478 // vCards allow two names: Formatted name is not supported anymore since |
|
479 // converting it is not unambiguous and it must not be supported by the |
|
480 // PIM API internal specification version 4.3. IMC's vCard specification |
|
481 // states that Formatted name is an optional field for vCard parsers. |
|
482 if (field == EPIMContactName && aItem.CountValuesL(EPIMContactName) > 0) |
|
483 { |
|
484 // we already have a name, so we just change the current one |
|
485 // NOTE: There can be name reading fields before the name array |
|
486 // elements are added so we have take care of it |
|
487 const CDesCArray& nameArray = aItem.GetStringArrayL(EPIMContactName, 0); |
|
488 TPtrC name(nameArray.MdcaPoint(EPIMContactExtFamilyNameReading)); |
|
489 if (name != KPIMNullArrayElement) |
|
490 { |
|
491 // Delete empty item and add existing item |
|
492 itemArray->Delete(EPIMContactExtFamilyNameReading); |
|
493 itemArray->InsertL(EPIMContactExtFamilyNameReading, name); |
|
494 } |
|
495 name.Set(nameArray.MdcaPoint(EPIMContactExtGivenNameReading)); |
|
496 if (name != KPIMNullArrayElement) |
|
497 { |
|
498 // Delete empty item and add existing item |
|
499 itemArray->Delete(EPIMContactExtGivenNameReading); |
|
500 itemArray->InsertL(EPIMContactExtGivenNameReading, name); |
|
501 } |
|
502 |
|
503 aItem.SetStringArrayL(EPIMContactName, 0, attributes, itemArray); |
|
504 CleanupStack::Pop(); // itemArray now owned by aItem |
|
505 return; |
|
506 } |
|
507 else |
|
508 { |
|
509 // address can have attributes |
|
510 attributes = aProperty.MatchHomeAndWorkAttributes(); |
|
511 } |
|
512 aItem.AddStringArrayL(field, attributes, itemArray); |
|
513 CleanupStack::Pop(); // itemArray now owned by aItem |
|
514 } |
|
515 |
|
516 // ----------------------------------------------------------------------------- |
|
517 // CPIMCardPropertyConverter::ConvertDateFieldL |
|
518 // Converts a date field from a PIM Contact Item to a CParserVCard. |
|
519 // ----------------------------------------------------------------------------- |
|
520 // |
|
521 void CPIMCardPropertyConverter::ConvertDateFieldL(const CPIMItem& aItem, // item to convert from |
|
522 CParserVCard& aParser, // parser to insert the property to. |
|
523 TPIMContactField aField, // field to convert |
|
524 TInt aIndex) // index to the field |
|
525 { |
|
526 JELOG2(EPim); |
|
527 TVersitDateTime* versitDateTime = NULL; |
|
528 CParserPropertyValue* propertyValue = NULL; |
|
529 TPtrC8 propertyName(KNullDesC8); |
|
530 |
|
531 // Handle fields separately |
|
532 switch (aField) |
|
533 { |
|
534 case EPIMContactExtAnniversary: |
|
535 case EPIMContactBirthday: |
|
536 { |
|
537 const TPIMDate date = aItem.GetDateL(aField, aIndex); |
|
538 // Convert times to local time since UTC time designator is not |
|
539 // supported in anniversary and birthday fields |
|
540 RTz tzServer; |
|
541 User::LeaveIfError(tzServer.Connect()); |
|
542 CleanupClosePushL(tzServer); |
|
543 |
|
544 // Create timezone converter |
|
545 CTzConverter* converter = CTzConverter::NewL(tzServer); |
|
546 CleanupStack::PushL(converter); |
|
547 |
|
548 TTime localTime(date); |
|
549 User::LeaveIfError(converter->ConvertToLocalTime(localTime)); |
|
550 CleanupStack::PopAndDestroy(2); // converter, tzServer |
|
551 |
|
552 versitDateTime |
|
553 = new(ELeave) TVersitDateTime(date.DateTime(), TVersitDateTime::EIsMachineLocal); |
|
554 |
|
555 // Set specific property name |
|
556 if (aField == EPIMContactBirthday) |
|
557 { |
|
558 propertyName.Set(KVersitTokenBDAY); |
|
559 } |
|
560 else if (aField == EPIMContactExtAnniversary) |
|
561 { |
|
562 propertyName.Set(KVersitTokenAnniversary); |
|
563 } |
|
564 CleanupDeletePushL(versitDateTime); |
|
565 // Create new date property value |
|
566 propertyValue = new(ELeave) CParserPropertyValueDate(versitDateTime); |
|
567 break; |
|
568 } |
|
569 case EPIMContactRevision: |
|
570 { |
|
571 TPIMDate date = aItem.LastModified(); |
|
572 versitDateTime |
|
573 = new(ELeave) TVersitDateTime(date.DateTime(), TVersitDateTime::EIsUTC); |
|
574 propertyName.Set(KVersitTokenREV); |
|
575 CleanupDeletePushL(versitDateTime); |
|
576 // Create new date and time property value |
|
577 propertyValue |
|
578 = new(ELeave) CParserPropertyValueDateTime(versitDateTime); |
|
579 break; |
|
580 } |
|
581 default: |
|
582 { |
|
583 User::Panic(KPIMPanicCategory, EPIMPanicUnsupportedDateField); |
|
584 break; |
|
585 } |
|
586 } |
|
587 // versitDateTime is now owned by propertyValue |
|
588 CleanupStack::Pop(versitDateTime); |
|
589 AddPropertyToParserL(propertyValue, propertyName, NULL, aParser); |
|
590 // The paramArray and propertyValue are popped by the previous function call |
|
591 } |
|
592 |
|
593 // ----------------------------------------------------------------------------- |
|
594 // CPIMCardPropertyConverter::ConvertDatePropertyL |
|
595 // Converts a birthday from a vCard to a PIM Contact Item |
|
596 // ----------------------------------------------------------------------------- |
|
597 // |
|
598 void CPIMCardPropertyConverter::ConvertDatePropertyL( |
|
599 const CPIMParserProperty& aProperty, // property to convert |
|
600 CPIMContactItem& aItem) // item to insert the field to |
|
601 { |
|
602 JELOG2(EPim); |
|
603 TPIMField field = aProperty.MatchContactField(); |
|
604 switch (field) |
|
605 { |
|
606 case EPIMContactExtAnniversary: |
|
607 case EPIMContactBirthday: |
|
608 case EPIMContactRevision: |
|
609 { |
|
610 // All date property values are equal (in some way) |
|
611 CParserPropertyValueDateTime* value = |
|
612 static_cast<CParserPropertyValueDateTime*>(aProperty.Value()); |
|
613 // Get versit date time object. Both date time properties |
|
614 // return TVersitDateTime so we don't care about the actual object |
|
615 const TVersitDateTime* vDateTime = value->Value(); |
|
616 // Add new date to PIM item |
|
617 TPIMDate date(vDateTime->iDateTime); |
|
618 aItem.AddDateL(field, KPIMAttrNone, date); |
|
619 break; |
|
620 } |
|
621 default: |
|
622 { |
|
623 // Discard other fields |
|
624 } |
|
625 } |
|
626 } |
|
627 |
|
628 // ----------------------------------------------------------------------------- |
|
629 // CPIMCardPropertyConverter::ConvertStringFieldL |
|
630 // Converts a string field from a PIM Item to vCard |
|
631 // ----------------------------------------------------------------------------- |
|
632 // |
|
633 void CPIMCardPropertyConverter::ConvertStringFieldL(const CPIMItem& aItem, // item to convert from |
|
634 CParserVCard& aParser, // parser to write to |
|
635 TPIMContactField aField, // field to convert |
|
636 TInt aIndex) // index to the value in the field |
|
637 { |
|
638 JELOG2(EPim); |
|
639 // We'll gather all property parameters (attributes) to an array |
|
640 // which we give to the property in construction. It seems to be |
|
641 // the only way to give a property multiple parameters of same type. |
|
642 TPIMAttribute attributes = aItem.getAttributes(aField, aIndex); |
|
643 // Assistant tel field is mapped for its own field in s60, so |
|
644 // it must not be associated with the standard TEL field in vCards |
|
645 if (aField == EPIMContactTel && (attributes & EPIMContactAttrAsst) != 0) |
|
646 { |
|
647 const TDesC& asstTel = aItem.GetStringL(aField, aIndex); |
|
648 CParserPropertyValue* propertyValue = CParserPropertyValueHBufC::NewL( |
|
649 asstTel); |
|
650 AddPropertyToParserL(propertyValue, KPIMVersitTokenASSTTEL(), NULL, |
|
651 aParser); |
|
652 // Needed cleanup stack cleanup is done within the function |
|
653 return; |
|
654 } |
|
655 CPIMVCardParserParamArray* paramArray = |
|
656 new(ELeave) CPIMVCardParserParamArray(3); |
|
657 CleanupStack::PushL(paramArray); |
|
658 |
|
659 TPtrC8 propertyName; // mapped from field identifier |
|
660 |
|
661 switch (aField) |
|
662 { |
|
663 case EPIMContactEmail: |
|
664 { |
|
665 propertyName.Set(KVersitTokenEMAIL); |
|
666 AddParamHomeAndWorkL(attributes, *paramArray); |
|
667 // Contacts Model and PIM support PREF attribute, how ever |
|
668 // vCard specification does not. Thus we don't add it. |
|
669 break; |
|
670 } |
|
671 case EPIMContactNote: |
|
672 { |
|
673 propertyName.Set(KVersitTokenNOTE); |
|
674 break; |
|
675 } |
|
676 case EPIMContactTel: |
|
677 { |
|
678 propertyName.Set(KVersitTokenTEL); |
|
679 if ((attributes & EPIMContactAttrFax) != 0) |
|
680 { |
|
681 AddParserParameterL(*paramArray, KVersitParam8Fax()); |
|
682 } |
|
683 if ((attributes & EPIMContactAttrMobile) != 0) |
|
684 { |
|
685 AddParserParameterL(*paramArray, KVersitParam8Cell()); |
|
686 } |
|
687 if ((attributes & EPIMContactAttrPager) != 0) |
|
688 { |
|
689 AddParserParameterL(*paramArray, KVersitParam8Pager()); |
|
690 } |
|
691 if ((attributes & (EPIMContactAttrPager | EPIMContactAttrFax |
|
692 | EPIMContactAttrSms | EPIMContactAttrAuto |
|
693 | EPIMContactAttrExtVideoCall)) == 0) |
|
694 { |
|
695 AddParserParameterL(*paramArray, KVersitParam8Voice()); |
|
696 } |
|
697 if ((attributes & (EPIMContactAttrPreferred)) != 0) |
|
698 { |
|
699 AddParserParameterL(*paramArray, KVersitParam8Pref()); |
|
700 } |
|
701 if ((attributes & EPIMContactAttrAuto) != 0) |
|
702 { |
|
703 AddParserParameterL(*paramArray, KVersitParam8Car()); |
|
704 } |
|
705 if ((attributes & EPIMContactAttrExtVideoCall) != 0) |
|
706 { |
|
707 AddParserParameterL(*paramArray, KVersitParam8Video()); |
|
708 } |
|
709 // Contacts Model and PIM support SMS attribute, how ever |
|
710 // vCard specification does not. Thus we ignore it. |
|
711 // ATTR_OTHER is also ingored because Contacts Model doesn't |
|
712 // provide anything where we could map ATTR_OTHER |
|
713 |
|
714 // Add HOME or WORK after all other attributes |
|
715 AddParamHomeAndWorkL(attributes, *paramArray); |
|
716 break; |
|
717 } |
|
718 case EPIMContactTitle: |
|
719 { |
|
720 propertyName.Set(KVersitTokenTITLE); |
|
721 break; |
|
722 } |
|
723 case EPIMContactUrl: |
|
724 { |
|
725 propertyName.Set(KVersitTokenURL); |
|
726 AddParamHomeAndWorkL(attributes, *paramArray); |
|
727 break; |
|
728 } |
|
729 case EPIMContactNickname: |
|
730 { |
|
731 propertyName.Set(KPIMVersitTokenNICKNAME); |
|
732 break; |
|
733 } |
|
734 case EPIMContactExtDtmf: |
|
735 { |
|
736 propertyName.Set(KPIMVersitTokenDTMF); |
|
737 break; |
|
738 } |
|
739 case EPIMContactExtWvUserId: |
|
740 { |
|
741 propertyName.Set(KPIMVersitTokenWVID); |
|
742 break; |
|
743 } |
|
744 case EPIMContactExtSpouse: |
|
745 { |
|
746 propertyName.Set(KVersitTokenSpouse); |
|
747 break; |
|
748 } |
|
749 case EPIMContactExtChildren: |
|
750 { |
|
751 propertyName.Set(KVersitTokenChildren); |
|
752 break; |
|
753 } |
|
754 case EPIMContactExtAssistantName: |
|
755 { |
|
756 propertyName.Set(KVersitTokenAssistant); |
|
757 break; |
|
758 } |
|
759 case EPIMContactExtVoip: |
|
760 case EPIMContactExtSip: |
|
761 case EPIMContactExtPTT: |
|
762 case EPIMContactExtSWIS: |
|
763 { |
|
764 TPtrC8 paramName; |
|
765 propertyName.Set(KPIMVersitTokenSIP); |
|
766 // VOIP is mapped to a subfield of X-SIP |
|
767 if (aField == EPIMContactExtVoip) |
|
768 { |
|
769 paramName.Set(KPIMVersitTokenVoip); |
|
770 } |
|
771 // PTT is mapped to a subfield of X-SIP |
|
772 else if (aField == EPIMContactExtPTT) |
|
773 { |
|
774 paramName.Set(KPIMVersitTokenPoc); |
|
775 } |
|
776 // SWIS is mapped to a subfield of X-SIP |
|
777 else if (aField == EPIMContactExtSWIS) |
|
778 { |
|
779 paramName.Set(KPIMVersitTokenSwis); |
|
780 } |
|
781 if (aField != EPIMContactExtSip) |
|
782 { |
|
783 AddParserParameterL(*paramArray, paramName); |
|
784 } |
|
785 |
|
786 AddParamHomeAndWorkL(attributes, *paramArray); |
|
787 // Contacts Model and PIM support PREF attribute, how ever |
|
788 // vCard specification does not. Thus we don't add it. |
|
789 break; |
|
790 } |
|
791 case EPIMContactUid: |
|
792 { |
|
793 propertyName.Set(KVersitTokenUID); |
|
794 break; |
|
795 } |
|
796 default: |
|
797 { |
|
798 User::Panic(KPIMPanicCategory, EPIMPanicUnsupportedStringField); |
|
799 } |
|
800 } |
|
801 |
|
802 const TDesC& pimStringValue = aItem.GetStringL(aField, aIndex); |
|
803 |
|
804 CParserPropertyValue* propertyValue = CParserPropertyValueHBufC::NewL( |
|
805 pimStringValue); |
|
806 AddPropertyToParserL(propertyValue, propertyName, paramArray, aParser); |
|
807 // The paramArray and propertyValue are popped by the previous function call |
|
808 } |
|
809 |
|
810 // ----------------------------------------------------------------------------- |
|
811 // CPIMCardPropertyConverter::AddParserParameterL |
|
812 // Adds new parser parameter to the parameter array |
|
813 // ----------------------------------------------------------------------------- |
|
814 // |
|
815 void CPIMCardPropertyConverter::AddParserParameterL( |
|
816 CPIMVCardParserParamArray& aArrayOfParams, const TPtrC8 aParamName) |
|
817 { |
|
818 JELOG2(EPim); |
|
819 // Create a new parameter from the name |
|
820 CParserParam* newParam = CParserParam::NewL(aParamName, KNullDesC8); |
|
821 CleanupStack::PushL(newParam); |
|
822 // Add parameter to the param array |
|
823 aArrayOfParams.AppendL(newParam); |
|
824 // newParam is now owned by the parameter array |
|
825 CleanupStack::Pop(newParam); |
|
826 } |
|
827 |
|
828 // ----------------------------------------------------------------------------- |
|
829 // CPIMCardPropertyConverter::ConvertStringPropertyL |
|
830 // Converts a string property from a vCard to a PIM Contact Item |
|
831 // ----------------------------------------------------------------------------- |
|
832 // |
|
833 void CPIMCardPropertyConverter::ConvertStringPropertyL( |
|
834 const CPIMParserProperty& aProperty, // property to convert |
|
835 CPIMContactItem& aItem) // item to insert the field to |
|
836 { |
|
837 JELOG2(EPim); |
|
838 TPIMField field = aProperty.MatchContactField(); |
|
839 TPIMAttribute attributes = KPIMAttrNone; |
|
840 |
|
841 if (field == KErrNotFound) |
|
842 { |
|
843 return; |
|
844 } |
|
845 |
|
846 CParserPropertyValueHBufC* propertyValue = |
|
847 static_cast<CParserPropertyValueHBufC*>(aProperty.Value()); |
|
848 HBufC* value = propertyValue->TakeValueOwnership(); |
|
849 CleanupStack::PushL(value); |
|
850 |
|
851 switch (field) |
|
852 { |
|
853 case EPIMContactUrl: |
|
854 case EPIMContactEmail: |
|
855 // vCard EMAIL does not support PREF |
|
856 { |
|
857 attributes = aProperty.MatchHomeAndWorkAttributes(); |
|
858 break; |
|
859 } |
|
860 case EPIMContactTel: |
|
861 { |
|
862 // Assistant phone is not an attribute in TEL field |
|
863 // it must be handled separately |
|
864 if (aProperty.Name().CompareF(KPIMVersitTokenASSTTEL) == 0) |
|
865 { |
|
866 attributes = EPIMContactAttrAsst; |
|
867 } |
|
868 else |
|
869 { |
|
870 attributes = aProperty.MatchAllAttributes(); |
|
871 } |
|
872 break; |
|
873 } |
|
874 case EPIMContactExtVoip: |
|
875 { |
|
876 // VOIP field can have parameters HOME or WORK |
|
877 attributes = aProperty.MatchHomeAndWorkAttributes(); |
|
878 break; |
|
879 } |
|
880 default: |
|
881 { |
|
882 // no attributes |
|
883 } |
|
884 } |
|
885 aItem.AddStringL(field, attributes, value); |
|
886 CleanupStack::Pop(value); |
|
887 } |
|
888 |
|
889 // ----------------------------------------------------------------------------- |
|
890 // CPIMCardPropertyConverter::ConvertPhotoFieldL |
|
891 // Converts a photo field from a PIM Contact Item to a vCard |
|
892 // ----------------------------------------------------------------------------- |
|
893 // |
|
894 void CPIMCardPropertyConverter::ConvertPhotoFieldL(const CPIMItem& aItem, // item to convert from |
|
895 CParserVCard& aParser, // parser to write to |
|
896 TPIMContactField aField, // field to convert |
|
897 TInt aIndex) // index to the field |
|
898 { |
|
899 JELOG2(EPim); |
|
900 const CPIMByteArray& byteArray = aItem.GetBinaryRawL(aField, aIndex); |
|
901 |
|
902 const TUint8& byteRef = byteArray.At(0); |
|
903 const TUint8* bytePtr = &byteRef; |
|
904 TPtrC8 data(bytePtr, byteArray.Count()); |
|
905 |
|
906 CParserPropertyValue* propertyValue = |
|
907 CParserPropertyValueBinary::NewL(data); |
|
908 AddPropertyToParserL(propertyValue, KVersitTokenPHOTO(), NULL, aParser); |
|
909 // The paramArray and propertyValue are popped by the previous function call |
|
910 } |
|
911 |
|
912 // ----------------------------------------------------------------------------- |
|
913 // CPIMCardPropertyConverter::ConvertPhotoPropertyL |
|
914 // Converts a photo field from a vCard to a PIM Contact Item |
|
915 // ----------------------------------------------------------------------------- |
|
916 // |
|
917 void CPIMCardPropertyConverter::ConvertPhotoPropertyL( |
|
918 const CPIMParserProperty& aProperty, // property to convert |
|
919 CPIMContactItem& aItem) // item to insert the field to |
|
920 { |
|
921 JELOG2(EPim); |
|
922 if (aProperty.Name().CompareF(KVersitTokenPHOTO) != 0) |
|
923 { |
|
924 // Unsupported binary property, silently discarded |
|
925 return; |
|
926 } |
|
927 |
|
928 CParserPropertyValueBinary* propertyValue = |
|
929 static_cast<CParserPropertyValueBinary*>(aProperty.Value()); |
|
930 const CBufSeg* value = propertyValue->Value(); |
|
931 |
|
932 TInt binarySize = value->Size(); |
|
933 CPIMByteArray* byteArray = new(ELeave) CPIMByteArray(binarySize); |
|
934 CleanupStack::PushL(byteArray); |
|
935 byteArray->ResizeL(binarySize); |
|
936 TUint8& byteRef = byteArray->At(0); |
|
937 TUint8* bytePtr = &byteRef; |
|
938 |
|
939 value->Read(0, static_cast<TAny*>(bytePtr), binarySize); |
|
940 |
|
941 aItem.AddBinaryRawL(EPIMContactPhoto, KPIMAttrNone, byteArray); |
|
942 CleanupStack::Pop(byteArray); // byteArray now owned by aItem |
|
943 } |
|
944 |
|
945 // ----------------------------------------------------------------------------- |
|
946 // CPIMCardPropertyConverter::ConvertClassFieldL |
|
947 // Converts a CLASS field from a PIM Contact Item to a vCard |
|
948 // ----------------------------------------------------------------------------- |
|
949 // |
|
950 void CPIMCardPropertyConverter::ConvertClassFieldL(const CPIMItem& aItem, |
|
951 CParserVCard& aParser, TPIMContactField aField, TInt aIndex) |
|
952 { |
|
953 JELOG2(EPim); |
|
954 TInt classIntValue = aItem.getInt(aField, aIndex); |
|
955 TPtrC classStringValue(KPIMClassStringConfidential()); |
|
956 switch (classIntValue) |
|
957 { |
|
958 case EPIMContactClassConfidential: |
|
959 { |
|
960 classStringValue.Set(KPIMClassStringConfidential()); |
|
961 break; |
|
962 } |
|
963 case EPIMContactClassPrivate: |
|
964 { |
|
965 classStringValue.Set(KPIMClassStringPrivate()); |
|
966 break; |
|
967 } |
|
968 case EPIMContactClassPublic: |
|
969 { |
|
970 classStringValue.Set(KPIMClassStringPublic()); |
|
971 break; |
|
972 } |
|
973 default: |
|
974 { |
|
975 __ASSERT_DEBUG(EFalse, User::Invariant()); |
|
976 break; |
|
977 } |
|
978 } |
|
979 CParserPropertyValue* propertyValue = CParserPropertyValueHBufC::NewL( |
|
980 classStringValue); |
|
981 AddPropertyToParserL(propertyValue, KVersitTokenClass(), NULL, aParser); |
|
982 // The paramArray and propertyValue are popped by the previous function call |
|
983 } |
|
984 |
|
985 // ----------------------------------------------------------------------------- |
|
986 // CPIMCardPropertyConverter::ConvertClassPropertyL |
|
987 // Converts CLASS property to a PIM Event item. |
|
988 // ----------------------------------------------------------------------------- |
|
989 // |
|
990 void CPIMCardPropertyConverter::ConvertClassPropertyL( |
|
991 const CPIMParserProperty& aProperty, CPIMContactItem& aItem) |
|
992 { |
|
993 JELOG2(EPim); |
|
994 CParserPropertyValueHBufC* propertyValue = |
|
995 static_cast<CParserPropertyValueHBufC*>(aProperty.Value()); |
|
996 |
|
997 const TPtrC classStringPtr = propertyValue->Value(); |
|
998 TInt classInt = KErrCorrupt; |
|
999 |
|
1000 if (classStringPtr.CompareF(KPIMClassStringPublic) == 0) |
|
1001 { |
|
1002 classInt = EPIMContactClassPublic; |
|
1003 } |
|
1004 else if (classStringPtr.CompareF(KPIMClassStringPrivate) == 0) |
|
1005 { |
|
1006 classInt = EPIMContactClassPrivate; |
|
1007 } |
|
1008 else if (classStringPtr.CompareF(KPIMClassStringConfidential) == 0) |
|
1009 { |
|
1010 classInt = EPIMContactClassConfidential; |
|
1011 } |
|
1012 // else the class value in the originating vCalendar is flawed - ignore |
|
1013 |
|
1014 if (classInt != KErrCorrupt) |
|
1015 { |
|
1016 aItem.addInt(EPIMContactClass, KPIMAttrNone, classInt); |
|
1017 } |
|
1018 } |
|
1019 |
|
1020 // ----------------------------------------------------------------------------- |
|
1021 // CPIMCardPropertyConverter::ConvertOrganisationalFieldsL |
|
1022 // Converts organisational fields from PIM item to CParserVCard |
|
1023 // ----------------------------------------------------------------------------- |
|
1024 // |
|
1025 void CPIMCardPropertyConverter::ConvertOrganisationalFieldsL( |
|
1026 const CPIMItem& aItem, CParserVCard& aParser, TPIMContactField /*aField*/, |
|
1027 TInt /*aIndex*/) |
|
1028 { |
|
1029 JELOG2(EPim); |
|
1030 // Check that the field is not converted twice (e.g one of the |
|
1031 // organisational fields have been already converted and caused |
|
1032 // other field to be converted also |
|
1033 CArrayPtr<CParserProperty>* props = aParser.ArrayOfProperties(EFalse); |
|
1034 if (props) |
|
1035 { |
|
1036 TInt propCount = props->Count(); |
|
1037 for (TInt i = 0; i < propCount; i++) |
|
1038 { |
|
1039 const CParserProperty* property = props->At(i); |
|
1040 if (property->Name().CompareF(KVersitTokenORG) == 0) |
|
1041 { |
|
1042 return; |
|
1043 } |
|
1044 } |
|
1045 } |
|
1046 |
|
1047 // Create array from organisation and department fields |
|
1048 CDesCArray* orgArray = new(ELeave) CDesCArrayFlat(2); |
|
1049 CleanupStack::PushL(orgArray); |
|
1050 if (aItem.CountValuesL(EPIMContactOrg) > 0) |
|
1051 { |
|
1052 const TDesC& org = aItem.GetStringL(EPIMContactOrg, 0); |
|
1053 orgArray->AppendL(org); |
|
1054 } |
|
1055 else |
|
1056 { |
|
1057 orgArray->AppendL(KNullDesC); |
|
1058 } |
|
1059 // Department field is after organisational unit |
|
1060 if (aItem.CountValuesL(EPIMContactExtDepartment) > 0) |
|
1061 { |
|
1062 const TDesC& dep = aItem.GetStringL(EPIMContactExtDepartment, 0); |
|
1063 orgArray->AppendL(dep); |
|
1064 } |
|
1065 else |
|
1066 { |
|
1067 orgArray->AppendL(KNullDesC); |
|
1068 } |
|
1069 |
|
1070 CParserPropertyValue* propertyValue = |
|
1071 new(ELeave) CParserPropertyValueCDesCArray(orgArray); |
|
1072 CleanupStack::Pop(orgArray); // orgArray now owned by propertyValue |
|
1073 AddPropertyToParserL(propertyValue, KVersitTokenORG(), NULL, aParser); |
|
1074 // The paramArray and propertyValue are popped by the previous function call |
|
1075 } |
|
1076 |
|
1077 // ----------------------------------------------------------------------------- |
|
1078 // CPIMCardPropertyConverter::ConvertNameReadingFieldL |
|
1079 // Converts name reading fields from vCard to PIM item |
|
1080 // ----------------------------------------------------------------------------- |
|
1081 // |
|
1082 void CPIMCardPropertyConverter::ConvertNameReadingFieldL( |
|
1083 const CPIMParserProperty& aProperty, CPIMContactItem& aItem) |
|
1084 { |
|
1085 JELOG2(EPim); |
|
1086 TInt nameCount = iContactValidator.NumElementsL(EPIMContactName); |
|
1087 |
|
1088 // Name reading fields come in a HBufC property value although they |
|
1089 // are in an array property value and SHOULD come in as an array. |
|
1090 // So, we have to generate an array property from the HBufC proprety |
|
1091 CParserPropertyValueHBufC* propertyValue = |
|
1092 static_cast<CParserPropertyValueHBufC*>(aProperty.Value()); |
|
1093 HBufC* value = propertyValue->TakeValueOwnership(); |
|
1094 CleanupStack::PushL(value); |
|
1095 // PIM parser to access protected methods |
|
1096 CPIMVCardParser* parser = CPIMVCardParser::NewLC(); |
|
1097 CDesCArray* readingValues = parser->MakePropertyValueCDesCArrayL( |
|
1098 value->Des()); |
|
1099 CleanupStack::PopAndDestroy(2, value); // parser |
|
1100 CleanupStack::PushL(readingValues); |
|
1101 |
|
1102 // Array for the new name elements |
|
1103 CDesCArray* newNameArray = new(ELeave) CDesCArrayFlat(nameCount); |
|
1104 CleanupStack::PushL(newNameArray); |
|
1105 // Old elements exist |
|
1106 if (aItem.CountValuesL(EPIMContactName) > 0) |
|
1107 { |
|
1108 const CDesCArray& nameArray = aItem.GetStringArrayL(EPIMContactName, 0); |
|
1109 for (TInt i = 0; i < nameCount; i++) |
|
1110 { |
|
1111 TPtrC element(nameArray.MdcaPoint(i)); |
|
1112 newNameArray->AppendL(element); |
|
1113 } |
|
1114 // Add array elements. If the array count is larger than zero |
|
1115 // it indicates that at least the Last name reading field is present |
|
1116 if (readingValues->Count() > 0) |
|
1117 { |
|
1118 // Remove old value and add new |
|
1119 newNameArray->Delete(EPIMContactExtFamilyNameReading); |
|
1120 newNameArray->InsertL(EPIMContactExtFamilyNameReading, |
|
1121 readingValues->MdcaPoint(0)); |
|
1122 } |
|
1123 // If the array count is larger than one it indicates that |
|
1124 // the First name reading is also present |
|
1125 if (readingValues->Count() > 1) |
|
1126 { |
|
1127 newNameArray->Delete(EPIMContactExtGivenNameReading); |
|
1128 newNameArray->InsertL(EPIMContactExtGivenNameReading, |
|
1129 readingValues->MdcaPoint(1)); |
|
1130 } |
|
1131 |
|
1132 // Set new string array for the contact name field |
|
1133 aItem.SetStringArrayL(EPIMContactName, 0, KPIMAttrNone, newNameArray); |
|
1134 } |
|
1135 // No old name array |
|
1136 else |
|
1137 { |
|
1138 // Create a new array and append name reading values to it |
|
1139 for (TInt i = 0; i < nameCount; i++) |
|
1140 { |
|
1141 newNameArray->AppendL(KPIMNullArrayElement); |
|
1142 } |
|
1143 // Add array elements. If the array count is larger than zero |
|
1144 // it indicates that at least the Last name reading field is present |
|
1145 if (readingValues->Count() > 0) |
|
1146 { |
|
1147 // Remove old value and add new |
|
1148 newNameArray->Delete(EPIMContactExtFamilyNameReading); |
|
1149 newNameArray->InsertL(EPIMContactExtFamilyNameReading, |
|
1150 readingValues->MdcaPoint(0)); |
|
1151 } |
|
1152 // If the array count is larger than one it indicates that |
|
1153 // the First name reading is also present |
|
1154 if (readingValues->Count() > 1) |
|
1155 { |
|
1156 newNameArray->Delete(EPIMContactExtGivenNameReading); |
|
1157 newNameArray->InsertL(EPIMContactExtGivenNameReading, |
|
1158 readingValues->MdcaPoint(1)); |
|
1159 } |
|
1160 // Add new string array for the cotnact name field |
|
1161 aItem.AddStringArrayL(EPIMContactName, KPIMAttrNone, newNameArray); |
|
1162 } |
|
1163 |
|
1164 CleanupStack::Pop(newNameArray); |
|
1165 CleanupStack::PopAndDestroy(readingValues); |
|
1166 } |
|
1167 |
|
1168 // ----------------------------------------------------------------------------- |
|
1169 // CPIMCardPropertyConverter::AddPropertyToParserL |
|
1170 // adds a new property value to the parser. NOTE that the property value |
|
1171 // ----------------------------------------------------------------------------- |
|
1172 // |
|
1173 void CPIMCardPropertyConverter::AddPropertyToParserL( |
|
1174 CParserPropertyValue* aPropertyValue, const TDesC8& aPropertyName, |
|
1175 CPIMVCardParserParamArray* aArrayOfParams, CParserVCard& aParser) |
|
1176 { |
|
1177 JELOG2(EPim); |
|
1178 // Add property value to the cleanup stack. It should not be added |
|
1179 // before this call. This function is an exception and reduces much code |
|
1180 CleanupStack::PushL(aPropertyValue); |
|
1181 // Create a new parser property from the property value, its name and |
|
1182 // array of parameters. If there are no parameters, the aArrayOfParams |
|
1183 // should be NULL and the parser property will be generated without params |
|
1184 CParserProperty* property = CParserProperty::NewL(*aPropertyValue, |
|
1185 aPropertyName, aArrayOfParams); |
|
1186 // property takes ownership of the property value |
|
1187 CleanupStack::Pop(aPropertyValue); |
|
1188 // Pop aArrayOfParams if it is not NULL |
|
1189 if (aArrayOfParams) |
|
1190 { |
|
1191 CleanupStack::Pop(aArrayOfParams); |
|
1192 } |
|
1193 // NOTE: property MUST not be pushed to the cleanup stack since the |
|
1194 // AddPropertyL pushes it right away to the cleanup stack. So, we must not |
|
1195 // push it here to avoid duplicate stack pointers |
|
1196 aParser.AddPropertyL(property); |
|
1197 // Property is now owned by the parser but we do not have to pop it |
|
1198 } |
|
1199 |
|
1200 // End of file |