|
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. |