clock/clockmw/clocktimezone/src/timezoneclient.cpp
changeset 18 c198609911f9
child 26 a949c2543c15
child 45 b6db4fd4947b
equal deleted inserted replaced
0:f979ecb2b13e 18:c198609911f9
       
     1 /*
       
     2 * Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 * Definition file for the TimeZoneClient class.
       
    16 *
       
    17 */
       
    18 
       
    19 // System includes
       
    20 #include <QList>
       
    21 #include <QStandardItemModel>
       
    22 #include <QDebug>
       
    23 #include <QtAlgorithms>
       
    24 #include <tzlocalizationdatatypes.h>
       
    25 #include <tzlocalizer.h>
       
    26 #include <tz.h>
       
    27 #include <vtzrules.h>
       
    28 
       
    29 // User includes
       
    30 #include "timezoneclient.h"
       
    31 #include "clockcommon.h"
       
    32 #include "debug.h"
       
    33 #include "clockserverclt.h"
       
    34 
       
    35 const int KDaysInWeek(7);
       
    36 const int KZerothRule(0);
       
    37 const int KOneHour(1);
       
    38 const int KNoDifference(0);
       
    39 
       
    40 /*!
       
    41 	\class TimezoneClient
       
    42 
       
    43 	This class is the QObject based client interface for services offered by
       
    44 	tzserver and timezonelocalization.
       
    45  */
       
    46 
       
    47 /*!
       
    48 	Default constructor.
       
    49 
       
    50 	\param parent The parent.
       
    51  */
       
    52 TimezoneClient::TimezoneClient(QObject* parent)
       
    53 :QObject(parent),
       
    54  mTimeUpdateOn(false),
       
    55  mFetchCount(0)
       
    56 {
       
    57 	qDebug("clock: TimezoneClient::TimezoneClient() -->");
       
    58 
       
    59 	TCallBack callback(environmentCallback, this);
       
    60 
       
    61 	mNotifier = CEnvironmentChangeNotifier::NewL(
       
    62 			CActive::EPriorityStandard, callback);
       
    63 	mNotifier->Start();
       
    64 
       
    65 	RClkSrvInterface clkSrvInterface1;
       
    66 	User::LeaveIfError(clkSrvInterface1.Connect());
       
    67 	TBool aUpdate;
       
    68 	clkSrvInterface1.IsAutoTimeUpdateOn(aUpdate);
       
    69 	if(aUpdate){
       
    70 	mTimeUpdateOn = true;
       
    71 	}
       
    72 	else {
       
    73 	mTimeUpdateOn = false;
       
    74 	}
       
    75 	clkSrvInterface1.Close();
       
    76 
       
    77 	mTzLocalizer = CTzLocalizer::NewL();
       
    78 
       
    79 	qDebug("clock: TimezoneClient::TimezoneClient() <--");
       
    80 }
       
    81 
       
    82 /*!
       
    83 	Destructor.
       
    84  */
       
    85 TimezoneClient::~TimezoneClient()
       
    86 {
       
    87 	if (mNotifier) {
       
    88 		mNotifier->Cancel();
       
    89 		delete mNotifier;
       
    90 		mNotifier = 0;
       
    91 	}
       
    92 	if (mWorldClockModel) {
       
    93 		mWorldClockModel->clear();
       
    94 	}
       
    95 	if (mTzLocalizer) {
       
    96 		delete mTzLocalizer;
       
    97 		mTzLocalizer = NULL;
       
    98 	}
       
    99 	if (mTimeZoneIds.count()) {
       
   100 		mTimeZoneIds.clear();
       
   101 	}
       
   102 }
       
   103 
       
   104 /*!
       
   105 	This functions returns a QList of location info which represent all the
       
   106 	cities preset in the device returned by the tz server.
       
   107 
       
   108 	\return QList<LocationInfo> A list of location info objects which contain a
       
   109 			valid cityName, countryName, tz id and city group id. None of the other
       
   110 			data is filled.
       
   111  */
       
   112 QList<LocationInfo> TimezoneClient::getLocations()
       
   113 {
       
   114 	qDebug("clock: TimezoneClient::getLocations() -->");
       
   115 
       
   116 	// This list will contain the info of the cities fetched from tz server.
       
   117 	QList<LocationInfo> infoList;
       
   118 
       
   119 	// Construct the timezone localizer.
       
   120 	CTzLocalizer* localizer = CTzLocalizer::NewL();
       
   121 	CleanupStack::PushL(localizer);
       
   122 
       
   123 	// Get the cities, in alphabetical-ascending sorted order.
       
   124 	CTzLocalizedCityArray* cityArray =
       
   125 			localizer->GetCitiesL(CTzLocalizer::ETzAlphaNameAscending);
       
   126 	ASSERT(cityArray);
       
   127 	CleanupStack::PushL(cityArray);
       
   128 	int cityCount = cityArray->Count();
       
   129 
       
   130 	CTzLocalizedCityGroup* country = 0;
       
   131 	int prevGroupId = -1;
       
   132 	TPtrC countryName;
       
   133 
       
   134 	// Now get the country\city-group of each of the city.
       
   135 	// Print the timezone id and city group id as well.
       
   136 	for (int iter = 0; iter < cityCount; iter++) {
       
   137 		CTzLocalizedCity* localizedCity = &(cityArray->At(iter));
       
   138 		TPtrC cityName(localizedCity->Name());
       
   139 		int tzId(localizedCity->TimeZoneId());
       
   140 
       
   141 		if(-1==mTimeZoneIds.indexOf(tzId)) {
       
   142 			mTimeZoneIds.append(tzId);
       
   143 		}
       
   144 
       
   145 		int cityGroupId(localizedCity->GroupId());
       
   146 
       
   147 		if (cityGroupId != prevGroupId) {
       
   148 			prevGroupId = cityGroupId;
       
   149 
       
   150 			if (country) {
       
   151 				delete country;
       
   152 			}
       
   153 			country = localizer->GetCityGroupL(cityGroupId);
       
   154 			countryName.Set(country->Name());
       
   155 		}
       
   156 
       
   157 		// Now insert that data into the info list.
       
   158 		LocationInfo cityInfo;
       
   159 		cityInfo.cityGroupId = cityGroupId;
       
   160 		cityInfo.timezoneId = tzId;
       
   161 		cityInfo.cityName = QString::fromUtf16(
       
   162 				cityName.Ptr(), cityName.Length());
       
   163 		cityInfo.countryName = QString::fromUtf16(
       
   164 				countryName.Ptr(), countryName.Length());
       
   165 		infoList.append(cityInfo);
       
   166 	}
       
   167 
       
   168 	// Cleanup.
       
   169 	CleanupStack::PopAndDestroy(cityArray);
       
   170 	CleanupStack::PopAndDestroy(localizer);
       
   171 
       
   172 	qDebug("clock: TimezoneClient::getLocations() <--");
       
   173 
       
   174 	return infoList;
       
   175 }
       
   176 
       
   177 bool TimezoneClient::getUtcDstOffsetL(int& dstOffset, const CTzId& timezoneId)
       
   178 {
       
   179 	RTz tzHandle;
       
   180 	User::LeaveIfError(tzHandle.Connect());
       
   181 	CleanupClosePushL(tzHandle);
       
   182 
       
   183 	// Local time.
       
   184 	TTime homeTime;
       
   185 	homeTime.HomeTime();
       
   186 
       
   187 	TDateTime dateTime;
       
   188 	dateTime = homeTime.DateTime();
       
   189 
       
   190 	// Get the CTzRules for the current year and for the given time zone id.
       
   191 	CTzRules* timezoneRules = tzHandle.GetTimeZoneRulesL(
       
   192 			timezoneId, dateTime.Year(), dateTime.Year(), ETzWallTimeReference);
       
   193 	CleanupStack::PushL(timezoneRules);
       
   194 
       
   195 	// Get the Actualised rules for the same year.
       
   196 	// These are the DST rules from which we get the iNewOffset.
       
   197 	CVTzActualisedRules *actualizedRules =
       
   198 			CVTzActualisedRules::NewL(
       
   199 					homeTime.DateTime().Year(), homeTime.DateTime().Year());
       
   200 	CleanupStack::PushL(actualizedRules);
       
   201 	timezoneRules->GetActualisedRulesL(*actualizedRules);
       
   202 
       
   203 	// This way of fetching initial offset is being used rather than
       
   204 	// tzRules->InitialStdTimeOffset() because in some cases,
       
   205 	// the offset returned is incorrect. (For ex: Argentina and Canada/Iqaluit)
       
   206 	RArray<TInt> timeZones;
       
   207 	RArray<TInt> zoneOffsets;
       
   208 
       
   209 	// Append the current timezone ID and request for the standard offset
       
   210 	timeZones.Append(timezoneId.TimeZoneNumericID());
       
   211 	tzHandle.GetOffsetsForTimeZoneIdsL(timeZones, zoneOffsets);
       
   212 
       
   213 	// The initial offset or the standard offset (w/o DST)
       
   214 	int initialTimeZoneOffset = zoneOffsets[ 0 ];
       
   215 
       
   216 	// Close the resource handles
       
   217 	timeZones.Close();
       
   218 	zoneOffsets.Close();
       
   219 
       
   220 	// The number of actualised rules
       
   221 	int ruleCount = actualizedRules->Count();
       
   222 
       
   223 	for (int ruleIndex(0); ruleIndex < ruleCount; ruleIndex++) {
       
   224 		const TVTzActualisedRule& tVTzactRule = (*actualizedRules)[ruleIndex];
       
   225 
       
   226 		// If the standard offset and the new offset do not match then we have
       
   227 		// a dst offset. Technically if a timezone has DST then it can have a
       
   228 		// max of two offsets. One is the standard which doesn't show the DST
       
   229 		// usage, and the other is the DST offset which is
       
   230 		// standard offset + the amount of DST.
       
   231 		if (initialTimeZoneOffset != tVTzactRule.iNewOffset) {
       
   232 			dstOffset = tVTzactRule.iNewOffset;
       
   233 			CleanupStack::PopAndDestroy(actualizedRules);
       
   234 			CleanupStack::PopAndDestroy(timezoneRules);
       
   235 			CleanupStack::PopAndDestroy(&tzHandle);
       
   236 			return true;
       
   237 		} else {
       
   238 			dstOffset = initialTimeZoneOffset;
       
   239 		}
       
   240 	}
       
   241 	CleanupStack::PopAndDestroy(actualizedRules);
       
   242 	CleanupStack::PopAndDestroy(timezoneRules);
       
   243 	CleanupStack::PopAndDestroy(&tzHandle);
       
   244 	return false;
       
   245 }
       
   246 
       
   247 LocationInfo TimezoneClient::getCurrentZoneInfoL()
       
   248 {
       
   249 	qDebug() << "clock: TimezoneClient::getCurrentZoneInfoL -->";
       
   250 
       
   251 	// Current zone info.
       
   252 	LocationInfo currentLocation;
       
   253 	int timezoneId(0);
       
   254 	int utcOffset(0);
       
   255 
       
   256 	// Connect to the timezone server.
       
   257 	RTz tzHandle;
       
   258 	User::LeaveIfError(tzHandle.Connect());
       
   259 	CleanupClosePushL(tzHandle);
       
   260 
       
   261 	// Get the current timezone ID.
       
   262 	CTzId* tzId;
       
   263 	tzId = tzHandle.GetTimeZoneIdL();
       
   264 	CleanupStack::PushL(tzId);
       
   265 
       
   266 	// TODO: Get the standard offset for current timezone.
       
   267 	// This way of fetching initial offset is being used rather than
       
   268 	// tzRules->InitialStdTimeOffset()because in some cases, the offset returned
       
   269 	// is incorrect. (For ex: Argentina and Canada/Iqaluit)
       
   270 	RArray<TInt> timeZones;
       
   271 	RArray<TInt> zoneOffsets;
       
   272 
       
   273 	// Append the current timezone ID and request for the standard offset
       
   274 	timeZones.Append(tzId->TimeZoneNumericID());
       
   275 	tzHandle.GetOffsetsForTimeZoneIdsL(timeZones, zoneOffsets);
       
   276 
       
   277 	// The initial offset or the standard offset (w/o DST)
       
   278 	int initialTimeZoneOffset = zoneOffsets[0];
       
   279 
       
   280 	// Close the resource handles
       
   281 	timeZones.Close();
       
   282 	zoneOffsets.Close();
       
   283 
       
   284 	// Construct CTzLocalizer object to get the timezone from the ID.
       
   285 	CTzLocalizer* tzLocalizer = CTzLocalizer::NewL();
       
   286 
       
   287 	// Get all the localized timezones for the current timezone ID.
       
   288 	CTzLocalizedTimeZone* localizedTimeZone(NULL);
       
   289 
       
   290 	if (tzLocalizer) {
       
   291 		// Get the currently set localized timezone.
       
   292 		CleanupStack::PushL(tzLocalizer);
       
   293 		localizedTimeZone =
       
   294 			tzLocalizer->GetLocalizedTimeZoneL(tzId->TimeZoneNumericID());
       
   295 
       
   296 		if (localizedTimeZone) {
       
   297 			CleanupStack::PushL(localizedTimeZone);
       
   298 
       
   299 			// Get the frequently used localized city.
       
   300 			CTzLocalizedCity* localizedCity(0);
       
   301 			localizedCity = tzLocalizer->GetFrequentlyUsedZoneCityL(
       
   302 					CTzLocalizedTimeZone::ECurrentZone);
       
   303 			CleanupStack::PushL(localizedCity);
       
   304 
       
   305 			// Get all the city groups.
       
   306 			CTzLocalizedCityGroupArray* cityGroupArray =
       
   307 					tzLocalizer->GetAllCityGroupsL(
       
   308 							CTzLocalizer::ETzAlphaNameAscending);
       
   309 			CleanupStack::PushL(cityGroupArray);
       
   310 
       
   311 			// Get the index of the country corresponding to the city group ID.
       
   312 			int countryIndex(1);
       
   313 
       
   314 			for (int index = 0; index < cityGroupArray->Count(); index++) {
       
   315 				if (localizedCity->GroupId() ==
       
   316 						cityGroupArray->At(index).Id()) {
       
   317 					countryIndex = index;
       
   318 				}
       
   319 			}
       
   320 
       
   321 			// Get all the cities within the currently set country.
       
   322 			CTzLocalizedCityArray* cityList = tzLocalizer->GetCitiesInGroupL(
       
   323 					(cityGroupArray->At(countryIndex )).Id(),
       
   324 					CTzLocalizer::ETzAlphaNameAscending);
       
   325 			CleanupStack::PushL(cityList);
       
   326 
       
   327 			// Check if automatic time update is enabled.
       
   328 			bool timeUpdateOn( false );
       
   329 
       
   330 			// Connect to the clock server.
       
   331 			// TODO: connect to the clock server and get auto update status in
       
   332 			// var:  timeUpdateOn
       
   333 			// Check if the country contains only one city or if automatic
       
   334 			// time update is on.
       
   335 			if (1 == cityList->Count() || timeUpdateOn) {
       
   336 				// If yes, then display only the country name.
       
   337 				// TODO
       
   338 			} else {
       
   339 				// Display city name.
       
   340 				// TODO:
       
   341 			}
       
   342 
       
   343 			// Get the country name.
       
   344 			TPtrC countryName(cityGroupArray->At(countryIndex).Name());
       
   345 			currentLocation.countryName = QString::fromUtf16(
       
   346 					countryName.Ptr(), countryName.Length());
       
   347 
       
   348 			// Get the city name.
       
   349 			TPtrC cityName(localizedCity->Name());
       
   350 			currentLocation.cityName = QString::fromUtf16(
       
   351 					cityName.Ptr(), cityName.Length());
       
   352 
       
   353 			// Get the UTC offset.
       
   354 			timezoneId = localizedCity->TimeZoneId();
       
   355 
       
   356 			if (timezoneId) {
       
   357 				// Check if the DST is on for the current timezone.
       
   358 				if (isDSTOnL(timezoneId)) {
       
   359 					// Get the offset with DST enabled.
       
   360 					getUtcDstOffsetL(utcOffset, *tzId);
       
   361 
       
   362 					currentLocation.dstOn = true;
       
   363 					currentLocation.timezoneId = timezoneId;
       
   364 					currentLocation.zoneOffset = utcOffset;
       
   365 				} else {
       
   366 					// Use the standard offset.
       
   367 					currentLocation.dstOn = false;
       
   368 					currentLocation.timezoneId = timezoneId;
       
   369 					currentLocation.zoneOffset = initialTimeZoneOffset;
       
   370 				}
       
   371 			}
       
   372 
       
   373 			// Cleanup.
       
   374 			CleanupStack::PopAndDestroy( cityList );
       
   375 			CleanupStack::PopAndDestroy( cityGroupArray );
       
   376 			CleanupStack::PopAndDestroy( localizedCity );
       
   377 			CleanupStack::PopAndDestroy( localizedTimeZone );
       
   378 		}
       
   379 
       
   380 		// Cleanup.
       
   381 		CleanupStack::PopAndDestroy( tzLocalizer );
       
   382 	}
       
   383 
       
   384 	// Cleanup.
       
   385 	CleanupStack::PopAndDestroy( tzId );
       
   386 	CleanupStack::PopAndDestroy( &tzHandle );
       
   387 
       
   388 	qDebug() << "clock: TimezoneClient::getCurrentZoneInfoL <--";
       
   389 
       
   390 	return currentLocation;
       
   391 }
       
   392 
       
   393 void TimezoneClient::setAsCurrentLocationL(LocationInfo &location)
       
   394 {
       
   395 	Debug::writeDebugMsg(
       
   396 			"In time zone client setAsCurrentLocationL " + location.cityName +
       
   397 			" " +
       
   398 			location.countryName +
       
   399 			" " +
       
   400 			QString::number(location.zoneOffset));
       
   401 
       
   402 	// Construct CTzLocalizer object.
       
   403 	CTzLocalizer* tzLocalizer = CTzLocalizer::NewL();
       
   404 	CleanupStack::PushL( tzLocalizer );
       
   405 	tzLocalizer->SetTimeZoneL( location.timezoneId );
       
   406 
       
   407 	TPtrC ptrCityName(
       
   408 			reinterpret_cast<const TText*>(location.cityName.constData()));
       
   409 	CTzLocalizedCity* localizedCity =
       
   410 			tzLocalizer->FindCityByNameL(ptrCityName, location.timezoneId);
       
   411 	CleanupStack::PushL( localizedCity );
       
   412 	tzLocalizer->SetFrequentlyUsedZoneL(
       
   413 			*localizedCity, CTzLocalizedTimeZone::ECurrentZone);
       
   414 
       
   415 	// Cleanup.
       
   416 	CleanupStack::PopAndDestroy( localizedCity );
       
   417 	CleanupStack::PopAndDestroy( tzLocalizer );
       
   418 }
       
   419 
       
   420 bool TimezoneClient::isDSTOnL(int timezoneId)
       
   421 {
       
   422 	bool returnVal( false );
       
   423 	CTzId* tzId = CTzId::NewL( timezoneId );
       
   424 	CleanupStack::PushL( tzId );
       
   425 
       
   426 	RTz tzHandle;
       
   427 	User::LeaveIfError( tzHandle.Connect() );
       
   428 	CleanupClosePushL( tzHandle );
       
   429 
       
   430 	returnVal = tzHandle.IsDaylightSavingOnL( *tzId );
       
   431 
       
   432 	tzHandle.Close();
       
   433 	CleanupStack::PopAndDestroy( &tzHandle );
       
   434 	CleanupStack::PopAndDestroy( tzId );
       
   435 
       
   436 	return returnVal;
       
   437 }
       
   438 
       
   439 int TimezoneClient::getStandardOffset(int timezoneId)
       
   440 {
       
   441 	RTz tzHandle;
       
   442 	User::LeaveIfError(tzHandle.Connect());
       
   443 	CleanupClosePushL(tzHandle);
       
   444 
       
   445 	RArray<int> idArray;
       
   446 	RArray<int> offsetArray;
       
   447 	idArray.Append(timezoneId);
       
   448 
       
   449 	tzHandle.GetOffsetsForTimeZoneIdsL(idArray, offsetArray);
       
   450 	int stdOffset = offsetArray[0];
       
   451 
       
   452 	offsetArray.Close();
       
   453 	idArray.Close();
       
   454 
       
   455 	// Cleanup.
       
   456 	CleanupStack::PopAndDestroy(&tzHandle);
       
   457 
       
   458 	return stdOffset;
       
   459 }
       
   460 
       
   461 void TimezoneClient::getDstRulesL(
       
   462 		QDateTime &startTime, QDateTime &endTime, int timezoneId)
       
   463 {
       
   464 	RTz tzHandle;
       
   465 	User::LeaveIfError(tzHandle.Connect());
       
   466 	CleanupClosePushL(tzHandle);
       
   467 
       
   468 	// Local time.
       
   469 	TTime homeTime;
       
   470 	homeTime.HomeTime();
       
   471 
       
   472 	TDateTime dateTime;
       
   473 	dateTime = homeTime.DateTime();
       
   474 
       
   475 	CTzId *tzId = CTzId::NewL(timezoneId);
       
   476 	CleanupStack::PushL(tzId);
       
   477 	// Get the CTzRules for the current year and for the given time zone id.
       
   478 	CTzRules* timezoneRules = tzHandle.GetTimeZoneRulesL(
       
   479 			*tzId, dateTime.Year(), dateTime.Year(), ETzWallTimeReference);
       
   480 	CleanupStack::PushL(timezoneRules);
       
   481 
       
   482 	// Get the Actualised rules for the same year.
       
   483 	// These are the DST rules from which we get the iNewOffset.
       
   484 	CVTzActualisedRules *actualizedRules = CVTzActualisedRules::NewL(
       
   485 			homeTime.DateTime().Year(), homeTime.DateTime().Year() );
       
   486 	CleanupStack::PushL(actualizedRules);
       
   487 	timezoneRules->GetActualisedRulesL(*actualizedRules);
       
   488 
       
   489 	// This way of fetching initial offset is being used rather than
       
   490 	// tzRules->InitialStdTimeOffset() because in some cases,
       
   491 	// the offset returned is incorrect. (For ex: Argentina and Canada/Iqaluit)
       
   492 	RArray<TInt> timeZones;
       
   493 	RArray<TInt> zoneOffsets;
       
   494 
       
   495 	// Append the current timezone ID and request for the standard offset
       
   496 	timeZones.Append(timezoneId);
       
   497 	tzHandle.GetOffsetsForTimeZoneIdsL(timeZones, zoneOffsets);
       
   498 
       
   499 	// The initial offset or the standard offset (w/o DST)
       
   500 	int initialTimeZoneOffset = zoneOffsets[ 0 ];
       
   501 
       
   502 	// Close the resource handles
       
   503 	timeZones.Close();
       
   504 	zoneOffsets.Close();
       
   505 
       
   506 	// The number of actualised rules
       
   507 	int ruleCount = actualizedRules->Count();
       
   508 
       
   509 	for(int ruleIndex(1); ruleIndex < ruleCount; ruleIndex++) {
       
   510 		const TVTzActualisedRule& tVTzactRule = (*actualizedRules)[ruleIndex];
       
   511 
       
   512 		TTime ruleTime(tVTzactRule.iTimeOfChange);
       
   513 
       
   514 		if (initialTimeZoneOffset == tVTzactRule.iNewOffset) {
       
   515 			TTime tempRuleTime(ruleTime);
       
   516 			if (tVTzactRule.iTimeReference == ETzUtcTimeReference) {
       
   517 				tempRuleTime += TTimeIntervalMinutes(tVTzactRule.iNewOffset);
       
   518 			}
       
   519 
       
   520 			QTime tempTime;
       
   521 			QDate tempDate;
       
   522 			tempTime.setHMS(tempRuleTime.DateTime().Hour(),
       
   523 			                tempRuleTime.DateTime().Minute(),
       
   524 			                tempRuleTime.DateTime().Second());
       
   525 			tempDate.setYMD(tempRuleTime.DateTime().Year(),
       
   526 			                tempRuleTime.DateTime().Month()+1,
       
   527 			                tempRuleTime.DateTime().Day()+1);
       
   528 			endTime.setDate(tempDate);
       
   529 			endTime.setTime(tempTime);
       
   530 		} else {
       
   531 			TTime tempRuleTime(ruleTime);
       
   532 			if (tVTzactRule.iTimeReference == ETzUtcTimeReference) {
       
   533 				tempRuleTime += TTimeIntervalMinutes(tVTzactRule.iNewOffset);
       
   534 			}
       
   535 			QTime tempTime;
       
   536 			QDate tempDate;
       
   537 			tempTime.setHMS(tempRuleTime.DateTime().Hour(),
       
   538 			                tempRuleTime.DateTime().Minute(),
       
   539 			                tempRuleTime.DateTime().Second());
       
   540 			tempDate.setYMD(tempRuleTime.DateTime().Year(),
       
   541 			                tempRuleTime.DateTime().Month() + 1,
       
   542 			                tempRuleTime.DateTime().Day() + 1);
       
   543 			startTime.setDate(tempDate);
       
   544 			startTime.setTime(tempTime);
       
   545 		}
       
   546 	}
       
   547 	CleanupStack::PopAndDestroy(actualizedRules);
       
   548 	CleanupStack::PopAndDestroy(timezoneRules);
       
   549 	CleanupStack::PopAndDestroy(tzId);
       
   550 	CleanupStack::PopAndDestroy(&tzHandle);
       
   551 }
       
   552 
       
   553 QList<LocationInfo> TimezoneClient::getSavedLocations()
       
   554 {
       
   555 	QList<LocationInfo> locationList;
       
   556 
       
   557 	QString fileName(CITY_INFO_DB_PATH);
       
   558 	fileName.append(CITY_INFO_DB);
       
   559 
       
   560 	QFile cityInfoFile(fileName);
       
   561 	if (cityInfoFile.open(QIODevice::ReadOnly)) {
       
   562 		QDataStream writeStream(&cityInfoFile);
       
   563 		writeStream >> locationList;
       
   564 		cityInfoFile.close();
       
   565 	}
       
   566 	return locationList;
       
   567 }
       
   568 
       
   569 void TimezoneClient::saveLocations(const QList<LocationInfo> &locationList)
       
   570 {
       
   571 	QDir cityDbDir;
       
   572 	cityDbDir.mkpath(CITY_INFO_DB_PATH);
       
   573 
       
   574 	QString fileName(CITY_INFO_DB_PATH);
       
   575 	fileName.append(CITY_INFO_DB);
       
   576 
       
   577 	QFile cityInfoFile(fileName);
       
   578 	if (!cityInfoFile.open(QIODevice::WriteOnly)) {
       
   579 		// Error opening or creating file.
       
   580 		return;
       
   581 	}
       
   582 	QDataStream writeStream(&cityInfoFile);
       
   583 	writeStream << locationList;
       
   584 	cityInfoFile.close();
       
   585 
       
   586 	emit listUpdated();
       
   587 }
       
   588 
       
   589 void TimezoneClient::getCountries(QMap<QString, int>& countries)
       
   590 {
       
   591 	// Construct the timezone localizer.
       
   592 	CTzLocalizer* localizer = CTzLocalizer::NewL();
       
   593 	CleanupStack::PushL(localizer);
       
   594 
       
   595 	// Get all the city groups(countries).
       
   596 	QTime t;
       
   597 	t.start();
       
   598 	CTzLocalizedCityGroupArray* cityGroupArray =
       
   599 		localizer->GetAllCityGroupsL(CTzLocalizer::ETzAlphaNameAscending);
       
   600 	qDebug() << "Fetching city groups from tzloc: " << t.elapsed();
       
   601 	CleanupStack::PushL(cityGroupArray);
       
   602 
       
   603 	t.restart();
       
   604 	// Iterate through each of the city groups.
       
   605 	for (int i = 0; i < cityGroupArray->Count(); i++) {
       
   606 		CTzLocalizedCityGroup& cityGroup(cityGroupArray->At(i));
       
   607 		TPtrC countryName(cityGroup.Name());
       
   608 
       
   609 		// Get the QString of country name
       
   610 		QString qCountryName = QString::fromUtf16(
       
   611 				countryName.Ptr(),countryName.Length());
       
   612 	    countries[qCountryName] = cityGroup.Id();
       
   613 	}
       
   614 	qDebug() << "Converting " <<
       
   615 			cityGroupArray->Count() <<
       
   616 			"countries to qstring: " <<
       
   617 			t.elapsed();
       
   618 
       
   619 	// Cleanup.
       
   620 	CleanupStack::PopAndDestroy(cityGroupArray);
       
   621 	CleanupStack::PopAndDestroy(localizer);
       
   622 }
       
   623 
       
   624 void TimezoneClient::getCitiesForCountry(int id, QMap<QString, int>& cities)
       
   625 {
       
   626 	// Construct the timezone localizer.
       
   627 	CTzLocalizer* localizer = CTzLocalizer::NewL();
       
   628 	CleanupStack::PushL(localizer);
       
   629 
       
   630 	// Get the city group for the given id.
       
   631 	CTzLocalizedCityArray* cityArray = localizer->GetCitiesInGroupL(id,
       
   632 			CTzLocalizer::ETzAlphaNameAscending);
       
   633 	CleanupStack::PushL(cityArray);
       
   634 	CTzLocalizedCityArray* unsortedArray = localizer->GetCitiesInGroupL(id,
       
   635 			CTzLocalizer::ETzUnsorted);
       
   636 	CleanupStack::PushL(unsortedArray);
       
   637 
       
   638 	for (int i = 0; i < cityArray->Count(); i++) {
       
   639 		CTzLocalizedCity *city = &(cityArray->At(i));
       
   640 		TPtrC cityName = city->Name();
       
   641 
       
   642 		for (int j = 0; j < unsortedArray->Count(); j++) {
       
   643 			if (KErrNone ==
       
   644 					(unsortedArray->At(j)).Name().Compare(city->Name())) {
       
   645 				QString qCityname = QString::fromUtf16(
       
   646 						cityName.Ptr(),cityName.Length());
       
   647 				cities[qCityname] = j;
       
   648 
       
   649 				break;
       
   650 			}
       
   651 		}
       
   652 	}
       
   653 
       
   654 	// Cleanup.
       
   655 	CleanupStack::PopAndDestroy(unsortedArray);
       
   656 	CleanupStack::PopAndDestroy(cityArray);
       
   657 	CleanupStack::PopAndDestroy(localizer);
       
   658 }
       
   659 
       
   660 void TimezoneClient::getLocationInfo(
       
   661 		int groupId, int cityIndex, LocationInfo& cityInfo)
       
   662 {
       
   663 	TRAPD(
       
   664 			error,
       
   665 
       
   666 			// Construct the localizer.
       
   667 			CTzLocalizer* localizer = CTzLocalizer::NewLC();
       
   668 
       
   669 			// Get the localized city group.
       
   670 			CTzLocalizedCityGroup* cityGroup = localizer->GetCityGroupL(groupId);
       
   671 			CleanupStack::PushL(cityGroup);
       
   672 
       
   673 			// Get the localized city array for the given city group.
       
   674 			CTzLocalizedCityArray* cityArray = localizer->GetCitiesInGroupL(
       
   675 					groupId, CTzLocalizer::ETzUnsorted);
       
   676 			CleanupStack::PushL(cityArray);
       
   677 
       
   678 			// Get the required city.
       
   679 			CTzLocalizedCity* neededCity = &(cityArray->At(cityIndex));
       
   680 
       
   681 			// Fill the location information.
       
   682 			cityInfo.countryName = QString::fromUtf16(
       
   683 					cityGroup->Name().Ptr(), cityGroup->Name().Length());
       
   684 			cityInfo.cityName = QString::fromUtf16(
       
   685 					neededCity->Name().Ptr(), neededCity->Name().Length());
       
   686 			cityInfo.timezoneId = neededCity->TimeZoneId();
       
   687 			cityInfo.dstOn = dstOn(cityInfo.timezoneId);
       
   688 			cityInfo.zoneOffset = getDstZoneOffset(cityInfo.timezoneId);
       
   689 
       
   690 			// Cleanup.
       
   691 			CleanupStack::PopAndDestroy(cityArray);
       
   692 			CleanupStack::PopAndDestroy(cityGroup);
       
   693 			CleanupStack::PopAndDestroy(localizer);
       
   694 	)
       
   695 	Q_UNUSED(error)
       
   696 }
       
   697 
       
   698 QDataStream &operator<<(
       
   699 		QDataStream &writeStream, const LocationInfo& locationInfo)
       
   700 {
       
   701 	writeStream << locationInfo.cityName
       
   702 			<< locationInfo.countryName
       
   703 			<< locationInfo.listImageName
       
   704 			<< locationInfo.dstOn
       
   705 			<< locationInfo.timezoneId
       
   706 			<< locationInfo.zoneOffset;
       
   707 	return writeStream;
       
   708 }
       
   709 
       
   710 QDataStream &operator>>(
       
   711 		QDataStream &readStream, LocationInfo &locationInfo)
       
   712 {
       
   713 	readStream >> locationInfo.cityName
       
   714 	>> locationInfo.countryName
       
   715 	>> locationInfo.listImageName
       
   716 	>> locationInfo.dstOn
       
   717 	>> locationInfo.timezoneId
       
   718 	>> locationInfo.zoneOffset;
       
   719 	return readStream;
       
   720 }
       
   721 
       
   722 int TimezoneClient::environmentCallback(TAny* obj)
       
   723 {
       
   724 	TimezoneClient* self = static_cast<TimezoneClient *> (obj);
       
   725 
       
   726 	int changes = KInitialEvent;
       
   727 	if (self->mNotifier) {
       
   728 		changes = self->mNotifier->Change();
       
   729 	}
       
   730 
       
   731 	if (KInitialEvent <= changes) {
       
   732 		// We're not concerned about handling environment changes in that range.
       
   733 		return 0;
       
   734 	}
       
   735 
       
   736 	if (changes & (EChangesMidnightCrossover |
       
   737 			EChangesLocale |
       
   738 			EChangesSystemTime)) {
       
   739 		emit self->timechanged();
       
   740 	} else {
       
   741 		// Nothing to do.
       
   742 	}
       
   743 	return 0;
       
   744 }
       
   745 
       
   746 int TimezoneClient::getDstZoneOffset(int tzId)
       
   747 {
       
   748 	// Connect to the timezone server.
       
   749 	RTz client;
       
   750 	User::LeaveIfError(client.Connect());
       
   751 	CleanupClosePushL(client);
       
   752 
       
   753 	RArray<int> zoneIds;
       
   754 	RArray<int> zoneOffsets;
       
   755 	zoneIds.Append(tzId);
       
   756 
       
   757 	// Get the offsets.
       
   758 	client.GetOffsetsForTimeZoneIdsL(zoneIds, zoneOffsets);
       
   759 
       
   760 	// Cleanup.
       
   761 	CleanupStack::PopAndDestroy(&client);
       
   762 
       
   763 	return zoneOffsets[0];
       
   764 }
       
   765 
       
   766 bool TimezoneClient::dstOn(int tzId)
       
   767 {
       
   768 	// Connect to the timezone server.
       
   769 	RTz client;
       
   770 	User::LeaveIfError(client.Connect());
       
   771 	CleanupClosePushL(client);
       
   772 
       
   773 	CTzId *zoneId = CTzId::NewL(tzId);
       
   774 	CleanupStack::PushL(zoneId);
       
   775 
       
   776 	bool returnVal = client.IsDaylightSavingOnL(*zoneId);
       
   777 
       
   778 	// Cleanup.
       
   779 	CleanupStack::PopAndDestroy(zoneId);
       
   780 	CleanupStack::PopAndDestroy(&client);
       
   781 
       
   782 	return returnVal;
       
   783 }
       
   784 
       
   785 int TimezoneClient::getCityGroupIdByName(const QString& name)
       
   786 {
       
   787 	TPtrC namePtr;
       
   788 	namePtr.Set(name.utf16(), name.length());
       
   789 
       
   790 	// Construct the timezone localizer.
       
   791 	CTzLocalizer *localizer = CTzLocalizer::NewLC();
       
   792 
       
   793 	// Get the citygroup matching the name.
       
   794 	CTzLocalizedCityGroup *cityGroup = localizer->FindCityGroupByNameL(namePtr);
       
   795 	CleanupStack::PushL(cityGroup);
       
   796 
       
   797 	// Get the id.
       
   798 	int id = cityGroup->Id();
       
   799 
       
   800 	// Cleanup.
       
   801 	CleanupStack::PopAndDestroy(cityGroup);
       
   802 	CleanupStack::PopAndDestroy(localizer);
       
   803 
       
   804 	return id;
       
   805 }
       
   806 
       
   807 int TimezoneClient::getCityOffsetByNameAndId(const QString& name, int tzId)
       
   808 {
       
   809 	TPtrC namePtr;
       
   810 	namePtr.Set(name.utf16(), name.length());
       
   811 
       
   812 	// Construct the timezone localizer.
       
   813 	CTzLocalizer *localizer = CTzLocalizer::NewLC();
       
   814 
       
   815 	// Get the citygroup matching the name.
       
   816 	CTzLocalizedCityArray *cityArray = localizer->GetCitiesL(tzId);
       
   817 	CleanupStack::PushL(cityArray);
       
   818 
       
   819 	int id;
       
   820 	for (id = 0; id < cityArray->Count(); id++) {
       
   821 		if (KErrNone == cityArray->At(id).Name().Compare(namePtr)) {
       
   822 			break;
       
   823 		}
       
   824 	}
       
   825 	if (id == cityArray->Count()) {
       
   826 		id = -1;
       
   827 	}
       
   828 
       
   829 	// Cleanup.
       
   830 	CleanupStack::PopAndDestroy(cityArray);
       
   831 	CleanupStack::PopAndDestroy(localizer);
       
   832 
       
   833 	return id;
       
   834 
       
   835 }
       
   836 
       
   837 void TimezoneClient::setDateTime(QDateTime dateTime)
       
   838 {
       
   839 	TMonth month = intToMonth(dateTime.date().month());
       
   840 	TTime current(TDateTime(
       
   841 			dateTime.date().year(), month, dateTime.date().day() - 1,
       
   842 			dateTime.time().hour(), dateTime.time().minute(),
       
   843 			dateTime.time().second(), dateTime.time().msec() * 1000));
       
   844 	RTz tz;
       
   845 	User::LeaveIfError(tz.Connect());
       
   846 	CleanupClosePushL(tz);
       
   847 	TInt ret(tz.SetHomeTime(current));
       
   848 	CleanupStack::PopAndDestroy(&tz);
       
   849 }
       
   850 
       
   851 void TimezoneClient::setTimeUpdateOn(bool timeUpdate)
       
   852 {
       
   853     RClkSrvInterface clkSrvInterface;
       
   854     User::LeaveIfError(clkSrvInterface.Connect());
       
   855     if (timeUpdate) {
       
   856     clkSrvInterface.ActivateAllProtocols();
       
   857     }
       
   858     else {
       
   859     clkSrvInterface.DeActivateAllProtocols();
       
   860     }
       
   861 	mTimeUpdateOn = timeUpdate;
       
   862 	clkSrvInterface.Close();
       
   863 }
       
   864 
       
   865 bool TimezoneClient::timeUpdateOn()
       
   866 {
       
   867 	return mTimeUpdateOn;
       
   868 }
       
   869 
       
   870 QStandardItemModel *TimezoneClient::locationSelectorModel()
       
   871 {
       
   872 	if (!mWorldClockModel) {
       
   873 		createWorldClockModel();
       
   874 	}
       
   875 	return mWorldClockModel;
       
   876 }
       
   877 
       
   878 TMonth TimezoneClient::intToMonth(int month)
       
   879 {
       
   880 	switch (month) {
       
   881 		case 1:
       
   882 			return EJanuary;
       
   883 		case 2:
       
   884 			return EFebruary;
       
   885 		case 3:
       
   886 			return EMarch;
       
   887 		case 4:
       
   888 			return EApril;
       
   889 		case 5:
       
   890 			return EMay;
       
   891 		case 6:
       
   892 			return EJune;
       
   893 		case 7:
       
   894 			return EJuly;
       
   895 		case 8:
       
   896 			return EAugust;
       
   897 		case 9:
       
   898 			return ESeptember;
       
   899 		case 10:
       
   900 			return EOctober;
       
   901 		case 11:
       
   902 			return ENovember;
       
   903 		case 12:
       
   904 			return EDecember;
       
   905 		default:
       
   906 			// Nothing to do.
       
   907 			break;
       
   908 	}
       
   909 	return (TMonth) -1;
       
   910 }
       
   911 
       
   912 void TimezoneClient::createWorldClockModel()
       
   913 {
       
   914 	// Construct the model if its not yet done
       
   915 	if (!mWorldClockModel) {
       
   916 		// Create the model
       
   917 		mWorldClockModel = new QStandardItemModel(this);
       
   918 
       
   919 		getCountries(mAllCountries);
       
   920 		mCountryCount = mAllCountries.count();
       
   921 
       
   922 		// Construct the model in asynchronously
       
   923 		QTimer::singleShot(2000, this, SLOT(populateCities()));
       
   924 	}
       
   925 }
       
   926 
       
   927 void TimezoneClient::populateCities()
       
   928 {
       
   929 	// First iterate over all the counties
       
   930 	QMapIterator<QString, int> countryIter(mAllCountries);
       
   931 	while (countryIter.hasNext()) {
       
   932 		countryIter.next();
       
   933 		// Create an item for each country and append it to the model
       
   934 		QStandardItem *country = new QStandardItem(countryIter.key());
       
   935 		// Add the city group id
       
   936 		// TODO: Define and use proper role
       
   937 		country->setData(countryIter.value(), Qt::UserRole + 200);
       
   938 		mWorldClockModel->appendRow(country);
       
   939 
       
   940 		// Iterate through the city list of each country
       
   941 		QMap<QString, int> cityList;
       
   942 		getCitiesForCountry(countryIter.value(), cityList);
       
   943 		QMapIterator<QString, int> cityIter(cityList);
       
   944 		while (cityIter.hasNext()) {
       
   945 			cityIter.next();
       
   946 			// Create an item for the city and append it to that country
       
   947 			QStandardItem *city = new QStandardItem(cityIter.key());
       
   948 			// TODO: Define and use proper role
       
   949 			city->setData(cityIter.value(), Qt::UserRole + 200);
       
   950 			country->appendRow(city);
       
   951 		}
       
   952 	}
       
   953 }
       
   954 
       
   955 /*!
       
   956 	 Checks if DST changes will be applied in the next 24 hours.
       
   957 
       
   958 	 \param alarmInfo reference to alarm info
       
   959 	 \return true if there is DST change otherwise false
       
   960  */
       
   961 bool TimezoneClient::checkForDstChange(AlarmInfo& alarmInfo)
       
   962 {
       
   963 	// User to be notified whether DST rollover happens in a day or
       
   964 	// has happen within a day if he tries to change the time.
       
   965 	bool returnValue( EFalse );
       
   966 
       
   967 	// Establish connection with RTz to get the timezone ID
       
   968 	RTz tzHandle;
       
   969 	User::LeaveIfError( tzHandle.Connect() );
       
   970 	CleanupClosePushL( tzHandle );
       
   971 
       
   972 	// The timezone ID (current)
       
   973 	CTzId* currentTZId = tzHandle.GetTimeZoneIdL();
       
   974 	CleanupStack::PushL( currentTZId );
       
   975 
       
   976 	// The current time in UTC
       
   977 	TTime currentTime;
       
   978 	currentTime.UniversalTime();
       
   979 
       
   980 	// hometime (local time)
       
   981 	TTime homeTime;
       
   982 	homeTime.HomeTime();
       
   983 
       
   984 	//(Year, Month, Day, Hour, Minute, Second, Micrsecond)
       
   985 	TDateTime dateTime(homeTime.DateTime().Year(), EJanuary, 1, FALSE, FALSE,
       
   986 			FALSE, FALSE);
       
   987 
       
   988 	TTime tempTime( dateTime );
       
   989 
       
   990 	// Get the current rules for the timezone
       
   991 	CTzRules* currentRules = tzHandle.GetTimeZoneRulesL(*currentTZId,
       
   992 							tempTime, currentTime, ETzUtcTimeReference);
       
   993 	CleanupStack::PushL( currentRules );
       
   994 
       
   995 	// CVTzActualisedRules encapsulates the rules for a specific year.
       
   996 	// Every year has a dummy rule and further DST rules if DST is applicable
       
   997 	// (if Ohlson provides them)
       
   998 	CVTzActualisedRules *vActualisedRules = CVTzActualisedRules::NewL(
       
   999 			homeTime.DateTime().Year(),
       
  1000 			homeTime.DateTime().Year());
       
  1001 	CleanupStack::PushL( vActualisedRules );
       
  1002 
       
  1003 	// The dummy rule is always the begining of the year.
       
  1004 	// For example there is only 1 rule for
       
  1005 	// India/NewDelhi but USA/Atlanta has 3 rules.
       
  1006 	currentRules->GetActualisedRulesL( *vActualisedRules );
       
  1007 
       
  1008 	const int ruleCount( vActualisedRules->Count() );
       
  1009 	int ruleMatchIndex( KNoDifference );
       
  1010 
       
  1011 	TTimeIntervalSeconds secondsDifference;
       
  1012 	TTime ruleMatchTime;
       
  1013 
       
  1014 	// Fetch lowest time offset for the year residing at aTime.
       
  1015 	// This is used to determine if DST is on.
       
  1016 	for ( int ruleIndex( FALSE ); ruleIndex < ruleCount; ++ruleIndex ) {
       
  1017 		const TVTzActualisedRule& actualisedRule =
       
  1018 				( *vActualisedRules )[ ruleIndex ];
       
  1019 
       
  1020 		// Only check for the same year as requested (aTime)
       
  1021 		if (actualisedRule.iTimeOfChange.DateTime().Year()
       
  1022 				== homeTime.DateTime().Year()) {
       
  1023 			TMonth month = intToMonth(alarmInfo.alarmDateTime.month());
       
  1024 			TTime alarmTime(TDateTime(
       
  1025 					alarmInfo.alarmDateTime.year(),
       
  1026 					month,
       
  1027 					alarmInfo.alarmDateTime.day() - 1,
       
  1028 					alarmInfo.origAlarmTime.hour(),
       
  1029 					alarmInfo.origAlarmTime.minute(),
       
  1030 					alarmInfo.origAlarmTime.second(),
       
  1031 					alarmInfo.origAlarmTime.msec()*1000));
       
  1032 			int tempSecDiff = actualisedRule.iTimeOfChange.DateTime().Second() -
       
  1033 					alarmInfo.origAlarmTime.second() ;
       
  1034 
       
  1035 			alarmTime.SecondsFrom(actualisedRule.iTimeOfChange,
       
  1036 							secondsDifference);
       
  1037 			// Considering the time reference is important as America
       
  1038 			// (North & South) uses the Wall time (local time) reference
       
  1039 			// where as whole of Europe refers to time in terms of UTC time.
       
  1040 			// Correspondingly, the choise of local time or utc time
       
  1041 			// has to be made.
       
  1042 			TTime ruleTime;
       
  1043 
       
  1044 			if ( ETzUtcTimeReference == actualisedRule.iTimeReference ) {
       
  1045 				ruleTime = currentTime;
       
  1046 			}
       
  1047 			else if ( ETzWallTimeReference == actualisedRule.iTimeReference ) {
       
  1048 				ruleTime = homeTime;
       
  1049 			}
       
  1050 			else if( ETzStdTimeReference == actualisedRule.iTimeReference ) {
       
  1051 				// TODO: Testing so far hasn't encountered a rule in this time reference.
       
  1052 				// If in case an error is found, corresponding code can be added here.
       
  1053 				// No support from symbian for this.
       
  1054 			}
       
  1055 
       
  1056 			TDateTime sevenDays(FALSE, EJanuary, KDaysInWeek, FALSE, FALSE,
       
  1057 							FALSE, FALSE);
       
  1058 			TTime tempTime( sevenDays );
       
  1059 			TTime newTime( ruleTime.Int64() + tempTime.Int64() );
       
  1060 
       
  1061 			TTimeIntervalDays temp;
       
  1062 			temp = newTime.DaysFrom( ruleTime );
       
  1063 
       
  1064 			if ( ( secondsDifference.Int() >= KNoDifference ) &&
       
  1065 					( newTime > alarmTime) &&
       
  1066 					( actualisedRule.iTimeOfChange < alarmTime ) &&
       
  1067 					( ruleTime < actualisedRule.iTimeOfChange ) ) {
       
  1068 				// If there is a match, save the index and break.
       
  1069 				// We've got the rule and there's no need to continue with other rules.
       
  1070 				ruleMatchIndex = ruleIndex;
       
  1071 				ruleMatchTime = actualisedRule.iTimeOfChange;
       
  1072 				break;
       
  1073 			}
       
  1074 		}
       
  1075 	}
       
  1076 
       
  1077 	if ( ruleMatchIndex > KZerothRule ) {
       
  1078 		// There's a match, display the information note about DST change.
       
  1079 		TTime displayTime;
       
  1080 		TTimeIntervalHours oneHour( KOneHour );
       
  1081 		returnValue = ETrue;
       
  1082 	}
       
  1083 
       
  1084 	tzHandle.Close();
       
  1085 	CleanupStack::PopAndDestroy( vActualisedRules);
       
  1086 	CleanupStack::PopAndDestroy( currentRules );
       
  1087 	CleanupStack::PopAndDestroy( currentTZId );
       
  1088 	CleanupStack::PopAndDestroy( &tzHandle );
       
  1089 
       
  1090 	return returnValue;
       
  1091 }
       
  1092 
       
  1093 /*!
       
  1094 	Get all time zone ids
       
  1095 
       
  1096 	\return list of time zone ids
       
  1097  */
       
  1098 QList<int> TimezoneClient::getAllTimeZoneIds()
       
  1099 {
       
  1100 	if (mTimeZoneIds.count()) {
       
  1101 		return mTimeZoneIds;
       
  1102 	} else {
       
  1103 		// This list will contain the info of the cities fetched from tz server.
       
  1104 		QList<LocationInfo> infoList;
       
  1105 
       
  1106 		// Get the cities, in alphabetical-ascending sorted order.
       
  1107 		CTzLocalizedCityArray* cityArray =
       
  1108 				mTzLocalizer->GetCitiesL(CTzLocalizer::ETzAlphaNameAscending);
       
  1109 		ASSERT(cityArray);
       
  1110 		CleanupStack::PushL(cityArray);
       
  1111 		int cityCount = cityArray->Count();
       
  1112 
       
  1113 		// Now get the country\city-group of each of the city.
       
  1114 		// Print the timezone id and city group id as well.
       
  1115 		for (int iter = 0; iter < cityCount; iter++) {
       
  1116 			CTzLocalizedCity* localizedCity = &(cityArray->At(iter));
       
  1117 			int tzId(localizedCity->TimeZoneId());
       
  1118 			if(-1==mTimeZoneIds.indexOf(tzId)) {
       
  1119 				mTimeZoneIds.append(tzId);
       
  1120 			}
       
  1121 		}
       
  1122 
       
  1123 		CleanupStack::PopAndDestroy(cityArray);
       
  1124 		return mTimeZoneIds;
       
  1125 	}
       
  1126 }
       
  1127 
       
  1128 /*!
       
  1129 	Get all time zone ids
       
  1130 
       
  1131 	\return list of time zone ids
       
  1132  */
       
  1133 QList<int> TimezoneClient::getAllTimeZoneOffsets()
       
  1134 {
       
  1135 	QList<int> timeZoneOffsetList;
       
  1136 	QList<int> timeZoneIdList;
       
  1137 	if (mTimeZoneIds.count()) {
       
  1138 		timeZoneIdList = mTimeZoneIds;
       
  1139 	} else {
       
  1140 		timeZoneIdList = getAllTimeZoneIds();
       
  1141 	}
       
  1142 
       
  1143 	RTz tzHandle;
       
  1144 	User::LeaveIfError( tzHandle.Connect() );
       
  1145 	CleanupClosePushL( tzHandle );
       
  1146 
       
  1147 	RArray<int> idArray;
       
  1148 	RArray<int> offsetArray;
       
  1149 	int offset;
       
  1150 	int tzIdsCount = timeZoneIdList.count();
       
  1151 	for (int index=0;index<tzIdsCount;index++) {
       
  1152 		idArray.Append(timeZoneIdList.at(index));
       
  1153 		// Get the offsets for the time zone ids
       
  1154 		tzHandle.GetOffsetsForTimeZoneIdsL(idArray, offsetArray);
       
  1155 		offset = offsetArray[0];
       
  1156 
       
  1157 		// Add the offset if not exists in the list
       
  1158 		if(-1==(timeZoneOffsetList.indexOf(offset))) {
       
  1159 			timeZoneOffsetList.append(offset);
       
  1160 		}
       
  1161 
       
  1162 		offsetArray.Close();
       
  1163 		idArray.Close();
       
  1164 	}
       
  1165 
       
  1166 	tzHandle.Close();
       
  1167 	CleanupStack::PopAndDestroy( &tzHandle );
       
  1168 	// Sort the offset list
       
  1169 	qSort(timeZoneOffsetList.begin(),timeZoneOffsetList.end());
       
  1170 	return timeZoneOffsetList;
       
  1171 }
       
  1172 
       
  1173 
       
  1174 /*!
       
  1175 	Get countries list for a UTC offset
       
  1176 
       
  1177 	\param list of countries infomation having the same UTC offsets
       
  1178  */
       
  1179 QList<LocationInfo> TimezoneClient::getCountriesForUTCOffset(int utcOffset)
       
  1180 {
       
  1181 	// This list will contain the info of the countries.
       
  1182 	QList<LocationInfo> countryList;
       
  1183 	QList<int> cityGroupIdList;
       
  1184 
       
  1185 	// Get all cities for the UTC offset.
       
  1186 	CTzLocalizedCityArray* cityList =
       
  1187 			mTzLocalizer->GetCitiesWithUTCOffsetL(utcOffset);
       
  1188 	CleanupStack::PushL(cityList);
       
  1189 
       
  1190 	int cityCount = cityList->Count();
       
  1191 	CTzLocalizedCityGroup* country;
       
  1192 	for(int index=0;index<cityCount;index++) {
       
  1193 		CTzLocalizedCity* city = &(cityList->At(index));
       
  1194 		int cityGroupId(city->GroupId());
       
  1195 		int timeZoneId(city->TimeZoneId());
       
  1196 
       
  1197 		if(-1==cityGroupIdList.indexOf(cityGroupId)) {
       
  1198 			cityGroupIdList.append(cityGroupId);
       
  1199 
       
  1200 			country = mTzLocalizer->GetCityGroupL(cityGroupId);
       
  1201 
       
  1202 			// Now insert that data into the country List.
       
  1203 			LocationInfo cityInfo;
       
  1204 			cityInfo.cityGroupId = cityGroupId;
       
  1205 			cityInfo.countryName = QString::fromUtf16(
       
  1206 					country->Name().Ptr(), country->Name().Length());
       
  1207 			cityInfo.timezoneId = timeZoneId;
       
  1208 
       
  1209 			countryList.append(cityInfo);
       
  1210 			delete country;
       
  1211 		}
       
  1212 	}
       
  1213 	cityGroupIdList.clear();
       
  1214 	CleanupStack::PopAndDestroy(cityList);
       
  1215 	return countryList;
       
  1216 }
       
  1217 
       
  1218 /*!
       
  1219 	Add a new city to the city list using the
       
  1220 	name, time zone id and city group id
       
  1221 
       
  1222 	\param timeZoneId time zone id of the new city
       
  1223 	\cityName Name of the new city
       
  1224 	\cityGroupId Group Id of the country
       
  1225  */
       
  1226 LocationInfo TimezoneClient::addCity(
       
  1227 		int timeZoneId,QString &cityName,int cityGroupId)
       
  1228 {
       
  1229 	TPtrC namePtr;
       
  1230 	namePtr.Set(cityName.utf16(), cityName.length());
       
  1231 
       
  1232 	// Add a new city using the localizer
       
  1233 	CTzLocalizedCity* newCity =
       
  1234 			mTzLocalizer->AddCityL(timeZoneId, namePtr, cityGroupId);
       
  1235 	CleanupStack::PushL(newCity);
       
  1236 
       
  1237 	LocationInfo info;
       
  1238 	info.cityGroupId = newCity->GroupId();
       
  1239 	info.timezoneId = newCity->TimeZoneId();
       
  1240 	TPtrC newCityName(newCity->Name());
       
  1241 	info.cityName = QString::fromUtf16(
       
  1242 			newCityName.Ptr(), newCityName.Length());
       
  1243 
       
  1244 	CleanupStack::PopAndDestroy(newCity);
       
  1245 
       
  1246 	return info;
       
  1247 }
       
  1248 // End of file	--Don't remove this.