Merge lp:~nik90/unav/fix-unav-list-items into lp:~costales/unav/trunk

Proposed by Nekhelesh Ramananthan
Status: Merged
Merge reported by: costales
Merged at revision: not available
Proposed branch: lp:~nik90/unav/fix-unav-list-items
Merge into: lp:~costales/unav/trunk
Diff against target: 1479 lines (+615/-766)
5 files modified
qml/AboutPage.qml (+144/-254)
qml/FavoritesPage.qml (+11/-28)
qml/HeaderListItem.qml (+30/-0)
qml/SearchPage.qml (+356/-418)
qml/SettingsPage.qml (+74/-66)
To merge this branch: bzr merge lp:~nik90/unav/fix-unav-list-items
Reviewer Review Type Date Requested Status
costales Pending
Review via email: mp+288997@code.launchpad.net

Commit message

- Converts listitems to using ListItemLayouts
- Replace UbuntuListView with just ListView
- Added custom header listitem which uses the new ListItem instead of the deprecated ListItem.Header.
- Massive simplication of the about page code

Description of the change

This MP basically revamps all the list items shown in uNav to follow the system design. It also converts them to the new ListItemLayouts which is more performant, consistent design etc.

Also replaces UbuntuListView with ListView since we are not using any of the features offered by UbuntuListView thereby wasting memory use.

Simplified massively the about page code by using just one listmodel and one listview.

Added custom header listitem which uses the new ListItem instead of the deprecated ListItem.Header.

Note: It seems like a huge code diff in SearchPage.qml, but turns out I just aligned the code accidentally by pressing Ctrl+A and then Ctrl+I. Rest assured it just aligns the code correctly.

To post a comment you must log in.
lp:~nik90/unav/fix-unav-list-items updated
7. By Nekhelesh Ramananthan

Massive simplication of the about page (code wise)

Revision history for this message
costales (costales) wrote :

Thanks a lot Nekhelesh!! Great contribution!!
I added you to the credits with your name and your LP url, if you prefer another, tell me :)
A hug!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'qml/AboutPage.qml'
2--- qml/AboutPage.qml 2016-03-14 18:40:54 +0000
3+++ qml/AboutPage.qml 2016-03-15 01:14:51 +0000
4@@ -16,261 +16,151 @@
5
6 import QtQuick 2.4
7 import Ubuntu.Components 1.3
8-import Ubuntu.Components.ListItems 1.3 as ListItem
9 import "js/utils.js" as QmlJs
10
11 Page {
12- id: aboutPage
13- title: i18n.tr("About")
14-
15- Flickable {
16- id: flickable
17- anchors.fill: parent
18- contentHeight: appColumn.height + donateColumn.height + launchpadColumn.height + devColumn.height + voicesColumn.height + i18nColumn.height + poweredByColumn.height + units.gu(16)
19-
20- Column {
21- id: appColumn
22- spacing: units.gu(1)
23- anchors {
24- top: parent.top; left: parent.left; right: parent.right; topMargin: units.gu(5)
25- }
26- Image {
27- id: appImage
28- source: "../nav/img/about/logo.png"
29- anchors.horizontalCenter: parent.horizontalCenter
30- }
31- Label {
32- width: parent.width
33- wrapMode: Text.WordWrap
34- horizontalAlignment: Text.AlignHCenter
35- //TRANSLATORS: %1 and %2 are links that do not have to be translated: Year + Project + License
36- text: "© uNav 2015-" + new Date().getFullYear()
37- }
38- Label {
39- width: parent.width
40- wrapMode: Text.WordWrap
41- horizontalAlignment: Text.AlignHCenter
42- //TRANSLATORS: %1 and %2 are links that do not have to be translated: Year + Project + License
43- text: i18n.tr("Version %1. Under License %2").arg(navApp.applicationVersion).arg("<a href=\"http://www.gnu.org/licenses/gpl-3.0.en.html\">GPL3</a>")
44- onLinkActivated: Qt.openUrlExternally(link)
45- }
46- }
47-
48- Column {
49- id: donateColumn
50- anchors.top: appColumn.bottom
51- anchors.topMargin: units.gu(3)
52- width: parent.width
53- spacing: units.gu(1)
54- Label {
55- id: donateLabel
56- text: i18n.tr("Support its future development")
57- anchors.horizontalCenter: parent.horizontalCenter
58- wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
59- horizontalAlignment: Text.AlignHCenter
60- width: parent.width - units.gu(12)
61- }
62- Button {
63- anchors.horizontalCenter: parent.horizontalCenter
64- color: UbuntuColors.green
65- text: i18n.tr("Buy Donate Version")
66- onClicked: Qt.openUrlExternally("scope://com.canonical.scopes.clickstore?q=unavdonateversion")
67- }
68- }
69-
70- Column {
71- id: launchpadColumn
72- anchors.top: donateColumn.bottom
73- width: parent.width
74- ListItem.Header {
75- id: lpHeader
76- text: i18n.tr("Resources")
77- }
78-
79- Repeater {
80- id: lpListView
81-
82- model: lpModel
83- delegate: ListItem.Standard {
84- progression: true
85- showDivider: false
86- text: model.name
87- onClicked: Qt.openUrlExternally(model.link)
88- }
89- }
90-
91- ListModel {
92- id: lpModel
93- Component.onCompleted: initialize()
94- function initialize() {
95- lpModel.append({ name: i18n.tr("Bugs"), link: "https://bugs.launchpad.net/unav" })
96- lpModel.append({ name: i18n.tr("Translations"), link: "https://translations.launchpad.net/unav" })
97- lpModel.append({ name: i18n.tr("Answers"), link: "https://answers.launchpad.net/unav" })
98- lpModel.append({ name: i18n.tr("Contact"), link: "mailto:costales.marcos@gmail.com" })
99- }
100- }
101- }
102-
103- Column {
104- id: devColumn
105- anchors.top: launchpadColumn.bottom
106- anchors.topMargin: units.gu(2)
107- width: parent.width
108- ListItem.Header {
109- id: devHeader
110- text: i18n.tr("Developers")
111- }
112-
113- Repeater {
114- id: devListView
115-
116- model: devModel
117- delegate: ListItem.Standard {
118- progression: true
119- showDivider: false
120- text: model.name
121- onClicked: Qt.openUrlExternally(model.link)
122- }
123- }
124-
125- ListModel {
126- id: devModel
127- Component.onCompleted: initialize()
128- function initialize() {
129- devModel.append({ name: "JkB", link: "https://launchpad.net/~joergberroth" })
130- devModel.append({ name: "Marcos Costales (" + i18n.tr("Founder") + ")", link: "https://wiki.ubuntu.com/costales" })
131- }
132- }
133- }
134-
135- Column {
136- id: voicesColumn
137- anchors.top: devColumn.bottom
138- anchors.topMargin: units.gu(2)
139- width: parent.width
140-
141- ListItem.Header {
142- id: voicesHeader
143- text: i18n.tr("Voice")
144- }
145-
146- Repeater {
147- id: voicesListView
148- anchors.top: voicesColumn.bottom
149-
150- model: voicesModel
151- delegate: ListItem.Standard {
152- progression: true
153- showDivider: false
154- text: model.name
155- onClicked: Qt.openUrlExternally(model.link)
156- }
157- }
158-
159- ListModel {
160- id: voicesModel
161- Component.onCompleted: initialize()
162- function initialize() {
163- switch (Qt.locale().name.substring(0,2).toLowerCase()) {
164- case 'de':
165- voicesModel.append({name: "Ilonka Oettershagen", link: "https://plus.google.com/107664665064221547104"});
166- break;
167- case 'es':
168- voicesModel.append({name: "Fernando Lanero", link: "https://twitter.com/ferlanero"})
169- break;
170- case 'it':
171- voicesModel.append({name: "Silvia Bindelli", link: "https://twitter.com/SilviaBindelli"})
172- break;
173- case 'nl':
174- voicesModel.append({name: "Mark van den Driesche", link: "http://google.com/+Markcortbass"})
175- break;
176- case 'sl':
177- voicesModel.append({name: "Bernard Banko", link: "https://launchpad.net/~beernarrd"})
178- break;
179- default:
180- voicesModel.append({name: "Nathan Haines", link: "http://www.nhaines.com"})
181- }
182- }
183- }
184- }
185-
186- Column {
187- id: i18nColumn
188- anchors.top: voicesColumn.bottom
189- anchors.topMargin: units.gu(2)
190- width: parent.width
191-
192- ListItem.Header {
193- id: i18nHeader
194- text: i18n.tr("Translators")
195- }
196-
197- Repeater {
198- id: i18nListView
199-
200- model: i18nModel
201- delegate: ListItem.Standard {
202- progression: true
203- showDivider: false
204- text: model.name
205- onClicked: Qt.openUrlExternally(model.link)
206- }
207- }
208-
209- ListModel {
210- id: i18nModel
211- Component.onCompleted: initialize()
212- function initialize() {
213- var translators = QmlJs.getTranslators( i18n.tr("translator-credits") )
214- translators.forEach(function(translator) {
215- i18nModel.append({ name: translator['name'], link: translator['link'] });
216- });
217- }
218- }
219- }
220-
221- Column {
222- id: poweredByColumn
223- anchors.top: i18nColumn.bottom
224- anchors.topMargin: units.gu(2)
225- width: parent.width
226-
227- ListItem.Header {
228- id: poweredbyHeader
229- text: i18n.tr("Powered by")
230- }
231-
232- Repeater {
233- id: poweredbyListView
234-
235- model: poweredbyModel
236- delegate: ListItem.Standard {
237- progression: true
238- showDivider: false
239- text: model.name
240- onClicked: Qt.openUrlExternally(model.link)
241- }
242- }
243-
244- ListModel {
245- id: poweredbyModel
246- Component.onCompleted: initialize()
247- function initialize() {
248- poweredbyModel.append({ name: "OpenStreetMap & Contributors", link: "http://www.openstreetmap.org" })
249- poweredbyModel.append({ name: "Mapzen", link: "https://mapzen.com/projects/valhalla" })
250- poweredbyModel.append({ name: "MapQuest", link: "http://open.mapquest.com/" })
251- poweredbyModel.append({ name: "OpenStreetMap Nominatin", link: "http://open.mapquestapi.com/nominatim" })
252- poweredbyModel.append({ name: "Overpass API", link: "http://wiki.openstreetmap.org/wiki/Overpass_API/XAPI_Compatibility_Layer" })
253- poweredbyModel.append({ name: "OpenLayers", link: "http://openlayers.org" })
254- poweredbyModel.append({ name: "Turf.js", link: "http://turfjs.org" })
255- poweredbyModel.append({ name: "JQuery", link: "https://jquery.com" })
256- poweredbyModel.append({ name: "jquery.localize.js", link: "https://github.com/coderifous/jquery-localize" })
257- poweredbyModel.append({ name: "The Noun Project", link: "https://thenounproject.com" })
258- poweredbyModel.append({ name: "Wikimedia", link: "https://commons.wikimedia.org/wiki/Category:Multi-touch_gestures" })
259- poweredbyModel.append({ name: "IconFinder", link: "https://www.iconfinder.com/icons/172062/navigation_icon" })
260- poweredbyModel.append({ name: "Leaflet Marker", link: "https://github.com/Leaflet/Leaflet" })
261- }
262- }
263- }
264- }
265+ id: aboutPage
266+
267+ header: PageHeader {
268+ title: i18n.tr("About")
269+ flickable: creditsListView
270+ }
271+
272+ ListModel {
273+ id: creditsModel
274+
275+ Component.onCompleted: initialize()
276+
277+ function initialize() {
278+ // Resources
279+ creditsModel.append({ category: i18n.tr("Resources"), name: i18n.tr("Bugs"), link: "https://bugs.launchpad.net/unav" })
280+ creditsModel.append({ category: i18n.tr("Resources"), name: i18n.tr("Translations"), link: "https://translations.launchpad.net/unav" })
281+ creditsModel.append({ category: i18n.tr("Resources"), name: i18n.tr("Answers"), link: "https://answers.launchpad.net/unav" })
282+ creditsModel.append({ category: i18n.tr("Resources"), name: i18n.tr("Contact"), link: "mailto:costales.marcos@gmail.com" })
283+
284+ // Developers
285+ creditsModel.append({ category: i18n.tr("Developers"), name: "JkB", link: "https://launchpad.net/~joergberroth" })
286+ creditsModel.append({ category: i18n.tr("Developers"), name: "Marcos Costales (" + i18n.tr("Founder") + ")", link: "https://wiki.ubuntu.com/costales" })
287+
288+ // Voices
289+ switch (Qt.locale().name.substring(0,2).toLowerCase()) {
290+ case 'de':
291+ creditsModel.append({ category: i18n.tr("Voice"), name: "Ilonka Oettershagen", link: "https://plus.google.com/107664665064221547104" });
292+ break;
293+ case 'es':
294+ creditsModel.append({ category: i18n.tr("Voice"), name: "Fernando Lanero", link: "https://twitter.com/ferlanero" })
295+ break;
296+ case 'it':
297+ creditsModel.append({ category: i18n.tr("Voice"), name: "Silvia Bindelli", link: "https://twitter.com/SilviaBindelli" })
298+ break;
299+ case 'nl':
300+ creditsModel.append({ category: i18n.tr("Voice"), name: "Mark van den Driesche", link: "http://google.com/+Markcortbass" })
301+ break;
302+ case 'sl':
303+ creditsModel.append({ category: i18n.tr("Voice"), name: "Bernard Banko", link: "https://launchpad.net/~beernarrd" })
304+ break;
305+ default:
306+ creditsModel.append({ category: i18n.tr("Voice"), name: "Nathan Haines", link: "http://www.nhaines.com" })
307+ }
308+
309+ // Translators
310+ var translators = QmlJs.getTranslators( i18n.tr("translator-credits") )
311+ translators.forEach(function(translator) {
312+ creditsModel.append({ category: i18n.tr("Translators"), name: translator['name'], link: translator['link'] });
313+ });
314+
315+ // Powered By
316+ creditsModel.append({ category: i18n.tr("Powered by"), name: "OpenStreetMap & Contributors", link: "http://www.openstreetmap.org" })
317+ creditsModel.append({ category: i18n.tr("Powered by"), name: "Mapzen", link: "https://mapzen.com/projects/valhalla" })
318+ creditsModel.append({ category: i18n.tr("Powered by"), name: "MapQuest", link: "http://open.mapquest.com/" })
319+ creditsModel.append({ category: i18n.tr("Powered by"), name: "OpenStreetMap Nominatin", link: "http://open.mapquestapi.com/nominatim" })
320+ creditsModel.append({ category: i18n.tr("Powered by"), name: "Overpass API", link: "http://wiki.openstreetmap.org/wiki/Overpass_API/XAPI_Compatibility_Layer" })
321+ creditsModel.append({ category: i18n.tr("Powered by"), name: "OpenLayers", link: "http://openlayers.org" })
322+ creditsModel.append({ category: i18n.tr("Powered by"), name: "Turf.js", link: "http://turfjs.org" })
323+ creditsModel.append({ category: i18n.tr("Powered by"), name: "JQuery", link: "https://jquery.com" })
324+ creditsModel.append({ category: i18n.tr("Powered by"), name: "jquery.localize.js", link: "https://github.com/coderifous/jquery-localize" })
325+ creditsModel.append({ category: i18n.tr("Powered by"), name: "The Noun Project", link: "https://thenounproject.com" })
326+ creditsModel.append({ category: i18n.tr("Powered by"), name: "Wikimedia", link: "https://commons.wikimedia.org/wiki/Category:Multi-touch_gestures" })
327+ creditsModel.append({ category: i18n.tr("Powered by"), name: "IconFinder", link: "https://www.iconfinder.com/icons/172062/navigation_icon" })
328+ creditsModel.append({ category: i18n.tr("Powered by"), name: "Leaflet Marker", link: "https://github.com/Leaflet/Leaflet" })
329+ }
330+ }
331+
332+ ListView {
333+ id: creditsListView
334+
335+ model: creditsModel
336+ anchors.fill: parent
337+ section.property: "category"
338+ section.criteria: ViewSection.FullString
339+ section.delegate: HeaderListItem {
340+ title: section
341+ }
342+
343+ header: Item {
344+ width: parent.width
345+ height: appColumn.height + donateColumn.height + units.gu(10)
346+ Column {
347+ id: appColumn
348+ spacing: units.gu(1)
349+ anchors {
350+ top: parent.top; left: parent.left; right: parent.right; topMargin: units.gu(5)
351+ }
352+ Image {
353+ id: appImage
354+ source: "../nav/img/about/logo.png"
355+ anchors.horizontalCenter: parent.horizontalCenter
356+ }
357+ Label {
358+ width: parent.width
359+ wrapMode: Text.WordWrap
360+ horizontalAlignment: Text.AlignHCenter
361+ //TRANSLATORS: %1 and %2 are links that do not have to be translated: Year + Project + License
362+ text: "© uNav 2015-" + new Date().getFullYear()
363+ }
364+ Label {
365+ width: parent.width
366+ wrapMode: Text.WordWrap
367+ horizontalAlignment: Text.AlignHCenter
368+ //TRANSLATORS: %1 and %2 are links that do not have to be translated: Year + Project + License
369+ text: i18n.tr("Version %1. Under License %2").arg(navApp.applicationVersion).arg("<a href=\"http://www.gnu.org/licenses/gpl-3.0.en.html\">GPL3</a>")
370+ onLinkActivated: Qt.openUrlExternally(link)
371+ }
372+ }
373+
374+ Column {
375+ id: donateColumn
376+ anchors.top: appColumn.bottom
377+ anchors.topMargin: units.gu(3)
378+ width: parent.width
379+ spacing: units.gu(1)
380+ Label {
381+ id: donateLabel
382+ text: i18n.tr("Support its future development")
383+ anchors.horizontalCenter: parent.horizontalCenter
384+ wrapMode: TextEdit.WrapAtWordBoundaryOrAnywhere
385+ horizontalAlignment: Text.AlignHCenter
386+ width: parent.width - units.gu(12)
387+ }
388+ Button {
389+ anchors.horizontalCenter: parent.horizontalCenter
390+ color: UbuntuColors.green
391+ text: i18n.tr("Buy Donate Version")
392+ onClicked: Qt.openUrlExternally("scope://com.canonical.scopes.clickstore?q=unavdonateversion")
393+ }
394+ }
395+ }
396+
397+ delegate: ListItem {
398+ height: creditsDelegateLayout.height
399+ divider.visible: false
400+ ListItemLayout {
401+ id: creditsDelegateLayout
402+ title.text: model.name
403+ ProgressionSlot {}
404+ }
405+ onClicked: Qt.openUrlExternally(model.link)
406+ }
407+ }
408 }
409+
410
411=== modified file 'qml/FavoritesPage.qml'
412--- qml/FavoritesPage.qml 2016-03-14 18:40:54 +0000
413+++ qml/FavoritesPage.qml 2016-03-15 01:14:51 +0000
414@@ -200,12 +200,16 @@
415 }
416 }
417
418- UbuntuListView {
419+ ListView {
420 id: favoritesListView
421+
422 model: favoritesModel
423 anchors.fill: parent
424
425 delegate: ListItem {
426+ id: delegate
427+
428+ height: favouriteDelegateLayout.height + divider.height
429 leadingActions: ListItemActions {
430 actions: [
431 Action {
432@@ -237,33 +241,12 @@
433 ]
434 }
435
436- contentItem.anchors {
437- leftMargin: units.gu(1)
438- rightMargin: units.gu(1)
439- topMargin: units.gu(0.5)
440- bottomMargin: units.gu(0.5)
441- }
442-
443- Label {
444- height: parent.height
445- width: parent.width *4/5
446- text: model.name
447- elide: Text.ElideRight
448- wrapMode: Text.WordWrap
449- }
450-
451- Label {
452- anchors.bottom: parent.bottom
453- width: parent.width /5
454- anchors.right: parent.right
455- horizontalAlignment: Text.AlignRight
456- visible: (mainPageStack.center_onpos !== 0)
457- text: QmlJs.formatDistance(
458- QmlJs.calcPoiDistance(mainPageStack.currentLat, mainPageStack.currentLng, model.lat, model.lng, 10),
459- navApp.settings.unit
460- )
461- fontSize: "small"
462- }
463+ ListItemLayout {
464+ id: favouriteDelegateLayout
465+ title.text: model.name
466+ subtitle.visible: mainPageStack.center_onpos !== 0
467+ subtitle.text: QmlJs.formatDistance(QmlJs.calcPoiDistance(mainPageStack.currentLat, mainPageStack.currentLng, model.lat, model.lng, 10), navApp.settings.unit)
468+ }
469
470 onClicked: {
471 mainPageStack.pop(favoritesPage)
472
473=== added file 'qml/HeaderListItem.qml'
474--- qml/HeaderListItem.qml 1970-01-01 00:00:00 +0000
475+++ qml/HeaderListItem.qml 2016-03-15 01:14:51 +0000
476@@ -0,0 +1,30 @@
477+/*
478+ * uNav http://launchpad.net/unav
479+ * Copyright (C) 2016 Nekhelesh Ramananthan https://launchpad.net/~nik90
480+ *
481+ * uNav is free software; you can redistribute it and/or modify
482+ * it under the terms of the GNU General Public License as published by
483+ * the Free Software Foundation; either version 3 of the License, or
484+ * (at your option) any later version.
485+ *
486+ * uNav is distributed in the hope that it will be useful,
487+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
488+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
489+ * GNU General Public License for more details.
490+ */
491+
492+import QtQuick 2.4
493+import Ubuntu.Components 1.3
494+
495+ListItem {
496+ id: headerListItem
497+
498+ property string title
499+
500+ height: units.gu(4)
501+ Label {
502+ anchors { verticalCenter: parent.verticalCenter; left: parent.left; leftMargin: units.gu(2) }
503+ text: title
504+ font.bold: true
505+ }
506+}
507
508=== modified file 'qml/SearchPage.qml'
509--- qml/SearchPage.qml 2016-03-14 18:40:54 +0000
510+++ qml/SearchPage.qml 2016-03-15 01:14:51 +0000
511@@ -18,428 +18,366 @@
512 import QtQuick.Layouts 1.1
513 import Ubuntu.Components 1.3
514 import Ubuntu.Components.Popups 1.3
515-import Ubuntu.Components.ListItems 1.3 as ListItems
516 import QtQuick.LocalStorage 2.0
517 import QtQuick.XmlListModel 2.0
518 import "js/utils.js" as QmlJs
519 import "js/db.js" as UnavDB
520
521 Page {
522- id: searchPage
523-
524- title: i18n.tr("Search")
525- anchors.fill: parent
526-
527- state: "search"
528- states: [
529- PageHeadState {
530- name: "search"
531- head: searchPage.head
532-
533- backAction: Action {
534- iconName: "back"
535- text: i18n.tr("Back")
536- onTriggered: {
537- mainPageStack.pop(searchPage)
538- }
539- }
540-
541- contents: TextField {
542- id: searchField
543- width: parent ? parent.width - units.gu(2) : undefined
544- inputMethodHints: Qt.ImhNoPredictiveText
545- hasClearButton: true
546- placeholderText: i18n.tr("Where do we go?")
547- onTriggered: {
548- if (text.length > 2) {
549- statusLabel.visible = true
550- statusLabel.text = i18n.tr("Searching…");
551- resultsListView.visible = false
552- xmlSearchModel.searchString = text;
553- xmlSearchModel.search();
554- } else {
555- searchField.text = "";
556- }
557- }
558- }
559- }
560- ]
561-
562- Label {
563- id: statusLabel
564- width: parent.width - units.gu(4)
565- anchors.horizontalCenter: parent.horizontalCenter
566- anchors.verticalCenter: parent.verticalCenter
567- visible: historyModel.count === 0
568- horizontalAlignment: Text.AlignHCenter
569- wrapMode: Text.WordWrap
570- text: navApp.settings.saveHistory ? i18n.tr("No history yet…") : i18n.tr("History is disabled")
571- }
572-
573- Icon {
574- id: historyIcon
575- width: units.gu(6)
576- anchors.horizontalCenter: parent.horizontalCenter
577- anchors.bottom: statusLabel.top
578- anchors.bottomMargin: units.gu(2)
579- visible: historyModel.count === 0 && xmlSearchModel.status !== XmlListModel.Loading
580- name: "history"
581- }
582-
583- // Indicator to show search activity
584- ActivityIndicator {
585- id: searchActivity
586- anchors {
587- bottom: statusLabel.top
588- bottomMargin: units.gu (1)
589- horizontalCenter: parent.horizontalCenter
590- }
591- running: xmlSearchModel.status === XmlListModel.Loading
592- }
593-
594- ListModel {
595- id: historyModel
596- function initialize() {
597- historyModel.clear();
598- var res = UnavDB.getSearchHistory();
599- var len = res.rows.length;
600- for (var i = 0; i < len; ++i) {
601- historyModel.append({
602- title: i18n.tr("Search history"),
603- name: res.rows.item(i).key,
604- lat: res.rows.item(i).lat,
605- lng: res.rows.item(i).lng
606- });
607- }
608- res = UnavDB.getfavHistory();
609- len = res.rows.length;
610- for (i = 0; i < len; ++i) {
611- historyModel.append({
612- title: i18n.tr("Favorite history"),
613- name: res.rows.item(i).key,
614- lat: res.rows.item(i).lat,
615- lng: res.rows.item(i).lng
616- });
617- }
618- res = UnavDB.getNearByHistory();
619- len = res.rows.length;
620- for (i = 0; i < len; ++i) {
621- historyModel.append({
622- title: i18n.tr("Nearby history"),
623- name: i18n.tr(res.rows.item(i).type),
624- en_name: res.rows.item(i).type,
625- clause: res.rows.item(i).clause
626- });
627- }
628- }
629- Component.onCompleted: initialize()
630- }
631-
632- //OSMTouch Model:
633- XmlListModel {
634- id: xmlSearchModel
635-
636- onStatusChanged: {
637- if (status === XmlListModel.Error) {
638- statusLabel.text = i18n.tr("Time out! Please try again");
639- statusLabel.visible = true;
640- historyIcon.visible = false;
641- resultsListView.visible = false;
642- } if (status === XmlListModel.Ready && count === 0) {
643- //TRANSLATORS: The Argument is the search input. E.G. a Town, Address....
644- statusLabel.text = i18n.tr("Sorry, no result for %1").arg(searchField.text);
645- statusLabel.visible = true;
646- historyIcon.visible = false;
647- resultsListView.visible = false;
648- } if (status === XmlListModel.Ready && count >> 0) {
649- statusLabel.visible = false;
650- historyIcon.visible = false;
651- sortedSearchModel.sortXmlList();
652- }
653- }
654-
655- readonly property string searchUrl: "https://nominatim.openstreetmap.org/search?format=xml&email=marcos.costales@gmail.com&limit=50&q="
656- property string searchString
657-
658- function search() {
659- xmlSearchModel.clear()
660- sortedSearchModel.clear()
661- source = (searchUrl + searchString);
662- }
663-
664- function clear() {
665- source: "";
666- }
667-
668- source: ""
669- query: "/searchresults/place"
670-
671- XmlRole { name: "name"; query: "@display_name/string()"; isKey: true }
672- XmlRole { name: "lat"; query: "@lat/string()"; isKey: true }
673- XmlRole { name: "lng"; query: "@lon/string()"; isKey: true }
674- XmlRole { name: "icon"; query: "@icon/string()"; isKey: true }
675- }
676-
677- ListModel {
678- id: sortedSearchModel
679-
680- function sortXmlList (){
681- sortedSearchModel.clear()
682- var item
683- for (var i = 0; i < xmlSearchModel.count; i++) {
684- item = {
685- "name": xmlSearchModel.get(i).name,
686- "lat": xmlSearchModel.get(i).lat,
687- "lng": xmlSearchModel.get(i).lng,
688- "icon": (xmlSearchModel.get(i).icon).replace('.p.20.png', '.p.32.png'),
689- "distance": QmlJs.calcPoiDistance(
690- mainPageStack.currentLat,
691- mainPageStack.currentLng,
692- xmlSearchModel.get(i).lat,
693- xmlSearchModel.get(i).lng,
694- 10
695- )
696- }
697- if (i === 0) {
698- sortedSearchModel.append(item)
699- } else { // sort model by distance
700- var j = 0;
701- while (j <= sortedSearchModel.count) {
702- if (j === sortedSearchModel.count) {
703- sortedSearchModel.append(item)
704- break;
705- } else if (item.distance < sortedSearchModel.get(j).distance){
706- sortedSearchModel.insert(j,item)
707- break;
708- } else {
709- j++;
710- }
711- }
712- }
713- xmlSearchModel.clear();
714- historyListView.visible = false;
715- resultsListView.visible = true;
716- }
717- }
718- }
719-
720- Component {
721- id: sectionHeading
722-
723- Rectangle {
724- width: parent.width
725- height: childrenRect.height
726-
727- ListItems.Header {
728- id: listHeader
729- text: section
730- }
731- }
732- }
733-
734- UbuntuListView {
735- id: historyListView
736- model: historyModel
737- visible: !statusLabel.visible
738- anchors.fill: parent
739-
740- section.property: "title"
741- section.criteria: ViewSection.FullString
742- //section.labelPositioning: ViewSection.CurrentLabelAtStart + ViewSection.InlineLabels
743- section.delegate: sectionHeading
744-
745- delegate: ListItem {
746- leadingActions: ListItemActions {
747- actions: [
748- Action {
749- iconName: "delete"
750- onTriggered: {
751- switch (model.title) {
752- case i18n.tr("Search history"):
753- UnavDB.removeHistorySearch(model.name);
754- break;
755- case i18n.tr("Nearby history"):
756- UnavDB.removeHistoryNearby(model.en_name);
757- break;
758- case i18n.tr("Favorite history"):
759- UnavDB.removeHistoryFavorite(model.name);
760- }
761- historyModel.initialize()
762- }
763- }
764- ]
765- }
766-
767- trailingActions: ListItemActions {
768- actions: [
769- Action {
770- iconName: "send"
771- onTriggered: {
772- mainPageStack.pop(searchPage);
773- mainPageStack.routeState = 'yes';
774- mainPageStack.executeJavaScript("calc2coord("+ model.lat + "," + model.lng + ");");
775- }
776- },
777- Action {
778- iconName: "share"
779- onTriggered: {
780- PopupUtils.open(Qt.resolvedUrl("./Share.qml"), navApp, {"lat": model.lat, "lon": model.lng})
781- }
782- }
783- ]
784- }
785-
786- contentItem.anchors {
787- leftMargin: units.gu(2)
788- rightMargin: units.gu(1)
789- topMargin: units.gu(0.5)
790- bottomMargin: units.gu(0.5)
791- }
792-
793- Label {
794- height: parent.height
795- width: parent.width *4/5
796- text: model.name
797- elide: Text.ElideRight
798- wrapMode: Text.WordWrap
799- }
800-
801- Icon {
802- id: progressionIcon
803- anchors {
804- right: parent.right
805- verticalCenter: parent.verticalCenter
806- }
807- height: units.gu(2.5)
808- name: "next"
809- visible: model.title === i18n.tr("Nearby history")
810- }
811-
812- Label {
813- anchors.bottom: parent.bottom
814- width: parent.width /5
815- anchors.right: parent.right
816- horizontalAlignment: Text.AlignRight
817- visible: model.title !== i18n.tr("Nearby history") && mainPageStack.currentLat !== "null" && mainPageStack.currentLng !== "null"
818- text: QmlJs.formatDistance(
819- QmlJs.calcPoiDistance(
820- mainPageStack.currentLat,
821- mainPageStack.currentLng,
822- model.lat, model.lng,
823- 10
824- ),
825- navApp.settings.unit
826- )
827- fontSize: "small"
828- }
829-
830- onClicked: {
831- mainPageStack.pop(searchPage)
832- if (model.title === i18n.tr("Nearby history")) {
833- mainPageStack.push(Qt.resolvedUrl("PoiListPage.qml"),
834- {
835- lat: mainPageStack.currentLat,
836- lng: mainPageStack.currentLng,
837- poiType: model.name,
838- clause: model.clause,
839- geoDistFactor: 5
840- })
841- } else {
842- mainPageStack.executeJavaScript("ui.markers_POI_set([{ title: \"" +
843- model.name + "\", lat: " +
844- model.lat + ", lng: " +
845- model.lng + "}]);");
846- }
847- }
848- }
849- }
850-
851- UbuntuListView {
852- id: resultsListView
853- model: sortedSearchModel
854-
855- width: parent.width
856- height: parent.height - units.gu(6)
857- anchors.top: parent.top
858- anchors.topMargin: units.gu(6)
859- visible: false
860-
861- delegate: ListItem {
862- trailingActions: ListItemActions {
863- actions: [
864- Action {
865- iconName: "send"
866- onTriggered: {
867- if (navApp.settings.saveHistory) {
868- UnavDB.saveToSearchHistory(model.name, model.lat, model.lng)
869- }
870- mainPageStack.pop(searchPage);
871- mainPageStack.routeState = 'yes'
872- mainPageStack.executeJavaScript("calc2coord(" + model.lat + "," + model.lng + ");")
873- }
874- },
875- Action {
876- iconName: "share"
877- onTriggered: {
878- PopupUtils.open(Qt.resolvedUrl("./Share.qml"), navApp, {"lat": model.lat, "lon": model.lng})
879- }
880- },
881- Action {
882- iconName: "non-starred"
883- onTriggered: {
884- mainPageStack.pop(searchPage)
885- mainPageStack.push(Qt.resolvedUrl("FavoritesPage.qml"), {state:"adding", lat: model.lat, lng: model.lng, favName: model.name})
886- }
887- }
888- ]
889- }
890-
891- onClicked: {
892- if (navApp.settings.saveHistory) {
893- UnavDB.saveToSearchHistory(model.name, model.lat, model.lng)
894- }
895- mainPageStack.pop(searchPage)
896- mainPageStack.executeJavaScript("ui.markers_POI_set([{title: \"" + model.name + "\", lat: " + model.lat + ", lng: " + model.lng + "}]);");
897- }
898-
899- contentItem.anchors {
900- leftMargin: units.gu(1)
901- rightMargin: units.gu(1)
902- topMargin: units.gu(0.5)
903- bottomMargin: units.gu(0.5)
904- }
905-
906- Label {
907- anchors.left: parent.left
908- height: parent.height
909- width: parent.width *4/5
910- text: model.name
911- elide: Text.ElideRight
912- wrapMode: Text.WordWrap
913-
914- }
915-
916- Icon {
917- id: resIcon
918- height: 32
919- width: height
920- visible: model.icon !== ""
921- anchors {
922- top: parent.top
923- right: parent.right
924- }
925- source: model.icon
926- }
927-
928- Label {
929- anchors.bottom: parent.bottom
930- width: parent.width /5
931- anchors.right: parent.right
932- horizontalAlignment: Text.AlignRight
933- visible: mainPageStack.currentLat !== "null" && mainPageStack.currentLng !== "null"
934- text: QmlJs.formatDistance(model.distance, navApp.settings.unit)
935- fontSize: "small"
936- }
937- }
938- }
939+ id: searchPage
940+
941+ title: i18n.tr("Search")
942+
943+ state: "search"
944+ states: [
945+ PageHeadState {
946+ name: "search"
947+ head: searchPage.head
948+
949+ backAction: Action {
950+ iconName: "back"
951+ text: i18n.tr("Back")
952+ onTriggered: {
953+ mainPageStack.pop(searchPage)
954+ }
955+ }
956+
957+ contents: TextField {
958+ id: searchField
959+ width: parent ? parent.width - units.gu(2) : undefined
960+ inputMethodHints: Qt.ImhNoPredictiveText
961+ hasClearButton: true
962+ placeholderText: i18n.tr("Where do we go?")
963+ onTriggered: {
964+ if (text.length > 2) {
965+ statusLabel.visible = true
966+ statusLabel.text = i18n.tr("Searching…");
967+ resultsListView.visible = false
968+ xmlSearchModel.searchString = text;
969+ xmlSearchModel.search();
970+ } else {
971+ searchField.text = "";
972+ }
973+ }
974+ }
975+ }
976+ ]
977+
978+ Label {
979+ id: statusLabel
980+ width: parent.width - units.gu(4)
981+ anchors.centerIn: parent
982+ visible: historyModel.count === 0
983+ horizontalAlignment: Text.AlignHCenter
984+ wrapMode: Text.WordWrap
985+ text: navApp.settings.saveHistory ? i18n.tr("No history yet…")
986+ : i18n.tr("History is disabled")
987+ }
988+
989+ Icon {
990+ id: historyIcon
991+ width: units.gu(6)
992+ anchors { horizontalCenter: parent.horizontalCenter; bottom: statusLabel.top; bottomMargin: units.gu(2) }
993+ visible: historyModel.count === 0 && xmlSearchModel.status !== XmlListModel.Loading
994+ name: "history"
995+ }
996+
997+ // Indicator to show search activity
998+ ActivityIndicator {
999+ id: searchActivity
1000+ anchors {
1001+ bottom: statusLabel.top
1002+ bottomMargin: units.gu (1)
1003+ horizontalCenter: parent.horizontalCenter
1004+ }
1005+ running: xmlSearchModel.status === XmlListModel.Loading
1006+ }
1007+
1008+ ListModel {
1009+ id: historyModel
1010+ function initialize() {
1011+ historyModel.clear();
1012+ var res = UnavDB.getSearchHistory();
1013+ var len = res.rows.length;
1014+ for (var i = 0; i < len; ++i) {
1015+ historyModel.append({
1016+ title: i18n.tr("Search history"),
1017+ name: res.rows.item(i).key,
1018+ lat: res.rows.item(i).lat,
1019+ lng: res.rows.item(i).lng
1020+ });
1021+ }
1022+ res = UnavDB.getfavHistory();
1023+ len = res.rows.length;
1024+ for (i = 0; i < len; ++i) {
1025+ historyModel.append({
1026+ title: i18n.tr("Favorite history"),
1027+ name: res.rows.item(i).key,
1028+ lat: res.rows.item(i).lat,
1029+ lng: res.rows.item(i).lng
1030+ });
1031+ }
1032+ res = UnavDB.getNearByHistory();
1033+ len = res.rows.length;
1034+ for (i = 0; i < len; ++i) {
1035+ historyModel.append({
1036+ title: i18n.tr("Nearby history"),
1037+ name: i18n.tr(res.rows.item(i).type),
1038+ en_name: res.rows.item(i).type,
1039+ clause: res.rows.item(i).clause
1040+ });
1041+ }
1042+ }
1043+ Component.onCompleted: initialize()
1044+ }
1045+
1046+ //OSMTouch Model:
1047+ XmlListModel {
1048+ id: xmlSearchModel
1049+
1050+ onStatusChanged: {
1051+ if (status === XmlListModel.Error) {
1052+ statusLabel.text = i18n.tr("Time out! Please try again");
1053+ statusLabel.visible = true;
1054+ historyIcon.visible = false;
1055+ resultsListView.visible = false;
1056+ } if (status === XmlListModel.Ready && count === 0) {
1057+ //TRANSLATORS: The Argument is the search input. E.G. a Town, Address....
1058+ statusLabel.text = i18n.tr("Sorry, no result for %1").arg(searchField.text);
1059+ statusLabel.visible = true;
1060+ historyIcon.visible = false;
1061+ resultsListView.visible = false;
1062+ } if (status === XmlListModel.Ready && count >> 0) {
1063+ statusLabel.visible = false;
1064+ historyIcon.visible = false;
1065+ sortedSearchModel.sortXmlList();
1066+ }
1067+ }
1068+
1069+ readonly property string searchUrl: "https://nominatim.openstreetmap.org/search?format=xml&email=marcos.costales@gmail.com&limit=50&q="
1070+ property string searchString
1071+
1072+ function search() {
1073+ xmlSearchModel.clear()
1074+ sortedSearchModel.clear()
1075+ source = (searchUrl + searchString);
1076+ }
1077+
1078+ function clear() {
1079+ source: "";
1080+ }
1081+
1082+ source: ""
1083+ query: "/searchresults/place"
1084+
1085+ XmlRole { name: "name"; query: "@display_name/string()"; isKey: true }
1086+ XmlRole { name: "lat"; query: "@lat/string()"; isKey: true }
1087+ XmlRole { name: "lng"; query: "@lon/string()"; isKey: true }
1088+ XmlRole { name: "icon"; query: "@icon/string()"; isKey: true }
1089+ }
1090+
1091+ ListModel {
1092+ id: sortedSearchModel
1093+
1094+ function sortXmlList (){
1095+ sortedSearchModel.clear()
1096+ var item
1097+ for (var i = 0; i < xmlSearchModel.count; i++) {
1098+ item = {
1099+ "name": xmlSearchModel.get(i).name,
1100+ "lat": xmlSearchModel.get(i).lat,
1101+ "lng": xmlSearchModel.get(i).lng,
1102+ "icon": (xmlSearchModel.get(i).icon).replace('.p.20.png', '.p.32.png'),
1103+ "distance": QmlJs.calcPoiDistance(
1104+ mainPageStack.currentLat,
1105+ mainPageStack.currentLng,
1106+ xmlSearchModel.get(i).lat,
1107+ xmlSearchModel.get(i).lng,
1108+ 10
1109+ )
1110+ }
1111+ if (i === 0) {
1112+ sortedSearchModel.append(item)
1113+ } else { // sort model by distance
1114+ var j = 0;
1115+ while (j <= sortedSearchModel.count) {
1116+ if (j === sortedSearchModel.count) {
1117+ sortedSearchModel.append(item)
1118+ break;
1119+ } else if (item.distance < sortedSearchModel.get(j).distance){
1120+ sortedSearchModel.insert(j,item)
1121+ break;
1122+ } else {
1123+ j++;
1124+ }
1125+ }
1126+ }
1127+ xmlSearchModel.clear();
1128+ historyListView.visible = false;
1129+ resultsListView.visible = true;
1130+ }
1131+ }
1132+ }
1133+
1134+ ListView {
1135+ id: historyListView
1136+
1137+ model: historyModel
1138+ visible: !statusLabel.visible
1139+ anchors.fill: parent
1140+
1141+ section.property: "title"
1142+ section.criteria: ViewSection.FullString
1143+ section.delegate: HeaderListItem {
1144+ title: section
1145+ }
1146+
1147+ delegate: ListItem {
1148+ height: historyDelegateLayout.height + divider.height
1149+ leadingActions: ListItemActions {
1150+ actions: [
1151+ Action {
1152+ iconName: "delete"
1153+ onTriggered: {
1154+ switch (model.title) {
1155+ case i18n.tr("Search history"):
1156+ UnavDB.removeHistorySearch(model.name);
1157+ break;
1158+ case i18n.tr("Nearby history"):
1159+ UnavDB.removeHistoryNearby(model.en_name);
1160+ break;
1161+ case i18n.tr("Favorite history"):
1162+ UnavDB.removeHistoryFavorite(model.name);
1163+ }
1164+ historyModel.initialize()
1165+ }
1166+ }
1167+ ]
1168+ }
1169+
1170+ trailingActions: ListItemActions {
1171+ actions: [
1172+ Action {
1173+ iconName: "send"
1174+ onTriggered: {
1175+ mainPageStack.pop(searchPage);
1176+ mainPageStack.routeState = 'yes';
1177+ mainPageStack.executeJavaScript("calc2coord("+ model.lat + "," + model.lng + ");");
1178+ }
1179+ },
1180+ Action {
1181+ iconName: "share"
1182+ onTriggered: {
1183+ PopupUtils.open(Qt.resolvedUrl("./Share.qml"), navApp, {"lat": model.lat, "lon": model.lng})
1184+ }
1185+ }
1186+ ]
1187+ }
1188+
1189+ ListItemLayout {
1190+ id: historyDelegateLayout
1191+
1192+ title.text: model.name
1193+ title.maximumLineCount: 2
1194+ subtitle.text: QmlJs.formatDistance(QmlJs.calcPoiDistance(mainPageStack.currentLat, mainPageStack.currentLng, model.lat, model.lng, 10), navApp.settings.unit)
1195+ subtitle.visible: model.title !== i18n.tr("Nearby history") && mainPageStack.currentLat !== "null" && mainPageStack.currentLng !== "null"
1196+
1197+ Icon {
1198+ id: progressionIcon
1199+ height: units.gu(2.5)
1200+ name: "next"
1201+ visible: model.title === i18n.tr("Nearby history")
1202+ SlotsLayout.position: SlotsLayout.Last
1203+ }
1204+
1205+ }
1206+
1207+ onClicked: {
1208+ mainPageStack.pop(searchPage)
1209+ if (model.title === i18n.tr("Nearby history")) {
1210+ mainPageStack.push(Qt.resolvedUrl("PoiListPage.qml"),
1211+ {
1212+ lat: mainPageStack.currentLat,
1213+ lng: mainPageStack.currentLng,
1214+ poiType: model.name,
1215+ clause: model.clause,
1216+ geoDistFactor: 5
1217+ })
1218+ } else {
1219+ mainPageStack.executeJavaScript("ui.markers_POI_set([{ title: \"" +
1220+ model.name + "\", lat: " +
1221+ model.lat + ", lng: " +
1222+ model.lng + "}]);");
1223+ }
1224+ }
1225+ }
1226+ }
1227+
1228+ ListView {
1229+ id: resultsListView
1230+
1231+ anchors.fill: parent
1232+ anchors.topMargin: units.gu(6)
1233+ visible: false
1234+
1235+ model: sortedSearchModel
1236+
1237+ delegate: ListItem {
1238+ height: resultsDelegateLayout.height + divider.height
1239+ trailingActions: ListItemActions {
1240+ actions: [
1241+ Action {
1242+ iconName: "send"
1243+ onTriggered: {
1244+ if (navApp.settings.saveHistory) {
1245+ UnavDB.saveToSearchHistory(model.name, model.lat, model.lng)
1246+ }
1247+ mainPageStack.pop(searchPage);
1248+ mainPageStack.routeState = 'yes'
1249+ mainPageStack.executeJavaScript("calc2coord(" + model.lat + "," + model.lng + ");")
1250+ }
1251+ },
1252+ Action {
1253+ iconName: "share"
1254+ onTriggered: {
1255+ PopupUtils.open(Qt.resolvedUrl("./Share.qml"), navApp, {"lat": model.lat, "lon": model.lng})
1256+ }
1257+ },
1258+ Action {
1259+ iconName: "non-starred"
1260+ onTriggered: {
1261+ mainPageStack.pop(searchPage)
1262+ mainPageStack.push(Qt.resolvedUrl("FavoritesPage.qml"), {state:"adding", lat: model.lat, lng: model.lng, favName: model.name})
1263+ }
1264+ }
1265+ ]
1266+ }
1267+
1268+ onClicked: {
1269+ if (navApp.settings.saveHistory) {
1270+ UnavDB.saveToSearchHistory(model.name, model.lat, model.lng)
1271+ }
1272+ mainPageStack.pop(searchPage)
1273+ mainPageStack.executeJavaScript("ui.markers_POI_set([{title: \"" + model.name + "\", lat: " + model.lat + ", lng: " + model.lng + "}]);");
1274+ }
1275+
1276+ ListItemLayout {
1277+ id: resultsDelegateLayout
1278+
1279+ title.text: model.name
1280+ title.maximumLineCount: 2
1281+ subtitle.text: QmlJs.formatDistance(model.distance, navApp.settings.unit)
1282+ subtitle.visible: mainPageStack.currentLat !== "null" && mainPageStack.currentLng !== "null"
1283+
1284+ Icon {
1285+ id: resIcon
1286+ height: units.gu(2.5)
1287+ width: height
1288+ visible: model.icon !== ""
1289+ source: model.icon
1290+ SlotsLayout.position: SlotsLayout.Last
1291+ }
1292+ }
1293+ }
1294+ }
1295 }
1296
1297=== modified file 'qml/SettingsPage.qml'
1298--- qml/SettingsPage.qml 2016-03-14 18:40:54 +0000
1299+++ qml/SettingsPage.qml 2016-03-15 01:14:51 +0000
1300@@ -17,7 +17,7 @@
1301 import QtQuick 2.4
1302 import Ubuntu.Components 1.3
1303 import Ubuntu.Components.Popups 1.3
1304-import Ubuntu.Components.ListItems 1.3 as ListItem
1305+import Ubuntu.Components.ListItems 1.3 as ListItems
1306 import QtQuick.LocalStorage 2.0
1307 import "js/db.js" as UnavDB
1308
1309@@ -41,12 +41,12 @@
1310 right: parent.right
1311 }
1312
1313- ListItem.Header {
1314- id: mapModeHeader
1315- text: i18n.tr("Navigation")
1316- }
1317+ HeaderListItem {
1318+ id: mapModeHeader
1319+ title: i18n.tr("Navigation")
1320+ }
1321
1322- ListItem.ItemSelector {
1323+ ListItems.ItemSelector {
1324 id: modeList
1325 text: i18n.tr("Mode:")
1326 width: parent.width
1327@@ -63,40 +63,46 @@
1328 mainPageStack.executeJavaScript("if (nav.get_route_status() != 'no'){nav.set_route_status('waiting4signal')}; settings.set_routing_mode(" + selectedIndex +");")
1329 }
1330 }
1331-
1332- ListItem.Standard {
1333- visible: navApp.settings.routingMode === 0 ? true : false
1334- showDivider: true
1335- text: i18n.tr("Avoid Tolls")
1336- control: Switch {
1337- id: tollsSwitch
1338- checked: navApp.settings.avoidTolls
1339- onClicked: {
1340- navApp.settings.avoidTolls = checked;
1341- mainPageStack.executeJavaScript("if (nav.get_route_status() != 'no'){nav.set_route_status('waiting4signal')}; settings.set_avoid_tolls(" + checked.toString() + ");")
1342- }
1343- }
1344- }
1345-
1346- ListItem.Standard {
1347- visible: navApp.settings.routingMode === 0 ? true : false
1348- showDivider: true
1349- text: i18n.tr("Speed Camera Alerts")
1350- control: Switch {
1351- id: radarsSwitch
1352- checked: navApp.settings.alertRadars
1353- onClicked: {
1354- navApp.settings.alertRadars = checked;
1355- mainPageStack.executeJavaScript("if (nav.get_route_status() != 'no'){nav.set_route_status('waiting4signal')}; settings.set_alert_radars(" + checked.toString() + ");");
1356- if (navApp.settings.legalRadarShow) {
1357- navApp.settings.legalRadarShow = false;
1358- PopupUtils.open(confirmEnableRadar);
1359- }
1360- }
1361- }
1362- }
1363-
1364- ListItem.ItemSelector {
1365+
1366+ ListItem {
1367+ height: tollsLayout.height + divider.height
1368+ ListItemLayout {
1369+ id: tollsLayout
1370+ title.text: i18n.tr("Avoid Tolls")
1371+ Switch {
1372+ id: tollsSwitch
1373+ checked: navApp.settings.avoidTolls
1374+ onClicked: {
1375+ navApp.settings.avoidTolls = checked;
1376+ mainPageStack.executeJavaScript("if (nav.get_route_status() != 'no'){nav.set_route_status('waiting4signal')}; settings.set_avoid_tolls(" + checked.toString() + ");")
1377+ }
1378+ SlotsLayout.position: SlotsLayout.Last
1379+ }
1380+ }
1381+ }
1382+
1383+ ListItem {
1384+ height: speedCameraLayout.height + divider.height
1385+ ListItemLayout {
1386+ id: speedCameraLayout
1387+ title.text: i18n.tr("Speed Camera Alerts")
1388+ Switch {
1389+ id: radarsSwitch
1390+ checked: navApp.settings.alertRadars
1391+ onClicked: {
1392+ navApp.settings.alertRadars = checked;
1393+ mainPageStack.executeJavaScript("if (nav.get_route_status() != 'no'){nav.set_route_status('waiting4signal')}; settings.set_alert_radars(" + checked.toString() + ");");
1394+ if (navApp.settings.legalRadarShow) {
1395+ navApp.settings.legalRadarShow = false;
1396+ PopupUtils.open(confirmEnableRadar);
1397+ }
1398+ }
1399+ SlotsLayout.position: SlotsLayout.Last
1400+ }
1401+ }
1402+ }
1403+
1404+ ListItems.ItemSelector {
1405 id: soundsList
1406 text: i18n.tr("Indications:")
1407 width: parent.width
1408@@ -114,12 +120,12 @@
1409 }
1410 }
1411
1412- ListItem.Header {
1413+ HeaderListItem {
1414 id: mapListHeader
1415- text: i18n.tr("Map")
1416+ title: i18n.tr("Map")
1417 }
1418
1419- ListItem.ItemSelector {
1420+ ListItems.ItemSelector {
1421 id: unitsList
1422 text: i18n.tr("Units:")
1423 width: parent.width
1424@@ -137,30 +143,32 @@
1425 }
1426 }
1427
1428- ListItem.Header {
1429+ HeaderListItem {
1430 id: privacyListHeader
1431- text: i18n.tr("History")
1432- }
1433-
1434- ListItem.Standard {
1435- showDivider: false
1436- text: i18n.tr("Store new searches")
1437-
1438- control: Switch {
1439- id: saveHistorySwitch
1440- checked: navApp.settings.saveHistory
1441- onClicked: {
1442- navApp.settings.saveHistory = checked;
1443- }
1444- }
1445- }
1446-
1447- ListItem.Standard {
1448- showDivider: true
1449- text: i18n.tr("Clear History")
1450- onClicked: PopupUtils.open(confirmEraseHistory)
1451- }
1452-
1453+ title: i18n.tr("History")
1454+ }
1455+
1456+ ListItem {
1457+ height: storeSearchLayout.height + divider.height
1458+ ListItemLayout {
1459+ id: storeSearchLayout
1460+ title.text: i18n.tr("Store new searches")
1461+ Switch {
1462+ id: saveHistorySwitch
1463+ checked: navApp.settings.saveHistory
1464+ onClicked: navApp.settings.saveHistory = checked
1465+ SlotsLayout.position: SlotsLayout.Last
1466+ }
1467+ }
1468+ }
1469+
1470+ ListItem {
1471+ Label {
1472+ anchors { verticalCenter: parent.verticalCenter; left: parent.left; leftMargin: units.gu(2) }
1473+ text: i18n.tr("Clear History")
1474+ }
1475+ onClicked: PopupUtils.open(confirmEraseHistory)
1476+ }
1477 }
1478
1479 Component {

Subscribers

People subscribed via source and target branches