diff -r a3a1ae9acec6 -r da5135c61bad meetingrequest/mrprocessor/mrcaleventplugin/src/cmrcalentry.cpp --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#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 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 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 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