--- /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<CCalEntry::TType>(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<CCalEntry::TStatus>(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<TAgnRpt*> (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<CCalEntry::TStatus>(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;
+ }
+