diff -r 000000000000 -r f979ecb2b13e pimappservices/calendar/shared/src/agmsimpleentry.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pimappservices/calendar/shared/src/agmsimpleentry.cpp Tue Feb 02 10:12:19 2010 +0200 @@ -0,0 +1,776 @@ +// Copyright (c) 1997-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 "agmsimpleentry.h" +#include "agmallocator.h" +#include "agmrptdef.h" +#include "agmdate.h" +#include "agmpanic.h" + +// ------------------------------------ CAgnSimpleEntry ---------------------------------- +EXPORT_C void CAgnSimpleEntry::SetCollectionId(TCalCollectionId aCallectionId) + { + iCollectionId = aCallectionId; + } + +EXPORT_C TCalCollectionId CAgnSimpleEntry::CollectionId() const + { + return iCollectionId; + } + +TAny* CAgnSimpleEntry::operator new(TUint aSize, TLeave aType, CAgnSimpleEntryAllocator* aAllocator) +/** Overloaded new operator, to allocate CAgnSimpleEntry objects using the CAgnSimpleEntryAllocator. +@internalComponent +*/ + { + // check if the allocator is passed... + + if ( aAllocator ) + { + return ( aAllocator->NewSimpleEntryL(aSize) ); + } + + // ...if not allocate the object with the base class new operator + + return ( CBase::operator new(aSize, aType) ); + } + +CAgnSimpleEntry::CAgnSimpleEntry(CCalEntry::TType aType) + : iCompletedDateUtc(Time::NullTTime()), + iAlarmOffset(KAlarmNotSet), + iType(aType), + iStatus(CCalEntry::ENullStatus) +/** +@internalComponent +*/ + { + iLastModifiedDateUtc.UniversalTime(); + iStartTime.SetNull(); + iEndTime.SetNull(); + } + +CAgnSimpleEntry::~CAgnSimpleEntry() +/** The destructor frees all resources owned by the object, prior to its destruction. + +@internalComponent +*/ + { + delete iRptDef; + } + + +EXPORT_C TBool CAgnSimpleEntry::HasAlarm() const +/** Tests whether the entry is alarmed. + +@internalComponent +@return ETrue if the entry has an alarm, EFalse if it does not have an alarm +or if the entry is crossed out. +*/ + { + if (iCompletedDateUtc != Time::NullTTime()) + { + return (EFalse); + } + + return (iAlarmOffset != KAlarmNotSet); + } + +EXPORT_C void CAgnSimpleEntry::SetAlarmOffset(const TTimeIntervalMinutes& aStartTimeOffset) +/** +@internalComponent +*/ + { + iAlarmOffset = aStartTimeOffset.Int(); + } + +EXPORT_C TTimeIntervalMinutes CAgnSimpleEntry::AlarmOffset() const +/** Gets the time of the alarm as a time interval before the alarm origin, i.e. the instance time. + +@internalComponent +@return Time interval in minutes. +*/ + { + return TTimeIntervalMinutes(iAlarmOffset); + } + +EXPORT_C CCalEntry::TType CAgnSimpleEntry::Type() const +/** +@internalComponent +*/ + { + return static_cast(iType); + } + +EXPORT_C void CAgnSimpleEntry::SetRptDefL(const CAgnRptDef& aRptDef) +/** Sets the entry's repeat definition. + +The repeat definition includes daily, weekly, monthly and yearly repeat +details, until time, sporadic dates and exceptions. + +@internalAll +@param aRptDef Reference to the new repeat definition. +*/ + { + __ASSERT_DEBUG(aRptDef.InvariantL()==KErrNone, User::Leave(KErrArgument)); + + delete iRptDef; + iRptDef = NULL; + + iRptDef = CAgnRptDef::NewL(*this); + iRptDef->CopyL(aRptDef); + } + +EXPORT_C CAgnRptDef* CAgnSimpleEntry::RptDef() + { + return iRptDef; + } + +EXPORT_C const CAgnRptDef* CAgnSimpleEntry::RptDef() const + { + return iRptDef; + } + +TBool CAgnSimpleEntry::operator==(const CAgnSimpleEntry& aSimpleEntry) const +// +// Equality operator +// + { + if (iType != aSimpleEntry.iType) + { + return EFalse; + } + + if ( TimeMode() == MAgnCalendarTimeMode::EFloating ) + { + if ( StartTime() != aSimpleEntry.StartTime() ) + { + return EFalse; + } + + if ( EndTime() != aSimpleEntry.EndTime() ) + { + return EFalse; + } + } + else + { + if ( StartTime() != aSimpleEntry.StartTime() ) + { + return EFalse; + } + + if ( EndTime() != aSimpleEntry.EndTime() ) + { + return EFalse; + } + } + + if ( CompletedDateUtc() != aSimpleEntry.CompletedDateUtc() ) + { + return EFalse; + } + + if ( TimeMode() != aSimpleEntry.TimeMode() ) + { + return EFalse; + } + + if (iCompletedDateUtc != aSimpleEntry.iCompletedDateUtc || + AlarmOffset() != aSimpleEntry.AlarmOffset() || + HasAlarm() != aSimpleEntry.HasAlarm() || + Status() != aSimpleEntry.Status()) + { + return EFalse; + } + + if (iRptDef) + { + if (aSimpleEntry.iRptDef) + { + return (*iRptDef == *aSimpleEntry.iRptDef); + } + else + { + return EFalse; // this has a rpt def but aSimpleEntry doesn't + } + } + else if (aSimpleEntry.iRptDef) + { + return EFalse; // this doesn't have a rpt def but aSimpleEntry does + } + + return ETrue; + } + +EXPORT_C void CAgnSimpleEntry::ClearRepeat() +/** Clears the repeat details including exceptions and unsets the entry's 'is repeating' +property. + +@internalComponent +*/ + { + delete iRptDef; + iRptDef=NULL; + } + +void CAgnSimpleEntry::CopySimpleEntryL(const CAgnSimpleEntry& aSimpleEntry, CCalEntry::TCopyType aCopyType) +// +// Copy the details from aSimpleEntry. +// If aCopyRptDetails is false then the repeat details including exceptions is not copied +// and the entry therefore becomes a non-repeating entry. +// + { + iStatus = aSimpleEntry.iStatus; + iAlarmOffset = aSimpleEntry.iAlarmOffset; + + delete iRptDef; + iRptDef = NULL; + + if ( aSimpleEntry.iRptDef ) + { + iRptDef = CAgnRptDef::NewL(*this); + iRptDef->CopyL(*aSimpleEntry.iRptDef); + } + + if (aCopyType == CCalEntry::ECopyAll) + { + iEntryId = aSimpleEntry.iEntryId; + iLocalUid = aSimpleEntry.iLocalUid; + iGuidHash = aSimpleEntry.iGuidHash; + } + + iPriority = aSimpleEntry.iPriority; + + iStartTime = aSimpleEntry.StartTime(); + iEndTime = aSimpleEntry.EndTime(); + + StartTimeChanged(); + + iCompletedDateUtc = aSimpleEntry.iCompletedDateUtc; + iLastModifiedDateUtc = aSimpleEntry.iLastModifiedDateUtc; + + iUserInt = aSimpleEntry.UserInt(); + iCollectionId = aSimpleEntry.CollectionId(); + } + +EXPORT_C void CAgnSimpleEntry::SetStatus(CCalEntry::TStatus aStatus) +/** Sets the status of the entry to one of the values defined in the TAgnStatus enumeration. + +@internalComponent +@param aStatus The status of the entry. +*/ + { + __ASSERT_DEBUG( (aStatus == CCalEntry::ETentative) + |(aStatus == CCalEntry::EConfirmed) + |(aStatus == CCalEntry::ECancelled) + |(aStatus == CCalEntry::ETodoNeedsAction) + |(aStatus == CCalEntry::ETodoCompleted) + |(aStatus == CCalEntry::ETodoInProcess) + |(aStatus == CCalEntry::ENullStatus) + |(aStatus == CCalEntry::EVCalAccepted) + |(aStatus == CCalEntry::EVCalNeedsAction) + |(aStatus == CCalEntry::EVCalSent) + |(aStatus == CCalEntry::EVCalDeclined) + |(aStatus == CCalEntry::EVCalDelegated), + Panic(EAgmErrInvalidStatus)); + + iStatus = aStatus; + } + + +EXPORT_C CCalEntry::TStatus CAgnSimpleEntry::Status() const +/** Returns the status of the entry. + +@internalComponent +@return The status of the entry, as defined in the TAgnStatus enumeration. +*/ + { + return static_cast(iStatus); + } + +EXPORT_C void CAgnSimpleEntry::SetLastModifiedDate() +/** +@internalComponent +*/ + { + iLastModifiedDateUtc.UniversalTime(); + } + +EXPORT_C void CAgnSimpleEntry::SetLastModifiedDateUtc(const TTime& aLastModifiedDateUtc) +/** +@internalComponent +*/ + { + iLastModifiedDateUtc = aLastModifiedDateUtc; + } + +EXPORT_C const TTime& CAgnSimpleEntry::LastModifiedDateUtc() const +/** +@internalComponent +*/ + { + return iLastModifiedDateUtc; + } + +EXPORT_C void CAgnSimpleEntry::SetPriority(TUint8 aPriority) +/** +@internalComponent +*/ + { + iPriority = aPriority; + } + +EXPORT_C TUint8 CAgnSimpleEntry::Priority() const +/** +@internalComponent +*/ + { + return iPriority; + } + +EXPORT_C const TTime& CAgnSimpleEntry::CompletedDateUtc() const +/** +@internalComponent +*/ + { + return iCompletedDateUtc; + } + +EXPORT_C void CAgnSimpleEntry::SetCompletedDateUtcL(const TTime& aDateUtc) +/** +@internalComponent +*/ + { + __ASSERT_ALWAYS(iType == CCalEntry::ETodo, User::Leave(KErrNotSupported)); + iCompletedDateUtc = aDateUtc; + } + +EXPORT_C void CAgnSimpleEntry::SetIncomplete() +/** +@internalComponent +*/ + { + iCompletedDateUtc = Time::NullTTime(); + } + +EXPORT_C void CAgnSimpleEntry::SetStartAndEndTimeL(const TAgnCalendarTime& aStartTime, const TAgnCalendarTime& aEndTime) +/** +@internalComponent +*/ + { + __ASSERT_ALWAYS(aStartTime.TimeMode() == aEndTime.TimeMode() || ! aStartTime.IsSet() || ! aEndTime.IsSet(), User::Leave(KErrNotSupported)); + if (iType != CCalEntry::ETodo) + { + __ASSERT_ALWAYS(aStartTime.IsSet(), User::Leave(KErrArgument)); + } + + if (iStartTime != aStartTime) + { + StartTimeChanged(); + } + iStartTime = aStartTime; + iEndTime = aEndTime; + } + +EXPORT_C void CAgnSimpleEntry::AdjustStartUntilTimeForRepEntryL() + { + if (iRptDef) + { + TAgnRpt* repeat = const_cast (iRptDef->RRule()); + if (repeat) + { + // Ensure that the start date actually falls on a repeating instance. For example, + // if the repeat rule is every Wednesday, and the DtStart is a Monday, it should be + // nudged forwards to the Wednesday of that week. + + TTime startTimeUtc = EntryTime().UtcL(); + + startTimeUtc -= TTimeIntervalMicroSeconds(1); + TTime firstInstanceUtc; + + TBool isStillRpt = ETrue; + if (iRptDef->NudgeNextInstanceUtcL(startTimeUtc, firstInstanceUtc)) + { + isStillRpt = MoveStartTimeLocalL(AgnDateTime::ConvertToLocalTimeL(firstInstanceUtc)); + } + + if (isStillRpt) + { + //Need to call UntilTimeL because iUntilTime might be set according to the iCount. + repeat->UntilTimeL(); + } + } + } + } + + +EXPORT_C TBool CAgnSimpleEntry::MoveStartTimeLocalL(const TTime& aNewEntryTimeLocal) +/** This function shifts the time of the entry to the specified time. +This is used when a repeat rule is set which cannot have an instance on the DTSTART time (or DUE time for todos). +E.g. if an event has a DTSTART on a Monday but repeats every Wednesday, the DTSTART will be shifted to the Wednesday. + +@internalComponent +*/ + { + TBool isStillRpt = ETrue; + TTime startTime = aNewEntryTimeLocal; + if (Type() == CCalEntry::ETodo) + { + startTime = DurationMinusL(startTime); + } + TAgnCalendarTime startAgnTime; + TAgnCalendarTime endAgnTime; + if (TimeMode() == MAgnCalendarTimeMode::EFloating) + { + startAgnTime.SetFloatingL(startTime); + endAgnTime.SetFloatingL(DurationPlusL(startTime)); + } + else + { + startAgnTime.SetLocalL(startTime); + endAgnTime.SetLocalL(DurationPlusL(startTime)); + } + + SetStartAndEndTimeL(startAgnTime, endAgnTime); + + if (iRptDef && iRptDef->RRule()) + { + if (iRptDef->RRule()->InvariantL()) + { + iRptDef->ClearRRule(); + isStillRpt = EFalse; + } + } + return isStillRpt; + } + +void CAgnSimpleEntry::StartTimeChanged() +/** +@internalComponent +*/ + { + if (iRptDef) + { + iRptDef->StartTimeChanged(); + } + } + +EXPORT_C TTime CAgnSimpleEntry::DurationPlusL(const TTime& aTime) const +/* +@internalComponent +Return the Time of aTime plus the duration of the entry. +*/ + { + if ( ! iEndTime.IsSet() || ! StartTime().IsSet()) + { + return aTime; + } + + TTime returnTime(aTime); + + // add the duration in minutes (there anough minutes to cover the whole of the agenda time range) + TTimeIntervalMinutes deltaMinutes; + iEndTime.LocalL().MinutesFrom(iStartTime.LocalL(), deltaMinutes); + returnTime += deltaMinutes; + + // add the microseconds + TTimeIntervalMicroSeconds deltaMicroSeconds = iEndTime.LocalL().MicroSecondsFrom(iStartTime.LocalL() + deltaMinutes); + returnTime += deltaMicroSeconds; + + return returnTime; + } + +EXPORT_C TTime CAgnSimpleEntry::DurationMinusL(const TTime& aTime) const +/* +@internalComponent +Return the Time of aTime minus the duration of the entry. +*/ + { + if ( ! iEndTime.IsSet() || ! StartTime().IsSet()) + { + return aTime; + } + + TTime returnTime(aTime); + + // add the duration in minutes (there anough minutes to cover the whole of the agenda time range) + TTimeIntervalMinutes deltaMinutes; + iEndTime.LocalL().MinutesFrom(iStartTime.LocalL(), deltaMinutes); + returnTime -= deltaMinutes; + + // add the microseconds + TTimeIntervalMicroSeconds deltaMicroSeconds = iEndTime.LocalL().MicroSecondsFrom(iStartTime.LocalL() + deltaMinutes); + returnTime -= deltaMicroSeconds; + + return returnTime; + } + +EXPORT_C const TAgnCalendarTime& CAgnSimpleEntry::StartTime() const +/** +@internalComponent +*/ + { + return iStartTime; + } + +EXPORT_C const TAgnCalendarTime& CAgnSimpleEntry::EndTime() const +/** +@internalComponent +*/ + { + return iEndTime; + } + +EXPORT_C MAgnCalendarTimeMode::TTimeMode CAgnSimpleEntry::TimeMode() const +/** +@internalComponent +*/ + { + if (!iStartTime.IsSet() && iEndTime.IsSet()) + { + return iEndTime.TimeMode(); + } + return iStartTime.TimeMode(); + } + +EXPORT_C void CAgnSimpleEntry::ExternalizeL(RWriteStream& aStream, TBool aToBuffer) const +/** +@internalComponent +*/ + { + doExternalizeL(aStream, aToBuffer); + aStream.WriteInt32L(iUserInt); + } + +void CAgnSimpleEntry::doExternalizeL(RWriteStream& aStream, TBool aToBuffer) const + { + iEntryId.ExternalizeL(aStream); + if (iRptDef) + { + aStream.WriteUint8L(ETrue); + iRptDef->ExternalizeL(aStream, aToBuffer); + } + else + { + aStream.WriteUint8L(EFalse); + } + + if (HasAlarm()) + { + aStream.WriteInt32L(iAlarmOffset); + } + else + { + aStream.WriteInt32L(KAlarmNotSet); + } + + aStream.WriteUint8L(iStatus); + + aStream << iLastModifiedDateUtc.Int64(); + aStream.WriteUint8L(iPriority); + aStream << iStartTime; + aStream << iEndTime; + aStream << iCompletedDateUtc.Int64(); + aStream << iLocalUid; + } + +EXPORT_C void CAgnSimpleEntry::ExternalizeGuidHashL(RWriteStream& aStream) const + { + aStream.WriteUint32L(iGuidHash); + } + +EXPORT_C void CAgnSimpleEntry::InternalizeL(RReadStream& aStream, TBool aFromBuffer) +/** +@internalComponent +*/ + { + doInternalizeL(aStream, aFromBuffer); + iUserInt = aStream.ReadInt32L(); + } + +void CAgnSimpleEntry::doInternalizeL(RReadStream& aStream, TBool aFromBuffer) + { + iEntryId.InternalizeL(aStream); + + delete iRptDef; + iRptDef = NULL; + if (aStream.ReadUint8L()) + { + iRptDef = CAgnRptDef::NewL(*this); + iRptDef->InternalizeL(aStream, aFromBuffer); + } + iAlarmOffset = aStream.ReadInt32L(); + + iStatus = static_cast(aStream.ReadUint8L()); + + TInt64 lastChanged; + aStream >> lastChanged; + iLastModifiedDateUtc = lastChanged; + iPriority = aStream.ReadUint8L(); + + aStream >> iStartTime; + aStream >> iEndTime; + StartTimeChanged(); + + TInt64 completedDate; + aStream >> completedDate; + iCompletedDateUtc = completedDate; + aStream >> iLocalUid; + } + +EXPORT_C void CAgnSimpleEntry::InternalizeGuidHashL(RReadStream& aStream) + { + iGuidHash = aStream.ReadUint32L(); + } + + +EXPORT_C const TAgnEntryId& CAgnSimpleEntry::EntryId() const +/** +@internalComponent +*/ + { + return iEntryId; + } + +EXPORT_C void CAgnSimpleEntry::SetEntryId(const TAgnEntryId& aId) +/** +@internalComponent +*/ + { + iEntryId = aId; + } + +EXPORT_C TCalLocalUid CAgnSimpleEntry::LocalUid() const +/** Gets the entry's unique ID. + +The unique ID is assigned when the entry is created, and is preserved during updates. +Because of this, it can be used to identify the entry during synchronisation. + +@return The entry's unique ID. +@internalComponent +*/ + { + return iLocalUid; + } + +EXPORT_C void CAgnSimpleEntry::SetLocalUid(TCalLocalUid aUId) +/** Sets the entry's unique ID. + +@param aUId The entry's unique ID. + +@internalComponent +*/ + { + iLocalUid = aUId; + } + +EXPORT_C TUint32 CAgnSimpleEntry::GuidHash() const +/** +@internalComponent +*/ + { + return iGuidHash; + } + +EXPORT_C void CAgnSimpleEntry::SetGuidHash(TUint32 aGuidHash) +/** +@internalComponent +*/ + { + iGuidHash = aGuidHash; + } + +EXPORT_C const TAgnCalendarTime& CAgnSimpleEntry::EntryTime() const +/** +@internalComponent +*/ + { + if (Type() == CCalEntry::ETodo) + { + return iEndTime; + } + return iStartTime; + } + +EXPORT_C TTime CAgnSimpleEntry::ValidFromTimeLocalL() const +/** +@internalComponent +*/ + { + TTime startTimeLocal(iStartTime.LocalL()); + TTime firstInstanceLocal(AgnDateTime::MaxDate()); + + if (iRptDef) + { + firstInstanceLocal = iRptDef->FirstInstanceL().LocalL(); + + if (Type() == CCalEntry::ETodo) + { + // for a todo, the instance time minus the duration is the start of the first instance + firstInstanceLocal = DurationMinusL(firstInstanceLocal); + } + } + + // If iEndTime is not set then this is an undated todo so we should return that (Time::NullTTime()) + // otherwise we should return the earliest from either the repeat rule or the entry itself + return ( iEndTime.IsSet() && (firstInstanceLocal < startTimeLocal )) ? firstInstanceLocal : startTimeLocal; + } + +EXPORT_C TTime CAgnSimpleEntry::ValidToTimeLocalL() const +/** +@internalComponent +*/ + { + TTime endTimeLocal(iEndTime.LocalL()); + TTime lastInstanceLocal(AgnDateTime::MinDate()); + + if (iRptDef) + { + lastInstanceLocal = iRptDef->LastInstanceL().LocalL(); + + if (Type() != CCalEntry::ETodo) + { + // for a non-todo, the until time plus duration is the end of the last instance + lastInstanceLocal = DurationPlusL(lastInstanceLocal); + } + } + + // If iEndTime is not set then this is an undated todo so we should return that (Time::NullTTime()) + // otherwise we should return the latest from either the repeat rule or the entry itself + return ( iEndTime.IsSet() && (lastInstanceLocal > endTimeLocal)) ? lastInstanceLocal : endTimeLocal; + } + +/** +Sets the user integer for this entry. + +@param aUserInt The new value of the user integer. +@internalComponent +*/ +EXPORT_C void CAgnSimpleEntry::SetUserInt( TUint32 aUserInt ) + { + iUserInt = aUserInt; + } + +/** +Gets the user integer of this entry. + +@return The user integer. +@internalComponent +*/ +EXPORT_C TUint32 CAgnSimpleEntry::UserInt() const + { + return iUserInt; + } +