|
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "agmentry.h" |
|
17 |
|
18 #include "agmattendee.h" |
|
19 #include "agmcategory.h" |
|
20 #include <calinterimapipanic.h> |
|
21 #include "agmcontent.h" |
|
22 #include "agmattachment.h" |
|
23 #include "agmdate.h" |
|
24 #include "agmrptdef.h" |
|
25 #include "agmutil.h" |
|
26 |
|
27 #include <calentry.h> |
|
28 //#include "calentryimpl.h" |
|
29 #include <e32math.h> |
|
30 |
|
31 #include <asshddefs.h> |
|
32 |
|
33 |
|
34 //---------------------------------- CAgnEntry ------------------------------------------ |
|
35 |
|
36 EXPORT_C CAgnEntry* CAgnEntry::NewL(CCalEntry::TType aType) |
|
37 { |
|
38 __ASSERT_ALWAYS(aType>=CCalEntry::EAppt && aType<=CCalEntry::EAnniv, Panic(EAgmErrBadTypeEntry)); |
|
39 // allocate a CAgnEntry object, which invokes the CAgnSimpleEntry new operator, but passing no allocator |
|
40 // this makes the CAgnSimpleEntry new operator use the default new operator |
|
41 |
|
42 return new (ELeave, NULL) CAgnEntry(aType);; |
|
43 } |
|
44 |
|
45 EXPORT_C CAgnEntry* CAgnEntry::NewL(RReadStream& aStream) |
|
46 //Creates an entry and restores it from aStream |
|
47 { |
|
48 // type must be read first because NewL requires it |
|
49 TUint8 typeData = aStream.ReadUint8L(); |
|
50 |
|
51 CCalEntry::TType type=CCalEntry::TType(typeData); |
|
52 |
|
53 __ASSERT_ALWAYS(type==CCalEntry::EAppt || type==CCalEntry::EEvent || |
|
54 type==CCalEntry::EAnniv || type==CCalEntry::ETodo || |
|
55 type==CCalEntry::EReminder, User::Leave(KErrCorrupt)); |
|
56 |
|
57 CAgnEntry* entry = CAgnEntry::NewL(type); |
|
58 CleanupStack::PushL(entry); |
|
59 entry->InternalizeL(aStream); |
|
60 CleanupStack::Pop(); |
|
61 return entry; |
|
62 } |
|
63 |
|
64 |
|
65 CAgnEntry::CAgnEntry(CCalEntry::TType aType) : CAgnSimpleEntry(aType) |
|
66 { |
|
67 iSummary = NULL; |
|
68 iSummaryStreamId = KNullStreamId; |
|
69 iDescription = NULL; |
|
70 iDescriptionStreamId = KNullStreamId; |
|
71 SetFlagOff(EAgnAlarmActionDeleted); |
|
72 iDTStampUtc = Time::NullTTime(); |
|
73 iLatitude=KGEODefaultValue; |
|
74 iLongitude=KGEODefaultValue; |
|
75 } |
|
76 |
|
77 void CAgnEntry::ConstructL(HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum) |
|
78 { |
|
79 iGsData = CGsParentData::NewL(aUid, aSeqNum, aMethod); // takes ownership of aUid |
|
80 } |
|
81 |
|
82 void CAgnEntry::ConstructL(HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum, const TAgnCalendarTime& aRecurrenceId, CalCommon::TRecurrenceRange aRange) |
|
83 { |
|
84 iGsData = CGsChildData::NewL(aUid, aSeqNum, aMethod, aRecurrenceId, aRange); // takes ownership of aUid |
|
85 } |
|
86 |
|
87 EXPORT_C CAgnEntry* CAgnEntry::NewL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum, const TAgnCalendarTime& aRecurrenceId, CalCommon::TRecurrenceRange aRange) |
|
88 { |
|
89 CAgnEntry* entry = new (ELeave, NULL) CAgnEntry(aType); |
|
90 |
|
91 CleanupStack::PushL(entry); |
|
92 entry->ConstructL(aUid, aMethod, aSeqNum, aRecurrenceId, aRange); |
|
93 CleanupStack::Pop(entry); |
|
94 |
|
95 return entry; |
|
96 } |
|
97 |
|
98 EXPORT_C CAgnEntry* CAgnEntry::NewL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum) |
|
99 { |
|
100 CAgnEntry* entry = new (ELeave, NULL) CAgnEntry(aType); |
|
101 |
|
102 CleanupStack::PushL(entry); |
|
103 entry->ConstructL(aUid, aMethod, aSeqNum); |
|
104 CleanupStack::Pop(entry); |
|
105 |
|
106 return entry; |
|
107 } |
|
108 |
|
109 EXPORT_C CAgnEntry::~CAgnEntry() |
|
110 /** The destructor frees all resources owned by the entry, prior to its destruction. |
|
111 @internalComponent |
|
112 */ |
|
113 { |
|
114 if ( iAttendeeList ) |
|
115 { |
|
116 iAttendeeList->ResetAndDestroy(); |
|
117 delete iAttendeeList; |
|
118 } |
|
119 delete iMeetingOrganizer; |
|
120 |
|
121 delete iLocation; |
|
122 |
|
123 if ( iCategoryList ) |
|
124 { |
|
125 iCategoryList->ResetAndDestroy(); |
|
126 delete iCategoryList; |
|
127 } |
|
128 |
|
129 if (iAttachments) |
|
130 { |
|
131 iAttachments->ResetAndDestroy(); |
|
132 delete iAttachments; |
|
133 } |
|
134 |
|
135 delete iDescription; |
|
136 delete iSummary; |
|
137 delete iAlarmSoundName; |
|
138 delete iAlarmAction; |
|
139 |
|
140 delete iGsData; |
|
141 } |
|
142 |
|
143 |
|
144 EXPORT_C const TDesC& CAgnEntry::Summary() const |
|
145 /** Gets a pointer to the rich text object owned by the entry. |
|
146 |
|
147 @internalComponent |
|
148 @return Pointer to the rich text object. The caller does not take ownership. */ |
|
149 { |
|
150 if ( iSummary ) |
|
151 { |
|
152 return *iSummary; |
|
153 } |
|
154 |
|
155 return KNullDesC; |
|
156 } |
|
157 |
|
158 |
|
159 EXPORT_C TBool CAgnEntry::CompareL(const CAgnEntry& aEntry) const |
|
160 /** Compares another entry for equality with this one. |
|
161 |
|
162 The entries' instance IDs and unique IDs are also compared. |
|
163 |
|
164 @internalComponent |
|
165 @param aEntry Pointer to an entry. |
|
166 @param aCompareId This argument is used internally, for test purposes only. |
|
167 As it has a default value, it can be ignored by developers. |
|
168 @return ETrue if aEntry is the same as this entry, EFalse if not. Note. Replication |
|
169 data is not included in the comparison, except for the replication status. |
|
170 */ |
|
171 { |
|
172 if ( ! (*this == aEntry) ) |
|
173 { |
|
174 return EFalse; |
|
175 } |
|
176 |
|
177 if ( ReplicationStatus() != aEntry.ReplicationStatus() ) |
|
178 { |
|
179 return EFalse; |
|
180 } |
|
181 |
|
182 if ( HasAlarm() ) |
|
183 { |
|
184 if ( AlarmSoundName() != aEntry.AlarmSoundName() ) |
|
185 { |
|
186 return EFalse; |
|
187 } |
|
188 |
|
189 CAgnContent* content1 = AlarmAction(); |
|
190 CAgnContent* content2 = aEntry.AlarmAction(); |
|
191 if ( content1 == NULL ) |
|
192 { |
|
193 if ( content2 != NULL ) |
|
194 { |
|
195 return EFalse; |
|
196 } |
|
197 } |
|
198 else |
|
199 { |
|
200 if ( content2 == NULL ) |
|
201 { |
|
202 return EFalse; |
|
203 } |
|
204 |
|
205 if ( content1->Type() != content2->Type() ) |
|
206 { |
|
207 return EFalse; |
|
208 } |
|
209 |
|
210 if ( content1->Content() != content2->Content() ) |
|
211 { |
|
212 return EFalse; |
|
213 } |
|
214 |
|
215 if ( content1->MimeType() != content2->MimeType() ) |
|
216 { |
|
217 return EFalse; |
|
218 } |
|
219 } |
|
220 } |
|
221 |
|
222 if ( BusyStatus() != aEntry.BusyStatus() ) |
|
223 { |
|
224 return EFalse; |
|
225 } |
|
226 |
|
227 // Compare GEO values |
|
228 TReal entryLatitude; |
|
229 TReal entryLongitude; |
|
230 |
|
231 aEntry.GeoValue(entryLatitude,entryLongitude); |
|
232 |
|
233 if ( iLatitude != entryLatitude || entryLongitude != iLongitude ) |
|
234 { |
|
235 return EFalse; |
|
236 } |
|
237 |
|
238 // Compare the user integer. |
|
239 if (UserInt() != aEntry.UserInt()) |
|
240 { |
|
241 return EFalse; |
|
242 } |
|
243 |
|
244 if ( DTStampUtcL() != aEntry.DTStampUtcL() ) |
|
245 { |
|
246 return EFalse; |
|
247 } |
|
248 |
|
249 if ( Method() != aEntry.Method() ) |
|
250 { |
|
251 return EFalse; |
|
252 } |
|
253 |
|
254 if ( SequenceNumber() != aEntry.SequenceNumber() ) |
|
255 { |
|
256 return EFalse; |
|
257 } |
|
258 |
|
259 if ( RecurrenceId() != aEntry.RecurrenceId() ) |
|
260 { |
|
261 return EFalse; |
|
262 } |
|
263 |
|
264 const TInt KNumOfCategories = CategoryCount(); |
|
265 |
|
266 if ( aEntry.CategoryCount() != KNumOfCategories ) |
|
267 { |
|
268 return EFalse; |
|
269 } |
|
270 |
|
271 const RPointerArray<CAgnCategory>* categoryList1 = iCategoryList; |
|
272 const RPointerArray<CAgnCategory>* categoryList2 = aEntry.iCategoryList; |
|
273 |
|
274 if (categoryList1 && categoryList2) |
|
275 { |
|
276 TBool categoryFound = EFalse; |
|
277 |
|
278 for ( TInt i = 0 ; i < KNumOfCategories; ++i ) |
|
279 { |
|
280 categoryFound = EFalse; |
|
281 |
|
282 for ( TInt j = 0; ! categoryFound && j < KNumOfCategories; ++j ) |
|
283 { |
|
284 if ( (*categoryList1)[i]->Category() == (*categoryList2)[j]->Category() ) |
|
285 { |
|
286 if ( (*categoryList1)[i]->Category() == CCalCategory::ECalExtended ) |
|
287 { |
|
288 if ( (*categoryList1)[i]->ExtendedCategoryName() == (*categoryList2)[j]->ExtendedCategoryName() ) |
|
289 { |
|
290 categoryFound = ETrue; |
|
291 } |
|
292 } |
|
293 else |
|
294 { |
|
295 categoryFound = ETrue; |
|
296 } |
|
297 } |
|
298 } |
|
299 |
|
300 if ( !categoryFound ) |
|
301 { |
|
302 return EFalse; |
|
303 } |
|
304 } |
|
305 } |
|
306 |
|
307 const TInt KNumOfAttendees = AttendeeCount(); |
|
308 |
|
309 if ( KNumOfAttendees != aEntry.AttendeeCount() ) |
|
310 { |
|
311 return EFalse; |
|
312 } |
|
313 |
|
314 if ( KNumOfAttendees > 0 && KNumOfAttendees == aEntry.AttendeeCount() ) |
|
315 { |
|
316 const RPointerArray<CAgnAttendee>& KAttendeeList1 = *iAttendeeList; |
|
317 const RPointerArray<CAgnAttendee>& KAttendeeList2 = *aEntry.iAttendeeList; |
|
318 |
|
319 for ( TInt i = 0; i < KNumOfAttendees; ++i ) |
|
320 { |
|
321 const TPtrC& KAttendee1 = KAttendeeList1[i]->Address(); |
|
322 |
|
323 TBool attendeeFound = EFalse; |
|
324 |
|
325 for ( TInt j = 0; !attendeeFound && j < KNumOfAttendees; ++j ) |
|
326 { |
|
327 const TPtrC& KAttendee2 = KAttendeeList2[j]->Address(); |
|
328 |
|
329 if ( KAttendee1.CompareF(KAttendee2) == 0 ) |
|
330 { |
|
331 attendeeFound = ETrue; |
|
332 } |
|
333 } |
|
334 |
|
335 if ( !attendeeFound ) |
|
336 { |
|
337 return EFalse; |
|
338 } |
|
339 } |
|
340 } |
|
341 |
|
342 const TInt KNumAttachments = AttachmentCount(); |
|
343 if (KNumAttachments != aEntry.AttachmentCount()) |
|
344 { |
|
345 return EFalse; |
|
346 } |
|
347 if (KNumAttachments > 0) |
|
348 { |
|
349 RArray<TBool> foundAttachmentAlready; |
|
350 CleanupClosePushL(foundAttachmentAlready); |
|
351 |
|
352 for (TInt i = 0; i < KNumAttachments; ++i) |
|
353 { |
|
354 foundAttachmentAlready.AppendL(EFalse); |
|
355 } |
|
356 |
|
357 for (TInt i = 0; i < KNumAttachments; ++i) |
|
358 { |
|
359 TBool attachmentFound = EFalse; |
|
360 for (TInt j = 0; j < KNumAttachments; ++j) |
|
361 { |
|
362 if (!foundAttachmentAlready[j] && Attachment(i).CompareL(aEntry.Attachment(j))) |
|
363 { |
|
364 foundAttachmentAlready[j] = ETrue; |
|
365 attachmentFound = ETrue; |
|
366 break; |
|
367 } |
|
368 } |
|
369 if (!attachmentFound) |
|
370 { |
|
371 CleanupStack::PopAndDestroy(); // foundAttachmentAlready.Close() |
|
372 return EFalse; |
|
373 } |
|
374 } |
|
375 |
|
376 CleanupStack::PopAndDestroy(); // foundAttachmentAlready.Close() |
|
377 } |
|
378 |
|
379 if ( PhoneOwner() == NULL ) |
|
380 { |
|
381 if ( aEntry.PhoneOwner() != NULL ) |
|
382 { |
|
383 return EFalse; |
|
384 } |
|
385 } |
|
386 else |
|
387 { |
|
388 // PhoneOwner() != NULL |
|
389 if ( aEntry.PhoneOwner() == NULL ) |
|
390 { |
|
391 return EFalse; |
|
392 } |
|
393 else if ( PhoneOwner()->Address() != aEntry.PhoneOwner()->Address() ) |
|
394 { |
|
395 return EFalse; |
|
396 } |
|
397 } |
|
398 |
|
399 if ( Summary() != aEntry.Summary() ) |
|
400 { |
|
401 return EFalse; |
|
402 } |
|
403 |
|
404 if ( Description() != aEntry.Description() ) |
|
405 { |
|
406 return EFalse; |
|
407 } |
|
408 |
|
409 if ( Location() != aEntry.Location() ) |
|
410 { |
|
411 return EFalse; |
|
412 } |
|
413 |
|
414 return ETrue; |
|
415 } |
|
416 |
|
417 |
|
418 EXPORT_C const TDesC& CAgnEntry::AlarmSoundName() const |
|
419 /** Gets the name of the alarm sound as set by SetAlarmSoundName(). |
|
420 |
|
421 Returns NULL if the entry isn't alarmed. |
|
422 |
|
423 @internalComponent |
|
424 @return The name of the alarm sound. |
|
425 */ |
|
426 { |
|
427 |
|
428 if ( HasAlarm() && iAlarmSoundName ) |
|
429 { |
|
430 return *iAlarmSoundName; |
|
431 } |
|
432 |
|
433 return KNullDesC(); |
|
434 } |
|
435 |
|
436 |
|
437 EXPORT_C void CAgnEntry::SetAlarmSoundNameL(const TDesC& aAlarmSoundName) |
|
438 /** Sets the name of the alarm sound. |
|
439 |
|
440 Note: if the length of the new alarm sound name is greater than KMaxAlarmSoundName |
|
441 characters, it will be ignored. |
|
442 |
|
443 @internalComponent |
|
444 @param aAlarmSoundName The name of the alarm sound. |
|
445 */ |
|
446 { |
|
447 const TInt KLen = aAlarmSoundName.Length(); |
|
448 |
|
449 if ( KLen > 0 && KLen <= KMaxAlarmSoundNameLength ) |
|
450 { |
|
451 // delete and set always to NULL before AllocL because |
|
452 // that call could leave and the pointer be not NULL |
|
453 |
|
454 delete iAlarmSoundName; |
|
455 iAlarmSoundName = NULL; |
|
456 |
|
457 iAlarmSoundName = aAlarmSoundName.AllocL(); |
|
458 } |
|
459 } |
|
460 |
|
461 |
|
462 EXPORT_C void CAgnEntry::ClearAlarm() |
|
463 /** Clear associated alarm |
|
464 |
|
465 @internalComponent |
|
466 */ |
|
467 { |
|
468 delete iAlarmSoundName; |
|
469 iAlarmSoundName = NULL; |
|
470 |
|
471 if ( iAlarmActionStreamId != KNullStreamId) |
|
472 { |
|
473 SetFlagOn(EAgnAlarmActionDeleted); |
|
474 } |
|
475 |
|
476 delete iAlarmAction; |
|
477 iAlarmAction = NULL; |
|
478 |
|
479 SetAlarmOffset(KAlarmNotSet); |
|
480 } |
|
481 |
|
482 void CAgnEntry::ExternalizeGsDataL(RWriteStream& aStream, TBool aToBuffer) const |
|
483 { |
|
484 aStream.WriteInt8L(GsDataType()); |
|
485 |
|
486 if(aToBuffer) |
|
487 { |
|
488 iGsData->ExternalizeToBufferL(aStream); |
|
489 } |
|
490 else |
|
491 { |
|
492 iGsData->ExternalizeL(aStream); |
|
493 } |
|
494 } |
|
495 |
|
496 EXPORT_C void CAgnEntry::PruneRDatesL(const TAgnCalendarTime& aRecurrenceId, CalCommon::TRecurrenceRange aRange) |
|
497 /** |
|
498 Used when adding a repeating child to a parent entry. |
|
499 Removes all sporadic dates either after or before the specified recurrence ID. |
|
500 @internalComponent |
|
501 */ |
|
502 { |
|
503 __ASSERT_DEBUG(iGsData->GsDataType() == CGsData::EParent, Panic(EAgmErrNotParentEntry)); |
|
504 __ASSERT_DEBUG(RptDef(), Panic(EAgmErrNotParentEntry)); |
|
505 __ASSERT_DEBUG(aRange == CalCommon::EThisAndFuture || aRange == CalCommon::EThisAndPrior, Panic(EAgmErrInvalidRecurrenceRange)); |
|
506 |
|
507 if (RptDef()->HasSporadicDates()) |
|
508 { |
|
509 const RArray<TAgnCalendarTime>* KSporadicDates = RptDef()->SporadicDateList(); |
|
510 |
|
511 for (TInt i = KSporadicDates->Count() - 1; i >= 0; --i) |
|
512 { |
|
513 const TAgnCalendarTime& KSporadicDate = (*KSporadicDates)[i]; |
|
514 if ( (aRecurrenceId > KSporadicDate && aRange == CalCommon::EThisAndPrior ) || |
|
515 (aRecurrenceId < KSporadicDate && aRange == CalCommon::EThisAndFuture ) ) |
|
516 { |
|
517 RptDef()->RemoveSporadicDate(KSporadicDate); |
|
518 } |
|
519 } |
|
520 } |
|
521 } |
|
522 |
|
523 void CAgnEntry::InternalizeGsDataL(RReadStream& aStream, TBool aFromBuffer) |
|
524 { |
|
525 CGsData::TGsDataType dataType = static_cast<CGsData::TGsDataType>(aStream.ReadInt8L()); |
|
526 |
|
527 if(dataType == CGsData::EParent) |
|
528 { |
|
529 iGsData = CGsParentData::NewL(); |
|
530 } |
|
531 else |
|
532 { |
|
533 iGsData = CGsChildData::NewL(); |
|
534 } |
|
535 |
|
536 if(aFromBuffer) |
|
537 { |
|
538 iGsData->InternalizeFromBufferL(aStream); |
|
539 } |
|
540 else |
|
541 { |
|
542 iGsData->InternalizeL(aStream); |
|
543 } |
|
544 } |
|
545 |
|
546 EXPORT_C void CAgnEntry::ExternalizeL(RWriteStream& aStream) const |
|
547 /** Externalises an entry's details and attributes, but not its rich text to a |
|
548 write stream. |
|
549 |
|
550 The presence of this function means that the standard templated operator<<() |
|
551 (defined in s32strm.h) is available to externalise objects of this class. |
|
552 |
|
553 @internalComponent |
|
554 @param aStream Stream to which the object should be externalised. |
|
555 */ |
|
556 { |
|
557 ExternalizeEntryL(aStream); |
|
558 ExternalizeGsDataL(aStream, EFalse); |
|
559 } |
|
560 |
|
561 void CAgnEntry::ExternalizeEntryL(RWriteStream& aStream, TBool aToBuffer) const |
|
562 { |
|
563 CAgnSimpleEntry::doExternalizeL(aStream, aToBuffer); |
|
564 aStream.WriteInt8L(iReplicationStatus); |
|
565 |
|
566 if ( HasAlarm() ) |
|
567 { |
|
568 if (iAlarmSoundName) |
|
569 { |
|
570 aStream << *iAlarmSoundName; |
|
571 } |
|
572 else |
|
573 { |
|
574 aStream << KNullDesC(); |
|
575 } |
|
576 } |
|
577 |
|
578 // Make sure there is no server pointer |
|
579 // - This may have been set up from a previous FetchEntry |
|
580 __ASSERT_DEBUG(iSummaryStreamId == KNullStreamId || |
|
581 !(iSummary && iSummary->Length() > 0 && iSummaryStreamId == KNullStreamId), |
|
582 Panic(EAgmNoNotesStreamId)); |
|
583 |
|
584 aStream << iSummaryStreamId; |
|
585 |
|
586 TInt size = 0; |
|
587 if ( iLocation ) |
|
588 { |
|
589 size = iLocation->Length(); |
|
590 aStream.WriteUint32L(size); |
|
591 aStream.WriteL(iLocation->Des(), size); |
|
592 } |
|
593 else |
|
594 { |
|
595 size = 0; |
|
596 aStream.WriteUint32L(size); |
|
597 } |
|
598 |
|
599 TInt phoneOwnerIndex = 0; |
|
600 |
|
601 if ( iAttendeeList ) |
|
602 { |
|
603 size = iAttendeeList->Count(); |
|
604 aStream.WriteUint32L(size); |
|
605 |
|
606 for ( TInt i = 0; i < size; ++i ) |
|
607 { |
|
608 CAgnAttendee*& attendeeI = (*iAttendeeList)[i]; |
|
609 |
|
610 attendeeI->ExternalizeL(aStream); |
|
611 |
|
612 if ( iPhoneOwner == attendeeI ) |
|
613 { |
|
614 phoneOwnerIndex = i + 1; |
|
615 } |
|
616 } |
|
617 } |
|
618 else |
|
619 { |
|
620 size = 0; |
|
621 aStream.WriteUint32L(size); |
|
622 } |
|
623 |
|
624 // phone owner index. 0 implies no phoneowner |
|
625 aStream.WriteUint32L(phoneOwnerIndex); |
|
626 |
|
627 // meeting organizer if present |
|
628 if (iMeetingOrganizer) |
|
629 { |
|
630 aStream.WriteUint8L(ETrue); |
|
631 iMeetingOrganizer->ExternalizeL(aStream); |
|
632 } |
|
633 else |
|
634 { |
|
635 aStream.WriteUint8L(EFalse); |
|
636 } |
|
637 |
|
638 // Write the creation date field |
|
639 |
|
640 aStream << iDTStampUtc.Int64(); |
|
641 |
|
642 // this does not change the file format |
|
643 if ( iCategoryList ) |
|
644 { |
|
645 size = iCategoryList->Count(); |
|
646 aStream.WriteUint32L(size); |
|
647 |
|
648 for ( TInt ccount = 0; ccount < size; ++ccount ) |
|
649 { |
|
650 (*iCategoryList)[ccount]->ExternalizeL(aStream); |
|
651 } |
|
652 } |
|
653 else |
|
654 { |
|
655 size = 0; |
|
656 aStream.WriteUint32L(size); |
|
657 } |
|
658 |
|
659 // Write the Notes Stream Id - Null value indicates no Notes data. |
|
660 // If the Notes exist, they should have been saved previously, so Stream id != 0 !!! |
|
661 __ASSERT_DEBUG((iDescriptionStreamId == KNullStreamId) || |
|
662 !(iDescription && iDescription->Length() > 0 && iDescriptionStreamId == KNullStreamId), |
|
663 Panic(EAgmNoNotesStreamId)); |
|
664 aStream << iDescriptionStreamId; |
|
665 aStream << iAlarmActionStreamId; |
|
666 |
|
667 aStream.WriteUint8L(iBusyStatus); |
|
668 |
|
669 // GEO properties |
|
670 aStream.WriteReal64L(iLatitude); |
|
671 aStream.WriteReal64L(iLongitude); |
|
672 |
|
673 const TInt KAttachmentCount = AttachmentCount(); |
|
674 aStream.WriteUint16L(KAttachmentCount); |
|
675 for (TInt i = 0; i < KAttachmentCount; ++i) |
|
676 { |
|
677 if ( ! Attachment(i).FlagsSet(CAgnAttachment::EDataHasBeenSet)) |
|
678 { |
|
679 // attachments with just content IDs should not be stored |
|
680 User::Leave(KErrArgument); |
|
681 } |
|
682 else |
|
683 { |
|
684 aStream << Attachment(i); |
|
685 } |
|
686 } |
|
687 |
|
688 // Set the user integer of the stream. |
|
689 aStream.WriteInt32L( UserInt() ); |
|
690 |
|
691 // future DC proofing |
|
692 aStream.WriteUint32L(0); // number of bytes until end of entry |
|
693 } |
|
694 |
|
695 |
|
696 EXPORT_C void CAgnEntry::InternalizeL(RReadStream& aStream) |
|
697 { |
|
698 InternalizeEntryL(aStream, EFalse); |
|
699 InternalizeGsDataL(aStream, EFalse); |
|
700 } |
|
701 |
|
702 void CAgnEntry::InternalizeEntryL(RReadStream& aStream, TBool aFromBuffer) |
|
703 /** Internalises an entry's details and attributes, but not its rich text from |
|
704 a read stream. |
|
705 |
|
706 The presence of this function means that the standard templated operator>>() |
|
707 (defined in s32strm.h) is available to internalise objects of this class. |
|
708 |
|
709 @internalComponent |
|
710 @param aStream Stream from which the object should be internalised. |
|
711 */ |
|
712 { |
|
713 CAgnSimpleEntry::doInternalizeL(aStream, aFromBuffer); |
|
714 iReplicationStatus = static_cast<CCalEntry::TReplicationStatus>(aStream.ReadInt8L()); |
|
715 |
|
716 delete iAlarmSoundName; |
|
717 iAlarmSoundName = NULL; |
|
718 |
|
719 if ( HasAlarm() ) |
|
720 { |
|
721 iAlarmSoundName = HBufC::NewL(aStream, KMaxAlarmSoundNameLength); |
|
722 if ( iAlarmSoundName->Length() == 0 ) |
|
723 { |
|
724 delete iAlarmSoundName; |
|
725 iAlarmSoundName = NULL; |
|
726 } |
|
727 } |
|
728 |
|
729 aStream >> iSummaryStreamId; |
|
730 |
|
731 // Delete any location that may exist |
|
732 delete iLocation; |
|
733 iLocation = NULL; |
|
734 |
|
735 TInt size = aStream.ReadUint32L(); |
|
736 if ( size ) |
|
737 { |
|
738 iLocation = HBufC::NewL(size); |
|
739 TPtr bufPtr = iLocation->Des(); |
|
740 aStream.ReadL(bufPtr, size); |
|
741 } |
|
742 |
|
743 size = aStream.ReadUint32L(); |
|
744 if ( iAttendeeList ) |
|
745 { |
|
746 iAttendeeList->ResetAndDestroy(); |
|
747 } |
|
748 else |
|
749 { |
|
750 if ( size ) |
|
751 { |
|
752 CreateAttendeeListL(); |
|
753 } |
|
754 } |
|
755 iPhoneOwner = NULL; |
|
756 iMeetingOrganizer = NULL; |
|
757 |
|
758 for ( TInt count = 0; count < size; ++count ) |
|
759 { |
|
760 CAgnAttendee* attendee = CAgnAttendee::NewL(aStream); |
|
761 CleanupStack::PushL(attendee); |
|
762 iAttendeeList->AppendL(attendee); |
|
763 CleanupStack::Pop(attendee); |
|
764 } |
|
765 |
|
766 // populate the phoneowner/organizer fields if existing |
|
767 TInt phoneOwnerIndex = aStream.ReadUint32L(); |
|
768 if (phoneOwnerIndex > 0) |
|
769 { |
|
770 iPhoneOwner = (*iAttendeeList)[phoneOwnerIndex-1]; |
|
771 } |
|
772 |
|
773 // meeting organizer if present |
|
774 if (aStream.ReadUint8L()) |
|
775 { |
|
776 iMeetingOrganizer = CAgnAttendee::NewL(aStream); |
|
777 } |
|
778 |
|
779 TInt64 dtStamp; |
|
780 aStream >> dtStamp; |
|
781 iDTStampUtc = dtStamp; |
|
782 |
|
783 size = aStream.ReadUint32L(); |
|
784 |
|
785 if ( iCategoryList ) |
|
786 { |
|
787 iCategoryList->ResetAndDestroy(); |
|
788 } |
|
789 else |
|
790 { |
|
791 if ( size ) |
|
792 { |
|
793 iCategoryList = new (ELeave) RPointerArray<CAgnCategory>; |
|
794 } |
|
795 } |
|
796 |
|
797 for ( TInt ccount = 0; ccount < size; ++ccount ) |
|
798 { |
|
799 CAgnCategory* category = CAgnCategory::NewL(aStream); |
|
800 CleanupStack::PushL(category); |
|
801 iCategoryList->AppendL(category); |
|
802 CleanupStack::Pop(category); |
|
803 } |
|
804 |
|
805 // If it's the new file format read in the Stream Id for the notes text |
|
806 aStream >> iDescriptionStreamId; |
|
807 |
|
808 aStream >> iAlarmActionStreamId; |
|
809 |
|
810 iBusyStatus = static_cast<CCalEntry::TTransp>(aStream.ReadUint8L()); |
|
811 |
|
812 // GEO properties |
|
813 TReal geoLatitude = aStream.ReadReal64L(); |
|
814 TReal geoLongitude = aStream.ReadReal64L(); |
|
815 |
|
816 SetGeoValueL(geoLatitude, geoLongitude); |
|
817 |
|
818 TInt attachmentCount = aStream.ReadUint16L(); |
|
819 for (TInt i = 0; i < attachmentCount; ++i) |
|
820 { |
|
821 |
|
822 CAgnAttachment* attachment = AttachmentFactory::NewAttachmentL(aStream); |
|
823 CleanupStack::PushL(attachment); |
|
824 AddAttachmentL(attachment); |
|
825 CleanupStack::Pop(attachment); |
|
826 } |
|
827 |
|
828 // Set the user integer of this entry from the stream. |
|
829 SetUserInt(aStream.ReadInt32L()); |
|
830 |
|
831 // future DC proofing |
|
832 size = aStream.ReadUint32L(); // number of bytes until end of entry |
|
833 while (size > 0) |
|
834 { |
|
835 aStream.ReadUint8L(); // ignore data |
|
836 size--; |
|
837 } |
|
838 } |
|
839 |
|
840 EXPORT_C CAgnEntry* CAgnEntry::CloneL() const |
|
841 { |
|
842 CAgnEntry* entry = NULL; |
|
843 HBufC8* guid = (this->Guid()).AllocLC(); |
|
844 if(this->GsDataType() == CGsData::EParent) |
|
845 { |
|
846 entry = CAgnEntry::NewL(this->Type(), guid, this->Method(), this->SequenceNumber()); |
|
847 } |
|
848 else |
|
849 { |
|
850 entry = CAgnEntry::NewL(this->Type(), guid, this->Method(), this->SequenceNumber(), this->RecurrenceId(), this->RecurrenceRange()); |
|
851 } |
|
852 CleanupStack::Pop(guid); |
|
853 CleanupStack::PushL(entry); |
|
854 entry->CopyFromL(*this, CCalEntry::ECopyAll); |
|
855 CleanupStack::Pop(entry); |
|
856 return entry; |
|
857 } |
|
858 |
|
859 EXPORT_C void CAgnEntry::CopyFromL(const CAgnEntry& aSource, CCalEntry::TCopyType aCopyType) |
|
860 /** Copy the details common to all entry types from aSource. |
|
861 If aCopyType is EShallowCopy it indicates that if aSources rich text is stored out of line and its |
|
862 not loaded then it isn't loaded and copied |
|
863 */ |
|
864 { |
|
865 CopySimpleEntryL(aSource, aCopyType); |
|
866 |
|
867 // NOTE: don't use the internal set methods with pointers because doing a CopyFrom |
|
868 // we are supposed to carbon copy the original. If the original has a NULL |
|
869 // pointer in a member, we have to do the same and not keep any old stuff |
|
870 iReplicationStatus = aSource.iReplicationStatus; |
|
871 |
|
872 if( iAttendeeList ) |
|
873 { |
|
874 iAttendeeList->ResetAndDestroy(); |
|
875 } |
|
876 iPhoneOwner = NULL; |
|
877 delete iMeetingOrganizer; |
|
878 iMeetingOrganizer = NULL; |
|
879 |
|
880 const TInt KAttendees = aSource.AttendeeCount(); |
|
881 for ( TInt count = 0; count < KAttendees; ++count ) |
|
882 { |
|
883 CAgnAttendee& attendee = aSource.FetchAttendee(count); |
|
884 |
|
885 CAgnAttendee* newAttendee = attendee.CloneL(); |
|
886 AddAttendeeL(newAttendee); |
|
887 |
|
888 if ( aSource.PhoneOwner() == &attendee ) |
|
889 { |
|
890 SetPhoneOwnerL(newAttendee); |
|
891 } |
|
892 } |
|
893 |
|
894 if (aSource.Organizer()) |
|
895 { |
|
896 iMeetingOrganizer = aSource.Organizer()->CloneL(); |
|
897 } |
|
898 |
|
899 // Copy the Location |
|
900 delete iLocation; |
|
901 iLocation = NULL; |
|
902 |
|
903 if ( aSource.iLocation ) |
|
904 { |
|
905 iLocation = aSource.iLocation->AllocL(); |
|
906 } |
|
907 |
|
908 iDTStampUtc = aSource.iDTStampUtc; |
|
909 |
|
910 if( iCategoryList ) |
|
911 { |
|
912 iCategoryList->ResetAndDestroy(); |
|
913 } |
|
914 |
|
915 const TInt KCategories = aSource.CategoryCount(); |
|
916 for ( TInt ccount = 0; ccount < KCategories; ++ccount ) |
|
917 { |
|
918 CAgnCategory& category = aSource.FetchCategory(ccount); |
|
919 |
|
920 CAgnCategory* newCategory = CAgnCategory::NewL(category); |
|
921 CleanupStack::PushL(newCategory); |
|
922 AddCategoryL(newCategory); |
|
923 CleanupStack::Pop(newCategory); |
|
924 } |
|
925 |
|
926 iBusyStatus = aSource.BusyStatus(); |
|
927 |
|
928 // GEO properties |
|
929 TReal sourceLatitude; |
|
930 TReal sourceLongitude; |
|
931 aSource.GeoValue(sourceLatitude,sourceLongitude); |
|
932 |
|
933 iLatitude = sourceLatitude; |
|
934 iLongitude = sourceLongitude; |
|
935 |
|
936 // Copy the Notes buffer |
|
937 |
|
938 delete iDescription; |
|
939 iDescription = NULL; |
|
940 |
|
941 if ( aSource.iDescription ) |
|
942 { |
|
943 iDescription = aSource.iDescription->AllocL(); |
|
944 } |
|
945 |
|
946 iDescriptionStreamId = aSource.iDescriptionStreamId; |
|
947 |
|
948 |
|
949 // Copy the Summary buffer |
|
950 |
|
951 delete iSummary; |
|
952 iSummary = NULL; |
|
953 |
|
954 if ( aSource.iSummary ) |
|
955 { |
|
956 iSummary = aSource.iSummary->AllocL(); |
|
957 } |
|
958 |
|
959 iSummaryStreamId = aSource.iSummaryStreamId; |
|
960 |
|
961 |
|
962 // Copy the Alarm sound name |
|
963 |
|
964 delete iAlarmSoundName; |
|
965 iAlarmSoundName = NULL; |
|
966 |
|
967 if ( aSource.iAlarmSoundName ) |
|
968 { |
|
969 iAlarmSoundName = aSource.iAlarmSoundName->AllocL(); |
|
970 } |
|
971 |
|
972 |
|
973 // Copy the Alarm action |
|
974 |
|
975 delete iAlarmAction; |
|
976 iAlarmAction = NULL; |
|
977 |
|
978 if ( aSource.iAlarmAction ) |
|
979 { |
|
980 iAlarmAction = aSource.iAlarmAction->CloneL(); |
|
981 } |
|
982 |
|
983 iAlarmActionStreamId = aSource.iAlarmActionStreamId; |
|
984 iFlags = aSource.iFlags; |
|
985 |
|
986 if ( iAttachments ) |
|
987 { |
|
988 iAttachments->ResetAndDestroy(); |
|
989 delete iAttachments; |
|
990 iAttachments = NULL; |
|
991 } |
|
992 |
|
993 const TInt KAttachments = aSource.AttachmentCount(); |
|
994 for ( TInt i = 0; i < KAttachments; ++i ) |
|
995 { |
|
996 CAgnAttachment& attachment = aSource.Attachment(i); |
|
997 CAgnAttachment* attachmentCopy = AttachmentFactory::CloneL(attachment); |
|
998 CleanupStack::PushL(attachmentCopy); |
|
999 AddAttachmentL(attachmentCopy); |
|
1000 CleanupStack::Pop(attachmentCopy); |
|
1001 } |
|
1002 |
|
1003 iGsData->CopyDataL(*aSource.iGsData); |
|
1004 |
|
1005 if(aCopyType == CCalEntry::ECopyAll) |
|
1006 { |
|
1007 HBufC8* guid = aSource.Guid().AllocL(); |
|
1008 SetGuid(guid); |
|
1009 } |
|
1010 } |
|
1011 |
|
1012 EXPORT_C CCalEntry::TReplicationStatus CAgnEntry::ReplicationStatus() const |
|
1013 /** Get ReplicationStatus |
|
1014 |
|
1015 @internalComponent |
|
1016 */ |
|
1017 { |
|
1018 return static_cast<CCalEntry::TReplicationStatus>(iReplicationStatus); |
|
1019 } |
|
1020 |
|
1021 |
|
1022 EXPORT_C void CAgnEntry::SetReplicationStatusL(CCalEntry::TReplicationStatus aReplicationStatus) |
|
1023 /** Set ReplicationStatus |
|
1024 |
|
1025 @internalComponent |
|
1026 @leave KErrArgument if passed parameter exceeds boundaries |
|
1027 */ |
|
1028 { |
|
1029 if( aReplicationStatus < CCalEntry::EOpen || aReplicationStatus > CCalEntry::ERestricted ) |
|
1030 { |
|
1031 User::Leave(KErrArgument); |
|
1032 } |
|
1033 |
|
1034 iReplicationStatus = aReplicationStatus; |
|
1035 } |
|
1036 |
|
1037 |
|
1038 EXPORT_C TBool CAgnEntry::SummaryIsLoaded() const |
|
1039 /** Check if summary text is loaded from stream |
|
1040 |
|
1041 @internalComponent |
|
1042 */ |
|
1043 { |
|
1044 if ( ! iSummary && iSummaryStreamId != KNullStreamId ) |
|
1045 { |
|
1046 return EFalse; |
|
1047 } |
|
1048 |
|
1049 return ETrue; |
|
1050 } |
|
1051 |
|
1052 |
|
1053 EXPORT_C void CAgnEntry::SetSummary(HBufC* aSummary) |
|
1054 /** Set summary |
|
1055 |
|
1056 @internalComponent |
|
1057 */ |
|
1058 { |
|
1059 delete iSummary; |
|
1060 iSummary = aSummary; |
|
1061 } |
|
1062 |
|
1063 |
|
1064 EXPORT_C void CAgnEntry::SetLocationL(const TDesC& aLocation) |
|
1065 /** Sets the contents of the entry's location field. |
|
1066 |
|
1067 Sets the entry's 'has extended' property. |
|
1068 |
|
1069 @internalComponent |
|
1070 @param aLocation Descriptor containing a location, e.g. for a meeting. |
|
1071 */ |
|
1072 { |
|
1073 delete iLocation; |
|
1074 iLocation = NULL; |
|
1075 iLocation = aLocation.AllocL(); |
|
1076 } |
|
1077 |
|
1078 |
|
1079 EXPORT_C const TDesC& CAgnEntry::Location() const |
|
1080 /** Gets the contents of the entry's location field. |
|
1081 |
|
1082 @internalComponent |
|
1083 @return The location field. NULL if the entry has no location field. |
|
1084 */ |
|
1085 { |
|
1086 if ( iLocation ) |
|
1087 { |
|
1088 return *iLocation; |
|
1089 } |
|
1090 |
|
1091 return KNullDesC(); |
|
1092 } |
|
1093 |
|
1094 |
|
1095 EXPORT_C TInt CAgnEntry::AttendeeCount() const |
|
1096 /** Gets the number of attendees that have been added to the entry. |
|
1097 |
|
1098 @internalComponent |
|
1099 @return Number of attendees added. |
|
1100 */ |
|
1101 { |
|
1102 if ( ! iAttendeeList ) |
|
1103 { |
|
1104 return 0; |
|
1105 } |
|
1106 |
|
1107 return iAttendeeList->Count(); |
|
1108 } |
|
1109 |
|
1110 EXPORT_C CAgnAttendee& CAgnEntry::FetchAttendee(TInt aIndex) const |
|
1111 /** Gets the attendee at the specified index within the entry's list of |
|
1112 attendees. |
|
1113 |
|
1114 The index specified must be valid (between zero and AttendeeCount() |
|
1115 - 1), otherwise a panic occurs. |
|
1116 |
|
1117 @internalComponent |
|
1118 @param aIndex Index to identify the specified attendee. |
|
1119 @return The attendee details. */ |
|
1120 { |
|
1121 return *(*iAttendeeList)[aIndex]; |
|
1122 } |
|
1123 |
|
1124 |
|
1125 EXPORT_C void CAgnEntry::AddAttendeeL(CAgnAttendee* aAttendee) |
|
1126 /** Appends an attendee to the entry's list of attendees. |
|
1127 |
|
1128 @internalComponent |
|
1129 @param aAttendee Pointer to the attendee details. |
|
1130 */ |
|
1131 { |
|
1132 CleanupStack::PushL(aAttendee); |
|
1133 CreateAttendeeListL(); |
|
1134 |
|
1135 // Add an attendee for this entry |
|
1136 iAttendeeList->AppendL(aAttendee); |
|
1137 CleanupStack::Pop(aAttendee); |
|
1138 } |
|
1139 |
|
1140 void CAgnEntry::CreateAttendeeListL() |
|
1141 { |
|
1142 if ( !iAttendeeList ) |
|
1143 { |
|
1144 iAttendeeList = new (ELeave) RPointerArray<CAgnAttendee>; |
|
1145 } |
|
1146 } |
|
1147 |
|
1148 EXPORT_C void CAgnEntry::SetOrganizerL(CAgnAttendee* aAttendee) |
|
1149 /** Set attendee as organiser |
|
1150 |
|
1151 @internalComponent |
|
1152 */ |
|
1153 { |
|
1154 if (iMeetingOrganizer == iPhoneOwner) |
|
1155 { |
|
1156 iPhoneOwner = NULL; |
|
1157 } |
|
1158 delete iMeetingOrganizer; |
|
1159 iMeetingOrganizer = aAttendee; |
|
1160 } |
|
1161 |
|
1162 EXPORT_C CAgnAttendee* CAgnEntry::Organizer() const |
|
1163 /** Get Organizer as attendee object |
|
1164 |
|
1165 @internalComponent |
|
1166 */ |
|
1167 { |
|
1168 return iMeetingOrganizer; |
|
1169 } |
|
1170 |
|
1171 EXPORT_C void CAgnEntry::DeleteAttendee(TInt aIndex) |
|
1172 /** Deletes the attendee at the index specified from the entry's list of attendees. |
|
1173 |
|
1174 If there is no attendee at the index specified, a panic occurs. |
|
1175 |
|
1176 @internalComponent |
|
1177 @param aIndex Index of the attendee to delete. |
|
1178 */ |
|
1179 { |
|
1180 CAgnAttendee* attendee = (*iAttendeeList)[aIndex]; |
|
1181 |
|
1182 if (iPhoneOwner == attendee) |
|
1183 { |
|
1184 iPhoneOwner = NULL; |
|
1185 } |
|
1186 |
|
1187 if (iMeetingOrganizer == attendee) |
|
1188 { |
|
1189 iMeetingOrganizer = NULL; |
|
1190 } |
|
1191 |
|
1192 iAttendeeList->Remove(aIndex); |
|
1193 delete attendee; |
|
1194 } |
|
1195 |
|
1196 |
|
1197 EXPORT_C CAgnAttendee* CAgnEntry::PhoneOwner() const |
|
1198 /** Get Phone owner as attendee object |
|
1199 |
|
1200 @internalComponent |
|
1201 */ |
|
1202 { |
|
1203 return iPhoneOwner; |
|
1204 } |
|
1205 |
|
1206 |
|
1207 EXPORT_C void CAgnEntry::SetPhoneOwnerL(CAgnAttendee* aAttendee) |
|
1208 /** Set Phone owner as attendee, this must be an existing attendee |
|
1209 |
|
1210 @internalComponent |
|
1211 @leave KErrNotFound if the passed attendee is not matching anyone in the current list |
|
1212 */ |
|
1213 { |
|
1214 TInt ownerExists = KErrNotFound; |
|
1215 |
|
1216 if (iAttendeeList) |
|
1217 { |
|
1218 const TInt KCount = iAttendeeList->Count(); |
|
1219 |
|
1220 for (TInt i = 0; i < KCount; ++i) |
|
1221 { |
|
1222 if (aAttendee == (*iAttendeeList)[i]) |
|
1223 { |
|
1224 ownerExists = i; |
|
1225 } |
|
1226 } |
|
1227 } |
|
1228 |
|
1229 if (ownerExists == KErrNotFound && aAttendee != iMeetingOrganizer) |
|
1230 { |
|
1231 User::Leave(KErrNotFound); |
|
1232 } |
|
1233 |
|
1234 iPhoneOwner = aAttendee; |
|
1235 } |
|
1236 |
|
1237 |
|
1238 EXPORT_C void CAgnEntry::SetDTStampUtcL(const TTime& aDTStampUtc) |
|
1239 /** |
|
1240 @internalComponent |
|
1241 */ |
|
1242 { |
|
1243 iDTStampUtc = aDTStampUtc; |
|
1244 } |
|
1245 |
|
1246 |
|
1247 EXPORT_C const TTime& CAgnEntry::DTStampUtcL() const |
|
1248 /** |
|
1249 @internalComponent |
|
1250 @return TTime |
|
1251 */ |
|
1252 { |
|
1253 return iDTStampUtc; |
|
1254 } |
|
1255 |
|
1256 EXPORT_C TInt CAgnEntry::CategoryCount() const |
|
1257 /** Gets the number of categories owned by the entry. |
|
1258 |
|
1259 @internalComponent |
|
1260 @return The number of categories. |
|
1261 */ |
|
1262 { |
|
1263 if ( !iCategoryList ) |
|
1264 { |
|
1265 return 0; |
|
1266 } |
|
1267 |
|
1268 return iCategoryList->Count(); |
|
1269 } |
|
1270 |
|
1271 |
|
1272 EXPORT_C void CAgnEntry::AddCategoryL(CAgnCategory* aCategory) |
|
1273 /** Appends a category to the entry's list of categories. |
|
1274 |
|
1275 The entry takes ownership of the category specified. |
|
1276 |
|
1277 @internalComponent |
|
1278 @param aCategory The category to be added |
|
1279 @leave KErrAlreadyExists if category already present |
|
1280 */ |
|
1281 { |
|
1282 // Add an category for this entry |
|
1283 if ( !iCategoryList ) |
|
1284 { |
|
1285 iCategoryList = new (ELeave) RPointerArray<CAgnCategory>; |
|
1286 } |
|
1287 |
|
1288 // Need to check that the category isn't already in the list |
|
1289 if ( ! CategoryExist(*aCategory) ) |
|
1290 { |
|
1291 iCategoryList->AppendL(aCategory); |
|
1292 } |
|
1293 else |
|
1294 { |
|
1295 User::Leave(KErrAlreadyExists); |
|
1296 } |
|
1297 } |
|
1298 |
|
1299 TBool CAgnEntry::CategoryExist(CAgnCategory& aSearchCategory) const |
|
1300 /** Check if category is already present |
|
1301 |
|
1302 @internalComponent |
|
1303 */ |
|
1304 { |
|
1305 if (!iCategoryList) |
|
1306 { |
|
1307 return EFalse; |
|
1308 } |
|
1309 |
|
1310 //return ETrue if aSearchCategory belongs to this object, otherwise return EFalse |
|
1311 const TInt KNumCatList = iCategoryList->Count(); |
|
1312 |
|
1313 for ( TInt i = 0; i < KNumCatList; ++i ) |
|
1314 { |
|
1315 CAgnCategory& category = FetchCategory(i); |
|
1316 |
|
1317 CCalCategory::TCalCategoryType categoryType = category.Category(); |
|
1318 |
|
1319 if ( categoryType == aSearchCategory.Category()) |
|
1320 { |
|
1321 if ( categoryType == CCalCategory::ECalExtended ) // Need to compare names |
|
1322 { |
|
1323 if ( category.ExtendedCategoryName().CompareF(aSearchCategory.ExtendedCategoryName()) == 0 ) |
|
1324 { |
|
1325 return ETrue; |
|
1326 } |
|
1327 } |
|
1328 else |
|
1329 { |
|
1330 return ETrue; |
|
1331 } |
|
1332 } |
|
1333 } |
|
1334 |
|
1335 return EFalse; |
|
1336 } |
|
1337 |
|
1338 |
|
1339 EXPORT_C CAgnCategory& CAgnEntry::FetchCategory(TInt aIndex) const |
|
1340 /** Gets the indexed category. |
|
1341 |
|
1342 @internalComponent |
|
1343 @param aIndex Index into the entry's list of categories. Must be valid |
|
1344 or a panic occurs. |
|
1345 @return Pointer to the category located at the index specified. |
|
1346 */ |
|
1347 { |
|
1348 __ASSERT_DEBUG(iCategoryList != NULL, Panic(EAgmErrCategoryListNotInitialised)); |
|
1349 __ASSERT_DEBUG(aIndex < iCategoryList->Count(), Panic(EAgmErrCategoryOutOfRange)); |
|
1350 |
|
1351 return *(*iCategoryList)[aIndex]; |
|
1352 } |
|
1353 |
|
1354 |
|
1355 EXPORT_C void CAgnEntry::DeleteCategory(TInt aIndex) |
|
1356 /** Deletes the indexed category. |
|
1357 |
|
1358 @internalComponent |
|
1359 @param aIndex Index into the entry's list of categories. Must be valid |
|
1360 or a panic occurs. |
|
1361 */ |
|
1362 { |
|
1363 __ASSERT_DEBUG(iCategoryList != NULL, Panic(EAgmErrCategoryListNotInitialised)); |
|
1364 CAgnCategory* category = (*iCategoryList)[aIndex]; |
|
1365 delete category; |
|
1366 iCategoryList->Remove(aIndex); |
|
1367 |
|
1368 if ( iCategoryList->Count() == 0 ) |
|
1369 { |
|
1370 iCategoryList->ResetAndDestroy(); |
|
1371 delete iCategoryList; |
|
1372 iCategoryList=NULL; |
|
1373 } |
|
1374 } |
|
1375 |
|
1376 |
|
1377 EXPORT_C const TDesC& CAgnEntry::Description() const |
|
1378 /** Gets the notes text. |
|
1379 |
|
1380 If no notes text has been set, a empty descriptor (KNullDesC) is returned. |
|
1381 |
|
1382 @internalComponent |
|
1383 @capability ReadUserData |
|
1384 @return The notes text. |
|
1385 */ |
|
1386 { |
|
1387 if ( iDescription ) |
|
1388 { |
|
1389 return *iDescription; |
|
1390 } |
|
1391 return KNullDesC; |
|
1392 } |
|
1393 |
|
1394 |
|
1395 EXPORT_C TBool CAgnEntry::DescriptionIsLoaded() const |
|
1396 /** Check notes is loaded |
|
1397 |
|
1398 @internalComponent |
|
1399 @capability ReadUserData |
|
1400 @return Boolean to indicate if loaded or not |
|
1401 */ |
|
1402 { |
|
1403 if ( !iDescription && iDescriptionStreamId != KNullStreamId ) |
|
1404 { |
|
1405 return EFalse; |
|
1406 } |
|
1407 |
|
1408 return ETrue; |
|
1409 } |
|
1410 |
|
1411 |
|
1412 EXPORT_C void CAgnEntry::SetDescription(HBufC* aDescription) |
|
1413 /** Sets the notes text. |
|
1414 |
|
1415 This object takes ownership of aNotes. |
|
1416 |
|
1417 @internalComponent |
|
1418 @param aNotes Notes text. |
|
1419 */ |
|
1420 { |
|
1421 delete iDescription; |
|
1422 iDescription = aDescription; |
|
1423 } |
|
1424 |
|
1425 |
|
1426 EXPORT_C CAgnEntry::TAgnDataChange CAgnEntry::DescriptionChange() const |
|
1427 /** Check if the notes changed |
|
1428 |
|
1429 1. If iDescription is NULL, The description has never been added or never been loaded - No Change |
|
1430 2. If iDescriptionStreamId is not KNullStreamId and iDecription is KNullDesC, The descrioption has been deleted (CAgnEntry::SetDescrioprion() can be used to delete description) |
|
1431 3. If iDescriptionStreamId is not KNullStreamId and iDecription is not KNullDesC, The descrioption could be updated |
|
1432 4. If iDescriptionStreamId is KNullStreamId and iDescription is not KNullDesC, The description has been added |
|
1433 |
|
1434 @internalComponent |
|
1435 @return TAgnDescriptionChange value indicating the type of change |
|
1436 */ |
|
1437 { |
|
1438 TAgnDataChange change = EAgnDataNoChange; |
|
1439 if ( iDescription ) |
|
1440 { |
|
1441 if ( iDescriptionStreamId != KNullStreamId ) |
|
1442 { |
|
1443 if ( *iDescription == KNullDesC ) |
|
1444 { |
|
1445 change = EAgnDataDeleted; |
|
1446 } |
|
1447 else |
|
1448 { |
|
1449 change = EAgnDataUpdated; |
|
1450 } |
|
1451 } |
|
1452 else if ( *iDescription != KNullDesC ) |
|
1453 { |
|
1454 change = EAgnDataAdded; |
|
1455 } |
|
1456 } |
|
1457 |
|
1458 return change; |
|
1459 } |
|
1460 |
|
1461 |
|
1462 EXPORT_C CAgnEntry::TAgnDataChange CAgnEntry::SummaryChange() const |
|
1463 /** Check if the summary changed |
|
1464 |
|
1465 1. If iSummary is NULL, The Summary has never been added or laoded- No Change |
|
1466 2. If iSummaryStreamId is not KNullStreamId and iSummary is KNullDesC, The Summary has been deleted (CAgnEntry::SetSummary() can be used to delete description) |
|
1467 3. If iSummaryStreamId is not KNullStreamId and iSummary is not KNullDesC, The Summary could be updated |
|
1468 4. If iSummaryStreamId is KNullStreamId and iSummary is not KNullDesC, The Summary has been added |
|
1469 |
|
1470 @internalComponent |
|
1471 @return TAgnSummaryChange value indicating the type of change |
|
1472 */ |
|
1473 { |
|
1474 TAgnDataChange change = EAgnDataNoChange; |
|
1475 |
|
1476 if ( iSummary ) |
|
1477 { |
|
1478 if ( iSummaryStreamId != KNullStreamId ) |
|
1479 { |
|
1480 if ( *iSummary == KNullDesC ) |
|
1481 { |
|
1482 change = EAgnDataDeleted; |
|
1483 } |
|
1484 else |
|
1485 { |
|
1486 change = EAgnDataUpdated; |
|
1487 } |
|
1488 } |
|
1489 else if ( *iSummary != KNullDesC ) |
|
1490 { |
|
1491 change = EAgnDataAdded; |
|
1492 } |
|
1493 } |
|
1494 |
|
1495 return change; |
|
1496 } |
|
1497 |
|
1498 |
|
1499 EXPORT_C CAgnEntry::TAgnDataChange CAgnEntry::AlarmActionChange() const |
|
1500 /** Check if the alarm action changed |
|
1501 |
|
1502 1. If iAlarmActionDeleted is true, alarm has been deleted |
|
1503 2. If iAlarmActionStreamId is KNullStreamId and iAlarmAction is not NULL, alarm has been added |
|
1504 3. If iAlarmActionStreamId is not KNullStreamId and iAlarmAction is not KNullDesC, The AlarmAction could be updated |
|
1505 |
|
1506 @internalComponent |
|
1507 @return TAgnAlarmActionChange value indicating the type of change |
|
1508 */ |
|
1509 { |
|
1510 TAgnDataChange change = EAgnDataNoChange; |
|
1511 |
|
1512 if ( IsFlagSet(EAgnAlarmActionDeleted) ) |
|
1513 { |
|
1514 change = EAgnDataDeleted; |
|
1515 } |
|
1516 else if ( iAlarmAction ) |
|
1517 { |
|
1518 if ( iAlarmActionStreamId == KNullStreamId ) |
|
1519 { |
|
1520 change = EAgnDataAdded; |
|
1521 } |
|
1522 else |
|
1523 { |
|
1524 change = EAgnDataUpdated; |
|
1525 } |
|
1526 } |
|
1527 |
|
1528 return change; |
|
1529 } |
|
1530 |
|
1531 |
|
1532 EXPORT_C const TStreamId& CAgnEntry::DescriptionStreamId() const |
|
1533 /** Gets the ID of the embedded stream store in which the description has been stored. |
|
1534 |
|
1535 @internalComponent |
|
1536 @return The ID for the stream store in which the description has been stored. |
|
1537 */ |
|
1538 { |
|
1539 return iDescriptionStreamId; |
|
1540 } |
|
1541 |
|
1542 |
|
1543 EXPORT_C void CAgnEntry::SetDescriptionStreamId(const TStreamId& aStreamId) |
|
1544 /** Sets the ID of the embedded stream store in which the description has been stored. |
|
1545 |
|
1546 @internalComponent |
|
1547 @param The ID for the stream store in which the description has been stored. |
|
1548 */ |
|
1549 { |
|
1550 iDescriptionStreamId = aStreamId; |
|
1551 } |
|
1552 |
|
1553 |
|
1554 EXPORT_C void CAgnEntry::SetSummaryStreamId(const TStreamId& aStreamId) |
|
1555 /** Sets the ID of the embedded stream store in which the summary has been stored. |
|
1556 |
|
1557 @internalComponent |
|
1558 @param The ID for the stream store in which the summary has been stored. |
|
1559 */ |
|
1560 { |
|
1561 iSummaryStreamId = aStreamId; |
|
1562 } |
|
1563 |
|
1564 EXPORT_C const TStreamId& CAgnEntry::SummaryStreamId() const |
|
1565 /** Gets the ID of the embedded stream store in which the summary has been stored. |
|
1566 |
|
1567 @internalComponent |
|
1568 @return The ID for the stream store in which the summary has been stored. |
|
1569 */ |
|
1570 { |
|
1571 return iSummaryStreamId; |
|
1572 } |
|
1573 |
|
1574 /** |
|
1575 @internalComponent |
|
1576 @capability None |
|
1577 @return TPtrC8 |
|
1578 */ |
|
1579 EXPORT_C const TDesC8& CAgnEntry::Guid() const |
|
1580 { |
|
1581 return iGsData->Guid(); |
|
1582 } |
|
1583 |
|
1584 EXPORT_C void CAgnEntry::SetMethod(CCalEntry::TMethod aMethod) |
|
1585 { |
|
1586 iGsData->SetMethod(aMethod); |
|
1587 } |
|
1588 |
|
1589 EXPORT_C void CAgnEntry::SetGuid(HBufC8* aGuid) |
|
1590 /** |
|
1591 @internalComponent |
|
1592 */ |
|
1593 { |
|
1594 iGsData->SetGuid(aGuid); |
|
1595 } |
|
1596 |
|
1597 EXPORT_C CGsData::TGsDataType CAgnEntry::GsDataType() const |
|
1598 /** |
|
1599 @internalComponent |
|
1600 */ |
|
1601 { |
|
1602 return iGsData->GsDataType(); |
|
1603 } |
|
1604 |
|
1605 EXPORT_C CCalEntry::TMethod CAgnEntry::Method() const |
|
1606 /** |
|
1607 @internalComponent |
|
1608 */ |
|
1609 { |
|
1610 return iGsData->Method(); |
|
1611 } |
|
1612 |
|
1613 EXPORT_C TInt CAgnEntry::SequenceNumber() const |
|
1614 /** |
|
1615 @internalComponent |
|
1616 */ |
|
1617 { |
|
1618 return iGsData->SequenceNumber(); |
|
1619 } |
|
1620 |
|
1621 |
|
1622 EXPORT_C void CAgnEntry::SetSequenceNumber(TInt aSeqNum) |
|
1623 { |
|
1624 iGsData->SetSequenceNumber(aSeqNum); |
|
1625 } |
|
1626 /** |
|
1627 @internalComponent |
|
1628 @capability None |
|
1629 @return TTime |
|
1630 */ |
|
1631 EXPORT_C TAgnCalendarTime CAgnEntry::RecurrenceId() const |
|
1632 { |
|
1633 return iGsData->RecurrenceId(); |
|
1634 } |
|
1635 |
|
1636 /** |
|
1637 @internalComponent |
|
1638 */ |
|
1639 EXPORT_C CalCommon::TRecurrenceRange CAgnEntry::RecurrenceRange() const |
|
1640 { |
|
1641 return iGsData->RecurrenceRange(); |
|
1642 } |
|
1643 |
|
1644 EXPORT_C TCalLocalUid CAgnEntry::ParentId() const |
|
1645 { |
|
1646 __ASSERT_DEBUG(GsDataType() == CGsData::EChild, Panic(EAgmErrNotChildEntry)); |
|
1647 |
|
1648 return (static_cast<CGsChildData*>(iGsData)->ParentId()); |
|
1649 } |
|
1650 |
|
1651 EXPORT_C void CAgnEntry::SetParentId(TCalLocalUid aParentId) |
|
1652 { |
|
1653 __ASSERT_DEBUG(GsDataType() == CGsData::EChild, Panic(EAgmErrNotChildEntry)); |
|
1654 |
|
1655 static_cast<CGsChildData*>(iGsData)->SetParentId(aParentId); |
|
1656 } |
|
1657 |
|
1658 EXPORT_C void CAgnEntry::UpdateRecurrenceIdL(const TAgnCalendarTime& aRecId) |
|
1659 { |
|
1660 __ASSERT_DEBUG(GsDataType() == CGsData::EChild, Panic(EAgmErrNotChildEntry)); |
|
1661 |
|
1662 CGsChildData* childData = static_cast<CGsChildData*>(iGsData); |
|
1663 TTimeIntervalHours hoursChange; |
|
1664 aRecId.UtcL().HoursFrom(RecurrenceId().UtcL(), hoursChange); |
|
1665 childData->SetRecurrenceId(aRecId); |
|
1666 } |
|
1667 |
|
1668 EXPORT_C void CAgnEntry::SetRecurrenceRangeL(CalCommon::TRecurrenceRange aRange) |
|
1669 { |
|
1670 if (RptDef()) |
|
1671 { |
|
1672 __ASSERT_DEBUG(aRange == CalCommon::EThisAndFuture || aRange == CalCommon::EThisAndPrior, User::Leave(KErrCorrupt)); |
|
1673 } |
|
1674 else |
|
1675 { |
|
1676 __ASSERT_DEBUG(aRange == CalCommon::EThisOnly, User::Leave(KErrCorrupt)); |
|
1677 } |
|
1678 |
|
1679 CGsChildData* childData = static_cast<CGsChildData*>(iGsData); |
|
1680 childData->SetRecurrenceRange(aRange); |
|
1681 } |
|
1682 |
|
1683 EXPORT_C TBool CAgnEntry::HasChildren() const |
|
1684 { |
|
1685 if (GsDataType() == CGsData::EParent && ChildIds().Count() > 0) |
|
1686 { |
|
1687 return ETrue; |
|
1688 } |
|
1689 return EFalse; |
|
1690 } |
|
1691 |
|
1692 EXPORT_C const RArray<TGsChildRefData>& CAgnEntry::ChildIds() const |
|
1693 { |
|
1694 __ASSERT_DEBUG(GsDataType() == CGsData::EParent, Panic(EAgmErrNotParentEntry)); |
|
1695 |
|
1696 return (static_cast<CGsParentData*>(iGsData)->ChildIds()); |
|
1697 } |
|
1698 |
|
1699 EXPORT_C void CAgnEntry::AddChildIdL(const TGsChildRefData& aChildRefData) |
|
1700 { |
|
1701 __ASSERT_DEBUG(GsDataType() == CGsData::EParent, Panic(EAgmErrNotParentEntry)); |
|
1702 |
|
1703 static_cast<CGsParentData*>(iGsData)->AddChildIdL(aChildRefData); |
|
1704 } |
|
1705 |
|
1706 EXPORT_C void CAgnEntry::RemoveChildId(TCalLocalUid aId) |
|
1707 { |
|
1708 __ASSERT_DEBUG(GsDataType() == CGsData::EParent, Panic(EAgmErrNotParentEntry)); |
|
1709 |
|
1710 static_cast<CGsParentData*>(iGsData)->RemoveChildId(aId); |
|
1711 } |
|
1712 |
|
1713 EXPORT_C void CAgnEntry::SetRecurrenceIdFromParentL(const CAgnEntry& aParentEntry) |
|
1714 {//Set the recurrence id and range by its parent data. |
|
1715 __ASSERT_DEBUG(GsDataType() == CGsData::EChild, Panic(EAgmErrNotChildEntry)); |
|
1716 TAgnCalendarTime recurid = RecurrenceId(); |
|
1717 |
|
1718 CGsChildData* childGsData = static_cast<CGsChildData*>(iGsData); |
|
1719 if ( ! recurid.IsSet()) |
|
1720 { |
|
1721 recurid = aParentEntry.GetChildRecurrenceId(LocalUid()); |
|
1722 childGsData->SetRecurrenceId(recurid); |
|
1723 } |
|
1724 } |
|
1725 |
|
1726 TAgnCalendarTime CAgnEntry::GetChildRecurrenceId(TCalLocalUid aChildId) const |
|
1727 {//Get the recurrence id for one of its children |
|
1728 const RArray<TGsChildRefData>& KChildIds = ChildIds(); |
|
1729 |
|
1730 const TInt KCount((KChildIds.Count())); |
|
1731 TAgnCalendarTime recurId; |
|
1732 |
|
1733 for (TInt i = 0; i < KCount; ++i) |
|
1734 { |
|
1735 if (KChildIds[i].ChildId() == aChildId) |
|
1736 { |
|
1737 recurId = KChildIds[i].RecurrenceId(); |
|
1738 break; |
|
1739 } |
|
1740 } |
|
1741 return recurId; |
|
1742 } |
|
1743 |
|
1744 |
|
1745 EXPORT_C void CAgnEntry::SetAlarmAction(CAgnContent* aAlarmAction) |
|
1746 /** Set an alarm action object to the Agenda entry. |
|
1747 The Agenda Entry takes ownership of the passed object. |
|
1748 @internalComponent |
|
1749 */ |
|
1750 { |
|
1751 if(iAlarmAction && !aAlarmAction && iAlarmActionStreamId != KNullStreamId) |
|
1752 { |
|
1753 SetFlagOn(EAgnAlarmActionDeleted); |
|
1754 } |
|
1755 |
|
1756 delete iAlarmAction; |
|
1757 |
|
1758 // Take ownership of the content. |
|
1759 iAlarmAction = aAlarmAction; |
|
1760 } |
|
1761 |
|
1762 |
|
1763 EXPORT_C TBool CAgnEntry::AlarmActionIsLoaded() const |
|
1764 /** Check if Alarm action object is loaded from the stream |
|
1765 @internalComponent |
|
1766 */ |
|
1767 { |
|
1768 if ( !iAlarmAction && iAlarmActionStreamId != KNullStreamId && ! IsFlagSet(EAgnAlarmActionDeleted) ) |
|
1769 { |
|
1770 return EFalse; |
|
1771 } |
|
1772 |
|
1773 return ETrue; |
|
1774 } |
|
1775 |
|
1776 |
|
1777 EXPORT_C CAgnContent* CAgnEntry::AlarmAction() const |
|
1778 /** Get the Alarm action object |
|
1779 @internalComponent |
|
1780 */ |
|
1781 { |
|
1782 return iAlarmAction; |
|
1783 } |
|
1784 |
|
1785 |
|
1786 EXPORT_C void CAgnEntry::SetAlarmActionStreamId(const TStreamId& aStreamId) |
|
1787 /** Set the Alarm action stream id |
|
1788 @internalComponent |
|
1789 */ |
|
1790 { |
|
1791 iAlarmActionStreamId = aStreamId; |
|
1792 } |
|
1793 |
|
1794 |
|
1795 EXPORT_C const TStreamId& CAgnEntry::AlarmActionStreamId() const |
|
1796 /** Get the Alarm action stream id |
|
1797 @internalComponent |
|
1798 */ |
|
1799 { |
|
1800 return iAlarmActionStreamId; |
|
1801 } |
|
1802 |
|
1803 EXPORT_C void CAgnEntry::AddAttachmentL(CAgnAttachment* aAttachment) |
|
1804 { |
|
1805 if (!iAttachments) |
|
1806 { |
|
1807 iAttachments = new (ELeave) RPointerArray<CAgnAttachment>; |
|
1808 } |
|
1809 if (aAttachment) |
|
1810 { |
|
1811 iAttachments->AppendL(aAttachment); |
|
1812 } |
|
1813 } |
|
1814 |
|
1815 EXPORT_C TInt CAgnEntry::DeleteAttachmentL(const CAgnAttachment& aAttachment) |
|
1816 { |
|
1817 TInt ret = -1; |
|
1818 if (iAttachments) |
|
1819 { |
|
1820 const TInt KAttachmentCount = iAttachments->Count(); |
|
1821 for (TInt i = 0; i < KAttachmentCount; ++i) |
|
1822 { |
|
1823 CAgnAttachment* attachToCompare = (*iAttachments)[i]; |
|
1824 if (attachToCompare->CompareL(aAttachment)) |
|
1825 { |
|
1826 ret = i; |
|
1827 delete attachToCompare; |
|
1828 iAttachments->Remove(i); |
|
1829 break; |
|
1830 } |
|
1831 } |
|
1832 } |
|
1833 return ret; |
|
1834 } |
|
1835 |
|
1836 EXPORT_C CAgnAttachment& CAgnEntry::Attachment(TInt aIndex) const |
|
1837 { |
|
1838 return *(*iAttachments)[aIndex]; |
|
1839 } |
|
1840 |
|
1841 EXPORT_C TInt CAgnEntry::AttachmentCount() const |
|
1842 { |
|
1843 if (iAttachments) |
|
1844 { |
|
1845 return iAttachments->Count(); |
|
1846 } |
|
1847 return 0; |
|
1848 } |
|
1849 |
|
1850 /** |
|
1851 Sets the user integer for this entry. |
|
1852 |
|
1853 @param aUserInt The new value of the user integer. |
|
1854 @internalComponent |
|
1855 */ |
|
1856 EXPORT_C void CAgnEntry::SetUserInt( TUint32 aUserInt ) |
|
1857 { |
|
1858 CAgnSimpleEntry::SetUserInt(aUserInt); |
|
1859 } |
|
1860 |
|
1861 /** |
|
1862 Gets the user integer of this entry. |
|
1863 |
|
1864 @return The user integer. |
|
1865 @internalComponent |
|
1866 */ |
|
1867 EXPORT_C TUint32 CAgnEntry::UserInt() const |
|
1868 { |
|
1869 return CAgnSimpleEntry::UserInt(); |
|
1870 } |
|
1871 |
|
1872 EXPORT_C void CAgnEntry::ExternalizeToBufferL(RWriteStream& aWriteStream) const |
|
1873 /** Used for passing the data to the between client and server |
|
1874 @internalComponent |
|
1875 */ |
|
1876 { |
|
1877 ExternalizeEntryL(aWriteStream, ETrue); |
|
1878 ExternalizeGsDataL(aWriteStream, ETrue); |
|
1879 |
|
1880 if ( iDescription ) |
|
1881 { |
|
1882 aWriteStream.WriteUint8L(ETrue); |
|
1883 aWriteStream << *iDescription; |
|
1884 } |
|
1885 else |
|
1886 { |
|
1887 aWriteStream.WriteUint8L(EFalse); |
|
1888 } |
|
1889 |
|
1890 if ( iSummary ) |
|
1891 { |
|
1892 aWriteStream.WriteUint8L(ETrue); |
|
1893 aWriteStream << *iSummary; |
|
1894 } |
|
1895 else |
|
1896 { |
|
1897 aWriteStream.WriteUint8L(EFalse); |
|
1898 } |
|
1899 |
|
1900 TBool hasAlarmContent = iAlarmAction?ETrue:EFalse; |
|
1901 aWriteStream.WriteUint8L(hasAlarmContent); |
|
1902 if ( hasAlarmContent ) |
|
1903 { |
|
1904 aWriteStream << *iAlarmAction; |
|
1905 } |
|
1906 |
|
1907 aWriteStream.WriteUint8L(IsFlagSet(EAgnAlarmActionDeleted)); |
|
1908 } |
|
1909 |
|
1910 |
|
1911 EXPORT_C void CAgnEntry::InternalizeFromBufferL(RReadStream& aReadStream) |
|
1912 /** Used for passing the data to the between client and server |
|
1913 @internalComponent |
|
1914 */ |
|
1915 { |
|
1916 InternalizeEntryL(aReadStream, ETrue); |
|
1917 InternalizeGsDataL(aReadStream, ETrue); |
|
1918 |
|
1919 delete iDescription; |
|
1920 iDescription = NULL; |
|
1921 if(aReadStream.ReadUint8L())//iDescription is not NULL |
|
1922 {//The following does not allocate KMaxTInt cells on heap |
|
1923 iDescription = HBufC::NewL(aReadStream, KMaxTInt); |
|
1924 } |
|
1925 |
|
1926 delete iSummary; |
|
1927 iSummary = NULL; |
|
1928 |
|
1929 if(aReadStream.ReadUint8L())//iSummary is not NULL |
|
1930 {//The following does not allocate KMaxTInt cells on heap |
|
1931 iSummary = HBufC::NewL(aReadStream, KMaxTInt); |
|
1932 } |
|
1933 |
|
1934 delete iAlarmAction; |
|
1935 iAlarmAction = NULL; |
|
1936 TBool hasAlarmContent = aReadStream.ReadUint8L(); |
|
1937 if ( hasAlarmContent ) |
|
1938 { |
|
1939 iAlarmAction = new (ELeave) CAgnContent; |
|
1940 aReadStream >> *iAlarmAction; |
|
1941 } |
|
1942 |
|
1943 if (aReadStream.ReadUint8L()) |
|
1944 { |
|
1945 SetFlagOn(EAgnAlarmActionDeleted); |
|
1946 } |
|
1947 else |
|
1948 { |
|
1949 SetFlagOff(EAgnAlarmActionDeleted); |
|
1950 } |
|
1951 // Externalize the entry details to the buffer |
|
1952 // Any rich text components will be stored in the textStream buffer |
|
1953 } |
|
1954 |
|
1955 |
|
1956 EXPORT_C CCalEntry::TTransp CAgnEntry::BusyStatus() const |
|
1957 /** Get transparency value |
|
1958 @internalComponent |
|
1959 */ |
|
1960 { |
|
1961 return static_cast<CCalEntry::TTransp>(iBusyStatus); |
|
1962 } |
|
1963 |
|
1964 |
|
1965 EXPORT_C void CAgnEntry::SetBusyStatusL(CCalEntry::TTransp aBusyStatus) |
|
1966 /** Set transparency value |
|
1967 @internalComponent |
|
1968 @leave KErrArgument if passed parameter is negative |
|
1969 */ |
|
1970 { |
|
1971 if ( aBusyStatus < 0 ) |
|
1972 { |
|
1973 User::Leave( KErrArgument ); |
|
1974 } |
|
1975 |
|
1976 iBusyStatus = aBusyStatus; |
|
1977 } |
|
1978 |
|
1979 EXPORT_C void CAgnEntry::GeoValue(TReal& aLatitude, TReal& aLongitude) const |
|
1980 { |
|
1981 aLatitude=iLatitude; |
|
1982 aLongitude=iLongitude; |
|
1983 } |
|
1984 |
|
1985 /** Set GEO - Latitude and Longitude values for the entry |
|
1986 Latitude is bound between +-0-90 degrees |
|
1987 Longitude is bound between +-0-180 degrees |
|
1988 @internalComponent |
|
1989 @leave KErrArgument if passed parameter is out of bounds. |
|
1990 */ |
|
1991 EXPORT_C void CAgnEntry::SetGeoValueL(const TReal& aLatitude, const TReal& aLongitude) |
|
1992 { |
|
1993 // Bounds checking |
|
1994 __ASSERT_ALWAYS( |
|
1995 ((aLatitude >= KCalGEOMinLatitude && aLatitude <= KCalGEOMaxLatitude) || aLatitude == KGEODefaultValue) |
|
1996 && ((aLongitude >= KCalGEOMinLongitude && aLongitude <= KCalGEOMaxLongitude) || aLongitude == KGEODefaultValue), |
|
1997 User::Leave(KErrArgument)); |
|
1998 |
|
1999 // Truncate to KGEOMaxDecimals decimal places |
|
2000 TReal truncatedLatitude; |
|
2001 TReal truncatedLongitude; |
|
2002 Math::Round(truncatedLatitude,aLatitude,KCalGEOMaxDecimalPlaces); |
|
2003 Math::Round(truncatedLongitude,aLongitude,KCalGEOMaxDecimalPlaces); |
|
2004 |
|
2005 iLatitude = truncatedLatitude; |
|
2006 iLongitude = truncatedLongitude; |
|
2007 } |
|
2008 |
|
2009 // verify entry is valid before storing it |
|
2010 EXPORT_C void CAgnEntry::VerifyBeforeStoreL() |
|
2011 { |
|
2012 //Check entry time |
|
2013 if ( Type() != CCalEntry::ETodo ) |
|
2014 { |
|
2015 __ASSERT_ALWAYS(StartTime().IsSet(), Panic(EAgmErrTimeNotSet)); |
|
2016 if ( Type() != CCalEntry::EReminder ) |
|
2017 { |
|
2018 __ASSERT_ALWAYS(EndTime().IsSet(), Panic(EAgmErrTimeNotSet)); |
|
2019 } |
|
2020 } |
|
2021 //Check repeating rule |
|
2022 if ( RptDef() ) |
|
2023 { |
|
2024 // check entry's repeat rule valid |
|
2025 if ( RptDef()->InvariantL() != KErrNone ) |
|
2026 { |
|
2027 const TAgnRpt* rptRule = RptDef()->RRule(); |
|
2028 __ASSERT_ALWAYS(rptRule, User::Leave(KErrCorrupt)); // this can never be NULL if Invariant returns an error |
|
2029 |
|
2030 // if entry has only one instance, clear the repeat rule |
|
2031 if ( rptRule->InstanceCountL() == 1 ) |
|
2032 { |
|
2033 RptDef()->ClearRRule(); |
|
2034 } |
|
2035 else |
|
2036 { |
|
2037 User::Leave(KErrArgument); |
|
2038 } |
|
2039 } |
|
2040 |
|
2041 else if (RptDef()->Exceptions()) |
|
2042 { |
|
2043 RptDef()->PruneExceptionsL(); |
|
2044 } |
|
2045 |
|
2046 //check the RDates here |
|
2047 TInt i = 0; |
|
2048 while (RptDef()->SporadicDateList() && i < RptDef()->SporadicDateList()->Count()) |
|
2049 { |
|
2050 const TAgnCalendarTime& KSporadicDate = (*RptDef()->SporadicDateList())[i]; |
|
2051 if (RptDef()->IsARepeatRuleDateInstanceL(KSporadicDate.LocalL())) |
|
2052 { |
|
2053 RptDef()->RemoveSporadicDate(KSporadicDate); |
|
2054 } |
|
2055 else if (EntryTime() == KSporadicDate) |
|
2056 { |
|
2057 // the DTSTART may not be checked in IsARepeatRuleDateInstance, so check it explicitly |
|
2058 RptDef()->RemoveSporadicDate(KSporadicDate); |
|
2059 } |
|
2060 else |
|
2061 { |
|
2062 // this sporadic date is ok |
|
2063 ++i; |
|
2064 } |
|
2065 } |
|
2066 |
|
2067 const TAgnRpt* rptRule = RptDef()->RRule(); |
|
2068 if(!rptRule && !(RptDef()->HasSporadicDates())) |
|
2069 { |
|
2070 ClearRepeat(); |
|
2071 } |
|
2072 } |
|
2073 } |
|
2074 |
|
2075 void CAgnEntry::SetFlagOn(TFlags aFlag) |
|
2076 { |
|
2077 iFlags |= aFlag; |
|
2078 } |
|
2079 |
|
2080 void CAgnEntry::SetFlagOff(TFlags aFlag) |
|
2081 { |
|
2082 iFlags &= ~aFlag; |
|
2083 } |
|
2084 |
|
2085 TBool CAgnEntry::IsFlagSet(TFlags aFlag) const |
|
2086 { |
|
2087 return (iFlags & aFlag); |
|
2088 } |