--- a/clock2/clockui/uilayer/clockmainview/src/clockmainview.cpp Tue Apr 27 16:36:22 2010 +0300
+++ b/clock2/clockui/uilayer/clockmainview/src/clockmainview.cpp Tue May 11 16:12:24 2010 +0300
@@ -41,6 +41,18 @@
#include "clock_debug.h"
// Constants
+const TInt KMaxCharsInNote( 32 );
+const TInt KZerothRule( 0 );
+const TInt KDaysInWeek( 7 );
+const TInt KOneMinuteInMicrosecond( 1000000 * 60 );
+const TInt KOneHourInMinute( 60 );
+const TInt KOneMinute( 1 );
+const TInt KOneHour( 1 );
+const TInt KNoDifference( 0 );
+
+_LIT( KDateTimeFormatter, "%-B%:0%J%:1%T%:3%+B" ); // For the date and time displayed in the rollover note.
+
+
// Literals
@@ -183,6 +195,11 @@
// Update the latest alarm details.
iAlarmModel->ClockAlarmInfo( iAlarmId, iAlarmInfo );
+ if(CheckForDstChangesL())
+ {
+ DisplayRemainingTimeL();
+ }
+
// First update the model with the latest alarm id.
iAlarmModel->SaveLatestAlarmId( iAlarmId );
@@ -399,6 +416,11 @@
// Update the latest alarm details.
iAlarmModel->ClockAlarmInfo( iAlarmId, iAlarmInfo );
+ if(CheckForDstChangesL())
+ {
+ DisplayRemainingTimeL();
+ }
+
// First update the model with the latest alarm id.
iAlarmModel->SaveLatestAlarmId( iAlarmId );
@@ -879,4 +901,334 @@
return static_cast< CClockAppUi* > ( AppUi() );
}
+// ---------------------------------------------------------
+// CClockAlarmEditorImpl::DisplayRemainingTimeL
+// rest of the details are commented in the header
+// ---------------------------------------------------------
+//
+void CClockMainView::DisplayRemainingTimeL()
+ {
+ __PRINTS( "CClockAlarmEditorImpl::DisplayRemainingTimeL - Entry" );
+
+ HBufC* stringHolder( NULL );
+
+ TTime currentTime;
+ currentTime.HomeTime();
+
+ TTime alarmTime = iAlarmInfo.iOrigExpiryTime;
+ TBool oneDayDifference( EFalse );
+
+ // Check for the day of the alarm.
+ if( currentTime < alarmTime )
+ {
+ currentTime += TTimeIntervalDays( 1 );
+ // Check if the alarm is for the current day.
+ oneDayDifference = ( currentTime < alarmTime )? ETrue : EFalse;
+ }
+
+ TInt alarmDay( alarmTime.DayNoInWeek() );
+ const TInt KTimeStringLength( 10 );
+ TBuf< KTimeStringLength > timeString;
+
+ HBufC* timeFormat = StringLoader::LoadLC( R_QTN_TIME_USUAL_WITH_ZERO, iCoeEnv );
+ CleanupStack::Pop( timeFormat );
+
+ alarmTime.FormatL( timeString, *timeFormat );
+
+ CDesCArrayFlat* stringArray = new( ELeave ) CDesCArrayFlat( 2 );
+ CDesCArrayFlat* workDaysList = iCoeEnv->ReadDesCArrayResourceL( R_CLOCK_WEEK_DAYS_ARRAY );
+
+ // The day on which alarm is set.
+ stringArray->AppendL( ( *workDaysList )[ alarmDay ] );
+ // The time string.
+ stringArray->AppendL( timeString );
+
+ // Choose the appropriate Repeat type.
+ switch( iAlarmInfo.iRepeat )
+ {
+ case EAlarmRepeatDefintionRepeatNext24Hours:
+ case EAlarmRepeatDefintionRepeatOnce:
+ {
+ if( oneDayDifference )
+ {
+ stringHolder = StringLoader::LoadLC( R_QTN_CLOCK_ALARM_NOTE_ONCE_NEXT, *stringArray, iEikonEnv );
+ }
+ }
+ break;
+
+ case EAlarmRepeatDefintionRepeatDaily:
+ {
+ stringHolder = StringLoader::LoadLC( R_QTN_CLOCK_ALARM_NOTE_DAY_CLK, timeString, iEikonEnv );
+ }
+ break;
+
+ case EAlarmRepeatDefintionRepeatWeekly:
+ {
+ stringHolder = StringLoader::LoadLC( R_QTN_CLOCK_ALARM_NOTE_WEEK_CLK, *stringArray, iEikonEnv );
+ }
+ break;
+
+ case EAlarmRepeatDefintionRepeatWorkday:
+ {
+ stringHolder = StringLoader::LoadLC( R_QTN_CLOCK_ALARM_NOTE_WDAY_CLK, timeString, iEikonEnv );
+ }
+ break;
+
+ default:
+ {
+ // No implementation yet.
+ }
+ break;
+ }
+
+ // Cleanup.
+ delete timeFormat;
+ delete stringArray;
+ delete workDaysList;
+
+ // Need to show the confirmation note.
+ if( ( EAlarmStatusEnabled == iAlarmInfo.iStatus ) && stringHolder )
+ {
+ // TODO: to be verified todo this or not.
+ CAknConfirmationNote* confirmationNote = new( ELeave ) CAknConfirmationNote( ETrue );
+
+ TPtr stringHolderPtr = stringHolder->Des();
+ AknTextUtils::DisplayTextLanguageSpecificNumberConversion( stringHolderPtr );
+
+ confirmationNote->ExecuteLD( *stringHolder );
+
+ // Cleanup
+ CleanupStack::PopAndDestroy( stringHolder );
+ }
+
+ // Dislpay the second note.
+ if( !oneDayDifference )
+ {
+ TTime homeTime;
+ homeTime.HomeTime();
+
+ TDateTime currentDate( homeTime.DateTime() );
+ TDateTime alarmDate( iAlarmInfo.iAlarmTime.DateTime() );
+
+ alarmDate.SetYear( currentDate.Year() );
+ alarmDate.SetMonth( currentDate.Month() );
+ alarmDate.SetDay( currentDate.Day() );
+
+ TTime newAlarmTime( alarmDate );
+
+ if( newAlarmTime < homeTime )
+ {
+ newAlarmTime += TTimeIntervalDays( 1 );
+ }
+
+ // Construct the remaining time.
+ TTimeIntervalMicroSeconds remainingTime( newAlarmTime.MicroSecondsFrom( homeTime ) );
+ TInt64 tempInt = ( remainingTime.Int64() ) / KOneMinuteInMicrosecond;
+ TInt remainingMinutes = I64INT( tempInt );
+
+ CArrayFix< TInt >* timeArray = new( ELeave ) CArrayFixFlat< TInt >( 2 );
+ CleanupStack::PushL( timeArray );
+
+ TInt remainingHours( remainingMinutes / KOneHourInMinute );
+
+ remainingMinutes -= remainingHours * KOneHourInMinute;
+
+ timeArray->AppendL( remainingHours );
+ timeArray->AppendL( remainingMinutes );
+
+ // Alarm is with in 1 day. Choose the appropriate strings to be displayed.
+ switch( remainingHours )
+ {
+ case KOneMinute:
+ {
+ if( KOneMinute == remainingMinutes )
+ {
+ stringHolder = StringLoader::LoadLC( R_CLOCK_ALARM_CONF_SINGULAR, *timeArray, iEikonEnv );
+ }
+ else
+ {
+ stringHolder = StringLoader::LoadLC( R_CLOCK_ALARM_CONF_HOUR_SEV_MIN, *timeArray, iEikonEnv );
+ }
+ }
+ break;
+
+ default:
+ {
+ if( KOneMinute == remainingMinutes )
+ {
+ stringHolder = StringLoader::LoadLC( R_CLOCK_ALARM_CONF_SEV_HOURS_MIN, *timeArray, iEikonEnv );
+ }
+ else
+ {
+ stringHolder = StringLoader::LoadLC( R_CLOCK_ALARM_CONF_PLURAL, *timeArray, iEikonEnv );
+ }
+ }
+ break;
+ }
+
+ // TODO: to be verified todo this or not.
+ if( ( EAlarmStatusEnabled == iAlarmInfo.iStatus ) && stringHolder )
+ {
+ CAknConfirmationNote* confirmationNote = new( ELeave ) CAknConfirmationNote( ETrue );
+
+ TPtr stringHolderPtr = stringHolder->Des();
+ AknTextUtils::DisplayTextLanguageSpecificNumberConversion( stringHolderPtr );
+
+ confirmationNote->ExecuteLD( *stringHolder );
+ }
+
+ // Cleanup.
+ CleanupStack::PopAndDestroy( stringHolder );
+ CleanupStack::PopAndDestroy( timeArray );
+ }
+
+ __PRINTS( "CClockAlarmEditorImpl::DisplayRemainingTimeL - Exit" );
+ }
+
+// ---------------------------------------------------------
+// CClockAlarmEditorImpl::CheckForDstChangesL
+// rest of the details are commented in the header
+// ---------------------------------------------------------
+//
+TBool CClockMainView::CheckForDstChangesL()
+ {
+ __PRINTS( "CClockAlarmEditorImpl::CheckForDstChangesL - Entry" );
+
+ // User to be notified whether DST rollover happens in a day or
+ // has happen within a day if he tries to change the time.
+ TBool returnValue( ETrue );
+
+ // Establish connection with RTz to get the timezone ID
+ RTz tzHandle;
+ User::LeaveIfError( tzHandle.Connect() );
+ CleanupClosePushL( tzHandle );
+
+ // The timezone ID (current)
+ CTzId* currentTZId = tzHandle.GetTimeZoneIdL();
+ CleanupStack::PushL( currentTZId );
+
+ // The current time in UTC
+ TTime currentTime;
+ currentTime.UniversalTime();
+
+ // hometime (local time)
+ TTime homeTime;
+ homeTime.HomeTime();
+
+ //(Year, Month, Day, Hour, Minute, Second, Micrsecond)
+ TDateTime dateTime( homeTime.DateTime().Year(), EJanuary, 1, FALSE, FALSE, FALSE, FALSE );
+
+ TTime tempTime( dateTime );
+
+ // Get the current rules for the timezone
+ CTzRules* currentRules = tzHandle.GetTimeZoneRulesL( *currentTZId, tempTime, currentTime, ETzUtcTimeReference );
+ CleanupStack::PushL( currentRules );
+
+ // CVTzActualisedRules encapsulates the rules for a specific year.
+ // Every year has a dummy rule and further DST rules if DST is applicable (if Ohlson provides them)
+ CVTzActualisedRules *vActualisedRules = CVTzActualisedRules::NewL(
+ homeTime.DateTime().Year(),
+ homeTime.DateTime().Year());
+ CleanupStack::PushL( vActualisedRules );
+
+ // The dummy rule is always the begining of the year.
+ // For example there is only 1 rule for India/NewDelhi but USA/Atlanta has 3 rules.
+ currentRules->GetActualisedRulesL( *vActualisedRules );
+
+ const TInt ruleCount( vActualisedRules->Count() );
+ TInt ruleMatchIndex( KNoDifference );
+
+ TTimeIntervalSeconds secondsDifference;
+ TTime ruleMatchTime;
+
+ // Fetch lowest time offset for the year residing at aTime.
+ // This is used to determine if DST is on.
+ for( TInt ruleIndex( FALSE ); ruleIndex < ruleCount; ++ruleIndex )
+ {
+ const TVTzActualisedRule& actualisedRule = ( *vActualisedRules )[ ruleIndex ];
+
+ // Only check for the same year as requested (aTime)
+ if( actualisedRule.iTimeOfChange.DateTime().Year() == homeTime.DateTime().Year() )
+ {
+ iAlarmInfo.iAlarmTime.SecondsFrom( actualisedRule.iTimeOfChange, secondsDifference );
+ // Considering the time reference is important as America (North & South) uses
+ // the Wall time (local time) reference where as whole of Europe refers to time
+ // in terms of UTC time. Correspondingly, the choise of local time or utc time
+ // has to be made.
+ TTime ruleTime;
+
+ if( ETzUtcTimeReference == actualisedRule.iTimeReference )
+ {
+ ruleTime = currentTime;
+ }
+ else if( ETzWallTimeReference == actualisedRule.iTimeReference )
+ {
+ ruleTime = homeTime;
+ }
+ else if( ETzStdTimeReference == actualisedRule.iTimeReference )
+ {
+ // TODO: Testing so far hasn't encountered a rule in this time reference.
+ // If in case an error is found, corresponding code can be added here.
+ // No support from symbian for this.
+ }
+
+ TDateTime sevenDays( FALSE, EJanuary, KDaysInWeek, FALSE, FALSE, FALSE, FALSE );
+ TTime tempTime( sevenDays );
+ TTime newTime( ruleTime.Int64() + tempTime.Int64() );
+
+ TTimeIntervalDays temp;
+ temp = newTime.DaysFrom( ruleTime );
+
+ if( ( secondsDifference.Int() >= KNoDifference ) &&
+ ( newTime > iAlarmInfo.iAlarmTime ) &&
+ ( actualisedRule.iTimeOfChange < iAlarmInfo.iAlarmTime ) &&
+ ( ruleTime < actualisedRule.iTimeOfChange ) )
+ {
+ // If there is a match, save the index and break.
+ // We've got the rule and there's no need to continue with other rules.
+ ruleMatchIndex = ruleIndex;
+ ruleMatchTime = actualisedRule.iTimeOfChange;
+ break;
+ }
+ }
+ }
+
+ if( ruleMatchIndex > KZerothRule )
+ {
+ // There's a match, display the information note about DST change.
+ TTime displayTime;
+ TTimeIntervalHours oneHour( KOneHour );
+
+ displayTime = iAlarmInfo.iAlarmTime;
+
+ TBuf< KMaxCharsInNote > dateTimeString;
+
+ // dateString will have "11:59 pm" - as above, but no seconds
+ displayTime.FormatL( dateTimeString, KDateTimeFormatter );
+
+ // If This note is displayed,
+ CAknInformationNote* informationNote = new( ELeave ) CAknInformationNote( ETrue );
+
+ HBufC* noteText = StringLoader::LoadLC(
+ R_QTN_CLOCK_NOTE_ALARM_DST_ROLLOVER,
+ dateTimeString,
+ iCoeEnv);
+ TInt error = informationNote->ExecuteLD( noteText->Des() );
+
+ // Don't display the second note. Not necessary to show both notes.
+ returnValue = ETrue;
+ CleanupStack::PopAndDestroy( noteText );
+ }
+
+ tzHandle.Close();
+ CleanupStack::PopAndDestroy( vActualisedRules);
+ CleanupStack::PopAndDestroy( currentRules );
+ CleanupStack::PopAndDestroy( currentTZId );
+ CleanupStack::PopAndDestroy( &tzHandle );
+
+ __PRINTS( "CClockAlarmEditorImpl::CheckForDstChangesL - Exit" );
+
+ return returnValue;
+ }
+
// End of file