diff -r 000000000000 -r f979ecb2b13e pimappservices/calendar/client/src/calentryimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pimappservices/calendar/client/src/calentryimpl.cpp Tue Feb 02 10:12:19 2010 +0200 @@ -0,0 +1,1812 @@ +// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include "calentryimpl.h" + +#include "calclient.h" +#include "agsalarm.h" +#include "agmattachment.h" +#include "agmdate.h" +#include "agmentry.h" +#include "agmpanic.h" +#include "agmcategory.h" +#include "agmattendee.h" +#include "agmcontent.h" +#include +#include "calcategoryimpl.h" +#include +#include +#include +#include "calsessionimpl.h" +#include "caluserimpl.h" + +const TInt KAttendeeGranularity = 2; +const TInt KCategoryGranularity = 1; +const TInt KAttachmentGranularity = 1; + + +CCalEntryImpl::~CCalEntryImpl() + { + if(iSessionImpl) + { + iSessionImpl->DecrementReferenceCount(); + } + + if (iLiteEntry) + { + iLiteEntry->DecrementRefCount(); + } + if(iCalAttachmentList) + { + iCalAttachmentList->ResetAndDestroy(); + delete iCalAttachmentList; + } + if(iCalAttendeeList) + { + iCalAttendeeList->ResetAndDestroy(); + delete iCalAttendeeList; + } + if(iCalCategoryList) + { + iCalCategoryList->ResetAndDestroy(); + delete iCalCategoryList; + } + delete iCalOrganizer; + delete iFullEntry; + } + +CCalEntryImpl::CCalEntryImpl() + { + } + +CCalEntryImpl::CCalEntryImpl(CAgnEntry& aEntry, CCalSessionImpl& aSessionImpl) + : iFullEntry(&aEntry), iSessionImpl(&aSessionImpl) + { + iSessionImpl->IncrementReferenceCount(); + } + + +CCalEntryImpl::CCalEntryImpl(CCalLiteEntry& aEntry, CCalSessionImpl& aSessionImpl) + : iLiteEntry(&aEntry), iSessionImpl(&aSessionImpl) + { + iSessionImpl->IncrementReferenceCount(); + iLiteEntry->IncrementRefCount(); + } + +void CCalEntryImpl::ClearSimpleEntry() + { + if (iSessionImpl && iLiteEntry) + { + iLiteEntry->DecrementRefCount(); + iLiteEntry = NULL; + } + } + +CCalEntryImpl* CCalEntryImpl::NewL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum) + { + __ASSERT_ALWAYS(aUid && aUid->Length() > 0, User::Leave(KErrArgument)); + + CCalEntryImpl* self = new (ELeave) CCalEntryImpl(); + CleanupStack::PushL(self); + self->ConstructL(aType, aUid, aMethod, aSeqNum); // takes ownership of aUid + CleanupStack::Pop(self); + return self; + } + +CCalEntryImpl* CCalEntryImpl::NewL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod, + TUint aSeqNum, const TCalTime& aRecurrenceId, CalCommon::TRecurrenceRange aRange) + { + __ASSERT_ALWAYS(aUid && aUid->Length() > 0, User::Leave(KErrArgument)); + + CCalEntryImpl* self = new (ELeave) CCalEntryImpl(); + CleanupStack::PushL(self); + self->ConstructL(aType, aUid, aMethod, aSeqNum, CalUtils::TCalTimeToTAgnCalendarTimeL(aRecurrenceId), aRange); + // takes ownership of aUid + CleanupStack::Pop(self); + return self; + } + +CCalEntryImpl* CCalEntryImpl::NewL(CAgnEntry& aEntry, CCalSessionImpl& aSessionImpl) + { + CCalEntryImpl* self = new (ELeave) CCalEntryImpl(aEntry, aSessionImpl); + return self; + } + +CCalEntryImpl* CCalEntryImpl::NewL(CCalLiteEntry& aEntry, CCalSessionImpl& aSessionImpl) + { + CCalEntryImpl* self = new (ELeave) CCalEntryImpl(aEntry, aSessionImpl); + return self; + } + +void CCalEntryImpl::ConstructL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum, const TAgnCalendarTime& aRecurrenceId, CalCommon::TRecurrenceRange aRange) + { + // Create appropriate CAgnEntry type child entry. + iFullEntry = CAgnEntry::NewL(aType, aUid, aMethod, aSeqNum, aRecurrenceId, aRange); // takes ownership of aUid + } + + +void CCalEntryImpl::ConstructL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum) + { + // Create appropriate CAgnEntry type parent entry. + iFullEntry = CAgnEntry::NewL(aType, aUid, aMethod,aSeqNum); + } + +void CCalEntryImpl::LoadFullEntryL() + { + if (iLiteEntry) + { + // iFullEntry should be NULL at this point + __ASSERT_DEBUG(iFullEntry == NULL, User::Leave(KErrCorrupt)); + + // extract full CAgnEntry from TAgnLiteEntry and store it in iFullEntry + TCalLocalUid id = iLiteEntry->LiteEntry().LocalUid(); + iFullEntry = iSessionImpl->Server().FetchEntryL(id, iSessionImpl->FileId()); + __ASSERT_ALWAYS(iFullEntry, User::Leave(KErrNotFound)); + iFullEntry->SetCollectionId(iLiteEntry->LiteEntry().CollectionId()); + ClearSimpleEntry(); + } + } + +// return the CAgnEntry associated with this entry, loading it from the server if necessary +CAgnEntry* CCalEntryImpl::GetFullEntryL() + { + LoadFullEntryL(); + return iFullEntry; + } + +void CCalEntryImpl::PopulateCategoryListL() + { + if (!iCalCategoryList) + { + LoadFullEntryL(); + iCalCategoryList = new (ELeave) RPointerArray(KCategoryGranularity); + + const TInt KCategoryCount = iFullEntry->CategoryCount(); + for (TInt i = 0; i < KCategoryCount; ++i) + { + CAgnCategory& agnCategory = iFullEntry->FetchCategory(i); // ownership not taken + CCalCategoryImpl* impl = CCalCategoryImpl::NewL(&agnCategory); // doesn't take ownership of agnCategory + CleanupStack::PushL(impl); + CCalCategory* category = CCalCategory::NewL(impl); // takes ownership of impl + CleanupStack::Pop(impl); + CleanupStack::PushL(category); + iCalCategoryList->AppendL(category); // takes ownership of category + CleanupStack::Pop(category); + } + } + } + +void CCalEntryImpl::PopulateAttendeeListL() + { + if(!iCalAttendeeList) + { + LoadFullEntryL(); + + iCalAttendeeList = new(ELeave) RPointerArray(KAttendeeGranularity); + + const TInt KAttendeeCount = iFullEntry->AttendeeCount(); + for(TInt i = 0; i < KAttendeeCount; ++i) + { + CAgnAttendee& agnAttendee = iFullEntry->FetchAttendee(i); + + CCalUserImpl* impl = CCalUserImpl::NewL(&agnAttendee); // doesn't take ownership of agnAttendee + CleanupStack::PushL(impl); + CCalAttendee* calAttendee = CCalAttendee::NewL(impl); // takes ownership of impl + CleanupStack::Pop(impl); + + CleanupStack::PushL(calAttendee); + iCalAttendeeList->AppendL(calAttendee); + CleanupStack::Pop(calAttendee); + } + } + } + + +void CCalEntryImpl::AddAttendeeL(CCalAttendee* aAttendee) + { + if (!aAttendee) + { + User::Leave( KErrArgument ); + } + + CleanupStack::PushL(aAttendee); + __ASSERT_ALWAYS(aAttendee != NULL, User::Leave(KErrArgument)); + PopulateAttendeeListL(); + + CCalUserImpl* userImpl = aAttendee->Impl(); + CAgnAttendee* attendee = userImpl->Attendee(); + + // add attendee to CAgnEntry (no longer owned by CCalAttendee) + userImpl->SetOwnsCAgnAttendee(EFalse); + iFullEntry->AddAttendeeL(attendee); + + // store attendee in attendee array too + iCalAttendeeList->AppendL(aAttendee); + CleanupStack::Pop(aAttendee); + } + +RPointerArray& CCalEntryImpl::AttendeesL() + { + PopulateAttendeeListL(); + return *iCalAttendeeList; + } + +void CCalEntryImpl::DeleteAttendeeL(TInt aIndex) + { + LoadFullEntryL(); + + if(iCalAttendeeList) + { + if (aIndex < 0 || aIndex >= iCalAttendeeList->Count()) + { + User::Leave(KErrArgument); + } + delete (*iCalAttendeeList)[aIndex]; + iCalAttendeeList->Remove(aIndex); + } + + iFullEntry->DeleteAttendee(aIndex); + } + +void CCalEntryImpl::SetOrganizerL(CCalUser* aUser) + { + CleanupStack::PushL(aUser); + __ASSERT_ALWAYS(aUser != NULL, User::Leave(KErrArgument)); + LoadFullEntryL(); + + aUser->Impl()->SetOwnsCAgnAttendee(EFalse); + iFullEntry->SetOrganizerL(aUser->Impl()->Attendee()); // takes ownership of user immediately + + delete iCalOrganizer; + iCalOrganizer = aUser; + CleanupStack::Pop(aUser); + } + +void CCalEntryImpl::SetPhoneOwnerL(const CCalUser* aOwner) + { + __ASSERT_ALWAYS(aOwner != NULL, User::Leave(KErrArgument)); + LoadFullEntryL(); + CCalUserImpl* userImpl = aOwner->Impl(); + iFullEntry->SetPhoneOwnerL(userImpl->Attendee()); + } + +CCalUser* CCalEntryImpl::PhoneOwnerL() + { + LoadFullEntryL(); + + CAgnAttendee* agnPhoneOwner = iFullEntry->PhoneOwner(); + + if(agnPhoneOwner) + { + //check to see if phone owner is the organizer + if(OrganizerL()) + { + if(agnPhoneOwner == iCalOrganizer->Impl()->Attendee()) + { + return iCalOrganizer; + } + } + + PopulateAttendeeListL(); + + // see if the phone owner is one of the other attendees + const TInt KAttendeeCount = iCalAttendeeList->Count(); + for(TInt i = 0; i < KAttendeeCount; ++i) + { + CCalAttendee* calAttendee = (*iCalAttendeeList)[i]; + if(agnPhoneOwner == calAttendee->Impl()->Attendee()) + { + return calAttendee; + } + } + } + return NULL; + } + + +CCalUser* CCalEntryImpl::OrganizerL() + { + LoadFullEntryL(); + if( ! iCalOrganizer) + { + CAgnAttendee* organizer = iFullEntry->Organizer(); + + if(organizer) + { + CCalUserImpl* impl = CCalUserImpl::NewL(organizer); + CleanupStack::PushL(impl); + impl->SetOwnsCAgnAttendee(EFalse); + iCalOrganizer = CCalUser::NewL(impl); + CleanupStack::Pop(impl); + } + } + + return iCalOrganizer; + } + +CTzRules* CCalEntryImpl::GetTzRulesL() + { + CAgnRptDef* rptDef = SimpleEntry()->RptDef(); + + if (rptDef == NULL) + { + return NULL; + } + return rptDef->CloneTzRulesL(); + } + +void CCalEntryImpl::SetTzRulesL(const CTzRules& aTzRules) + { + LoadFullEntryL(); + + if (TimeMode() == MAgnCalendarTimeMode::EFloating) + { + User::Leave(KErrArgument); + } + + CAgnRptDef* rptDef = SimpleEntry()->RptDef(); // doesn't take ownership + + if (!rptDef) + { + User::Leave(KErrNotFound); + } + + rptDef->SetTimeZoneL(aTzRules); // rptDef doesn't take ownership of aTzRules + } + +void CCalEntryImpl::SetTzRulesL() + { + LoadFullEntryL(); + + if (TimeMode() == MAgnCalendarTimeMode::EFloating) + { + User::Leave(KErrArgument); + } + + CAgnRptDef* rptDef = SimpleEntry()->RptDef(); + if (rptDef == NULL) + { + User::Leave(KErrNotFound); + } + rptDef->SetTimeZoneL(); + } + +void CCalEntryImpl::SetRDatesL(const RArray& aRDates) + { + LoadFullEntryL(); + SetDatesL(ETrue, aRDates); + } + +void CCalEntryImpl::SetExceptionDatesL(const RArray& aExDates) + { + LoadFullEntryL(); + + if (iFullEntry->RptDef() == NULL) + { + User::Leave(KErrNotFound); + } + + SetDatesL(EFalse, aExDates); + } + +//if aDateType is ETrue, add dates to sporadic date list +//if aDateType is EFalse, add dates to exception list +void CCalEntryImpl::SetDatesL(TBool aDateType, const RArray& aDates) + { + const TCalTime::TTimeMode KEntryTimeMode = static_cast(TimeMode()); + const TInt KDateCount = aDates.Count(); + TInt i = 0; + for (i = 0; i < KDateCount; i++) + { + if (aDates[i].TimeMode() != KEntryTimeMode) + { + User::Leave(KErrArgument); + } + } + + CAgnRptDef* rptDef = SimpleEntry()->RptDef(); + + TBool entryHasNoRptDef(rptDef == NULL); + if (entryHasNoRptDef) + { + rptDef = CAgnRptDef::NewL(*SimpleEntry()); + CleanupStack::PushL(rptDef); + } + else + { + if (aDateType) + { + rptDef->RemoveAllSporadicDates(); + } + else + { + rptDef->RemoveAllExceptions(); + } + } + + // store the dates + for (i = 0; i < KDateCount; ++i) + { + TAgnCalendarTime agnTime = CalUtils::TCalTimeToTAgnCalendarTimeL(aDates[i]); + if (aDateType) + { + rptDef->AddSporadicDateL(agnTime); + } + else + { + rptDef->AddExceptionL(agnTime); + } + } + + // if the rptDef didn't exist in the entry already, add it + if (entryHasNoRptDef) + { + iFullEntry->SetRptDefL(*rptDef); // makes a copy of rptDef + CleanupStack::PopAndDestroy(rptDef); + } + } + +void CCalEntryImpl::GetRDatesL(RArray& aRDates) + { + aRDates.Reset(); + const CAgnRptDef* KRptDef = SimpleEntry()->RptDef(); + if (KRptDef) + { + FetchDatesL(KRptDef->SporadicDateList(), aRDates); + } + } + +void CCalEntryImpl::GetExceptionDatesL(RArray& aExDates) + { + aExDates.Reset(); + const CAgnRptDef* KRptDef = SimpleEntry()->RptDef(); + if (KRptDef) + { + FetchDatesL(KRptDef->Exceptions(), aExDates); + } + } + +void CCalEntryImpl::FetchDatesL(const RArray* aDateList, RArray& aRDates) + { + // aDateList may be NULL + if (aDateList) + { + const TInt KDateCount = aDateList->Count(); + for (TInt i = 0; i < KDateCount; ++i) + { + TCalTime calTime = CalUtils::TAgnCalendarTimeToTCalTimeL((*aDateList)[i]); + aRDates.AppendL(calTime); + } + } + } + +CCalEntry::TMethod CCalEntryImpl::MethodL() + { + LoadFullEntryL(); + return iFullEntry->Method(); + } + +TCalTime CCalEntryImpl::RecurrenceIdL() + { + // If this entry has been committed to store, the Rec-Id can be retrieved from the + // CAgnEntryModel by passing the appropraite CAgnEntry. + // Else try to retrieve it from CAgnEntry's temporary GS data. + + LoadFullEntryL(); + return CalUtils::TAgnCalendarTimeToTCalTimeL(iFullEntry->RecurrenceId()); + } + +CalCommon::TRecurrenceRange CCalEntryImpl::RecurrenceRangeL() + { + LoadFullEntryL(); + return iFullEntry->RecurrenceRange(); + } + +const TDesC8& CCalEntryImpl::UidL() + { + LoadFullEntryL(); + // Does not transfer ownership + if(iFullEntry->Guid() == KNullDesC8) + { + // this entry must be a child entry whose GUID has not been loaded + __ASSERT_ALWAYS(iFullEntry->GsDataType() == CGsData::EChild, User::Leave(KErrCorrupt)); + + // get parent entry + TCalLocalUid parentId = iFullEntry->ParentId(); + CAgnEntry* parentEntry = iSessionImpl->Server().FetchEntryL(parentId, iSessionImpl->FileId()); + __ASSERT_ALWAYS(parentEntry, User::Leave(KErrNotFound)); + CleanupStack::PushL(parentEntry); + HBufC8* guidHbuf = parentEntry->Guid().AllocL(); + CleanupStack::PopAndDestroy(parentEntry); + + iFullEntry->SetGuid(guidHbuf); + } + + return iFullEntry->Guid(); + } + + +TInt CCalEntryImpl::SequenceNumberL() + { + LoadFullEntryL(); + return iFullEntry->SequenceNumber(); + } + + +void CCalEntryImpl::SetMethodL(CCalEntry::TMethod aMethod) + { + LoadFullEntryL(); + iFullEntry->SetMethod(aMethod); + } + +const RPointerArray& CCalEntryImpl::CategoryListL() + { + PopulateCategoryListL(); + + return *iCalCategoryList; + } + +void CCalEntryImpl::AddCategoryL(CCalCategory* aCategory) + { + CleanupStack::PushL(aCategory); + __ASSERT_ALWAYS(aCategory != NULL, User::Leave(KErrArgument)); + + PopulateCategoryListL(); + + // add the category to the list + iCalCategoryList->AppendL(aCategory); + CleanupStack::Pop(aCategory); + + TInt err(KErrNone); + + // add category to CAgnEntry + TRAP(err , iFullEntry->AddCategoryL( aCategory->Impl()->AgnCategory() ) ); // this can leave before taking ownership + + if (err != KErrNone) + { + delete (*iCalCategoryList)[iCalCategoryList->Count() - 1]; + iCalCategoryList->Remove(iCalCategoryList->Count() - 1); + User::Leave(err); + } + + aCategory->Impl()->SetOwnAgnCategory(EFalse); + } + +void CCalEntryImpl::DeleteCategoryL(TInt aIndex) + { + LoadFullEntryL(); + + if (aIndex < 0 || aIndex >= iFullEntry->CategoryCount()) + { + User::Leave(KErrArgument); + } + + iFullEntry->DeleteCategory(aIndex); + if(iCalCategoryList) + { + delete (*iCalCategoryList)[aIndex]; + iCalCategoryList->Remove(aIndex); + + // check count of CAgnCategory and CCalCategory is the same + __ASSERT_DEBUG(iCalCategoryList->Count() == iFullEntry->CategoryCount(), Panic(EAgmErrCategoryCountCorrupt)); + } + } + +TBool CCalEntryImpl::GetRRuleL(TCalRRule& aRule) + { + const CAgnRptDef* KRptDef = SimpleEntry()->RptDef(); + if (KRptDef == NULL || KRptDef->RRule() == NULL) + { + return EFalse; + } + + const TAgnRpt* KRpt = KRptDef->RRule(); + + // get the DTSTART property + if (SimpleEntry()->Type() == CCalEntry::ETodo) + { + aRule.SetDtStart(EndTimeL()); + } + else + { + aRule.SetDtStart(StartTimeL()); + } + + TInt repCount = 0; + TCalTime untilCaltime = CalUtils::TAgnCalendarTimeToTCalTimeL(KRpt->UntilTimeL()); + + if (untilCaltime.TimeLocalL() == TCalTime::MaxTime()) + { + //Idealy, only UTC maximum time should be used to indicate the repeating forever. However, for a behaviour compatible reason, + //when the client sets local or UTC repeating until time to be maximum time, it is treated as repeating forever. + untilCaltime.SetTimeUtcL(TCalTime::MaxTime()); + } + else + { + repCount = KRpt->InstanceCountL(); + } + + aRule.SetUntilAndCount(untilCaltime, repCount); + + // get the INTERVAL property + aRule.SetInterval(KRpt->Interval()); + + // get the TCalRRule's type, and type-specific data + switch (KRpt->Type()) + { + case TAgnRpt::EDaily: + aRule.SetType(TCalRRule::EDaily); + break; + case TAgnRpt::EYearlyByDate: + aRule.SetType(TCalRRule::EYearly); + break; + case TAgnRpt::EYearlyByDay: + { + aRule.SetType(TCalRRule::EYearly); + + TDay day; + TAgnRpt::TWeekInMonth weekInMonth; + TMonth month; + TInt year; + + const TAgnYearlyByDayRpt* KYearlyRpt = static_cast(KRpt); + KYearlyRpt->GetStartDayL(day, weekInMonth, month, year); + TInt8 week = CalUtils::AgnWeekInMonthToWeekNumberL(weekInMonth); + TCalRRule::TDayOfMonth dayOfMonth(day, week); + + RArray dayOfMonthArray; + CleanupClosePushL(dayOfMonthArray); + dayOfMonthArray.AppendL(dayOfMonth); + aRule.SetByDay(dayOfMonthArray); + CleanupStack::PopAndDestroy(&dayOfMonthArray); + + RArray monthArray; + CleanupClosePushL(monthArray); + monthArray.AppendL(month); + aRule.SetByMonth(monthArray); + CleanupStack::PopAndDestroy(&monthArray); + } + break; + case TAgnRpt::EWeekly: + { + aRule.SetType(TCalRRule::EWeekly); + const TAgnWeeklyRpt* KWeeklyRpt = static_cast(KRpt); + aRule.SetWkSt(KWeeklyRpt->FirstDayOfWeek()); + + RArray array; + CleanupClosePushL(array); + TDay day = EMonday; + while (day <= ESunday) + { + if (KWeeklyRpt->IsDaySet(day)) + { + array.AppendL(day); + } + day = static_cast(static_cast(day) + 1); + } + aRule.SetByDay(array); + CleanupStack::PopAndDestroy(&array); + } + break; + case TAgnRpt::EMonthlyByDays: + { + aRule.SetType(TCalRRule::EMonthly); + const TAgnMonthlyByDaysRpt* KMonthlyByDayRpt = static_cast(KRpt); + + RArray dayArray; + CleanupClosePushL(dayArray); + + TAgnRpt::TWeekInMonth week = TAgnRpt::EFirst; + while (week <= TAgnRpt::ELast) + { + TDay day = EMonday; + while (day <= ESunday) + { + if (KMonthlyByDayRpt->IsDaySet(day, week)) + { + TInt8 weekInt = CalUtils::AgnWeekInMonthToWeekNumberL(week); + TCalRRule::TDayOfMonth dayOfMonth(day, weekInt); + dayArray.AppendL(dayOfMonth); + } + day = static_cast(static_cast(day) + 1); + } + + week = static_cast(static_cast(week) + 1); + } + //coverity [dead_error_begin] + aRule.SetByDay(dayArray); + + CleanupStack::PopAndDestroy(&dayArray); // dayArray.Close() + } + break; + case TAgnRpt::EMonthlyByDates: + { + aRule.SetType(TCalRRule::EMonthly); + const TAgnMonthlyByDatesRpt* KMonthlyByDateRpt = static_cast(KRpt); + + RArray array; + CleanupClosePushL(array); + for (TInt i = 0; i < 31; ++i) // dates run from 0 to 30 + { + if (KMonthlyByDateRpt->IsDateSet(i)) + { + array.AppendL(i); + } + } + aRule.SetByMonthDay(array); + CleanupStack::PopAndDestroy(&array); + } + break; + default: + CalUtils::Panic(EInvalidRepeatRuleType); + break; + } + + return ETrue; + } + +TBool CCalEntryImpl::CompareL(const CCalEntry& aEntry) + { + // load full CAgnEntries before comparison + LoadFullEntryL(); + aEntry.Impl()->LoadFullEntryL(); + + // Load both entry's summary, description and alarm action data before comparing - these properties + // are stored in separate streams so may not be loaded at this point + SummaryL(); + aEntry.SummaryL(); + DescriptionL(); + aEntry.DescriptionL(); + delete AlarmL(); + delete aEntry.AlarmL(); + + return (iFullEntry->CompareL(*aEntry.Impl()->GetFullEntryL())); + } + +void CCalEntryImpl::CopyFromL(CCalEntryImpl& aOther, CCalEntry::TCopyType aCopyType) + { + TCalCollectionId collectionId = 0; + if (iLiteEntry) + { + TUint8 collectionId = aOther.SimpleEntry()->CollectionId(); + } + aOther.LoadFullEntryL(); + // Delete old state. + ClearSimpleEntry(); + + if(iCalAttendeeList) + { + iCalAttendeeList->ResetAndDestroy(); + delete iCalAttendeeList; + iCalAttendeeList = NULL; + } + + if(iCalCategoryList) + { + iCalCategoryList->ResetAndDestroy(); + delete iCalCategoryList; + iCalCategoryList = NULL; + } + + delete iCalOrganizer; + iCalOrganizer = NULL; + + if(iSessionImpl) + { + // Use this entry's existing uid. + iSessionImpl->DecrementReferenceCount(); + } + iSessionImpl = aOther.iSessionImpl; + if (iSessionImpl) + { + iSessionImpl->IncrementReferenceCount(); + } + + // ensure other entry has a full CAgnEntry + aOther.LoadFullEntryL(); + + // ensure other entry has summary, description and alarm action properties loaded - these + // are stored in separate streams + aOther.SummaryL(); + aOther.DescriptionL(); + delete aOther.AlarmL(); + + iFullEntry->CopyFromL(*aOther.iFullEntry, aCopyType); + iFullEntry->SetLastModifiedDate(); + iFullEntry->SetCollectionId(collectionId); + } + +void CCalEntryImpl::SetAlarmL(CCalAlarm* aAlarm) + { + LoadFullEntryL(); + + if ( aAlarm == NULL ) + { + // if aAlarm is NULL, clear the alarm data + iFullEntry->ClearAlarm(); + } + else + { + // This method does not take ownership of aAlarm, so need to copy the alarm details + // before adding to the entry. + + // the alarm must be on the same day in local time as the event + TDateTime dt = iFullEntry->EntryTime().LocalL().DateTime(); + TInt minutes = dt.Hour()*60 + dt.Minute(); + __ASSERT_ALWAYS(minutes - aAlarm->TimeOffset().Int() <= KAgnMinutesInADay, User::Leave(KErrNotSupported)); + + iFullEntry->SetAlarmOffset(aAlarm->TimeOffset()); + iFullEntry->SetAlarmSoundNameL(aAlarm->AlarmSoundNameL()); + + CCalContent* alarmAction = aAlarm->AlarmAction(); // doesn't take ownership + + if ( alarmAction ) + { + CAgnContent* agnAlarmAction = static_cast(alarmAction->Impl()); + + if ( agnAlarmAction ) + { + CAgnContent* alarmActionCopy = agnAlarmAction->CloneL(); + iFullEntry->SetAlarmAction(alarmActionCopy); // entry takes ownership of alarmActionCopy + } + } + else + { + iFullEntry->SetAlarmAction(NULL); + } + } + } + +CCalAlarm* CCalEntryImpl::AlarmL() + { + LoadFullEntryL(); + + if (!iFullEntry->HasAlarm()) + { + return NULL; + } + + TTime time = iFullEntry->EntryTime().LocalL(); + + // Invalid or non-existant entries are set on import to NULL time + // That being the case, we return NULL for the Alarm. + TDateTime timeOfEvent; + if(time == Time::NullTTime()) + { + return NULL; + } + else + { + timeOfEvent = time.DateTime(); + } + + CCalAlarm* alarm = CCalAlarm::NewL(); + CleanupStack::PushL(alarm); + + alarm->SetTimeOffset(iFullEntry->AlarmOffset().Int()); + alarm->SetAlarmSoundNameL(iFullEntry->AlarmSoundName()); + + if(!iFullEntry->AlarmActionIsLoaded()) + { + CAgnContent* agnAlarmaction = iSessionImpl->Server().RestoreAlarmActionL(iFullEntry->AlarmActionStreamId(), iSessionImpl->FileId()); + // Restore should always return something, even if it's only a Null Descriptor + iFullEntry->SetAlarmAction(agnAlarmaction); + } + + if (iFullEntry->AlarmAction()) + { + CCalContent* alarmAction = CCalContent::NewL(); + CleanupStack::PushL(alarmAction); + CAgnContent* agnAlarmActionCopy = iFullEntry->AlarmAction()->CloneL(); + alarmAction->SetImpl(agnAlarmActionCopy); // Takes ownership of agnAlarmAction. + alarm->SetAlarmAction(alarmAction); // Takes ownership of alarmAction. + CleanupStack::Pop(alarmAction); + } + + CleanupStack::Pop(alarm); + return alarm; + } + +void CCalEntryImpl::SetCommonRptDataL(const TCalRRule& aRpt, CAgnRptDef& aRptRule) + { + // set repeat rule data which is not specific to the rule type + // Both repeating count and until time could be set. If so, the one come earlist will be set as repeating until time. + // Note that the repeating until time will be adjusted in TAgnRpt::UntilTimeL() when the entry is stored (CCalEntryViewImpl::DoStore and + // CAgnSimpleEntry::AdjustStartUntilTimeForRepEntryL)By then, the TZ rule has been set to a repeating entry. + aRptRule.SetInterval(aRpt.Interval()); + const_cast (aRptRule.RRule())->SetCount(aRpt.Count()); + + TTime untilTime = aRpt.Until().TimeLocalL(); + if (untilTime != Time::NullTTime()) + { + TAgnCalendarTime untilTimeTAgn = CalUtils::TCalTimeToTAgnCalendarTimeL(aRpt.Until()); + aRptRule.SetUntilTime(untilTimeTAgn); + } + } + +void CCalEntryImpl::SetRRuleL(const TCalRRule& aRpt) + { + if (aRpt.Until().TimeLocalL() != Time::NullTTime() && aRpt.DtStart().TimeLocalL() >= aRpt.Until().TimeLocalL()) + { + // if Until time is set to earlier than the start time and is non-NULL, leave + User::Leave(KErrArgument); + } + LoadFullEntryL(); + + //Leaves if this is a todo entry and its end date has not been set or this is a non-todo entry and its start date has not been set + //since repeating pattern is based on those time attributes. + if ( ! iFullEntry->EntryTime().IsSet()) + { + User::Leave(KErrArgument); + } + + TBool createdNewRptDef = EFalse; + CAgnRptDef* rptDef = iFullEntry->RptDef(); + if(rptDef == NULL) + { + rptDef = CAgnRptDef::NewL(*iFullEntry); + CleanupStack::PushL(rptDef); + createdNewRptDef = ETrue; + } + + switch (aRpt.Type()) + { + case TCalRRule::EDaily: + { + TAgnDailyRpt daily(*rptDef); + rptDef->SetRRuleL(daily); + } + break; + case TCalRRule::EWeekly: + { + TAgnWeeklyRpt weekly(*rptDef); + weekly.SetFirstDayOfWeek(aRpt.WkSt()); + RArray array; + CleanupClosePushL(array); + aRpt.GetByDayL(array); + const TInt KWeeklyDayCount = array.Count(); + for (TInt i = 0; i < KWeeklyDayCount; ++i) + { + weekly.SetDay(array[i]); + } + CleanupStack::PopAndDestroy(&array); + + rptDef->SetRRuleL(weekly); + } + break; + case TCalRRule::EMonthly: + { + RArray array; + CleanupClosePushL(array); + aRpt.GetByMonthDayL(array); + if (array.Count() <= 0) + { + // may be monthly by week + RArray dayArray; + CleanupClosePushL(dayArray); + aRpt.GetByDayL(dayArray); + const TInt KMonthlyDayCount = dayArray.Count(); + if (KMonthlyDayCount > 0) + { + TAgnMonthlyByDaysRpt monthlyByDayAndWeek(*rptDef); + for (TInt i = 0; i < KMonthlyDayCount; ++i) + { + TCalRRule::TDayOfMonth dayOfMonth = dayArray[i]; + TAgnRpt::TWeekInMonth weekNum = CalUtils::WeekNumberToAgnWeekInMonthL(dayOfMonth.WeekInMonth()); + monthlyByDayAndWeek.SetDay(dayOfMonth.Day(), weekNum); + } + + rptDef->SetRRuleL(monthlyByDayAndWeek); + } + CleanupStack::PopAndDestroy(&dayArray); // dayArray.Close() + } + else + { + TAgnMonthlyByDatesRpt monthlyByDate(*rptDef); + const TInt KMonthlyDateCount = array.Count(); + for (TInt i = 0; i < KMonthlyDateCount; ++i) + { + monthlyByDate.SetDate(array[i]); + } + + rptDef->SetRRuleL(monthlyByDate); + } + CleanupStack::PopAndDestroy(&array); // array.Reset(); + } + break; + case TCalRRule::EYearly: + { + RArray dayArray; + CleanupClosePushL(dayArray); + aRpt.GetByDayL(dayArray); + if (dayArray.Count() > 0) + { + RArray monthArray; + CleanupClosePushL(monthArray); + aRpt.GetByMonthL(monthArray); + if (monthArray.Count() > 0) + { + TDay day = dayArray[0].Day(); + TAgnRpt::TWeekInMonth week = CalUtils::WeekNumberToAgnWeekInMonthL(dayArray[0].WeekInMonth()); + TMonth month = monthArray[0]; + + TAgnYearlyByDayRpt yearlyByDay(*rptDef); + + // Check that the first month to repeat on is earlier than the repeat dtstart date... + TDateTime rptStartTime = aRpt.DtStart().TimeUtcL().DateTime(); + TInt year = rptStartTime.Year(); + if (month < rptStartTime.Month()) + { + // ...if not, start the following year + year++; + } + + TTime newStartDay = yearlyByDay.FindStartDayL(day, week, month, year); + TCalTime newStartDaycal; + newStartDaycal.SetTimeLocalL(newStartDay); + const_cast(aRpt).SetDtStart(newStartDaycal); + TTime untilTimeLocal = yearlyByDay.UntilTimeL().LocalL(); + TDateTime rptUntilTime = untilTimeLocal.DateTime(); + if (aRpt.Count() != 0 || year < rptUntilTime.Year() || + (year == rptUntilTime.Year() && month < rptUntilTime.Month()) + ) + { + // The count has been set + // or the first month to repeat on is not later than the repeat until date + rptDef->SetRRuleL(yearlyByDay); + } + } + else + { + User::Leave(KErrArgument); + } + CleanupStack::PopAndDestroy(&monthArray); + } + else + { + TAgnYearlyByDateRpt yearlyByDate(*rptDef); + rptDef->SetRRuleL(yearlyByDate); + } + CleanupStack::PopAndDestroy(&dayArray); + } + break; + default: + User::Leave(KErrNotSupported); + break; + } + + if (rptDef->RRule()) + { + SetCommonRptDataL(aRpt, *rptDef); + } + + if (createdNewRptDef) + { + if (rptDef->RRule()) + { + iFullEntry->SetRptDefL(*rptDef); + } + CleanupStack::PopAndDestroy(rptDef); + } + + //Move the entry start date is same as repeating date + + TDateTime newEntryDateTime; + if(EntryTypeL() == CCalEntry::ETodo) + { + newEntryDateTime = EndTimeL().TimeLocalL().DateTime(); + } + else + { + newEntryDateTime = StartTimeL().TimeLocalL().DateTime(); + } + + newEntryDateTime.SetYear(aRpt.DtStart().TimeLocalL().DateTime().Year()); + newEntryDateTime.SetMonth(aRpt.DtStart().TimeLocalL().DateTime().Month()); + newEntryDateTime.SetDay(aRpt.DtStart().TimeLocalL().DateTime().Day()); + + //adjust the entrytime (it the entry start time for non-todos and end time for todos) + iFullEntry->MoveStartTimeLocalL(newEntryDateTime); + } + +void CCalEntryImpl::ClearRepeatingPropertiesL() + { + SimpleEntry()->ClearRepeat(); + } + +TCalTime CCalEntryImpl::NextInstanceForLocalUIDL(const TCalTime& aTime) + { + const TTime KTimeUtc = aTime.TimeUtcL() + TTimeIntervalMicroSeconds(1); + TTime nextTimeUtc = Time::NullTTime(); + + const CAgnRptDef* KRptDef = SimpleEntry()->RptDef(); + if (KRptDef) + { + if (KRptDef->NudgeNextInstanceUtcL(KTimeUtc, nextTimeUtc) == EFalse) + { + nextTimeUtc = Time::NullTTime(); + } + } + else + { + TTime entryTimeUtc = SimpleEntry()->EntryTime().UtcL(); + if (KTimeUtc < entryTimeUtc) + { + nextTimeUtc = entryTimeUtc; + } + } + + TCalTime calTime; + calTime.SetTimeUtcL(nextTimeUtc); + return calTime; + } + +TCalTime CCalEntryImpl::PreviousInstanceForLocalUIDL(const TCalTime& aTime) + { + const TTime KTimeUtc = aTime.TimeUtcL() - TTimeIntervalMicroSeconds(1); + TTime prevTimeUtc = Time::NullTTime(); + + const CAgnRptDef* KRptDef = SimpleEntry()->RptDef(); + if (KRptDef) + { + if (KRptDef->NudgePreviousInstanceUtcL(KTimeUtc, prevTimeUtc) == EFalse) + { + prevTimeUtc = Time::NullTTime(); + } + } + else + { + TTime entryTimeUtc = SimpleEntry()->EntryTime().UtcL(); + if (KTimeUtc > entryTimeUtc) + { + prevTimeUtc = entryTimeUtc; + } + } + + TCalTime calTime; + calTime.SetTimeUtcL(prevTimeUtc); + return calTime; + } + +TCalTime CCalEntryImpl::LastModifiedDateL() + { + TTime lastModifiedEntry = SimpleEntry()->LastModifiedDateUtc(); + if(iSessionImpl && SimpleEntry()->RptDef() && SimpleEntry()->TimeMode()!= MAgnCalendarTimeMode::EFloating) + { + TTime lastModifiedTzChange = iSessionImpl->TzRulesLastModifiedDateL(); + if(lastModifiedTzChange>lastModifiedEntry) + { + lastModifiedEntry = lastModifiedTzChange; + } + } + TCalTime lastModifiedTime; + lastModifiedTime.SetTimeUtcL(lastModifiedEntry); + return lastModifiedTime; + } + +TCalTime CCalEntryImpl::DTStampL() + { + LoadFullEntryL(); + TCalTime dTStampTime; + dTStampTime.SetTimeUtcL(iFullEntry->DTStampUtcL()); + return dTStampTime; + } + +void CCalEntryImpl::SetLocationL(const TDesC& aLocation) + { + LoadFullEntryL(); + iFullEntry->SetLocationL(aLocation); + } + +const TDesC& CCalEntryImpl::LocationL() + { + LoadFullEntryL(); + return iFullEntry->Location(); + } + +void CCalEntryImpl::SetPriorityL(TUint aPriority) + { + LoadFullEntryL(); + iFullEntry->SetPriority(aPriority); + } + +TUint CCalEntryImpl::PriorityL() + { + return SimpleEntry()->Priority(); + } + +TCalTime CCalEntryImpl::StartTimeL() + { + return CalUtils::TAgnCalendarTimeToTCalTimeL(SimpleEntry()->StartTime()); + } + +TCalTime CCalEntryImpl::EndTimeL() + { + TCalTime calEndTime; // initialised to Null time on construction + if (SimpleEntry()->Type() != CCalEntry::EReminder) + { + calEndTime = CalUtils::TAgnCalendarTimeToTCalTimeL(SimpleEntry()->EndTime()); + } + return calEndTime; + } + +void CCalEntryImpl::SetStartAndEndTimeL(const TCalTime& aStartTime, const TCalTime& aEndTime) + { + LoadFullEntryL(); + TCalTime::TTimeMode mode = aStartTime.TimeMode(); + if (aEndTime.TimeUtcL() != Time::NullTTime()) + { + if (aStartTime.TimeUtcL() != Time::NullTTime()) + { + // both times are non-null so check the modes + __ASSERT_ALWAYS(aStartTime.TimeMode() == aEndTime.TimeMode(), User::Leave(KErrArgument)); + + // both times are non-null so check that end time is not earlier than start time + __ASSERT_ALWAYS(aStartTime.TimeUtcL() <= aEndTime.TimeUtcL(), User::Leave(KErrArgument)); + } + else + { + // start time non-null so fetch mode from end time + mode = aEndTime.TimeMode(); + } + } + __ASSERT_ALWAYS(mode == TCalTime::EFixedUtc || mode == TCalTime::EFloating, User::Leave(KErrArgument)); + + // either this is a parent entry, or time mode should match recurrence ID + __ASSERT_ALWAYS(RecurrenceIdL().TimeUtcL() == Time::NullTTime() || + mode == RecurrenceIdL().TimeMode(), + User::Leave(KErrArgument)); + + TAgnCalendarTime agnStartTime = CalUtils::TCalTimeToTAgnCalendarTimeL(aStartTime); + TAgnCalendarTime agnEndTime = CalUtils::TCalTimeToTAgnCalendarTimeL(aEndTime); + + const CCalEntry::TType KType = SimpleEntry()->Type(); + + switch (KType) + { + case CCalEntry::ETodo: + // for todos, if end time is not set, set start time to null as well - this is an undated entry + if ( ! agnEndTime.IsSet()) + { + agnStartTime = agnEndTime; + } + break; + case CCalEntry::EReminder: + // for reminders, end time is the same as start time + agnEndTime = agnStartTime; + break; + case CCalEntry::EAppt: + case CCalEntry::EAnniv: + case CCalEntry::EEvent: + // for other entries, if end time is not set, make it the same as the start time + if ( ! agnEndTime.IsSet()) + { + agnEndTime = agnStartTime; + } + break; + default: + // bad entry type + User::Leave(KErrArgument); + break; + } + + iFullEntry->SetStartAndEndTimeL(agnStartTime, agnEndTime); + } + +MAgnCalendarTimeMode::TTimeMode CCalEntryImpl::TimeMode() const + { + return SimpleEntry()->TimeMode(); + } + +TCalTime CCalEntryImpl::CompletedTimeL() + { + TTime completedDateUtc(Time::NullTTime()); + if (SimpleEntry()->Type() == CCalEntry::ETodo) + { + completedDateUtc = SimpleEntry()->CompletedDateUtc(); + } + TCalTime calCompletedDate; + calCompletedDate.SetTimeUtcL(completedDateUtc); + return calCompletedDate; + } + +void CCalEntryImpl::SetCompletedL(TBool aCompleted, const TCalTime& aDate) + { + LoadFullEntryL(); + if (SimpleEntry()->Type() == CCalEntry::ETodo) + { + if (aCompleted) + { + SimpleEntry()->SetCompletedDateUtcL(aDate.TimeUtcL()); + SetStatusL(CCalEntry::ETodoCompleted); + } + else + { + SimpleEntry()->SetIncomplete(); // resets completed date to null time + SetStatusL(CCalEntry::ETodoNeedsAction); + } + } + else + { + User::Leave(KErrNotSupported); + } + } + +void CCalEntryImpl::SetSummaryL(const TDesC& aSummary) + { + LoadFullEntryL(); + HBufC* summ = aSummary.AllocL(); + iFullEntry->SetSummary(summ); // takes ownership of aSummary + } + +const TDesC& CCalEntryImpl::SummaryL() + { + LoadFullEntryL(); + + if(!iFullEntry->SummaryIsLoaded()) + { + __ASSERT_DEBUG(iFullEntry->SummaryStreamId() != KNullStreamId, Panic(EAgmNoNotesStreamId)); + HBufC* summary = iSessionImpl->Server().RestoreTextL(iFullEntry->SummaryStreamId(), iSessionImpl->FileId()); + // Restore should always return something, even if it's only a Null Descriptor + iFullEntry->SetSummary(summary); + } + + return iFullEntry->Summary(); + } + +void CCalEntryImpl::SetDescriptionL(const TDesC& aDescription) + { + LoadFullEntryL(); + HBufC* desc = aDescription.AllocL(); + iFullEntry->SetDescription(desc); // takes ownership of aDescription + } + +const TDesC& CCalEntryImpl::DescriptionL() + { + LoadFullEntryL(); + + if(!iFullEntry->DescriptionIsLoaded()) + { + __ASSERT_DEBUG(iFullEntry->DescriptionStreamId() != KNullStreamId, Panic(EAgmNoNotesStreamId)); + HBufC* description = iSessionImpl->Server().RestoreTextL(iFullEntry->DescriptionStreamId(), iSessionImpl->FileId()); + // Restore should always return something, even if it's only a Null Descriptor + iFullEntry->SetDescription(description); + } + + return iFullEntry->Description(); + } + +CCalEntry::TType CCalEntryImpl::EntryTypeL() + { + return SimpleEntry()->Type(); + } + +void CCalEntryImpl::SetStatusL(CCalEntry::TStatus aStatus) + { + LoadFullEntryL(); + switch (aStatus) + { + case CCalEntry::ETentative: + case CCalEntry::EConfirmed: + __ASSERT_ALWAYS(EntryTypeL() != CCalEntry::ETodo, User::Leave(KErrNotSupported)); + break; + case CCalEntry::ECancelled: + SimpleEntry()->SetIncomplete(); + break; + + case CCalEntry::ETodoCompleted: + case CCalEntry::ETodoNeedsAction: + case CCalEntry::ETodoInProcess: + __ASSERT_ALWAYS(EntryTypeL() == CCalEntry::ETodo, User::Leave(KErrNotSupported)); + break; + default: + // do nothing + break; + } + if (aStatus == CCalEntry::ETodoCompleted) + { + if (iFullEntry->CompletedDateUtc() == Time::NullTTime()) + { + TTime time; + time.UniversalTime(); + iFullEntry->SetCompletedDateUtcL(time); + } + } + + iFullEntry->SetStatus(aStatus); + } + +void CCalEntryImpl::SetReplicationStatusL(CCalEntry::TReplicationStatus aReplicationStatus) + { + LoadFullEntryL(); + iFullEntry->SetReplicationStatusL(aReplicationStatus); + } + +CCalEntry::TReplicationStatus CCalEntryImpl::ReplicationStatusL() + { + LoadFullEntryL(); + return iFullEntry->ReplicationStatus(); + } + +CCalEntry::TStatus CCalEntryImpl::StatusL() + { + return SimpleEntry()->Status(); + } + +void CCalEntryImpl::SetSequenceNumberL(TInt aSeqNum) + { + LoadFullEntryL(); + iFullEntry->SetSequenceNumber(aSeqNum); + } + +void CCalEntryImpl::SetLastModifiedDateL() + { + LoadFullEntryL(); + iFullEntry->SetLastModifiedDate(); + } + +void CCalEntryImpl::SetLastModifiedDateL(const TCalTime& aModifiedTime) + { + LoadFullEntryL(); + iFullEntry->SetLastModifiedDateUtc(aModifiedTime.TimeUtcL()); + } + +void CCalEntryImpl::SetDTStampL(const TCalTime& aDTStampTime) + { + LoadFullEntryL(); + iFullEntry->SetDTStampUtcL(aDTStampTime.TimeUtcL()); + } + +TAgnEntryId CCalEntryImpl::AgnEntryIdL() + { + return SimpleEntry()->EntryId(); + } + +void CCalEntryImpl::SetLocalUidL(TCalLocalUid aLocalId) + { + LoadFullEntryL(); + iFullEntry->SetLocalUid(aLocalId); + } + +TCalLocalUid CCalEntryImpl::LocalUidL() + { + if(iLiteEntry) + { + return iLiteEntry->LiteEntry().LocalUid(); + } + else + { + return iFullEntry->LocalUid(); + } + } + +TUint8 CCalEntryImpl::ShortFileIdL() + { + if(iLiteEntry) + { + return iLiteEntry->LiteEntry().CollectionId(); + } + else + { + return iFullEntry->CollectionId(); + } + } + +CCalEntry::TTransp CCalEntryImpl::BusyStatusL() + { + LoadFullEntryL(); + return iFullEntry->BusyStatus(); + } + +void CCalEntryImpl::SetBusyStatusL(CCalEntry::TTransp aBusyStatus) + { + LoadFullEntryL(); + iFullEntry->SetBusyStatusL(aBusyStatus); + } + +CCalGeoValue* CCalEntryImpl::GeoValueL() + { + LoadFullEntryL(); + TReal geoLatitude; + TReal geoLongitude; + iFullEntry->GeoValue(geoLatitude,geoLongitude); + if(geoLatitude != KGEODefaultValue && geoLongitude != KGEODefaultValue) + { + CCalGeoValue* geoValue = CCalGeoValue::NewL(); + CleanupStack::PushL(geoValue); + geoValue->SetLatLongL(geoLatitude,geoLongitude); + CleanupStack::Pop(geoValue); + return geoValue; + } + return NULL; + } + +void CCalEntryImpl::SetGeoValueL(const CCalGeoValue& aGeoValue) + { + LoadFullEntryL(); + TReal geoLatitude; + TReal geoLongitude; + aGeoValue.GetLatLong(geoLatitude,geoLongitude); + iFullEntry->SetGeoValueL(geoLatitude,geoLongitude); + } + +void CCalEntryImpl::ClearGeoValueL() + { + LoadFullEntryL(); + iFullEntry->SetGeoValueL(KGEODefaultValue,KGEODefaultValue); + } + +TCalTime CCalEntryImpl::FindRptUntilTimeL(TInt aCount) + { + const CAgnRptDef* KRptDef = SimpleEntry()->RptDef(); + + TTime untilTime = Time::NullTTime(); + + if (KRptDef) + { + untilTime = KRptDef->RRule()->FindRptUntilTimeLocalL(aCount); + } + + TCalTime calUntilTime; + calUntilTime.SetTimeLocalL(untilTime); + + return calUntilTime; + } + + + void CCalEntryImpl::AddAttachmentL(CCalAttachment* aAttachment) + { + __ASSERT_ALWAYS(aAttachment, User::Leave(KErrArgument)); + + PopulateAttachmentListL(); + iCalAttachmentList->AppendL(aAttachment); + + TRAPD(err , iFullEntry->AddAttachmentL(&aAttachment->Impl())); + + if (err != KErrNone) + { + TInt count = iCalAttachmentList->Count(); + iCalAttachmentList->Remove(count - 1); + User::Leave(err); + } + + aAttachment->Impl().ClearFlag(CAgnAttachment::EOwnedByCalAttachment); + + } + +void CCalEntryImpl::PopulateAttachmentListL() + { + if (!iCalAttachmentList) + { + + LoadFullEntryL(); + iCalAttachmentList = new (ELeave) RPointerArray(KAttachmentGranularity); + + const TInt KAttachmentCount = iFullEntry->AttachmentCount(); + for (TInt i = 0; i < KAttachmentCount; ++i) + { + CAgnAttachment& agnAttachment = iFullEntry->Attachment(i); + CCalAttachment* calAttachment = CCalAttachment::NewL(agnAttachment, *iSessionImpl); + CleanupStack::PushL(calAttachment); + agnAttachment.ClearFlag(CAgnAttachment::EOwnedByCalAttachment); + iCalAttachmentList->AppendL(calAttachment); + CleanupStack::Pop(calAttachment); + } + } + + } + +void CCalEntryImpl::DeleteAttachmentL(const CCalAttachment& aAttachment) + { + LoadFullEntryL(); + TInt index = iFullEntry->DeleteAttachmentL(aAttachment.Impl()); + if(iCalAttachmentList && index >= 0 && index < iCalAttachmentList->Count()) + { + delete (*iCalAttachmentList)[index]; + iCalAttachmentList->Remove(index); + __ASSERT_DEBUG(iCalAttachmentList->Count() == iFullEntry->AttachmentCount(), Panic(EAgmErrAttachmentCountCorrupt)); + } + } + +CCalAttachment* CCalEntryImpl::AttachmentL(TInt aIndex) + { + PopulateAttachmentListL(); + + if (aIndex < 0 || aIndex >= iCalAttachmentList->Count() ) + { + return NULL; + } + + return (*iCalAttachmentList)[aIndex]; + } + +TInt CCalEntryImpl::AttachmentCountL() + { + LoadFullEntryL(); + return iFullEntry->AttachmentCount(); + } + +CAgnSimpleEntry* CCalEntryImpl::SimpleEntry() + { + if (!iFullEntry) + { + return &iLiteEntry->LiteEntry(); + } + return iFullEntry; + } + +const CAgnSimpleEntry* CCalEntryImpl::SimpleEntry() const + { + if (!iFullEntry) + { + return &iLiteEntry->LiteEntry(); + } + return iFullEntry; + } + +void CCalEntryImpl::SetUserIntL( TUint32 aUserInt ) + { + SimpleEntry()->SetUserInt(aUserInt); + } + +TUint32 CCalEntryImpl::UserIntL() + { + return SimpleEntry()->UserInt(); + } + + +// CCalEntryIdImpl // + +CCalEntryIdImpl* CCalEntryIdImpl::NewL(TDesC8* aFlatData) + { + CCalEntryIdImpl* self = new(ELeave) CCalEntryIdImpl(); + CleanupStack::PushL(self); + self->ConstructL(aFlatData); + CleanupStack::Pop(self); + return self; + } + +CCalEntryIdImpl::CCalEntryIdImpl() + { + } + +CCalEntryIdImpl::~CCalEntryIdImpl() + { + delete iFlatData; + } + +void CCalEntryIdImpl::ConstructL(TDesC8* aFlatData) + { + __ASSERT_ALWAYS(aFlatData != NULL, User::Leave(KErrArgument)); + + iFlatData = aFlatData; + iUniqueId = reinterpret_cast(aFlatData->Ptr()); + } + +TPtrC8 CCalEntryIdImpl::IdL() + { + return iUniqueId->iGlobalIdentifier; + } + +TPtrC CCalEntryIdImpl::StoreFileNameL() + { + return iUniqueId->iFileName; + } + +TCalTime CCalEntryIdImpl::RecurrenceIdL() + { + TCalTime time; + + if(iUniqueId->iTimeMode ==MAgnCalendarTimeMode::EFloating) + { + time.SetTimeLocalFloatingL(iUniqueId->iRecurrenceId); + } + else + { + time.SetTimeUtcL(iUniqueId->iRecurrenceId); + } + + return time; + } + +TCalTime CCalEntryIdImpl::InstanceTimeL() + { + TCalTime time; + + if(iUniqueId->iTimeMode == MAgnCalendarTimeMode::EFloating) + { + time.SetTimeLocalL(iUniqueId->iInstanceTime); + } + else + { + time.SetTimeUtcL(iUniqueId->iInstanceTime); + } + + return time; + } + +TCalLocalUid CCalEntryIdImpl::LocalUidL() + { + return iUniqueId->iAgnUniqueId; + } + + +/** Construct a new CCalLiteEntry + +@param aLiteEntry The TAgnLiteEntry to be shared between CCalEntry objects. +@param aSession A reference to the CCalSession +@internalComponent +*/ +CCalLiteEntry* CCalLiteEntry::NewL(CAgnSimpleEntry& aSimpleEntry, RAgendaServ& aAgendaServ) + { + CCalLiteEntry* self = new(ELeave) CCalLiteEntry(aSimpleEntry, aAgendaServ); + return self; + } + +/** Constructor + +@param aLiteEntry The TAgnLiteEntry to be shared between CCalEntry objects. +@param aSession A reference to the CCalSession +@internalComponent +*/ +CCalLiteEntry::CCalLiteEntry(CAgnSimpleEntry& aLiteEntry, RAgendaServ& aAgendaServ) + : iAgendaServ(aAgendaServ), iLiteEntry(aLiteEntry) + { + iAgendaServ.IncreaseRef(); + } + +/** Deletes the TAgnLiteEntry that is contained + +@internalComponent +*/ +CCalLiteEntry::~CCalLiteEntry() + { + iAgendaServ.DeleteSimpleEntry(&iLiteEntry); + iAgendaServ.DecreaseRef(); + } + +/** Get a reference to the TAgnLiteEntry + +@return A reference to the TAgnLiteEntry +@internalComponent +*/ +CAgnSimpleEntry& CCalLiteEntry::LiteEntry() const + { + return iLiteEntry; + } + +/** Increments the reference count + +This should only be called by a CCalEntry object that is being created from a CCalLiteEntry +@internalComponent +*/ +void CCalLiteEntry::IncrementRefCount() + { + ++iRefCount; + } + +/** Decrements the reference count and deletes this CCalLiteEntry if there are no more entries refering to it + +This should only be called by a CCalEntry object +@internalComponent +*/ +void CCalLiteEntry::DecrementRefCount() + { + __ASSERT_ALWAYS(iRefCount > 0, User::Invariant()); + if (--iRefCount == 0) + { + delete this; + } + }