|
1 // Copyright (c) 2006-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 "agsfileconverter.h" |
|
17 |
|
18 #include <s32file.h> |
|
19 #include <apparc.h> |
|
20 #include <asshddefs.h> |
|
21 #include <txtrich.h> |
|
22 #include <vtzrules.h> |
|
23 |
|
24 #include "agscategorylist.h" |
|
25 #include "agsentrymanager.h" |
|
26 #include "agmcontent.h" |
|
27 #include "agmdate.h" |
|
28 #include "agmentry.h" |
|
29 #include "agsentrymodel.h" |
|
30 #include "agsstreamidset.h" |
|
31 #include "agmutil.h" |
|
32 #include "agsver.h" |
|
33 #include "agmcategory.h" |
|
34 #include "agmattendee.h" |
|
35 #include "agsfilemanager.h" |
|
36 #include "agsmain.h" |
|
37 #include "calcommonimpl.h" |
|
38 #include "agstzruleindex.h" |
|
39 |
|
40 const TInt KMajorVersionNumber = 1; |
|
41 const TInt KMinorVersionNumber = 2; |
|
42 |
|
43 const TInt KBuildNumber = 2; // Build 1.2.2 is current build |
|
44 const TInt KBuildCompatibleVersion = 1; |
|
45 // |
|
46 const TInt KOldMinorVersionNumber = 1; |
|
47 const TInt KOldBuildV94 = 211; // build 1.1.211 is v9.4 compacted version |
|
48 const TInt KOldBuildV92 = 210; // build 1.1.210 is v9.2 |
|
49 const TInt KOldBuildV91 = 209; // build 1.1.209 is v9.1 |
|
50 // build 1.1.208 is v8.0 and v8.1 |
|
51 // build 1.1.207 is 6.0 & 6.1 (prior builds 204-206 were dev releases) |
|
52 |
|
53 // ---------------------------- CalFileVersionUtils ------------------------- |
|
54 |
|
55 CAgnCalendarConverter* CalFileVersionUtils::CreateConverterL(const TAgnVersion& aFileVersion, CAgnServFile& aAgnServerFile) |
|
56 /** @internalComponent */ |
|
57 { |
|
58 CAgnCalendarConverter* converter = NULL; |
|
59 |
|
60 if (aFileVersion == TAgnVersion(TVersion(KMajorVersionNumber, KOldMinorVersionNumber, KOldBuildV91))) |
|
61 { |
|
62 // file format 1.1.209 used in 9.1 |
|
63 converter = CAgnCalendarConverter209::NewL(aAgnServerFile); |
|
64 } |
|
65 else if (aFileVersion == TAgnVersion(TVersion(KMajorVersionNumber, KOldMinorVersionNumber, KOldBuildV92))) |
|
66 { |
|
67 // file format 1.1.210 used in 9.2 |
|
68 converter = CAgnCalendarConverter210::NewL(aAgnServerFile); |
|
69 } |
|
70 else if (aFileVersion == TAgnVersion(TVersion(KMajorVersionNumber, KOldMinorVersionNumber, KOldBuildV94))) |
|
71 { |
|
72 // file format 1.1.211 used in 9.4 compacted file version |
|
73 converter = CAgnCalendarConverter211::NewL(aAgnServerFile); |
|
74 } |
|
75 else if (aFileVersion == CurrentFileVersion() ) |
|
76 { |
|
77 converter = NULL; |
|
78 } |
|
79 else |
|
80 { |
|
81 User::Leave(KErrNotSupported); |
|
82 } |
|
83 |
|
84 return converter; |
|
85 } |
|
86 |
|
87 void CalFileVersionUtils::FileVersionSupportedL(const TAgnVersion& aFileVersion, CalCommon::TCalFileVersionSupport& aStatus) |
|
88 { |
|
89 if ( aFileVersion == CurrentFileVersion() || |
|
90 aFileVersion == TAgnVersion(TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildCompatibleVersion))) |
|
91 { |
|
92 // The the file was created by an agenda model |
|
93 // of the current version |
|
94 // |
|
95 aStatus = CalCommon::EFileIsCurrentVersion; |
|
96 } |
|
97 else |
|
98 { |
|
99 RArray<TAgnVersion> supportedFileVersions; |
|
100 CleanupClosePushL(supportedFileVersions); |
|
101 supportedFileVersions.AppendL(TAgnVersion(TVersion(KMajorVersionNumber, KOldMinorVersionNumber, KOldBuildV94))); |
|
102 supportedFileVersions.AppendL(TAgnVersion(TVersion(KMajorVersionNumber, KOldMinorVersionNumber, KOldBuildV92))); |
|
103 supportedFileVersions.AppendL(TAgnVersion(TVersion(KMajorVersionNumber, KOldMinorVersionNumber, KOldBuildV91))); |
|
104 |
|
105 // The file version is not current but if it is in the |
|
106 // list of versions supported by this agenda model it can |
|
107 // be converted to current version. |
|
108 // |
|
109 aStatus = CalCommon::EUnsupportedFileVersion; |
|
110 for ( TInt i = 0; i < supportedFileVersions.Count(); ++i ) |
|
111 { |
|
112 if ( supportedFileVersions[i] == aFileVersion ) |
|
113 { |
|
114 aStatus = CalCommon::EFileNeedsConverting; |
|
115 break; |
|
116 } |
|
117 } |
|
118 CleanupStack::PopAndDestroy(&supportedFileVersions); |
|
119 } |
|
120 } |
|
121 |
|
122 TAgnVersion CalFileVersionUtils::CurrentFileVersion() |
|
123 { |
|
124 return (TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildNumber)); |
|
125 } |
|
126 |
|
127 // ---------------------------- CAgnCalendarConverter ------------------------- |
|
128 |
|
129 CAgnCalendarConverter::CAgnCalendarConverter() |
|
130 { |
|
131 } |
|
132 |
|
133 CAgnCalendarConverter::~CAgnCalendarConverter() |
|
134 /** @internalComponent */ |
|
135 { |
|
136 if(iOutputTzRuleIndex) |
|
137 { |
|
138 delete iOutputTzRuleIndex; |
|
139 } |
|
140 |
|
141 delete iDictionary; |
|
142 delete iOutputStreamStore; |
|
143 delete iOutModelStreamIdSet; |
|
144 delete iOutEntryManager; |
|
145 } |
|
146 |
|
147 void CAgnCalendarConverter::ConstructL(CAgnServFile& aAgnServerFile) |
|
148 /** @internalComponent */ |
|
149 { |
|
150 iOutModelStreamIdSet = CAgnModelStreamIdSet::NewL(); |
|
151 iOutEntryManager = CAgnEntryManager::NewL(); |
|
152 iAgnServerFile = &aAgnServerFile; |
|
153 |
|
154 // Get the original (old version) stream store from the CAgnServFile |
|
155 // |
|
156 iInputStreamStore = iAgnServerFile->StoreL(); |
|
157 __ASSERT_ALWAYS(iInputStreamStore, User::Leave(KErrCorrupt)); |
|
158 |
|
159 // Create the output stream store |
|
160 // |
|
161 TParsePtrC fullFileName(iAgnServerFile->FileName()); |
|
162 HBufC* fileName = HBufC::NewLC(fullFileName.Drive().Length() + |
|
163 fullFileName.NameAndExt().Length() + |
|
164 KUpdatedAgendaFileExtension().Length()); |
|
165 TPtr fileNamePtr(fileName->Des()); |
|
166 fileNamePtr.Append(fullFileName.Drive()); |
|
167 fileNamePtr.Append(fullFileName.NameAndExt()); |
|
168 fileNamePtr.Append(KUpdatedAgendaFileExtension); |
|
169 |
|
170 // Create the output stream store where converted information will be kept |
|
171 // This code copied from CAgnServerSession::CreateAgendaFileL() and CAgnEntryModel::CreateL(CStreamStore& aStore) |
|
172 // |
|
173 iOutputStreamStore = iAgnServerFile->Server().FileMgr()->CreateAgendaFileLC(fileNamePtr); |
|
174 CleanupStack::Pop(iOutputStreamStore); |
|
175 CleanupStack::PopAndDestroy(fileName); |
|
176 iOutputStreamStore->SetTypeL(TUidType(KPermanentFileStoreLayoutUid, KUidAppDllDoc, KUidAgnApp)); |
|
177 |
|
178 iOutEntryManager->SetStore(*iOutputStreamStore); |
|
179 |
|
180 // Create the network of stream Ids needed by the model |
|
181 TStreamId headstreamId = iOutModelStreamIdSet->CreateL(*iOutputStreamStore, CalFileVersionUtils::CurrentFileVersion()); |
|
182 |
|
183 // Create the stream dictionary for iOutputStreamStore and keep headstreamId in it |
|
184 // |
|
185 iDictionary = CStreamDictionary::NewL(); |
|
186 iDictionary->AssignL(KUidAgnModel, headstreamId); |
|
187 |
|
188 // Set stream dictionary in stream store |
|
189 TApaAppIdentifier dummyApp(KUidAgnModel, KNullDesC()); |
|
190 CApaProcess::WriteRootStreamL(*iOutputStreamStore,*iDictionary, dummyApp); |
|
191 |
|
192 iOutputTzRuleIndex = CAgnTzRuleIndex::NewL(*iDictionary, *iOutputStreamStore); |
|
193 } |
|
194 |
|
195 CFileStore& CAgnCalendarConverter::InputStreamStore() const |
|
196 { |
|
197 return *iInputStreamStore; |
|
198 } |
|
199 |
|
200 CFileStore& CAgnCalendarConverter::OutputStreamStore() const |
|
201 { |
|
202 return *iOutputStreamStore; |
|
203 } |
|
204 |
|
205 CAgnServFile& CAgnCalendarConverter::AgnServerFile() const |
|
206 { |
|
207 return *iAgnServerFile; |
|
208 } |
|
209 |
|
210 CStreamDictionary& CAgnCalendarConverter::Dictionary() const |
|
211 { |
|
212 return *iDictionary; |
|
213 } |
|
214 |
|
215 void CAgnCalendarConverter::AddToIndexL(CAgnEntry& aEntry) const |
|
216 { |
|
217 iAgnServerFile->Model()->UpdateIndexL(aEntry, NULL, CAgnEntryModel::EAdd); |
|
218 } |
|
219 |
|
220 void CAgnCalendarConverter::SetNextLocalUidValue(TInt aValue) const |
|
221 { |
|
222 iAgnServerFile->Model()->iNextLocalUidValue = aValue; |
|
223 } |
|
224 |
|
225 void CAgnCalendarConverter::SetModelStreamIds(const TAgnVersion& aVersion, |
|
226 const TStreamId& aEntrySetStreamId, |
|
227 const TStreamId& aNextLocalUidValueStreamId, |
|
228 const TStreamId& aEntryManagerStreamId, |
|
229 const TStreamId& aFileInformationStreamId, |
|
230 CAgnModelStreamIdSet& aModelStreamIdSet) const |
|
231 { |
|
232 aModelStreamIdSet.iVersion = aVersion; |
|
233 aModelStreamIdSet.iEntrySetStreamId = aEntrySetStreamId; |
|
234 aModelStreamIdSet.iNextLocalUidValueStreamId = aNextLocalUidValueStreamId; |
|
235 aModelStreamIdSet.iEntryManagerStreamId = aEntryManagerStreamId; |
|
236 aModelStreamIdSet.iFileInformationStreamId = aFileInformationStreamId; |
|
237 } |
|
238 |
|
239 /** |
|
240 This method is executed as the last step of a calendar file conversion. |
|
241 Externalizes to the new file store the new CAgnEntryManager and CAgnModelStreamIdSet. |
|
242 Calls ReplaceAgendaFile() to update the Model and its ServerFile with the products of the |
|
243 conversion. |
|
244 @internalComponent */ |
|
245 void CAgnCalendarConverter::CompleteConversionL() |
|
246 { |
|
247 // Copy iFileId and iNextUniqueIdValue to the Converter's output stream store |
|
248 // |
|
249 iAgnServerFile->Model()->ExternalizeFileIdL(*iOutputStreamStore, iOutModelStreamIdSet->FileInformationStreamId()); |
|
250 iAgnServerFile->Model()->ExternalizeNextUidValuesL(*iOutputStreamStore, iOutModelStreamIdSet->NextLocalUidValueStreamId()); |
|
251 iOutputStreamStore->CommitL(); |
|
252 |
|
253 // Commit the streamIdSet and the EntryManager to the output store |
|
254 // |
|
255 RStoreWriteStream stream; |
|
256 stream.ReplaceLC(*iOutputStreamStore,iOutModelStreamIdSet->EntryManagerStreamId()); |
|
257 stream << *iOutEntryManager; |
|
258 stream.CommitL(); |
|
259 CleanupStack::PopAndDestroy(); |
|
260 |
|
261 iOutModelStreamIdSet->CommitL(*iOutputStreamStore); |
|
262 iOutputStreamStore->CommitL(); |
|
263 |
|
264 delete iDictionary; |
|
265 iDictionary = NULL; |
|
266 delete iOutputStreamStore; |
|
267 iOutputStreamStore = NULL; |
|
268 |
|
269 // Set new calendar file and dictionary in CAgnServFile |
|
270 // (this deletes the old file, and hands over the ownership of iOutputTzRuleIndex) |
|
271 // |
|
272 iAgnServerFile->ReplaceConvertedAgendaFileL(*iOutEntryManager, *iOutputTzRuleIndex); |
|
273 iOutputTzRuleIndex = NULL; |
|
274 } |
|
275 |
|
276 /** |
|
277 This method stores in CAgnCalendarConverter::iOutputStreamStore the entry that has been internalized |
|
278 from an old version file. |
|
279 |
|
280 The persistence layer objects owned by the CAgnCalendarConverter (iOutEntryManager and iOutModelStreamIdSet) |
|
281 will also be updated to register the new entry. |
|
282 @internalComponent */ |
|
283 void CAgnCalendarConverter::SaveRestoredEntryL(CAgnEntry& aEntry) const |
|
284 { |
|
285 |
|
286 // Externalize outline attributes first |
|
287 TStreamId id = KNullStreamId; |
|
288 RStoreWriteStream out; |
|
289 |
|
290 id = WriteDescriptorToStreamL(aEntry.Description()); |
|
291 aEntry.SetDescriptionStreamId(id); |
|
292 |
|
293 id = WriteDescriptorToStreamL(aEntry.Summary()); |
|
294 aEntry.SetSummaryStreamId(id); |
|
295 |
|
296 if(aEntry.AlarmAction()) |
|
297 { |
|
298 RStoreWriteStream out; |
|
299 id = out.CreateLC(*iOutputStreamStore); |
|
300 out << *aEntry.AlarmAction(); |
|
301 out.CommitL(); |
|
302 CleanupStack::PopAndDestroy(); //out |
|
303 aEntry.SetAlarmActionStreamId(id); |
|
304 } |
|
305 |
|
306 iOutputTzRuleIndex->AddTzRuleL(aEntry); |
|
307 TStreamId newStreamId = iOutEntryManager->AddEntryL(aEntry); // This changes the entry/instance ID |
|
308 |
|
309 if (newStreamId != KNullStreamId) |
|
310 { |
|
311 // This puts the stream id in the array but doesn't commit it |
|
312 // To reduce file acces, the ModelStreamIdSet is only commited when all |
|
313 // the entries have been converted. |
|
314 iOutModelStreamIdSet->EntryStreamIdSet().AddL(newStreamId); |
|
315 } |
|
316 } |
|
317 |
|
318 TStreamId CAgnCalendarConverter::WriteDescriptorToStreamL(const TDesC& aString) const |
|
319 /** @internalComponent */ |
|
320 { |
|
321 if (aString.Length() > 0) |
|
322 { |
|
323 RStoreWriteStream out; |
|
324 TStreamId id = out.CreateLC(*iOutputStreamStore); |
|
325 out.WriteUint32L(aString.Length()); |
|
326 out << aString; |
|
327 out.CommitL(); |
|
328 CleanupStack::PopAndDestroy(); //out |
|
329 return id; |
|
330 } |
|
331 return KNullStreamId; |
|
332 } |
|
333 |
|
334 // CAgnCalendarConverter209 // |
|
335 |
|
336 CAgnCalendarConverter209::CAgnCalendarConverter209() |
|
337 { |
|
338 } |
|
339 |
|
340 CAgnCalendarConverter209* CAgnCalendarConverter209::NewL(CAgnServFile& aAgnServerFile) |
|
341 { |
|
342 CAgnCalendarConverter209* converter = new (ELeave) CAgnCalendarConverter209(); |
|
343 CleanupStack::PushL(converter); |
|
344 converter->ConstructL(aAgnServerFile); |
|
345 CleanupStack::Pop(converter); |
|
346 return converter; |
|
347 } |
|
348 |
|
349 void CAgnCalendarConverter209::InternalizeEntriesL(RReadStream& aStream) |
|
350 /** @internalComponent */ |
|
351 { |
|
352 // The layout of the calendar file in 1.1.x puts a set of calendar entries first, followed by their |
|
353 // extended data. For this reason, the entire set must be loaded into memory before they can be stored. |
|
354 RPointerArray<CAgnEntry> entryArray(TAgnEntryId::EMaxNumEntriesPerStream); |
|
355 CleanupResetAndDestroyPushL(entryArray); |
|
356 |
|
357 RArray<TBool> isExtendedArray; |
|
358 CleanupClosePushL(isExtendedArray); |
|
359 |
|
360 const TUint8 KCount = aStream.ReadUint8L(); |
|
361 for ( TInt ii = 0; ii < KCount; ++ii ) |
|
362 { |
|
363 // Read in entries |
|
364 TBool isExtended = EFalse; |
|
365 CAgnEntry* entry = InternalizeEntryL(aStream, isExtended); |
|
366 CleanupStack::PushL(entry); |
|
367 entryArray.AppendL(entry); |
|
368 CleanupStack::Pop(entry); |
|
369 |
|
370 isExtendedArray.AppendL(isExtended); // isExtended is set to ETrue if the entry has extended data (to be loaded later) |
|
371 } |
|
372 |
|
373 for ( TInt i = 0; i < KCount; ++i ) |
|
374 { |
|
375 // Now read in the extended attributes if necessary |
|
376 if (isExtendedArray[i]) |
|
377 { |
|
378 InternalizeExtendedEntryL(aStream, *entryArray[i]); |
|
379 } |
|
380 |
|
381 // The old aEntry has been internalized, so add it to the current version of the file |
|
382 SaveRestoredEntryL(*entryArray[i]); |
|
383 |
|
384 // add this entry to the index |
|
385 AddToIndexL(*entryArray[i]); |
|
386 } |
|
387 |
|
388 CleanupStack::PopAndDestroy(&isExtendedArray); |
|
389 CleanupStack::PopAndDestroy(&entryArray); |
|
390 } |
|
391 |
|
392 void CAgnCalendarConverter209::InternalizeNextUidValuesL(RReadStream& aStream) |
|
393 { |
|
394 SetNextLocalUidValue(aStream.ReadUint32L()); |
|
395 } |
|
396 |
|
397 /** |
|
398 This method internalizes the CAgnModelStreamIdSet according to the file version. |
|
399 It also copies to the Converter's own stream store the contents of |
|
400 aModelStreamIdSet's streams that must be preserved |
|
401 during the conversion: iNextUniqueIdValue and iFileId. |
|
402 |
|
403 (Currently, it works for both 9.1 and 9.2 to 9.3) |
|
404 @internalComponent */ |
|
405 void CAgnCalendarConverter209::InternalizeModelStreamIdSetL(RReadStream& aStream, CAgnModelStreamIdSet& aModelStreamIdSet) |
|
406 { |
|
407 // 9.2/9.1 was: 9.3 is: |
|
408 // iVersion iVersion |
|
409 // iTodoListListStreamId |
|
410 // iDeletedTodoListListStreamId |
|
411 // iEntrySetStreamId iEntrySetStreamId |
|
412 // iFormatLayerStreamId |
|
413 // iNextLocalUidValueStreamId iNextLocalUidValueStreamId |
|
414 // iObserverControllerStreamId |
|
415 // iLastSynchronizedDateStreamId |
|
416 // iEntryStoreStreamId iEntryManagerStreamId |
|
417 // iFileInformationStreamId iFileInformationStreamId |
|
418 |
|
419 // Get the 9.1/9.2 bytes. Those that exit in 9.3, set them in the CAgnModelStreamIdSet. |
|
420 // Skip the rest. |
|
421 TStreamId disposableStreamId; |
|
422 |
|
423 TAgnVersion version; |
|
424 aStream >> version; |
|
425 |
|
426 //Skip: iTodoListStreamId, iDeletedTodoListListStreamId |
|
427 aStream >> disposableStreamId; |
|
428 aStream >> disposableStreamId; |
|
429 |
|
430 TStreamId entrySetStreamId; |
|
431 aStream >> entrySetStreamId; |
|
432 |
|
433 //Skip: iFormatLayerStreamId |
|
434 aStream >> disposableStreamId; |
|
435 |
|
436 TStreamId nextLocalUidValueStreamId; |
|
437 aStream >> nextLocalUidValueStreamId; |
|
438 |
|
439 //Skip: iObserverControllerStreamId, iLastSynchronizedDateStreamId; |
|
440 aStream >> disposableStreamId; |
|
441 aStream >> disposableStreamId; |
|
442 |
|
443 TStreamId entryManagerStreamId; |
|
444 aStream >> entryManagerStreamId; |
|
445 |
|
446 TStreamId fileInformationStreamId; |
|
447 aStream >> fileInformationStreamId; |
|
448 |
|
449 SetModelStreamIds(version, entrySetStreamId, nextLocalUidValueStreamId, entryManagerStreamId, fileInformationStreamId, aModelStreamIdSet); |
|
450 } |
|
451 |
|
452 /** |
|
453 Categories have not changed from 9.1 to 9.3. |
|
454 Just copy them from the original file to the new file. |
|
455 |
|
456 @internalComponent */ |
|
457 void CAgnCalendarConverter209::InternalizeCategoriesL() |
|
458 { |
|
459 TStreamId streamId = AgnServerFile().WriteCategoryListL(OutputStreamStore()); |
|
460 AgnServerFile().AddStreamToDictionaryL(KUidAgnCategoryList, streamId, Dictionary(), OutputStreamStore()); |
|
461 } |
|
462 |
|
463 CAgnEntry* CAgnCalendarConverter209::InternalizeEntryL(RReadStream& aStream, TBool& aHasExtended) |
|
464 { |
|
465 enum TAgnEntryTypeV9192 // the entry type enumeration in v9.1 and v9.2 |
|
466 { |
|
467 EAgnAppt, |
|
468 EAgnTodo, |
|
469 EAgnEvent, |
|
470 EAgnAnniv |
|
471 }; |
|
472 |
|
473 const TInt KAgnExtendedDataFlag = 0x80; |
|
474 // Remove 9.1's/9.2's KAgnExtendedDataFlag (0x80) |
|
475 // from the entry type |
|
476 // |
|
477 TUint8 typeData = aStream.ReadUint8L(); |
|
478 |
|
479 if (typeData & KAgnExtendedDataFlag) |
|
480 { |
|
481 const TUint8 KVersion = aStream.ReadUint8L(); |
|
482 __ASSERT_ALWAYS(KVersion !=0, User::Leave(KErrCorrupt)); //version mumbers started from 1 |
|
483 if (KVersion > 1) |
|
484 { |
|
485 const TUint8 KLength = aStream.ReadUint8L(); |
|
486 for (TInt i=0; i<KLength; ++i) |
|
487 { |
|
488 aStream.ReadUint8L(); //skip additional data becouse we don't support it yet |
|
489 } |
|
490 } |
|
491 typeData &= ~KAgnExtendedDataFlag; |
|
492 } |
|
493 |
|
494 const TAgnEntryTypeV9192 KV9192Type = static_cast<TAgnEntryTypeV9192>(typeData); |
|
495 |
|
496 CCalEntry::TType entryType = CCalEntry::EAppt; |
|
497 |
|
498 TAgnEntryId entryId; |
|
499 entryId.InternalizeL(aStream); //TUInt32 iId |
|
500 TUint16 attributes = aStream.ReadUint16L(); |
|
501 |
|
502 switch (KV9192Type) |
|
503 { |
|
504 case EAgnAppt: |
|
505 if (attributes & EBit9) |
|
506 { |
|
507 entryType = CCalEntry::EReminder; // is a day note |
|
508 } |
|
509 else |
|
510 { |
|
511 entryType = CCalEntry::EAppt; |
|
512 } |
|
513 break; |
|
514 case EAgnAnniv: |
|
515 entryType = CCalEntry::EAnniv; |
|
516 break; |
|
517 case EAgnEvent: |
|
518 entryType = CCalEntry::EEvent; |
|
519 break; |
|
520 case EAgnTodo: |
|
521 entryType = CCalEntry::ETodo; |
|
522 break; |
|
523 default: |
|
524 User::Leave(KErrCorrupt); |
|
525 } |
|
526 |
|
527 if (attributes & EBit13) |
|
528 { |
|
529 aHasExtended = ETrue; |
|
530 } |
|
531 else |
|
532 { |
|
533 aHasExtended = EFalse; |
|
534 } |
|
535 |
|
536 CCalEntry::TStatus status = CCalEntry::ENullStatus; |
|
537 // Get status from attributes' bits |
|
538 // |
|
539 if (attributes & (EBit14 | EBit15 | EBit16)) |
|
540 { |
|
541 // Bits 14,15,16 on. |
|
542 status = CCalEntry::EVCalDelegated; |
|
543 } |
|
544 else if (attributes & (EBit14 | EBit15)) |
|
545 { |
|
546 // Bits 14, 15 on |
|
547 if (entryType == CCalEntry::ETodo) |
|
548 { |
|
549 status = CCalEntry::ETodoCompleted; |
|
550 } |
|
551 } |
|
552 else if (attributes & (EBit14 | EBit16)) |
|
553 { |
|
554 //Bits 14,16 on |
|
555 status = CCalEntry::EVCalDeclined; |
|
556 } |
|
557 else if (attributes & (EBit15 | EBit16)) |
|
558 { |
|
559 // Bits 15, 16 on |
|
560 status = CCalEntry::EVCalSent; |
|
561 } |
|
562 else if (attributes & EBit14) |
|
563 { |
|
564 if (entryType != CCalEntry::ETodo) |
|
565 { |
|
566 status = CCalEntry::EConfirmed; |
|
567 } |
|
568 } |
|
569 else if (attributes & EBit15) |
|
570 { |
|
571 status = CCalEntry::EVCalNeedsAction; |
|
572 } |
|
573 else if (attributes & EBit16) |
|
574 { |
|
575 status = CCalEntry::EVCalAccepted; |
|
576 } |
|
577 else if(attributes & EBit11) |
|
578 { |
|
579 if (entryType != CCalEntry::ETodo) |
|
580 { |
|
581 status = CCalEntry::ETentative; |
|
582 } |
|
583 } |
|
584 |
|
585 // read GS data |
|
586 enum TGsTypeV9192 |
|
587 { |
|
588 /** Not a GS Entry (created using AgnModel APIs directly, not CalInterimAPI. */ |
|
589 ENonGsEntry, |
|
590 /** Parent Entry. */ |
|
591 EGsRootParent, |
|
592 /** Not used. */ |
|
593 EGsParent, |
|
594 /** Child Entry. */ |
|
595 EGsLeaf |
|
596 }; |
|
597 |
|
598 CAgnEntry* entry = NULL; |
|
599 |
|
600 const TGsTypeV9192 KCalTypeV9192 = static_cast<TGsTypeV9192> (aStream.ReadInt8L()); |
|
601 switch (KCalTypeV9192) |
|
602 { |
|
603 case EGsRootParent: |
|
604 { |
|
605 aStream.ReadUint32L(); // ignore guid hash |
|
606 HBufC8* guid = HBufC8::NewLC(aStream, KAgnEntryMaxGuidLength); |
|
607 |
|
608 aStream.ReadInt8L(); // read other class type |
|
609 |
|
610 entry = CAgnEntry::NewL(entryType, guid, CCalEntry::EMethodNone, 0); // dummy values for method and sequence number |
|
611 CleanupStack::Pop(guid); |
|
612 CleanupStack::PushL(entry); |
|
613 |
|
614 TAgnCalendarTime recurId; |
|
615 |
|
616 const TInt KCount = aStream.ReadInt32L(); |
|
617 for (TInt i = 0; i < KCount; ++i) |
|
618 { |
|
619 TCalLocalUid childId = aStream.ReadUint32L(); |
|
620 aStream >> recurId; |
|
621 |
|
622 TGsChildRefData childData(childId, recurId); |
|
623 entry->AddChildIdL(childData); |
|
624 } |
|
625 |
|
626 // set correct value for method and sequence number |
|
627 TInt32 seqNum = aStream.ReadInt32L(); |
|
628 entry->SetSequenceNumber(seqNum); |
|
629 |
|
630 CCalEntry::TMethod method = static_cast<CCalEntry::TMethod> (aStream.ReadInt8L()); |
|
631 entry->SetMethod(method); |
|
632 |
|
633 aStream.ReadUint32L(); // parent ID (Null for a parent) |
|
634 } |
|
635 break; |
|
636 |
|
637 case EGsLeaf: |
|
638 { |
|
639 TInt32 seqNum = aStream.ReadInt32L(); |
|
640 CCalEntry::TMethod method = static_cast<CCalEntry::TMethod> (aStream.ReadInt8L()); |
|
641 TCalLocalUid parentId = aStream.ReadUint32L(); |
|
642 |
|
643 entry = CAgnEntry::NewL(entryType, NULL, method, seqNum, TAgnCalendarTime(), CalCommon::EThisOnly); |
|
644 CleanupStack::PushL(entry); |
|
645 entry->SetParentId(parentId); |
|
646 } |
|
647 break; |
|
648 |
|
649 case EGsParent: // fall through |
|
650 case ENonGsEntry: |
|
651 // this is a non-GS entry, get the GUID from the unique ID, entry == NULL |
|
652 break; |
|
653 |
|
654 default: |
|
655 { |
|
656 User::Leave(KErrCorrupt); |
|
657 } |
|
658 } |
|
659 |
|
660 // Read in entry's unique Id |
|
661 // |
|
662 TCalLocalUid localUid; |
|
663 aStream >> localUid; |
|
664 |
|
665 // create entry now we have all the information |
|
666 |
|
667 if (!entry) // create non-GS entry from unique ID |
|
668 { |
|
669 TBuf8<32> uniqueIdBuf; |
|
670 uniqueIdBuf.AppendNum(localUid); |
|
671 HBufC8* guid = uniqueIdBuf.AllocLC(); |
|
672 entry = CAgnEntry::NewL(entryType, guid, CCalEntry::EMethodNone, 0); |
|
673 CleanupStack::Pop(guid); |
|
674 CleanupStack::PushL(entry); |
|
675 } |
|
676 |
|
677 entry->SetStatus(status); |
|
678 entry->SetLocalUid(localUid); |
|
679 |
|
680 // TReplicationData was next in 9.1/9.2, with the following data: |
|
681 // TStatus iStatus; |
|
682 // TBool iHasBeenDeleted; |
|
683 // TUint iCount; |
|
684 // TAgnCalendarTime iLastChangedDateUtc |
|
685 // |
|
686 entry->SetReplicationStatusL(static_cast<CCalEntry::TReplicationStatus>(aStream.ReadInt8L())); |
|
687 |
|
688 TBool hasBeenDeleted = aStream.ReadUint8L();// Not used in 9.3 but checked later |
|
689 aStream.ReadUint8L();//skip iCount |
|
690 TAgnCalendarTime lastChangedDate; |
|
691 aStream >> lastChangedDate; |
|
692 entry->SetLastModifiedDateUtc(lastChangedDate.UtcL()); |
|
693 |
|
694 // CAgnRptDef |
|
695 // |
|
696 // In 9.1/9.2, the second bit of the 'attributes' |
|
697 // indicates presence/absence of a repeat definition |
|
698 // |
|
699 CArrayFixFlat<TAgnCalendarTime>* exceptions = NULL; |
|
700 if (attributes & EBit2) |
|
701 { |
|
702 exceptions = InternalizeRptDefL(aStream, *entry); |
|
703 } |
|
704 |
|
705 TInt32 alarmPreTime = InternalizeAlarmL(aStream, attributes, *entry); |
|
706 InternalizeSummaryL(aStream, hasBeenDeleted, *entry); |
|
707 InternalizeTypeSpecificDataL(aStream, attributes, *entry); |
|
708 AddExceptionsL(*entry, exceptions); // must add exceptions after start date has been set |
|
709 delete exceptions; |
|
710 |
|
711 // if the entry is floating, the until date must be converted to a floating TAgnCalendarTime |
|
712 if (entry->TimeMode() == MAgnCalendarTimeMode::EFloating) |
|
713 { |
|
714 if (entry->RptDef() && entry->RptDef()->RRule()) |
|
715 { |
|
716 if (AgnDateTime::IsValidAgendaTTime(entry->RptDef()->RRule()->UntilTimeL().UtcL())) |
|
717 { |
|
718 TAgnCalendarTime agnUntilTime; |
|
719 agnUntilTime.SetFloatingL(entry->RptDef()->RRule()->UntilTimeL().UtcL()); |
|
720 entry->RptDef()->SetUntilTime(agnUntilTime); |
|
721 } |
|
722 } |
|
723 } |
|
724 |
|
725 // if the entry has an alarm, calculate the offset from the pretime used in v9.1/v9.2 |
|
726 if (alarmPreTime != KMaxTInt32) |
|
727 { |
|
728 if (KV9192Type == EAgnTodo) |
|
729 { |
|
730 entry->SetAlarmOffset(CalculateAlarmOffsetL(alarmPreTime, entry->EndTime().LocalL())); |
|
731 } |
|
732 else |
|
733 { |
|
734 entry->SetAlarmOffset(CalculateAlarmOffsetL(alarmPreTime, entry->StartTime().LocalL())); |
|
735 } |
|
736 } |
|
737 |
|
738 CleanupStack::Pop(entry); |
|
739 |
|
740 return entry; |
|
741 } |
|
742 |
|
743 CArrayFixFlat<TAgnCalendarTime>* CAgnCalendarConverter209::InternalizeRptDefL(RReadStream& aStream, CAgnEntry& aEntry) const |
|
744 { |
|
745 CAgnRptDef* rptDef = CAgnRptDef::NewL(aEntry); |
|
746 CleanupStack::PushL(rptDef); |
|
747 |
|
748 InternalizeRepeatRuleL(aStream, *rptDef); |
|
749 CArrayFixFlat<TAgnCalendarTime>* exceptions = InternalizeExceptionsL(aStream); |
|
750 CleanupStack::PushL(exceptions); |
|
751 InternalizeSporadicDatesL(aStream, *rptDef); |
|
752 |
|
753 InternalizeTimeZoneL(aStream, *rptDef); |
|
754 |
|
755 aStream.ReadUint8L(); // ignore show next only |
|
756 |
|
757 aEntry.SetRptDefL(*rptDef); |
|
758 |
|
759 CleanupStack::Pop(exceptions); |
|
760 CleanupStack::PopAndDestroy(rptDef); |
|
761 return exceptions; |
|
762 } |
|
763 |
|
764 void CAgnCalendarConverter209::AddExceptionsL(CAgnEntry& aEntry, CArrayFixFlat<TAgnCalendarTime>* aExceptions) const |
|
765 { |
|
766 // must add exceptions after sporadic dates |
|
767 if (aExceptions && aEntry.RptDef()) |
|
768 { |
|
769 const TInt KCount = aExceptions->Count(); |
|
770 if (KCount > 0) |
|
771 { |
|
772 for (TInt i = 0; i < KCount; ++i) |
|
773 { |
|
774 aEntry.RptDef()->AddExceptionL((*aExceptions)[i]); |
|
775 } |
|
776 } |
|
777 } |
|
778 } |
|
779 |
|
780 void CAgnCalendarConverter209::InternalizeRepeatRuleL(RReadStream& aStream, CAgnRptDef& aRptDef) const |
|
781 { |
|
782 TBool hasRepeatRule = aStream.ReadUint8L(); |
|
783 |
|
784 // TAgnRpt |
|
785 // |
|
786 // This data member of CAgnRptDef is different in 9.3 |
|
787 // |
|
788 if (hasRepeatRule) |
|
789 { |
|
790 TAgnRpt* rule = NULL; |
|
791 TAgnRpt::TType rptType = static_cast<TAgnRpt::TType>(aStream.ReadUint8L()); |
|
792 |
|
793 // Intenalize data in base class for repeat definitions |
|
794 // (TAgnRpt) |
|
795 // |
|
796 TInt64 timeInt64; |
|
797 aStream >> timeInt64; // ignore start time |
|
798 aStream >> timeInt64; |
|
799 TAgnCalendarTime untilTime; |
|
800 untilTime.SetUtcL(timeInt64); // not right if the entry is floating, this must be fixed once the time mode is known |
|
801 |
|
802 TUint16 interval; |
|
803 aStream >> interval; |
|
804 |
|
805 // skip iRptNextOnly and iRptForever (not used in 9.3) |
|
806 aStream.ReadUint8L(); |
|
807 aStream.ReadUint8L(); |
|
808 |
|
809 // Internalize data in classes derived from TAgnRpt |
|
810 // |
|
811 switch(rptType) |
|
812 { |
|
813 case TAgnRpt::EDaily: |
|
814 //Nothing else to internalize for rpt rule |
|
815 rule = new (ELeave) TAgnDailyRpt(aRptDef); |
|
816 CleanupStack::PushL(rule); |
|
817 break; |
|
818 case TAgnRpt::EWeekly: |
|
819 { |
|
820 rule = new (ELeave) TAgnWeeklyRpt(aRptDef); |
|
821 CleanupStack::PushL(rule); |
|
822 TAgnWeeklyRpt* weeklyRule = static_cast<TAgnWeeklyRpt*>(rule); |
|
823 TUint8 weeklyRptDays = aStream.ReadUint8L(); |
|
824 if (weeklyRptDays & EBit1) |
|
825 { |
|
826 weeklyRule->SetDay(EMonday); |
|
827 } |
|
828 if (weeklyRptDays & EBit2) |
|
829 { |
|
830 weeklyRule->SetDay(ETuesday); |
|
831 } |
|
832 if (weeklyRptDays & EBit3) |
|
833 { |
|
834 weeklyRule->SetDay(EWednesday); |
|
835 } |
|
836 if (weeklyRptDays & EBit4) |
|
837 { |
|
838 weeklyRule->SetDay(EThursday); |
|
839 } |
|
840 if (weeklyRptDays & EBit5) |
|
841 { |
|
842 weeklyRule->SetDay(EFriday); |
|
843 } |
|
844 if (weeklyRptDays & EBit6) |
|
845 { |
|
846 weeklyRule->SetDay(ESaturday); |
|
847 } |
|
848 if (weeklyRptDays & EBit7) |
|
849 { |
|
850 weeklyRule->SetDay(ESunday); |
|
851 } |
|
852 |
|
853 TDay firstDayOfWeek = static_cast<TDay>(aStream.ReadUint8L()); |
|
854 weeklyRule->SetFirstDayOfWeek(firstDayOfWeek); |
|
855 } |
|
856 break; |
|
857 case TAgnRpt::EMonthlyByDates: |
|
858 { |
|
859 rule = new (ELeave) TAgnMonthlyByDatesRpt(aRptDef); |
|
860 CleanupStack::PushL(rule); |
|
861 TInt32 monthlyRptDates; |
|
862 aStream >> monthlyRptDates; |
|
863 for (TInt i = 0; i <= 30; ++i) // check 31 dates |
|
864 { |
|
865 TInt dateToCheck = 1 << i; |
|
866 if (monthlyRptDates & dateToCheck) |
|
867 { |
|
868 static_cast<TAgnMonthlyByDatesRpt*>(rule)->SetDate(i); |
|
869 } |
|
870 } |
|
871 } |
|
872 break; |
|
873 case TAgnRpt::EMonthlyByDays: |
|
874 { |
|
875 rule = new (ELeave) TAgnMonthlyByDaysRpt(aRptDef); |
|
876 CleanupStack::PushL(rule); |
|
877 TAgnMonthlyByDaysRpt* monthlyRule = static_cast<TAgnMonthlyByDaysRpt*>(rule); |
|
878 |
|
879 TInt weekInMonth = 0; |
|
880 while (weekInMonth <= 4) // 5 weeks in month (1st, 2nd, 3rd, 4th, last) |
|
881 { |
|
882 TUint8 monthlyRptDays = aStream.ReadUint8L(); |
|
883 if (monthlyRptDays & EBit1) |
|
884 { |
|
885 monthlyRule->SetDay(EMonday, static_cast<TAgnRpt::TWeekInMonth>(weekInMonth)); |
|
886 } |
|
887 if (monthlyRptDays & EBit2) |
|
888 { |
|
889 monthlyRule->SetDay(ETuesday, static_cast<TAgnRpt::TWeekInMonth>(weekInMonth)); |
|
890 } |
|
891 if (monthlyRptDays & EBit3) |
|
892 { |
|
893 monthlyRule->SetDay(EWednesday, static_cast<TAgnRpt::TWeekInMonth>(weekInMonth)); |
|
894 } |
|
895 if (monthlyRptDays & EBit4) |
|
896 { |
|
897 monthlyRule->SetDay(EThursday, static_cast<TAgnRpt::TWeekInMonth>(weekInMonth)); |
|
898 } |
|
899 if (monthlyRptDays & EBit5) |
|
900 { |
|
901 monthlyRule->SetDay(EFriday, static_cast<TAgnRpt::TWeekInMonth>(weekInMonth)); |
|
902 } |
|
903 if (monthlyRptDays & EBit6) |
|
904 { |
|
905 monthlyRule->SetDay(ESaturday, static_cast<TAgnRpt::TWeekInMonth>(weekInMonth)); |
|
906 } |
|
907 if (monthlyRptDays & EBit7) |
|
908 { |
|
909 monthlyRule->SetDay(ESunday, static_cast<TAgnRpt::TWeekInMonth>(weekInMonth)); |
|
910 } |
|
911 ++weekInMonth; |
|
912 } |
|
913 } |
|
914 break; |
|
915 case TAgnRpt::EYearlyByDay: |
|
916 { |
|
917 rule = new (ELeave) TAgnYearlyByDayRpt(aRptDef); |
|
918 CleanupStack::PushL(rule); |
|
919 TAgnRpt::TWeekInMonth weekInMonth = static_cast<TAgnRpt::TWeekInMonth>(aStream.ReadUint8L()); |
|
920 TDay day = static_cast<TDay>(aStream.ReadUint8L()); |
|
921 TDateTime untilDateTime = untilTime.LocalL().DateTime(); |
|
922 static_cast<TAgnYearlyByDayRpt*>(rule)->FindStartDayL(day, weekInMonth, untilDateTime.Month(), untilDateTime.Year()); |
|
923 } |
|
924 break; |
|
925 case TAgnRpt::EYearlyByDate: |
|
926 rule = new (ELeave) TAgnYearlyByDateRpt(aRptDef); |
|
927 CleanupStack::PushL(rule); |
|
928 break; |
|
929 default: |
|
930 User::Leave(KErrCorrupt); |
|
931 } |
|
932 rule->SetInterval(interval); |
|
933 |
|
934 aRptDef.SetRRuleL(*rule); |
|
935 aRptDef.SetUntilTime(untilTime); |
|
936 CleanupStack::PopAndDestroy(rule); |
|
937 } |
|
938 } |
|
939 |
|
940 CArrayFixFlat<TAgnCalendarTime>* CAgnCalendarConverter209::InternalizeExceptionsL(RReadStream& aStream) const |
|
941 { |
|
942 CArrayFixFlat<TAgnCalendarTime>* exceptionArray = NULL; |
|
943 if (aStream.ReadUint8L()) |
|
944 { |
|
945 const TInt KExceptionArrayGranularity = 4; |
|
946 |
|
947 exceptionArray = new (ELeave) CArrayFixFlat<TAgnCalendarTime>(KExceptionArrayGranularity); |
|
948 CleanupStack::PushL(exceptionArray); |
|
949 aStream >> *exceptionArray; |
|
950 CleanupStack::Pop(exceptionArray); |
|
951 } |
|
952 return exceptionArray; |
|
953 } |
|
954 |
|
955 void CAgnCalendarConverter209::InternalizeSporadicDatesL(RReadStream& aStream, CAgnRptDef& aRptDef) const |
|
956 { |
|
957 const TInt KCount = aStream.ReadUint16L(); |
|
958 if (KCount > 0) |
|
959 { |
|
960 TAgnCalendarTime time; |
|
961 for (TInt i = 0; i < KCount; ++i) |
|
962 { |
|
963 aStream >> time; |
|
964 aRptDef.AddSporadicDateL(time); |
|
965 } |
|
966 } |
|
967 } |
|
968 |
|
969 void CAgnCalendarConverter209::InternalizeTimeZoneL(RReadStream& aStream, CAgnRptDef& aRptDef) const |
|
970 { |
|
971 // Time Zone |
|
972 TBool hasTimeZone = aStream.ReadUint8L(); |
|
973 if (hasTimeZone) |
|
974 { |
|
975 CTzRules* tzRules = CTzRules::NewL(aStream); |
|
976 CleanupStack::PushL(tzRules); |
|
977 aRptDef.SetTimeZoneL(*tzRules); |
|
978 CleanupStack::PopAndDestroy(tzRules); |
|
979 } |
|
980 } |
|
981 |
|
982 TInt32 CAgnCalendarConverter209::InternalizeAlarmL(RReadStream& aStream, TInt16 aAttributes, CAgnEntry& aEntry) const |
|
983 { |
|
984 // In 9.1/9.2, the eigth bit of the 'attributes' |
|
985 // indicates presence/absence of a entry symbol |
|
986 // |
|
987 if (aAttributes & EBit8) |
|
988 { |
|
989 aStream.ReadInt16L();//Skip entry symbol (not used in 9.3) |
|
990 } |
|
991 |
|
992 // Alarm data |
|
993 // |
|
994 // In 9.1/9.2, the bits 1 (EIsCrossedOut) and 5(EHasAlarm) |
|
995 // of 'attributes' are used to tell if alarm information |
|
996 // has been externalized or not |
|
997 // |
|
998 TInt32 alarmPreTime = KMaxTInt32; |
|
999 if ( ! (aAttributes & EBit1)) |
|
1000 { |
|
1001 // Entry is not a completed todo |
|
1002 if (aAttributes & EBit5) |
|
1003 { |
|
1004 // Entry has alarm info |
|
1005 HBufC* alarmSoundName = HBufC::NewLC(aStream, KMaxAlarmSoundNameLength); |
|
1006 if (alarmSoundName->Length() > 0) |
|
1007 { |
|
1008 aEntry.SetAlarmSoundNameL(*alarmSoundName); |
|
1009 } |
|
1010 CleanupStack::PopAndDestroy(alarmSoundName); |
|
1011 |
|
1012 alarmPreTime = aStream.ReadInt32L(); |
|
1013 // alarm offset is converted as an offset later once entry time is known |
|
1014 } |
|
1015 } |
|
1016 return alarmPreTime; |
|
1017 } |
|
1018 |
|
1019 void CAgnCalendarConverter209::InternalizeSummaryL(RReadStream& aStream, TBool aHasBeenDeleted, CAgnEntry& aEntry) const |
|
1020 { |
|
1021 // Rich Text |
|
1022 // In 9.1/9.2 may contain several streamIds (Styles,MarkupData,text); |
|
1023 // It may be stored inline or offline. |
|
1024 // In 9.3, only the text is wanted for the 'Summary'. |
|
1025 // |
|
1026 if ( ! aHasBeenDeleted) |
|
1027 { |
|
1028 TBool isStoredInline = TBool(aStream.ReadInt8L()); |
|
1029 |
|
1030 // Create auxiliary RichText object |
|
1031 CParaFormatLayer* paraFormatLayer = CParaFormatLayer::NewL(); |
|
1032 CleanupStack::PushL(paraFormatLayer); |
|
1033 |
|
1034 CCharFormatLayer* charFormatLayer = CCharFormatLayer::NewL(); |
|
1035 CleanupStack::PushL(charFormatLayer); |
|
1036 |
|
1037 CRichText *auxRichText = CRichText::NewL(paraFormatLayer,charFormatLayer,CEditableText::EFlatStorage,32); |
|
1038 CleanupStack::PushL(auxRichText); |
|
1039 // Populate the rich text object |
|
1040 // |
|
1041 if (isStoredInline) |
|
1042 { |
|
1043 auxRichText->InternalizeStyleDataL(aStream); |
|
1044 TBool hasMarkupData=TBool(aStream.ReadUint8L()); |
|
1045 if (hasMarkupData) |
|
1046 { |
|
1047 auxRichText->InternalizeMarkupDataL(aStream); |
|
1048 } |
|
1049 auxRichText->InternalizePlainTextL(aStream); |
|
1050 } |
|
1051 else |
|
1052 { |
|
1053 // Rich Text stored offline |
|
1054 TStreamId richTextStreamId; |
|
1055 aStream >> richTextStreamId; |
|
1056 if (richTextStreamId != KNullStreamId) |
|
1057 { |
|
1058 RStoreReadStream richTextStream; |
|
1059 CleanupClosePushL(richTextStream); |
|
1060 richTextStream.OpenL(InputStreamStore(),richTextStreamId); |
|
1061 CPersistentStore* embeddedStore = CEmbeddedStore::FromLC(richTextStream); |
|
1062 auxRichText->RestoreL(*embeddedStore,embeddedStore->Root()); |
|
1063 CleanupStack::PopAndDestroy(embeddedStore); |
|
1064 CleanupStack::PopAndDestroy(&richTextStream); // richTextStream.Close() |
|
1065 } |
|
1066 } |
|
1067 |
|
1068 // Get the text if there's any and leave it in the entry |
|
1069 // |
|
1070 if (auxRichText->DocumentLength() > 0) |
|
1071 { |
|
1072 HBufC* summaryBuffer = HBufC::NewLC(auxRichText->DocumentLength()); |
|
1073 TPtr summaryBufPtr(summaryBuffer->Des()); |
|
1074 auxRichText->Extract(summaryBufPtr); |
|
1075 |
|
1076 // Set the summary in the entry |
|
1077 // |
|
1078 aEntry.SetSummary(summaryBuffer); |
|
1079 CleanupStack::Pop(summaryBuffer); |
|
1080 } |
|
1081 |
|
1082 CleanupStack::PopAndDestroy(auxRichText); |
|
1083 CleanupStack::PopAndDestroy(charFormatLayer); |
|
1084 CleanupStack::PopAndDestroy(paraFormatLayer); |
|
1085 } |
|
1086 else |
|
1087 { |
|
1088 // Deleted entry has no rich text. No Summary. |
|
1089 aEntry.SetSummaryStreamId(KNullStreamId); |
|
1090 } |
|
1091 } |
|
1092 |
|
1093 void CAgnCalendarConverter209::InternalizeTypeSpecificDataL(RReadStream& aStream, TInt16 aAttributes, CAgnEntry& aEntry) const |
|
1094 { |
|
1095 // |
|
1096 // Restore data dependent on entry type (stored with StoreSpecificsL in 9.1/2) |
|
1097 // |
|
1098 TAgnCalendarTime time; |
|
1099 |
|
1100 const CCalEntry::TType KEntryType = aEntry.Type(); |
|
1101 switch(KEntryType) |
|
1102 { |
|
1103 case CCalEntry::EAppt: |
|
1104 case CCalEntry::EReminder: |
|
1105 case CCalEntry::EEvent: |
|
1106 case CCalEntry::EAnniv: |
|
1107 { |
|
1108 aStream >> time; |
|
1109 |
|
1110 TAgnCalendarTime endTime; |
|
1111 aStream >> endTime;; |
|
1112 |
|
1113 if ( ! endTime.IsSet()) |
|
1114 { |
|
1115 aEntry.SetStartAndEndTimeL(time, time); |
|
1116 } |
|
1117 else |
|
1118 { |
|
1119 aEntry.SetStartAndEndTimeL(time, endTime); |
|
1120 } |
|
1121 |
|
1122 if (KEntryType == CCalEntry::EAnniv || KEntryType == CCalEntry::EEvent) |
|
1123 { |
|
1124 aStream >> time; // Events and Anniversaries have a display time, not used in 9.3 |
|
1125 if (KEntryType == CCalEntry::EAnniv) |
|
1126 { |
|
1127 aStream.ReadInt16L(); // Skip iBaseYear |
|
1128 aStream.ReadUint8L(); // Skip iDisplayAs |
|
1129 aStream.ReadInt8L(); // Skip iHasBaseYear |
|
1130 } |
|
1131 } |
|
1132 break; |
|
1133 } |
|
1134 |
|
1135 case CCalEntry::ETodo: |
|
1136 { |
|
1137 aStream.ReadInt32L(); // Skip iTodoListId |
|
1138 aStream >> time; // Was iDueDate in 9.1/2 |
|
1139 if(aAttributes & EBit1) |
|
1140 { |
|
1141 // Is a crossed out (completed) Todo |
|
1142 // |
|
1143 TAgnCalendarTime completedDate; |
|
1144 aStream >> completedDate; |
|
1145 aEntry.SetCompletedDateUtcL(completedDate.UtcL()); |
|
1146 } |
|
1147 else |
|
1148 { |
|
1149 // This is not a completed Todo |
|
1150 aEntry.SetCompletedDateUtcL(Time::NullTTime()); |
|
1151 } |
|
1152 |
|
1153 if (time.IsSet()) // = end time |
|
1154 { |
|
1155 TInt duration = aStream.ReadUint16L(); |
|
1156 TTimeIntervalDays intervalDays(duration); |
|
1157 TAgnCalendarTime startTime; |
|
1158 if (time.TimeMode() == MAgnCalendarTimeMode::EFloating) |
|
1159 { |
|
1160 startTime.SetFloatingL(time.LocalL() - intervalDays); |
|
1161 } |
|
1162 else |
|
1163 { |
|
1164 startTime.SetLocalL(time.LocalL() - intervalDays); |
|
1165 } |
|
1166 aEntry.SetStartAndEndTimeL(startTime, time); |
|
1167 } |
|
1168 |
|
1169 aStream.ReadUint8L();// Skip iAlarmFrom |
|
1170 aStream >> time; // Not used in 9.3 |
|
1171 aEntry.SetPriority(aStream.ReadUint8L()); // For Todos, use this priority; for other entry types, take priority from the extended entry |
|
1172 aStream.ReadUint8L(); //Skip iDisplayDueDateAs |
|
1173 } |
|
1174 break; |
|
1175 } |
|
1176 } |
|
1177 |
|
1178 /** Algorithm to calculate the alarm offset from the 'pretime' and the 'alarm origin'. |
|
1179 This algorithm is used in v9.1 and v9.2 code. The alarm origin is the instance time corresponding to the alarm. |
|
1180 The pretime is the value saved to file, it is a combination of the minute of the day (0-1440) and the number of |
|
1181 days before the event that the alarm occurs. |
|
1182 @internalComponent */ |
|
1183 TInt32 CAgnCalendarConverter209::CalculateAlarmOffsetL(TInt32 aPreTime, const TTime& aAlarmOrigin) const |
|
1184 { |
|
1185 // copied from TAgnAlarmPreTime::AlarmInstanceDateTime and TAgnAlarmPreTime::AlarmTime |
|
1186 TDateTime alarmOriginDateTime = aAlarmOrigin.DateTime(); |
|
1187 TInt alarmOriginTimeOfDay = alarmOriginDateTime.Hour()*60 + alarmOriginDateTime.Minute(); |
|
1188 |
|
1189 TUint daysWarning = (aPreTime - alarmOriginTimeOfDay) / KAgnMinutesInADay; |
|
1190 TUint time = KAgnMinutesInADay - ((aPreTime - alarmOriginTimeOfDay) % KAgnMinutesInADay); |
|
1191 if (time == KAgnMinutesInADay) |
|
1192 { |
|
1193 time = 0; |
|
1194 if (daysWarning > 0) |
|
1195 { |
|
1196 daysWarning -= 1; |
|
1197 } |
|
1198 } |
|
1199 |
|
1200 TTime alarmTime = aAlarmOrigin - TTimeIntervalDays(daysWarning); |
|
1201 TDateTime alarmDateTime = alarmTime.DateTime(); |
|
1202 alarmDateTime.SetHour(time / 60); |
|
1203 alarmDateTime.SetMinute(time % 60); |
|
1204 TTimeIntervalMinutes offset; |
|
1205 aAlarmOrigin.MinutesFrom(TTime(alarmDateTime), offset); |
|
1206 return offset.Int(); |
|
1207 } |
|
1208 |
|
1209 void CAgnCalendarConverter209::InternalizeExtendedEntryL(RReadStream& aStream, CAgnEntry& aEntry) |
|
1210 /** @internalComponent */ |
|
1211 { |
|
1212 // Internalize information that in 9.1/9.2 lives in the Extended entry |
|
1213 // |
|
1214 TInt id = aStream.ReadUint32L(); //Not in 9.3, but needed later in this method |
|
1215 TInt size = aStream.ReadUint32L(); |
|
1216 |
|
1217 // Skip GlobalId |
|
1218 TBuf<32> dummyBuffer; |
|
1219 if (size) |
|
1220 { |
|
1221 aStream.ReadL(dummyBuffer,size); |
|
1222 } |
|
1223 |
|
1224 // Populate location |
|
1225 // |
|
1226 size = aStream.ReadUint32L(); |
|
1227 if (size) |
|
1228 { |
|
1229 HBufC* location = HBufC::NewLC(size); |
|
1230 TPtr bufPtr = location->Des(); |
|
1231 aStream.ReadL(bufPtr,size); |
|
1232 aEntry.SetLocationL(*location); |
|
1233 CleanupStack::PopAndDestroy(); |
|
1234 } |
|
1235 |
|
1236 // Populate attendee list |
|
1237 // |
|
1238 size = aStream.ReadUint32L(); |
|
1239 |
|
1240 RPointerArray<CAgnAttendee> attendees; |
|
1241 CleanupClosePushL(attendees); |
|
1242 |
|
1243 for (TInt count=0; count < size; count++) |
|
1244 { |
|
1245 TBool organizer = EFalse; |
|
1246 CAgnAttendee* attendee = InternalizeAttendeeL(aStream, organizer); |
|
1247 if (organizer) |
|
1248 { |
|
1249 aEntry.SetOrganizerL(attendee); |
|
1250 } |
|
1251 else |
|
1252 { |
|
1253 aEntry.AddAttendeeL(attendee); |
|
1254 } |
|
1255 attendees.AppendL(attendee); |
|
1256 } |
|
1257 |
|
1258 // populate the phoneowner/organizer fields |
|
1259 // |
|
1260 size = aStream.ReadUint32L(); |
|
1261 |
|
1262 if(size > 0 && size <= attendees.Count()) |
|
1263 { |
|
1264 aEntry.SetPhoneOwnerL(attendees[size-1]); |
|
1265 } |
|
1266 |
|
1267 size = aStream.ReadUint32L(); |
|
1268 |
|
1269 if(size > 0 && size <= attendees.Count()) |
|
1270 { |
|
1271 CAgnAttendee* organizer = attendees[size-1]->CloneL(); |
|
1272 CleanupStack::PushL(organizer); |
|
1273 aEntry.SetOrganizerL(organizer); |
|
1274 CleanupStack::Pop(organizer); |
|
1275 } |
|
1276 CleanupStack::PopAndDestroy(&attendees); // attendees.Close() |
|
1277 |
|
1278 // Populate DT stamp |
|
1279 // |
|
1280 TAgnCalendarTime dtStamp; |
|
1281 aStream >> dtStamp; |
|
1282 aEntry.SetDTStampUtcL(dtStamp.UtcL()); |
|
1283 |
|
1284 TInt expansion = aStream.ReadUint8L(); // read number of bytes in expansion |
|
1285 // Only try to internalize category information if it exists |
|
1286 if (expansion>0) |
|
1287 { |
|
1288 |
|
1289 // Read in categories |
|
1290 // |
|
1291 size = aStream.ReadUint32L(); |
|
1292 |
|
1293 for (TInt ccount=0; ccount<size; ccount++) |
|
1294 { |
|
1295 CAgnCategory* category = InternalizeCategoryL(aStream); |
|
1296 CleanupStack::PushL(category); |
|
1297 aEntry.AddCategoryL(category); |
|
1298 CleanupStack::Pop(category); |
|
1299 } |
|
1300 |
|
1301 // Skip iBackgroundSymbolColor |
|
1302 aStream.ReadUint8L(); |
|
1303 aStream.ReadUint8L(); |
|
1304 aStream.ReadUint8L(); |
|
1305 |
|
1306 // If it's the new file format read in the Stream Id for the notes text |
|
1307 const TInt KExtendedAttributesIdv1_0 = 0x110000F2; // from 9.1 / 9.2 |
|
1308 |
|
1309 if (id == KExtendedAttributesIdv1_0) |
|
1310 { |
|
1311 // Set the priority for entries that are not Todos (for Todos it's been set already) |
|
1312 if (aEntry.Type() != CCalEntry::ETodo) |
|
1313 { |
|
1314 aEntry.SetPriority(aStream.ReadUint8L()); |
|
1315 } |
|
1316 else |
|
1317 { |
|
1318 // Skip the priority |
|
1319 aStream.ReadUint8L(); |
|
1320 } |
|
1321 |
|
1322 // 9.1/2 "Notes" field is "Description" in 9.3 |
|
1323 TStreamId descriptionStreamId; |
|
1324 aStream >> descriptionStreamId; |
|
1325 |
|
1326 if(descriptionStreamId != KNullStreamId) |
|
1327 { |
|
1328 // Put the description in the aEntry |
|
1329 // |
|
1330 RStoreReadStream in; |
|
1331 in.OpenLC(InputStreamStore(), descriptionStreamId); |
|
1332 TInt textLength = in.ReadUint32L(); |
|
1333 if(textLength > 0) |
|
1334 { |
|
1335 HBufC* text = HBufC::NewL(in, textLength); |
|
1336 aEntry.SetDescription(text); |
|
1337 } |
|
1338 CleanupStack::PopAndDestroy(); //in |
|
1339 } |
|
1340 |
|
1341 // Ignore iNotesClipboardStreamId |
|
1342 TStreamId clipboardStreamId; |
|
1343 aStream >> clipboardStreamId; |
|
1344 } |
|
1345 } |
|
1346 } |
|
1347 |
|
1348 CAgnCategory* CAgnCalendarConverter209::InternalizeCategoryL(RReadStream& aStream) const |
|
1349 { |
|
1350 CCalCategory::TCalCategoryType categoryType = static_cast<CCalCategory::TCalCategoryType>(aStream.ReadUint8L()); |
|
1351 |
|
1352 TInt size = aStream.ReadUint32L(); |
|
1353 HBufC* extendedCategoryName = HBufC::NewLC(size); |
|
1354 TPtr bufPtr = extendedCategoryName->Des(); |
|
1355 aStream.ReadL(bufPtr,size); |
|
1356 |
|
1357 CAgnCategory* category = NULL; |
|
1358 if (categoryType == CCalCategory::ECalExtended || extendedCategoryName->Length() > 0) |
|
1359 { |
|
1360 category = CAgnCategory::NewL(*extendedCategoryName); |
|
1361 } |
|
1362 else |
|
1363 { |
|
1364 category = CAgnCategory::NewL(categoryType); |
|
1365 } |
|
1366 CleanupStack::PopAndDestroy(extendedCategoryName); |
|
1367 return category; |
|
1368 } |
|
1369 |
|
1370 CAgnAttendee* CAgnCalendarConverter209::InternalizeAttendeeL(RReadStream& aStream, TBool& aOrganizer) const |
|
1371 { |
|
1372 CAgnAttendee::TAgnRole agnRole = static_cast<CAgnAttendee::TAgnRole>(aStream.ReadUint8L()); |
|
1373 aStream.ReadUint8L();// Skip iStatus |
|
1374 TBool responseRequested = aStream.ReadUint8L(); |
|
1375 aStream.ReadUint8L(); // ignore expect value |
|
1376 CCalAttendee::TCalRole calRole = static_cast<CCalAttendee::TCalRole>(aStream.ReadUint8L()); |
|
1377 CCalAttendee::TCalStatus calStatus = static_cast<CCalAttendee::TCalStatus>(aStream.ReadUint8L()); |
|
1378 |
|
1379 // read in Address |
|
1380 TInt size = aStream.ReadUint32L(); |
|
1381 HBufC* address = HBufC::NewLC(size); |
|
1382 TPtr bufPtr = address->Des(); |
|
1383 aStream.ReadL(bufPtr,size); |
|
1384 |
|
1385 size = aStream.ReadUint32L(); |
|
1386 HBufC* commonName = HBufC::NewLC(size); |
|
1387 TPtr bufPtr2 = commonName->Des(); |
|
1388 aStream.ReadL(bufPtr2,size); |
|
1389 |
|
1390 size = aStream.ReadUint32L(); |
|
1391 HBufC* sentBy = HBufC::NewLC(size); |
|
1392 TPtr bufPtr3 = sentBy->Des(); |
|
1393 aStream.ReadL(bufPtr3,size); |
|
1394 |
|
1395 CAgnAttendee* attendee = CAgnAttendee::NewL(*address, *sentBy); |
|
1396 CleanupStack::PushL(attendee); |
|
1397 attendee->SetCommonNameL(*commonName); |
|
1398 |
|
1399 attendee->SetResponseRequested(responseRequested); |
|
1400 attendee->SetRole(agnRole); |
|
1401 if (agnRole == CAgnAttendee::EOrganizer) |
|
1402 { |
|
1403 aOrganizer = ETrue; |
|
1404 } |
|
1405 attendee->SetCalStatus(calStatus); |
|
1406 |
|
1407 CleanupStack::Pop(attendee); |
|
1408 CleanupStack::PopAndDestroy(sentBy); |
|
1409 CleanupStack::PopAndDestroy(commonName); |
|
1410 CleanupStack::PopAndDestroy(address); |
|
1411 |
|
1412 return attendee; |
|
1413 } |
|
1414 |
|
1415 // CAgnCalendarConverter210 // |
|
1416 |
|
1417 CAgnCalendarConverter210::CAgnCalendarConverter210() |
|
1418 { |
|
1419 } |
|
1420 |
|
1421 CAgnCalendarConverter210* CAgnCalendarConverter210::NewL(CAgnServFile& aAgnServerFile) |
|
1422 { |
|
1423 CAgnCalendarConverter210* converter = new (ELeave) CAgnCalendarConverter210(); |
|
1424 CleanupStack::PushL(converter); |
|
1425 converter->ConstructL(aAgnServerFile); |
|
1426 CleanupStack::Pop(converter); |
|
1427 return converter; |
|
1428 } |
|
1429 |
|
1430 void CAgnCalendarConverter210::InternalizeExtendedEntryL(RReadStream& aStream, CAgnEntry& aEntry) |
|
1431 { |
|
1432 CAgnCalendarConverter209::InternalizeExtendedEntryL(aStream, aEntry); |
|
1433 InternalizeAlarmActionL(aStream, InputStreamStore(), aEntry); |
|
1434 } |
|
1435 |
|
1436 /** |
|
1437 Internalize alarm action |
|
1438 @internalComponent */ |
|
1439 void CAgnCalendarConverter210::InternalizeAlarmActionL(RReadStream& aStream, CStreamStore& aInputStreamStore, CAgnEntry& aEntry) |
|
1440 { |
|
1441 TStreamId alarmActionStreamId; |
|
1442 aStream >> alarmActionStreamId; |
|
1443 if ( alarmActionStreamId != KNullStreamId) |
|
1444 { |
|
1445 RStoreReadStream in; |
|
1446 in.OpenLC(aInputStreamStore, alarmActionStreamId); |
|
1447 CAgnContent* alarmAction = new (ELeave) CAgnContent; |
|
1448 CleanupStack::PushL(alarmAction); |
|
1449 in >> *alarmAction; |
|
1450 aEntry.SetAlarmAction(alarmAction); |
|
1451 CleanupStack::Pop(alarmAction); |
|
1452 CleanupStack::PopAndDestroy(); //in |
|
1453 } |
|
1454 } |
|
1455 |
|
1456 // CAgnCalendarConverter211 // |
|
1457 CAgnCalendarConverter211* CAgnCalendarConverter211::NewL(CAgnServFile& aAgnServerFile) |
|
1458 { |
|
1459 CAgnCalendarConverter211* converter = new (ELeave) CAgnCalendarConverter211(); |
|
1460 CleanupStack::PushL(converter); |
|
1461 converter->ConstructL(aAgnServerFile); |
|
1462 CleanupStack::Pop(converter); |
|
1463 return converter; |
|
1464 } |
|
1465 |
|
1466 CAgnCalendarConverter211::CAgnCalendarConverter211() |
|
1467 { |
|
1468 } |
|
1469 |
|
1470 CAgnCalendarConverter211::~CAgnCalendarConverter211() |
|
1471 { |
|
1472 delete iInputTzRuleIndex; |
|
1473 } |
|
1474 |
|
1475 void CAgnCalendarConverter211::ConstructL(CAgnServFile& aAgnServerFile) |
|
1476 { |
|
1477 CAgnCalendarConverter::ConstructL(aAgnServerFile); |
|
1478 iInputTzRuleIndex = CAgnTzRuleIndex::NewL(*aAgnServerFile.Dictionary(), *aAgnServerFile.StoreL()); |
|
1479 } |
|
1480 |
|
1481 void CAgnCalendarConverter211::InternalizeTimeZoneL(RReadStream& aStream, CAgnRptDef& aRptDef) const |
|
1482 { |
|
1483 TBool isSystemRule = aStream.ReadUint8L(); |
|
1484 TStreamId streamId; |
|
1485 aStream >> streamId; |
|
1486 |
|
1487 if(streamId != KNullStreamId) |
|
1488 { |
|
1489 CTzRules* tzRule = iInputTzRuleIndex->FindTzRuleByStreamIdL(streamId, isSystemRule); |
|
1490 CleanupStack::PushL(tzRule); |
|
1491 aRptDef.SetTimeZoneL(*tzRule); |
|
1492 CleanupStack::PopAndDestroy(tzRule); |
|
1493 } |
|
1494 } |
|
1495 |
|
1496 |