diff -r 000000000000 -r f979ecb2b13e clock2/clockui/uilayer/clockworldview/src/clockworldarray.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/clock2/clockui/uilayer/clockworldview/src/clockworldarray.cpp Tue Feb 02 10:12:19 2010 +0200 @@ -0,0 +1,977 @@ +/* +* Copyright (c) 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: This is the source file for the CClockWorldArray class. +* +*/ + +// System includes +#include +#include +#include +#include +#include +#include + +// User includes +#include "clockworldarray.h" +#include "clock_debug.h" +#include "clockworldthumbnailprovider.h" +#include "clockworlditemprocessor.h" + +// Constants +const TInt KTimeFieldLength( 14 ); +const TInt KThreeSepTwoNums( 5 ); +const TInt KAdditionalLength( 2 ); +const TInt KHourMinuteFieldLength( 10 ); +const TInt KListGranularity( 15 ); +const TInt KHomeCityImageIndex( 0 ); +const TInt KImageIndex( 1 ); +const TInt KDstIconIndex( 2 ); +const TInt KBlankIcon( 3 ); +const TInt KZerothRule( 0 ); +const TInt KDayFieldLength( 4 ); +const TInt KShortDayNames[] = + { + R_QTN_WEEK_TWO_CHARS_MO, + R_QTN_WEEK_TWO_CHARS_TU, + R_QTN_WEEK_TWO_CHARS_WE, + R_QTN_WEEK_TWO_CHARS_TH, + R_QTN_WEEK_TWO_CHARS_FR, + R_QTN_WEEK_TWO_CHARS_SA, + R_QTN_WEEK_TWO_CHARS_SU + }; + +// Literals +_LIT( KDummyTime, "00:00 AM" ); +_LIT( KFieldSeparator, "\t" ); +_LIT( KPadFormat,"%-2S%S%-8S%S" ); +_LIT( KSeparatorOne,"\t2" ); +_LIT( KDummyDay, "Tu" ); + +// --------------------------------------------------------- +// CClockWorldArray::NewL +// rest of the details are commented in the header +// --------------------------------------------------------- +// +CClockWorldArray* CClockWorldArray::NewL( CArrayPakFlat< TCityInfo >* aArray, CEikonEnv* aEnv ) + { + __PRINTS( "CClockWorldArray::NewL - Entry" ); + + CClockWorldArray* self = new( ELeave ) CClockWorldArray; + CleanupStack::PushL( self ); + + self->ConstructL( aArray, aEnv ); + + CleanupStack::Pop( self ); + + __PRINTS( "CClockWorldArray::NewL - Exit" ); + + return self; + } + +// --------------------------------------------------------- +// CClockWorldArray::~CClockWorldArray +// rest of the details are commented in the header +// --------------------------------------------------------- +// +CClockWorldArray::~CClockWorldArray() + { + __PRINTS( "CClockWorldArray::~CClockWorldArray - Entry" ); + + if( iListData ) + { + iListData->ResetAndDestroy(); + delete iListData; + iListData = NULL; + } + if( iThumbnailProvider ) + { + delete iThumbnailProvider; + iThumbnailProvider = NULL; + } + + __PRINTS( "CClockWorldArray::~CClockWorldArray - Exit" ); + } + +// --------------------------------------------------------- +// CClockWorldArray::MdcaCount +// rest of the details are commented in the header +// --------------------------------------------------------- +// +TInt CClockWorldArray::MdcaCount() const + { + __PRINTS( "CClockWorldArray::MdcaCount - Entry" ); + + __PRINTS( "CClockWorldArray::MdcaCount - Exit" ); + + return iListData->Count(); + } + +// --------------------------------------------------------- +// CClockWorldArray::MdcaPoint +// rest of the details are commented in the header +// --------------------------------------------------------- +// +TPtrC16 CClockWorldArray::MdcaPoint( TInt aIndex ) const + { + __PRINTS( "CClockWorldArray::MdcaPoint - Entry" ); + + // If not within range, then return. + if( ( FALSE > aIndex ) || ( aIndex >= iListData->Count() ) ) + { + __PRINTS( "CClockWorldArray::MdcaPoint - Exit" ); + + return NULL; + } + + __PRINTS( "CClockWorldArray::MdcaPoint - Exit" ); + + return *( *iListData )[ aIndex ]; + } + +// --------------------------------------------------------- +// CClockWorldArray::AddCityL +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockWorldArray::AddCityL( TCityInfo aCityInfo ) + { + __PRINTS( "CClockWorldArray::AddCityL - Entry" ); + + // First construct the heap buffer to hold the item text. + HBufC* cityItem( NULL ); + + // The formatting for the list item is: KThreeSepOneNum = "\t \t \t xx", + // where xx = Number for icon and '\t' = Separator. + TInt stringLength( KDayFieldLength + + KTimeFieldLength + + aCityInfo.iCity.Length() + + aCityInfo.iCountry.Length() + + KThreeSepTwoNums ); + + cityItem = HBufC::NewLC( stringLength + KAdditionalLength ); + + // Now modify the contents. + TPtr cityItemPtr = cityItem->Des(); + + // First the image. + cityItemPtr.AppendNum( KImageIndex ); + // Go to the next item. + cityItemPtr.Append( KFieldSeparator ); + // Now append Day. + cityItemPtr.Append( KDummyDay ); + // Append a space. + cityItemPtr.Append( KSingleSpace ); + // Now append Time. + cityItemPtr.Append( KDummyTime ); + // Append a space. + cityItemPtr.Append( KSingleSpace ); + // Go to the next item. + cityItemPtr.Append( KFieldSeparator ); + // The country. + cityItemPtr.Append( aCityInfo.iCity ); + // Go to the next item. + cityItemPtr.Append( KSeparatorComma ); + // Append a space. + cityItemPtr.Append( KSingleSpace ); + // The city. + cityItemPtr.Append( aCityInfo.iCountry ); + + // Update the member variables. + iListData->AppendL( cityItem ); + iCityArray->AppendL( aCityInfo, sizeof( aCityInfo ) ); + + // Cleanup. + CleanupStack::Pop( cityItem ); + + UpdateTimeEntryList(); + + __PRINTS( "CClockWorldArray::AddCityL - Exit" ); + } + +// --------------------------------------------------------- +// CClockWorldArray::RemoveCity +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockWorldArray::RemoveCity( TInt aIndex ) + { + __PRINTS( "CClockWorldArray::RemoveCityRemoveCity - Entry" ); + + // If not within range, then return. + if( ( FALSE > aIndex ) || ( aIndex > iListData->Count() ) ) + { + __PRINTS( "CClockWorldArray::NewL - Entry" ); + + return; + } + + // Pointer to the item at aIndex. + HBufC* tempHeapBuf( ( *iListData )[ aIndex ] ); + + iListData->Delete( aIndex ); + iCityArray->Delete( aIndex ); + + // Cleanup. + if( tempHeapBuf ) + { + delete tempHeapBuf; + } + + __PRINTS( "CClockWorldArray::RemoveCity - Exit" ); + } + +// --------------------------------------------------------- +// CClockWorldArray::GetCity +// rest of the details are commented in the header +// --------------------------------------------------------- +// +const TCityInfo& CClockWorldArray::GetCity( TInt aIndex ) + { + __PRINTS( "CClockWorldArray::GetCity - Entry" ); + + __PRINTS( "CClockWorldArray::GetCity - Exit" ); + + return ( *iCityArray )[ aIndex ]; + } + +// --------------------------------------------------------- +// CClockWorldArray::GetListBoxIndex +// rest of the details are commented in the header +// --------------------------------------------------------- +// +TInt CClockWorldArray::GetListBoxIndex( TCityInfo aCityInfo ) + { + __PRINTS( "CClockWorldArray::GetListBoxIndex - Entry" ); + + TInt cityIndex( KErrNotFound ); + TCityInfo cityInfo; + _LIT( KEmptyText, "" ); + + // Check if the name of the city is empty. If empty, shouldn't be added to the list. + if( !aCityInfo.iCity.Compare( KEmptyText ) || !aCityInfo.iCountry.Compare( KEmptyText ) ) + { + __PRINTS( "CClockWorldArray::GetListBoxIndex - Exit" ); + + return KErrNone; + } + + // Else, we search for the city and return the index. + for( TInt index( FALSE ); index < iCityArray->Count(); index++ ) + { + cityInfo = ( *iCityArray )[ index ]; + if( KErrNone != cityInfo.iCountry.Compare( aCityInfo.iCountry ) ) + { + continue; + } + else if( KErrNone == cityInfo.iCity.Compare( aCityInfo.iCity ) ) + { + cityIndex = index; + break; + } + } + + __PRINTS( "CClockWorldArray::GetListBoxIndex - Exit" ); + + return cityIndex; + } + +// --------------------------------------------------------- +// CClockWorldArray::UpdateImageInListItem +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockWorldArray::UpdateImageInListItem( TInt aImageIndex, TInt aListIndex, TPtrC aFileName ) + { + __PRINTS( "CClockWorldArray::UpdateImageInListItem - Entry" ); + + TBuf16< 4 > newImageIndex; + newImageIndex.AppendNum( aImageIndex ); + newImageIndex.Append( KFieldSeparator ); + + // Pointer to the item text. + HBufC* tempHeapBuf = ( *iListData )[ aListIndex ]; + + TInt separatorPosition( tempHeapBuf->Find( KFieldSeparator ) ); + + // Delete the old image index. + if( FALSE < separatorPosition ) + { + tempHeapBuf->Des().Delete( KZerothIndex, separatorPosition + 1 ); + } + + // Insert the new imageIndex and fiels separtor. + tempHeapBuf->Des().Insert( KZerothIndex, newImageIndex ); + + // Update the image path in the TCityInfo object + ( *iCityArray )[ aListIndex ].iImagePath.Copy( aFileName ); + + __PRINTS( "CClockWorldArray::UpdateImageInListItem - Exit" ); + } + +// --------------------------------------------------------- +// CClockWorldArray::CheckIfImageLoaded +// rest of the details are commented in the header +// --------------------------------------------------------- +// +TInt CClockWorldArray::CheckIfImageLoaded( TPtrC aFileName, TInt aListItemIndex ) + { + __PRINTS( "CClockWorldArray::CheckIfImageLoaded - Entry" ); + + TInt returnValue ( KErrNotFound ); + + // Check whether input fileName matches with the image path for each listitem + // Return the image index in case a match is found or KErrNotFound in case of no match found. + for( TInt index( FALSE ); index < MdcaCount(); index++ ) + { + if(!( ( *iCityArray )[ index ].iImagePath.Compare( aFileName ) ) ) + { + HBufC* tempHeapBuf = ( *iListData )[ index ]; + + TInt appendIndex ( GetImageIndex( index ) ); + + // Check and return the appended Index if it is not the default image + if( ( KImageIndex != appendIndex ) && ( index != aListItemIndex ) ) + { + returnValue = appendIndex; + break; + } + } + } + + __PRINTS( "CClockWorldArray::CheckIfImageLoaded - Exit" ); + + return returnValue; + } + +// --------------------------------------------------------- +// CClockWorldArray::GetImageIndex +// rest of the details are commented in the header +// --------------------------------------------------------- +// +TInt CClockWorldArray::GetImageIndex( TInt aListItem ) + { + __PRINTS( "CClockWorldArray::GetImageIndex - Entry" ); + + // Get the list data for the fiven listitem + TInt imageIndex ( KErrNone ); + HBufC* tempHeapBuf = ( *iListData )[ aListItem ]; + + // Parse the string to extract a first signed 8-bit integer which is the image index. + TLex tempString( tempHeapBuf->Des() ); + tempString.Val( imageIndex ); + + __PRINTS( "CClockWorldArray::GetImageIndex - Exit" ); + + return imageIndex; + } + +// --------------------------------------------------------- +// CClockWorldArray::InsertHomeCityItem +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockWorldArray::InsertHomeCityItem() + { + __PRINTS( "CClockWorldArray::InsertHomeCityItem - Entry" ); + + TCityInfo cityInfo; + + // Here first we append the home city by default. + // TODO: The case when automatic time update is On needs to be discussed. + RTz tzHandle; + User::LeaveIfError( tzHandle.Connect() ); + + // Get the timezone id. + CTzId* currentTimeZoneId = tzHandle.GetTimeZoneIdL(); + CleanupStack::PushL( currentTimeZoneId ); + + // Construct CTzLocalizer object to get the timezone from the id. + CTzLocalizer* tzLocalizer( NULL ); + TRAPD( errorVal, tzLocalizer = CTzLocalizer::NewL() ); + + CTzLocalizedTimeZone* localizedTimeZone( NULL ); + + if( KErrNone == errorVal ) + { + CleanupStack::PushL( tzLocalizer ); + + // Get the current localized zone. + TRAPD( errorVal, localizedTimeZone = tzLocalizer->GetLocalizedTimeZoneL( currentTimeZoneId->TimeZoneNumericID() ) ); + + if( localizedTimeZone && ( KErrNone == errorVal ) ) + { + CleanupStack::PushL( localizedTimeZone ); + + // Get the frequently used localized city. + CTzLocalizedCity* localizedCity = tzLocalizer->GetFrequentlyUsedZoneCityL( CTzLocalizedTimeZone::ECurrentZone ); + CleanupStack::PushL( localizedCity ); + + // Get all the city groups. + CTzLocalizedCityGroupArray* cityGroupArray = tzLocalizer->GetAllCityGroupsL( CTzLocalizer::ETzAlphaNameAscending ); + CleanupStack::PushL( cityGroupArray ); + + // Get the index of the country corresponding to the city group ID. + TInt countryIndex( 1 ); + + for( TInt index( KErrNone ); index < cityGroupArray->Count(); index++ ) + { + if( localizedCity->GroupId() == cityGroupArray->At( index ).Id() ) + { + countryIndex = index; + } + } + + // Get all the cities within the currently set country. + CTzLocalizedCityArray* cityList = tzLocalizer->GetCitiesInGroupL( ( cityGroupArray->At( countryIndex ) ).Id(), + CTzLocalizer::ETzUnsorted ); + CleanupStack::PushL( cityList ); + + // Construct the city information. + cityInfo.iCity = localizedCity->Name(); + cityInfo.iCountry = cityGroupArray->At( countryIndex ).Name(); + cityInfo.iTimeZoneId = localizedCity->TimeZoneId(); + + // Get the timezone offset for the timezone id. + RArray< TInt > tzId; + RArray< TInt > zoneOffset; + + tzId.Append( cityInfo.iTimeZoneId ); + tzHandle.GetOffsetsForTimeZoneIdsL( tzId, zoneOffset ); + + cityInfo.iUtcOffset = zoneOffset[ KZerothIndex ]; + + // Cleanup. + tzId.Close(); + zoneOffset.Close(); + + // The city group id. + cityInfo.iCityGroupId = localizedCity->GroupId(); + + TInt selectedIndex( KErrNotFound ); + for( TInt index( KZerothIndex ); index < cityList->Count(); index++ ) + { + if( KErrNone == ( cityList->At( index ) ).Name().Compare( localizedCity->Name() ) ) + { + selectedIndex = index; + break; + } + } + + // Finally the city offset in the city group. + cityInfo.iCityOffsetInGroup = selectedIndex; + + // Insert the item at the begining of the list. + TInt stringLength( KDayFieldLength + + KTimeFieldLength + + cityInfo.iCity.Length() + + cityInfo.iCountry.Length() + + KThreeSepTwoNums ); + + // Allocate memory for the item. + HBufC* cityItem = HBufC::NewLC( stringLength + KAdditionalLength ); + TPtr cityItemPtr( cityItem->Des() ); + + // Update the data in the array. + cityItemPtr.AppendNum( KHomeCityImageIndex ); + cityItemPtr.Append( KFieldSeparator ); + cityItemPtr.Append( KDummyDay ); + cityItemPtr.Append( KSingleSpace ); + cityItemPtr.Append( KDummyTime ); + cityItemPtr.Append( KSingleSpace ); + cityItemPtr.Append( KFieldSeparator ); + cityItemPtr.Append( cityInfo.iCity ); + cityItemPtr.Append( KSeparatorComma ); + cityItemPtr.Append( KSingleSpace ); + cityItemPtr.Append( cityInfo.iCountry ); + + // Here we check if it is already in the list. If so, we need to delete the one present + // and insert the home city at the top of the list. + TInt itemIndex( GetListBoxIndex( cityInfo ) ); + + if( KErrNotFound != itemIndex ) + { + // Remove the city at that index. + RemoveCity( itemIndex ); + } + + // If we already have 15 cities in the list, + // We delete the last item from the list. + if( KMaxCitiesInList == iListData->Count() ) + { + // Delete the last item. + RemoveCity( iListData->Count() - 1 ); + } + + // Insert the same at the top of the list. + iListData->InsertL( KZerothIndex, cityItem ); + iCityArray->InsertL( KZerothIndex, cityInfo, sizeof( cityInfo ) ); + + // Cleanup. + CleanupStack::Pop( cityItem ); + CleanupStack::PopAndDestroy( cityList ); + CleanupStack::PopAndDestroy( cityGroupArray ); + CleanupStack::PopAndDestroy( localizedCity ); + CleanupStack::PopAndDestroy( localizedTimeZone ); + } + + // Cleanup. + CleanupStack::PopAndDestroy( tzLocalizer ); + } + + // Cleanup. + tzHandle.Close(); + CleanupStack::PopAndDestroy( currentTimeZoneId ); + + __PRINTS( "CClockWorldArray::InsertHomeCityItem - Exit" ); + } + +// --------------------------------------------------------- +// CClockWorldArray::InsertOldHomeCityItem +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockWorldArray::InsertOldHomeCityItem( TCityInfo aCityInfo, TInt aIndex ) + { + __PRINTS( "CClockWorldArray::InsertOldHomeCityItem - Entry" ); + + // Insert the item at the begining of the list. + TInt stringLength( KDayFieldLength + + KTimeFieldLength + + aCityInfo.iCity.Length() + + aCityInfo.iCountry.Length() + + KThreeSepTwoNums ); + + // Allocate memory for the item. + HBufC* cityItem = HBufC::NewLC( stringLength + KAdditionalLength ); + TPtr cityItemPtr( cityItem->Des() ); + + // Update the data in the array. + cityItemPtr.AppendNum( KImageIndex ); + cityItemPtr.Append( KFieldSeparator ); + cityItemPtr.Append( KDummyDay ); + cityItemPtr.Append( KSingleSpace ); + cityItemPtr.Append( KDummyTime ); + cityItemPtr.Append( KSingleSpace ); + cityItemPtr.Append( KFieldSeparator ); + cityItemPtr.Append( aCityInfo.iCity ); + cityItemPtr.Append( KSeparatorComma ); + cityItemPtr.Append( KSingleSpace ); + cityItemPtr.Append( aCityInfo.iCountry ); + + iListData->InsertL( aIndex, cityItem ); + iCityArray->InsertL( aIndex, aCityInfo, sizeof( aCityInfo ) ); + + // Cleanup. + CleanupStack::Pop( cityItem ); + + __PRINTS( "CClockWorldArray::InsertOldHomeCityItem - Exit" ); + } + +// --------------------------------------------------------- +// CClockWorldArray::SetThumbnail +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockWorldArray::SetThumbnail( CFbsBitmap* aBitmap, TInt aThumbnailRequestId ) + { + __PRINTS( "CClockWorldArray::SetThumbnail - Entry" ); + + if( aBitmap ) + { + TCityInfo cityInfo; + + // Match the thumbnail request-id sent by the callback function with the ones set for any of the listitems. + for( TInt index( FALSE ); index < iCityArray->Count(); index++ ) + { + cityInfo= iCityArray->At( index ); + + if( aThumbnailRequestId == cityInfo.iThumbnailRequestId ) + { + // Set the thumbnail bitmap. + iCityArray->At( index ).iThumbnailBitmap = aBitmap; + + // Set request id to KErrNotFound as operation is complete. + iCityArray->At( index ).iThumbnailRequestId = KErrNotFound; + + //Process the listitem to display the set thumbnail. + if( iItemProcessor ) + { + iItemProcessor->ProcessEachItem( index ); + } + break; + } + } + } + + __PRINTS( "CClockWorldArray::SetThumbnail - Exit" ); + } + +// --------------------------------------------------------- +// CClockWorldArray::GetThumbnailL +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockWorldArray::GetThumbnailL( TPtrC aFileName, TInt aIndex ) + { + __PRINTS( "CClockWorldArray::GetThumbnailL - Entry" ); + + // Request for thumbnail for the given image. + TInt requestId( iThumbnailProvider->GetThumbnailL( aFileName ) ); + + //Store the request id. + iCityArray->At( aIndex ).iThumbnailRequestId = requestId; + + __PRINTS( "CClockWorldArray::GetThumbnailL - Exit" ); + } + +// --------------------------------------------------------- +// CClockWorldArray::DeleteThumbnail +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockWorldArray::DeleteThumbnailL( TPtrC aFileName ) + { + __PRINTS( "CClockWorldArray::DeleteThumbnail - Entry" ); + + // Request for thumbnail for the given image. + iThumbnailProvider->DeleteThumbnailL( aFileName ); + + __PRINTS( "CClockWorldArray::DeleteThumbnailL - Exit" ); + } + +// --------------------------------------------------------- +// CClockWorldArray::SetItemProcessor +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockWorldArray::SetItemProcessor( CClockWorldItemProcessor* aItemProcessor ) + { + __PRINTS( "CClockWorldArray::SetItemProcessor - Entry" ); + + iItemProcessor = aItemProcessor; + + __PRINTS( "CClockWorldArray::SetItemProcessor - Exit" ); + } + +// --------------------------------------------------------- +// CClockWorldArray::UpdateTimeEntry +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockWorldArray::UpdateTimeEntry( TInt aIndex ) + { + __PRINTS( "CClockWorldArray::UpdateTimeEntry - Entry" ); + + TTime universalTime; + universalTime.UniversalTime(); + + // Check if Dst is applicable in the city. + TBool dstApplicable( EFalse ); + TRAP_IGNORE( dstApplicable = IsDstOnL( aIndex ) ); + + // The dst offset to be added if DST is applicable. + TInt32 dstOffset( KErrNotFound ); + + // Construct the Local time. + if( dstApplicable ) + { + CTzId* timeZoneId = CTzId::NewL( (*iCityArray )[ aIndex ].iTimeZoneId ); + CleanupStack::PushL( timeZoneId ); + TRAP_IGNORE( GetOffSetWithDstL( dstOffset, *timeZoneId ) ) ; + + if( ( FALSE <= aIndex ) && ( aIndex < iCityArray->Count() ) ) + { + universalTime += TTimeIntervalMinutes( dstOffset ); + } + CleanupStack::PopAndDestroy( timeZoneId ); + } + else + { + if( ( FALSE <= aIndex ) && ( aIndex < iCityArray->Count() ) ) + { + universalTime += TTimeIntervalMinutes( ( *iCityArray )[ aIndex ].iUtcOffset ); + } + } + + TBuf< KHourMinuteFieldLength > timeString; + TBuf< KTimeFieldLength > clockString; + TBuf< KDayFieldLength > dayString; + + // Pointer to the item text. + HBufC* tempHeapBuf = ( *iListData )[ aIndex ]; + + // The timestring formatter. + HBufC* formatString( NULL ); + TRAP_IGNORE( + formatString = StringLoader::LoadL( R_QTN_TIME_USUAL_WITH_ZERO, iEnv ); + universalTime.FormatL( timeString, *formatString ); ); + + // Construct the day item. + TInt dayNumber = universalTime.DayNoInWeek(); + + // Construct the Day string + HBufC* dayStringBuffer( NULL ); + TRAP_IGNORE( dayStringBuffer = StringLoader::LoadL( KShortDayNames[ dayNumber ], iEnv ); ); + dayString = dayStringBuffer->Des(); + + // For Mirrored languages. + AknTextUtils::LanguageSpecificNumberConversion( timeString ); + + clockString.Format( KPadFormat, &dayString, &KSingleSpace, &timeString, &KSingleSpace ); + + TInt separatorPosition( tempHeapBuf->Find( KFieldSeparator ) ); + tempHeapBuf->Des().Replace( separatorPosition + 1, clockString.Length(), clockString ); + + if( dstApplicable ) + { + TInt iconFound( tempHeapBuf->Des().Find( KSeparatorOne ) ); + if( KErrNotFound == iconFound ) + { + tempHeapBuf->Des().Append( KFieldSeparator ); + tempHeapBuf->Des().AppendNum( KDstIconIndex ); + } + } + else + { + TInt iconPosition( tempHeapBuf->Find( KSeparatorOne ) ); + + if( FALSE < iconPosition ) + { + tempHeapBuf->Des().Delete( iconPosition, KBlankIcon ); + } + } + // Cleanup. + delete formatString; + delete dayStringBuffer; + + __PRINTS( "CClockWorldArray::UpdateTimeEntry - Exit" ); + } + +// --------------------------------------------------------- +// CClockWorldArray::UpdateTimeEntryList +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockWorldArray::UpdateTimeEntryList() + { + __PRINTS( "CClockWorldArray::UpdateTimeEntryList - Entry" ); + + if ( !iListData ) + { + return; + } + for ( TInt i = 0; i < iListData->Count(); i++ ) + { + UpdateTimeEntry( i ); + } + + __PRINTS( "CClockWorldArray::UpdateTimeEntryList - Exit" ); + } + +// --------------------------------------------------------- +// CClockWorldArray::CClockWorldArray +// rest of the details are commented in the header +// --------------------------------------------------------- +// +CClockWorldArray::CClockWorldArray() + { + __PRINTS( "CClockWorldArray::CClockWorldArray - Entry" ); + + // No implementation yet. + + __PRINTS( "CClockWorldArray::CClockWorldArray - Exit" ); + } + +// --------------------------------------------------------- +// CClockWorldArray::ConstructL +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockWorldArray::ConstructL( CArrayPakFlat< TCityInfo >* aArray, CEikonEnv* aEnv ) + { + __PRINTS( "CClockWorldArray::ConstructL - Entry" ); + + // Initialize the list data. + iListData = new( ELeave ) CArrayPtrFlat< HBufC >( KListGranularity ); + iCityArray = aArray; + iEnv = aEnv; + + TCityInfo cityInfo; + HBufC* cityItem; + + iThumbnailProvider = CClockWorldThumbnailProvider::NewL( this ); + + // Request the thumbnail for all the listitems ,which have a unique image path,in descending order. + for( TInt index( iCityArray->Count() -1 );index >= 0;index-- ) + { + cityInfo = ( *iCityArray )[ index ]; + if( cityInfo.iImagePath.Compare( KDefaultImagePath ) ) + { + cityInfo.iThumbnailBitmap = NULL; + GetThumbnailL( cityInfo.iImagePath, index ); + } + } + for( TInt index( FALSE ); index < aArray->Count(); index++ ) + { + cityInfo = ( *aArray )[ index ]; + + // KThreeSepOneNum = "\t \t \t xx", where xx = Number for icon and '\t' = Separator. + TInt stringLength( KDayFieldLength + + KTimeFieldLength + + cityInfo.iCity.Length() + + cityInfo.iCountry.Length() + + KThreeSepTwoNums ); + + // Allocate memory for the item. + cityItem = HBufC::NewLC( stringLength + KAdditionalLength ); + TPtr cityptr( cityItem->Des() ); + + // Update the data in the array. + cityptr.AppendNum( KImageIndex ); + cityptr.Append( KFieldSeparator ); + cityptr.Append( KDummyDay ); + cityptr.Append( KSingleSpace ); + cityptr.Append( KDummyTime ); + cityptr.Append( KSingleSpace ); + cityptr.Append( KFieldSeparator ); + cityptr.Append( cityInfo.iCity ); + cityptr.Append( KSeparatorComma ); + cityptr.Append( KSingleSpace ); + cityptr.Append( cityInfo.iCountry ); + + iListData->AppendL( cityItem ); + // Cleanup. + CleanupStack::Pop( cityItem ); + } + + __PRINTS( "CClockWorldArray::ConstructL - Exit" ); + } + +// --------------------------------------------------------- +// CClockWorldArray::IsDstOnL +// rest of the details are commented in the header +// --------------------------------------------------------- +// +TBool CClockWorldArray::IsDstOnL( TInt aIndex ) const + { + __PRINTS( "CClockWorldArray::IsDstOnL - Entry" ); + + TBool dstState( EFalse ); + + if( ( FALSE <= aIndex ) && ( aIndex < iListData->Count() ) ) + { + // Construct a timezone id object. + CTzId* timeZoneId = CTzId::NewL( (*iCityArray )[ aIndex ].iTimeZoneId ); + CleanupStack::PushL( timeZoneId ); + + RTz tzHandle; + // Connect to the timezone server. + User::LeaveIfError( tzHandle.Connect() ); + CleanupClosePushL( tzHandle ); + + // Check for Dst for the timezone id. + dstState = tzHandle.IsDaylightSavingOnL( *timeZoneId ); + + // Cleanup. + CleanupStack::PopAndDestroy( &tzHandle ); + CleanupStack::PopAndDestroy( timeZoneId ); + } + + __PRINTS( "CClockWorldArray::IsDstOnL - Exit" ); + + // Return the state. + return dstState; + } + +// --------------------------------------------------------- +// CClockWorldArray::GetOffSetWithDstL +// rest of the details are commented in the header +// --------------------------------------------------------- +// +void CClockWorldArray::GetOffSetWithDstL( TInt32& aDstOffset, const CTzId& aTzId ) const + { + __PRINTS( "CClockWorldArray::GetOffSetWithDstL - Entry" ); + + RTz tzHandle; + User::LeaveIfError( tzHandle.Connect() ); + CleanupClosePushL( tzHandle ); + + // Local time + TTime homeTime; + homeTime.HomeTime(); + + TDateTime dateTime; + dateTime = homeTime.DateTime(); + + // Get the CTzRules for the current year and for the given time zone id. + CTzRules* tzRules = tzHandle.GetTimeZoneRulesL( aTzId, + dateTime.Year(), + dateTime.Year(), + ETzWallTimeReference ); + CleanupStack::PushL( tzRules ); + + // Get the Actualised rules for the same year. These are the DST rules from which we get the iNewOffset. + CVTzActualisedRules *vActualisedRules = CVTzActualisedRules::NewL( + homeTime.DateTime().Year(), + homeTime.DateTime().Year() ); + CleanupStack::PushL( vActualisedRules ); + tzRules->GetActualisedRulesL( *vActualisedRules ); + + // This way of fetching initial offset is being used rather than tzRules->InitialStdTimeOffset() + // because in some cases, the offset returned is incorrect. (For ex: Argentina and Canada/Iqaluit) + RArray< TInt > timeZones; + RArray< TInt > zoneOffsets; + + // Append the current timezone ID and request for the standard offset + timeZones.Append( aTzId.TimeZoneNumericID() ); + tzHandle.GetOffsetsForTimeZoneIdsL( timeZones, zoneOffsets ); + + // The initial offset or the standard offset (w/o DST) + TInt initialTimeZoneOffset( zoneOffsets[ 0 ] ); + + // Close the resource handles + timeZones.Close(); + zoneOffsets.Close(); + + // The number of actualised rules + TInt ruleCount( vActualisedRules->Count() ); + + for( TInt ruleIndex( KZerothRule ); ruleIndex < ruleCount; ruleIndex++ ) + { + const TVTzActualisedRule& tVTzactRule = ( *vActualisedRules )[ ruleIndex ]; + + // If the standard offset and the new offset do not match then we have a dst offset. + // Technically if a timezone has DST then it can have a max of two offsets. One is the standard which doesn't show the + // DST usage, and the other is the DST offset which is standard offset + the amount of DST + if( initialTimeZoneOffset != tVTzactRule.iNewOffset ) + { + aDstOffset = tVTzactRule.iNewOffset; + CleanupStack::PopAndDestroy( vActualisedRules ); + CleanupStack::PopAndDestroy( tzRules ); + CleanupStack::PopAndDestroy( &tzHandle ); + + __PRINTS( "CClockWorldArray::GetOffSetWithDstL - Exit" ); + + return; + } + } + CleanupStack::PopAndDestroy( vActualisedRules ); + CleanupStack::PopAndDestroy( tzRules ); + CleanupStack::PopAndDestroy( &tzHandle ); + + __PRINTS( "CClockWorldArray::GetOffSetWithDstL - Exit" ); + } + +// End of file