diff -r 000000000000 -r 8466d47a6819 meetingrequest/mrgui/src/cesmrmeetingtimevalidator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/meetingrequest/mrgui/src/cesmrmeetingtimevalidator.cpp Thu Dec 17 08:39:21 2009 +0200 @@ -0,0 +1,1750 @@ +/* +* 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: ESMR time and date sanity checks and saving + * +*/ + + +#include "emailtrace.h" +#include +#include +#include +#include +#include +#include "cesmrmeetingtimevalidator.h" +#include "cesmrglobalnote.h" +#include "mesmrfieldstorage.h" +#include "mesmrcalentry.h" +#include "mesmrmeetingrequestentry.h" +#include "mesmrfieldeventqueue.h" +#include "cesmrgenericfieldevent.h" + +// Unnamed namespace for local definitions +namespace { // codescanner::namespace + +// Definition fom max possible time +#define KMaxTTime (TTime(TDateTime(2100, EDecember, 31-2, 23, 59, 59, 999999))) + +// Definition fom min possible time +#define KMinTTime (TTime(TDateTime(1900, EJanuary, 2-1, 0, 0, 0, 0))) + +// Definition for max alarm duration +#define KMaxAlarmTime TTimeIntervalDays(31) + +// Definition for alarm time offset, when alarm is off +const TInt KAlarmNotSet(-1); + +#ifdef _DEBUG + +// Literal for panics +_LIT( KESMRMeetingTimeValidator, "ESMRMeetingTimeValidator" ); + +/** Panic code definitions */ +enum TKESMRMeetingTimeValidator + { + /** Start time field not set */ + EESMRMeetingTimeValidatorNullStartTime, + /** Stop time field not set */ + EESMRMeetingTimeValidatorNullStopTime, + /** Start date field not set */ + EESMRMeetingTimeValidatorNullStartDate, + /** Stop date field not set */ + EESMRMeetingTimeValidatorNullStopDate, + /** Stop time field not set */ + EESMRMeetingTimeValidatorStartLaterThanEnd, + /** Invalid date field id */ + EESMRMeetingTimeValidatorInvalidDateField + }; + +/** + * Raises system panic. + * @param aPanic Panic code + * @see TESMRRecurrentEditValidatorPanic + */ +void Panic( TKESMRMeetingTimeValidator aPanic ) + { + User::Panic( KESMRMeetingTimeValidator, aPanic ); + } + +#endif // _DEBUG + +const TInt KZero( 0 ); +const TInt KOne( 1 ); +const TInt KDaysInWeek( 7 ); +const TInt KDaysInFortnight( 14 ); +const TInt KNoon(12); + +/** + * 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, + TTime& aPrevInstanceStartTime ) + { + TTime nextStartTime = aPrevInstanceStartTime; + + switch ( aRecurrenceValue ) + { + case ERecurrenceDaily: + { + nextStartTime += TTimeIntervalDays( KOne ); + } + break; + + case ERecurrenceWeekly: + { + nextStartTime += TTimeIntervalDays( KDaysInWeek ); + } + break; + + + case ERecurrenceEverySecondWeek: + { + nextStartTime += TTimeIntervalDays( KDaysInFortnight ); + } + break; + + case ERecurrenceMonthly: + { + nextStartTime += TTimeIntervalMonths( KOne ); + } + break; + + case ERecurrenceYearly: + { + nextStartTime += TTimeIntervalYears( KOne ); + } + break; + + default: + nextStartTime = aPrevInstanceStartTime; + break; + } + + return nextStartTime; + } + +/** + * Returns the default alarm time for all day event + * @param allday event start time + * @return alarm time + */ +TTime DefaultAlldayEventAlarmTime( TTime& aMeetingStartTime ) + { + TTime defaultAlarmTime = aMeetingStartTime - TTimeIntervalHours(KNoon); + + if ( defaultAlarmTime < KMinTTime ) + { + defaultAlarmTime = KMinTTime; + } + return defaultAlarmTime; + } + + +/** + * Sets time to editor. Time is checked and adjusted + * between min and max before setting + * @param aEditor Reference to time editor + * @param aTime On return contains the set time. + */ +void SetTimeToEditor( + CEikTimeEditor& aEditor, + TTime& aTime ) + { + if ( aTime < KMinTTime ) + { + aTime = KMinTTime; + } + else if ( aTime > KMaxTTime ) + { + aTime = KMaxTTime; + } + + if ( aEditor.IsVisible() ) + { + aEditor.SetTime( aTime ); + } + } + +/** + * Sets date to editor. Date is checked and adjusted + * between min and max before setting + * @param aEditor Reference to time editor + * @param aDate On return contains the set date. + */ +void SetDateToEditor( + CEikDateEditor& aEditor, + TTime& aDate ) + { + if ( aDate < KMinTTime ) + { + aDate = KMinTTime; + } + else if ( aDate > KMaxTTime ) + { + aDate = KMaxTTime; + } + + if ( aEditor.IsVisible() ) + { + aEditor.SetDate( aDate ); + } + } + +} // namespace + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::CESMRMeetingTimeValidator +// --------------------------------------------------------------------------- +// +inline CESMRMeetingTimeValidator::CESMRMeetingTimeValidator() +: iRecurrenceValue( ERecurrenceNot ), + iCurrentStartTime( Time::NullTTime() ), + iCurrentEndTime( Time::NullTTime() ), + iCurrentAlarmTime( Time::NullTTime() ), + iCurrentRecurrenceUntil( Time::NullTTime() ), + iStartTimeBeforeAlldayEvent( Time::NullTTime() ), + iEndTimeBeforeAlldayEvent( Time::NullTTime() ), + iAlldayEvent( EFalse ), + iAlarmOnOff( EFalse ), + iComparativeStartTime( Time::NullTTime().DateTime() ) + { + FUNC_LOG; + // Do nothing + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::~CESMRMeetingTimeValidator +// --------------------------------------------------------------------------- +// +CESMRMeetingTimeValidator::~CESMRMeetingTimeValidator( ) + { + FUNC_LOG; + // Do nothing + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::NewL +// --------------------------------------------------------------------------- +// +CESMRMeetingTimeValidator* CESMRMeetingTimeValidator::NewL( ) + { + FUNC_LOG; + CESMRMeetingTimeValidator* self = new (ELeave) CESMRMeetingTimeValidator(); + return self; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::ValidateL +// --------------------------------------------------------------------------- +// +MESMRFieldValidator::TESMRFieldValidatorError + CESMRMeetingTimeValidator::ValidateL( + TBool aCorrectAutomatically ) + { + FUNC_LOG; + MESMRFieldValidator::TESMRFieldValidatorError KErrorNone( + MESMRFieldValidator::EErrorNone ); + + MESMRFieldValidator::TESMRFieldValidatorError error( + MESMRFieldValidator::EErrorNone ); + + if( aCorrectAutomatically ) + { + ForceValuesL(); + } + else + { + TTime startTime = StartDateTime(); + TTime endTime = EndDateTime(); + + // In recurrent events if user has changed the start date and + // presses Save or Done, we have to force the end date to same + // value as start date and modify the recurrence until according + // to the new start time value + if ( ERecurrenceNot != iRecurrenceValue && + ( startTime.DateTime().Day() != endTime.DateTime().Day() || + startTime.DateTime().Month() != endTime.DateTime().Month() || + startTime.DateTime().Year() != endTime.DateTime().Year() ) ) + { + endTime = ForceEndDateTime(); + + SetTimeToEditor( *iEndTime, endTime ); + SetDateToEditor( *iEndDate, endTime ); + + // We have to also adjust the recurrence until time + // according to the new start time + TTime newUntil = ForceRecurrenceUntilTime(); + + SetDateToEditor( *iRecurrenceUntilDate, newUntil ); + } + + TTime currentAlarmTime = startTime - iCurrentAlarmTimeOffset; + TTime currentTime; + currentTime.HomeTime(); + + if ( endTime < startTime ) + { + error = MESMRFieldValidator::EErrorEndEarlierThanStart; + } + + if ( KErrorNone == error && ERecurrenceNot != iRecurrenceValue ) + { + TDateTime startDt = startTime.DateTime(); + TDateTime endDt = endTime.DateTime(); + + if ( startDt.Day() != endDt.Day() || + startDt.Month() != endDt.Month() || + startDt.Year() != endDt.Year() ) + { + error = MESMRFieldValidator::EErrorRecDifferetStartAndEnd; + } + + if ( KErrorNone == error && + ERecurrenceNot != iRecurrenceValue && + iRecurrenceUntilDate && iRecurrenceUntilDate->IsVisible() ) + { + TTime recurUntil = RecurrenceUntilTime(); + if ( ERecurrenceUnknown != iRecurrenceValue && + recurUntil < startTime ) + { + error = MESMRFieldValidator::EErrorRecUntilEarlierThanStart; + } + } + } + + if ( KErrorNone == error && + MESMRCalEntry::EESMRCalEntryMeetingRequest == iEntry->Type() ) + { + // Check that is modified entry + MESMRMeetingRequestEntry* mrEntry = + static_cast( iEntry ); + if ( mrEntry->IsRecurrentEventL() && + MESMRCalEntry::EESMRThisOnly == mrEntry->RecurrenceModRule() ) + { + TBool instanceAlreadyOnThisDay( + mrEntry->AnyInstanceOnDayL(startTime, endTime) ); + + if ( instanceAlreadyOnThisDay ) + { + error = MESMRFieldValidator::EErrorRescheduleInstance; + } + } + } + + if ( KErrorNone == error && iAlldayEvent && iAlarmOnOff ) + { + TTime alarmTime = AlarmDateTime(); + if ( alarmTime > startTime ) + { + SetTimeToEditor( *iAlarmTime, iCurrentAlarmTime ); + SetDateToEditor( *iAlarmDate, iCurrentAlarmTime ); + + error = MESMRFieldValidator::EErrorAlarmLaterThanStart; + } + + TTime currentTime; + currentTime.HomeTime(); + if ( KErrorNone == error && alarmTime < currentTime ) + { + error = MESMRFieldValidator::EErrorAlarmInPast; + } + if ( KErrorNone == error && alarmTime < startTime ) + { + TTimeIntervalDays alarmBefore = startTime.DaysFrom(alarmTime); + if ( alarmBefore > KMaxAlarmTime ) + { + error = MESMRFieldValidator::EErrorAlarmTooMuchInPast; + } + } + } + + MESMRCalEntry::TESMRRecurrenceModifyingRule rule = + MESMRCalEntry::EESMRThisOnly; + + // Checking if entry is recurrent + if ( iEntry->IsRecurrentEventL()) + { + // Getting the recurrence information + rule = iEntry->RecurrenceModRule(); + } + + // Showing error note if alarm in past, when + // entry has no recurrence + if ( KErrorNone == error && + currentAlarmTime < currentTime && + !iAlldayEvent && + iCurrentAlarmTimeOffset.Int() != KAlarmNotSet && + iRecurrenceValue == ERecurrenceNot ) + { + error = MESMRFieldValidator::EErrorRelativeAlarmInPast; + } + + TTime until; + if ( iRecurrenceValue != ERecurrenceNot && + iRecurrenceValue != ERecurrenceUnknown ) + { + until = RecurrenceUntilTime(); + + // Showing error note if is alarm in past, + // when entry has recurrence + if ( KErrorNone == error && + iCurrentAlarmTimeOffset.Int() != KAlarmNotSet && + until < currentTime && + rule != MESMRCalEntry::EESMRAllInSeries ) + { + error = MESMRFieldValidator::EErrorRelativeAlarmInPast; + } + } + } + return error; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::ReadValuesFromEntryL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::ReadValuesFromEntryL( + MESMRCalEntry& aEntry ) + { + FUNC_LOG; + MESMRCalEntry::TESMRCalEntryType entryType( aEntry.Type() ); + + if ( MESMRCalEntry::EESMRCalEntryMeetingRequest == entryType || + MESMRCalEntry::EESMRCalEntryMeeting == entryType ) + { + // Meeting or meeting request + __ASSERT_DEBUG( + iStartTime, + Panic(EESMRMeetingTimeValidatorNullStartTime) ); + + __ASSERT_DEBUG( + iEndTime, + Panic(EESMRMeetingTimeValidatorNullStopTime) ); + + __ASSERT_DEBUG( + iStartDate, + Panic(EESMRMeetingTimeValidatorNullStartTime) ); + + __ASSERT_DEBUG( + iEndDate, + Panic(EESMRMeetingTimeValidatorNullStopTime) ); + + iEntry = &aEntry; + CCalEntry& entry( aEntry.Entry() ); + + iCurrentStartTime = entry.StartTimeL().TimeLocalL(); + iCurrentEndTime = entry.EndTimeL().TimeLocalL(); + + //Comparative start time required for comparisons in editor + //recurrence handling + iComparativeStartTime = iCurrentStartTime.DateTime(); + + if ( aEntry.IsAllDayEventL() ) + { + iCurrentEndTime -= TTimeIntervalDays( KOne ); + } + + TTime start = iCurrentStartTime; + TTime end = iCurrentEndTime; + + SetTimeToEditor( *iStartTime, start ); + SetDateToEditor( *iStartDate, start ); + + SetTimeToEditor( *iEndTime, end ); + SetDateToEditor( *iEndDate, end ); + + ReadAlarmFromEntryL( entry ); + ReadRecurrenceFromEntryL( aEntry ); + + DrawEditorsDeferred(); + } + } +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::StoreValuesToEntryL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::StoreValuesToEntryL( + MESMRCalEntry& aEntry ) + { + FUNC_LOG; + CCalEntry& entry( aEntry.Entry() ); + + // Before writing start and end time to enty, let's + // check is currently edited entry exception for series + // If entry is an exception and start time is set after + // repeat until date; the calinterim API will delete + // the recurrence rules from entry, so the + // solution to avoid this is to move the repeat until date + // to match the new start and end time for this exception entry. + if ( ERecurrenceNot == iRecurrenceValue && + aEntry.IsRecurrentEventL() && + MESMRCalEntry::EESMRThisOnly == aEntry.RecurrenceModRule() ) + { + TCalRRule originalRRule; + if ( iEntry->Entry().GetRRuleL( originalRRule ) ) + { + TTime localUntilTime = originalRRule.Until().TimeLocalL(); + TTime endTime = EndDateTime(); + TDateTime datetimeendtime = endTime.DateTime(); + TDateTime datetimelocalUntil = localUntilTime.DateTime(); + + if ( endTime > localUntilTime ) + { + TCalRRule rRule; + rRule.SetDtStart( originalRRule.DtStart() ); + rRule.SetType( originalRRule.Type() ); + + TCalTime newUntil; + newUntil.SetTimeLocalL( endTime ); + rRule.SetUntil( newUntil ); + rRule.SetInterval( originalRRule.Interval() ); + iEntry->Entry().SetRRuleL( rRule ); + } + } + } + else if ( aEntry.IsRecurrentEventL() && + MESMRCalEntry::EESMRAllInSeries == aEntry.RecurrenceModRule() ) + { + TTime orgStartTime = iEntry->Entry().StartTimeL().TimeLocalL(); + TTime orgEndTime = iEntry->Entry().EndTimeL().TimeLocalL(); + + if ( orgStartTime != StartDateTime() || + orgEndTime != EndDateTime() ) + { + // We are editing the series --> We need to clear the recurrence from the entry + // When changing start or end time --> Exceptions needs to be cleared from the series + // It is set later in this method. + aEntry.SetRecurrenceL( ERecurrenceNot, Time::NullTTime() ); + } + } + + WriteStartAndEndTimeToEntryL( aEntry ); + + if ( iAlldayEvent ) + { + TTime startTime = StartDateTime(); + TTime endTime = EndDateTime(); + + // For all day event end time is adjusted 24 hours + // forward so that it ends correctly + aEntry.SetAllDayEventL( startTime, endTime ); + + if ( iAlarmOnOff ) + { + TTime alarmTime = AlarmDateTime(); + TTimeIntervalMinutes alarmDiff; + startTime.MinutesFrom( alarmTime, alarmDiff ); + + CCalAlarm* alarm = CCalAlarm::NewL(); + CleanupStack::PushL( alarm ); + alarm->SetTimeOffset( alarmDiff ); + + entry.SetAlarmL( alarm ); + CleanupStack::PopAndDestroy( alarm ); + alarm = NULL; + } + else + { + entry.SetAlarmL( NULL ); + } + } + + if ( ERecurrenceNot != iRecurrenceValue && + ERecurrenceUnknown != iRecurrenceValue ) + { + aEntry.SetRecurrenceL( + iRecurrenceValue, + RecurrenceUntilTime() ); + } + else if ( ERecurrenceNot == iRecurrenceValue && + aEntry.IsRecurrentEventL() && + MESMRCalEntry::EESMRAllInSeries == aEntry.RecurrenceModRule() ) + { + aEntry.SetRecurrenceL( + iRecurrenceValue, + Time::NullTTime() ); + } + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::SetStartTimeFieldL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::SetStartTimeFieldL( + CEikTimeEditor& aStartTime ) + { + FUNC_LOG; + iStartTime = &aStartTime; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::SetEndTimeFieldL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::SetEndTimeFieldL( + CEikTimeEditor& aEndTime ) + { + FUNC_LOG; + iEndTime = &aEndTime; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::SetStartDateFieldL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::SetStartDateFieldL( + CEikDateEditor& aStartDate ) + { + FUNC_LOG; + iStartDate = &aStartDate; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::SetEndDateFieldL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::SetEndDateFieldL( + CEikDateEditor& aEndTime ) + { + FUNC_LOG; + iEndDate = &aEndTime; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::SetAlarmTimeFieldL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::SetAlarmTimeFieldL( + CEikTimeEditor& aAlarmTime ) + { + FUNC_LOG; + iAlarmTime = &aAlarmTime; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::SetAlarmDateFieldL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::SetAlarmDateFieldL( + CEikDateEditor& aAlarmDate ) + { + FUNC_LOG; + iAlarmDate = &aAlarmDate; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::StartTimeChangedL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::SetRecurrenceUntilDateFieldL( + CEikDateEditor& aRecurrenceUntil ) + { + FUNC_LOG; + iRecurrenceUntilDate = &aRecurrenceUntil; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::StartTimeChangedL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::StartTimeChangedL() + { + FUNC_LOG; + StartDateChandedL(); + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::EndTimeChangedL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::EndTimeChangedL() + { + FUNC_LOG; + PreValidateEditorContent(); + HandleEndTimeChangeL(); + DrawEditorsDeferred(); + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::StartDateChandedL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::StartDateChandedL() + { + FUNC_LOG; + PreValidateEditorContent(); + HandleStartTimeChangeL(); + HandleAlarmTimeChangedL(); + DrawEditorsDeferred(); + SendFieldChangeEventL( EESMRFieldStartDate ); + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::EndDateChangedL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::EndDateChangedL() + { + FUNC_LOG; + TInt err( KErrNone ); + + PreValidateEditorContent(); + + TTime start = StartDateTime(); + TTime end = EndDateTime(); + + if ( end < start ) + { + err = KErrArgument; + } + + if ( err == KErrNone ) + { + HandleEndTimeChangeL(); + HandleAlarmTimeChangedL(); + } + else + { + SetTimeToEditor( *iEndTime, iCurrentEndTime ); + SetDateToEditor( *iEndDate, iCurrentEndTime ); + } + + DrawEditorsDeferred(); + + User::LeaveIfError( err ); + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::AlarmTimeChangedL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::AlarmTimeChangedL() + { + FUNC_LOG; + AlarmDateChangedL(); + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::AlarmDateChangedL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::AlarmDateChangedL() + { + FUNC_LOG; + if ( iAlarmOnOff && iAlarmTime && iAlarmDate && iAlldayEvent ) + { + PreValidateEditorContent(); + HandleAlarmTimeChangedL(); + DrawEditorsDeferred(); + } + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::RelativeAlarmChangedL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::RelativeAlarmChangedL( + TTimeIntervalMinutes aCurrentAlarmTimeOffset, + TBool aHandleAlarmChange, + TBool& aRelativeAlarmValid ) + { + FUNC_LOG; + iRelativeAlarmValid = &aRelativeAlarmValid; + iCurrentAlarmTimeOffset = aCurrentAlarmTimeOffset; + + if ( aHandleAlarmChange ) + { + HandleRelativeAlarmTimeChangedL(); + } + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::SetAllDayEventL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::SetAllDayEventL( + TBool aAlldayEvent ) + { + FUNC_LOG; + if ( iAlldayEvent != aAlldayEvent ) + { + iAlldayEvent = aAlldayEvent; + + if ( iAlldayEvent ) + { + iStartTimeBeforeAlldayEvent = iCurrentStartTime; + iEndTimeBeforeAlldayEvent = iCurrentEndTime; + + TTime start = StartDateTime(); + iCurrentStartTime = StartDateTime(); + iCurrentEndTime = EndDateTime(); + + if ( iAlarmOnOff ) + { + TTime alarm = DefaultAlldayEventAlarmTime( start ); + SetTimeToEditor( *iAlarmTime, alarm ); + SetDateToEditor( *iAlarmDate, alarm ); + iCurrentAlarmTime = alarm; + } + + DrawEditorsDeferred(); + } + else + { + SetTimeToEditor( *iStartTime, iStartTimeBeforeAlldayEvent ); + SetTimeToEditor( *iEndTime, iEndTimeBeforeAlldayEvent ); + + TTime start = StartDateTime(); + TTime end = EndDateTime(); + + if ( start > end ) + { + // User has modified dates so that end time + // is earlier than start time + end = start; + } + + SetTimeToEditor( *iStartTime, start ); + SetDateToEditor( *iStartDate, start ); + + SetTimeToEditor( *iEndTime, end ); + SetDateToEditor( *iEndDate, end ); + + iCurrentStartTime = start; + iCurrentEndTime = end; + + DrawEditorsDeferred(); + } + } + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::SetAlarmOnOffL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::SetAlarmOnOffL( + TBool aAlarmOn ) + { + FUNC_LOG; + iAlarmOnOff = aAlarmOn; + + if ( iAlarmOnOff && iAlldayEvent ) + { + TTime nullTime = Time::NullTTime(); + + if ( iCurrentAlarmTime > iCurrentStartTime || + iCurrentAlarmTime == nullTime ) + { + iCurrentAlarmTime = + DefaultAlldayEventAlarmTime( iCurrentStartTime ); + SetTimeToEditor( *iAlarmTime, iCurrentAlarmTime ); + SetDateToEditor( *iAlarmDate, iCurrentAlarmTime ); + } + } + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::RecurrenceChangedL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::RecurrenceChangedL( + TESMRRecurrenceValue aRecurrence ) + { + FUNC_LOG; + if ( aRecurrence != iRecurrenceValue ) + { + + TDateTime start = StartDateTime(); + TDateTime end = EndDateTime(); + + if ( start.Day() != end.Day() || + start.Month() != end.Month() || + start.Year() != end.Year()) + { + User::Leave( KErrArgument ); + } + + iRecurrenceValue = aRecurrence; + PreValidateEditorContent(); + HandleRecurrenceTypeChanged(); + DrawEditorsDeferred(); + } + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::RecurrenceEndDateChangedL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::RecurrenceEndDateChangedL() + { + FUNC_LOG; + PreValidateEditorContent(); + HandleRecurrenceEndDateChangedL(); + DrawEditorsDeferred(); + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::IsRelativeAlarmValid +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingTimeValidator::IsRelativeAlarmValid( + TTimeIntervalMinutes aAlarmTimeOffset ) + { + FUNC_LOG; + TBool validity( ETrue ); + TTime startTime = StartDateTime(); + TTime currentTime; + currentTime.HomeTime(); + + if ( ( startTime - aAlarmTimeOffset ) < currentTime && + aAlarmTimeOffset.Int() != KAlarmNotSet ) + { + validity = EFalse; + } + + return validity; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::SetFieldEventQueue +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::SetFieldEventQueue( + MESMRFieldEventQueue* aEventQueue ) + { + FUNC_LOG; + iEventQueue = aEventQueue; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::PreValidateEditorContent +// --------------------------------------------------------------------------- +// +TInt CESMRMeetingTimeValidator::PreValidateEditorContent() + { + FUNC_LOG; + TInt err( KErrNone ); + TRAP( err, PreValidateEditorContentL() ); + return err; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::PreValidateEditorContentL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::PreValidateEditorContentL() + { + FUNC_LOG; + if (iStartTime && iStartTime->IsVisible() ) + { + iStartTime->PrepareForFocusLossL(); + } + if (iEndTime && iEndTime->IsVisible() ) + { + iEndTime->PrepareForFocusLossL(); + } + if (iStartDate && iStartDate->IsVisible() ) + { + iStartDate->PrepareForFocusLossL(); + } + if (iEndDate && iEndDate->IsVisible() ) + { + iEndDate->PrepareForFocusLossL(); + } + if ( iAlarmOnOff && iAlarmTime && iAlldayEvent && iAlarmTime->IsVisible() ) + { + TDateTime dt = iAlarmTime->Time().DateTime(); + iAlarmTime->PrepareForFocusLossL(); + } + if ( iAlarmOnOff && iAlarmDate && iAlldayEvent && iAlarmDate->IsVisible() ) + { + iAlarmDate->PrepareForFocusLossL(); + } + if ( iRecurrenceUntilDate && iRecurrenceUntilDate->IsVisible() ) + { + iRecurrenceUntilDate->PrepareForFocusLossL(); + } + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::HandleStartTimeChangeL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::HandleStartTimeChangeL() + { + FUNC_LOG; + TTime startTime = StartDateTime(); + TTime endTime = EndDateTime(); + + SetTimeToEditor( *iStartTime, startTime ); + SetDateToEditor( *iStartDate, startTime ); + + TTimeIntervalMinutes startTimeChange; + User::LeaveIfError( + startTime.MinutesFrom( + iCurrentStartTime, + startTimeChange ) ); + + endTime += startTimeChange; + + if ( MESMRCalEntry::EESMRCalEntryMeetingRequest == iEntry->Type() ) + { + MESMRMeetingRequestEntry* mrEntry = + static_cast( iEntry ); + if ( mrEntry->IsRecurrentEventL() && + MESMRCalEntry::EESMRThisOnly == mrEntry->RecurrenceModRule() ) + { + TBool instanceAlreadyOnThisDay( + mrEntry->AnyInstanceOnDayL(startTime, endTime) ); + + if ( instanceAlreadyOnThisDay ) + { + // Restore previous time + SetTimeToEditor( *iStartTime, iCurrentStartTime ); + SetDateToEditor( *iStartDate, iCurrentStartTime ); + + User::Leave( KErrOverflow ); + } + } + } + + SetTimeToEditor( *iEndTime, endTime ); + SetDateToEditor( *iEndDate, endTime ); + + iCurrentStartTime = startTime; + iCurrentEndTime = endTime; + + if ( iAlldayEvent && iAlarmOnOff && + iAlarmTime->IsVisible() && iAlarmDate->IsVisible() ) + { + TTime alarmTime = AlarmDateTime(); + alarmTime += startTimeChange; + + SetTimeToEditor( *iAlarmTime, alarmTime ); + SetDateToEditor( *iAlarmDate, alarmTime ); + + iCurrentAlarmTime = alarmTime; + } + + if ( ERecurrenceNot != iRecurrenceValue && + iRecurrenceUntilDate && iRecurrenceUntilDate->IsVisible() ) + { + TTime recUntil = RecurrenceUntilTime(); + + if ( startTime.DateTime().Day() != iComparativeStartTime.Day() || + startTime.DateTime().Month() != iComparativeStartTime.Month() || + startTime.DateTime().Year() != iComparativeStartTime.Year() ) + { + // We want to update the recurrence until only when + // a) Day, b) Month, c) or Year of the start time has changed + recUntil += startTimeChange; + iComparativeStartTime = startTime.DateTime(); + } + + SetDateToEditor( *iRecurrenceUntilDate, recUntil ); + iCurrentRecurrenceUntil = recUntil; + } + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::HandleEndTimeChangeL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::HandleEndTimeChangeL() + { + FUNC_LOG; + TInt err( KErrNone ); + TTime startTime = StartDateTime(); + TTime endTime = EndDateTime(); + + if ( !iAlldayEvent && endTime < startTime ) + { + if( ERecurrenceNot != iRecurrenceValue ) + { + err = KErrArgument; + } + else + { + // End time is earlier than start time + // and this is not allday event. + endTime += TTimeIntervalDays( KOne ); + } + } + + if ( MESMRCalEntry::EESMRCalEntryMeetingRequest == iEntry->Type() ) + { + // Check that is modified entry + MESMRMeetingRequestEntry* mrEntry = + static_cast( iEntry ); + if ( mrEntry->IsRecurrentEventL() && + MESMRCalEntry::EESMRThisOnly == mrEntry->RecurrenceModRule() ) + { + TBool instanceAlreadyOnThisDay( + mrEntry->AnyInstanceOnDayL(startTime, endTime) ); + + if ( instanceAlreadyOnThisDay ) + { + // Restore previous time + SetTimeToEditor( *iStartTime, iCurrentStartTime ); + SetDateToEditor( *iStartDate, iCurrentStartTime ); + + err = KErrOverflow; + } + } + } + + if ( KErrNone == err ) + { + iCurrentStartTime = startTime; + iCurrentEndTime = endTime; + } + + if ( !iAlldayEvent ) + { + SetTimeToEditor( *iStartTime, iCurrentStartTime ); + SetTimeToEditor( *iEndTime, iCurrentEndTime ); + } + + SetDateToEditor( *iStartDate, iCurrentStartTime ); + SetDateToEditor( *iEndDate, iCurrentEndTime ); + + User::LeaveIfError( err ); + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::HandleAlarmTimeChangedL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::HandleAlarmTimeChangedL() + { + FUNC_LOG; + TInt err(KErrNone); + + if ( iAlarmOnOff && iAlarmTime && iAlarmDate && iAlldayEvent ) + { + TTime alarm = AlarmDateTime(); + TTime start = StartDateTime(); + + if ( start < alarm ) + { + alarm = iCurrentAlarmTime; + err = KErrArgument; + } + else + { + iCurrentAlarmTime = alarm; + } + + SetTimeToEditor( *iAlarmTime, iCurrentAlarmTime ); + SetDateToEditor( *iAlarmDate, iCurrentAlarmTime ); + } + + User::LeaveIfError( err ); + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::HandleRelativeAlarmTimeChangedL() +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::HandleRelativeAlarmTimeChangedL() + { + FUNC_LOG; + TInt err( KErrNone ); + + // Getting current time + TTime currentTime; + currentTime.HomeTime(); + + // Getting meeting start time + TTime meetingStartTime = StartDateTime(); + + // Getting current alarm time + TTime currentAlarmTime = meetingStartTime - iCurrentAlarmTimeOffset; + + // If alarm is set, entry is not recurrent, but alarm occures in past + if ( currentAlarmTime < currentTime && + iCurrentAlarmTimeOffset.Int() != KAlarmNotSet && + iRecurrenceValue == ERecurrenceNot ) + { + err = KErrArgument; + } + + if ( iRecurrenceValue != ERecurrenceNot && + iRecurrenceValue != ERecurrenceUnknown ) + { + TTime until = RecurrenceUntilTime(); + + // if alarm is set, entry is recurrent, but until date is in past + if ( iCurrentAlarmTimeOffset.Int() != KAlarmNotSet && + until < currentTime ) + { + err = KErrArgument; + } + } + + User::LeaveIfError( err ); + } +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::HandleRecurrenceTypeChanged +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::HandleRecurrenceTypeChanged() + { + FUNC_LOG; + if ( ERecurrenceNot != iRecurrenceValue ) + { + TTime start = StartDateTime(); + TTime minTimeForRecurrenceEnd = + TimeForNextInstaceStartTime( iRecurrenceValue, start ); + + TDateTime a = iCurrentRecurrenceUntil.DateTime(); + TDateTime b = minTimeForRecurrenceEnd.DateTime(); + + if ( iCurrentRecurrenceUntil < minTimeForRecurrenceEnd ) + { + iCurrentRecurrenceUntil = minTimeForRecurrenceEnd; + } + } + else + { + iCurrentRecurrenceUntil = StartDateTime(); + } + + if ( iRecurrenceUntilDate ) + { + SetDateToEditor( *iRecurrenceUntilDate, iCurrentRecurrenceUntil ); + } + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::HandleRecurrenceEndDateChangedL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::HandleRecurrenceEndDateChangedL() + { + FUNC_LOG; + TInt err( KErrNone ); + + TTime start = StartDateTime(); + TTime recurrenceUntilTime = RecurrenceUntilTime(); + + if ( recurrenceUntilTime <= start ) + { + err = KErrArgument; + } + else + { + iCurrentRecurrenceUntil = recurrenceUntilTime; + } + + if ( iRecurrenceUntilDate ) + { + SetDateToEditor( *iRecurrenceUntilDate, iCurrentRecurrenceUntil ); + } + + User::LeaveIfError( err ); + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::DrawEditorsDeferred +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::DrawEditorsDeferred() + { + FUNC_LOG; + if (iStartTime && iStartTime->IsVisible() ) + { + iStartTime->DrawDeferred(); + } + if (iEndTime && iEndTime->IsVisible() ) + { + iEndTime->DrawDeferred(); + } + if (iStartDate && iStartDate->IsVisible() ) + { + iStartDate->DrawDeferred(); + } + if (iEndDate && iEndDate->IsVisible() ) + { + iEndDate->DrawDeferred(); + } + if ( iAlarmOnOff && iAlarmTime && iAlldayEvent && iAlarmTime->IsVisible() ) + { + iAlarmTime->DrawDeferred(); + } + if ( iAlarmOnOff && iAlarmDate && iAlldayEvent && iAlarmDate->IsVisible() ) + { + iAlarmDate->DrawDeferred(); + } + if ( iRecurrenceUntilDate && iRecurrenceUntilDate->IsVisible() ) + { + iRecurrenceUntilDate->DrawDeferred(); + } + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::StartDateTime +// --------------------------------------------------------------------------- +// +TDateTime CESMRMeetingTimeValidator::StartDateTime() + { + FUNC_LOG; + TDateTime startDateTime = iStartDate->Date().DateTime(); + TDateTime startTime = iStartTime->Time().DateTime(); + + if ( iAlldayEvent ) + { + startDateTime.SetHour( KZero ); + startDateTime.SetMinute( KZero ); + startDateTime.SetSecond( KZero ); + } + else + { + startDateTime.SetHour( startTime.Hour() ); + startDateTime.SetMinute( startTime.Minute() ); + startDateTime.SetSecond( startTime.Second() ); + } + + return startDateTime; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::EndDateTime +// --------------------------------------------------------------------------- +// +TDateTime CESMRMeetingTimeValidator::EndDateTime() + { + FUNC_LOG; + TDateTime endDateTime = iEndDate->Date().DateTime(); + TDateTime endTime = iEndTime->Time().DateTime(); + + if ( iAlldayEvent ) + { + endDateTime.SetHour( KZero ); + endDateTime.SetMinute( KZero ); + endDateTime.SetSecond( KZero ); + } + else + { + endDateTime.SetHour( endTime.Hour() ); + endDateTime.SetMinute( endTime.Minute() ); + endDateTime.SetSecond( endTime.Second() ); + } + + return endDateTime; + } + + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::AlarmDateTime +// --------------------------------------------------------------------------- +// +TDateTime CESMRMeetingTimeValidator::AlarmDateTime() + { + FUNC_LOG; + TDateTime alarmDateTime = iAlarmDate->Date().DateTime(); + TDateTime alarmTime = iAlarmTime->Time().DateTime(); + + alarmDateTime.SetHour( alarmTime.Hour() ); + alarmDateTime.SetMinute( alarmTime.Minute() ); + alarmDateTime.SetSecond( alarmTime.Second() ); + + return alarmDateTime; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::RecurrenceUntilTime +// --------------------------------------------------------------------------- +// +TDateTime CESMRMeetingTimeValidator::RecurrenceUntilTime() + { + FUNC_LOG; + TDateTime recurrenceUntil = + iRecurrenceUntilDate->Date().DateTime(); + TDateTime startTime = iStartTime->Time().DateTime(); + + recurrenceUntil.SetHour( startTime.Hour() ); + recurrenceUntil.SetMinute( startTime.Minute() ); + recurrenceUntil.SetSecond( startTime.Second() ); + + return recurrenceUntil; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::ReadAlarmFromEntryL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::ReadAlarmFromEntryL( + CCalEntry& aEntry ) + { + FUNC_LOG; + // Alarm is set for validating + CCalAlarm *alarm = aEntry.AlarmL(); + CleanupStack::PushL( alarm ); + + if ( alarm ) + { + // Alarm is set + iCurrentAlarmTime = iCurrentStartTime - alarm->TimeOffset(); + } + else + { + iCurrentAlarmTime = Time::NullTTime(); + iAlarmOnOff = EFalse; + } + + CleanupStack::PopAndDestroy( alarm ); + alarm = NULL; + + if ( iAlarmDate && iAlarmTime && iAlarmOnOff ) + { + SetTimeToEditor( *iAlarmTime, iCurrentAlarmTime ); + SetDateToEditor( *iAlarmDate, iCurrentAlarmTime ); + } + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::ReadRecurrenceFromEntryL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::ReadRecurrenceFromEntryL( + MESMRCalEntry& aEntry ) + { + FUNC_LOG; + if ( aEntry.IsRecurrentEventL() && + MESMRCalEntry::EESMRAllInSeries == aEntry.RecurrenceModRule() ) + { + aEntry.GetRecurrenceL( + iRecurrenceValue, + iCurrentRecurrenceUntil ); + + if ( iRecurrenceUntilDate && iRecurrenceUntilDate->IsVisible() ) + { + // Recurrence time has to be shown in the editor as local time + TCalTime recurrenceTime; + recurrenceTime.SetTimeUtcL( iCurrentRecurrenceUntil ); + TTime localRecurrenceTime = recurrenceTime.TimeLocalL(); + + SetDateToEditor( *iRecurrenceUntilDate, localRecurrenceTime ); + } + } + else + { + iRecurrenceValue = ERecurrenceNot; + } + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::ForceValuesL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::ForceValuesL() + { + FUNC_LOG; + TTime startTime = StartDateTime(); + TTime endTime = EndDateTime(); + + if ( endTime < startTime ) + { + // For end and start date following check and correction is made: + // - Entry ends earlier than starts + // --> For stored entries, orginal values are restored. + // --> For unsaved entries endTime is set to start time. + // + if ( iEntry->IsStoredL() ) + { + // If entry is stored, orginal values are restored + const CCalEntry& orginalEntry( iEntry->OriginalEntry() ); + startTime = orginalEntry.StartTimeL().TimeLocalL(); + endTime = orginalEntry.EndTimeL().TimeLocalL(); + } + else + { + endTime = startTime; + } + } + + // if entry has not directly supported recurrence value + // e.g. every second day; the repeat until field is + // in read only mode and iRecurrenceUntilDate is + // not set to validator + if ( iRecurrenceUntilDate && + ERecurrenceNot != iRecurrenceValue ) + { + // For recurrent event following checks and corrections are made: + // - Start and end date are the same. If not --> end = start + // - recurrence until is not earlier than start + // --> recurrenceUntil = start + one year + // + TDateTime startDt = startTime.DateTime(); + TDateTime endDt = endTime.DateTime(); + + if ( startDt.Day() != endDt.Day() || + startDt.Month() != endDt.Month() || + startDt.Year() != endDt.Year() ) + { + // Setting start and end date to be the same day + endDt.SetDay( startDt.Day() ); + endDt.SetMonth( startDt.Month() ); + endDt.SetYear( startDt.Year() ); + endTime = endDt; + } + + TTime recurUntil = RecurrenceUntilTime(); + if ( ERecurrenceUnknown != iRecurrenceValue && + recurUntil < startTime ) + { + recurUntil = startTime + TTimeIntervalYears( KOne ); + iCurrentRecurrenceUntil = recurUntil; + } + } + + if ( iAlldayEvent && iAlarmOnOff ) + { + // For alarm following cehcks and corrections are made: + // - Alarm is more that 31 days before start + // --> Alarm is adjusted to be 30,5 half days before + // - Alarm is later than start time + // --> Default alarm time is set for alarm + // - Alarm occurs in past + // --> For unsaved entries alarm is set off + // + TTime alarmTime = AlarmDateTime(); + TTimeIntervalDays alarmBefore = startTime.DaysFrom(alarmTime); + if ( alarmBefore > KMaxAlarmTime ) + { + // Adjust alarm time to 30,5 half days earlier + alarmTime = startTime - KMaxAlarmTime + TTimeIntervalHours(KNoon); + } + + if ( alarmTime > startTime ) + { + // Setting alarm to default value + alarmTime = DefaultAlldayEventAlarmTime( startTime ); + } + + TTime currentTime; currentTime.HomeTime(); + if ( alarmTime < currentTime ) + { + if ( !iEntry->IsStoredL() ) + { + // Setting alarm to default value if entry is not stored + iAlarmOnOff = EFalse; + } + } + + iCurrentAlarmTime = alarmTime; + } + + TTime currentTime; + currentTime.HomeTime(); + + // If relative alarm time is in past + if ( !iAlldayEvent && + ( startTime - iCurrentAlarmTimeOffset ) < currentTime ) + { + // Setting relative alarm to off + iCurrentAlarmTimeOffset = KAlarmNotSet; + *iRelativeAlarmValid = EFalse; + } + + iCurrentStartTime = startTime; + iCurrentEndTime = endTime; + + // Start + SetTimeToEditor( *iStartTime, startTime ); + SetDateToEditor( *iStartDate, startTime ); + + // End + SetTimeToEditor( *iEndTime, endTime ); + SetDateToEditor( *iEndDate, endTime ); + + // Alarm + if(iAlarmTime) + { + SetTimeToEditor( *iAlarmTime, iCurrentAlarmTime ); + } + + if(iAlarmDate) + { + SetDateToEditor( *iAlarmDate, iCurrentAlarmTime ); + } + + + // if editing certain occurance of recurrent event series + // the repeat until date is not available. + if ( iRecurrenceUntilDate ) + { + // Recurrence until + SetDateToEditor( *iRecurrenceUntilDate, iCurrentRecurrenceUntil ); + } + + } + + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::ForceEndDateTime +// --------------------------------------------------------------------------- +// +TDateTime CESMRMeetingTimeValidator::ForceEndDateTime() + { + FUNC_LOG; + // In recurrent event cases, when user has modified the end date + // and presses Done or Save, the end date has to be adjusted to + // the current start date. The Hours, minutes and seconds should + // still remain in original value though. + + TDateTime startDateTime = iStartDate->Date().DateTime(); + + TDateTime modifiedEndDateTime = iEndDate->Date().DateTime(); + TDateTime endTime = iEndTime->Time().DateTime(); + + modifiedEndDateTime.SetDay( startDateTime.Day() ); + modifiedEndDateTime.SetMonth( startDateTime.Month() ); + modifiedEndDateTime.SetYear( startDateTime.Year() ); + + modifiedEndDateTime.SetHour( endTime.Hour() ); + modifiedEndDateTime.SetMinute( endTime.Minute() ); + modifiedEndDateTime.SetSecond( endTime.Second() ); + + return modifiedEndDateTime; + } + + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::ForceRepeatUntilTimeL +// --------------------------------------------------------------------------- +// +TTime CESMRMeetingTimeValidator::ForceRecurrenceUntilTime() + { + FUNC_LOG; + // In recurrent event cases, when user has modified the end date + // and presses Done or Save, the recurrence until time has to be + // adjusted according to the new start date. + + TTime newUntil(0); + + // Let's find out what the original period of recurrence was + TTimeIntervalMinutes recurrencePeriod(0); + TDateTime originalStartTime = iComparativeStartTime; + + // We do not need Hours, Minutes, seconds when setting + // recurrence until date + originalStartTime.SetHour(0); + originalStartTime.SetMinute(0); + originalStartTime.SetSecond(0); + + TTime originalRecurrenceUntilTime = iRecurrenceUntilDate->Date(); + + originalRecurrenceUntilTime.MinutesFrom( + originalStartTime, recurrencePeriod ); + + // New recurrence until time is the new meeting start date plus + // the recurrence period + newUntil = iStartDate->Date() + recurrencePeriod; + + return newUntil; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::WriteStartAndEndTimeToEntryL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::WriteStartAndEndTimeToEntryL( + MESMRCalEntry& aEntry ) + { + FUNC_LOG; + CCalEntry& entry( aEntry.Entry() ); + const CCalEntry& originalEntry( aEntry.OriginalEntry() ); + + TTime startTime = StartDateTime(); + TTime endTime = EndDateTime(); + + TTime orgStartTime = originalEntry.StartTimeL().TimeLocalL(); + TTime orgEndTime = originalEntry.EndTimeL().TimeLocalL(); + + if ( !aEntry.IsStoredL() || orgStartTime != startTime || + orgEndTime != endTime ) + { + // End time has changed --> Store it to entry + TCalTime start; + start.SetTimeLocalL( startTime ); + + TCalTime end; + end.SetTimeLocalL( endTime ); + + TDateTime st = start.TimeLocalL().DateTime(); + TDateTime et = end.TimeLocalL().DateTime(); + + entry.SetStartAndEndTimeL( start, end ); + } + else if ( aEntry.IsRecurrentEventL() && + MESMRCalEntry::EESMRAllInSeries == aEntry.RecurrenceModRule() ) + { + // For recurrent events, parent entry's start and end time is stored + // to entry. + + CCalInstance* instance = aEntry.InstanceL(); + if ( instance ) + { + CleanupStack::PushL( instance ); + + CCalEntry& parent = instance->Entry(); + entry.SetStartAndEndTimeL( + parent.StartTimeL(), + parent.EndTimeL() ); + + CleanupStack::PopAndDestroy( instance ); + instance = NULL; + } + } + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingTimeValidator::SendFieldChangeEventL +// --------------------------------------------------------------------------- +// +void CESMRMeetingTimeValidator::SendFieldChangeEventL( + TESMREntryFieldId aFieldId ) + { + FUNC_LOG; + if ( iEventQueue ) + { + CESMRGenericFieldEvent* event = + CESMRGenericFieldEvent::NewLC( NULL, + MESMRFieldEvent::EESMRFieldChangeEvent ); + TInt fieldId = aFieldId; + CESMRFieldEventValue* field = CESMRFieldEventValue::NewLC( + CESMRFieldEventValue::EESMRInteger, &fieldId ); + event->AddParamL( field ); + CleanupStack::Pop( field ); + CESMRFieldEventValue* date = CESMRFieldEventValue::NewLC( + CESMRFieldEventValue::EESMRTTime, &iCurrentStartTime ); + event->AddParamL( date, ETrue ); + CleanupStack::Pop( date ); + iEventQueue->NotifyEventL( *event ); + CleanupStack::PopAndDestroy( event ); + } + } + +// EOF +