2 * Copyright (C) 2015-2016 Canonical, Ltd.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 import QtQuick.Layouts 1.1
19 import Ubuntu.Components 1.3
21 import Ubuntu.SystemSettings.TimeDate 1.1
22 import Utils 0.1 as Utils
23 import ".." as LocalComponents
24 import "../../Components"
26 LocalComponents.Page {
30 title: i18n.tr("Time Zone")
31 forwardButtonSourceComponent: forwardButton
33 property string selectedTimeZone: ""
34 property string selectedTimeZoneName: ""
35 readonly property bool showingMap: wideMode && width >= units.gu(110)
38 readonly property alias tdModule: timeDatePanel
40 function highlightTimezone(offset) {
41 highlightImage.source = "data/timezonemap/timezone_" + offset + ".png";
44 // geo coords conversion functions (adapted from libtimezonemap)
45 function radians(degrees) {
46 return degrees * Math.PI / 180;
49 function longitudeToX(longitude, map_width) {
50 const xdeg_offset = -6;
51 const x = (map_width * (180.0 + longitude) / 360.0) + (map_width * xdeg_offset / 180.0);
55 function latitudeToY(latitude, map_height) {
56 const bottom_lat = -59;
58 const top_per = top_lat / 180.0;
60 var y = 1.25 * Math.log(Math.tan(0.25*Math.PI + 0.4 * radians(latitude)));
61 const full_range = 4.6068250867599998;
62 const top_offset = full_range * top_per;
63 const map_range = Math.abs(1.25 * Math.log(Math.tan(0.25*Math.PI + 0.4 * radians(bottom_lat))) - top_offset);
64 y = Math.abs(y - top_offset);
70 function resetViews() {
72 selectedTimeZoneName = ""
73 tzList.currentIndex = -1
74 highlightImage.source = ""
83 onContentAnimationRunningChanged: {
84 if (!contentAnimationRunning) {
85 if (tzList.count == 1) { // preselect the first (and only) TZ
86 var tz = tzList.itemAt(0,0);
93 searchField.forceActiveFocus();
101 objectName: "tz" + index
102 highlightColor: backgroundColor
103 divider.colorFrom: dividerColor
104 divider.colorTo: backgroundColor
105 readonly property bool currentTz: ListView.view.currentIndex === index
108 anchors.verticalCenter: parent.verticalCenter
109 anchors.left: parent.left
110 anchors.leftMargin: !wideMode ? staticMargin : 0
111 anchors.right: image.left
112 anchors.rightMargin: units.gu(2)
117 font.weight: tz.currentTz ? Font.Normal : Font.Light
120 elide: Text.ElideMiddle
126 text: Utils.TimezoneFormatter.currentTimeInTimezoneWithAbbrev(timeZone)
127 font.weight: tz.currentTz ? Font.Normal : Font.Light
136 verticalCenter: parent.verticalCenter
137 rightMargin: !wideMode ? staticMargin : 0
139 fillMode: Image.PreserveAspectFit
140 height: units.gu(1.5)
142 source: "data/Tick@30.png"
143 visible: tz.currentTz
147 highlightTimezone(offset);
148 ListView.view.currentIndex = index;
149 selectedTimeZone = timeZone;
150 selectedTimeZoneName = city;
151 //print("Clicked at city with coords:", longitude, latitude);
152 //print("Clicked on TZ:", timeZone);
153 //print("Highlight at (x,y):", longitudeToX(longitude, map.width), latitudeToY(latitude, map.height));
154 pinImage.x = Qt.binding(function() { return longitudeToX(longitude, map.width) - pinImage.width; });
155 pinImage.y = Qt.binding(function() { return latitudeToY(latitude, map.height) - pinImage.height; });
166 bottom: content.bottom
167 right: !showingMap ? content.right : undefined
168 leftMargin: showingMap ? staticMargin : (wideMode ? tzPage.leftMargin : 0)
169 rightMargin: showingMap ? staticMargin : (wideMode ? tzPage.rightMargin : 0)
170 topMargin: customMargin
173 width: Math.min(parent.width, units.gu(34))
175 LocalComponents.WizardTextField {
177 objectName: "tzFilter"
178 anchors.left: parent.left
179 anchors.right: parent.right
180 anchors.leftMargin: !showingMap && !wideMode ? staticMargin : undefined
181 anchors.rightMargin: !showingMap && !wideMode ? staticMargin : undefined
182 placeholderText: i18n.tr("Enter your city")
183 inputMethodHints: Qt.ImhNoPredictiveText
184 onTextChanged: resetViews();
188 Layout.fillHeight: true
192 anchors.left: parent.left
193 anchors.right: parent.right
195 model: TimeZoneModel {
197 filter: searchField.text
198 country: i18n.language.split('_')[1].split('.')[0]
200 delegate: tzComponent
204 anchors.centerIn: tzList
205 running: tzList.count == 0 &&
206 searchField.length > 0 &&
207 timeZoneModel.listUpdating
214 visible: showingMap && !contentAnimationRunning
218 left: leftColumn.right
219 leftMargin: units.gu(4)
221 rightMargin: staticMargin
223 topMargin: customMargin
224 bottom: parent.bottom
225 bottomMargin: buttonBarHeight
230 width: Math.min(parent.width, height * 1.95) // keep our aspect ratio
231 height: parent.height
238 source: "data/timezonemap/map.png"
239 sourceSize: Qt.size(map.width, map.height)
240 fillMode: Image.PreserveAspectFit
242 visible: mapContainer.visible
249 sourceSize: Qt.size(map.width, map.height)
250 fillMode: Image.PreserveAspectFit
252 visible: selectedTimeZone != ""
254 anchors.fill: backgroundImage
259 source: "data/timezonemap/pin.png"
260 visible: x != 0 && y != 0
270 LocalComponents.StackButton {
271 text: i18n.tr("Next")
272 enabled: selectedTimeZone != ""
274 timeDatePanel.setTimeZone(selectedTimeZone, selectedTimeZoneName);