Merge lp:~carla-sella/ubuntu-clock-app/alarm-tests into lp:ubuntu-clock-app

Proposed by Carla Sella
Status: Rejected
Rejected by: Carla Sella
Proposed branch: lp:~carla-sella/ubuntu-clock-app/alarm-tests
Merge into: lp:ubuntu-clock-app
Diff against target: 3054 lines (+820/-1669)
31 files modified
README.autopilot (+37/-0)
app/alarm/AlarmLabel.qml (+2/-0)
app/alarm/AlarmList.qml (+7/-0)
app/alarm/AlarmPage.qml (+1/-0)
app/alarm/AlarmRepeat.qml (+4/-0)
app/alarm/AlarmSound.qml (+3/-0)
app/alarm/EditAlarmPage.qml (+5/-0)
app/clock/ClockPage.qml (+0/-6)
app/tests/autopilot/run (+0/-11)
app/tests/autopilot/ubuntu-clock-app/__init__.py (+0/-132)
app/tests/autopilot/ubuntu-clock-app/main/__init__.py (+0/-1)
app/tests/autopilot/ubuntu-clock-app/main/test_main.py (+0/-23)
app/tests/unit/tst_hellocomponent.qml (+0/-49)
app/worldclock/UserWorldCityList.qml (+0/-154)
app/worldclock/WorldCityList.qml (+5/-33)
app/worldclock/world-city-list.xml (+10/-1080)
backend/CMakeLists.txt (+0/-1)
backend/modules/Timezone/backend.cpp (+0/-2)
backend/modules/Timezone/generictimezonemodel.cpp (+0/-81)
backend/modules/Timezone/generictimezonemodel.h (+0/-58)
backend/modules/Timezone/timezonemodel.cpp (+4/-19)
backend/modules/Timezone/timezonemodel.h (+4/-17)
backend/modules/Timezone/xmltimezonemodel.cpp (+1/-0)
manifest.json (+5/-2)
tests/autopilot/run (+11/-0)
tests/autopilot/ubuntu_clock_app/__init__.py (+19/-0)
tests/autopilot/ubuntu_clock_app/emulators.py (+406/-0)
tests/autopilot/ubuntu_clock_app/tests/__init__.py (+121/-0)
tests/autopilot/ubuntu_clock_app/tests/test_alarm.py (+79/-0)
tests/autopilot/ubuntu_clock_app/tests/test_clock.py (+47/-0)
tests/unit/tst_hellocomponent.qml (+49/-0)
To merge this branch: bzr merge lp:~carla-sella/ubuntu-clock-app/alarm-tests
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Needs Fixing
Victor Thompson Needs Fixing
Nekhelesh Ramananthan Needs Fixing
Nicholas Skaggs Pending
Review via email: mp+227816@code.launchpad.net

Commit message

Autopilot alarm test for new clock app

Description of the change

Merge proposal for fixing click on header back button.

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
32. By Carla Sella

Made changes for click packages.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

During my testing, I noticed that the header button errors you got were due to timing issues. The alarm page was not fully visible before it tried clicking on the header buttons.

In the README.autopilot, can you add the following lines,

Prerequisities
==============

Install the following autopilot packages required to run the tests,
sudo apt-get install python-autopilot libautopilot-qt ubuntu-ui-toolkit-autopilot

review: Needs Fixing
Revision history for this message
Carla Sella (carla-sella) wrote :

Ok thank you I will try to solve the timing issues.

33. By Carla Sella

For merging.

34. By Carla Sella

Working on alarmListRepeater problem.

Revision history for this message
Carla Sella (carla-sella) wrote :

Stuck on getting count property of alarmListRepeater, I get StateNotFoundError.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
35. By Carla Sella

Uncommented line.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Carla Sella (carla-sella) wrote :

Fixed the count property of alarmListRepeater issue, I will carry on with the test now.

36. By Carla Sella

Commit for merging.

37. By Carla Sella

Commit for merging.

38. By Carla Sella

Commit for merging.

Revision history for this message
Carla Sella (carla-sella) wrote :

I'm getting this error if launching clock app with autopilot launch -i Qt qmlscene ../../app/ubuntu-clock-app.qml:

file:///home/letozaf/autopilot-tests/reboot/app/worldclock/UserWorldCityList.qml:20 module "Timezone" is not installed

and this error with autopilot run -vv : http://paste.ubuntu.com/7866133/.

Had to merge otherwise could not get header addAlarmAction head button, it used to work and then didn't anymore I think after un apt-get upgrade && apt-get dist-upgrade.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Victor Thompson (vthompson) wrote :

Carla, to resolve your issue, please follow the instructions in README.developers. Mostly you'll need to do steps 2 and 3 and modify your autopilot call (I believe you might be able to do a "sudo make install" to avoid adding the "-I" portion):

1. mkdir builddir && cd builddir
2. cmake .. && make
3. autopilot launch -i Qt qmlscene ../../app/ubuntu-clock-app.qml -I ../../builddir/backend/

Revision history for this message
Victor Thompson (vthompson) wrote :

Please see my inline comments.

review: Needs Fixing
39. By Carla Sella

For merging.

40. By Carla Sella

For merging.

Revision history for this message
Carla Sella (carla-sella) wrote :

Thank you Victor, eveything looks fine now.
I will carry on finishing the test.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
41. By Carla Sella

Test completed, only needs locale fixing.

42. By Carla Sella

Fixed pep8 and pyflakes.

43. By Carla Sella

Fixed minor things.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

Hmm I notice a lot of code diff from other branches that were recently merged to trunk. Carla how do you merge trunk into your branch? This technically shouldn't show up in this MP.

Revision history for this message
Carla Sella (carla-sella) wrote :

I also noted something weired :(.
I do not understand why, maybe it has been a revert I made when I had some problems with the Timezone module.
So what should I do to fix this mess I made ?
Thanks.

Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

Can you ping me on irc later tonight when you are free? I can go over the steps with you.

Revision history for this message
Carla Sella (carla-sella) wrote :

Ok I will ping you tonight around 21:00 if that's ok for you.
Thanks.

Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

Yup that's fine :)

Unmerged revisions

43. By Carla Sella

Fixed minor things.

42. By Carla Sella

Fixed pep8 and pyflakes.

41. By Carla Sella

Test completed, only needs locale fixing.

40. By Carla Sella

For merging.

39. By Carla Sella

For merging.

38. By Carla Sella

Commit for merging.

37. By Carla Sella

Commit for merging.

36. By Carla Sella

Commit for merging.

35. By Carla Sella

Uncommented line.

34. By Carla Sella

Working on alarmListRepeater problem.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'README.autopilot'
2--- README.autopilot 1970-01-01 00:00:00 +0000
3+++ README.autopilot 2014-07-28 20:36:30 +0000
4@@ -0,0 +1,37 @@
5+Running autopilot tests
6+=======================
7+
8+
9+Prerequisities:
10+
11+Install the following autopilot packages required to run the tests,
12+sudo apt-get install python-autopilot libautopilot-qt ubuntu-ui-toolkit-autopilot
13+
14+
15+
16+on the desktop:
17+
18+from terminal:
19+
20+1. Branch the code.
21+ bzr branch lp:ubuntu-clock-app/reboot
22+2. Navigate to the tests/autopilot directory.
23+ cd ubuntu-clock-app/reboot/tests/autopilot
24+3. run all tests.
25+ $ autopilot run -vv ubuntu_clock_app
26+
27+ to list all tests:
28+ $ autopilot list ubuntu_clock_app
29+
30+ To run only one test (for instance: test_add_single_type_alarm_must_add_to_alarm_list in TestAlarm.py):
31+ $ autopilot run -vv ubuntu_clock_app.tests.test_alarm.TestAlarm.test_add_single_type_alarm_must_add_to_alarm_list
32+
33+
34+
35+
36+on device:
37+
38+Using autopkg:
39+
40+1. navigate to the directory where the ubuntu-clock-app branch is and run:
41+ $ adt-run ubuntu-clock-app --click=com.ubuntu.clock.devel --- ssh -s /usr/share/autopkgtest/ssh-setup/adb
42
43=== modified file 'app/alarm/AlarmLabel.qml'
44--- app/alarm/AlarmLabel.qml 2014-07-17 12:21:45 +0000
45+++ app/alarm/AlarmLabel.qml 2014-07-28 20:36:30 +0000
46@@ -21,6 +21,7 @@
47
48 Page {
49 id: _alarmLabelPage
50+ objectName: "alarmLabelPage"
51
52 visible: false
53 title: i18n.tr("Label")
54@@ -44,6 +45,7 @@
55
56 TextField {
57 id: _labelEntry
58+ objectName: "labelEntry"
59 text: alarm.message
60 width: parent.width
61 }
62
63=== modified file 'app/alarm/AlarmList.qml'
64--- app/alarm/AlarmList.qml 2014-07-17 12:21:45 +0000
65+++ app/alarm/AlarmList.qml 2014-07-28 20:36:30 +0000
66@@ -58,14 +58,18 @@
67
68 Column {
69 id: alarmList
70+ objectName: 'alarmList'
71 anchors.fill: parent
72
73 Repeater {
74 model: alarmListFlickable.model
75+ objectName: "alarmListRepeater"
76 ListItem.Base {
77+ objectName: "alarm" + index
78
79 Label {
80 id: alarmTime
81+ objectName: "listAlarmTime" + index
82
83 anchors {
84 top: alarmDetailsColumn.top
85@@ -89,6 +93,7 @@
86
87 Label {
88 id: alarmLabel
89+ objectName: "listAlarmLabel" + index
90
91 text: message
92 fontSize: "medium"
93@@ -98,6 +103,7 @@
94
95 Label {
96 id: alarmSubtitle
97+ objectName: "listAlarmSubtitle" + index
98
99 fontSize: "xx-small"
100 width: parent.width
101@@ -108,6 +114,7 @@
102
103 Switch {
104 id: alarmStatus
105+ objectName: "listAlarmStatus" + index
106
107 anchors {
108 right: parent.right
109
110=== modified file 'app/alarm/AlarmPage.qml'
111--- app/alarm/AlarmPage.qml 2014-07-17 12:21:45 +0000
112+++ app/alarm/AlarmPage.qml 2014-07-28 20:36:30 +0000
113@@ -26,6 +26,7 @@
114 flickable: null
115
116 head.actions: Action {
117+ objectName: "addAlarmAction"
118 iconName: "add"
119 text: i18n.tr("Alarm")
120 onTriggered: {
121
122=== modified file 'app/alarm/AlarmRepeat.qml'
123--- app/alarm/AlarmRepeat.qml 2014-07-17 12:21:45 +0000
124+++ app/alarm/AlarmRepeat.qml 2014-07-28 20:36:30 +0000
125@@ -22,6 +22,7 @@
126
127 Page {
128 id: _alarmRepeatPage
129+ objectName: "alarmRepeatPage"
130
131 visible: false
132 title: i18n.tr("Repeat")
133@@ -75,12 +76,14 @@
134
135 Repeater {
136 id: _alarmDays
137+ objectName: 'alarmDays'
138
139 model: daysModel
140
141 ListItem.Standard {
142 Label {
143 id: _alarmDay
144+ objectName: 'alarmDay' + index
145
146 anchors {
147 left: parent.left
148@@ -93,6 +96,7 @@
149 }
150
151 control: Switch {
152+ objectName: 'daySwitch' + index
153 checked: (alarm.daysOfWeek & flag) == flag
154 onCheckedChanged: {
155 if (checked) {
156
157=== modified file 'app/alarm/AlarmSound.qml'
158--- app/alarm/AlarmSound.qml 2014-07-17 12:21:45 +0000
159+++ app/alarm/AlarmSound.qml 2014-07-28 20:36:30 +0000
160@@ -52,6 +52,7 @@
161
162 Repeater {
163 id: _alarmSounds
164+ objectName: "alarmSounds"
165
166 model: _soundModel
167
168@@ -64,6 +65,7 @@
169
170 Label {
171 id: _soundName
172+ objectName: "soundName" + index
173
174 anchors {
175 left: parent.left
176@@ -77,6 +79,7 @@
177
178 CheckBox {
179 id: _soundStatus
180+ objectName: "soundStatus" + index
181
182 anchors {
183 right: parent.right
184
185=== modified file 'app/alarm/EditAlarmPage.qml'
186--- app/alarm/EditAlarmPage.qml 2014-07-17 12:21:45 +0000
187+++ app/alarm/EditAlarmPage.qml 2014-07-28 20:36:30 +0000
188@@ -25,6 +25,7 @@
189
190 Page {
191 id: _addAlarmPage
192+ objectName: "AddAlarmPage"
193
194 // Property to determine if this is a new/saved alarm
195 property bool isNewAlarm: true
196@@ -47,6 +48,7 @@
197
198 actions: Action {
199 iconName: "ok"
200+ objectName: "saveAlarmAction"
201 text: i18n.tr("Alarm")
202 onTriggered: {
203 if(isNewAlarm) {
204@@ -171,6 +173,7 @@
205
206 SubtitledListItem {
207 id: _alarmRepeat
208+ objectName: "alarmRepeat"
209
210 text: i18n.tr("Repeat")
211 subText: alarmUtils.format_day_string(_alarm.daysOfWeek)
212@@ -180,6 +183,7 @@
213
214 SubtitledListItem {
215 id: _alarmLabel
216+ objectName: "alarmLabel"
217
218 text: i18n.tr("Label")
219 subText: _alarm.message
220@@ -189,6 +193,7 @@
221
222 SubtitledListItem {
223 id: _alarmSound
224+ objectName: "alarmSound"
225 /*
226 #TODO: Add support for choosing new alarm sound when indicator-
227 datetime supports custom alarm sounds
228
229=== modified file 'app/clock/ClockPage.qml'
230--- app/clock/ClockPage.qml 2014-07-21 16:48:11 +0000
231+++ app/clock/ClockPage.qml 2014-07-28 20:36:30 +0000
232@@ -20,7 +20,6 @@
233 import U1db 1.0 as U1db
234 import Ubuntu.Components 1.1
235 import "../components"
236-import "../worldclock"
237 import "../components/Utils.js" as Utils
238
239 PageWithBottomEdge {
240@@ -50,7 +49,6 @@
241 anchors.fill: parent
242 contentWidth: parent.width
243 contentHeight: clock.height + date.height + locationRow.height
244- + worldCityColumn.height + units.gu(20)
245
246 PullToAdd {
247 id: addCityButton
248@@ -144,10 +142,6 @@
249 }
250 }
251
252- UserWorldCityList {
253- id: worldCityColumn
254- }
255-
256 onDragEnded: {
257 if(contentY < _minThreshold) {
258 mainStack.push(Qt.resolvedUrl("../worldclock/WorldCityList.qml"))
259
260=== removed directory 'app/tests'
261=== removed directory 'app/tests/autopilot'
262=== removed file 'app/tests/autopilot/run'
263--- app/tests/autopilot/run 2014-06-06 18:45:49 +0000
264+++ app/tests/autopilot/run 1970-01-01 00:00:00 +0000
265@@ -1,11 +0,0 @@
266-#!/bin/bash
267-
268-if [[ -z `which autopilot` ]]; then
269- echo "Autopilot is not installed. Skip"
270- exit
271-fi
272-
273-SCRIPTPATH=`dirname $0`
274-pushd ${SCRIPTPATH}
275-autopilot run ubuntu-clock-app
276-popd
277
278=== removed directory 'app/tests/autopilot/ubuntu-clock-app'
279=== removed file 'app/tests/autopilot/ubuntu-clock-app/__init__.py'
280--- app/tests/autopilot/ubuntu-clock-app/__init__.py 2014-06-06 18:45:49 +0000
281+++ app/tests/autopilot/ubuntu-clock-app/__init__.py 1970-01-01 00:00:00 +0000
282@@ -1,132 +0,0 @@
283-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
284-
285-"""Ubuntu Touch App autopilot tests."""
286-
287-from os import remove
288-import os.path
289-from tempfile import mktemp
290-import subprocess
291-
292-from autopilot.input import Mouse, Touch, Pointer
293-from autopilot.matchers import Eventually
294-from autopilot.platform import model
295-from testtools.matchers import Is, Not, Equals
296-from autopilot.testcase import AutopilotTestCase
297-
298-def get_module_include_path():
299- return os.path.abspath(
300- os.path.join(
301- os.path.dirname(__file__),
302- '..',
303- '..',
304- '..',
305- '..',
306- 'backend',
307- 'modules')
308- )
309-
310-
311-class UbuntuTouchAppTestCase(AutopilotTestCase):
312- """A common test case class that provides several useful methods for the tests."""
313-
314- if model() == 'Desktop':
315- scenarios = [
316- ('with mouse', dict(input_device_class=Mouse))
317- ]
318- else:
319- scenarios = [
320- ('with touch', dict(input_device_class=Touch))
321- ]
322-
323- @property
324- def main_window(self):
325- return MainWindow(self.app)
326-
327-
328- def setUp(self):
329- self.pointing_device = Pointer(self.input_device_class.create())
330- super(UbuntuTouchAppTestCase, self).setUp()
331- self.launch_test_qml()
332-
333-
334- def launch_test_qml(self):
335- # If the test class has defined a 'test_qml' class attribute then we
336- # write it to disk and launch it inside the QML Scene. If not, then we
337- # silently do nothing (presumably the test has something else planned).
338- arch = subprocess.check_output(["dpkg-architecture",
339- "-qDEB_HOST_MULTIARCH"]).strip()
340- if hasattr(self, 'test_qml') and isinstance(self.test_qml, basestring):
341- qml_path = mktemp(suffix='.qml')
342- open(qml_path, 'w').write(self.test_qml)
343- self.addCleanup(remove, qml_path)
344-
345- self.app = self.launch_test_application(
346- "/usr/lib/" + arch + "/qt5/bin/qmlscene",
347- "-I", get_module_include_path(),
348- qml_path,
349- app_type='qt')
350-
351- if hasattr(self, 'test_qml_file') and isinstance(self.test_qml_file, basestring):
352- qml_path = self.test_qml_file
353- self.app = self.launch_test_application(
354- "/usr/lib/" + arch + "/qt5/bin/qmlscene",
355- "-I", get_module_include_path(),
356- qml_path,
357- app_type='qt')
358-
359- self.assertThat(self.get_qml_view().visible, Eventually(Equals(True)))
360-
361-
362- def get_qml_view(self):
363- """Get the main QML view"""
364-
365- return self.app.select_single("QQuickView")
366-
367- def get_mainview(self):
368- """Get the QML MainView"""
369-
370- mainView = self.app.select_single("MainView")
371- self.assertThat(mainView, Not(Is(None)))
372- return mainView
373-
374-
375- def get_object(self,objectName):
376- """Get a object based on the objectName"""
377-
378- obj = self.app.select_single(objectName=objectName)
379- self.assertThat(obj, Not(Is(None)))
380- return obj
381-
382-
383- def mouse_click(self,objectName):
384- """Move mouse on top of the object and click on it"""
385-
386- obj = self.get_object(objectName)
387- self.pointing_device.move_to_object(obj)
388- self.pointing_device.click()
389-
390-
391- def mouse_press(self,objectName):
392- """Move mouse on top of the object and press mouse button (without releasing it)"""
393-
394- obj = self.get_object(objectName)
395- self.pointing_device.move_to_object(obj)
396- self.pointing_device.press()
397-
398-
399- def mouse_release(self):
400- """Release mouse button"""
401-
402- self.pointing_device.release()
403-
404-
405- def type_string(self, string):
406- """Type a string with keyboard"""
407-
408- self.keyboard.type(string)
409-
410-
411- def type_key(self, key):
412- """Type a single key with keyboard"""
413-
414- self.keyboard.key(key)
415
416=== removed directory 'app/tests/autopilot/ubuntu-clock-app/main'
417=== removed file 'app/tests/autopilot/ubuntu-clock-app/main/__init__.py'
418--- app/tests/autopilot/ubuntu-clock-app/main/__init__.py 2014-06-06 18:45:49 +0000
419+++ app/tests/autopilot/ubuntu-clock-app/main/__init__.py 1970-01-01 00:00:00 +0000
420@@ -1,1 +0,0 @@
421-""" A main.qml test suite """
422
423=== removed file 'app/tests/autopilot/ubuntu-clock-app/main/test_main.py'
424--- app/tests/autopilot/ubuntu-clock-app/main/test_main.py 2014-06-06 18:45:49 +0000
425+++ app/tests/autopilot/ubuntu-clock-app/main/test_main.py 1970-01-01 00:00:00 +0000
426@@ -1,23 +0,0 @@
427-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
428-
429-"""Tests for the Hello World"""
430-
431-from autopilot.matchers import Eventually
432-from textwrap import dedent
433-from testtools.matchers import Is, Not, Equals
434-from testtools import skip
435-import os
436-from ubuntu-clock-app import UbuntuTouchAppTestCase
437-
438-
439-class MainTests(UbuntuTouchAppTestCase):
440- """Generic tests for the Hello World"""
441-
442- test_qml_file = "%s/%s.qml" % (os.path.dirname(os.path.realpath(__file__)),"../../../../ubuntu-clock-app")
443-
444- def test_0_can_select_mainView(self):
445- """Must be able to select the mainview."""
446-
447- mainView = self.get_mainview()
448- self.assertThat(mainView.visible,Eventually(Equals(True)))
449-
450
451=== removed directory 'app/tests/unit'
452=== removed file 'app/tests/unit/tst_hellocomponent.qml'
453--- app/tests/unit/tst_hellocomponent.qml 2014-06-06 18:45:49 +0000
454+++ app/tests/unit/tst_hellocomponent.qml 1970-01-01 00:00:00 +0000
455@@ -1,49 +0,0 @@
456-import QtQuick 2.0
457-import QtTest 1.0
458-import Ubuntu.Components 0.1
459-import "../../components"
460-
461-// See more details @ http://qt-project.org/doc/qt-5.0/qtquick/qml-testcase.html
462-
463-// Execute tests with:
464-// qmltestrunner
465-
466-Item {
467- // The objects
468- HelloComponent {
469- id: objectUnderTest
470- }
471-
472- TestCase {
473- name: "HelloComponent"
474-
475- function init() {
476- console.debug(">> init");
477- compare("",objectUnderTest.text,"text was not empty on init");
478- console.debug("<< init");
479- }
480-
481- function cleanup() {
482- console.debug(">> cleanup");
483- console.debug("<< cleanup");
484- }
485-
486- function initTestCase() {
487- console.debug(">> initTestCase");
488- console.debug("<< initTestCase");
489- }
490-
491- function cleanupTestCase() {
492- console.debug(">> cleanupTestCase");
493- console.debug("<< cleanupTestCase");
494- }
495-
496- function test_canReadAndWriteText() {
497- var expected = "Hello World";
498-
499- objectUnderTest.text = expected;
500-
501- compare(expected,objectUnderTest.text,"expected did not equal result");
502- }
503- }
504-}
505
506=== removed file 'app/worldclock/UserWorldCityList.qml'
507--- app/worldclock/UserWorldCityList.qml 2014-07-22 13:02:03 +0000
508+++ app/worldclock/UserWorldCityList.qml 1970-01-01 00:00:00 +0000
509@@ -1,154 +0,0 @@
510-/*
511- * Copyright (C) 2014 Canonical Ltd
512- *
513- * This file is part of Ubuntu Clock App
514- *
515- * Ubuntu Clock App is free software: you can redistribute it and/or modify
516- * it under the terms of the GNU General Public License version 3 as
517- * published by the Free Software Foundation.
518- *
519- * Ubuntu Clock App is distributed in the hope that it will be useful,
520- * but WITHOUT ANY WARRANTY; without even the implied warranty of
521- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
522- * GNU General Public License for more details.
523- *
524- * You should have received a copy of the GNU General Public License
525- * along with this program. If not, see <http://www.gnu.org/licenses/>.
526- */
527-
528-import QtQuick 2.0
529-import Timezone 1.0
530-import U1db 1.0 as U1db
531-import Ubuntu.Components 1.1
532-import "../components"
533-import "../components/Utils.js" as Utils
534-
535-Column {
536- id: worldCityColumn
537-
538- function getTimeDiff(time) {
539- var hours, minutes;
540- time = Math.floor(time / 60)
541- minutes = time % 60
542- hours = Math.floor(time / 60)
543- return [hours, minutes]
544- }
545-
546- anchors.top: locationRow.bottom
547- anchors.topMargin: units.gu(6)
548- width: parent.width
549-
550- // U1db Index to index all documents storing the world city details
551- U1db.Index {
552- id: by_worldcity
553- database: clockDB
554- expression: [
555- "worldlocation.city",
556- "worldlocation.country",
557- "worldlocation.timezone"
558- ]
559- }
560-
561- // U1db Query to create a model of the world cities saved by the user
562- U1db.Query {
563- id: worldCityQuery
564- index: by_worldcity
565- query: ["*","*","*"]
566- }
567-
568- GenericTimeZoneModel {
569- id: u1dbModel
570- updateInterval: 1000
571- results: worldCityQuery.results
572- }
573-
574- Repeater {
575- model: u1dbModel
576- delegate: SubtitledListItem {
577-
578- height: units.gu(8)
579-
580- text: model.city
581- subText: model.country
582- showDivider: false
583- removable: true
584- confirmRemoval: true
585-
586- Label {
587- id: localTimeLabel
588-
589- anchors.centerIn: parent
590- fontSize: "large"
591- text: model.localTime
592- }
593-
594- Label {
595- id: relativeTimeLabel
596-
597- anchors.right: parent.right
598- anchors.verticalCenter: parent.verticalCenter
599-
600- fontSize: "xx-small"
601- horizontalAlignment: Text.AlignRight
602- text: {
603- var day;
604-
605- if(model.daysTo === 0) {
606- day = i18n.tr("Today")
607- }
608-
609- else if(model.daysTo === 1) {
610- day = i18n.tr("Tomorrow")
611- }
612-
613- else if(model.daysTo === -1) {
614- day = i18n.tr("Yesterday")
615- }
616-
617- var isBehind = model.timeTo > 0 ? i18n.tr("behind")
618- : i18n.tr("ahead")
619-
620- var timediff = worldCityColumn.getTimeDiff(Math.abs(model.timeTo))
621- var minute = timediff[1]
622- var hour = timediff[0]
623-
624- if(hour > 0 && minute > 0) {
625- return ("%1\n%2hr%3min %4")
626- .arg(day)
627- .arg(hour)
628- .arg(minute)
629- .arg(isBehind)
630- }
631-
632- else if(hour > 0 && minute === 0) {
633- return ("%1\n%2hr %3")
634- .arg(day)
635- .arg(hour)
636- .arg(isBehind)
637- }
638-
639- else if(hour === 0 && minute > 0) {
640- return ("%1\n%2min %3")
641- .arg(day)
642- .arg(minute)
643- .arg(isBehind)
644- }
645-
646- else {
647- return i18n.tr("No Time Difference")
648- }
649- }
650- }
651-
652- onItemRemoved: {
653- /*
654- NOTE: This causes the document to be deleted twice resulting
655- in an error. The bug has been reported at
656- https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1276118
657- */
658- Utils.log("Deleting world location: " + model.city)
659- clockDB.deleteDoc(worldCityQuery.documents[index])
660- }
661- }
662- }
663-}
664
665=== modified file 'app/worldclock/WorldCityList.qml'
666--- app/worldclock/WorldCityList.qml 2014-07-22 14:01:43 +0000
667+++ app/worldclock/WorldCityList.qml 2014-07-28 20:36:30 +0000
668@@ -69,8 +69,6 @@
669 contents: TextField {
670 id: searchField
671
672- inputMethodHints: Qt.ImhNoPredictiveText
673-
674 anchors {
675 left: parent ? parent.left : undefined
676 right: parent ? parent.right : undefined
677@@ -85,21 +83,9 @@
678 }
679 ]
680
681- Connections {
682- target: clockApp
683- onApplicationStateChanged: {
684- /*
685- Update world city list immediately when the clock app is brought
686- from suspend instead of waiting for the next minute to update.
687- */
688- if(applicationState)
689- timeZoneModel.update()
690- }
691- }
692-
693 XmlTimeZoneModel {
694 id: timeZoneModel
695- updateInterval: 60000
696+ updateInterval: 1000
697 source: Qt.resolvedUrl("world-city-list.xml")
698 }
699
700@@ -113,22 +99,6 @@
701 ListView {
702 id: cityList
703
704- function addWorldCity(city, country, timezone) {
705- console.log("[LOG]: Adding city to U1db Database")
706- clockDB.putDoc
707- (
708- {
709- "worldlocation":
710- {
711- "city": city,
712- "country": country,
713- "timezone": timezone
714- }
715- },
716- encodeURIComponent(city + "_" + country)
717- )
718- }
719-
720 anchors.fill: parent
721
722 model: sortedTimeZoneModel
723@@ -166,8 +136,10 @@
724 }
725
726 onClicked: {
727- cityList.addWorldCity(city, country, timezoneID)
728- mainStack.pop()
729+ /*
730+ #TODO: Add support for saving chosen city permanently to disk
731+ */
732+ console.log("#TODO: Add city to U1DB Model")
733 }
734 }
735 }
736
737=== modified file 'app/worldclock/world-city-list.xml'
738--- app/worldclock/world-city-list.xml 2014-07-22 14:50:43 +0000
739+++ app/worldclock/world-city-list.xml 2014-07-28 20:36:30 +0000
740@@ -21,8 +21,8 @@
741 <countryName>Australia</countryName>
742 </City>
743 <City>
744- <cityName>Albuquerque</cityName>
745- <timezoneID>America/Denver</timezoneID>
746+ <cityName>Alaska</cityName>
747+ <timezoneID>America/Anchorage</timezoneID>
748 <countryName>United States</countryName>
749 </City>
750 <City>
751@@ -56,39 +56,19 @@
752 <countryName>United States</countryName>
753 </City>
754 <City>
755- <cityName>Andorra</cityName>
756- <timezoneID>Europe/Andorra</timezoneID>
757- <countryName>Andorra</countryName>
758- </City>
759- <City>
760- <cityName>Ankara</cityName>
761- <timezoneID>Europe/Istanbul</timezoneID>
762- <countryName>Turkey</countryName>
763- </City>
764- <City>
765- <cityName>Ann Arbor</cityName>
766- <timezoneID>America/Detroit</timezoneID>
767- <countryName>United States</countryName>
768- </City>
769- <City>
770 <cityName>Antananarivo</cityName>
771 <timezoneID>Indian/Antananarivo</timezoneID>
772 <countryName>Madagascar</countryName>
773 </City>
774 <City>
775- <cityName>Aqtau</cityName>
776- <timezoneID>Asia/Aqtau</timezoneID>
777- <countryName>Kazakhstan</countryName>
778+ <cityName>Antigua</cityName>
779+ <timezoneID>America/Antigua</timezoneID>
780+ <countryName>Spain</countryName>
781 </City>
782 <City>
783 <cityName>Aruba</cityName>
784 <timezoneID>America/Aruba</timezoneID>
785- <countryName>Aruba</countryName>
786- </City>
787- <City>
788- <cityName>Asunción</cityName>
789- <timezoneID>America/Asuncion</timezoneID>
790- <countryName>Paraguay</countryName>
791+ <countryName>Indonesia</countryName>
792 </City>
793 <City>
794 <cityName>Athens</cityName>
795@@ -96,19 +76,14 @@
796 <countryName>Greece</countryName>
797 </City>
798 <City>
799- <cityName>Atlanta</cityName>
800- <timezoneID>America/New_York</timezoneID>
801- <countryName>United States</countryName>
802- </City>
803- <City>
804 <cityName>Auckland</cityName>
805 <timezoneID>Pacific/Auckland</timezoneID>
806 <countryName>New Zealand</countryName>
807 </City>
808 <City>
809- <cityName>Austin</cityName>
810- <timezoneID>America/Chicago</timezoneID>
811- <countryName>United States</countryName>
812+ <cityName>Azores</cityName>
813+ <timezoneID>Atlantic/Azores</timezoneID>
814+ <countryName>Portugal</countryName>
815 </City>
816 <City>
817 <cityName>Baghdad</cityName>
818@@ -116,41 +91,16 @@
819 <countryName>Iraq</countryName>
820 </City>
821 <City>
822- <cityName>Bahrain</cityName>
823- <timezoneID>Asia/Bahrain</timezoneID>
824- <countryName>Bahrain</countryName>
825- </City>
826- <City>
827 <cityName>Baku</cityName>
828 <timezoneID>Asia/Baku</timezoneID>
829 <countryName>Azerbaijan</countryName>
830 </City>
831 <City>
832- <cityName>Baltimore</cityName>
833- <timezoneID>America/New_York</timezoneID>
834- <countryName>United States</countryName>
835- </City>
836- <City>
837- <cityName>Bangalore</cityName>
838- <timezoneID>Asia/Kolkata</timezoneID>
839- <countryName>India</countryName>
840- </City>
841- <City>
842 <cityName>Bangkok</cityName>
843 <timezoneID>Asia/Bangkok</timezoneID>
844 <countryName>Thailand</countryName>
845 </City>
846 <City>
847- <cityName>Barbados</cityName>
848- <timezoneID>America/Barbados</timezoneID>
849- <countryName>Barbados</countryName>
850- </City>
851- <City>
852- <cityName>Barcelona</cityName>
853- <timezoneID>Europe/Madrid</timezoneID>
854- <countryName>Spain</countryName>
855- </City>
856- <City>
857 <cityName>Beijing</cityName>
858 <timezoneID>Asia/Shanghai</timezoneID>
859 <countryName>China</countryName>
860@@ -171,61 +121,21 @@
861 <countryName>Serbia</countryName>
862 </City>
863 <City>
864- <cityName>Belize</cityName>
865- <timezoneID>America/Belize</timezoneID>
866- <countryName>Belize</countryName>
867- </City>
868- <City>
869- <cityName>Belo Horizonte</cityName>
870- <timezoneID>America/Sao_Paulo</timezoneID>
871- <countryName>Brazil</countryName>
872- </City>
873- <City>
874 <cityName>Berlin</cityName>
875 <timezoneID>Europe/Berlin</timezoneID>
876 <countryName>Germany</countryName>
877 </City>
878 <City>
879- <cityName>Bermuda</cityName>
880- <timezoneID>Atlantic/Bermuda</timezoneID>
881- <countryName>Bermuda</countryName>
882- </City>
883- <City>
884 <cityName>Beulah</cityName>
885 <timezoneID>America/North_Dakota/Beulah</timezoneID>
886 <countryName>United States</countryName>
887 </City>
888 <City>
889- <cityName>Black Rock City</cityName>
890- <timezoneID>America/Chicago</timezoneID>
891- <countryName>United States</countryName>
892- </City>
893- <City>
894 <cityName>Blantyre</cityName>
895 <timezoneID>Africa/Blantyre</timezoneID>
896 <countryName>Malawi</countryName>
897 </City>
898 <City>
899- <cityName>Bogotá</cityName>
900- <timezoneID>America/Bogota</timezoneID>
901- <countryName>Colombia</countryName>
902- </City>
903- <City>
904- <cityName>Boston</cityName>
905- <timezoneID>America/New_York</timezoneID>
906- <countryName>United States</countryName>
907- </City>
908- <City>
909- <cityName>Boulder</cityName>
910- <timezoneID>America/Denver</timezoneID>
911- <countryName>United States</countryName>
912- </City>
913- <City>
914- <cityName>Brasília</cityName>
915- <timezoneID>America/Sao_Paulo</timezoneID>
916- <countryName>Brazil</countryName>
917- </City>
918- <City>
919 <cityName>Bratislava</cityName>
920 <timezoneID>Europe/Bratislava</timezoneID>
921 <countryName>Slovakia</countryName>
922@@ -271,16 +181,6 @@
923 <countryName>India</countryName>
924 </City>
925 <City>
926- <cityName>Calgary</cityName>
927- <timezoneID>America/Edmonton</timezoneID>
928- <countryName>Canada</countryName>
929- </City>
930- <City>
931- <cityName>Cambridge</cityName>
932- <timezoneID>Europe/London</timezoneID>
933- <countryName>United Kingdom</countryName>
934- </City>
935- <City>
936 <cityName>Canary</cityName>
937 <timezoneID>Atlantic/Canary</timezoneID>
938 <countryName>Australia</countryName>
939@@ -291,16 +191,6 @@
940 <countryName>Australia</countryName>
941 </City>
942 <City>
943- <cityName>Cancún</cityName>
944- <timezoneID>America/Cancun</timezoneID>
945- <countryName>Mexico</countryName>
946- </City>
947- <City>
948- <cityName>Cape Town</cityName>
949- <timezoneID>Africa/Johannesburg</timezoneID>
950- <countryName>South Africa</countryName>
951- </City>
952- <City>
953 <cityName>Caracas</cityName>
954 <timezoneID>America/Caracas</timezoneID>
955 <countryName>Venezuela</countryName>
956@@ -326,31 +216,11 @@
957 <countryName>Mexico</countryName>
958 </City>
959 <City>
960- <cityName>Chişinău</cityName>
961- <timezoneID>Europe/Chisinau</timezoneID>
962- <countryName>Moldova</countryName>
963- </City>
964- <City>
965- <cityName>Cincinnati</cityName>
966- <timezoneID>America/New_York</timezoneID>
967- <countryName>United States</countryName>
968- </City>
969- <City>
970- <cityName>Cleveland</cityName>
971- <timezoneID>America/New_York</timezoneID>
972- <countryName>United States</countryName>
973- </City>
974- <City>
975 <cityName>Colombo</cityName>
976 <timezoneID>Asia/Colombo</timezoneID>
977 <countryName>Sri Lanka</countryName>
978 </City>
979 <City>
980- <cityName>Columbus</cityName>
981- <timezoneID>America/New_York</timezoneID>
982- <countryName>United States</countryName>
983- </City>
984- <City>
985 <cityName>Conakry</cityName>
986 <timezoneID>Africa/Conakry</timezoneID>
987 <countryName>Guinea</countryName>
988@@ -359,16 +229,6 @@
989 <cityName>Copenhagen</cityName>
990 <timezoneID>Europe/Copenhagen</timezoneID>
991 <countryName>Denmark</countryName>
992- </City>
993- <City>
994- <cityName>Costa Rica</cityName>
995- <timezoneID>America/Costa_Rica</timezoneID>
996- <countryName>Costa Rica</countryName>
997- </City>
998- <City>
999- <cityName>Curaçao</cityName>
1000- <timezoneID>America/Curacao</timezoneID>
1001- <countryName>Curacao</countryName>
1002 </City>
1003 <City>
1004 <cityName>Dakar</cityName>
1005@@ -376,11 +236,6 @@
1006 <countryName>Senegal</countryName>
1007 </City>
1008 <City>
1009- <cityName>Dallas</cityName>
1010- <timezoneID>America/Chicago</timezoneID>
1011- <countryName>United States</countryName>
1012- </City>
1013- <City>
1014 <cityName>Damascus</cityName>
1015 <timezoneID>Asia/Damascus</timezoneID>
1016 <countryName>Syria</countryName>
1017@@ -401,11 +256,6 @@
1018 <countryName>Canada</countryName>
1019 </City>
1020 <City>
1021- <cityName>Delhi</cityName>
1022- <timezoneID>Asia/Kolkata</timezoneID>
1023- <countryName>India</countryName>
1024- </City>
1025- <City>
1026 <cityName>Denver</cityName>
1027 <timezoneID>America/Denver</timezoneID>
1028 <countryName>United States</countryName>
1029@@ -426,16 +276,6 @@
1030 <countryName>Djibouti</countryName>
1031 </City>
1032 <City>
1033- <cityName>Doha</cityName>
1034- <timezoneID>Asia/Qatar</timezoneID>
1035- <countryName>Qatar</countryName>
1036- </City>
1037- <City>
1038- <cityName>Dominica</cityName>
1039- <timezoneID>America/Dominica</timezoneID>
1040- <countryName>Dominica</countryName>
1041- </City>
1042- <City>
1043 <cityName>Dubai</cityName>
1044 <timezoneID>Asia/Dubai</timezoneID>
1045 <countryName>United Arab Emirates</countryName>
1046@@ -446,41 +286,16 @@
1047 <countryName>Ireland</countryName>
1048 </City>
1049 <City>
1050- <cityName>Easter Island</cityName>
1051- <timezoneID>Pacific/Easter</timezoneID>
1052- <countryName>Chile</countryName>
1053- </City>
1054- <City>
1055 <cityName>Edmonton</cityName>
1056 <timezoneID>America/Edmonton</timezoneID>
1057 <countryName>Canada</countryName>
1058 </City>
1059 <City>
1060- <cityName>El Salvador</cityName>
1061- <timezoneID>America/El_Salvador</timezoneID>
1062- <countryName>El Salvador</countryName>
1063- </City>
1064- <City>
1065- <cityName>Fiji</cityName>
1066- <timezoneID>Pacific/Fiji</timezoneID>
1067- <countryName>Fiji</countryName>
1068- </City>
1069- <City>
1070 <cityName>Fortaleza</cityName>
1071 <timezoneID>America/Fortaleza</timezoneID>
1072 <countryName>Brazil</countryName>
1073 </City>
1074 <City>
1075- <cityName>Frankfurt</cityName>
1076- <timezoneID>Europe/Berlin</timezoneID>
1077- <countryName>Germany</countryName>
1078- </City>
1079- <City>
1080- <cityName>Freetown</cityName>
1081- <timezoneID>Africa/Freetown</timezoneID>
1082- <countryName>Sierra Leone</countryName>
1083- </City>
1084- <City>
1085 <cityName>Gaborone</cityName>
1086 <timezoneID>Africa/Gaborone</timezoneID>
1087 <countryName>Botswana</countryName>
1088@@ -489,892 +304,7 @@
1089 <cityName>Gaza</cityName>
1090 <timezoneID>Asia/Gaza</timezoneID>
1091 <countryName>Palestine</countryName>
1092- </City>
1093- <City>
1094- <cityName>Gibraltar</cityName>
1095- <timezoneID>Europe/Gibraltar</timezoneID>
1096- <countryName>Gibraltar</countryName>
1097- </City>
1098- <City>
1099- <cityName>Grand Turk</cityName>
1100- <timezoneID>America/Grand_Turk</timezoneID>
1101- <countryName>Turks and Caicos Islands</countryName>
1102- </City>
1103- <City>
1104- <cityName>Grenada</cityName>
1105- <timezoneID>America/Grenada</timezoneID>
1106- <countryName>Grenada</countryName>
1107- </City>
1108- <City>
1109- <cityName>Guam</cityName>
1110- <timezoneID>Pacific/Guam</timezoneID>
1111- <countryName>Guam</countryName>
1112- </City>
1113- <City>
1114- <cityName>Guangzhou</cityName>
1115- <timezoneID>Asia/Shanghai</timezoneID>
1116- <countryName>China</countryName>
1117- </City>
1118- <City>
1119- <cityName>Guatemala</cityName>
1120- <timezoneID>America/Guatemala</timezoneID>
1121- <countryName>Guatemala</countryName>
1122- </City>
1123- <City>
1124- <cityName>Gurgaon</cityName>
1125- <timezoneID>Asia/Kolkata</timezoneID>
1126- <countryName>India</countryName>
1127- </City>
1128- <City>
1129- <cityName>Guyana</cityName>
1130- <timezoneID>America/Guyana</timezoneID>
1131- <countryName>Guyana</countryName>
1132- </City>
1133- <City>
1134- <cityName>Haifa</cityName>
1135- <timezoneID>Asia/Jerusalem</timezoneID>
1136- <countryName>Israel</countryName>
1137- </City>
1138- <City>
1139- <cityName>Halifax</cityName>
1140- <timezoneID>America/Halifax</timezoneID>
1141- <countryName>Canada</countryName>
1142- </City>
1143- <City>
1144- <cityName>Hamburg</cityName>
1145- <timezoneID>Europe/Berlin</timezoneID>
1146- <countryName>Germany</countryName>
1147- </City>
1148- <City>
1149- <cityName>Hanoi</cityName>
1150- <timezoneID>Asia/Ho_Chi_Minh</timezoneID>
1151- <countryName>Vietnam</countryName>
1152- </City>
1153- <City>
1154- <cityName>Harare</cityName>
1155- <timezoneID>Africa/Harare</timezoneID>
1156- <countryName>Zimbabwe</countryName>
1157- </City>
1158- <City>
1159- <cityName>Havana</cityName>
1160- <timezoneID>America/Havana</timezoneID>
1161- <countryName>Cuba</countryName>
1162- </City>
1163- <City>
1164- <cityName>Hebron</cityName>
1165- <timezoneID>Asia/Hebron</timezoneID>
1166- <countryName>Palestine</countryName>
1167- </City>
1168- <City>
1169- <cityName>Helsinki</cityName>
1170- <timezoneID>Europe/Helsinki</timezoneID>
1171- <countryName>Finland</countryName>
1172- </City>
1173- <City>
1174- <cityName>Ho Chi Minh City</cityName>
1175- <timezoneID>Asia/Ho_Chi_Minh</timezoneID>
1176- <countryName>Vietnam</countryName>
1177- </City>
1178- <City>
1179- <cityName>Hong Kong</cityName>
1180- <timezoneID>Asia/Hong_Kong</timezoneID>
1181- <countryName>Hong Kong</countryName>
1182- </City>
1183- <City>
1184- <cityName>Honolulu</cityName>
1185- <timezoneID>Pacific/Honolulu</timezoneID>
1186- <countryName>United States</countryName>
1187- </City>
1188- <City>
1189- <cityName>Houston</cityName>
1190- <timezoneID>America/Chicago</timezoneID>
1191- <countryName>United States</countryName>
1192- </City>
1193- <City>
1194- <cityName>Hyderabad</cityName>
1195- <timezoneID>Asia/Kolkata</timezoneID>
1196- <countryName>India</countryName>
1197- </City>
1198- <City>
1199- <cityName>Indianapolis</cityName>
1200- <timezoneID>America/Indiana/Indianapolis</timezoneID>
1201- <countryName>United States</countryName>
1202- </City>
1203- <City>
1204- <cityName>Islamabad</cityName>
1205- <timezoneID>Asia/Karachi</timezoneID>
1206- <countryName>Pakistan</countryName>
1207- </City>
1208- <City>
1209- <cityName>Isle of Man</cityName>
1210- <timezoneID>Europe/Isle_of_Man</timezoneID>
1211- <countryName>Isle of Man</countryName>
1212- </City>
1213- <City>
1214- <cityName>Istanbul</cityName>
1215- <timezoneID>Europe/Istanbul</timezoneID>
1216- <countryName>Turkey</countryName>
1217- </City>
1218- <City>
1219- <cityName>Jacksonville</cityName>
1220- <timezoneID>America/New_York</timezoneID>
1221- <countryName>United States</countryName>
1222- </City>
1223- <City>
1224- <cityName>Jakarta</cityName>
1225- <timezoneID>Asia/Jakarta</timezoneID>
1226- <countryName>Indonesia</countryName>
1227- </City>
1228- <City>
1229- <cityName>Jerusalem</cityName>
1230- <timezoneID>Asia/Jerusalem</timezoneID>
1231- <countryName>Israel</countryName>
1232- </City>
1233- <City>
1234- <cityName>Johannesburg</cityName>
1235- <timezoneID>Africa/Johannesburg</timezoneID>
1236- <countryName>South Africa</countryName>
1237- </City>
1238- <City>
1239- <cityName>Kabul</cityName>
1240- <timezoneID>Asia/Kabul</timezoneID>
1241- <countryName>Afghanistan</countryName>
1242- </City>
1243- <City>
1244- <cityName>Kampala</cityName>
1245- <timezoneID>Africa/Kampala</timezoneID>
1246- <countryName>Uganda</countryName>
1247- </City>
1248- <City>
1249- <cityName>Karachi</cityName>
1250- <timezoneID>Asia/Karachi</timezoneID>
1251- <countryName>Pakistan</countryName>
1252- </City>
1253- <City>
1254- <cityName>Khartoum</cityName>
1255- <timezoneID>Africa/Khartoum</timezoneID>
1256- <countryName>Sudan</countryName>
1257- </City>
1258- <City>
1259- <cityName>Kiev</cityName>
1260- <timezoneID>Europe/Kiev</timezoneID>
1261- <countryName>Ukraine</countryName>
1262- </City>
1263- <City>
1264- <cityName>Kigali</cityName>
1265- <timezoneID>Africa/Kigali</timezoneID>
1266- <countryName>Rwanda</countryName>
1267- </City>
1268- <City>
1269- <cityName>Kingston</cityName>
1270- <timezoneID>America/Toronto</timezoneID>
1271- <countryName>Canada</countryName>
1272- </City>
1273- <City>
1274- <cityName>Kinshasa</cityName>
1275- <timezoneID>Africa/Kinshasa</timezoneID>
1276- <countryName>Democratic Republic of the Congo</countryName>
1277- </City>
1278- <City>
1279- <cityName>Kiritimati</cityName>
1280- <timezoneID>Pacific/Kiritimati</timezoneID>
1281- <countryName>Kiribati</countryName>
1282- </City>
1283- <City>
1284- <cityName>Kirkland</cityName>
1285- <timezoneID>America/Montreal</timezoneID>
1286- <countryName>Canada</countryName>
1287- </City>
1288- <City>
1289- <cityName>Knox</cityName>
1290- <timezoneID>Australia/Melbourne</timezoneID>
1291- <countryName>Australia</countryName>
1292- </City>
1293- <City>
1294- <cityName>Knoxville</cityName>
1295- <timezoneID>America/New_York</timezoneID>
1296- <countryName>United States</countryName>
1297- </City>
1298- <City>
1299- <cityName>Kraków</cityName>
1300- <timezoneID>Europe/Warsaw</timezoneID>
1301- <countryName>Poland</countryName>
1302- </City>
1303- <City>
1304- <cityName>Kuala Lumpur</cityName>
1305- <timezoneID>Asia/Kuala_Lumpur</timezoneID>
1306- <countryName>Malaysia</countryName>
1307- </City>
1308- <City>
1309- <cityName>Kuwait City</cityName>
1310- <timezoneID>Asia/Kuwait</timezoneID>
1311- <countryName>Kuwait</countryName>
1312- </City>
1313- <City>
1314- <cityName>Kyiv</cityName>
1315- <timezoneID>Europe/Kiev</timezoneID>
1316- <countryName>Ukraine</countryName>
1317- </City>
1318- <City>
1319- <cityName>Lagos</cityName>
1320- <timezoneID>Africa/Lagos</timezoneID>
1321- <countryName>Nigeria</countryName>
1322- </City>
1323- <City>
1324- <cityName>Lahore</cityName>
1325- <timezoneID>Asia/Karachi</timezoneID>
1326- <countryName>Pakistan</countryName>
1327- </City>
1328- <City>
1329- <cityName>Las Vegas</cityName>
1330- <timezoneID>America/Los_Angeles</timezoneID>
1331- <countryName>United States</countryName>
1332- </City>
1333- <City>
1334- <cityName>Lima</cityName>
1335- <timezoneID>America/Lima</timezoneID>
1336- <countryName>Peru</countryName>
1337- </City>
1338- <City>
1339- <cityName>Lisbon</cityName>
1340- <timezoneID>Europe/Lisbon</timezoneID>
1341- <countryName>Portugal</countryName>
1342- </City>
1343- <City>
1344- <cityName>London</cityName>
1345- <timezoneID>Europe/London</timezoneID>
1346- <countryName>United Kingdom</countryName>
1347- </City>
1348- <City>
1349- <cityName>Longyearbyen</cityName>
1350- <timezoneID>Arctic/Longyearbyen</timezoneID>
1351- <countryName>Svalbard and Jan Mayen</countryName>
1352- </City>
1353- <City>
1354- <cityName>Los Angeles</cityName>
1355- <timezoneID>America/Los_Angeles</timezoneID>
1356- <countryName>United States</countryName>
1357- </City>
1358- <City>
1359- <cityName>Louisville</cityName>
1360- <timezoneID>America/Kentucky/Louisville</timezoneID>
1361- <countryName>United States</countryName>
1362- </City>
1363- <City>
1364- <cityName>Luxembourg</cityName>
1365- <timezoneID>Europe/Luxembourg</timezoneID>
1366- <countryName>Luxembourg</countryName>
1367- </City>
1368- <City>
1369- <cityName>Macau</cityName>
1370- <timezoneID>Asia/Macau</timezoneID>
1371- <countryName>Macao</countryName>
1372- </City>
1373- <City>
1374- <cityName>Madison</cityName>
1375- <timezoneID>America/Chicago</timezoneID>
1376- <countryName>United States</countryName>
1377- </City>
1378- <City>
1379- <cityName>Madrid</cityName>
1380- <timezoneID>Europe/Madrid</timezoneID>
1381- <countryName>Spain</countryName>
1382- </City>
1383- <City>
1384- <cityName>Maldives</cityName>
1385- <timezoneID>Indian/Maldives</timezoneID>
1386- <countryName>Maldives</countryName>
1387- </City>
1388- <City>
1389- <cityName>Malta</cityName>
1390- <timezoneID>Europe/Malta</timezoneID>
1391- <countryName>Malta</countryName>
1392- </City>
1393- <City>
1394- <cityName>Managua</cityName>
1395- <timezoneID>America/Managua</timezoneID>
1396- <countryName>Nicaragua</countryName>
1397- </City>
1398- <City>
1399- <cityName>Manchester</cityName>
1400- <timezoneID>Europe/London</timezoneID>
1401- <countryName>United Kingdom</countryName>
1402- </City>
1403- <City>
1404- <cityName>Manila</cityName>
1405- <timezoneID>Asia/Manila</timezoneID>
1406- <countryName>Philippines</countryName>
1407- </City>
1408- <City>
1409- <cityName>Marengo</cityName>
1410- <timezoneID>America/Indiana/Marengo</timezoneID>
1411- <countryName>United States</countryName>
1412- </City>
1413- <City>
1414- <cityName>Martinique</cityName>
1415- <timezoneID>America/Martinique</timezoneID>
1416- <countryName>Canada</countryName>
1417- </City>
1418- <City>
1419- <cityName>Maseru</cityName>
1420- <timezoneID>Africa/Maseru</timezoneID>
1421- <countryName>Lesotho</countryName>
1422- </City>
1423- <City>
1424- <cityName>Melbourne</cityName>
1425- <timezoneID>Australia/Melbourne</timezoneID>
1426- <countryName>Australia</countryName>
1427- </City>
1428- <City>
1429- <cityName>Memphis</cityName>
1430- <timezoneID>America/Chicago</timezoneID>
1431- <countryName>United States</countryName>
1432- </City>
1433- <City>
1434- <cityName>Mendoza</cityName>
1435- <timezoneID>America/Argentina/Mendoza</timezoneID>
1436- <countryName>Argentina</countryName>
1437- </City>
1438- <City>
1439- <cityName>Metlakatla</cityName>
1440- <timezoneID>America/Metlakatla</timezoneID>
1441- <countryName>United States</countryName>
1442- </City>
1443- <City>
1444- <cityName>Mexico City</cityName>
1445- <timezoneID>America/Mexico_City</timezoneID>
1446- <countryName>Mexico</countryName>
1447- </City>
1448- <City>
1449- <cityName>Miami</cityName>
1450- <timezoneID>America/New_York</timezoneID>
1451- <countryName>United States</countryName>
1452- </City>
1453- <City>
1454- <cityName>Milan</cityName>
1455- <timezoneID>Europe/Rome</timezoneID>
1456- <countryName>Italy</countryName>
1457- </City>
1458- <City>
1459- <cityName>Milwaukee</cityName>
1460- <timezoneID>America/Chicago</timezoneID>
1461- <countryName>United States</countryName>
1462- </City>
1463- <City>
1464- <cityName>Minneapolis</cityName>
1465- <timezoneID>America/Chicago</timezoneID>
1466- <countryName>United States</countryName>
1467- </City>
1468- <City>
1469- <cityName>Minsk</cityName>
1470- <timezoneID>Europe/Minsk</timezoneID>
1471- <countryName>Belarus</countryName>
1472- </City>
1473- <City>
1474- <cityName>Mogadishu</cityName>
1475- <timezoneID>Africa/Mogadishu</timezoneID>
1476- <countryName>Somalia</countryName>
1477- </City>
1478- <City>
1479- <cityName>Monrovia</cityName>
1480- <timezoneID>Africa/Monrovia</timezoneID>
1481- <countryName>Liberia</countryName>
1482- </City>
1483- <City>
1484- <cityName>Monaco</cityName>
1485- <timezoneID>Europe/Monaco</timezoneID>
1486- <countryName>Monaco</countryName>
1487- </City>
1488- <City>
1489- <cityName>Monterrey</cityName>
1490- <timezoneID>America/Monterrey</timezoneID>
1491- <countryName>Mexico</countryName>
1492- </City>
1493- <City>
1494- <cityName>Montevideo</cityName>
1495- <timezoneID>America/Montevideo</timezoneID>
1496- <countryName>Uruguay</countryName>
1497- </City>
1498- <City>
1499- <cityName>Montreal</cityName>
1500- <timezoneID>America/Montreal</timezoneID>
1501- <countryName>Canada</countryName>
1502- </City>
1503- <City>
1504- <cityName>Moscow</cityName>
1505- <timezoneID>Europe/Moscow</timezoneID>
1506- <countryName>Russia</countryName>
1507- </City>
1508- <City>
1509- <cityName>Mountain View</cityName>
1510- <timezoneID>America/Los_Angeles</timezoneID>
1511- <countryName>United States</countryName>
1512- </City>
1513- <City>
1514- <cityName>Mumbai</cityName>
1515- <timezoneID>Asia/Kolkata</timezoneID>
1516- <countryName>India</countryName>
1517- </City>
1518- <City>
1519- <cityName>Munich</cityName>
1520- <timezoneID>Europe/Berlin</timezoneID>
1521- <countryName>Germany</countryName>
1522- </City>
1523- <City>
1524- <cityName>Muscat</cityName>
1525- <timezoneID>Asia/Muscat</timezoneID>
1526- <countryName>Oman</countryName>
1527- </City>
1528- <City>
1529- <cityName>Nairobi</cityName>
1530- <timezoneID>Africa/Nairobi</timezoneID>
1531- <countryName>Kenya</countryName>
1532- </City>
1533- <City>
1534- <cityName>Nashville</cityName>
1535- <timezoneID>America/Chicago</timezoneID>
1536- <countryName>United States</countryName>
1537- </City>
1538- <City>
1539- <cityName>Nassau</cityName>
1540- <timezoneID>America/Nassau</timezoneID>
1541- <countryName>Bahamas</countryName>
1542- </City>
1543- <City>
1544- <cityName>New Orleans</cityName>
1545- <timezoneID>America/Chicago</timezoneID>
1546- <countryName>United States</countryName>
1547- </City>
1548- <City>
1549- <cityName>New Salem</cityName>
1550- <timezoneID>America/North_Dakota/New_Salem</timezoneID>
1551- <countryName>United States</countryName>
1552- </City>
1553- <City>
1554- <cityName>New South Wales</cityName>
1555- <timezoneID>Australia/Sydney</timezoneID>
1556- <countryName>Australia</countryName>
1557- </City>
1558- <City>
1559- <cityName>New York</cityName>
1560- <timezoneID>America/New_York</timezoneID>
1561- <countryName>United States</countryName>
1562- </City>
1563- <City>
1564- <cityName>Newfoundland</cityName>
1565- <timezoneID>America/St_Johns</timezoneID>
1566- <countryName>United States</countryName>
1567- </City>
1568- <City>
1569- <cityName>Nouméa</cityName>
1570- <timezoneID>Pacific/Noumea</timezoneID>
1571- <countryName>New Caledonia</countryName>
1572- </City>
1573- <City>
1574- <cityName>Nuestra Señora de La Paz</cityName>
1575- <timezoneID>America/Bogota</timezoneID>
1576- <countryName>Colombia</countryName>
1577- </City>
1578- <City>
1579- <cityName>Oklahoma City</cityName>
1580- <timezoneID>America/Chicago</timezoneID>
1581- <countryName>United States</countryName>
1582- </City>
1583- <City>
1584- <cityName>Osaka</cityName>
1585- <timezoneID>Asia/Tokyo</timezoneID>
1586- <countryName>Japan</countryName>
1587- </City>
1588- <City>
1589- <cityName>Oslo</cityName>
1590- <timezoneID>Europe/Oslo</timezoneID>
1591- <countryName>Norway</countryName>
1592- </City>
1593- <City>
1594- <cityName>Ottawa</cityName>
1595- <timezoneID>America/Toronto</timezoneID>
1596- <countryName>Canada</countryName>
1597- </City>
1598- <City>
1599- <cityName>Oulu</cityName>
1600- <timezoneID>Europe/Helsinki</timezoneID>
1601- <countryName>Finland</countryName>
1602- </City>
1603- <City>
1604- <cityName>Panamá</cityName>
1605- <timezoneID>America/Panama</timezoneID>
1606- <countryName>Panama</countryName>
1607- </City>
1608- <City>
1609- <cityName>Paramaribo</cityName>
1610- <timezoneID>America/Paramaribo</timezoneID>
1611- <countryName>Suriname</countryName>
1612- </City>
1613- <City>
1614- <cityName>Paris</cityName>
1615- <timezoneID>Europe/Paris</timezoneID>
1616- <countryName>France</countryName>
1617- </City>
1618- <City>
1619- <cityName>Perth</cityName>
1620- <timezoneID>Australia/Perth</timezoneID>
1621- <countryName>Australia</countryName>
1622- </City>
1623- <City>
1624- <cityName>Petersburg</cityName>
1625- <timezoneID>America/Indiana/Petersburg</timezoneID>
1626- <countryName>Russia</countryName>
1627- </City>
1628- <City>
1629- <cityName>Philadelphia</cityName>
1630- <timezoneID>America/New_York</timezoneID>
1631- <countryName>United States</countryName>
1632- </City>
1633- <City>
1634- <cityName>Phnom Penh</cityName>
1635- <timezoneID>Asia/Phnom_Penh</timezoneID>
1636- <countryName>Cambodia</countryName>
1637- </City>
1638- <City>
1639- <cityName>Phoenix</cityName>
1640- <timezoneID>America/Phoenix</timezoneID>
1641- <countryName>United States</countryName>
1642- </City>
1643- <City>
1644- <cityName>Pittsburgh</cityName>
1645- <timezoneID>America/New_York</timezoneID>
1646- <countryName>United States</countryName>
1647- </City>
1648- <City>
1649- <cityName>Port of Spain</cityName>
1650- <timezoneID>America/Port_of_Spain</timezoneID>
1651- <countryName>Trinidad and Tobago</countryName>
1652- </City>
1653- <City>
1654- <cityName>Port au Prince</cityName>
1655- <timezoneID>America/Port-au-Prince</timezoneID>
1656- <countryName>Haiti</countryName>
1657- </City>
1658- <City>
1659- <cityName>Portland</cityName>
1660- <timezoneID>America/Los_Angeles</timezoneID>
1661- <countryName>United States</countryName>
1662- </City>
1663- <City>
1664- <cityName>Prague</cityName>
1665- <timezoneID>Europe/Prague</timezoneID>
1666- <countryName>Czech</countryName>
1667- </City>
1668- <City>
1669- <cityName>Pyongyang</cityName>
1670- <timezoneID>Asia/Pyongyang</timezoneID>
1671- <countryName>North Korea</countryName>
1672- </City>
1673- <City>
1674- <cityName>Queensland</cityName>
1675- <timezoneID>Australia/Brisbane</timezoneID>
1676- <countryName>United States</countryName>
1677- </City>
1678- <City>
1679- <cityName>Quito</cityName>
1680- <timezoneID>America/Guayaquil</timezoneID>
1681- <countryName>Ecuador</countryName>
1682- </City>
1683- <City>
1684- <cityName>Rangoon</cityName>
1685- <timezoneID>Asia/Rangoon</timezoneID>
1686- <countryName>Myanmar</countryName>
1687- </City>
1688- <City>
1689- <cityName>Reno</cityName>
1690- <timezoneID>America/Los_Angeles</timezoneID>
1691- <countryName>United States</countryName>
1692- </City>
1693- <City>
1694- <cityName>Reston</cityName>
1695- <timezoneID>America/New_York</timezoneID>
1696- <countryName>United States</countryName>
1697- </City>
1698- <City>
1699- <cityName>Reykjavík</cityName>
1700- <timezoneID>Atlantic/Reykjavik</timezoneID>
1701- <countryName>Iceland</countryName>
1702- </City>
1703- <City>
1704- <cityName>Riga</cityName>
1705- <timezoneID>Europe/Riga</timezoneID>
1706- <countryName>Latvia</countryName>
1707- </City>
1708- <City>
1709- <cityName>Rio de Janeiro</cityName>
1710- <timezoneID>America/Sao_Paulo</timezoneID>
1711- <countryName>Brazil</countryName>
1712- </City>
1713- <City>
1714- <cityName>Riyadh</cityName>
1715- <timezoneID>Asia/Riyadh</timezoneID>
1716- <countryName>Saudi Arabia</countryName>
1717- </City>
1718- <City>
1719- <cityName>Rome</cityName>
1720- <timezoneID>Europe/Rome</timezoneID>
1721- <countryName>Italy</countryName>
1722- </City>
1723- <City>
1724- <cityName>Sacramento</cityName>
1725- <timezoneID>America/Los_Angeles</timezoneID>
1726- <countryName>United States</countryName>
1727- </City>
1728- <City>
1729- <cityName>Salt Lake City</cityName>
1730- <timezoneID>America/Denver</timezoneID>
1731- <countryName>United States</countryName>
1732- </City>
1733- <City>
1734- <cityName>Samoa</cityName>
1735- <timezoneID>Pacific/Apia</timezoneID>
1736- <countryName>Samoa</countryName>
1737- </City>
1738- <City>
1739- <cityName>San Antonio</cityName>
1740- <timezoneID>America/Chicago</timezoneID>
1741- <countryName>United States</countryName>
1742- </City>
1743- <City>
1744- <cityName>San Diego</cityName>
1745- <timezoneID>America/Los_Angeles</timezoneID>
1746- <countryName>United States</countryName>
1747- </City>
1748- <City>
1749- <cityName>San Francisco</cityName>
1750- <timezoneID>America/Costa_Rica</timezoneID>
1751- <countryName>United States</countryName>
1752- </City>
1753- <City>
1754- <cityName>San José</cityName>
1755- <timezoneID>America/Costa_Rica</timezoneID>
1756- <countryName>Costa Rica</countryName>
1757- </City>
1758- <City>
1759- <cityName>San Juan</cityName>
1760- <timezoneID>America/Puerto_Rico</timezoneID>
1761- <countryName>Puerto Rico</countryName>
1762- </City>
1763- <City>
1764- <cityName>San Marino</cityName>
1765- <timezoneID>Europe/San_Marino</timezoneID>
1766- <countryName>San Marino</countryName>
1767- </City>
1768- <City>
1769- <cityName>San Salvador</cityName>
1770- <timezoneID>America/El_Salvador</timezoneID>
1771- <countryName>El Salvador</countryName>
1772- </City>
1773- <City>
1774- <cityName>Sanaa</cityName>
1775- <timezoneID>Asia/Aden</timezoneID>
1776- <countryName>Yemen</countryName>
1777- </City>
1778- <City>
1779- <cityName>Santiago</cityName>
1780- <timezoneID>America/Santiago</timezoneID>
1781- <countryName>Chile</countryName>
1782- </City>
1783- <City>
1784- <cityName>Santo Domingo</cityName>
1785- <timezoneID>America/Santo_Domingo</timezoneID>
1786- <countryName>Dominican Republic</countryName>
1787- </City>
1788- <City>
1789- <cityName>São Paulo</cityName>
1790- <timezoneID>America/Sao_Paulo</timezoneID>
1791- <countryName>Brazil</countryName>
1792- </City>
1793- <City>
1794- <cityName>São Tomé</cityName>
1795- <timezoneID>Africa/Sao_Tome</timezoneID>
1796- <countryName>São Tomé and Príncipe</countryName>
1797- </City>
1798- <City>
1799- <cityName>Sarajevo</cityName>
1800- <timezoneID>Europe/Sarajevo</timezoneID>
1801- <countryName>Bosnia and Herzegovina</countryName>
1802- </City>
1803- <City>
1804- <cityName>Saskatchewan</cityName>
1805- <timezoneID>America/Regina</timezoneID>
1806- <countryName>Canada</countryName>
1807- </City>
1808- <City>
1809- <cityName>Seattle</cityName>
1810- <timezoneID>America/Los_Angeles</timezoneID>
1811- <countryName>United States</countryName>
1812- </City>
1813- <City>
1814- <cityName>Seoul</cityName>
1815- <timezoneID>Asia/Seoul</timezoneID>
1816- <countryName>South Korea</countryName>
1817- </City>
1818- <City>
1819- <cityName>Shanghai</cityName>
1820- <timezoneID>Asia/Shanghai</timezoneID>
1821- <countryName>China</countryName>
1822- </City>
1823- <City>
1824- <cityName>Singapore</cityName>
1825- <timezoneID>Asia/Singapore</timezoneID>
1826- <countryName>Singapore</countryName>
1827- </City>
1828- <City>
1829- <cityName>Simferopol’</cityName>
1830- <timezoneID>Europe/Simferopol</timezoneID>
1831- <countryName>Ukraine</countryName>
1832- </City>
1833- <City>
1834- <cityName>Skopje</cityName>
1835- <timezoneID>Europe/Skopje</timezoneID>
1836- <countryName>Macedonia</countryName>
1837- </City>
1838- <City>
1839- <cityName>Sofia</cityName>
1840- <timezoneID>Europe/Sofia</timezoneID>
1841- <countryName>Bulgaria</countryName>
1842- </City>
1843- <City>
1844- <cityName>St.Johns</cityName>
1845- <timezoneID>America/St_Johns</timezoneID>
1846- <countryName>Canada</countryName>
1847- </City>
1848- <City>
1849- <cityName>St.Kitts</cityName>
1850- <timezoneID>America/St_Kitts</timezoneID>
1851- <countryName>Saint Kitts and Nevis</countryName>
1852- </City>
1853- <City>
1854- <cityName>St.Louis</cityName>
1855- <timezoneID>America/Chicago</timezoneID>
1856- <countryName>United States</countryName>
1857- </City>
1858- <City>
1859- <cityName>Stanley</cityName>
1860- <timezoneID>Atlantic/Stanley</timezoneID>
1861- <countryName>Falkland Islands</countryName>
1862- </City>
1863- <City>
1864- <cityName>Stockholm</cityName>
1865- <timezoneID>Europe/Stockholm</timezoneID>
1866- <countryName>Sweden</countryName>
1867- </City>
1868- <City>
1869- <cityName>Suva</cityName>
1870- <timezoneID>Pacific/Fiji</timezoneID>
1871- <countryName>Fiji</countryName>
1872- </City>
1873- <City>
1874- <cityName>Sydney</cityName>
1875- <timezoneID>Australia/Sydney</timezoneID>
1876- <countryName>Australia</countryName>
1877- </City>
1878- <City>
1879- <cityName>Taipei</cityName>
1880- <timezoneID>Asia/Taipei</timezoneID>
1881- <countryName>Taiwan</countryName>
1882- </City>
1883- <City>
1884- <cityName>Tallinn</cityName>
1885- <timezoneID>Europe/Tallinn</timezoneID>
1886- <countryName>Estonia</countryName>
1887- </City>
1888- <City>
1889- <cityName>Tehran</cityName>
1890- <timezoneID>Asia/Tehran</timezoneID>
1891- <countryName>Iran</countryName>
1892- </City>
1893- <City>
1894- <cityName>Tokyo</cityName>
1895- <timezoneID>Asia/Tokyo</timezoneID>
1896- <countryName>Japan</countryName>
1897- </City>
1898- <City>
1899- <cityName>Toronto</cityName>
1900- <timezoneID>America/Toronto</timezoneID>
1901- <countryName>Canada</countryName>
1902- </City>
1903- <City>
1904- <cityName>Tripoli</cityName>
1905- <timezoneID>Africa/Tripoli</timezoneID>
1906- <countryName>Libyra</countryName>
1907- </City>
1908- <City>
1909- <cityName>Tunis</cityName>
1910- <timezoneID>Africa/Tunis</timezoneID>
1911- <countryName>Tunisia</countryName>
1912- </City>
1913- <City>
1914- <cityName>Ulan Bator</cityName>
1915- <timezoneID>Asia/Ulan_Bator</timezoneID>
1916- <countryName>Mongolia</countryName>
1917- </City>
1918- <City>
1919- <cityName>Vancouver</cityName>
1920- <timezoneID>America/Vancouver</timezoneID>
1921- <countryName>Canada</countryName>
1922- </City>
1923- <City>
1924- <cityName>Vatican City</cityName>
1925- <timezoneID>Europe/Vatican</timezoneID>
1926- <countryName>Vatican City</countryName>
1927- </City>
1928- <City>
1929- <cityName>Vevay</cityName>
1930- <timezoneID>America/Indiana/Vevay</timezoneID>
1931- <countryName>United States</countryName>
1932- </City>
1933- <City>
1934- <cityName>Vienna</cityName>
1935- <timezoneID>Europe/Vienna</timezoneID>
1936- <countryName>Austria</countryName>
1937- </City>
1938- <City>
1939- <cityName>Vilnius</cityName>
1940- <timezoneID>Europe/Vilnius</timezoneID>
1941- <countryName>Lithuania</countryName>
1942- </City>
1943- <City>
1944- <cityName>Vincennes</cityName>
1945- <timezoneID>America/Indiana/Vincennes</timezoneID>
1946- <countryName>France</countryName>
1947- </City>
1948- <City>
1949- <cityName>Warsaw</cityName>
1950- <timezoneID>Europe/Warsaw</timezoneID>
1951- <countryName>Poland</countryName>
1952- </City>
1953- <City>
1954- <cityName>Washington D.C</cityName>
1955- <timezoneID>America/New_York</timezoneID>
1956- <countryName>United States</countryName>
1957- </City>
1958- <City>
1959- <cityName>Winamac</cityName>
1960- <timezoneID>America/Indiana/Winamac</timezoneID>
1961- <countryName>United States</countryName>
1962- </City>
1963- <City>
1964- <cityName>Winnipeg</cityName>
1965- <timezoneID>America/Winnipeg</timezoneID>
1966- <countryName>Canada</countryName>
1967- </City>
1968- <City>
1969- <cityName>Wrocław</cityName>
1970- <timezoneID>Europe/Warsaw</timezoneID>
1971- <countryName>Poland</countryName>
1972- </City>
1973- <City>
1974- <cityName>Zagreb</cityName>
1975- <timezoneID>Europe/Zagreb</timezoneID>
1976- <countryName>Croatia</countryName>
1977- </City>
1978+ </City>
1979 <City>
1980 <cityName>Zürich</cityName>
1981 <timezoneID>Europe/Zurich</timezoneID>
1982
1983=== modified file 'backend/CMakeLists.txt'
1984--- backend/CMakeLists.txt 2014-07-22 12:51:38 +0000
1985+++ backend/CMakeLists.txt 2014-07-28 20:36:30 +0000
1986@@ -7,7 +7,6 @@
1987 modules/Timezone/backend.cpp
1988 modules/Timezone/timezonemodel.cpp
1989 modules/Timezone/xmltimezonemodel.cpp
1990- modules/Timezone/generictimezonemodel.cpp
1991 )
1992
1993 set(
1994
1995=== modified file 'backend/modules/Timezone/backend.cpp'
1996--- backend/modules/Timezone/backend.cpp 2014-07-22 12:51:38 +0000
1997+++ backend/modules/Timezone/backend.cpp 2014-07-28 20:36:30 +0000
1998@@ -21,14 +21,12 @@
1999 #include "backend.h"
2000 #include "timezonemodel.h"
2001 #include "xmltimezonemodel.h"
2002-#include "generictimezonemodel.h"
2003
2004 void BackendPlugin::registerTypes(const char *uri)
2005 {
2006 Q_ASSERT(uri == QLatin1String("Timezone"));
2007
2008 qmlRegisterType<XmlTimeZoneModel>(uri, 1, 0, "XmlTimeZoneModel");
2009- qmlRegisterType<GenericTimeZoneModel>(uri, 1, 0, "GenericTimeZoneModel");
2010 }
2011
2012 void BackendPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
2013
2014=== removed file 'backend/modules/Timezone/generictimezonemodel.cpp'
2015--- backend/modules/Timezone/generictimezonemodel.cpp 2014-07-22 13:02:03 +0000
2016+++ backend/modules/Timezone/generictimezonemodel.cpp 1970-01-01 00:00:00 +0000
2017@@ -1,81 +0,0 @@
2018-/*
2019- * Copyright (C) 2014 Canonical Ltd
2020- *
2021- * This file is part of Ubuntu Clock App
2022- *
2023- * Ubuntu Clock App is free software: you can redistribute it and/or modify
2024- * it under the terms of the GNU General Public License version 3 as
2025- * published by the Free Software Foundation.
2026- *
2027- * Ubuntu Clock App is distributed in the hope that it will be useful,
2028- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2029- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2030- * GNU General Public License for more details.
2031- *
2032- * You should have received a copy of the GNU General Public License
2033- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2034- */
2035-
2036-#include "generictimezonemodel.h"
2037-
2038-#include <QDebug>
2039-
2040-GenericTimeZoneModel::GenericTimeZoneModel(QObject *parent) :
2041- TimeZoneModel(parent)
2042-{
2043-}
2044-
2045-QList<QVariant> GenericTimeZoneModel::results() const
2046-{
2047- return m_results;
2048-}
2049-
2050-void GenericTimeZoneModel::setResults(const QList<QVariant> &results)
2051-{
2052- if(m_results == results) {
2053- // Don't parse the results again if it is the same results being set again
2054- return;
2055- }
2056-
2057- // Change the results and emit the changed signal to let QML know
2058- m_results = results;
2059- emit resultsChanged();
2060-
2061- // Parse through results
2062- loadTimeZonesFromVariantList();
2063-}
2064-
2065-void GenericTimeZoneModel::loadTimeZonesFromVariantList()
2066-{
2067- if(m_results.isEmpty()) {
2068- // Don't parse an empty results
2069- return;
2070- }
2071-
2072- // Let QML know model is being reset and rebuilt
2073- beginResetModel();
2074-
2075- m_timeZones.clear();
2076-
2077- TimeZone tz;
2078-
2079- /*
2080- Cycle through the u1db query model results and transfer them to the
2081- TimeZone list.
2082- */
2083- for (int i=0; i < m_results.size(); i++) {
2084- // Map query model results to timezone tz
2085- tz.cityName = m_results.value(i).toMap().value("city").toString();
2086- tz.country = m_results.value(i).toMap().value("country").toString();
2087- tz.timeZoneId = m_results.value(i).toMap().value("timezone").toString();
2088-
2089- m_timeZones.append(tz);
2090-
2091- // Clear tz before next iteration
2092- tz = TimeZone();
2093- }
2094-
2095-
2096- // Let QML know model is reusable again
2097- endResetModel();
2098-}
2099
2100=== removed file 'backend/modules/Timezone/generictimezonemodel.h'
2101--- backend/modules/Timezone/generictimezonemodel.h 2014-07-22 13:10:43 +0000
2102+++ backend/modules/Timezone/generictimezonemodel.h 1970-01-01 00:00:00 +0000
2103@@ -1,58 +0,0 @@
2104-/*
2105- * Copyright (C) 2014 Canonical Ltd
2106- *
2107- * This file is part of Ubuntu Clock App
2108- *
2109- * Ubuntu Clock App is free software: you can redistribute it and/or modify
2110- * it under the terms of the GNU General Public License version 3 as
2111- * published by the Free Software Foundation.
2112- *
2113- * Ubuntu Clock App is distributed in the hope that it will be useful,
2114- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2115- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2116- * GNU General Public License for more details.
2117- *
2118- * You should have received a copy of the GNU General Public License
2119- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2120- */
2121-
2122-#ifndef GENERICTIMEZONEMODEL_H
2123-#define GENERICTIMEZONEMODEL_H
2124-
2125-#include <QList>
2126-#include <QVariant>
2127-
2128-#include "timezonemodel.h"
2129-
2130-class GenericTimeZoneModel : public TimeZoneModel
2131-{
2132- Q_OBJECT
2133-
2134- // Property to store the u1db query model results
2135- Q_PROPERTY(QList<QVariant> results
2136- READ results
2137- WRITE setResults
2138- NOTIFY resultsChanged)
2139-
2140-public:
2141- GenericTimeZoneModel(QObject *parent = 0);
2142-
2143- // Function to read the model
2144- QList<QVariant> results() const;
2145-
2146- // Function to set the model
2147- void setResults(const QList<QVariant> &results);
2148-
2149-signals:
2150- // Signal to notify the change of the model to QML
2151- void resultsChanged();
2152-
2153-private:
2154- // Function to do the QList parsing
2155- void loadTimeZonesFromVariantList();
2156-
2157- // Private copy of the model received from QML
2158- QList<QVariant> m_results;
2159-};
2160-
2161-#endif // GENERICTIMEZONEMODEL_H
2162
2163=== modified file 'backend/modules/Timezone/timezonemodel.cpp'
2164--- backend/modules/Timezone/timezonemodel.cpp 2014-07-22 12:52:39 +0000
2165+++ backend/modules/Timezone/timezonemodel.cpp 2014-07-28 20:36:30 +0000
2166@@ -64,10 +64,6 @@
2167 We have defined Roles in our .h file. Lets use them here.
2168 */
2169
2170- QTimeZone zone(m_timeZones.at(row).timeZoneId.toLatin1());
2171- QDateTime worldCityTime(QDateTime::currentDateTime().toTimeZone(zone));
2172- QDateTime localCityTime(QDateTime::currentDateTime());
2173-
2174 switch (role) {
2175 case RoleCityName:
2176 return m_timeZones.at(row).cityName;
2177@@ -76,19 +72,10 @@
2178 case RoleTimeZoneId:
2179 return m_timeZones.at(row).timeZoneId;
2180 case RoleTimeString:
2181- /*
2182- FIXME: Until https://bugreports.qt-project.org/browse/QTBUG-40275
2183- is fixed, we will have to return a string.
2184- */
2185- return worldCityTime.toString("hh:mm");
2186- case RoleDaysTo:
2187- return localCityTime.daysTo(worldCityTime);
2188- case RoleTimeTo:
2189- /*
2190- FIXME: Workaround for localCityTime.secsTo(worldCityTime) which returns
2191- 0 indicating that the datetime object is invalid.
2192- */
2193- return localCityTime.offsetFromUtc() - worldCityTime.offsetFromUtc();
2194+ QTimeZone zone(m_timeZones.at(row).timeZoneId.toLatin1());
2195+ // TODO: pass formatting options as parameter to toString().
2196+ // see: http://qt-project.org/doc/qt-5/qdate.html#toString
2197+ return QDateTime::currentDateTime().toTimeZone(zone).toString("hh:mm");
2198 }
2199
2200 /*
2201@@ -105,8 +92,6 @@
2202 roles.insert(RoleCountryName, "country");
2203 roles.insert(RoleTimeZoneId, "timezoneID");
2204 roles.insert(RoleTimeString, "localTime");
2205- roles.insert(RoleDaysTo, "daysTo");
2206- roles.insert(RoleTimeTo, "timeTo");
2207 return roles;
2208 }
2209
2210
2211=== modified file 'backend/modules/Timezone/timezonemodel.h'
2212--- backend/modules/Timezone/timezonemodel.h 2014-07-22 12:55:56 +0000
2213+++ backend/modules/Timezone/timezonemodel.h 2014-07-28 20:36:30 +0000
2214@@ -33,19 +33,14 @@
2215 /*
2216 Property to determine the interval before updating the time (default is 0)
2217 */
2218- Q_PROPERTY(int updateInterval
2219- READ updateInterval
2220- WRITE setUpdateInterval
2221- NOTIFY updateIntervalChanged)
2222+ Q_PROPERTY(int updateInterval READ updateInterval WRITE setUpdateInterval NOTIFY updateIntervalChanged)
2223
2224 public:
2225 enum Roles {
2226 RoleCityName,
2227 RoleCountryName,
2228 RoleTimeZoneId,
2229- RoleTimeString,
2230- RoleDaysTo,
2231- RoleTimeTo,
2232+ RoleTimeString
2233 };
2234
2235 /*
2236@@ -77,16 +72,8 @@
2237 // Signal to notify the updateInterval change to QML
2238 void updateIntervalChanged();
2239
2240-public slots:
2241- /*
2242- Public slot called internally by m_updateTimer and also from QML to
2243- explicitly refresh the model when required.
2244-
2245- Use Case: The world city list is updated every minute to improve
2246- performance. However when the clock app is brought from the background
2247- (due to user switching between apps) the world city list must be updated
2248- immediately rather than waiting for a minute before updating.
2249- */
2250+private slots:
2251+ // Private slot that gets called by the updateTimer
2252 void update();
2253
2254 private:
2255
2256=== modified file 'backend/modules/Timezone/xmltimezonemodel.cpp'
2257--- backend/modules/Timezone/xmltimezonemodel.cpp 2014-07-20 22:33:13 +0000
2258+++ backend/modules/Timezone/xmltimezonemodel.cpp 2014-07-28 20:36:30 +0000
2259@@ -121,6 +121,7 @@
2260 if (reader.name() == "City") {
2261 // A time zone has ended. insert it into list
2262 m_timeZones.append(tz);
2263+ qDebug() << "appended tz:" << tz.cityName << tz.country << tz.timeZoneId;
2264 }
2265 if (reader.name() == "cityName") {
2266 isCityName = false;
2267
2268=== modified file 'manifest.json'
2269--- manifest.json 2014-07-08 10:52:02 +0000
2270+++ manifest.json 2014-07-28 20:36:30 +0000
2271@@ -11,5 +11,8 @@
2272 }
2273 },
2274 "version": "0.1",
2275- "maintainer": "Ubuntu App Cats <ubuntu-touch-coreapps@lists.launchpad.net>"
2276-}
2277\ No newline at end of file
2278+ "maintainer": "Ubuntu App Cats <ubuntu-touch-coreapps@lists.launchpad.net>",
2279+ "x-test": {
2280+ "autopilot": "ubuntu_clock_app"
2281+ }
2282+}
2283
2284=== added directory 'tests'
2285=== added directory 'tests/autopilot'
2286=== added file 'tests/autopilot/run'
2287--- tests/autopilot/run 1970-01-01 00:00:00 +0000
2288+++ tests/autopilot/run 2014-07-28 20:36:30 +0000
2289@@ -0,0 +1,11 @@
2290+#!/bin/bash
2291+
2292+if [[ -z `which autopilot` ]]; then
2293+ echo "Autopilot is not installed. Skip"
2294+ exit
2295+fi
2296+
2297+SCRIPTPATH=`dirname $0`
2298+pushd ${SCRIPTPATH}
2299+autopilot run ubuntu-clock-app
2300+popd
2301
2302=== added directory 'tests/autopilot/ubuntu_clock_app'
2303=== added file 'tests/autopilot/ubuntu_clock_app/__init__.py'
2304--- tests/autopilot/ubuntu_clock_app/__init__.py 1970-01-01 00:00:00 +0000
2305+++ tests/autopilot/ubuntu_clock_app/__init__.py 2014-07-28 20:36:30 +0000
2306@@ -0,0 +1,19 @@
2307+# -#- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -#-
2308+#
2309+# Copyright (C) 2013, 2014 Canonical Ltd
2310+#
2311+# This program is free software: you can redistribute it and/or modify
2312+# it under the terms of the GNU General Public License version 3 as
2313+# published by the Free Software Foundation.
2314+#
2315+# This program is distributed in the hope that it will be useful,
2316+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2317+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2318+# GNU General Public License for more details.
2319+#
2320+# You should have received a copy of the GNU General Public License
2321+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2322+#
2323+# Authored by: Renato Araujo Oliveira Filho <renato@canonical.com>
2324+
2325+"""clock-app autopilot tests and emulators - top level package."""
2326
2327=== added file 'tests/autopilot/ubuntu_clock_app/emulators.py'
2328--- tests/autopilot/ubuntu_clock_app/emulators.py 1970-01-01 00:00:00 +0000
2329+++ tests/autopilot/ubuntu_clock_app/emulators.py 2014-07-28 20:36:30 +0000
2330@@ -0,0 +1,406 @@
2331+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2332+#
2333+# Copyright (C) 2013, 2014 Canonical Ltd.
2334+#
2335+# This program is free software; you can redistribute it and/or modify
2336+# it under the terms of the GNU Lesser General Public License as published by
2337+# the Free Software Foundation; version 3.
2338+#
2339+# This program is distributed in the hope that it will be useful,
2340+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2341+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2342+# GNU Lesser General Public License for more details.
2343+#
2344+# You should have received a copy of the GNU Lesser General Public License
2345+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2346+#
2347+# Authored by: Nekhelesh Ramananthan <krnekhelesh@gmail.com>
2348+# Nicholas Skaggs <nicholas.skaggs@canonical.com>
2349+
2350+import logging
2351+
2352+from autopilot import logging as autopilot_logging
2353+
2354+from ubuntuuitoolkit import emulators as toolkit_emulators, pickers
2355+
2356+logger = logging.getLogger(__name__)
2357+
2358+
2359+class ClockEmulatorException(toolkit_emulators.ToolkitEmulatorException):
2360+
2361+ """Exception raised when there is an error with the emulator."""
2362+
2363+
2364+class MainView(toolkit_emulators.MainView):
2365+
2366+ @autopilot_logging.log_action(logger.info)
2367+ def open_clock(self):
2368+ """Open the Clock Page.
2369+
2370+ :return the Clock Page
2371+
2372+ """
2373+ return self.wait_select_single(ClockPage)
2374+
2375+ @autopilot_logging.log_action(logger.info)
2376+ def open_alarm(self):
2377+ """Open the Alarm Page.
2378+
2379+ :return: the Alarm Page.
2380+
2381+ """
2382+ clockPage = self.wait_select_single(ClockPage)
2383+ clockPage.drag_bottomEdge_up()
2384+ self.get_header().visible.wait_for(True)
2385+ return self.wait_select_single(Page11)
2386+
2387+ def get_AlarmList(self):
2388+ """ Get the AlarmList object. """
2389+ return AlarmList.select(self)
2390+
2391+
2392+class Page(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
2393+
2394+ """Autopilot helper for Pages."""
2395+
2396+ def __init__(self, *args):
2397+ super(Page, self).__init__(*args)
2398+ # XXX we need a better way to keep reference to the main view.
2399+ # --elopio - 2014-01-31
2400+ self.main_view = self.get_root_instance().select_single(MainView)
2401+
2402+
2403+class ClockPage(Page):
2404+
2405+ """Autopilot helper for the Clock page."""
2406+
2407+ @autopilot_logging.log_action(logger.info)
2408+ def drag_bottomEdge_up(self):
2409+ """Function to drag the bottom edge up."""
2410+ self._click_bottomEdge()
2411+
2412+ x, y, w, h = self.globalRect
2413+ start_x = stop_x = x + (w / 2)
2414+ start_y = y + (h - 1)
2415+
2416+ stop_y = start_y - h
2417+ self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
2418+
2419+ self._wait_for_ClockPage_to_close()
2420+
2421+ def _click_bottomEdge(self):
2422+ """Function to click on the bottom edge."""
2423+ bottomEdge = self.wait_select_single(
2424+ 'QQuickItem', objectName='bottomEdgeTip')
2425+ self.pointing_device.click_object(bottomEdge)
2426+
2427+ def _wait_for_ClockPage_to_close(self):
2428+ self.isCollapsed.wait_for(False)
2429+
2430+
2431+class Page11(Page):
2432+
2433+ """Autopilot helper for the Alarm page."""
2434+
2435+ @autopilot_logging.log_action(logger.info)
2436+ def add_single_alarm(self, name, day, time_to_set, test_sound_name):
2437+ """Add a single type alarm
2438+
2439+ :param name: name of alarm
2440+ :param day: day on which the alarm should be triggered
2441+ :param time_to_set: time to set alarm to
2442+ :param test_sound_name: sound to set in alarm
2443+
2444+ """
2445+ alarmListPage = AlarmList.select(self.main_view)
2446+ old_alarm_count = alarmListPage.get_num_of_alarms()
2447+
2448+ edit_alarm_page = self._click_add_alarm_button()
2449+ edit_alarm_page.set_alarm_time(time_to_set)
2450+
2451+ alarm_repeat_page = edit_alarm_page.open_alarmRepeat_page()
2452+ alarm_repeat_page.set_single_alarm_day(day)
2453+ self._click_header_backButton()
2454+
2455+ alarm_label_page = edit_alarm_page.open_alarmLabel_page()
2456+ alarm_label_page.set_alarm_label(name)
2457+ self._click_header_customBackButton()
2458+
2459+ # TODO
2460+ # alarm_sound_page = edit_alarm_page.open_alarmSound_page()
2461+ # alarm_sound_page.set_alarm_sound(test_sound_name)
2462+ # self._click_header_backButton()
2463+
2464+ self._click_save()
2465+ self._confirm_alarm_creation(old_alarm_count)
2466+
2467+ def _click_add_alarm_button(self):
2468+ """Click the add alarm header button."""
2469+ header = self.main_view.get_header()
2470+ header.click_action_button('addAlarmAction')
2471+ return self.main_view.wait_select_single(EditAlarmPage)
2472+
2473+ def _click_header_customBackButton(self):
2474+ """Click the header button: 'customBackButton' """
2475+ header = self.main_view.get_header()
2476+ header.click_custom_back_button()
2477+
2478+ def _click_header_backButton(self):
2479+ """Click the header button: 'backButton' """
2480+ header = self.main_view.get_header()
2481+ header.click_back_button()
2482+
2483+ def _click_save(self):
2484+ """Click the save timer header button"""
2485+ header = self.main_view.get_header()
2486+ header.click_action_button('saveAlarmAction')
2487+
2488+ def _confirm_alarm_creation(self, count):
2489+ """Confirm creation of alarm
2490+
2491+ :param count: alarm count before alarm creation
2492+
2493+ """
2494+ try:
2495+ AlarmList.select(self.main_view)._get_saved_alarms_list().\
2496+ count.wait_for(count + 1)
2497+ except AssertionError:
2498+ raise ClockEmulatorException('Error creating alarm.')
2499+
2500+
2501+class EditAlarmPage(Page):
2502+
2503+ """Autopilot helper for the Add Alarm page."""
2504+
2505+ @autopilot_logging.log_action(logger.info)
2506+ def set_alarm_time(self, time_to_set):
2507+ """Set alarm time on datepicker.
2508+
2509+ :param time_to_set: time to set on datepicker
2510+
2511+ """
2512+ PickerRow_HoursPicker = self.wait_select_single(
2513+ "Picker", objectName="PickerRow_HoursPicker")
2514+ self._set_picker(PickerRow_HoursPicker, 'time', time_to_set)
2515+
2516+ def _set_picker(self, field, mode, value):
2517+ # open picker
2518+ self.pointing_device.click_object(field)
2519+ # valid options are date or time; assume date if invalid/no option
2520+ if mode == 'time':
2521+ mode_value = 'Hours|Minutes'
2522+ else:
2523+ mode_value = 'Years|Months|Days'
2524+ picker = self.wait_select_single(
2525+ pickers.DatePicker, mode=mode_value, visible=True)
2526+ if mode_value == 'Hours|Minutes':
2527+ picker.pick_time(value)
2528+ else:
2529+ picker.pick_date(value)
2530+ # close picker
2531+ self.pointing_device.click_object(field)
2532+
2533+ @autopilot_logging.log_action(logger.info)
2534+ def open_alarmRepeat_page(self):
2535+ """ Open the alarmRepeat page """
2536+
2537+ alarmRepeatItem = self.wait_select_single(
2538+ "SubtitledListItem", objectName="alarmRepeat")
2539+ self.pointing_device.click_object(alarmRepeatItem)
2540+ return self.main_view.wait_select_single(AlarmRepeat)
2541+
2542+ @autopilot_logging.log_action(logger.info)
2543+ def open_alarmLabel_page(self):
2544+ """ Open the alarmLabel page """
2545+
2546+ alarmLabelItem = self.wait_select_single(
2547+ "SubtitledListItem", objectName="alarmLabel")
2548+ self.pointing_device.click_object(alarmLabelItem)
2549+ return AlarmLable.select(self.main_view)
2550+
2551+ @autopilot_logging.log_action(logger.info)
2552+ def open_alarmSound_page(self):
2553+ """ Open the alarmSound page """
2554+
2555+ alarmSoundItem = self.wait_select_single(
2556+ "SubtitledListItem", objectName="alarmSound")
2557+ self.pointing_device.click_object(alarmSoundItem)
2558+ return self.main_view.wait_select_single(AlarmSound)
2559+
2560+
2561+class AlarmRepeat(Page):
2562+
2563+ """Autopilot helper for the AlarmRepeat page."""
2564+
2565+ @autopilot_logging.log_action(logger.info)
2566+ def set_single_alarm_day(self, day):
2567+ """Set the alarm day of a single type alarm.
2568+
2569+ :param day: single day on which alarm is triggered
2570+
2571+ """
2572+ self.unselect_selected_days()
2573+ for index in range(self._get_num_of_days()):
2574+ if self.wait_select_single(
2575+ 'Label', objectName='alarmDay{}'.format(index)).\
2576+ text == day:
2577+ self._select_single_alarm_day(index)
2578+
2579+ def _get_num_of_days(self):
2580+ return int(self.wait_select_single(
2581+ 'QQuickRepeater', objectName='alarmDays').count)
2582+
2583+ def _select_single_alarm_day(self, index):
2584+ """ function for selecting the day passed to the function.
2585+
2586+ :param index: the day to be selected
2587+
2588+ """
2589+ dayCheckbox = self.wait_select_single(
2590+ 'CheckBox', objectName='daySwitch{}'.format(index))
2591+ if dayCheckbox.checked is False:
2592+ self.pointing_device.click_object(dayCheckbox)
2593+
2594+ @autopilot_logging.log_action(logger.info)
2595+ def unselect_selected_days(self):
2596+ """ function for unselecting already selected days. """
2597+ for index in range(self._get_num_of_days()):
2598+ if self.wait_select_single(
2599+ 'CheckBox', objectName='daySwitch{}'.format(index)).\
2600+ checked:
2601+ self.pointing_device.click_object(self.wait_select_single(
2602+ 'CheckBox', objectName='daySwitch{}'.format(index)))
2603+
2604+
2605+class AlarmSound(Page):
2606+
2607+ """Autopilot helper for the AlarmSound page."""
2608+
2609+ @autopilot_logging.log_action(logger.info)
2610+ def set_alarm_sound(self, test_sound_name):
2611+ """Set alarm sound.
2612+
2613+ :param test_sound_name: sound to set for alarm
2614+
2615+ """
2616+ self.unselect_selected_sound()
2617+ for index in range(self._get_num_of_sounds()):
2618+ if self.wait_select_single(
2619+ 'Label', objectName='soundName{}'.format(index)).\
2620+ text == test_sound_name:
2621+ self._select_alarm_sound(index)
2622+
2623+ def _get_num_of_sounds(self):
2624+ return int(self.wait_select_single(
2625+ 'QQuickRepeater', objectName='alarmSounds').count)
2626+
2627+ def _select_alarm_sound(self, index):
2628+ """ function for selecting the sound passed to the function.
2629+
2630+ :param index: the sound to be selected
2631+
2632+ """
2633+ soundCheckbox = self.wait_select_single(
2634+ 'CheckBox', objectName='soundStatus{}'.format(index))
2635+ if soundCheckbox.checked is False:
2636+ self.pointing_device.click_object(soundCheckbox)
2637+
2638+ @autopilot_logging.log_action(logger.info)
2639+ def unselect_selected_sound(self):
2640+ """ function for unselecting already selected days. """
2641+ for index in range(self._get_num_of_sounds()):
2642+ if self.wait_select_single(
2643+ 'CheckBox', objectName='soundStatus{}'.format(index)).\
2644+ checked:
2645+ self.pointing_device.click_object(self.wait_select_single(
2646+ 'CheckBox', objectName='soundStatus{}'.format(index)))
2647+
2648+
2649+class AlarmLable(object):
2650+
2651+ """Autopilot helper for the AlarmLabel page."""
2652+
2653+ def __init__(self, proxy_object):
2654+ super(AlarmLable, self).__init__()
2655+ self.proxy_object = proxy_object
2656+
2657+ @classmethod
2658+ def select(cls, main_view):
2659+ proxy_object = main_view.wait_select_single(
2660+ objectName='alarmLabelPage')
2661+ proxy_object.visible.wait_for(True)
2662+ return cls(proxy_object)
2663+
2664+ @autopilot_logging.log_action(logger.info)
2665+ def set_alarm_label(self, name):
2666+ """Set alarm label.
2667+
2668+ :param name: label for alarm to set
2669+
2670+ """
2671+ alarmTextfield = self.proxy_object.wait_select_single(
2672+ "TextField", objectName='labelEntry')
2673+ # TODO: This wait to ensure that the textfield is visible before
2674+ # entering text should be part of the SDK emulator. Until then, it has
2675+ # been added here. http://pad.lv/1289616 --nik90 2014-03-06
2676+ alarmTextfield.visible.wait_for(True)
2677+ alarmTextfield.write(name)
2678+
2679+
2680+class AlarmList(object):
2681+
2682+ """Autopilot helper for the AlarmList."""
2683+
2684+ def __init__(self, proxy_object):
2685+ super(AlarmList, self).__init__()
2686+ self.proxy_object = proxy_object
2687+
2688+ @classmethod
2689+ def select(cls, main_view):
2690+ proxy_object = main_view.wait_select_single(
2691+ objectName='alarmListFlickable')
2692+ proxy_object.visible.wait_for(True)
2693+ return cls(proxy_object)
2694+
2695+ def get_num_of_alarms(self):
2696+ """Return the number of saved alarms."""
2697+ return int(self._get_saved_alarms_list().count)
2698+
2699+ def _get_saved_alarms_list(self):
2700+ """Return the saved alarm list"""
2701+ return self.proxy_object.wait_select_single(
2702+ 'QQuickRepeater', objectName='alarmListRepeater')
2703+
2704+ def get_saved_alarms(self):
2705+ """Return a list with the information of the saved alarms.
2706+
2707+ Each item of the returned list is a tuple of
2708+ (name, recurrence, time, enabled).
2709+
2710+ """
2711+ alarms = []
2712+ for index in range(self.get_num_of_alarms()):
2713+ name = self.proxy_object.wait_select_single(
2714+ 'Label', objectName='listAlarmLabel{}'.format(index)).text
2715+ recurrence = self.proxy_object.wait_select_single(
2716+ 'Label', objectName='listAlarmSubtitle{}'.format(index)).text
2717+ time = self.proxy_object.wait_select_single(
2718+ 'Label', objectName='listAlarmTime{}'.format(index)).text
2719+ enabled = self.proxy_object.wait_select_single(
2720+ toolkit_emulators.CheckBox,
2721+ objectName='listAlarmStatus{}'.format(index)).checked
2722+ alarms.append((name, recurrence, enabled, time))
2723+ return alarms
2724+
2725+ @autopilot_logging.log_action(logger.info)
2726+ def delete_alarm(self, index):
2727+ """Delete an alarm at the specified index."""
2728+ old_alarm_count = self.get_num_of_alarms()
2729+ alarm = self.proxy_object.wait_select_single(
2730+ toolkit_emulators.Base, objectName='alarm{}'.format(index))
2731+ alarm.swipe_to_delete()
2732+ alarm.confirm_removal()
2733+ try:
2734+ self._get_saved_alarms_list().count.wait_for(old_alarm_count - 1)
2735+ except AssertionError:
2736+ raise ClockEmulatorException('Error deleting alarm.')
2737
2738=== added directory 'tests/autopilot/ubuntu_clock_app/tests'
2739=== added file 'tests/autopilot/ubuntu_clock_app/tests/__init__.py'
2740--- tests/autopilot/ubuntu_clock_app/tests/__init__.py 1970-01-01 00:00:00 +0000
2741+++ tests/autopilot/ubuntu_clock_app/tests/__init__.py 2014-07-28 20:36:30 +0000
2742@@ -0,0 +1,121 @@
2743+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2744+#
2745+# Copyright (C) 2013, 2014 Canonical Ltd
2746+#
2747+# This program is free software: you can redistribute it and/or modify
2748+# it under the terms of the GNU General Public License version 3 as
2749+# published by the Free Software Foundation.
2750+#
2751+# This program is distributed in the hope that it will be useful,
2752+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2753+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2754+# GNU General Public License for more details.
2755+#
2756+# You should have received a copy of the GNU General Public License
2757+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2758+#
2759+# Authored by: Renato Araujo Oliveira Filho <renato@canonical.com>
2760+
2761+
2762+"""clock-app autopilot tests."""
2763+
2764+import os.path
2765+import os
2766+import shutil
2767+import logging
2768+
2769+from autopilot import input
2770+from autopilot.platform import model
2771+from ubuntuuitoolkit import (
2772+ base,
2773+ emulators as toolkit_emulators
2774+)
2775+
2776+from ubuntu_clock_app import emulators
2777+
2778+logger = logging.getLogger(__name__)
2779+
2780+
2781+class ClockAppTestCase(base.UbuntuUIToolkitAppTestCase):
2782+
2783+ """A common test case class that provides several useful methods for
2784+ calendar-app tests.
2785+
2786+ """
2787+ local_location = "../../app/ubuntu-clock-app.qml"
2788+ installed_location = "/usr/share/ubuntu-clock-app/app/ubuntu-clock-app.qml"
2789+ sqlite_dir = os.path.expanduser(
2790+ "~/.local/share/com.ubuntu.clock")
2791+ backup_dir = sqlite_dir + ".backup"
2792+
2793+ def setUp(self):
2794+ super(ClockAppTestCase, self).setUp()
2795+ self.pointing_device = input.Pointer(self.input_device_class.create())
2796+
2797+ # backup and wipe db's before testing
2798+ self.temp_move_sqlite_db()
2799+ self.addCleanup(self.restore_sqlite_db)
2800+
2801+ # turn off the OSK so it doesn't block screen elements
2802+ if model() != 'Desktop':
2803+ os.system("stop maliit-server")
2804+ self.addCleanup(os.system, "start maliit-server")
2805+
2806+ if os.path.exists(self.local_location):
2807+ self.launch_test_local()
2808+ elif os.path.exists(self.installed_location):
2809+ self.launch_test_installed()
2810+ else:
2811+ self.launch_test_click()
2812+
2813+ def launch_test_local(self):
2814+ self.app = self.launch_test_application(
2815+ base.get_qmlscene_launch_command(),
2816+ self.local_location,
2817+ app_type='qt',
2818+ emulator_base=toolkit_emulators.UbuntuUIToolkitEmulatorBase)
2819+
2820+ def launch_test_installed(self):
2821+ self.app = self.launch_test_application(
2822+ base.get_qmlscene_launch_command(),
2823+ self.installed_location,
2824+ app_type='qt',
2825+ emulator_base=toolkit_emulators.UbuntuUIToolkitEmulatorBase)
2826+
2827+ def launch_test_click(self):
2828+ self.app = self.launch_click_package(
2829+ "com.ubuntu.clock.devel",
2830+ emulator_base=toolkit_emulators.UbuntuUIToolkitEmulatorBase)
2831+
2832+ def temp_move_sqlite_db(self):
2833+ try:
2834+ shutil.rmtree(self.backup_dir)
2835+ except:
2836+ pass
2837+ else:
2838+ logger.warning("Prexisting backup database found and removed")
2839+
2840+ try:
2841+ shutil.move(self.sqlite_dir, self.backup_dir)
2842+ except:
2843+ logger.warning("No current database found")
2844+ else:
2845+ logger.debug("Backed up database")
2846+
2847+ def restore_sqlite_db(self):
2848+ if os.path.exists(self.backup_dir):
2849+ if os.path.exists(self.sqlite_dir):
2850+ try:
2851+ shutil.rmtree(self.sqlite_dir)
2852+ except:
2853+ logger.error("Failed to remove test database and restore" /
2854+ "database")
2855+ return
2856+ try:
2857+ shutil.move(self.backup_dir, self.sqlite_dir)
2858+ except:
2859+ logger.error("Failed to restore database")
2860+
2861+ @property
2862+ def main_view(self):
2863+ return self.app.wait_select_single(emulators.MainView)
2864
2865=== added file 'tests/autopilot/ubuntu_clock_app/tests/test_alarm.py'
2866--- tests/autopilot/ubuntu_clock_app/tests/test_alarm.py 1970-01-01 00:00:00 +0000
2867+++ tests/autopilot/ubuntu_clock_app/tests/test_alarm.py 2014-07-28 20:36:30 +0000
2868@@ -0,0 +1,79 @@
2869+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2870+#
2871+# Copyright (C) 2013, 2014 Canonical Ltd
2872+#
2873+# This program is free software: you can redistribute it and/or modify
2874+# it under the terms of the GNU General Public License version 3 as
2875+# published by the Free Software Foundation.
2876+#
2877+# This program is distributed in the hope that it will be useful,
2878+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2879+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2880+# GNU General Public License for more details.
2881+#
2882+# You should have received a copy of the GNU General Public License
2883+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2884+#
2885+# Authored by: Nicholas Skaggs <nicholas.skaggs@canonical.com>
2886+# Nekhelesh Ramananthan <krnekhelesh@gmail.com>
2887+
2888+"""Tests for the Clock App - Alarm"""
2889+
2890+from __future__ import absolute_import
2891+
2892+import datetime
2893+
2894+from autopilot.matchers import Eventually
2895+from testtools.matchers import Equals
2896+from ubuntu_clock_app.tests import ClockAppTestCase
2897+
2898+
2899+class TestAlarm(ClockAppTestCase):
2900+
2901+ """Tests the alarm page features"""
2902+
2903+ def setUp(self):
2904+ """ This is needed to wait for the application to start.
2905+
2906+ In the testfarm, the application may take some time to show up.
2907+
2908+ """
2909+ super(TestAlarm, self).setUp()
2910+ self.assertThat(
2911+ self.main_view.visible, Eventually(Equals(True)))
2912+
2913+ self.page = self.main_view.open_alarm()
2914+
2915+ def test_add_single_type_alarm_must_add_to_alarm_list(self):
2916+ """Test to check if a single type alarm is saved properly
2917+
2918+ This test saves a single type alarm and verifies if it is added to the
2919+ alarm list in the alarm page.
2920+
2921+ """
2922+ tomorrow = datetime.datetime.now() + datetime.timedelta(days=1)
2923+ time_to_set = datetime.time(6, 10, 0)
2924+ test_alarm_name = 'Single Test'
2925+ # TODO this will be affected by the locale. --elopio - 2014-02-27
2926+ expected_alarm_name = unicode(test_alarm_name)
2927+ expected_recurrence = unicode(tomorrow.strftime('%A'))
2928+ expected_enabled_value = True
2929+ expected_time = unicode("6:10 AM")
2930+ expected_sound = "Ubuntu"
2931+ expected_alarm_info = (
2932+ expected_alarm_name, expected_recurrence, expected_enabled_value,
2933+ expected_time, expected_sound)
2934+
2935+ tomorrow_day = tomorrow.strftime('%A')
2936+ self.page.add_single_alarm(
2937+ test_alarm_name, tomorrow_day, time_to_set, expected_sound)
2938+
2939+ alarmlistPage = self.main_view.get_AlarmList()
2940+ saved_alarms = alarmlistPage.get_saved_alarms()
2941+ self.assertIn(expected_alarm_info, saved_alarms)
2942+
2943+ # TODO: Remove this statement once proper support for cleaning the
2944+ # test alarm environment is added. Until then remove the alarm
2945+ # created during the test at the end of the test.
2946+ # -- nik90 - 2014-03-03
2947+ alarmlistPage.delete_alarm(index=0)
2948
2949=== added file 'tests/autopilot/ubuntu_clock_app/tests/test_clock.py'
2950--- tests/autopilot/ubuntu_clock_app/tests/test_clock.py 1970-01-01 00:00:00 +0000
2951+++ tests/autopilot/ubuntu_clock_app/tests/test_clock.py 2014-07-28 20:36:30 +0000
2952@@ -0,0 +1,47 @@
2953+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2954+#
2955+# Copyright (C) 2013, 2014 Canonical Ltd
2956+#
2957+# This program is free software: you can redistribute it and/or modify
2958+# it under the terms of the GNU General Public License version 3 as
2959+# published by the Free Software Foundation.
2960+#
2961+# This program is distributed in the hope that it will be useful,
2962+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2963+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2964+# GNU General Public License for more details.
2965+#
2966+# You should have received a copy of the GNU General Public License
2967+# along with this program. If not, see <http://www.gnu.org/licenses/>.
2968+#
2969+# Authored by: Renato Araujo Oliveira Filho <renato@canonical.com>
2970+# Nekhelesh Ramananthan <krnekhelesh@gmail.com>
2971+
2972+"""
2973+Tests for the Clock App, main window.
2974+"""
2975+
2976+from __future__ import absolute_import
2977+
2978+from testtools.matchers import Equals
2979+from autopilot.matchers import Eventually
2980+
2981+from ubuntu_clock_app.tests import ClockAppTestCase
2982+
2983+
2984+class TestClock(ClockAppTestCase):
2985+
2986+ """Test the clock page features."""
2987+
2988+ def setUp(self):
2989+ """This is needed to wait for the application to start.
2990+
2991+ In the testfarm, the application may take some time to show up.
2992+
2993+ """
2994+
2995+ super(TestClock, self).setUp()
2996+ self.assertThat(
2997+ self.main_view.visible, Eventually(Equals(True)))
2998+
2999+ self.page = self.main_view.open_clock()
3000
3001=== added directory 'tests/unit'
3002=== added file 'tests/unit/tst_hellocomponent.qml'
3003--- tests/unit/tst_hellocomponent.qml 1970-01-01 00:00:00 +0000
3004+++ tests/unit/tst_hellocomponent.qml 2014-07-28 20:36:30 +0000
3005@@ -0,0 +1,49 @@
3006+import QtQuick 2.0
3007+import QtTest 1.0
3008+import Ubuntu.Components 0.1
3009+import "../../components"
3010+
3011+// See more details @ http://qt-project.org/doc/qt-5.0/qtquick/qml-testcase.html
3012+
3013+// Execute tests with:
3014+// qmltestrunner
3015+
3016+Item {
3017+ // The objects
3018+ HelloComponent {
3019+ id: objectUnderTest
3020+ }
3021+
3022+ TestCase {
3023+ name: "HelloComponent"
3024+
3025+ function init() {
3026+ console.debug(">> init");
3027+ compare("",objectUnderTest.text,"text was not empty on init");
3028+ console.debug("<< init");
3029+ }
3030+
3031+ function cleanup() {
3032+ console.debug(">> cleanup");
3033+ console.debug("<< cleanup");
3034+ }
3035+
3036+ function initTestCase() {
3037+ console.debug(">> initTestCase");
3038+ console.debug("<< initTestCase");
3039+ }
3040+
3041+ function cleanupTestCase() {
3042+ console.debug(">> cleanupTestCase");
3043+ console.debug("<< cleanupTestCase");
3044+ }
3045+
3046+ function test_canReadAndWriteText() {
3047+ var expected = "Hello World";
3048+
3049+ objectUnderTest.text = expected;
3050+
3051+ compare(expected,objectUnderTest.text,"expected did not equal result");
3052+ }
3053+ }
3054+}

Subscribers

People subscribed via source and target branches