Merge lp:~martin-borho/ubuntu-weather-app/pagestack into lp:ubuntu-weather-app/obsolete.trunk

Proposed by Martin Borho
Status: Merged
Approved by: Alan Pope 🍺🐧🐱 πŸ¦„
Approved revision: 348
Merged at revision: 355
Proposed branch: lp:~martin-borho/ubuntu-weather-app/pagestack
Merge into: lp:ubuntu-weather-app/obsolete.trunk
Diff against target: 1503 lines (+580/-550)
9 files modified
components/AddLocationPage.qml (+117/-96)
components/LocationManagerPage.qml (+157/-152)
components/SettingsPage.qml (+194/-0)
components/SettingsSheet.qml (+0/-195)
tests/autopilot/ubuntu_weather_app/emulators.py (+0/-45)
tests/autopilot/ubuntu_weather_app/tests/__init__.py (+74/-19)
tests/autopilot/ubuntu_weather_app/tests/test_locationmanager.py (+15/-14)
tests/autopilot/ubuntu_weather_app/tests/test_settings.py (+18/-16)
ubuntu-weather-app.qml (+5/-13)
To merge this branch: bzr merge lp:~martin-borho/ubuntu-weather-app/pagestack
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Alan Pope 🍺🐧🐱 πŸ¦„ (community) Needs Fixing
Review via email: mp+231093@code.launchpad.net

Commit message

Replaced used Sheet components for settings and managing locations with Page components.

Description of the change

Replaced the Sheet components used for settings and managing locations with Page components. No extra confirm button anymore.

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)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

Looks good, thanks Martin!

review: Approve
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
Martin Borho (martin-borho) wrote :

balloons ran in this yesterday too, seems like a jenkins related issue...

https://code.launchpad.net/~nskaggs/ubuntu-weather-app/1362234/+merge/232443/comments/566430

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
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
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
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
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
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
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
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

Tried running the tests locally on my nexus 4 and they fail here. http://paste.ubuntu.com/8209507/

review: Needs Fixing
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
Martin Borho (martin-borho) wrote :

popey: test on devices shuldbe fixed when https://code.launchpad.net/~canonical-platform-qa/ubuntu-weather-app/fix1365279-setup_once/+merge/233305 has landed.

But the jenkins errors I can't reproduce neither on device nor on desktop... and I have no clue why.

Some files were removed/added, should the deb-version get increased perhaps?

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Martin Borho (martin-borho) wrote :

\o/

Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

Sweet!

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

merged from trunk, fixed conflict

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== renamed file 'components/AddLocationSheet.qml' => 'components/AddLocationPage.qml'
2--- components/AddLocationSheet.qml 2014-09-02 07:21:28 +0000
3+++ components/AddLocationPage.qml 2014-09-04 17:21:39 +0000
4@@ -25,102 +25,122 @@
5 import "WeatherApi.js" as WeatherApi
6 import "CitiesList.js" as Cities
7
8-Component {
9-
10- DefaultSheet {
11- id: addLocationSheet
12- objectName: "AddLocationSheet"
13- title: i18n.tr("Add city")
14- contentsHeight: parent.height
15- contentsWidth: parent.width
16- doneButton: false
17-
18- Component.onCompleted: {
19- Cities.preList.forEach(function(loc) {
20- citiesModel.append(loc)
21- })
22- }
23-
24- Connections {
25- target: mainView
26- onEscapeKey: {
27- PopupUtils.close(addLocationSheet)
28- clear()
29- }
30- }
31-
32- function searchResponseHandler(messageObject) {
33- searching.running = false;
34- if(!messageObject.error) {
35- listView.visible = true
36- var results = [],
37+Page {
38+ id: addLocationPage
39+ objectName: "AddLocationPage"
40+ title: i18n.tr("Add city")
41+ anchors.fill: parent
42+ visible: false
43+
44+ readonly property real headerHeight: units.gu(9.5)
45+ readonly property real bottomHeight: units.gu(9.5)
46+
47+ property variant addCallback: null
48+
49+ Connections {
50+ target: mainView
51+ onEscapeKey: {
52+ pageStack.pop()
53+ clear()
54+ }
55+ }
56+
57+ head.backAction: Action {
58+ iconName: "back"
59+ visible: true
60+ onTriggered: {
61+ pageStack.pop()
62+ }
63+ }
64+
65+ Component.onCompleted: {
66+ Cities.preList.forEach(function(loc) {
67+ citiesModel.append(loc)
68+ })
69+ console.log(addCallback)
70+ }
71+
72+ function searchResponseHandler(messageObject) {
73+ searching.running = false;
74+ if(!messageObject.error) {
75+ listView.visible = true
76+ var results = [],
77 a1Counts = {},
78- a3Counts = {},
79- location;
80- // build a temp list and count the adminAreas
81- messageObject.result.locations.forEach(function(loc) {
82- a1Counts[loc.name+loc.adminName1] = (!a1Counts[loc.name+loc.adminName1]) ? 1 : a1Counts[loc.name+loc.adminName1]+1;
83- a3Counts[loc.name+loc.adminName3] = (!a3Counts[loc.name+loc.adminName3]) ? 1 : a3Counts[loc.name+loc.adminName3]+1;
84- results.push(loc);
85- });
86- // append results to the model and build a distinct subtitle
87- for(var x=0;x<results.length;x++) {
88- location = results[x];
89- location["areaLabel"] = buildAreaLabel(location, a1Counts ,a3Counts)
90- citiesModel.append(location);
91- noCityError.visible = false
92- }
93- //
94- if (!citiesModel.count) {
95- noCityError.visible = true
96- noCityError.text = i18n.tr("No location was found for %1").arg(locationString.text)
97- }
98- } else {
99- console.log("search: "+messageObject.error.msg+" / "+messageObject.error.request.url)
100- httpFailedSearch.show();
101- }
102- }
103-
104- function buildAreaLabel(loc, a1Counts, a3Counts) {
105- var label = "";
106- label += ((loc.adminName1) ? loc.adminName1.replace(/ Region$/,'')+", ":"");
107- label += ((loc.adminName2 && a1Counts[loc.name+loc.adminName1] > 1 && a3Counts[loc.name+loc.adminName3] > 1) ? loc.adminName2.replace(/ Region$/,'')+", ":"");
108- label += ((loc.adminName3 && a1Counts[loc.name+loc.adminName1] > 1) ? loc.adminName3.replace(/ Region$/,'')+", ":"");
109- label += ((Countries.codes[loc.country]) ? i18n.tr(Countries.codes[loc.country]): loc.country);
110- return label;
111- }
112-
113- function clear() {
114- locationString.text = '';
115+ a3Counts = {},
116+ location;
117+ // build a temp list and count the adminAreas
118+ messageObject.result.locations.forEach(function(loc) {
119+ a1Counts[loc.name+loc.adminName1] = (!a1Counts[loc.name+loc.adminName1]) ? 1 : a1Counts[loc.name+loc.adminName1]+1;
120+ a3Counts[loc.name+loc.adminName3] = (!a3Counts[loc.name+loc.adminName3]) ? 1 : a3Counts[loc.name+loc.adminName3]+1;
121+ results.push(loc);
122+ });
123+ // append results to the model and build a distinct subtitle
124+ for(var x=0;x<results.length;x++) {
125+ location = results[x];
126+ location["areaLabel"] = buildAreaLabel(location, a1Counts ,a3Counts)
127+ citiesModel.append(location);
128+ noCityError.visible = false
129+ }
130+ //
131+ if (!citiesModel.count) {
132+ noCityError.visible = true
133+ noCityError.text = i18n.tr("No location was found for %1").arg(locationString.text)
134+ }
135+ } else {
136+ console.log("search: "+messageObject.error.msg+" / "+messageObject.error.request.url)
137+ httpFailedSearch.show();
138+ }
139+ }
140+
141+ function buildAreaLabel(loc, a1Counts, a3Counts) {
142+ var label = "";
143+ label += ((loc.adminName1) ? loc.adminName1.replace(/ Region$/,'')+", ":"");
144+ label += ((loc.adminName2 && a1Counts[loc.name+loc.adminName1] > 1 && a3Counts[loc.name+loc.adminName3] > 1) ? loc.adminName2.replace(/ Region$/,'')+", ":"");
145+ label += ((loc.adminName3 && a1Counts[loc.name+loc.adminName1] > 1) ? loc.adminName3.replace(/ Region$/,'')+", ":"");
146+ label += ((Countries.codes[loc.country]) ? i18n.tr(Countries.codes[loc.country]): loc.country);
147+ return label;
148+ }
149+
150+ function clear() {
151+ locationString.text = '';
152+ citiesModel.clear();
153+ listView.visible = true;
154+ }
155+
156+ function doSearch() {
157+ if(locationString.text !== "") {
158+ cityList.visible = true
159 citiesModel.clear();
160- listView.visible = true;
161- }
162-
163- function doSearch() {
164- if(locationString.text !== "") {
165- cityList.visible = true
166- citiesModel.clear();
167- searching.running = true;
168- WeatherApi.sendRequest({
169- action: "searchByName",
170- params: {name:locationString.text, units:"metric"}
171- }, searchResponseHandler)
172- }
173- }
174-
175- SplashComponent {
176- id: httpFailedSearch
177- objectName: "HTTPFailedSearch"
178- }
179-
180- ListModel {
181- id: citiesModel
182- }
183-
184- container: Item {
185+ searching.running = true;
186+ WeatherApi.sendRequest({
187+ action: "searchByName",
188+ params: {name:locationString.text, units:"metric"}
189+ }, searchResponseHandler)
190+ }
191+ }
192+
193+ SplashComponent {
194+ id: httpFailedSearch
195+ objectName: "HTTPFailedSearch"
196+ }
197+
198+ ListModel {
199+ id: citiesModel
200+ }
201+
202+ Rectangle {
203+ anchors.fill:parent
204+ color: "lightgrey"
205+
206+ Item {
207 anchors {
208+ top:parent.top
209+ topMargin:headerHeight+units.gu(1)
210+ margins: units.gu(2)
211 right: parent.right
212 left: parent.left
213+ bottom: parent.bottom
214+ bottomMargin:bottomHeight
215 }
216 Rectangle {
217 id: searchInput
218@@ -134,7 +154,7 @@
219 color: "transparent"
220 TextField {
221 id: locationString
222- objectName: "SearchField"
223+ objectName: "SearchField"
224 anchors.fill: parent
225 placeholderText: i18n.tr("Enter a city name")
226 hasClearButton: true
227@@ -184,7 +204,7 @@
228 left: parent.left
229 right: parent.right
230 }
231- height: addLocationSheet.height-searchInput.height-units.gu(9.5)
232+ height: addLocationPage.height-searchInput.height-units.gu(9.5)
233 color: "transparent"
234 visible: true
235 Label {
236@@ -214,7 +234,7 @@
237 fontSize: "medium"
238 }
239 }
240- }
241+ }
242 ListView {
243 id: listView;
244 objectName: "SearchResultList"
245@@ -256,8 +276,8 @@
246 }
247 onClicked: {
248 var location = citiesModel.get(index)
249- locationManagerSheet.addLocation(location)
250- PopupUtils.close(addLocationSheet)
251+ locationManagerPage.addLocation(location)
252+ pageStack.pop()
253 clear()
254 }
255 }
256@@ -269,4 +289,5 @@
257 }
258 }
259 }
260+
261 }
262
263=== renamed file 'components/LocationManagerSheet.qml' => 'components/LocationManagerPage.qml'
264--- components/LocationManagerSheet.qml 2014-09-02 07:21:28 +0000
265+++ components/LocationManagerPage.qml 2014-09-04 17:21:39 +0000
266@@ -24,93 +24,152 @@
267 import "CountryCodes.js" as Countries
268 import "WeatherApi.js" as WeatherApi
269
270-Component {
271- id: locationManagerComponent
272-
273- ComposerSheet {
274- id: locationManagerSheet
275- objectName: "LocationManagerSheet"
276- title: i18n.tr("Edit locations")
277- contentsHeight: parent.height
278- contentsWidth: parent.width
279-
280- property int initial_sum: 0
281- property bool limited: (locationModel.count > 7)
282-
283- signal cancelSheet()
284- onCancelSheet: {
285- if(initial_sum === 0) {
286- // refresh mainview to land again here,
287- // when no locations were defined when
288- // opening the sheet
289- mainView.refreshData()
290- } else {
291+Page {
292+ id: locationManagerPage
293+ objectName: "LocationManagerPage"
294+ title: i18n.tr("Edit locations")
295+ anchors.fill: parent
296+ visible: false
297+
298+ readonly property real headerHeight: units.gu(9.5)
299+ readonly property real bottomHeight: units.gu(9.5)
300+
301+ property int initial_sum: 0
302+ property bool limited: (locationModel.count > 7)
303+
304+ head.backAction: Action {
305+ iconName: "back"
306+ onTriggered: {
307+ var locationsChanged = false,
308+ refresh = false;
309+ // remove
310+ for(var x=0;x<locationsRemoved.count;x++) {
311+ var delLoc = locationsRemoved.get(x);
312+ storage.clearLocation(delLoc.dbId);
313+ locationsChanged = true;
314+ }
315+ // add
316+ for(var y=0;y<locationModel.count;y++) {
317+ var loc = locationModel.get(y);
318+ if(loc.dbId === undefined || loc.dbId=== 0) {
319+ storage.insertLocation({location:loc});
320+ locationsChanged = true;
321+ }
322+ }
323+ // refresh tabs if neccessary
324+ if(locationsChanged || locationModel.count === 0) {
325+ refresh = true;
326+ }
327+ // handle dummy "current location" item
328+ currentLocationItem.visible = false
329+ locationLookupItem.visible = true
330+ lookupItemAddButton.visible = true
331+ mainView.shortCutsLimited = false;
332+ if(locationModel.count > 0) {
333+ // reset text color
334 Theme.palette.selected.backgroundText = "#f4f4e8"
335- }
336- mainView.shortCutsLimited = false;
337- PopupUtils.close(locationManagerSheet)
338- }
339- Connections { target: mainView; onEscapeKey: cancelSheet()}
340-
341- Component.onCompleted: {
342- mainView.shortCutsLimited = true;
343- locationsRemoved.clear();
344- loadData();
345- Theme.palette.selected.backgroundText = "#656565"
346- }
347-
348- function lookupResponseHandler(messageObject) {
349- lookupIndicator.running = false;
350- if(!messageObject.error) {
351- if(messageObject.result.locations && messageObject.result.locations.length > 0) {
352- var location = messageObject.result.locations[0];
353- currentLocationItem.detectedLocation = location;
354- currentLocationLabel.text = location.name
355- currentLocationAreaLabel.text = location.adminName1
356- locationLookupItem.visible = false
357- currentLocationItem.visible = true;
358- }
359- } else {
360- console.log("search: "+messageObject.error.msg+" / "+messageObject.error.request.url)
361- httpFailedLookup.show();
362- }
363- }
364-
365- function loadData() {
366- storage.getLocations(fillLocationsList);
367- }
368-
369- function checkLocationExists(location) {
370- for(var x=0;x<locationModel.count;x++) {
371- var loc = locationModel.get(x);
372- if(loc.services.geonames && (loc.services.geonames === location.services.geonames)) {
373- existsNotification.show()
374- return true;
375- }
376- }
377- return false;
378- }
379-
380- function fillLocationsList(locations) {
381- initial_sum = locations.length;
382- locationModel.clear()
383- for(var x=0;x<locations.length;x++) {
384- var dbId = locations[x].db.id,
385+ popFromStack(refresh)
386+ }
387+ }
388+ }
389+
390+ Component.onCompleted: {
391+ mainView.shortCutsLimited = true;
392+ locationsRemoved.clear();
393+ loadData();
394+ Theme.palette.selected.backgroundText = "#656565"
395+ }
396+
397+ Connections { target: mainView; onEscapeKey: popFromStack()}
398+
399+ function popFromStack(refresh) {
400+ Theme.palette.selected.backgroundText = "#f3f3e7"
401+ pageStack.pop()
402+ // refresh at least from storage, to prevent header content from disapearing
403+ refreshData(!refresh, refresh);
404+ }
405+
406+ function lookupResponseHandler(messageObject) {
407+ lookupIndicator.running = false;
408+ if(!messageObject.error) {
409+ if(messageObject.result.locations && messageObject.result.locations.length > 0) {
410+ var location = messageObject.result.locations[0];
411+ currentLocationItem.detectedLocation = location;
412+ currentLocationLabel.text = location.name
413+ currentLocationAreaLabel.text = location.adminName1
414+ locationLookupItem.visible = false
415+ currentLocationItem.visible = true;
416+ }
417+ } else {
418+ console.log("search: "+messageObject.error.msg+" / "+messageObject.error.request.url)
419+ httpFailedLookup.show();
420+ }
421+ }
422+
423+ function loadData() {
424+ storage.getLocations(fillLocationsList);
425+ }
426+
427+ function checkLocationExists(location) {
428+ for(var x=0;x<locationModel.count;x++) {
429+ var loc = locationModel.get(x);
430+ if(loc.services.geonames && (loc.services.geonames === location.services.geonames)) {
431+ existsNotification.show()
432+ return true;
433+ }
434+ }
435+ return false;
436+ }
437+
438+ function fillLocationsList(locations) {
439+ initial_sum = locations.length;
440+ locationModel.clear()
441+ for(var x=0;x<locations.length;x++) {
442+ var dbId = locations[x].db.id,
443 location = locations[x].location;
444- // add db-id to the location object
445- location.dbId = dbId;
446- locationModel.append(locations[x].location);
447- }
448- }
449-
450- function addLocation(location) {
451- if(!checkLocationExists(location)) {
452- locationModel.append(location)
453- }
454- }
455-
456- container: Column {
457- anchors.fill: parent
458+ // add db-id to the location object
459+ location.dbId = dbId;
460+ locationModel.append(locations[x].location);
461+ }
462+ }
463+
464+ function addLocation(location) {
465+ if(!checkLocationExists(location)) {
466+ locationModel.append(location)
467+ }
468+ }
469+
470+ Dialog {
471+ id:existsNotification
472+ title: i18n.tr("Location already added.")
473+ Button {
474+ text: i18n.tr("OK")
475+ onClicked: PopupUtils.close(existsNotification)
476+ }
477+ }
478+
479+ ListModel {
480+ id: locationModel
481+ }
482+
483+ ListModel {
484+ id: locationsRemoved
485+ }
486+
487+ Rectangle {
488+ anchors.fill:parent
489+ color: "lightgrey"
490+
491+ Column {
492+ anchors {
493+ top:parent.top
494+ topMargin:headerHeight
495+ margins: units.gu(2)
496+ right: parent.right
497+ left: parent.left
498+ bottom: parent.bottom
499+ bottomMargin:bottomHeight
500+ }
501 Rectangle {
502 anchors {
503 left:parent.left
504@@ -161,12 +220,12 @@
505 anchors.left: parent.left
506 anchors.leftMargin: units.gu(3)
507 }
508- onClicked: {
509+ onClicked: {
510 lookupIndicator.running = true;
511 WeatherApi.sendRequest({
512- action: "getGeoIp",
513- params: {}
514- }, lookupResponseHandler);
515+ action: "getGeoIp",
516+ params: {}
517+ }, lookupResponseHandler);
518 }
519 }
520 ListItem.Standard {
521@@ -181,7 +240,7 @@
522 objectName: "CurrentLocationLabel"
523 text: ""
524 elide: Text.ElideRight
525- anchors {
526+ anchors {
527 top: parent.top
528 topMargin: units.gu(0.5)
529 left: parent.left
530@@ -255,7 +314,7 @@
531 }
532 clip:true
533 color:"transparent"
534- height: locationManagerSheet.height-locationLookupItem.height-units.gu(19.2)
535+ height: locationManagerPage.height-locationLookupItem.height-units.gu(19.2)
536 ListView {
537 objectName: "LocationList"
538 anchors.fill: parent
539@@ -338,71 +397,17 @@
540 fontSize: "small"
541 }
542 onClicked: {
543- PopupUtils.open(addLocationSheet)
544+ pageStack.push(Qt.createComponent("AddLocationPage.qml"))
545 }
546 }
547 }
548 }
549 }
550-
551- Dialog {
552- id:existsNotification
553- title: i18n.tr("Location already added.")
554- Button {
555- text: i18n.tr("OK")
556- onClicked: PopupUtils.close(existsNotification)
557- }
558- }
559-
560- ListModel {
561- id: locationModel
562- }
563-
564- ListModel {
565- id: locationsRemoved
566- }
567-
568- onConfirmClicked: {
569- var locationsChanged = false;
570- // remove
571- for(var x=0;x<locationsRemoved.count;x++) {
572- var delLoc = locationsRemoved.get(x);
573- storage.clearLocation(delLoc.dbId);
574- locationsChanged = true;
575- }
576- // add
577- for(var y=0;y<locationModel.count;y++) {
578- var loc = locationModel.get(y);
579- if(loc.dbId === undefined || loc.dbId=== 0) {
580- storage.insertLocation({location:loc});
581- locationsChanged = true;
582- }
583- }
584- // refresh tabs if neccessary
585- if(locationsChanged || locationModel.count === 0) {
586- mainView.refreshData()
587- }
588- // handle dummy "current location" item
589- currentLocationItem.visible = false
590- locationLookupItem.visible = true
591- lookupItemAddButton.visible = true
592- if(locationModel.count > 0) {
593- // reset text color
594- Theme.palette.selected.backgroundText = "#f4f4e8"
595- }
596- mainView.shortCutsLimited = false;
597- }
598-
599- onCancelClicked: cancelSheet()
600-
601- AddLocationSheet {
602- id:addLocationSheet
603- }
604-
605- SplashComponent {
606- id: httpFailedLookup
607- objectName: "HTTPFailedLookup"
608- message: i18n.tr("Couldn't specify your current location, please try later again!")
609- }
610+ }
611+
612+ SplashComponent {
613+ id: httpFailedLookup
614+ objectName: "HTTPFailedLookup"
615+ message: i18n.tr("Couldn't specify your current location, please try later again!")
616 }
617 }
618
619=== added file 'components/SettingsPage.qml'
620--- components/SettingsPage.qml 1970-01-01 00:00:00 +0000
621+++ components/SettingsPage.qml 2014-09-04 17:21:39 +0000
622@@ -0,0 +1,194 @@
623+/*
624+ * Copyright (C) 2013, 2014 Canonical Ltd
625+ *
626+ * This program is free software: you can redistribute it and/or modify
627+ * it under the terms of the GNU General Public License version 3 as
628+ * published by the Free Software Foundation.
629+ *
630+ * This program is distributed in the hope that it will be useful,
631+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
632+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
633+ * GNU General Public License for more details.
634+ *
635+ * You should have received a copy of the GNU General Public License
636+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
637+ *
638+ * Authored by: RaΓΊl Yeguas <neokore@gmail.com>
639+ * Martin Borho <martin@borho.net>
640+ */
641+import QtQuick 2.0
642+import Ubuntu.Components 1.1
643+
644+Page {
645+ title: i18n.tr("Settings")
646+ anchors.fill: parent
647+ visible: false
648+ readonly property real headerHeight: units.gu(9.5)
649+ readonly property real bottomHeight: units.gu(9.5)
650+ property bool refresh_from_storage: false
651+ property bool refresh_from_service: false
652+
653+ head.backAction: Action {
654+ iconName: "back"
655+ onTriggered: {
656+ if(refresh_from_storage === true || refresh_from_service === true) {
657+ storage.getSettings(function(storedSettings) {
658+ for(var settingName in storedSettings) {
659+ settings[settingName] = storedSettings[settingName];
660+ }
661+ refreshData(refresh_from_storage, refresh_from_service);
662+ });
663+ } else {
664+ // reload tabs from storage, to prevent header content from diappearing
665+ refreshData(true);
666+ }
667+ popFromStack()
668+ }
669+ }
670+
671+ Connections { target: mainView; onEscapeKey: popFromStack()}
672+
673+ function popFromStack() {
674+ Theme.palette.selected.backgroundText = "#f3f3e7"
675+ pageStack.pop()
676+ }
677+
678+ function fillTempSelector() {
679+ temperatureUnitsSelectorModel.append({ name: "celsiusOption", label: i18n.tr("Celsius")});
680+ temperatureUnitsSelectorModel.append({ name: "fahrenheitOption", label: i18n.tr("Fahrenheit")});
681+ temperatureUnitsSelector.selectedIndex = (settings["units"] === "imperial") ? 1 : 0;
682+ }
683+
684+ function fillWindSelector() {
685+ windUnitsSelectorModel.append({ name: "kmhOption", label: i18n.tr("Kilometers per hour")});
686+ windUnitsSelectorModel.append({ name: "mphOption", label: i18n.tr("Miles per hour")});
687+ windUnitsSelector.selectedIndex = (settings["wind_units"] === "mph") ? 1 : 0;
688+ }
689+
690+ function fillPrecipSelector() {
691+ precipitationUnitsSelectorModel.append({ name: "millimetersOption", label: i18n.tr("Millimeters")});
692+ precipitationUnitsSelectorModel.append({ name: "inchesOption", label: i18n.tr("Inches")});
693+ precipitationUnitsSelector.selectedIndex = (settings["precip_units"] === "in") ? 1 : 0;
694+ }
695+
696+ Component.onCompleted: {
697+ refresh_from_service = false;
698+ refresh_from_storage = false;
699+ fillTempSelector();
700+ fillWindSelector();
701+ fillPrecipSelector();
702+ mainView.shortCutsLimited = true;
703+ Theme.palette.selected.backgroundText = "#656565"
704+ //Theme.palette.selected.background = "#656565"
705+ }
706+
707+ Rectangle {
708+ anchors.fill:parent
709+ color: "lightgrey"
710+
711+ Column {
712+ anchors {
713+ top:parent.top
714+ topMargin:headerHeight+units.gu(3)
715+ margins: units.gu(2)
716+ right: parent.right
717+ left: parent.left
718+ bottom: parent.bottom
719+ bottomMargin:bottomHeight
720+ }
721+
722+
723+ Component {
724+ id: unitsSelectorDelegate
725+ OptionSelectorDelegate {
726+ text: i18n.tr(label)
727+ objectName: name
728+ }
729+ }
730+
731+ ListModel {
732+ id: temperatureUnitsSelectorModel
733+ }
734+
735+ OptionSelector {
736+ id: temperatureUnitsSelector
737+ objectName: "TemperatureUnitsSelector"
738+ text: i18n.tr("Temperature units")
739+ delegate: unitsSelectorDelegate
740+ model: temperatureUnitsSelectorModel
741+ onSelectedIndexChanged: {
742+ var selectedUnit = (selectedIndex === 0) ? "metric" : "imperial";
743+ storage.saveSetting("units", selectedUnit);
744+ refresh_from_storage = true;
745+ }
746+ }
747+
748+ ListModel {
749+ id: windUnitsSelectorModel
750+ }
751+
752+ OptionSelector {
753+ id: windUnitsSelector
754+ objectName: "WindUnitsSelector"
755+ text: i18n.tr("Wind speed units")
756+ delegate: unitsSelectorDelegate
757+ model: windUnitsSelectorModel
758+ onSelectedIndexChanged: {
759+ var selectedWindUnit = (selectedIndex === 0) ? "kmh" : "mph";
760+ storage.saveSetting("wind_units", selectedWindUnit);
761+ refresh_from_storage = true;
762+ }
763+ }
764+
765+ ListModel {
766+ id: precipitationUnitsSelectorModel
767+ }
768+
769+ OptionSelector {
770+ id: precipitationUnitsSelector
771+ objectName: "PrecipitationUnitsSelector"
772+ text: i18n.tr("Precipitation units")
773+ delegate: unitsSelectorDelegate
774+ model: precipitationUnitsSelectorModel
775+ // Precipitation units not available at TWC
776+ visible: (serviceSelector.selectedIndex !== 0) ? 1 : 0
777+ opacity: (serviceSelector.selectedIndex !== 0) ? 1 : 0
778+ Behavior on visible {
779+ enabled: (serviceSelector.selectedIndex === 0)
780+ NumberAnimation { duration: 1500}
781+ }
782+ Behavior on opacity {
783+ NumberAnimation {
784+ easing: UbuntuAnimation.StandardEasingReverse;
785+ duration: UbuntuAnimation.SlowDuration
786+ }
787+ }
788+ onSelectedIndexChanged: {
789+ var selectedPrecipUnit = (selectedIndex === 0) ? "mm" : "in";
790+ storage.saveSetting("precip_units", selectedPrecipUnit);
791+ refresh_from_storage = true;
792+ }
793+ }
794+
795+ ListModel {
796+ id: serviceSelectorModel
797+ ListElement { name: "twcOption"; label: "The Weather Channel" }
798+ ListElement { name: "owmOption"; label: "Openweathermap" }
799+ }
800+
801+ OptionSelector {
802+ id: serviceSelector
803+ objectName: "ServiceSelector"
804+ text: i18n.tr("Weather Service")
805+ delegate: unitsSelectorDelegate
806+ model: serviceSelectorModel
807+ selectedIndex: (settings["service"] === "openweathermap") ? 1 : 0;
808+ onSelectedIndexChanged: {
809+ var selectedService = (selectedIndex === 0) ? "weatherchannel" : "openweathermap";
810+ storage.saveSetting("service", selectedService);
811+ refresh_from_service = true;
812+ }
813+ }
814+ }
815+ }
816+}
817
818=== removed file 'components/SettingsSheet.qml'
819--- components/SettingsSheet.qml 2014-09-02 07:21:28 +0000
820+++ components/SettingsSheet.qml 1970-01-01 00:00:00 +0000
821@@ -1,195 +0,0 @@
822-/*
823- * Copyright (C) 2013 Canonical Ltd
824- *
825- * This program is free software: you can redistribute it and/or modify
826- * it under the terms of the GNU General Public License version 3 as
827- * published by the Free Software Foundation.
828- *
829- * This program is distributed in the hope that it will be useful,
830- * but WITHOUT ANY WARRANTY; without even the implied warranty of
831- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
832- * GNU General Public License for more details.
833- *
834- * You should have received a copy of the GNU General Public License
835- * along with this program. If not, see <http://www.gnu.org/licenses/>.
836- *
837- * Authored by: RaΓΊl Yeguas <neokore@gmail.com>
838- * Martin Borho <martin@borho.net>
839- */
840-import QtQuick 2.0
841-import Ubuntu.Components 1.1
842-import Ubuntu.Components.Popups 1.0
843-
844-Component {
845- ComposerSheet {
846- id: sheet
847- objectName: "SettingsSheet"
848- title: i18n.tr("Settings")
849- contentsHeight: parent.height
850- contentsWidth: parent.width
851-
852- function fillTempSelector() {
853- with(temperatureUnitsSelectorModel) {
854- append({ name: "celsiusOption", label: i18n.tr("Celsius")});
855- append({ name: "fahrenheitOption", label: i18n.tr("Fahrenheit")});
856- }
857- temperatureUnitsSelector.selectedIndex = (settings["units"] === "imperial") ? 1 : 0;
858- }
859-
860- function fillWindSelector() {
861- with(windUnitsSelectorModel) {
862- append({ name: "kmhOption", label: i18n.tr("Kilometers per hour")});
863- append({ name: "mphOption", label: i18n.tr("Miles per hour")});
864- }
865- windUnitsSelector.selectedIndex = (settings["wind_units"] === "mph") ? 1 : 0;
866- }
867-
868- function fillPrecipSelector() {
869- with(precipitationUnitsSelectorModel) {
870- append({ name: "millimetersOption", label: i18n.tr("Millimeters")});
871- append({ name: "inchesOption", label: i18n.tr("Inches")});
872- }
873- precipitationUnitsSelector.selectedIndex = (settings["precip_units"] === "in") ? 1 : 0;
874- }
875-
876- Component.onCompleted: {
877- fillTempSelector();
878- fillWindSelector();
879- fillPrecipSelector();
880- mainView.shortCutsLimited = true;
881- Theme.palette.selected.backgroundText = "#656565"
882- }
883-
884- container: Column {
885- anchors.left: parent.left
886- anchors.right: parent.right
887-
888- Component {
889- id: unitsSelectorDelegate
890- OptionSelectorDelegate {
891- text: i18n.tr(label)
892- objectName: name
893- }
894- }
895-
896- ListModel {
897- id: temperatureUnitsSelectorModel
898- }
899-
900- OptionSelector {
901- id: temperatureUnitsSelector
902- objectName: "TemperatureUnitsSelector"
903- text: i18n.tr("Temperature units")
904- delegate: unitsSelectorDelegate
905- model: temperatureUnitsSelectorModel
906- }
907-
908- ListModel {
909- id: windUnitsSelectorModel
910- }
911-
912- OptionSelector {
913- id: windUnitsSelector
914- objectName: "WindUnitsSelector"
915- text: i18n.tr("Wind speed units")
916- delegate: unitsSelectorDelegate
917- model: windUnitsSelectorModel
918- }
919-
920- ListModel {
921- id: precipitationUnitsSelectorModel
922- }
923-
924- OptionSelector {
925- id: precipitationUnitsSelector
926- objectName: "PrecipitationUnitsSelector"
927- text: i18n.tr("Precipitation units")
928- delegate: unitsSelectorDelegate
929- model: precipitationUnitsSelectorModel
930- // Precipitation units not available at TWC
931- visible: (serviceSelector.selectedIndex !== 0) ? 1 : 0
932- opacity: (serviceSelector.selectedIndex !== 0) ? 1 : 0
933- Behavior on visible {
934- enabled: (serviceSelector.selectedIndex === 0)
935- NumberAnimation { duration: 1500}
936- }
937- Behavior on opacity {
938- NumberAnimation {
939- easing: UbuntuAnimation.StandardEasingReverse;
940- duration: UbuntuAnimation.SlowDuration
941- }
942- }
943- }
944-
945- ListModel {
946- id: serviceSelectorModel
947- ListElement { name: "twcOption"; label: "The Weather Channel" }
948- ListElement { name: "owmOption"; label: "Openweathermap" }
949- }
950-
951- OptionSelector {
952- id: serviceSelector
953- objectName: "ServiceSelector"
954- text: i18n.tr("Weather Service")
955- delegate: unitsSelectorDelegate
956- model: serviceSelectorModel
957- selectedIndex: (settings["service"] === "openweathermap") ? 1 : 0;
958- }
959- }
960-
961- signal cancelSheet()
962- onCancelSheet: {
963- Theme.palette.selected.backgroundText = "#f4f4e8";
964- mainView.shortCutsLimited = false;
965- PopupUtils.close(sheet)
966- }
967- Connections { target: mainView; onEscapeKey: cancelSheet() }
968-
969- onConfirmClicked: {
970- var refresh_from_storage = false,
971- refresh_from_service = false,
972- selectedUnit = (temperatureUnitsSelector.selectedIndex === 0) ? "metric" : "imperial",
973- selectedWindUnit = (windUnitsSelector.selectedIndex === 0) ? "kmh" : "mph",
974- selectedPrecipUnit = (precipitationUnitsSelector.selectedIndex === 0) ? "mm" : "in",
975- selectedService = (serviceSelector.selectedIndex === 0) ? "weatherchannel" : "openweathermap";
976- // check if temperaure scale was changed
977- if(settings["units"] !== selectedUnit) {
978- storage.saveSetting("units", selectedUnit);
979- refresh_from_storage = true;
980- }
981- //
982- if(settings["wind_units"] !== selectedWindUnit) {
983- storage.saveSetting("wind_units", selectedWindUnit);
984- refresh_from_storage = true;
985- }
986- //
987- if(settings["precip_units"] !== selectedPrecipUnit) {
988- storage.saveSetting("precip_units", selectedPrecipUnit);
989- refresh_from_storage = true;
990- }
991- //
992- if(settings["service"] !== selectedService) {
993- storage.saveSetting("service", selectedService);
994- refresh_from_service = true;
995- }
996- // handling of other settings here
997- // ....
998-
999- // a setting was changed, reload settings and refresh the location tabs
1000- if(refresh_from_storage === true || refresh_from_service === true) {
1001- storage.getSettings(function(storedSettings) {
1002- for(var settingName in storedSettings) {
1003- settings[settingName] = storedSettings[settingName];
1004- }
1005- refreshData(refresh_from_storage, refresh_from_service);
1006- });
1007- }
1008- Theme.palette.selected.backgroundText = "#f4f4e8"
1009- PopupUtils.close(sheet)
1010- }
1011-
1012- onCancelClicked: {
1013- cancelSheet()
1014- }
1015- }
1016-}
1017
1018=== removed file 'tests/autopilot/ubuntu_weather_app/emulators.py'
1019--- tests/autopilot/ubuntu_weather_app/emulators.py 2014-05-19 16:05:56 +0000
1020+++ tests/autopilot/ubuntu_weather_app/emulators.py 1970-01-01 00:00:00 +0000
1021@@ -1,45 +0,0 @@
1022-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1023-# Copyright 2013 Canonical
1024-#
1025-# This program is free software: you can redistribute it and/or modify it
1026-# under the terms of the GNU General Public License version 3, as published
1027-# by the Free Software Foundation.
1028-#
1029-# Authored by: Martin Borho <martin@borho.net>
1030-
1031-"""weather app autopilot tests and emulators - top level package."""
1032-
1033-from ubuntuuitoolkit import emulators as toolkit_emulators
1034-
1035-
1036-class MainView(toolkit_emulators.MainView):
1037-
1038- def get_tabs(self):
1039- """Return the LocationTabs emulator of the MainView."""
1040- tabs = self.wait_select_single(Tabs)
1041- assert tabs is not None, toolkit_emulators._NO_TABS_ERROR
1042- return tabs
1043-
1044- def wait_for_activity_to_finish(self):
1045- """Wait for any running activity indicator to finish"""
1046- try:
1047- self._get_activity_indicator().running.wait_for(False)
1048- except:
1049- # No activity in progress.
1050- pass
1051-
1052- def _get_activity_indicator(self):
1053- """Return an activity indicator"""
1054- return self.select_single("ActivityIndicator", running="True")
1055-
1056-
1057-class Tabs(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
1058- """LocationTabs Autopilot emulator."""
1059-
1060- def get_current_tab(self):
1061- """Return the currently selected tab."""
1062- return self.select_many('LocationTab')[self.selectedTabIndex]
1063-
1064- def get_number_of_tabs(self):
1065- """Return the number of tabs."""
1066- return len(self.select_many('LocationTab'))
1067
1068=== modified file 'tests/autopilot/ubuntu_weather_app/tests/__init__.py'
1069--- tests/autopilot/ubuntu_weather_app/tests/__init__.py 2014-09-04 05:56:22 +0000
1070+++ tests/autopilot/ubuntu_weather_app/tests/__init__.py 2014-09-04 17:21:39 +0000
1071@@ -1,5 +1,5 @@
1072 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1073-# Copyright 2013 Canonical
1074+# Copyright 2013, 2014 Canonical
1075 #
1076 # This program is free software: you can redistribute it and/or modify it
1077 # under the terms of the GNU General Public License version 3, as published
1078@@ -25,11 +25,44 @@
1079 base,
1080 emulators as toolkit_emulators
1081 )
1082-from ubuntu_weather_app import emulators
1083+from ubuntuuitoolkit._custom_proxy_objects import AppHeader
1084 import ubuntu_weather_app
1085
1086 logger = logging.getLogger(__name__)
1087
1088+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1089+# Copyright 2013 Canonical
1090+#
1091+# This program is free software: you can redistribute it and/or modify it
1092+# under the terms of the GNU General Public License version 3, as published
1093+# by the Free Software Foundation.
1094+#
1095+# Authored by: Martin Borho <martin@borho.net>
1096+
1097+"""weather app autopilot tests and emulators - top level package."""
1098+
1099+import ubuntuuitoolkit
1100+
1101+
1102+class MainView(ubuntuuitoolkit.MainView):
1103+
1104+ def get_tabs(self):
1105+ tabs = self.wait_select_single(Tabs)
1106+ assert tabs is not None, toolkit_emulators._NO_TABS_ERROR
1107+ return tabs
1108+
1109+ def wait_for_activity_to_finish(self):
1110+ """Wait for any running activity indicator to finish"""
1111+ try:
1112+ self._get_activity_indicator().running.wait_for(False)
1113+ except:
1114+ # No activity in progress.
1115+ pass
1116+
1117+ def _get_activity_indicator(self):
1118+ """Return an activity indicator"""
1119+ return self.select_single("ActivityIndicator", running="True")
1120+
1121
1122 class WeatherTestCase(base.UbuntuUIToolkitAppTestCase):
1123
1124@@ -89,23 +122,45 @@
1125
1126 @property
1127 def main_view(self):
1128- return self.app.wait_select_single(emulators.MainView)
1129-
1130-
1131-class SheetMixin(object):
1132+ return self.app.wait_select_single(MainView)
1133+
1134+
1135+class AppHeader(AppHeader):
1136+ """AppHeader Autopilot custom proxy object."""
1137+
1138+ def click_action_button(self, action_object_name):
1139+ """Click an action button of the header.
1140+
1141+ :parameter object_name: The QML objectName property of the action
1142+ :raise ToolkitException: If there is no action button with that object
1143+ name.
1144+
1145+ """
1146+ self._show_if_not_visible()
1147+
1148+ button = self._get_action_button(action_object_name)
1149+ time.sleep(2)
1150+ self.pointing_device.click_object(button)
1151+
1152+
1153+class Tabs(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
1154+ """LocationTabs Autopilot emulator."""
1155+
1156+ def get_current_tab(self):
1157+ """Return the currently selected tab."""
1158+ return self.select_many('LocationTab')[self.selectedTabIndex]
1159+
1160+ def get_number_of_tabs(self):
1161+ """Return the number of tabs."""
1162+ return len(self.select_many('LocationTab'))
1163+
1164+
1165+class PageMixin(object):
1166 """A mixin to to give access to common sheet elements"""
1167
1168- def _click_sheet_confirm(self):
1169- """Clicks the confirm button"""
1170- button = self.main_view.select_single(
1171- 'Button', objectName='confirmButton')
1172- self.pointing_device.click_object(button)
1173-
1174- def _click_sheet_cancel(self):
1175- """Clicks the cancel button"""
1176- button = self.main_view.select_single(
1177- 'Button', objectName='cancelButton')
1178- self.pointing_device.click_object(button)
1179+ def _go_back(self):
1180+ """Go back in PageStack"""
1181+ self.main_view.get_header().click_custom_back_button()
1182
1183
1184 class LocationManagerMixin(object):
1185@@ -119,8 +174,8 @@
1186 self.pointing_device.move_to_object(addCityItem)
1187 self.pointing_device.click()
1188
1189- addLocPage = self.main_view.select_single(
1190- "DefaultSheet", objectName="AddLocationSheet")
1191+ addLocPage = self.main_view.wait_select_single(
1192+ "AddLocationPage", objectName="AddLocationPage")
1193 self.assertThat(addLocPage.visible, Eventually(Equals(True)))
1194
1195
1196
1197=== modified file 'tests/autopilot/ubuntu_weather_app/tests/test_locationmanager.py'
1198--- tests/autopilot/ubuntu_weather_app/tests/test_locationmanager.py 2014-09-04 06:37:54 +0000
1199+++ tests/autopilot/ubuntu_weather_app/tests/test_locationmanager.py 2014-09-04 17:21:39 +0000
1200@@ -17,7 +17,7 @@
1201 from ubuntu_weather_app.tests import (
1202 WeatherTestCase,
1203 DatabaseMixin,
1204- SheetMixin,
1205+ PageMixin,
1206 LocationManagerMixin
1207 )
1208
1209@@ -30,7 +30,7 @@
1210 # FIXME Use fixtures instead of the complex multiple inheritance.
1211 # --elopio - 2014-09-03
1212 class BaseTestLocationManager(
1213- WeatherTestCase, DatabaseMixin, SheetMixin, LocationManagerMixin):
1214+ WeatherTestCase, DatabaseMixin, PageMixin, LocationManagerMixin):
1215
1216 def _open_location_manager(self, kb=False):
1217 """Opens the location manager"""
1218@@ -40,8 +40,8 @@
1219 self.main_view.get_header().click_action_button("EditButton")
1220
1221 # test location manager becomes visible
1222- managerSheet = self.main_view.select_single(
1223- 'ComposerSheet', objectName='LocationManagerSheet')
1224+ managerSheet = self.main_view.wait_select_single(
1225+ 'LocationManagerPage', objectName='LocationManagerPage')
1226 self.assertThat(managerSheet.visible, Eventually(Equals(True)))
1227
1228 def _swipe_first_location_to_remove(self):
1229@@ -58,8 +58,8 @@
1230 Eventually(Equals(number_of_locations - 1)))
1231
1232 def _get_number_of_locations(self):
1233- qqlw = self.app.wait_select_single("ComposerSheet").wait_select_single(
1234- "QQuickListView")
1235+ qqlw = self.app.wait_select_single(
1236+ "LocationManagerPage").wait_select_single("QQuickListView")
1237 return qqlw.count
1238
1239 def _add_location(self, location):
1240@@ -81,7 +81,7 @@
1241 # LocationManagerPage should be visible and location added
1242 addedItem = self.main_view.wait_select_single('Label', text=location)
1243 self.assertThat(addedItem.text, Eventually(Equals(location)))
1244- self._click_sheet_confirm()
1245+ self._go_back()
1246
1247 # back to locations, wait till data is loaded
1248 self.main_view.wait_for_activity_to_finish()
1249@@ -144,7 +144,7 @@
1250 addedItem = self.main_view.wait_select_single(
1251 'Label', objectName="existingLocation0")
1252 self.assertThat(addedItem.text, Eventually(Equals(location)))
1253- self._click_sheet_confirm()
1254+ self._go_back()
1255
1256 # back to locations, wait till data is loaded
1257 self.main_view.wait_for_activity_to_finish()
1258@@ -188,7 +188,7 @@
1259 def test_cancel_adding_location(self):
1260 """Cancel the cities search"""
1261 self._open_add_location_page()
1262- self._click_sheet_cancel()
1263+ self._go_back()
1264 locationList = self.main_view.wait_select_single(
1265 'QQuickListView', objectName='LocationList')
1266 self.assertThat(locationList.visible, Eventually(Equals(True)))
1267@@ -231,7 +231,7 @@
1268 addedItem = self.main_view.wait_select_single(
1269 'Label', objectName="existingLocation0")
1270 self.assertThat(addedItem.text, Eventually(Equals(location_name)))
1271- self._click_sheet_confirm()
1272+ self._go_back()
1273
1274 # back to locations, wait till data is loaded
1275 self.main_view.wait_for_activity_to_finish()
1276@@ -260,10 +260,11 @@
1277 self.add_locations_to_database()
1278 logger.debug("Re-Launching app to introspect")
1279
1280- def _remove_location(self):
1281+ def _remove_location(self, stay=False):
1282 self._open_location_manager()
1283 self._swipe_first_location_to_remove()
1284- self._click_sheet_confirm()
1285+ if not stay:
1286+ self._go_back()
1287
1288 def _wait_for_tab(self):
1289 loadingPage = self.main_view.get_tabs()
1290@@ -286,6 +287,7 @@
1291 tabObjects = lambda: len(self.main_view.select_many('LocationTab'))
1292 self.assertThat(tabObjects, Eventually(Equals(tabsSumStart - 1)))
1293
1294+ @skip("skipped because of no cancel action exists atm")
1295 def test_cancel_remove_location(self):
1296 """Cancels removing of location"""
1297 # wait data is loaded
1298@@ -309,10 +311,9 @@
1299 """Tests if removing and add a location in one action works
1300 https://bugs.launchpad.net/ubuntu-weather-app/+bug/1230297"""
1301 # remove a location
1302- self._remove_location()
1303+ self._remove_location(stay=True)
1304
1305 # add a location
1306- self._open_location_manager()
1307 self._add_location("Cairo")
1308
1309 # back to locations, wait till data is loaded
1310
1311=== modified file 'tests/autopilot/ubuntu_weather_app/tests/test_settings.py'
1312--- tests/autopilot/ubuntu_weather_app/tests/test_settings.py 2014-07-10 19:34:54 +0000
1313+++ tests/autopilot/ubuntu_weather_app/tests/test_settings.py 2014-09-04 17:21:39 +0000
1314@@ -10,14 +10,15 @@
1315 from __future__ import absolute_import
1316 from testtools.matchers import Equals, Is, Not
1317 from autopilot.matchers import Eventually
1318+from unittest import skip
1319 import logging
1320
1321-from ubuntu_weather_app.tests import WeatherTestCase, DatabaseMixin, SheetMixin
1322+from ubuntu_weather_app.tests import WeatherTestCase, DatabaseMixin, PageMixin
1323
1324 logger = logging.getLogger(__name__)
1325
1326
1327-class TestSettings(WeatherTestCase, DatabaseMixin, SheetMixin):
1328+class TestSettings(WeatherTestCase, DatabaseMixin, PageMixin):
1329 def setUp(self):
1330 # we want to start with fake settings data
1331 self.create_blank_db()
1332@@ -28,7 +29,7 @@
1333 self.assertThat(
1334 self.main_view.visible, Eventually(Equals(True)))
1335
1336- def _open_settings_sheet(self):
1337+ def _open_settings_page(self):
1338 """Opens the settings sheet"""
1339 self.main_view.get_header().click_action_button("SettingsButton")
1340
1341@@ -146,37 +147,38 @@
1342 """Tests switching the scale in the settings"""
1343 # first check metric values and open the settings sheet
1344 self._check_units('metric')
1345- self._open_settings_sheet()
1346+ self._open_settings_page()
1347
1348 # get temp selector
1349 units_selector = self._get_selector("TemperatureUnitsSelector")
1350
1351 # choose second option, fahrenheit
1352 units_selector.select_option(objectName="fahrenheitOption")
1353- self._click_sheet_confirm()
1354+ self._go_back()
1355
1356 # wait for reload and check the imperial values
1357 self.main_view.wait_for_activity_to_finish()
1358 self._check_units('imperial')
1359
1360 # switch back to metric values again
1361- self._open_settings_sheet()
1362+ self._open_settings_page()
1363 units_selector = self._get_selector("TemperatureUnitsSelector")
1364
1365 # click celsius option
1366 units_selector.select_option(objectName="celsiusOption")
1367- self._click_sheet_confirm()
1368+ self._go_back()
1369
1370 # wait for reload and check the metric values again
1371 self.main_view.wait_for_activity_to_finish()
1372 self._check_units('metric')
1373
1374+ @skip("skipped because of missing cancel action")
1375 def test_switch_scale_cancel(self):
1376 """Test canceling switching scale"""
1377 # first check metric values and open the settings sheet
1378 self._check_units('metric')
1379 self._check_wind_units('kmh')
1380- self._open_settings_sheet()
1381+ self._open_settings_page()
1382
1383 # open the temp value selector
1384 units_selector = self._get_selector("TemperatureUnitsSelector")
1385@@ -197,22 +199,22 @@
1386 """Tests switching the wind scale in the settings"""
1387 # first check metric values and open the settings sheet
1388 self._check_wind_units('kmh')
1389- self._open_settings_sheet()
1390+ self._open_settings_page()
1391
1392 # choose mph and confirm
1393 wind_selector = self._get_selector("WindUnitsSelector")
1394 wind_selector.select_option(objectName="mphOption")
1395- self._click_sheet_confirm()
1396+ self._go_back()
1397
1398 # wait for reload and check the mph values
1399 self.main_view.wait_for_activity_to_finish()
1400 self._check_wind_units('mph')
1401
1402 # switch back to kmh values again
1403- self._open_settings_sheet()
1404+ self._open_settings_page()
1405 wind_selector = self._get_selector("WindUnitsSelector")
1406 wind_selector.select_option(objectName="kmhOption")
1407- self._click_sheet_confirm()
1408+ self._go_back()
1409
1410 # wait for reload and check the metric values again
1411 self.main_view.wait_for_activity_to_finish()
1412@@ -222,7 +224,7 @@
1413 """Tests switching the scale in the settings"""
1414 # first check metric values and open the settings sheet
1415 self._check_service('weatherchannel')
1416- self._open_settings_sheet()
1417+ self._open_settings_page()
1418
1419 # choose second option, openweathermap
1420 selector = self._get_selector("ServiceSelector")
1421@@ -232,14 +234,14 @@
1422 self.assertThat(lambda: self.main_view.select_single('OptionSelector',
1423 objectName='PrecipitationUnitsSelector'),
1424 Eventually(Not(Is(None))))
1425- self._click_sheet_confirm()
1426+ self._go_back()
1427
1428 # wait for reload and check the used service
1429 self.main_view.wait_for_activity_to_finish()
1430 self._check_service('openweathermap')
1431
1432 # switch back to twc values again
1433- self._open_settings_sheet()
1434+ self._open_settings_page()
1435 selector = self._get_selector("ServiceSelector")
1436 selector.select_option(objectName="twcOption")
1437
1438@@ -247,7 +249,7 @@
1439 self.assertThat(lambda: self.main_view.select_single('OptionSelector',
1440 objectName='PrecipitationUnitsSelector'),
1441 Eventually(Not(Is(None))))
1442- self._click_sheet_confirm()
1443+ self._go_back()
1444
1445 # wait for reload and check the metric values again
1446 self.main_view.wait_for_activity_to_finish()
1447
1448=== modified file 'ubuntu-weather-app.qml'
1449--- ubuntu-weather-app.qml 2014-09-02 07:21:28 +0000
1450+++ ubuntu-weather-app.qml 2014-09-04 17:21:39 +0000
1451@@ -185,7 +185,7 @@
1452 };
1453 }
1454 tabsString += "}"; // END Tabs componen
1455- tabsObject = Qt.createQmlObject(tabsString, tabPage, "tabs")
1456+ tabsObject = Qt.createQmlObject(tabsString, pageStack, "tabs")
1457 if(focusToLast) {
1458 tabsObject.selectedTabIndex = locLength -1;
1459 } else if(tabIndexAtRefresh > -1) {
1460@@ -215,11 +215,11 @@
1461 }
1462
1463 function showLocationManager() {
1464- PopupUtils.open(locationManager)
1465+ pageStack.push(Qt.resolvedUrl("components/LocationManagerPage.qml"))
1466 }
1467
1468 function showSettings() {
1469- PopupUtils.open(settingsSheet)
1470+ pageStack.push(Qt.resolvedUrl("components/SettingsPage.qml"))
1471 }
1472
1473 Component.onCompleted: {
1474@@ -237,19 +237,11 @@
1475 refreshData();
1476 })
1477 }
1478-
1479- Components.SettingsSheet {
1480- id: settingsSheet
1481- }
1482
1483 Components.Storage{
1484 id: storage
1485 }
1486
1487- Components.LocationManagerSheet {
1488- id:locationManager
1489- }
1490-
1491 Components.SplashComponent {
1492 id:httpFailedSplash
1493 objectName: "HTTPFailedSplash"
1494@@ -259,8 +251,8 @@
1495 id:refresh
1496 }
1497
1498- Item {
1499- id:tabPage
1500+ PageStack {
1501+ id:pageStack
1502 anchors.fill: parent
1503 }
1504

Subscribers

People subscribed via source and target branches