--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/meetingrequest/mrprocessor/mrcaleventplugin/src/cmrcalentry.cpp Wed Mar 31 21:08:33 2010 +0300
@@ -0,0 +1,1534 @@
+/*
+* Copyright (c) 2007-2008 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: Calendar Entry wrapper implementation
+*
+*/
+
+
+// INCLUDE FILES
+
+#include "cmrcalentry.h"
+#include "esmrhelper.h"
+
+#include "cesmrrecurrenceinfohandler.h"
+#include "cesmralarminfohandler.h"
+#include "tesmralarminfo.h"
+#include "cesmrcaluserutil.h"
+#include "cesmrcaldbmgr.h"
+#include "esmrentryhelper.h"
+#include "cesmrconflictchecker.h"
+
+#include <mrcaleventdata.rsg>
+#include <coemain.h>
+#include <e32std.h>
+#include <aknutils.h>
+#include <data_caging_path_literals.hrh>
+#include <centralrepository.h>
+#include <calentry.h>
+#include <calattachment.h>
+#include <calalarm.h>
+#include <calrrule.h>
+#include <calinstance.h>
+#include <calinstanceview.h>
+#include <caleninterimutils2.h>
+
+#include <calendarinternalcrkeys.h>
+#include <ct/rcpointerarray.h>
+
+#include <calenservices.h>
+
+#include "emailtrace.h"
+
+namespace { // codescanner::namespace
+
+const TInt KHoursInDay( 24 );
+const TInt KDefaultTodoAlarmHours( 12 );
+const TInt KDefaultAnniversaryAlarmHours( 12 );
+
+// Definition for max hours, minutes, seconds in day for To-Do
+const TInt KMaxHoursForTodo( 23 );
+const TInt KMaxMinutesForTodo( 59 );
+const TInt KMaxSecondsForTodo( 00 );
+
+// Definition for max hours, minutes, seconds in day for Memo
+const TInt KMaxHoursForMemo( 23 );
+const TInt KMaxMinutesForMemo( 59 );
+const TInt KMaxSecondsForMemo( 59 );
+
+// Definition for default alarm time for meeting
+const TInt KDefaultMeetingAlarmMinutes( 15 );
+
+// Definitions for alarm information resource file
+_LIT( KAlarmInfoResource, "mrcaleventdata.rsc" );
+
+#ifdef _DEBUG
+
+// Definition for panic text
+_LIT( KBCCalEntryPanicTxt, "MRCalEntry" );
+
+enum TBCCalEntryPanic
+ {
+ EBCCalEntryNotExist = 1, // Entry does not exist
+ };
+
+// ---------------------------------------------------------------------------
+// Raises panic.
+// ---------------------------------------------------------------------------
+//
+void Panic(TBCCalEntryPanic aPanic)
+ {
+ User::Panic( KBCCalEntryPanicTxt, aPanic);
+ }
+
+#endif // _DEBUG
+
+} // namespace
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::CMRCalEntry
+// ---------------------------------------------------------------------------
+//
+CMRCalEntry::CMRCalEntry(
+ MESMRCalDbMgr& aCalDb )
+: iCalDb( aCalDb )
+ {
+ FUNC_LOG;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::~CMRCalEntry
+// ---------------------------------------------------------------------------
+//
+CMRCalEntry::~CMRCalEntry()
+ {
+ FUNC_LOG;
+ delete iEntry;
+ delete iOriginalEntry;
+ delete iComparativeEntry;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::NewL
+// ---------------------------------------------------------------------------
+//
+CMRCalEntry* CMRCalEntry::NewL(
+ CCalEntry& aEntry,
+ MESMRCalDbMgr& aCalDb )
+ {
+ FUNC_LOG;
+
+ CMRCalEntry* self = new (ELeave) CMRCalEntry( aCalDb );
+ CleanupStack::PushL( self );
+ self->ConstructL( aEntry );
+ CleanupStack::Pop( self );
+
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::ConstructL(
+ CCalEntry& aEntry )
+ {
+ FUNC_LOG;
+ iOriginalEntry = CreateCopyL( aEntry );
+
+ // Create the entry for editing:
+ iEntry = CreateCopyL( *iOriginalEntry );
+
+ // Create copy of initialized entry for
+ // comparing purposes e.g. IsEntryEdited.
+ iComparativeEntry = CreateCopyL( *iEntry );
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::CreateCopyL
+//
+CCalEntry* CMRCalEntry::CreateCopyL( CCalEntry& aSourceEntry )
+ {
+ FUNC_LOG;
+ CCalEntry* entry =
+ ESMRHelper::CopyEntryL(
+ aSourceEntry,
+ aSourceEntry.MethodL(),
+ ESMRHelper::ECopyFull );
+
+ return entry;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::Type
+// ---------------------------------------------------------------------------
+//
+MESMRCalEntry::TESMRCalEntryType CMRCalEntry::Type() const
+ {
+ FUNC_LOG;
+
+ MESMRCalEntry::TESMRCalEntryType type( EESMRCalEntryNotSupported );
+
+ CCalEntry::TType entryType( CCalEntry::EAppt );
+
+ TRAP_IGNORE( {
+ entryType = DoGetEntry()->EntryTypeL();
+ } );
+
+ switch ( entryType )
+ {
+ case CCalEntry::EAppt:
+ {
+ type = EESMRCalEntryMeeting;
+ break;
+ }
+ case CCalEntry::ETodo:
+ {
+ type = EESMRCalEntryTodo;
+ break;
+ }
+ case CCalEntry::EEvent:
+ {
+ type = EESMRCalEntryMemo;
+ break;
+ }
+ case CCalEntry::EReminder:
+ {
+ type = EESMRCalEntryReminder;
+ break;
+ }
+ case CCalEntry::EAnniv:
+ {
+ type = EESMRCalEntryAnniversary;
+ break;
+ }
+ default:
+ break;
+ }
+
+ return type;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::MESMRCalEntryRef
+// ---------------------------------------------------------------------------
+//
+MESMRCalEntry& CMRCalEntry::MESMRCalEntryRef()
+ {
+ FUNC_LOG;
+ return *this;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::MESMRCalEntryRef
+// ---------------------------------------------------------------------------
+//
+const MESMRCalEntry& CMRCalEntry::MESMRCalEntryRef() const
+ {
+ FUNC_LOG;
+ return *this;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::Entry
+// ---------------------------------------------------------------------------
+//
+const CCalEntry& CMRCalEntry::Entry() const
+ {
+ FUNC_LOG;
+ return *DoGetEntry();
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::Entry
+// ---------------------------------------------------------------------------
+//
+CCalEntry& CMRCalEntry::Entry()
+ {
+ FUNC_LOG;
+ return *DoGetEntry();
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::InstanceL
+// ---------------------------------------------------------------------------
+//
+CCalInstance* CMRCalEntry::InstanceL() const
+ {
+ FUNC_LOG;
+
+ CCalInstance* instance = NULL;
+
+ instance = iCalDb.FindInstanceL( *DoGetEntry() );
+ if ( !instance )
+ {
+ // Instance not found by using the edited entry
+ // Trying with orginal.
+ instance = iCalDb.FindInstanceL( *iComparativeEntry );
+ }
+
+ if ( !instance )
+ {
+ // Instance not found by using edited or orginal entry.
+ // --> Leave
+ User::Leave( KErrNotFound );
+ }
+
+ return instance;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::CanSetRecurrenceL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::CanSetRecurrenceL() const
+ {
+ FUNC_LOG;
+
+ TBool canSetRecurrence( ETrue );
+
+ if ( DoGetEntry()->EntryTypeL() == CCalEntry::EAppt &&
+ IsRepeatingMeetingL(*iEntry) &&
+ (!ESMREntryHelper::IsModifyingEntryL(*iEntry) &&
+ MESMRCalEntry::EESMRThisOnly == iRecurrenceModRule ))
+ {
+ canSetRecurrence = EFalse;
+ }
+
+ return canSetRecurrence;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::GetRecurrenceL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::GetRecurrenceL(
+ TESMRRecurrenceValue& aRecurrence,
+ TTime& aUntil ) const
+ {
+ FUNC_LOG;
+
+ CESMRRecurrenceInfoHandler* recurrenceHandler =
+ CESMRRecurrenceInfoHandler::NewLC( *DoGetEntry() );
+
+ recurrenceHandler->GetRecurrenceL( aRecurrence, aUntil );
+ CleanupStack::PopAndDestroy( recurrenceHandler );
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::IsAllDayEventL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::IsAllDayEventL() const
+ {
+ FUNC_LOG;
+
+ TBool allDayEvent(EFalse);
+
+ CCalEntry::TType entryType = DoGetEntry()->EntryTypeL();
+
+ if ( (CCalEntry::EAppt == entryType) ||
+ (CCalEntry::EEvent == entryType) )
+ {
+ TCalTime startTime = iEntry->StartTimeL();
+ TCalTime stopTime = iEntry->EndTimeL();
+
+ TTimeIntervalHours hoursBetweenStartAndEnd;
+ stopTime.TimeLocalL().HoursFrom(
+ startTime.TimeLocalL(),
+ hoursBetweenStartAndEnd );
+
+ TCalTime::TTimeMode mode = startTime.TimeMode();
+
+ TInt hoursBetweenStartAndEndAsInt( hoursBetweenStartAndEnd.Int() );
+ TInt alldayDivident( hoursBetweenStartAndEndAsInt % KHoursInDay );
+
+ if ( hoursBetweenStartAndEndAsInt && 0 == alldayDivident )
+ {
+ TDateTime startTimeLocal = startTime.TimeLocalL().DateTime();
+ TDateTime stopTimeLocal = stopTime.TimeLocalL().DateTime();
+
+ if ( startTimeLocal.Hour() == 0 &&
+ startTimeLocal.Minute() == 0 &&
+ startTimeLocal.Minute() == stopTimeLocal.Minute() &&
+ startTimeLocal.Second() == 0 &&
+ startTimeLocal.Second() == stopTimeLocal.Second() )
+ {
+ allDayEvent = ETrue;
+ }
+ }
+ }
+
+ return allDayEvent;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::SetRecurrenceL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::SetRecurrenceL(
+ TESMRRecurrenceValue aRecurrence,
+ TTime aUntil )
+ {
+ FUNC_LOG;
+ // Check if this entry's recurrence can be edited
+
+ if ( !CanSetRecurrenceL() )
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ CESMRRecurrenceInfoHandler* recurrenceHandler =
+ CESMRRecurrenceInfoHandler::NewLC( *DoGetEntry() );
+
+ recurrenceHandler->SetRecurrenceL( aRecurrence, aUntil );
+ CleanupStack::PopAndDestroy( recurrenceHandler );
+
+ iRecurrenceModRule = MESMRCalEntry::EESMRAllInSeries;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::SetAllDayEventL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::SetAllDayEventL( TTime aStartDate, TTime aEndDate)
+ {
+ FUNC_LOG;
+ TCalTime startTime;
+ TCalTime stopTime;
+
+ TDateTime start;
+ TDateTime end;
+
+ // set the start time to 0:00
+ start.Set( aStartDate.DateTime().Year(),
+ aStartDate.DateTime().Month(),
+ aStartDate.DateTime().Day(),
+ 0,
+ 0,
+ 0,
+ 0);
+
+ // set the end date to next day from given end date since
+ // all day event should last 24 hours.
+ aEndDate += TTimeIntervalDays( 1 );
+
+ end.Set( aEndDate.DateTime().Year(),
+ aEndDate.DateTime().Month(),
+ aEndDate.DateTime().Day(),
+ 0,
+ 0,
+ 0,
+ 0);
+
+ startTime.SetTimeLocalL( start );
+ stopTime.SetTimeLocalL( end );
+
+ DoGetEntry()->SetStartAndEndTimeL( startTime, stopTime );
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::IsStoredL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::IsStoredL() const
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iEntry, Panic(EBCCalEntryNotExist ) );
+
+ TBool ret(EFalse);
+ CCalEntry* dbEntry = NULL;
+
+ TRAPD( err, dbEntry = iCalDb.FetchEntryL(
+ iEntry->UidL(),
+ iEntry->RecurrenceIdL() ) );
+
+ if ( KErrNotFound == err )
+ {
+ // Error has occured while retrieving an entry
+ ret = EFalse;
+ }
+ else if ( dbEntry)
+ {
+ // Entry was found from the calendar db --> it is stored for sure.
+ ret = ETrue;
+ }
+
+ delete dbEntry;
+
+ return ret;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::IsEntryEditedL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::IsEntryEditedL() const
+ {
+ FUNC_LOG;
+
+ TBool isSame(ETrue);
+
+ // The compare entry has not been created yet; so
+ // entry has not changed.
+ if ( iComparativeEntry )
+ {
+ isSame = iComparativeEntry->CompareL( *DoGetEntry() );
+
+ // CCalEntry's CompareL doesn't check the priority value:
+ if ( isSame && iEntry->PriorityL() != iComparativeEntry->PriorityL() )
+ {
+ isSame = EFalse;
+ }
+ else if ( iEntry->DescriptionL() != iComparativeEntry->DescriptionL() )
+ {
+ isSame = EFalse;
+ }
+ else if ( iEntry->LocationL() != iComparativeEntry->LocationL() )
+ {
+ isSame = EFalse;
+ }
+ else if ( iEntry->ReplicationStatusL() != iComparativeEntry->ReplicationStatusL() )
+ {
+ isSame = EFalse;
+ }
+
+ if ( IsStoredL() )
+ if ( iCalDb.EntryViewL( *iEntry ) != iCalDb.EntryView() )
+ {
+ isSame = EFalse;
+ }
+ }
+
+
+
+ return !isSame;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::IsRecurrentEventL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::IsRecurrentEventL() const
+ {
+ FUNC_LOG;
+ if ( DoGetEntry()->EntryTypeL() != CCalEntry::EAppt )
+ {
+ return EFalse;
+ }
+
+ TBool recurrenceEvent( EFalse );
+ if ( IsStoredL() )
+ {
+ // Entry is stored in calendar db
+ // Lets look recurrence using instance
+
+ // Ownership is transferred
+ CCalInstance* instance = NULL;
+ TRAPD(err, instance = InstanceL() );
+ if ( KErrNotFound != err )
+ {
+ User::LeaveIfError( err );
+ }
+
+ if ( instance )
+ {
+ CleanupStack::PushL( instance );
+
+ CCalEntry& instanceParentEntry = instance->Entry();
+
+ if ( IsRepeatingMeetingL( instanceParentEntry ) )
+ {
+ recurrenceEvent = ETrue;
+ }
+ CleanupStack::PopAndDestroy( instance );
+ }
+ else
+ {
+ if ( IsRepeatingMeetingL( *iEntry ) )
+ {
+ recurrenceEvent = ETrue;
+ }
+ }
+ }
+ else
+ {
+ // Entry is not stored in calendar db
+ if ( IsRepeatingMeetingL( *iEntry ) )
+ {
+ // This is repeating meeting
+ recurrenceEvent = ETrue;
+ }
+ }
+
+ return recurrenceEvent;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::IsEntryTypeChangedL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::IsEntryTypeChangedL() const
+ {
+ FUNC_LOG;
+
+ return iTypeChanged;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::SetModifyingRuleL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::SetModifyingRuleL( TESMRRecurrenceModifyingRule aRule,
+ const TBool aTypeChanging )
+ {
+ FUNC_LOG;
+
+ CESMRRecurrenceInfoHandler* recHandler =
+ CESMRRecurrenceInfoHandler::NewL( *iComparativeEntry );
+ CleanupStack::PushL( recHandler );
+
+ TESMRRecurrenceValue orginalRecurrence;
+ TTime orginalUntil;
+
+ recHandler->GetRecurrenceL(
+ orginalRecurrence,
+ orginalUntil);
+ CleanupStack::PopAndDestroy( recHandler );
+ recHandler = NULL;
+
+ TBool modifyingEntry( ESMREntryHelper::IsModifyingEntryL( *DoGetEntry() ) );
+
+ if ( MESMRCalEntry::EESMRAllInSeries == aRule && IsStoredL() && !aTypeChanging)
+ {
+ // When we want to modify series of recurrence entries -->
+ // Parent entry is modified
+ if ( ERecurrenceNot == orginalRecurrence && !modifyingEntry )
+ {
+ // Orginal entry was not recurrent event
+ // No need to fect instance at all
+ // For modifying entries we need to fetch the original parent entry
+ iRecurrenceModRule = aRule;
+ return;
+ }
+
+ CCalInstance* instance = NULL;
+ TRAPD(err, instance = InstanceL() );
+ if( KErrNotFound != err )
+ {
+ User::LeaveIfError( err );
+ }
+
+ if ( instance )
+ {
+ CleanupStack::PushL( instance );
+
+ CCalEntry::TMethod entryMethod( iEntry->MethodL() );
+
+ delete iEntry;
+ iEntry = NULL;
+
+ delete iComparativeEntry;
+ iComparativeEntry = NULL;
+
+ RCPointerArray<CCalEntry> entries;
+ CleanupClosePushL( entries );
+
+ iCalDb.EntryViewL( instance->Entry() )->FetchL(
+ instance->Entry().UidL(), entries );
+
+ TInt parentIndex( KErrNotFound );
+ TInt entryCount( entries.Count() );
+ for ( TInt i(0); i < entryCount && KErrNotFound == parentIndex; ++i )
+ {
+ TBool modifyingEntry( ESMREntryHelper::IsModifyingEntryL( *entries[i]) );
+ if ( !modifyingEntry )
+ {
+ parentIndex = i;
+ }
+ }
+
+ CCalEntry& parent = *entries[parentIndex];
+
+ TPtrC description( parent.DescriptionL() );
+
+ iEntry = CreateCopyL( parent );
+
+ // Adjust parent entry's start and end time to entry
+ TCalTime start;
+ TCalTime end;
+
+ CESMRRecurrenceInfoHandler* recurrenceHandler =
+ CESMRRecurrenceInfoHandler::NewLC( parent );
+
+ recurrenceHandler->GetFirstInstanceTimeL( start, end );
+ CleanupStack::PopAndDestroy( recurrenceHandler );
+ recurrenceHandler = NULL;
+
+ iEntry->SetStartAndEndTimeL( start, end );
+
+ iComparativeEntry = CreateCopyL( *iEntry );
+
+ iEntry->SetDescriptionL( description );
+ iComparativeEntry->SetDescriptionL( description );
+
+ CleanupStack::PopAndDestroy(); // entries
+ CleanupStack::PopAndDestroy( instance );
+ }
+ }
+ else if ( ERecurrenceNot != orginalRecurrence &&
+ aTypeChanging && !modifyingEntry )
+ {
+ // if entry( in the memory) is a recurrent event
+ // ,and if entry type is changing, and not in modifying status then EESMRAllInSeries
+ iRecurrenceModRule = EESMRAllInSeries ;
+ return;
+ }
+
+
+ iRecurrenceModRule = aRule;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::RecurrenceModRule
+// ---------------------------------------------------------------------------
+//
+MESMRCalEntry::TESMRRecurrenceModifyingRule
+ CMRCalEntry::RecurrenceModRule() const
+ {
+ FUNC_LOG;
+ return iRecurrenceModRule;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::GetAlarmL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::GetAlarmL(TESMRAlarmType& aAlarmType, TTime &aAlarmTime )
+ {
+ FUNC_LOG;
+
+ aAlarmType = MESMRCalEntry::EESMRAlarmNotFound;
+ aAlarmTime = Time::NullTTime();
+
+ TFileName alarmInfoResource;
+ ESMRHelper::LocateResourceFile(
+ KAlarmInfoResource,
+ KDC_RESOURCE_FILES_DIR,
+ alarmInfoResource);
+
+ CESMRAlarmInfoHandler* alarmInfoHandler =
+ CESMRAlarmInfoHandler::NewLC();
+
+ alarmInfoHandler->ReadFromResourceL(
+ alarmInfoResource,
+ MRCALEVENT_ALARM_INFO_TABLE );
+
+ TRAPD( err,
+ alarmInfoHandler->GetAbsoluteAlarmTimeL(*DoGetEntry(), aAlarmTime) );
+
+ if ( KErrNone == err )
+ {
+ aAlarmType = MESMRCalEntry::EESMRAlarmAbsolute;
+
+ // only meeting that is not allday event can have relative alarm:
+ if ( Type() == EESMRCalEntryMeeting && !IsAllDayEventL() )
+ {
+ TESMRAlarmInfo alarmInfo;
+ TRAP( err,
+ alarmInfoHandler->GetAlarmInfoObjectL(*iEntry, alarmInfo) );
+
+ if ( KErrNone == err )
+ {
+ aAlarmType = MESMRCalEntry::EESMRAlarmRelative;
+ if( alarmInfo.iRelativeAlarmInSeconds < 0 )
+ {
+ aAlarmType = MESMRCalEntry::EESMRAlarmNotFound;
+ }
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy( alarmInfoHandler );
+ alarmInfoHandler = NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::OriginalEntry
+// ---------------------------------------------------------------------------
+//
+const CCalEntry& CMRCalEntry::OriginalEntry()
+ {
+ FUNC_LOG;
+ return *iComparativeEntry;
+ }
+
+
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::IsRepeatingMeetingL
+// ----------------------------------------------------------------------------
+//
+TBool CMRCalEntry::IsRepeatingMeetingL(const CCalEntry& aEntry) const
+ {
+ FUNC_LOG;
+ TBool retVal( EFalse );
+
+ if ( ESMREntryHelper::IsModifyingEntryL(aEntry) )
+ {
+ retVal = ETrue;
+ }
+ else
+ {
+ TCalRRule dummyRule;
+ if ( aEntry.GetRRuleL( dummyRule ) )
+ {
+ retVal = ETrue;
+ }
+ else
+ {
+ RArray<TCalTime> dummyRDateList;
+ CleanupClosePushL( dummyRDateList );
+ aEntry.GetRDatesL( dummyRDateList );
+ if ( dummyRDateList.Count() > 0 )
+ {
+ retVal = ETrue;
+ }
+ CleanupStack::PopAndDestroy(); // dummyRDateList
+ }
+ }
+
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::SetPriorityL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::SetPriorityL ( TUint aPriority )
+ {
+ FUNC_LOG;
+ DoGetEntry()->SetPriorityL( aPriority );
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRMeetingRequestEntry::GetPriorityL
+// ---------------------------------------------------------------------------
+//
+TUint CMRCalEntry::GetPriorityL() const
+ {
+ FUNC_LOG;
+ TUint entryPriority = DoGetEntry()->PriorityL();
+
+ if ( iEntry->EntryTypeL() == CCalEntry::ETodo )
+ {
+ if ( entryPriority != EFSCalenTodoPriorityLow &&
+ entryPriority != EFSCalenTodoPriorityNormal &&
+ entryPriority != EFSCalenTodoPriorityHigh )
+ {
+ entryPriority = EFSCalenTodoPriorityNormal;
+ }
+ }
+ else
+ {
+ if ( entryPriority != EFSCalenMRPriorityLow &&
+ entryPriority != EFSCalenMRPriorityNormal &&
+ entryPriority != EFSCalenMRPriorityHigh )
+ {
+ entryPriority = EFSCalenMRPriorityNormal;
+ }
+ }
+
+ return entryPriority;
+ }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::UpdateEntryAfterStoringL
+// ----------------------------------------------------------------------------
+//
+void CMRCalEntry::UpdateEntryAfterStoringL()
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iEntry, Panic( EBCCalEntryNotExist ) );
+
+ CCalEntry* storedEntry = NULL;
+
+ if ( IsRecurrentEventL() &&
+ EESMRThisOnly == iRecurrenceModRule &&
+ IsStoredL() && !ESMREntryHelper::IsModifyingEntryL(*iEntry) )
+ {
+ // We have stored one instance of series.
+ storedEntry = iCalDb.FetchEntryL(
+ iEntry->UidL(),
+ iComparativeEntry->StartTimeL() );
+ }
+ else
+ {
+ // We are dealing with single instance or with the series
+ storedEntry = iCalDb.FetchEntryL(
+ iEntry->UidL(),
+ iEntry->RecurrenceIdL() );
+ }
+
+ __ASSERT_DEBUG( storedEntry, Panic( EBCCalEntryNotExist ) );
+ CleanupStack::PushL( storedEntry );
+
+ // Description needs to be fecthed explicitly into memory
+ TPtrC description( storedEntry->DescriptionL() );
+
+ delete iEntry;
+ iEntry = NULL;
+ iEntry = CreateCopyL(*storedEntry);
+
+ if ( MESMRCalEntry::EESMRAllInSeries == iRecurrenceModRule &&
+ IsRecurrentEventL() )
+ {
+ // Adjust parent entry's start and end time to entry
+ TCalTime start;
+ TCalTime end;
+
+ CESMRRecurrenceInfoHandler* recurrenceHandler =
+ CESMRRecurrenceInfoHandler::NewLC( *iEntry );
+
+ recurrenceHandler->GetFirstInstanceTimeL( start, end );
+ CleanupStack::PopAndDestroy( recurrenceHandler );
+ recurrenceHandler = NULL;
+
+ iEntry->SetStartAndEndTimeL( start, end );
+ iEntry->SetDescriptionL( description );
+ }
+
+ CCalEntry* temp = CreateCopyL( *iEntry );
+
+ delete iComparativeEntry;
+ iComparativeEntry = temp;
+
+ CleanupStack::PopAndDestroy( storedEntry );
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::SetDefaultValuesToEntryL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::SetDefaultValuesToEntryL()
+ {
+ FUNC_LOG;
+
+ if ( !IsStoredL() )
+ {
+ // by default when creating a meeting the priority
+ // value is normal
+ switch ( DoGetEntry()->EntryTypeL() )
+ {
+ case CCalEntry::ETodo:
+ {
+ SetDefaultValuesForTodoL();
+ }
+ break;
+ case CCalEntry::EEvent: // Memo
+ {
+ SetDefaultValuesForMemoL();
+ }
+ break;
+ case CCalEntry::EAppt:
+ {
+ SetDefaultValuesForMeetingL();
+ }
+ break;
+ case CCalEntry::EAnniv:
+ default:
+ {
+ SetDefaultValuesForAnniversaryL();
+ }
+ break;
+ }
+ iEntry->SetReplicationStatusL( CCalEntry::EOpen );
+
+ // Entry has now been set up with default values;
+ // Let's update comparative entry
+ delete iComparativeEntry;
+ iComparativeEntry = NULL;
+
+ iComparativeEntry = CreateCopyL( *iEntry );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::UpdateTimeStampL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::UpdateTimeStampL()
+ {
+ FUNC_LOG;
+
+ ASSERT( iEntry );
+
+ TTime currentUTCTime;
+ currentUTCTime.UniversalTime();
+
+ TCalTime currentTime;
+ currentTime.SetTimeUtcL( currentUTCTime );
+
+ iEntry->SetDTStampL( currentTime );
+ }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::CloneEntryLC
+// ----------------------------------------------------------------------------
+//
+CCalEntry* CMRCalEntry::CloneEntryLC( TESMRCalEntryType aType ) const
+ {
+ CCalEntry* entry = ESMRHelper::CopyEntryLC(
+ *DoGetEntry(),
+ iEntry->MethodL(),
+ ESMRHelper::ECopyFull,
+ TESMRCalendarEventType( aType ) );
+
+ return entry;
+ }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::UpdateComparativeEntry
+// ----------------------------------------------------------------------------
+//
+void CMRCalEntry::UpdateComparativeEntry( CCalEntry* aNewComparativeEntry )
+ {
+ FUNC_LOG;
+ if( iComparativeEntry )
+ {
+ delete iComparativeEntry;
+ iComparativeEntry = NULL;
+
+ iComparativeEntry = aNewComparativeEntry;
+ }
+
+ }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::SetDefaultValuesForTodoL
+// ----------------------------------------------------------------------------
+//
+void CMRCalEntry::SetDefaultValuesForTodoL()
+ {
+ FUNC_LOG;
+
+ SetPriorityL( EFSCalenTodoPriorityNormal );
+
+ // Update event time
+ TDateTime start = iEntry->StartTimeL().TimeLocalL().DateTime();
+ start.SetHour( KMaxHoursForTodo );
+ start.SetMinute( KMaxMinutesForTodo );
+ start.SetSecond( KMaxSecondsForTodo );
+
+ TCalTime dueTime;
+ dueTime.SetTimeLocalL( start );
+ iEntry->SetStartAndEndTimeL( dueTime, dueTime );
+
+ // Create default alarm
+ TTime eventTime = iEntry->EndTimeL().TimeLocalL();
+
+ // Calculate alarm time (due date at 12:00am)
+ TTime alarmTime = eventTime;
+ TDateTime alarmDateTime = alarmTime.DateTime();
+ alarmDateTime.SetHour( KDefaultTodoAlarmHours );
+ alarmDateTime.SetMinute( 0 );
+ alarmDateTime.SetSecond( 0 );
+ alarmDateTime.SetMicroSecond( 0 );
+ alarmTime = alarmDateTime;
+
+ TTime currentTime;
+ currentTime.HomeTime();
+
+ if ( alarmTime > currentTime )
+ {
+ CCalAlarm* alarm = CCalAlarm::NewL();
+ CleanupStack::PushL( alarm );
+ TTimeIntervalMinutes alarmOffset( 0 );
+ eventTime.MinutesFrom( alarmTime, alarmOffset );
+ alarm->SetTimeOffset( alarmOffset );
+ iEntry->SetAlarmL( alarm );
+ CleanupStack::PopAndDestroy( alarm );
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::SetDefaultValuesForMemoL
+// ----------------------------------------------------------------------------
+//
+void CMRCalEntry::SetDefaultValuesForMemoL()
+ {
+ FUNC_LOG;
+
+ SetPriorityL( EFSCalenMRPriorityNormal );
+
+ // Update event time
+ TDateTime start = iEntry->StartTimeL().TimeLocalL().DateTime();
+ start.SetHour( 0 );
+ start.SetMinute( 0 );
+ start.SetSecond( 0 );
+
+ TDateTime end = iEntry->EndTimeL().TimeLocalL().DateTime();
+ end.SetHour( KMaxHoursForMemo );
+ end.SetMinute( KMaxMinutesForMemo );
+ end.SetSecond( KMaxSecondsForMemo );
+
+ TCalTime startTime;
+ startTime.SetTimeLocalL( start );
+ TCalTime endTime;
+ endTime.SetTimeLocalL( end );
+
+ iEntry->SetStartAndEndTimeL( startTime, endTime );
+ }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::SetDefaultValuesForMeetingL
+// ----------------------------------------------------------------------------
+//
+void CMRCalEntry::SetDefaultValuesForMeetingL()
+ {
+ FUNC_LOG;
+
+ SetPriorityL( EFSCalenMRPriorityNormal );
+
+ // Get default alarm time from central repository
+ TInt defaultAlarmTime;
+ CRepository* repository = CRepository::NewLC( TUid::Uid(0x101F874B) /*KCRUidCalendar*/ );
+ TInt err = repository->Get( KCalendarDefaultAlarmTime, defaultAlarmTime );
+ CleanupStack::PopAndDestroy( repository );
+
+ if ( err != KErrNone )
+ {
+ defaultAlarmTime = KDefaultMeetingAlarmMinutes;
+ }
+
+ // Getting current time
+ TTime currentTime;
+ currentTime.HomeTime();
+
+ // Getting meeting start time
+ TTime start = iEntry->StartTimeL().TimeLocalL();
+
+ // Create default alarm
+ CCalAlarm* alarm = CCalAlarm::NewL();
+ CleanupStack::PushL( alarm );
+
+ TTimeIntervalMinutes alarmOffset( defaultAlarmTime );
+
+ // If alarm time is in past
+ if ( ( start - alarmOffset ) < currentTime )
+ {
+ // Setting alarm off
+ iEntry->SetAlarmL( NULL );
+ }
+ else
+ {
+ // Set default alarm time
+ alarm->SetTimeOffset( alarmOffset );
+ iEntry->SetAlarmL( alarm );
+ }
+ CleanupStack::PopAndDestroy( alarm );
+
+ if ( iEntry->StartTimeL().TimeUtcL() == iEntry->EndTimeL().TimeUtcL() )
+ {
+ // Should this value be read from cenrep?
+ TTimeIntervalHours KDefaultMeetingDuration(1);
+
+ TCalTime newEndTime;
+ newEndTime.SetTimeUtcL(
+ iEntry->StartTimeL().TimeUtcL() + KDefaultMeetingDuration );
+ iEntry->SetStartAndEndTimeL(iEntry->StartTimeL(), newEndTime);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::SetDefaultValuesForAnniversaryL
+// ----------------------------------------------------------------------------
+//
+void CMRCalEntry::SetDefaultValuesForAnniversaryL()
+ {
+ FUNC_LOG;
+
+ SetPriorityL( EFSCalenMRPriorityNormal );
+
+ // Getting event time
+ TTime eventTime = iEntry->StartTimeL().TimeLocalL();
+
+ // Setting default alarm parameters to previous day at noon
+ TTime alarmTime = eventTime - TTimeIntervalDays( 1 );
+ TDateTime alarmDateTime = alarmTime.DateTime();
+ alarmDateTime.SetHour( KDefaultAnniversaryAlarmHours );
+ alarmDateTime.SetMinute( 0 );
+ alarmDateTime.SetSecond( 0 );
+ alarmDateTime.SetMicroSecond( 0 );
+ alarmTime = alarmDateTime;
+
+ // Calculating alarm offset
+ TTimeIntervalMinutes alarmOffset( 0 );
+ eventTime.MinutesFrom( alarmTime, alarmOffset );
+
+ // Creating alarm
+ CCalAlarm* alarm = CCalAlarm::NewL();
+ CleanupStack::PushL( alarm );
+ alarm->SetTimeOffset( alarmOffset );
+
+ // Setting alarm
+ iEntry->SetAlarmL( alarm );
+ CleanupStack::PopAndDestroy( alarm );
+ alarm = NULL;
+ }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::DoGetEntry
+// ----------------------------------------------------------------------------
+//
+CCalEntry* CMRCalEntry::DoGetEntry() const
+ {
+ __ASSERT_DEBUG( iEntry, Panic( EBCCalEntryNotExist ) );
+
+ return iEntry;
+ }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::ValidateEntryL
+// ----------------------------------------------------------------------------
+//
+CCalEntry* CMRCalEntry::ValidateEntryL()
+ {
+ FUNC_LOG;
+
+ CCalEntry* entry = NULL;
+
+ MESMRCalEntry::TESMRCalEntryType entryType = Type();
+ switch ( entryType )
+ {
+ case EESMRCalEntryMeeting:
+ {
+ entry = ValidateMeetingL();
+ }
+ break;
+
+ case EESMRCalEntryAnniversary:
+ {
+ entry = CreateCopyL( *iEntry );
+ CleanupStack::PushL( entry );
+
+ // Special check for anniversary: Occurancy must be set to yearly
+ // for new entries
+ if ( ( entry->EntryTypeL() == CCalEntry::EAnniv ) &&
+ !IsStoredL() &&
+ !IsRecurrentEventL() )
+ {
+ TCalRRule rrule( TCalRRule::EYearly );
+ rrule.SetDtStart( Entry().StartTimeL() );
+ rrule.SetInterval( 1 );
+ rrule.SetCount( 0 );
+ entry->SetRRuleL( rrule );
+ }
+
+ CleanupStack::Pop( entry ); //Ownership given to caller
+ }
+ break;
+
+ case EESMRCalEntryTodo: // flow through
+ case EESMRCalEntryMemo: // flow through
+ case EESMRCalEntryReminder:
+ {
+ entry = CreateCopyL( *iEntry );
+ }
+ break;
+ default:
+ // This should not occur
+ User::Leave( KErrArgument );
+ break;
+ }
+
+ return entry;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::RemoveInstanceFromSeriesL
+// ---------------------------------------------------------------------------
+//
+CCalEntry* CMRCalEntry::RemoveInstanceFromSeriesL()
+ {
+ FUNC_LOG;
+
+ CCalEntry* retEntry = NULL;
+
+ if ( IsRecurrentEventL() &&
+ EESMRThisOnly == iRecurrenceModRule )
+ {
+ CCalInstance* instance = NULL;
+ TRAPD( err, instance = InstanceL() );
+ if( KErrNotFound != err )
+ {
+ User::LeaveIfError( err );
+ }
+
+ if ( instance )
+ {
+ CleanupStack::PushL( instance );
+
+ CCalEntry& parentEntry = instance->Entry();
+ retEntry = ESMRHelper::CopyEntryL(
+ parentEntry,
+ parentEntry.MethodL(),
+ ESMRHelper::ECopyFull );
+
+ CleanupStack::PopAndDestroy( instance );
+ instance = NULL;
+
+ CleanupStack::PushL( retEntry );
+
+ CESMRRecurrenceInfoHandler* recurrenceHandler =
+ CESMRRecurrenceInfoHandler::NewLC( *retEntry );
+
+ TCalTime orginalInstanceTime;
+ orginalInstanceTime.SetTimeUtcL(
+ iEntry->StartTimeL().TimeUtcL() );
+
+ recurrenceHandler->RemoveInstanceL( orginalInstanceTime );
+
+ CleanupStack::PopAndDestroy( recurrenceHandler );
+ CleanupStack::Pop( retEntry );
+ }
+ }
+ else
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ return retEntry;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::GetDBMgr
+// ---------------------------------------------------------------------------
+//
+MESMRCalDbMgr& CMRCalEntry::GetDBMgr()
+ {
+ return iCalDb;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::SupportsCapabilityL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::SupportsCapabilityL(
+ MESMRCalEntry::TMREntryCapability aCapability ) const
+ {
+ FUNC_LOG;
+
+ TBool retValue( EFalse );
+
+ if ( aCapability == MESMRCalEntry::EMRCapabilityAttachments )
+ {
+ retValue = ETrue;
+ }
+
+ return retValue;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::ContainsRemoteAttachmentsL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::ContainsRemoteAttachmentsL()
+ {
+ FUNC_LOG;
+
+ TBool retValue( EFalse );
+
+ TInt attachmentCount( iEntry->AttachmentCountL() );
+
+ for ( TInt i(0); i < attachmentCount && !retValue; ++i )
+ {
+ CCalAttachment* attachment = iEntry->AttachmentL(i);
+ CCalAttachment::TType type( attachment->Type() );
+
+ if ( CCalAttachment::EFile != type )
+ {
+ retValue = ETrue;
+ }
+ }
+
+ return retValue;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::ValidateMeetingL
+// ---------------------------------------------------------------------------
+//
+CCalEntry* CMRCalEntry::ValidateMeetingL()
+ {
+ FUNC_LOG;
+
+ CCalEntry* entry = NULL;
+
+ if ( IsRecurrentEventL() &&
+ EESMRThisOnly == iRecurrenceModRule &&
+ IsStoredL() &&
+ !ESMREntryHelper::IsModifyingEntryL( *iEntry ) )
+ {
+ CCalInstance* instance = NULL;
+ TRAPD( err, instance = InstanceL() );
+ if( KErrNotFound != err )
+ {
+ User::LeaveIfError( err );
+ }
+
+ if ( instance )
+ {
+
+ CleanupStack::PushL( instance );
+ CCalEntry& parent = instance->Entry();
+
+ entry = iCalDb.FetchEntryL(
+ parent.UidL(),
+ iComparativeEntry->StartTimeL() );
+
+ if ( !entry )
+ {
+
+ // copy global UID from the original entry
+ HBufC8* guid = parent.UidL().AllocLC();
+
+ // create new (child) entry
+ entry = CCalEntry::NewL(
+ parent.EntryTypeL(),
+ guid,
+ parent.MethodL(),
+ 0,
+ iComparativeEntry->StartTimeL(),
+ CalCommon::EThisOnly );
+
+ CleanupStack::Pop( guid );
+ guid = NULL; // ownership transferred
+ }
+
+ CleanupStack::PopAndDestroy( instance );
+ instance = NULL; // instance
+ CleanupStack::PushL( entry );
+
+
+ CCalEntry::TMethod method( iEntry->MethodL() );
+
+ entry->CopyFromL( *iEntry, CCalEntry::EDontCopyId );
+ entry->SetSequenceNumberL( 0 );
+ entry->SetMethodL( method );
+ entry->SetSummaryL( iEntry->SummaryL() );
+ entry->SetLocalUidL( TCalLocalUid( 0 ) );
+ entry->ClearRepeatingPropertiesL();
+
+ CleanupStack::Pop( entry );
+ }
+ }
+
+ if ( !entry )
+ {
+ entry = CreateCopyL( *iEntry );
+ }
+
+ return entry;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::SetTypeChanged
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::SetTypeChanged( TBool aTypeChanged )
+ {
+ FUNC_LOG;
+
+ iTypeChanged = aTypeChanged;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::AnyInstancesBetweenTimePeriodL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::AnyInstancesBetweenTimePeriodL(
+ TTime& aStart,
+ TTime& aEnd )
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iEntry, Panic( EBCCalEntryNotExist ) );
+
+ TBool retValue( EFalse );
+
+ RCPointerArray<CCalEntry> entries;
+ CleanupClosePushL( entries );
+
+ CESMRConflictChecker* conflictCheckker =
+ CESMRConflictChecker::NewL( iCalDb );
+ CleanupStack::PushL( conflictCheckker );
+
+ CCalInstance* instance = InstanceL();
+ CleanupStack::PushL( instance );
+
+ TCalCollectionId colId = instance->InstanceIdL().iCollectionId;
+ CleanupStack::PopAndDestroy( instance );
+
+ conflictCheckker->FindInstancesForEntryL( aStart,
+ aEnd,
+ *iEntry,
+ colId,
+ entries );
+
+ if ( entries.Count() )
+ {
+ retValue = ETrue;
+ }
+
+ CleanupStack::PopAndDestroy( conflictCheckker );
+ CleanupStack::PopAndDestroy(); // entries
+
+ return retValue;
+ }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::GetFirstInstanceStartAndEndTimeL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::GetFirstInstanceStartAndEndTimeL(
+ TTime& aStart,
+ TTime& aEnd )
+ {
+ FUNC_LOG;
+
+ __ASSERT_DEBUG( iEntry, Panic( EBCCalEntryNotExist ) );
+
+ // This fetches the parent entry
+ TCalTime recurrenceId;
+ recurrenceId.SetTimeLocalL( Time::NullTTime() );
+ CCalEntry* parent = iCalDb.FetchEntryL(
+ iEntry->UidL(),
+ recurrenceId );
+
+ CleanupStack::PushL( parent );
+
+ aStart = parent->StartTimeL().TimeLocalL();
+ aEnd = parent->EndTimeL().TimeLocalL();
+
+ CleanupStack::PopAndDestroy( parent );
+ }
+
+// EOF