--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/meetingrequest/mrservices/src/cesmrrecurrenceinfohandler.cpp Wed Sep 01 12:28:57 2010 +0100
@@ -0,0 +1,1716 @@
+/*
+* Copyright (c) 2007-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: This file implements CESMRRecurrenceInfoHandler.
+*
+*/
+
+#include "cesmrrecurrenceinfohandler.h"
+#include "cesmrcaluserutil.h"
+#include "esmrdef.h"
+#include "mesmrmeetingrequestentry.h"
+#include "cesmrcaldbmgr.h"
+
+#include <calentry.h>
+#include <calrrule.h>
+#include <ct/rcpointerarray.h>
+#include <calinstanceview.h>
+#include <calinstanceiterator.h>
+
+#include <calinstance.h>
+
+#include "emailtrace.h"
+
+/// Unnamed namespace for local definitions
+namespace {
+
+// Definition for 0
+const TInt KZero = 0;
+
+// Definition for 1
+const TInt KOne = 1;
+
+// Definition for 2
+const TInt KTwo = 2;
+
+// Definition for days in week
+const TInt KDaysInWeek = 7;
+
+// Definition for days in two weeks
+const TInt KDaysInTwoWeeks = 14;
+
+// Definition for montsh in year
+const TInt KMonthsInYear = 12;
+
+/**
+ * Compares two times and returns ETrue if they have same date components
+ * @param aLhs Left hand side component
+ * @param aRhs Right hand side component
+ */
+TBool IsSameDay(
+ const TDateTime& aLhs,
+ const TDateTime& aRhs )
+ {
+ TBool retValue(EFalse);
+
+ if ( aLhs.Day() == aRhs.Day() &&
+ aLhs.Month() == aRhs.Month() &&
+ aLhs.Year() == aRhs.Year() )
+ {
+ retValue = ETrue;
+ }
+
+ return retValue;
+ }
+
+/**
+ * Checks if instance is included in exception list.
+ * @param aInstanceTime Reference to instance time.
+ * @param aExDateList Reference to exception list.
+ */
+TBool IsTimeIncluded(
+ const TCalTime& aInstanceTime,
+ const RArray<TCalTime>& aExDateList )
+ {
+ FUNC_LOG;
+ TBool included( EFalse );
+ TInt exceptionCount( aExDateList.Count() );
+ if ( exceptionCount )
+ {
+ for (TInt i(0); (i < exceptionCount) && !included ; i++ )
+ {
+ const TCalTime& exceptionTime( aExDateList[i] );
+ TDateTime exDate = exceptionTime.TimeLocalL().DateTime();
+
+ if ( aInstanceTime.TimeLocalL() == exceptionTime.TimeLocalL() )
+ {
+ included = ETrue;
+ }
+ }
+ }
+ return included;
+ }
+
+/**
+ * Calculates time for next instance for recurrent event.
+ * @param aRecurrenceValue Defines the used recurrence.
+ * @param aPrevInstanceStartTime Start time of the previous instance.
+ */
+TTime TimeForNextInstaceStartTime(
+ TESMRRecurrenceValue aRecurrenceValue,
+ TCalTime& aPrevInstanceStartTime )
+ {
+ TTime nextStartTime = aPrevInstanceStartTime.TimeLocalL();
+
+ switch ( aRecurrenceValue )
+ {
+ case ERecurrenceDaily:
+ {
+ nextStartTime += TTimeIntervalDays( KOne );
+ }
+ break;
+ case ERecurrenceWeekly:
+ {
+ nextStartTime += TTimeIntervalDays( KDaysInWeek );
+ }
+ break;
+ case ERecurrenceEverySecondWeek:
+ {
+ nextStartTime += TTimeIntervalDays( KDaysInTwoWeeks );
+ }
+ break;
+ case ERecurrenceMonthly:
+ {
+ nextStartTime += TTimeIntervalMonths( KOne );
+ }
+ break;
+ case ERecurrenceYearly:
+ {
+ nextStartTime += TTimeIntervalYears( KOne );
+ }
+ break;
+ default:
+ {
+ nextStartTime = aPrevInstanceStartTime.TimeLocalL();
+ }
+ break;
+ }
+
+ return nextStartTime;
+ }
+
+
+void CalculateUntilForUnknownRecurrenceL(
+ TTime& aUntil,
+ TCalRRule& aRule )
+ {
+ aUntil = aRule.Until().TimeLocalL();
+ if ( Time::NullTTime() == aUntil )
+ {
+ aUntil = aRule.DtStart().TimeLocalL();
+ TInt factor( aRule.Count() * aRule.Interval() );
+
+ switch ( aRule.Type() )
+ {
+ case TCalRRule::EDaily:
+ {
+ aUntil += TTimeIntervalDays(factor );
+ }
+ break;
+ case TCalRRule::EWeekly:
+ {
+ aUntil += TTimeIntervalDays(factor * KDaysInWeek );
+ }
+ break;
+ case TCalRRule::EMonthly:
+ {
+ aUntil += TTimeIntervalMonths(factor );
+ }
+ break;
+ case TCalRRule::EYearly:
+ {
+ aUntil += TTimeIntervalYears(factor );
+ }
+ break;
+ }
+ }
+ }
+
+/**
+ * Checks if entry's recurrence end time is being adjusted
+ * @param aEntry Reference to entry
+ */
+TBool RecurrenceEndtimeAdjustedL(
+ const CCalEntry& aEntry,
+ MESMRCalDbMgr& aCalDb )
+ {
+ TBool retValue( EFalse );
+
+ TCalRRule rRule;
+ if ( aEntry.GetRRuleL( rRule) )
+ {
+ TCalTime recurrenceId;
+ recurrenceId.SetTimeUtcL( Time::NullTTime() );
+ CCalEntry* entry = aCalDb.FetchEntryL( aEntry.UidL(), recurrenceId );
+ CleanupStack::PushL( entry );
+
+ if ( entry )
+ {
+ TCalRRule entryRRule;
+ if ( entry->GetRRuleL( entryRRule ) )
+ {
+ TTime until1 = entryRRule.Until().TimeLocalL();
+ TTime until2 = rRule.Until().TimeLocalL();
+
+ if ( until1 != until2 )
+ {
+ retValue = ETrue;
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy( entry );
+ }
+
+ return retValue;
+ }
+
+/**
+ * Get the beginning of current param time
+ * @param aStartTime Reference to time
+ */
+TTime BeginningOfDay( const TTime& aStartTime )
+ {
+ TTime zero(TInt64(0));
+ return zero + aStartTime.DaysFrom( zero );
+ }
+
+/**
+ * Get the Time, hour, minute, sec, micsec of current param time
+ * @param aStartTime Reference to time
+ */
+TTimeIntervalMinutes TimeOfDay( const TTime& aDateTime )
+ {
+ TTime midnight = BeginningOfDay( aDateTime );
+ TTimeIntervalMinutes result;
+ aDateTime.MinutesFrom( midnight, result );
+
+ return result;
+ }
+
+template<typename T> class CleanupResetAndDestroyClose
+ {
+ public:
+ inline static void PushL( T& aRef );
+ private:
+ static void Close( TAny *aPtr );
+ };
+
+template<typename T> inline void CleanupResetAndDestroyClosePushL( T& aRef );
+
+template<typename T> inline void CleanupResetAndDestroyClose<T>::PushL( T& aRef )
+ {
+ CleanupStack::PushL( TCleanupItem( &Close, &aRef ) );
+ }
+
+template<typename T> void CleanupResetAndDestroyClose<T>::Close( TAny *aPtr )
+ {
+ static_cast<T*>(aPtr)->ResetAndDestroy();
+ static_cast<T*>(aPtr)->Close();
+ }
+
+template<typename T> inline void CleanupResetAndDestroyClosePushL( T& aRef )
+ {
+ CleanupResetAndDestroyClose<T>::PushL( aRef );
+ }
+
+} // namespace
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::CESMRRecurrenceInfoHandler
+// ---------------------------------------------------------------------------
+//
+inline CESMRRecurrenceInfoHandler::CESMRRecurrenceInfoHandler(
+ CCalEntry& aEntry,
+ MESMRCalDbMgr* aCalDb ) :
+ iEntry( aEntry ),
+ iCalDb( aCalDb )
+ {
+ FUNC_LOG;
+ // Not implementation yet
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::~CESMRRecurrenceInfoHandler
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CESMRRecurrenceInfoHandler::~CESMRRecurrenceInfoHandler()
+ {
+ FUNC_LOG;
+ // Not implementation yet
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::NewL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CESMRRecurrenceInfoHandler* CESMRRecurrenceInfoHandler::NewL(
+ CCalEntry& aEntry )
+ {
+ FUNC_LOG;
+
+ CESMRRecurrenceInfoHandler* self = NewLC( aEntry, NULL );
+ CleanupStack::Pop( self );
+
+
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::NewL
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CESMRRecurrenceInfoHandler* CESMRRecurrenceInfoHandler::NewL(
+ CCalEntry& aEntry,
+ MESMRCalDbMgr* aCalDb )
+ {
+ FUNC_LOG;
+
+ CESMRRecurrenceInfoHandler* self = NewLC( aEntry, aCalDb );
+ CleanupStack::Pop( self );
+
+
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::NewLC
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CESMRRecurrenceInfoHandler* CESMRRecurrenceInfoHandler::NewLC(
+ CCalEntry& aEntry )
+ {
+ FUNC_LOG;
+
+ CESMRRecurrenceInfoHandler* self =
+ new (ELeave) CESMRRecurrenceInfoHandler( aEntry, NULL );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+
+
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::NewLC
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CESMRRecurrenceInfoHandler* CESMRRecurrenceInfoHandler::NewLC(
+ CCalEntry& aEntry,
+ MESMRCalDbMgr* aCalDb )
+ {
+ FUNC_LOG;
+
+ CESMRRecurrenceInfoHandler* self =
+ new (ELeave) CESMRRecurrenceInfoHandler( aEntry, aCalDb );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+
+
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CESMRRecurrenceInfoHandler::ConstructL()
+ {
+ FUNC_LOG;
+ // Not implementation yet
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::SetRecurrenceL
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CESMRRecurrenceInfoHandler::SetRecurrenceL(
+ TESMRRecurrenceValue aRecurrence,
+ TTime aUntil )
+ {
+ FUNC_LOG;
+
+ // Recurrence until time needs to be in Utc mode, because comparison in
+ // NeedToSetRecurrenceL is based on UTC times
+ TCalTime until;
+ until.SetTimeLocalL( aUntil );
+ TTime recUntilUtc = until.TimeUtcL();
+
+ // Check input parameters
+ if ( ERecurrenceNot != aRecurrence &&
+ Time::NullTTime() == aUntil )
+ {
+ // No until parameter set --> Leave
+ User::Leave( KErrArgument );
+ }
+ else if ( ERecurrenceNot == aRecurrence )
+ {
+ // Clear all (recurrence, exceptions) repeating properties
+ iEntry.ClearRepeatingPropertiesL();
+ }
+ else if ( NeedToSetRecurrenceL(aRecurrence, recUntilUtc) )
+ {
+ // Calculate 'correct' until time
+ // Date component is taken from input parameter and
+ // time component from meeting's end time.
+ TDateTime until = aUntil.DateTime();
+ TDateTime endTime = iEntry.EndTimeL().TimeLocalL().DateTime();
+ until.SetHour( endTime.Hour() );
+ until.SetMinute( endTime.Minute() );
+ until.SetSecond( endTime.Second() );
+
+ TCalTime rEndTime;
+ rEndTime.SetTimeLocalL( TTime(until) );
+
+ TCalTime meetingStartTime = iEntry.StartTimeL();
+
+ TCalRRule rRule;
+ rRule.SetDtStart( meetingStartTime );
+
+ // Clear recurrence properties before setting the correct one
+ iEntry.ClearRepeatingPropertiesL();
+
+ switch ( aRecurrence )
+ {
+ case ERecurrenceDaily:
+ {
+ // Set daily recurrence
+ rRule.SetType( TCalRRule::EDaily );
+
+ TTimeIntervalDays daysBetween =
+ rEndTime.TimeLocalL().DaysFrom(
+ meetingStartTime.TimeLocalL() );
+
+ // First occurence and days between
+ rRule.SetCount( daysBetween.Int() + KOne);
+ rRule.SetInterval( KOne );
+ }
+ break;
+
+ case ERecurrenceWeekly:
+ {
+ // Set weekly recurrence.
+ rRule.SetType( TCalRRule::EWeekly );
+ TTimeIntervalDays weeksBetween =
+ rEndTime.TimeLocalL().DaysFrom(
+ meetingStartTime.TimeLocalL() );
+
+ weeksBetween = weeksBetween.Int() / KDaysInWeek;
+
+ RArray<TDay> dayArray;
+ CleanupClosePushL( dayArray );
+ dayArray.Append( rRule.DtStart().TimeLocalL().DayNoInWeek() );
+ rRule.SetByDay( dayArray );
+ CleanupStack::PopAndDestroy( &dayArray );
+
+ // First occurence and weeks between
+ rRule.SetCount(
+ weeksBetween.Int() + KOne);
+ rRule.SetInterval( KOne );
+ }
+ break;
+
+ case ERecurrenceEverySecondWeek:
+ {
+ // Set bi-weekly recurrence. This is weekly recurrence
+ // with 2 weeks interval.
+ rRule.SetType( TCalRRule::EWeekly );
+ TTimeIntervalDays fortNightBetween =
+ rEndTime.TimeLocalL().DaysFrom(
+ meetingStartTime.TimeLocalL() );
+
+ fortNightBetween =
+ fortNightBetween.Int() / KDaysInTwoWeeks;
+
+ RArray<TDay> dayArray;
+ CleanupClosePushL( dayArray );
+ dayArray.Append( rRule.DtStart().TimeLocalL().DayNoInWeek() );
+ rRule.SetByDay( dayArray );
+ CleanupStack::PopAndDestroy( &dayArray );
+
+ // First occurence and fortnights between
+ rRule.SetCount(
+ fortNightBetween.Int() + KOne);
+ rRule.SetInterval( KTwo );
+ }
+ break;
+
+ case ERecurrenceMonthly:
+ {
+ // Set monthly recurrence.
+ rRule.SetType( TCalRRule::EMonthly );
+
+ RArray<TInt> dateArray;
+ CleanupClosePushL( dateArray );
+ dateArray.Append(
+ rRule.DtStart().TimeLocalL().DayNoInMonth() );
+ rRule.SetByMonthDay( dateArray );
+ CleanupStack::PopAndDestroy( &dateArray );
+
+ TTimeIntervalMonths monthsBetween =
+ rEndTime.TimeLocalL().MonthsFrom(
+ meetingStartTime.TimeLocalL() );
+
+ // First occurence and months between
+ rRule.SetCount( monthsBetween.Int() + KOne);
+ rRule.SetInterval( KOne );
+ }
+ break;
+
+ case ERecurrenceYearly:
+ {
+ // Set yearly recurrence.
+ rRule.SetType( TCalRRule::EYearly );
+
+ TTimeIntervalYears yearsBetween =
+ rEndTime.TimeLocalL().YearsFrom(
+ meetingStartTime.TimeLocalL() );
+
+ // First occurence and months between
+ rRule.SetCount( yearsBetween.Int() + KOne);
+ rRule.SetInterval( KOne );
+ }
+ default:
+ break;
+ }
+ iEntry.SetRRuleL( rRule );
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::GetRecurrenceL
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CESMRRecurrenceInfoHandler::GetRecurrenceL(
+ TESMRRecurrenceValue& aRecurrence,
+ TTime& aUntil) const
+ {
+ FUNC_LOG;
+
+ TESMRRecurrenceValue recurrenceValue(ERecurrenceNot);
+
+ // Let's get RDates of the entry also to see if entry is repeating
+ RArray<TCalTime> rdates;
+ CleanupClosePushL( rdates );
+ iEntry.GetRDatesL( rdates );
+
+ TBool hasRdates = rdates.Count() > 0;
+
+ TCalRRule rRule;
+ if ( iEntry.GetRRuleL(rRule) || hasRdates )
+ {
+ // Entry has recurrence
+ recurrenceValue = ERecurrenceUnknown;
+
+ TCalRRule::TType rType = rRule.Type();
+ TInt interval = rRule.Interval();
+
+ switch ( rType )
+ {
+ case TCalRRule::EInvalid:
+ {
+ // Recurrence type has not yet been defined
+ // --> Consider it then unknown.
+ recurrenceValue = ERecurrenceUnknown;
+ }
+ break;
+
+ case TCalRRule::EDaily:
+ {
+ HandleDailyRecurrenceL( recurrenceValue, rRule );
+ }
+ break;
+
+ case TCalRRule::EWeekly:
+ {
+ HandleWeeklyRecurrenceL( recurrenceValue, rRule );
+ }
+ break;
+
+ case TCalRRule::EMonthly:
+ {
+ HandleMonthlyRecurrenceL( recurrenceValue, rRule );
+ }
+ break;
+
+ case TCalRRule::EYearly:
+ {
+ // Recurrence is based on a number of years
+ if ( KOne == interval)
+ {
+ recurrenceValue = ERecurrenceYearly;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if ( hasRdates )
+ {
+ // Getting the last RDates occurance time == Until time
+ aUntil = rdates[ rdates.Count() - 1 ].TimeUtcL();
+ }
+ else
+ {
+ CalculateRecurrenceUntilDateL(
+ recurrenceValue,
+ aUntil,
+ rRule,
+ iEntry );
+ }
+ }
+
+ CleanupStack::PopAndDestroy( &rdates );
+ aRecurrence = recurrenceValue;
+ }
+
+
+EXPORT_C void CESMRRecurrenceInfoHandler::RemoveInstanceL(
+ TCalTime aInstanceTime )
+ {
+ FUNC_LOG;
+
+ RArray<TCalTime> exDateList;
+ CleanupClosePushL( exDateList );
+
+ TDateTime instanceException = aInstanceTime.TimeLocalL().DateTime();
+ instanceException.SetHour( KZero );
+ instanceException.SetMinute( KZero );
+ instanceException.SetSecond( KZero );
+ instanceException.SetMicroSecond( KZero );
+
+ TCalTime exceptionTime;
+ exceptionTime.SetTimeUtcL( TTime(instanceException) );
+
+ iEntry.GetExceptionDatesL( exDateList );
+ exDateList.Append( exceptionTime );
+ iEntry.SetExceptionDatesL( exDateList );
+
+ CleanupStack::PopAndDestroy( &exDateList );
+
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::AddExceptionL
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CESMRRecurrenceInfoHandler::AddExceptionL(
+ TCalTime aNewInstanceTime,
+ TCalTime aOrginalInstanceTime )
+ {
+ FUNC_LOG;
+
+ // Entry's time has been modified and exception
+ // needs to be added to parent entry
+ RArray<TCalTime> rDateList;
+ CleanupClosePushL( rDateList );
+
+ RArray<TCalTime> exDateList;
+ CleanupClosePushL( exDateList );
+
+ // Only this instance is edited --> Set RRULE to entry
+ iEntry.GetRDatesL( rDateList );
+ iEntry.GetExceptionDatesL( exDateList );
+
+ rDateList.Append( aNewInstanceTime );
+ exDateList.Append( aOrginalInstanceTime );
+
+ iEntry.SetRDatesL( rDateList );
+ iEntry.SetExceptionDatesL( exDateList );
+
+ CleanupStack::PopAndDestroy( &exDateList );
+ CleanupStack::PopAndDestroy( &rDateList );
+
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::CopyRecurrenceInformationToL
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CESMRRecurrenceInfoHandler::CopyRecurrenceInformationToL(
+ CCalEntry& aDestination )
+ {
+ FUNC_LOG;
+
+ aDestination.ClearRepeatingPropertiesL();
+
+ TCalRRule rrule;
+ if ( iEntry.GetRRuleL(rrule) )
+ {
+ aDestination.SetRRuleL( rrule );
+
+ RArray<TCalTime> rDateList;
+ CleanupClosePushL( rDateList );
+
+ RArray<TCalTime> exDateList;
+ CleanupClosePushL( exDateList );
+
+ iEntry.GetRDatesL( rDateList );
+ iEntry.GetExceptionDatesL( exDateList );
+
+ aDestination.SetRDatesL( rDateList );
+ aDestination.SetExceptionDatesL( exDateList );
+
+ CleanupStack::PopAndDestroy( &exDateList );
+ CleanupStack::PopAndDestroy( &rDateList );
+ }
+
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::CopyRecurrenceInformationFromL
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CESMRRecurrenceInfoHandler::CopyRecurrenceInformationFromL(
+ const CCalEntry& aSource )
+ {
+ FUNC_LOG;
+
+ iEntry.ClearRepeatingPropertiesL();
+
+ TCalRRule rrule;
+ if ( aSource.GetRRuleL(rrule) )
+ {
+ iEntry.SetRRuleL( rrule );
+
+ RArray<TCalTime> rDateList;
+ CleanupClosePushL( rDateList );
+
+ RArray<TCalTime> exDateList;
+ CleanupClosePushL( exDateList );
+
+ aSource.GetRDatesL( rDateList );
+ aSource.GetExceptionDatesL( exDateList );
+
+ iEntry.SetRDatesL( rDateList );
+ iEntry.SetExceptionDatesL( exDateList );
+
+ CleanupStack::PopAndDestroy( &exDateList );
+ CleanupStack::PopAndDestroy( &rDateList );
+ }
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::GetFirstInstanceTimeL
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CESMRRecurrenceInfoHandler::GetFirstInstanceTimeL(
+ TCalTime& aStart,
+ TCalTime& aEnd )
+ {
+ FUNC_LOG;
+
+ TESMRRecurrenceValue recurrence( ERecurrenceNot );
+ TTime until( Time::NullTTime() );
+ GetRecurrenceL( recurrence, until );
+
+ if ( ERecurrenceNot == recurrence )
+ {
+ aStart = iEntry.StartTimeL();
+ aEnd = iEntry.EndTimeL();
+ }
+ else if ( ERecurrenceUnknown != recurrence )
+ {
+ aStart = iEntry.StartTimeL();
+ aEnd = iEntry.EndTimeL();
+
+ TTimeIntervalMinutes diff;
+ aEnd.TimeLocalL().MinutesFrom(
+ aStart.TimeLocalL(),
+ diff );
+
+ RArray<TCalTime> exDateList;
+ CleanupClosePushL( exDateList );
+ iEntry.GetExceptionDatesL( exDateList );
+
+ TInt exceptionCount( exDateList.Count() );
+ if ( exceptionCount )
+ {
+ TBool timeIncludedInExceptionList(
+ IsTimeIncluded( aStart, exDateList ) );
+
+ while( timeIncludedInExceptionList )
+ {
+ TTime nextInstanceTime =
+ TimeForNextInstaceStartTime(
+ recurrence,
+ aStart );
+
+ aStart.SetTimeLocalL( nextInstanceTime);
+ timeIncludedInExceptionList =
+ IsTimeIncluded( aStart, exDateList );
+ }
+ }
+
+ TCalTime untilCalTime;
+ untilCalTime.SetTimeUtcL( until );
+
+ TDateTime nextTime = aStart.TimeLocalL().DateTime();
+ TDateTime untilTime = untilCalTime.TimeLocalL().DateTime();
+
+ if ( aStart.TimeUtcL() > untilCalTime.TimeUtcL() )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ TTime end = aStart.TimeLocalL() + diff;
+ aEnd.SetTimeLocalL( end );
+
+ CleanupStack::PopAndDestroy( &exDateList );
+ }
+ else
+ {
+ // Unknown recurrence type
+ aStart = iEntry.StartTimeL();
+ aEnd = iEntry.EndTimeL();
+ }
+
+ }
+
+// -----------------------------------------------------------------------------
+// CCalenEditorDataHandler::GetPreviousInstanceTimeL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CESMRRecurrenceInfoHandler::GetPreviousInstanceTimeL( TCalTime& aPreviousStartTime,
+ TCalTime& aPreviousEndTime,
+ TTime aInstanceDateTime )
+ {
+ FUNC_LOG;
+
+ aPreviousStartTime.SetTimeLocalL( Time::NullTTime() );
+ aPreviousEndTime.SetTimeLocalL( Time::NullTTime() );
+
+ RPointerArray<CCalEntry> entries;
+ CleanupResetAndDestroyClosePushL( entries );
+
+ iCalDb->EntryViewL( iEntry )->FetchL( iEntry.UidL(), entries );
+
+ TCalTime currentInstanceDate = iEntry.RecurrenceIdL();
+ if( currentInstanceDate.TimeUtcL() == Time::NullTTime() )
+ {
+ // We must be creating a new exception. Calculate the recurrence id.
+ TTimeIntervalMinutes timeOfDay = TimeOfDay( entries[0]->StartTimeL().TimeLocalL() );
+ TTime beginningOfDay = BeginningOfDay( aInstanceDateTime );
+ currentInstanceDate.SetTimeLocalL( beginningOfDay + timeOfDay );
+ }
+
+ TCalRRule rrule;
+ if( entries[0]->GetRRuleL(rrule) )
+ {
+ TESMRRecurrenceValue repeatIndex = RepeatIndexL( *entries[0] );
+
+ TBool keepLooking = ETrue;
+ RArray<TCalTime> exdates;
+ CleanupClosePushL( exdates );
+ entries[0]->GetExceptionDatesL(exdates);
+
+ // Needed for case ERepeatOther
+ TCalRRule::TType type( rrule.Type() );
+ TInt repeatInterval( rrule.Interval() );
+ TCalTime start, end;
+ TTime previousInstanceTime = Time::NullTTime();
+
+ while( keepLooking )
+ {
+ // Subtract the repeat interval of the parent.
+ switch( repeatIndex )
+ {
+ case ERecurrenceDaily:
+ {
+ currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(1) );
+ break;
+ }
+
+ case ERecurrenceWeekly:
+ {
+ currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(7) );
+ break;
+ }
+
+ case ERecurrenceEverySecondWeek:
+ {
+ currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(14) );
+ break;
+ }
+
+ case ERecurrenceMonthly:
+ {
+ currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalMonths(1) );
+ break;
+ }
+
+ case ERecurrenceYearly:
+ {
+ currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalYears(1) );
+ break;
+ }
+
+ case ERecurrenceUnknown:
+ {
+ // Check if the current entry being edited is child entry
+ // If yes, then put back the child entry time to currentInstanceDate
+ if( iEntry.RecurrenceIdL().TimeUtcL() != Time::NullTTime() )
+ {
+ TTimeIntervalMinutes timeOfDay = TimeOfDay( iEntry.StartTimeL().TimeLocalL() );
+ TTime beginningOfDay = BeginningOfDay( aInstanceDateTime );
+ currentInstanceDate.SetTimeLocalL( beginningOfDay + timeOfDay );
+ }
+
+ switch( type )
+ {
+ case TCalRRule::EDaily:
+ {
+ start.SetTimeLocalL( currentInstanceDate.TimeLocalL() -
+ TTimeIntervalDays( 1 * repeatInterval ) );
+ break;
+ }
+
+ case TCalRRule::EWeekly:
+ {
+ start.SetTimeLocalL( currentInstanceDate.TimeLocalL() -
+ TTimeIntervalDays(7 * repeatInterval) );
+ break;
+ }
+
+ case TCalRRule::EMonthly:
+ {
+ // Add 7 days of buffer to cover the cases were gap b/w two instances of the event
+ // can go beuong 30 days. Ex: Every third wednesday of every month
+ start.SetTimeLocalL( currentInstanceDate.TimeLocalL() -
+ TTimeIntervalMonths(repeatInterval)-TTimeIntervalDays(7 * repeatInterval) );
+ break;
+ }
+
+ case TCalRRule::EYearly:
+ {
+ // Add 7 days of buffer to cover the cases were gap b/w two instances of the event
+ // can go beuong 365 days. Ex: Every third wednesday of September of every year
+ start.SetTimeLocalL( currentInstanceDate.TimeLocalL() -
+ TTimeIntervalYears(repeatInterval)-TTimeIntervalDays(7 * repeatInterval) );
+ break;
+ }
+ }
+
+ end.SetTimeLocalL( BeginningOfDay( currentInstanceDate.TimeLocalL() ) );
+ previousInstanceTime = GetPreviousInstanceForRepeatOtherL( *entries[0],
+ CalCommon::TCalTimeRange(start, end) );
+ currentInstanceDate.SetTimeLocalL( previousInstanceTime );
+ break;
+ }
+
+ case ERecurrenceNot:
+ default:
+ {
+ keepLooking = EFalse;
+ break;
+ }
+ }
+
+ // Is currentInstanceDate before parent dt start?
+ if( currentInstanceDate.TimeLocalL() < entries[0]->StartTimeL().TimeLocalL() )
+ {
+ // There are no instances before the exception
+ keepLooking = EFalse;
+ }
+ else
+ {
+ // Is there an exdate on currentInstanceDate?
+ TBool isExdateOnDay = EFalse;
+ for(TInt i=0; i<exdates.Count(); ++i)
+ {
+ if( exdates[i].TimeLocalL() == currentInstanceDate.TimeLocalL() )
+ {
+ isExdateOnDay = ETrue;
+ // There is an exdate - is there a child associated with the exdate?
+ for(TInt j=1; j<entries.Count(); ++j)
+ {
+ if( entries[j]->RecurrenceIdL().TimeLocalL() == currentInstanceDate.TimeLocalL() )
+ {
+ // This child is the previous instance.
+ aPreviousStartTime = entries[j]->StartTimeL();
+ aPreviousEndTime = entries[j]->EndTimeL();
+ keepLooking = EFalse;
+ }
+ }
+ break;
+ }
+ }
+
+ if( !isExdateOnDay )
+ {
+ // The instance exists and hasn't been deleted or made into an exception.
+ // Use information from the parent to set the start/end times.
+ aPreviousStartTime = currentInstanceDate;
+
+ TTimeIntervalMinutes duration;
+ TTime start = entries[0]->StartTimeL().TimeLocalL();
+ TTime end = entries[0]->EndTimeL().TimeLocalL();
+ end.MinutesFrom( start, duration );
+ aPreviousEndTime.SetTimeLocalL( currentInstanceDate.TimeLocalL() + duration );
+ keepLooking = EFalse;
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy( &exdates );
+ }
+
+ CleanupStack::PopAndDestroy(&entries);
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::GetNextInstanceTimeL
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CESMRRecurrenceInfoHandler::GetNextInstanceTimeL( TCalTime& aNextStartTime,
+ TCalTime& aNextEndTime,
+ TTime aInstanceDateTime )
+ {
+ FUNC_LOG;
+ aNextStartTime.SetTimeLocalL( Time::NullTTime() );
+ aNextEndTime.SetTimeLocalL( Time::NullTTime() );
+
+ RPointerArray<CCalEntry> entries;
+ CleanupResetAndDestroyClosePushL(entries);
+
+ iCalDb->EntryViewL(iEntry)->FetchL( iEntry.UidL(), entries );
+ TCalTime currentInstanceDate = iEntry.RecurrenceIdL();
+
+ if( currentInstanceDate.TimeUtcL() == Time::NullTTime() )
+ {
+ // We must be creating a new exception. Calculate the recurrence id.
+ TTimeIntervalMinutes timeOfDay = TimeOfDay( entries[0]->StartTimeL().TimeLocalL() );
+ TTime beginningOfDay = BeginningOfDay( aInstanceDateTime );
+ currentInstanceDate.SetTimeLocalL( beginningOfDay + timeOfDay );
+ }
+
+ TCalRRule rrule;
+ if( entries[0]->GetRRuleL(rrule) )
+ {
+ TESMRRecurrenceValue repeatIndex = RepeatIndexL( *entries[0] );
+
+ TBool keepLooking = ETrue;
+ RArray<TCalTime> exdates;
+ CleanupClosePushL( exdates );
+ entries[0]->GetExceptionDatesL( exdates );
+
+ // Needed for case ERepeatOther
+ TCalRRule::TType type( rrule.Type() );
+ TInt repeatInterval( rrule.Interval() );
+ TCalTime start, end;
+ TTime nextInstanceTime = Time::NullTTime();
+
+ while( keepLooking )
+ {
+ // Subtract the repeat interval of the parent.
+ switch( repeatIndex )
+ {
+ case ERecurrenceDaily:
+ {
+ currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(1) );
+ break;
+ }
+
+ case ERecurrenceWeekly:
+ {
+ currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(7) );
+ break;
+ }
+
+ case ERecurrenceEverySecondWeek:
+ {
+ currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(14) );
+ break;
+ }
+
+ case ERecurrenceMonthly:
+ {
+ currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalMonths(1) );
+ break;
+ }
+
+ case ERecurrenceYearly:
+ {
+ currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalYears(1) );
+ break;
+ }
+
+ case ERecurrenceUnknown:
+ {
+ // Check if the current entry being edited is child entry
+ // If yes, then put back the child entry time to currentInstanceDate
+ if(iEntry.RecurrenceIdL().TimeUtcL() != Time::NullTTime())
+ {
+ TTimeIntervalMinutes timeOfDay = TimeOfDay( iEntry.StartTimeL().TimeLocalL() );
+ TTime beginningOfDay = BeginningOfDay( aInstanceDateTime );
+ currentInstanceDate.SetTimeLocalL( beginningOfDay + timeOfDay );
+ }
+
+ switch( type )
+ {
+ case TCalRRule::EDaily:
+ {
+ end.SetTimeLocalL( currentInstanceDate.TimeLocalL() +
+ TTimeIntervalDays(1*repeatInterval) );
+ break;
+ }
+
+ case TCalRRule::EWeekly:
+ {
+ end.SetTimeLocalL( currentInstanceDate.TimeLocalL() +
+ TTimeIntervalDays(7 *repeatInterval) );
+ break;
+ }
+
+ case TCalRRule::EMonthly:
+ {
+ // Add 7 days of buffer to cover the cases were gap b/w two instances of the event
+ // can go beuong 30 days. Ex: Every third wednesday of every month
+ end.SetTimeLocalL( currentInstanceDate.TimeLocalL() +
+ TTimeIntervalMonths(repeatInterval) + TTimeIntervalDays(7 * repeatInterval) );
+ break;
+ }
+
+ case TCalRRule::EYearly:
+ {
+ // Add 7 days of buffer to cover the cases were gap b/w two instances of the event
+ // can go beuong 365 days. Ex: Every third wednesday of September of every year
+ end.SetTimeLocalL( currentInstanceDate.TimeLocalL() +
+ TTimeIntervalYears(repeatInterval) + TTimeIntervalDays(7 * repeatInterval) );
+ break;
+ }
+ }
+
+ start.SetTimeLocalL(BeginningOfDay(currentInstanceDate.TimeLocalL()+TTimeIntervalDays(1)));
+ nextInstanceTime = GetNextInstanceForRepeatOtherL(*entries[0], CalCommon::TCalTimeRange( start, end));
+ currentInstanceDate.SetTimeLocalL( nextInstanceTime);
+ break;
+ }
+ case ERecurrenceNot:
+ {
+ keepLooking = EFalse;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ // Is currentInstanceDate after parent dt end?
+ if( currentInstanceDate.TimeLocalL() > rrule.Until().TimeLocalL() )
+ {
+ // There are no instances before the exception
+ keepLooking = EFalse;
+ }
+ else
+ {
+ // Is there an exdate on currentInstanceDate?
+ TBool isExdateOnDay = EFalse;
+ for(TInt i=0; i<exdates.Count(); ++i)
+ {
+ if( exdates[i].TimeLocalL() == currentInstanceDate.TimeLocalL() )
+ {
+ isExdateOnDay = ETrue;
+ // There is an exdate - is there a child associated with the exdate?
+ for(TInt j=1; j<entries.Count(); ++j)
+ {
+ if( entries[j]->RecurrenceIdL().TimeLocalL() == currentInstanceDate.TimeLocalL() )
+ {
+ // This child is the previous instance.
+ aNextStartTime = entries[j]->StartTimeL();
+ aNextEndTime = entries[j]->EndTimeL();
+ keepLooking = EFalse;
+ }
+ }
+ break;
+ }
+ }
+
+ if( !isExdateOnDay )
+ {
+ // The instance exists and hasn't been deleted or made into an exception.
+ // Use information from the parent to set the start/end times.
+ aNextStartTime = currentInstanceDate;
+
+ TTimeIntervalMinutes duration;
+ TTime start = entries[0]->StartTimeL().TimeLocalL();
+ TTime end = entries[0]->EndTimeL().TimeLocalL();
+ end.MinutesFrom( start, duration );
+ aNextEndTime.SetTimeLocalL( currentInstanceDate.TimeLocalL() + duration );
+ keepLooking = EFalse;
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy( &exdates );
+ }
+
+ CleanupStack::PopAndDestroy(&entries);
+ }
+
+
+// -----------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::GetPreviousInstanceForRepeatOtherL()
+//
+// -----------------------------------------------------------------------------
+//
+TTime CESMRRecurrenceInfoHandler::GetPreviousInstanceForRepeatOtherL(
+ CCalEntry& aEntry, const CalCommon::TCalTimeRange& timeRange)
+ {
+ RPointerArray<CCalInstance> allInstances;
+ CleanupResetAndDestroyClosePushL( allInstances );
+
+ TInt filter;
+ // Get the entry type to be filtered
+ switch(aEntry.EntryTypeL())
+ {
+ case CCalEntry::EAppt:
+ {
+ filter = CalCommon::EIncludeAppts;
+ break;
+ }
+
+ case CCalEntry::ETodo:
+ {
+ filter = CalCommon::EIncludeCompletedTodos | CalCommon::EIncludeIncompletedTodos;
+ break;
+ }
+
+ case CCalEntry::EEvent:
+ {
+ filter = CalCommon::EIncludeEvents;
+ break;
+ }
+
+ case CCalEntry::EReminder:
+ {
+ filter = CalCommon::EIncludeReminder;
+ break;
+ }
+
+ case CCalEntry::EAnniv:
+ {
+ filter = CalCommon::EIncludeAnnivs;
+ break;
+ }
+
+ default:
+ {
+ filter = CalCommon::EIncludeAll;
+ break;
+ }
+
+ };
+
+ iCalDb->InstanceViewL(iEntry)->FindInstanceL( allInstances,
+ (CalCommon::TCalViewFilterFlags)filter,
+ timeRange);
+
+ TTime previousTime = Time::NullTTime();
+
+ for( TInt i = allInstances.Count() - 1; i >= 0; i-- )
+ {
+ if( allInstances[i]->Entry().UidL() == aEntry.UidL() )
+ {
+ previousTime = allInstances[i]->Time().TimeLocalL();
+ break;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( &allInstances );
+ return previousTime;
+ }
+
+// -----------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::GetNextInstanceForRepeatOtherL()
+//
+// -----------------------------------------------------------------------------
+//
+TTime CESMRRecurrenceInfoHandler::GetNextInstanceForRepeatOtherL(
+ CCalEntry& aEntry, const CalCommon::TCalTimeRange& timeRange )
+ {
+ RPointerArray<CCalInstance> allInstances;
+ CleanupResetAndDestroyClosePushL( allInstances );
+
+ TInt filter;
+ // Get the entry type to be filtered
+ switch( aEntry.EntryTypeL() )
+ {
+ case CCalEntry::EAppt:
+ {
+ filter = CalCommon::EIncludeAppts;
+ break;
+ }
+ case CCalEntry::ETodo:
+ {
+ filter = CalCommon::EIncludeCompletedTodos | CalCommon::EIncludeIncompletedTodos;
+ break;
+ }
+ case CCalEntry::EEvent:
+ {
+ filter = CalCommon::EIncludeEvents;
+ break;
+ }
+ case CCalEntry::EReminder:
+ {
+ filter = CalCommon::EIncludeReminder;
+ break;
+ }
+ case CCalEntry::EAnniv:
+ {
+ filter = CalCommon::EIncludeAnnivs;
+ break;
+ }
+ default:
+ {
+ filter = CalCommon::EIncludeAll;
+ break;
+ }
+ };
+
+ iCalDb->InstanceViewL(iEntry)->FindInstanceL( allInstances,
+ ( CalCommon::TCalViewFilterFlags )filter,
+ timeRange);
+
+ TTime nextTime = Time::NullTTime();
+
+ TInt i( 0 );
+ for( ; i < allInstances.Count(); i++ )
+ {
+ if( allInstances[i]->Entry().UidL() == aEntry.UidL() )
+ {
+ nextTime = allInstances[i]->Time().TimeLocalL();
+ break;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( &allInstances );
+ return nextTime;
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::RepeatIndexL
+//
+// ---------------------------------------------------------------------------
+//
+TESMRRecurrenceValue CESMRRecurrenceInfoHandler::RepeatIndexL( const CCalEntry& aEntry )
+ {
+ FUNC_LOG;
+
+ TESMRRecurrenceValue repeatIndex( ERecurrenceNot );
+
+ TCalRRule rrule;
+
+ if( aEntry.GetRRuleL( rrule) )
+ {
+ TCalRRule::TType type( rrule.Type() );
+ TInt repeatInterval( rrule.Interval() );
+
+ // If repeat type of current note is not supported in Calendar,
+ // default repeat value is "Other".
+ repeatIndex = ERecurrenceUnknown;
+
+ switch( type )
+ {
+ case TCalRRule::EDaily:
+ {
+ switch (repeatInterval)
+ {
+ case 1:
+ {
+ repeatIndex = ERecurrenceDaily;
+ break;
+ }
+ case 7:
+ {
+ repeatIndex = ERecurrenceWeekly;
+ break;
+ }
+ case 14:
+ {
+ repeatIndex = ERecurrenceEverySecondWeek;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ break;
+ }
+
+ case TCalRRule::EWeekly:
+ {
+ switch( repeatInterval )
+ {
+ case 1:
+ {
+ repeatIndex = ERecurrenceWeekly;
+ break;
+ }
+ case 2:
+ {
+ repeatIndex = ERecurrenceEverySecondWeek;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ break;
+ }
+
+ case TCalRRule::EMonthly:
+ {
+ RArray<TInt> monthDays(31);
+ rrule.GetByMonthDayL ( monthDays );
+
+ if( monthDays.Count() == 1)
+ {
+ switch( repeatInterval )
+ {
+ case 1:
+ {
+ repeatIndex = ERecurrenceMonthly;
+ break;
+ }
+ // If interval of repeat is 12 months,
+ // every year is shown in Note Editor,
+ // because it means yearly repeat.
+ case 12:
+ {
+ repeatIndex = ERecurrenceYearly;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ monthDays.Close();
+ break;
+ }
+
+ case TCalRRule::EYearly:
+ {
+ if( repeatInterval == 1 )
+ {
+ repeatIndex = ERecurrenceYearly;
+ }
+ break;
+ }
+
+ default:
+ {
+ // If repeat type of current note is not supported in Calendar,
+ // default repeat value is "Other".
+ repeatIndex = ERecurrenceUnknown;
+ break;
+ }
+ }
+ }
+
+ return repeatIndex;
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::CalculateRecurrenceUntilDateL
+//
+// ---------------------------------------------------------------------------
+//
+void CESMRRecurrenceInfoHandler::CalculateRecurrenceUntilDateL(
+ TESMRRecurrenceValue aRecurrenceType,
+ TTime& aUntil,
+ TCalRRule& aRule,
+ const CCalEntry& aEntry ) const
+ {
+ FUNC_LOG;
+
+ TCalRRule::TType rType = aRule.Type();
+ TInt count = aRule.Count();
+ TCalTime until = aRule.Until();
+
+ if ( count == KZero &&
+ until.TimeUtcL() == Time::NullTTime() )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ if ( !count )
+ {
+ aUntil = until.TimeUtcL();
+ }
+ else
+ {
+ aUntil = aEntry.StartTimeL().TimeUtcL();
+ switch( aRecurrenceType )
+ {
+ case ERecurrenceDaily:
+ {
+ --count;
+ aUntil += TTimeIntervalDays(count);
+
+ CESMRCalUserUtil* entryUtil =
+ CESMRCalUserUtil::NewLC( const_cast<CCalEntry&>(aEntry) );
+
+ if ( iCalDb && entryUtil->IsAlldayEventL() &&
+ RecurrenceEndtimeAdjustedL( aEntry, *iCalDb ) )
+ {
+ // If until is adjusted for allday entries
+ // we wound return until day one day too long
+ aUntil -= TTimeIntervalDays( KOne );
+ }
+ CleanupStack::PopAndDestroy( entryUtil );
+ break;
+ }
+ case ERecurrenceWeekly:
+ {
+ --count;
+ aUntil += TTimeIntervalDays(count * KDaysInWeek);
+ break;
+ }
+ case ERecurrenceEverySecondWeek:
+ {
+ --count;
+ aUntil += TTimeIntervalDays(count * KDaysInTwoWeeks);
+ break;
+ }
+ case ERecurrenceMonthly:
+ {
+ --count;
+ aUntil += TTimeIntervalMonths(count);
+ break;
+ }
+ case ERecurrenceYearly:
+ {
+ --count;
+ aUntil += TTimeIntervalYears(count);
+ break;
+ }
+ default:
+ {
+ // Check if until date can be calculated
+ CalculateUntilForUnknownRecurrenceL( aUntil, aRule );
+ break;
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::HandleDailyRecurrenceL
+// ---------------------------------------------------------------------------
+//
+void CESMRRecurrenceInfoHandler::HandleDailyRecurrenceL(
+ TESMRRecurrenceValue& aRecurrenceValue,
+ TCalRRule& aRule ) const
+ {
+ FUNC_LOG;
+ TInt interval( aRule.Interval() );
+ aRecurrenceValue = ERecurrenceUnknown;
+
+ // Recurrence is based on a number of days
+ if ( KOne == interval )
+ {
+ // Recurrence occurs daily
+ aRecurrenceValue = ERecurrenceDaily;
+ }
+ else if ( KDaysInWeek == interval)
+ {
+ // Interval is seven days
+ // --> recurrence occurs weekly
+ aRecurrenceValue = ERecurrenceWeekly;
+ }
+ else if ( KDaysInTwoWeeks == interval )
+ {
+ // Interval is fortnight -->
+ // recurrence occurs bi-weekly
+ aRecurrenceValue = ERecurrenceEverySecondWeek;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::HandleWeeklyRecurrenceL
+// ---------------------------------------------------------------------------
+//
+void CESMRRecurrenceInfoHandler::HandleWeeklyRecurrenceL(
+ TESMRRecurrenceValue& aRecurrenceValue,
+ TCalRRule& aRule ) const
+ {
+ FUNC_LOG;
+ TInt interval( aRule.Interval() );
+
+ RArray<TDay> byDays;
+ CleanupClosePushL( byDays );
+ aRule.GetByDayL(byDays);
+
+ if ( byDays.Count() > KOne )
+ {
+ // Entry is repeated more than once every week or
+ // every second week.
+ aRecurrenceValue = ERecurrenceUnknown;
+ }
+ else if ( KOne == interval)
+ {
+ aRecurrenceValue = ERecurrenceWeekly;
+ }
+ else if ( KTwo == interval )
+ {
+ aRecurrenceValue = ERecurrenceEverySecondWeek;
+ }
+
+ CleanupStack::PopAndDestroy( &byDays );
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::HandleMonthlyRecurrenceL
+// ---------------------------------------------------------------------------
+//
+void CESMRRecurrenceInfoHandler::HandleMonthlyRecurrenceL(
+ TESMRRecurrenceValue& aRecurrenceValue,
+ TCalRRule& aRule ) const
+ {
+ FUNC_LOG;
+ TInt interval( aRule.Interval() );
+
+ aRecurrenceValue = ERecurrenceUnknown;
+
+ // Recurrence is based on a number of months
+ // Recurrence is based on a number of weeks
+ if ( KOne == interval)
+ {
+ aRecurrenceValue = ERecurrenceMonthly;
+ }
+ else if ( KMonthsInYear == interval )
+ {
+ aRecurrenceValue = ERecurrenceYearly;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::HandleYearlyRecurrenceL
+// ---------------------------------------------------------------------------
+//
+void CESMRRecurrenceInfoHandler::HandleYearlyRecurrenceL(
+ TESMRRecurrenceValue& aRecurrenceValue,
+ TCalRRule& aRule ) const
+ {
+ FUNC_LOG;
+ TInt interval( aRule.Interval() );
+
+ // Recurrence is based on a number of years
+ if ( KOne == interval)
+ {
+ aRecurrenceValue = ERecurrenceYearly;
+ }
+ else
+ {
+ aRecurrenceValue = ERecurrenceUnknown;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRRecurrenceInfoHandler::NeedToSetRecurrence
+//
+// ---------------------------------------------------------------------------
+//
+TBool CESMRRecurrenceInfoHandler::NeedToSetRecurrenceL(
+ TESMRRecurrenceValue aRecurrence,
+ TTime aUntil ) const
+ {
+ FUNC_LOG;
+ TBool retValue(ETrue);
+
+ TESMRRecurrenceValue oldRecurrence;
+ TTime oldUntil;
+ GetRecurrenceL( oldRecurrence, oldUntil );
+
+ if( oldRecurrence == aRecurrence &&
+ IsSameDay( aUntil.DateTime(), oldUntil.DateTime() ) )
+ {
+ // Recurrence is not changed --> No need to set
+ retValue = EFalse;
+ }
+
+ return retValue;
+ }
+
+// EOF
+