clock2/clockui/uilayer/clockworldview/src/clockworldarray.cpp
changeset 0 f979ecb2b13e
--- /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 <AknUtils.h>
+#include <tz.h>
+#include <avkon.rsg>
+#include <StringLoader.h>
+#include <vtzrules.h>
+#include <tzlocalizer.h>
+
+// 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