Merge lp:~mterry/unity8/oobe-revert-geonames into lp:unity8

Proposed by Michał Sawicz
Status: Rejected
Rejected by: Michał Sawicz
Proposed branch: lp:~mterry/unity8/oobe-revert-geonames
Merge into: lp:unity8
Prerequisite: lp:~unity-team/unity8/oobe
Diff against target: 691 lines (+225/-199)
13 files modified
CMakeLists.txt (+0/-1)
debian/control (+1/-1)
plugins/Wizard/CMakeLists.txt (+4/-2)
plugins/Wizard/plugin.cpp (+1/-0)
plugins/Wizard/timezonemodel.cpp (+140/-156)
plugins/Wizard/timezonemodel.h (+55/-22)
qml/Wizard/Pages.qml (+11/-0)
qml/Wizard/Pages/10-welcome.qml (+1/-0)
qml/Wizard/Pages/50-timezone.qml (+3/-13)
qml/Wizard/Pages/passcode-confirm.qml (+2/-1)
qml/Wizard/Pages/passcode-set.qml (+2/-1)
tests/mocks/Wizard/CMakeLists.txt (+4/-2)
tests/mocks/Wizard/mockplugin.cpp (+1/-0)
To merge this branch: bzr merge lp:~mterry/unity8/oobe-revert-geonames
Reviewer Review Type Date Requested Status
Michał Sawicz Disapprove
Unity8 CI Bot continuous-integration Needs Fixing
Lukáš Tinkl (community) Needs Fixing
Review via email: mp+289758@code.launchpad.net

This proposal supersedes a proposal from 2016-03-22.

Commit message

Revert the use of geonames back to libtimezonemap in the wizard until we can fix a bug with it.

Description of the change

Revert the use of geonames back to libtimezonemap. These changes aren't perfect. It's just going back to an earlier version of the code.

To be fixed up later again to geonames once we fix a mystery freeze.

To post a comment you must log in.
Revision history for this message
Lukáš Tinkl (lukas-kde) wrote :

The changes in qml/Wizard/Pages/passcode-confirm.qml and qml/Wizard/Pages/passcode-set.qml are unrelated and undesired here.

review: Needs Fixing
Revision history for this message
Unity8 CI Bot (unity8-ci-bot) wrote :

FAILED: Continuous integration, rev:2159
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/787/
Executed test runs:
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=vivid+overlay,testname=qmluitests.sh/437
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=amd64,release=xenial,testname=qmluitests.sh/437
    UNSTABLE: https://unity8-jenkins.ubuntu.com/job/test-0-autopkgtest/label=phone-armhf,release=vivid+overlay,testname=autopilot.sh/437
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-0-fetch/1031
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=vivid+overlay/1046
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-1-sourcepkg/release=xenial/1046
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1044
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=vivid+overlay/1044/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/1044
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=amd64,release=xenial/1044/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1044
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=vivid+overlay/1044/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/1044
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=armhf,release=xenial/1044/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1044
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=vivid+overlay/1044/artifact/output/*zip*/output.zip
    SUCCESS: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/1044
        deb: https://unity8-jenkins.ubuntu.com/job/build-2-binpkg/arch=i386,release=xenial/1044/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://unity8-jenkins.ubuntu.com/job/lp-unity8-ci/787/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

No need after all.

review: Disapprove

Unmerged revisions

2159. By Michael Terry

Revert use of geonames

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2016-03-22 09:09:22 +0000
+++ CMakeLists.txt 2016-03-03 18:41:20 +0000
@@ -58,7 +58,6 @@
58find_package(Qt5Sql 5.4 REQUIRED)58find_package(Qt5Sql 5.4 REQUIRED)
5959
60pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=13)60pkg_check_modules(APPLICATION_API REQUIRED unity-shell-application=13)
61pkg_check_modules(GEONAMES REQUIRED geonames>=0.2)
62pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)61pkg_check_modules(GIO REQUIRED gio-2.0>=2.32)
63pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)62pkg_check_modules(GLIB REQUIRED glib-2.0>=2.32)
64pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)63pkg_check_modules(QMENUMODEL REQUIRED qmenumodel)
6564
=== modified file 'debian/control'
--- debian/control 2016-03-22 09:09:22 +0000
+++ debian/control 2016-03-22 09:09:23 +0000
@@ -15,7 +15,6 @@
15 gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),15 gsettings-ubuntu-schemas (>= 0.0.2+14.10.20140815),
16 libconnectivity-qt1-dev (>= 0.7.1),16 libconnectivity-qt1-dev (>= 0.7.1),
17 libevdev-dev,17 libevdev-dev,
18 libgeonames-dev (>= 0.2),
19 libgl1-mesa-dev[!armhf] | libgl-dev[!armhf],18 libgl1-mesa-dev[!armhf] | libgl-dev[!armhf],
20 libgl1-mesa-dri,19 libgl1-mesa-dri,
21 libgles2-mesa-dev[armhf],20 libgles2-mesa-dev[armhf],
@@ -29,6 +28,7 @@
29 libqt5svg5-dev,28 libqt5svg5-dev,
30 libqt5xmlpatterns5-dev,29 libqt5xmlpatterns5-dev,
31 libsystemsettings-dev,30 libsystemsettings-dev,
31 libtimezonemap1-dev,
32 libudev-dev,32 libudev-dev,
33 libunity-api-dev (>= 7.107),33 libunity-api-dev (>= 7.107),
34 libusermetricsoutput1-dev,34 libusermetricsoutput1-dev,
3535
=== modified file 'plugins/Wizard/CMakeLists.txt'
--- plugins/Wizard/CMakeLists.txt 2016-03-22 09:09:22 +0000
+++ plugins/Wizard/CMakeLists.txt 2016-03-22 09:09:23 +0000
@@ -1,4 +1,6 @@
1include_directories(${GLIB_INCLUDE_DIRS} ${GEONAMES_INCLUDE_DIRS})1pkg_search_module(TIMEZONEMAP REQUIRED timezonemap)
2
3include_directories(${GLIB_INCLUDE_DIRS} ${TIMEZONEMAP_INCLUDE_DIRS})
24
3add_library(Wizard-qml MODULE5add_library(Wizard-qml MODULE
4 plugin.cpp6 plugin.cpp
@@ -10,7 +12,7 @@
10)12)
1113
12qt5_use_modules(Wizard-qml DBus Qml Concurrent)14qt5_use_modules(Wizard-qml DBus Qml Concurrent)
13target_link_libraries(Wizard-qml ${GLIB_LDFLAGS} ${GEONAMES_LDFLAGS})15target_link_libraries(Wizard-qml ${GLIB_LDFLAGS} ${TIMEZONEMAP_LDFLAGS})
14add_unity8_plugin(Wizard 0.1 Wizard TARGETS Wizard-qml)16add_unity8_plugin(Wizard 0.1 Wizard TARGETS Wizard-qml)
1517
16set(POLKIT_LIB_DIR "${CMAKE_INSTALL_LOCALSTATEDIR}/lib/polkit-1")18set(POLKIT_LIB_DIR "${CMAKE_INSTALL_LOCALSTATEDIR}/lib/polkit-1")
1719
=== modified file 'plugins/Wizard/plugin.cpp'
--- plugins/Wizard/plugin.cpp 2016-03-22 09:09:22 +0000
+++ plugins/Wizard/plugin.cpp 2016-03-22 09:09:23 +0000
@@ -30,5 +30,6 @@
30 qmlRegisterSingletonType<System>(uri, 0, 1, "System", [](QQmlEngine*, QJSEngine*) -> QObject* { return new System; });30 qmlRegisterSingletonType<System>(uri, 0, 1, "System", [](QQmlEngine*, QJSEngine*) -> QObject* { return new System; });
31 qmlRegisterSingletonType<Status>(uri, 0, 1, "Status", [](QQmlEngine*, QJSEngine*) -> QObject* { return new Status; });31 qmlRegisterSingletonType<Status>(uri, 0, 1, "Status", [](QQmlEngine*, QJSEngine*) -> QObject* { return new Status; });
32 qmlRegisterType<TimeZoneLocationModel>(uri, 0, 1, "TimeZoneModel");32 qmlRegisterType<TimeZoneLocationModel>(uri, 0, 1, "TimeZoneModel");
33 qmlRegisterType<TimeZoneFilterModel>(uri, 0, 1, "TimeZoneFilterModel");
33 qmlRegisterType<LocalePlugin>(uri, 0, 1, "LocalePlugin");34 qmlRegisterType<LocalePlugin>(uri, 0, 1, "LocalePlugin");
34}35}
3536
=== modified file 'plugins/Wizard/timezonemodel.cpp'
--- plugins/Wizard/timezonemodel.cpp 2016-03-22 09:09:22 +0000
+++ plugins/Wizard/timezonemodel.cpp 2016-03-22 09:09:23 +0000
@@ -18,15 +18,17 @@
1818
19#include <glib.h>19#include <glib.h>
20#include <glib-object.h>20#include <glib-object.h>
21#include <timezonemap/tz.h>
2122
22#include "LocalePlugin.h"23#include "LocalePlugin.h"
23#include "timezonemodel.h"24#include "timezonemodel.h"
2425
25TimeZoneLocationModel::TimeZoneLocationModel(QObject *parent):26TimeZoneLocationModel::TimeZoneLocationModel(QObject *parent):
26 QAbstractListModel(parent),27 QAbstractListModel(parent),
27 m_listUpdating(false),28 m_workerThread(new TimeZonePopulateWorker())
28 m_cancellable(nullptr)
29{29{
30 qRegisterMetaType<TzLocationWizard>();
31
30 m_roleNames[Qt::DisplayRole] = "displayName";32 m_roleNames[Qt::DisplayRole] = "displayName";
31 m_roleNames[TimeZoneRole] = "timeZone";33 m_roleNames[TimeZoneRole] = "timeZone";
32 m_roleNames[CityRole] = "city";34 m_roleNames[CityRole] = "city";
@@ -34,52 +36,78 @@
34 m_roleNames[OffsetRole] = "offset";36 m_roleNames[OffsetRole] = "offset";
35 m_roleNames[LatitudeRole] = "latitude";37 m_roleNames[LatitudeRole] = "latitude";
36 m_roleNames[LongitudeRole] = "longitude";38 m_roleNames[LongitudeRole] = "longitude";
39
40 QObject::connect(m_workerThread,
41 &TimeZonePopulateWorker::resultReady,
42 this,
43 &TimeZoneLocationModel::processModelResult);
44 QObject::connect(m_workerThread,
45 &TimeZonePopulateWorker::finished,
46 this,
47 &TimeZoneLocationModel::store);
48 QObject::connect(m_workerThread,
49 &TimeZonePopulateWorker::finished,
50 m_workerThread,
51 &QObject::deleteLater);
52
53 init();
54}
55
56void TimeZoneLocationModel::init()
57{
58 beginResetModel();
59 m_workerThread->start();
60}
61
62void TimeZoneLocationModel::store()
63{
64 m_workerThread = nullptr;
65 endResetModel();
66}
67
68void TimeZoneLocationModel::processModelResult(const TzLocationWizard &location)
69{
70 m_locations.append(location);
37}71}
3872
39int TimeZoneLocationModel::rowCount(const QModelIndex &parent) const73int TimeZoneLocationModel::rowCount(const QModelIndex &parent) const
40{74{
41 if (parent.isValid()) {75 if (parent.isValid())
42 return 0;76 return 0;
43 } else if (m_filter.isEmpty()) {77 return m_locations.count();
44 return m_countryLocations.count();
45 } else {
46 return m_locations.count();
47 }
48}78}
4979
50QVariant TimeZoneLocationModel::data(const QModelIndex &index, int role) const80QVariant TimeZoneLocationModel::data(const QModelIndex &index, int role) const
51{81{
52 GeonamesCity *city;82 if (index.row() >= m_locations.count() || index.row() < 0)
53 if (m_filter.isEmpty()) {
54 city = m_countryLocations.value(index.row());
55 } else {
56 city = m_locations.value(index.row());
57 }
58 if (!city)
59 return QVariant();83 return QVariant();
6084
85 const TzLocationWizard tz = m_locations.at(index.row());
86
87 const QString country(tz.full_country.isEmpty() ? tz.country : tz.full_country);
88
61 switch (role) {89 switch (role) {
62 case Qt::DisplayRole:90 case Qt::DisplayRole:
63 return QStringLiteral("%1, %2, %3").arg(geonames_city_get_name(city))91 if (!tz.state.isEmpty())
64 .arg(geonames_city_get_state(city))92 return QStringLiteral("%1, %2, %3").arg(tz.city).arg(tz.state).arg(country);
65 .arg(geonames_city_get_country(city));93 else
94 return QStringLiteral("%1, %2").arg(tz.city).arg(country);
66 case SimpleRole:95 case SimpleRole:
67 return QStringLiteral("%1, %2").arg(geonames_city_get_name(city))96 return QStringLiteral("%1, %2").arg(tz.city).arg(country);
68 .arg(geonames_city_get_country(city));
69 case TimeZoneRole:97 case TimeZoneRole:
70 return geonames_city_get_timezone(city);98 return tz.timezone;
71 case CountryRole:99 case CountryRole:
72 return geonames_city_get_country(city);100 return tz.country;
73 case CityRole:101 case CityRole:
74 return geonames_city_get_name(city);102 return tz.city;
75 case OffsetRole: {103 case OffsetRole: {
76 QTimeZone tmp(geonames_city_get_timezone(city));104 QTimeZone tmp(tz.timezone.toLatin1());
77 return static_cast<double>(tmp.standardTimeOffset(QDateTime::currentDateTime())) / 3600;105 return static_cast<double>(tmp.standardTimeOffset(QDateTime::currentDateTime())) / 3600;
78 }106 }
79 case LatitudeRole:107 case LatitudeRole:
80 return geonames_city_get_latitude(city);108 return tz.latitude;
81 case LongitudeRole:109 case LongitudeRole:
82 return geonames_city_get_longitude(city);110 return tz.longitude;
83 default:111 default:
84 qWarning() << Q_FUNC_INFO << "Unknown role";112 qWarning() << Q_FUNC_INFO << "Unknown role";
85 return QVariant();113 return QVariant();
@@ -91,154 +119,110 @@
91 return m_roleNames;119 return m_roleNames;
92}120}
93121
94void TimeZoneLocationModel::setModel(const QList<GeonamesCity *> &locations)122void TimeZonePopulateWorker::run()
95{123{
96 beginResetModel();124 buildCityMap();
97125}
98 Q_FOREACH(GeonamesCity *city, m_locations) {126
99 geonames_city_free(city);127void TimeZonePopulateWorker::buildCityMap()
100 }128{
101129 TzDB *tzdb = tz_load_db();
102 m_locations = locations;130 GPtrArray *tz_locations = tz_get_locations(tzdb);
103 endResetModel();131
104}132 TimeZoneLocationModel::TzLocationWizard tmpTz;
105133
106void TimeZoneLocationModel::filterFinished(GObject *source_object,134 for (guint i = 0; i < tz_locations->len; ++i) {
107 GAsyncResult *res,135 auto tmp = static_cast<CcTimezoneLocation *>(g_ptr_array_index(tz_locations, i));
108 gpointer user_data)136 gchar *en_name, *country, *zone, *state, *full_country;
109{137 gdouble latitude;
110 Q_UNUSED(source_object);138 gdouble longitude;
111139 g_object_get (tmp, "en_name", &en_name,
112 g_autofree gint *cities = nullptr;140 "country", &country,
113 guint cities_len = 0;141 "zone", &zone,
114 g_autoptr(GError) error = nullptr;142 "state", &state,
115143 "full_country", &full_country,
116 cities = geonames_query_cities_finish(res, &cities_len, &error);144 "latitude", &latitude,
117 if (error) {145 "longitude", &longitude,
118 if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {146 nullptr);
119 TimeZoneLocationModel *model = static_cast<TimeZoneLocationModel *>(user_data);147 // There are empty entries in the DB
120 g_clear_object(&model->m_cancellable);148 if (g_strcmp0(en_name, "") != 0) {
121 model->setListUpdating(false);149 tmpTz.city = en_name;
122 qWarning() << "Could not filter timezones:" << error->message;150 tmpTz.country = country;
123 }151 tmpTz.timezone = zone;
124 return;152 tmpTz.state = state;
125 }153 tmpTz.full_country = full_country;
126154 tmpTz.latitude = latitude;
127 QList<GeonamesCity *> locations;155 tmpTz.longitude = longitude;
128156
129 for (guint i = 0; i < cities_len; ++i) {157 Q_EMIT (resultReady(tmpTz));
130 GeonamesCity *city = geonames_get_city(cities[i]);158 }
131 if (city) {159 g_free (en_name);
132 locations.append(city);160 g_free (country);
133 }161 g_free (zone);
134 }162 g_free (state);
135163 g_free (full_country);
136 TimeZoneLocationModel *model = static_cast<TimeZoneLocationModel *>(user_data);164 }
137165
138 g_clear_object(&model->m_cancellable);166 g_ptr_array_free (tz_locations, TRUE);
139167 tz_db_free(tzdb);
140 model->setModel(locations);168}
141 model->setListUpdating(false);169
142}170
143171TimeZoneFilterModel::TimeZoneFilterModel(QObject *parent)
144bool TimeZoneLocationModel::listUpdating() const172 : QSortFilterProxyModel(parent)
145{173{
146 return m_listUpdating;174 setDynamicSortFilter(false);
147}175 setSortLocaleAware(true);
148176 setSortRole(TimeZoneLocationModel::CityRole);
149void TimeZoneLocationModel::setListUpdating(bool listUpdating)177 m_stringMatcher.setCaseSensitivity(Qt::CaseInsensitive);
150{178 sort(0);
151 if (m_listUpdating != listUpdating) {179}
152 m_listUpdating = listUpdating;180
153 Q_EMIT listUpdatingChanged();181bool TimeZoneFilterModel::filterAcceptsRow(int row, const QModelIndex &parentIndex) const
154 }182{
155}183 if (!sourceModel()) {
156184 return true;
157QString TimeZoneLocationModel::filter() const185 }
186
187 if (!m_filter.isEmpty()) { // filtering by freeform text input, cf setFilter(QString)
188 const QString city = sourceModel()->index(row, 0, parentIndex).data(TimeZoneLocationModel::CityRole).toString();
189
190 if (m_stringMatcher.indexIn(city) == 0) { // match at the beginning of the city name
191 return true;
192 }
193 } else if (!m_country.isEmpty()) { // filter by country code
194 const QString countryCode = sourceModel()->index(row, 0, parentIndex).data(TimeZoneLocationModel::CountryRole).toString();
195 return m_country.compare(countryCode, Qt::CaseInsensitive) == 0;
196 }
197
198 return false;
199}
200
201QString TimeZoneFilterModel::filter() const
158{202{
159 return m_filter;203 return m_filter;
160}204}
161205
162void TimeZoneLocationModel::setFilter(const QString &filter)206void TimeZoneFilterModel::setFilter(const QString &filter)
163{207{
164 if (filter != m_filter) {208 if (filter != m_filter) {
165 m_filter = filter;209 m_filter = filter;
210 m_stringMatcher.setPattern(m_filter);
166 Q_EMIT filterChanged();211 Q_EMIT filterChanged();
167 }212 invalidate();
168213 }
169 setListUpdating(true);
170
171 if (m_cancellable) {
172 g_cancellable_cancel(m_cancellable);
173 g_clear_object(&m_cancellable);
174 }
175
176 setModel(QList<GeonamesCity *>());
177
178 if (filter.isEmpty()) {
179 setListUpdating(false);
180 return;
181 }
182
183 m_cancellable = g_cancellable_new();
184 geonames_query_cities(filter.toUtf8().data(),
185 GEONAMES_QUERY_DEFAULT,
186 m_cancellable,
187 filterFinished,
188 this);
189}214}
190215
191QString TimeZoneLocationModel::country() const216QString TimeZoneFilterModel::country() const
192{217{
193 return m_country;218 return m_country;
194}219}
195220
196static bool citycmp(GeonamesCity *a, GeonamesCity *b)221void TimeZoneFilterModel::setCountry(const QString &country)
197{
198 return geonames_city_get_population(b) < geonames_city_get_population(a);
199}
200
201void TimeZoneLocationModel::setCountry(const QString &country)
202{222{
203 if (m_country == country)223 if (m_country == country)
204 return;224 return;
205225
206 beginResetModel();
207
208 m_country = country;226 m_country = country;
209
210 Q_FOREACH(GeonamesCity *city, m_countryLocations) {
211 geonames_city_free(city);
212 }
213 m_countryLocations.clear();
214
215 gint num_cities = geonames_get_n_cities();
216 for (gint i = 0; i < num_cities; i++) {
217 GeonamesCity *city = geonames_get_city(i);
218 if (city && m_country == geonames_city_get_country_code(city)) {
219 m_countryLocations.append(city);
220 }
221 }
222
223 std::sort(m_countryLocations.begin(), m_countryLocations.end(), citycmp);
224
225 endResetModel();
226
227 Q_EMIT countryChanged(country);227 Q_EMIT countryChanged(country);
228}228}
229
230TimeZoneLocationModel::~TimeZoneLocationModel()
231{
232 if (m_cancellable) {
233 g_cancellable_cancel(m_cancellable);
234 g_clear_object(&m_cancellable);
235 }
236
237 Q_FOREACH(GeonamesCity *city, m_countryLocations) {
238 geonames_city_free(city);
239 }
240
241 Q_FOREACH(GeonamesCity *city, m_locations) {
242 geonames_city_free(city);
243 }
244}
245229
=== modified file 'plugins/Wizard/timezonemodel.h'
--- plugins/Wizard/timezonemodel.h 2016-03-22 09:09:22 +0000
+++ plugins/Wizard/timezonemodel.h 2016-03-22 09:09:23 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2016 Canonical Ltd.2 * Copyright (C) 2015 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -17,21 +17,21 @@
17#ifndef TIMEZONEMODEL_H17#ifndef TIMEZONEMODEL_H
18#define TIMEZONEMODEL_H18#define TIMEZONEMODEL_H
1919
20#include <geonames.h>
21#include <glib.h>
22#include <QAbstractListModel>20#include <QAbstractListModel>
21#include <QSortFilterProxyModel>
22#include <QThread>
23#include <QtConcurrent>
24#include <QtGui/QImage>
25
26class TimeZonePopulateWorker;
2327
24class TimeZoneLocationModel: public QAbstractListModel28class TimeZoneLocationModel: public QAbstractListModel
25{29{
26 Q_OBJECT30 Q_OBJECT
27 Q_PROPERTY(bool listUpdating READ listUpdating NOTIFY listUpdatingChanged)
28 Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged)
29 Q_PROPERTY(QString country READ country WRITE setCountry NOTIFY countryChanged)
30 Q_ENUMS(Roles)31 Q_ENUMS(Roles)
31
32public:32public:
33 explicit TimeZoneLocationModel(QObject *parent = nullptr);33 explicit TimeZoneLocationModel(QObject *parent = nullptr);
34 ~TimeZoneLocationModel();34 ~TimeZoneLocationModel() = default;
3535
36 enum Roles {36 enum Roles {
37 TimeZoneRole = Qt::UserRole + 1,37 TimeZoneRole = Qt::UserRole + 1,
@@ -43,11 +43,56 @@
43 LongitudeRole43 LongitudeRole
44 };44 };
4545
46 struct TzLocationWizard {
47 QString city;
48 QString country;
49 QString timezone;
50 QString state;
51 QString full_country;
52 double latitude;
53 double longitude;
54 };
55
46 int rowCount(const QModelIndex &parent = QModelIndex()) const override;56 int rowCount(const QModelIndex &parent = QModelIndex()) const override;
47 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;57 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
48 QHash<int, QByteArray> roleNames() const override;58 QHash<int, QByteArray> roleNames() const override;
4959
50 bool listUpdating() const;60private Q_SLOTS:
61 void processModelResult(const TzLocationWizard &location);
62 void store();
63
64private:
65 void init();
66 QHash<int, QByteArray> m_roleNames;
67 QList<TzLocationWizard> m_locations;
68 TimeZonePopulateWorker *m_workerThread;
69};
70
71Q_DECLARE_METATYPE (TimeZoneLocationModel::TzLocationWizard)
72
73class TimeZonePopulateWorker: public QThread
74{
75 Q_OBJECT
76public:
77 void run() override;
78
79Q_SIGNALS:
80 void resultReady(const TimeZoneLocationModel::TzLocationWizard &tz);
81
82private:
83 void buildCityMap();
84};
85
86class TimeZoneFilterModel: public QSortFilterProxyModel
87{
88 Q_OBJECT
89 Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged)
90 Q_PROPERTY(QString country READ country WRITE setCountry NOTIFY countryChanged)
91
92public:
93 explicit TimeZoneFilterModel(QObject *parent = nullptr);
94 ~TimeZoneFilterModel() = default;
95 bool filterAcceptsRow(int row, const QModelIndex &parentIndex) const override;
5196
52 QString filter() const;97 QString filter() const;
53 void setFilter(const QString &filter);98 void setFilter(const QString &filter);
@@ -56,25 +101,13 @@
56 void setCountry(const QString &country);101 void setCountry(const QString &country);
57102
58Q_SIGNALS:103Q_SIGNALS:
59 void listUpdatingChanged();
60 void filterChanged();104 void filterChanged();
61 void countryChanged(const QString &country);105 void countryChanged(const QString &country);
62106
63private:107private:
64 void setModel(const QList<GeonamesCity *> &locations);
65 void setListUpdating(bool listUpdating);
66 static void filterFinished(GObject *source_object,
67 GAsyncResult *res,
68 gpointer user_data);
69
70
71 bool m_listUpdating;
72 QString m_filter;108 QString m_filter;
109 QStringMatcher m_stringMatcher;
73 QString m_country;110 QString m_country;
74 GCancellable *m_cancellable;
75 QHash<int, QByteArray> m_roleNames;
76 QList<GeonamesCity *> m_locations;
77 QList<GeonamesCity *> m_countryLocations;
78};111};
79112
80#endif113#endif
81114
=== modified file 'qml/Wizard/Pages.qml'
--- qml/Wizard/Pages.qml 2016-03-22 09:09:22 +0000
+++ qml/Wizard/Pages.qml 2016-03-22 09:09:23 +0000
@@ -34,12 +34,23 @@
34 property int passwordMethod: UbuntuSecurityPrivacyPanel.Passphrase34 property int passwordMethod: UbuntuSecurityPrivacyPanel.Passphrase
35 property string password: ""35 property string password: ""
3636
37 property string countryCode: "US" // default country (for the timezone page)
37 property bool seenSIMPage: false // we want to see the SIM page at most once38 property bool seenSIMPage: false // we want to see the SIM page at most once
3839
39 property alias modemManager: modemManager40 property alias modemManager: modemManager
40 property alias simManager0: simManager041 property alias simManager0: simManager0
41 property alias simManager1: simManager142 property alias simManager1: simManager1
4243
44 TimeZoneModel { // preload the heavy models
45 id: tzModel
46 }
47
48 TimeZoneFilterModel {
49 id: tzFilterModel
50 sourceModel: tzModel
51 country: countryCode
52 }
53
43 theme: ThemeSettings {54 theme: ThemeSettings {
44 name: "Ubuntu.Components.Themes.Ambiance"55 name: "Ubuntu.Components.Themes.Ambiance"
45 }56 }
4657
=== modified file 'qml/Wizard/Pages/10-welcome.qml'
--- qml/Wizard/Pages/10-welcome.qml 2016-03-22 09:09:22 +0000
+++ qml/Wizard/Pages/10-welcome.qml 2016-03-22 09:09:23 +0000
@@ -157,6 +157,7 @@
157 System.updateSessionLocale(plugin.languageCodes[plugin.currentLanguage]);157 System.updateSessionLocale(plugin.languageCodes[plugin.currentLanguage]);
158 }158 }
159 i18n.language = plugin.languageCodes[plugin.currentLanguage]; // re-notify of change after above call (for qlocale change)159 i18n.language = plugin.languageCodes[plugin.currentLanguage]; // re-notify of change after above call (for qlocale change)
160 root.countryCode = plugin.languageCodes[plugin.currentLanguage].split('_')[1].split('.')[0]; // extract the country code, save it for the timezone page
160161
161 if (!root.modemManager.available || !root.modemManager.ready || root.modemManager.modems.length === 0 ||162 if (!root.modemManager.available || !root.modemManager.ready || root.modemManager.modems.length === 0 ||
162 (root.simManager0.present && root.simManager0.ready) || (root.simManager1.present && root.simManager1.ready) ||163 (root.simManager0.present && root.simManager0.ready) || (root.simManager1.present && root.simManager1.ready) ||
163164
=== modified file 'qml/Wizard/Pages/50-timezone.qml'
--- qml/Wizard/Pages/50-timezone.qml 2016-03-22 09:09:22 +0000
+++ qml/Wizard/Pages/50-timezone.qml 2016-03-22 09:09:23 +0000
@@ -87,6 +87,8 @@
87 }87 }
8888
89 resetViews();89 resetViews();
90 tzFilterModel.filter = Qt.binding(function() { return searchField.text; });
91 tzFilterModel.invalidate();
90 searchField.forceActiveFocus();92 searchField.forceActiveFocus();
91 }93 }
92 }94 }
@@ -188,21 +190,9 @@
188 anchors.left: parent.left190 anchors.left: parent.left
189 anchors.right: parent.right191 anchors.right: parent.right
190 currentIndex: -1192 currentIndex: -1
191 model: TimeZoneModel {193 model: tzFilterModel
192 id: timeZoneModel
193 filter: searchField.text
194 country: i18n.language.split('_')[1].split('.')[0]
195 }
196 delegate: tzComponent194 delegate: tzComponent
197 }195 }
198
199 ActivityIndicator {
200 anchors.centerIn: tzList
201 running: tzList.count == 0 &&
202 searchField.length > 0 &&
203 timeZoneModel.listUpdating
204 visible: running
205 }
206 }196 }
207197
208 Item {198 Item {
209199
=== modified file 'qml/Wizard/Pages/passcode-confirm.qml'
--- qml/Wizard/Pages/passcode-confirm.qml 2016-03-22 09:09:22 +0000
+++ qml/Wizard/Pages/passcode-confirm.qml 2016-03-22 09:09:23 +0000
@@ -37,7 +37,8 @@
37 UnityComponents.Lockscreen {37 UnityComponents.Lockscreen {
38 id: lockscreen38 id: lockscreen
39 anchors {39 anchors {
40 fill: content40 fill: parent
41 topMargin: customMargin
41 }42 }
4243
43 infoText: i18n.tr("Confirm passcode")44 infoText: i18n.tr("Confirm passcode")
4445
=== modified file 'qml/Wizard/Pages/passcode-set.qml'
--- qml/Wizard/Pages/passcode-set.qml 2016-03-22 09:09:22 +0000
+++ qml/Wizard/Pages/passcode-set.qml 2016-03-22 09:09:23 +0000
@@ -48,7 +48,8 @@
48 UnityComponents.Lockscreen {48 UnityComponents.Lockscreen {
49 id: lockscreen49 id: lockscreen
50 anchors {50 anchors {
51 fill: content51 fill: parent
52 topMargin: customMargin
52 }53 }
5354
54 infoText: i18n.tr("Choose passcode")55 infoText: i18n.tr("Choose passcode")
5556
=== modified file 'tests/mocks/Wizard/CMakeLists.txt'
--- tests/mocks/Wizard/CMakeLists.txt 2016-03-22 09:09:22 +0000
+++ tests/mocks/Wizard/CMakeLists.txt 2016-03-22 09:09:23 +0000
@@ -1,5 +1,7 @@
1pkg_search_module(TIMEZONEMAP REQUIRED timezonemap)
2
1include_directories(3include_directories(
2 ${GLIB_INCLUDE_DIRS} ${GEONAMES_INCLUDE_DIRS}4 ${GLIB_INCLUDE_DIRS} ${TIMEZONEMAP_INCLUDE_DIRS}
3 ${CMAKE_SOURCE_DIR}/plugins/Wizard5 ${CMAKE_SOURCE_DIR}/plugins/Wizard
4)6)
57
@@ -13,5 +15,5 @@
13)15)
1416
15qt5_use_modules(MockWizard-qml DBus Qml Concurrent)17qt5_use_modules(MockWizard-qml DBus Qml Concurrent)
16target_link_libraries(MockWizard-qml ${GLIB_LDFLAGS} ${GEONAMES_LDFLAGS})18target_link_libraries(MockWizard-qml ${GLIB_LDFLAGS} ${TIMEZONEMAP_LDFLAGS})
17add_unity8_mock(Wizard 0.1 Wizard TARGETS MockWizard-qml)19add_unity8_mock(Wizard 0.1 Wizard TARGETS MockWizard-qml)
1820
=== modified file 'tests/mocks/Wizard/mockplugin.cpp'
--- tests/mocks/Wizard/mockplugin.cpp 2016-03-22 09:09:22 +0000
+++ tests/mocks/Wizard/mockplugin.cpp 2016-03-22 09:09:23 +0000
@@ -30,5 +30,6 @@
30 qmlRegisterSingletonType<MockSystem>(uri, 0, 1, "System", [](QQmlEngine*, QJSEngine*) -> QObject* { return new MockSystem; });30 qmlRegisterSingletonType<MockSystem>(uri, 0, 1, "System", [](QQmlEngine*, QJSEngine*) -> QObject* { return new MockSystem; });
31 qmlRegisterSingletonType<Status>(uri, 0, 1, "Status", [](QQmlEngine*, QJSEngine*) -> QObject* { return new Status; });31 qmlRegisterSingletonType<Status>(uri, 0, 1, "Status", [](QQmlEngine*, QJSEngine*) -> QObject* { return new Status; });
32 qmlRegisterType<TimeZoneLocationModel>(uri, 0, 1, "TimeZoneModel");32 qmlRegisterType<TimeZoneLocationModel>(uri, 0, 1, "TimeZoneModel");
33 qmlRegisterType<TimeZoneFilterModel>(uri, 0, 1, "TimeZoneFilterModel");
33 qmlRegisterType<LocalePlugin>(uri, 0, 1, "LocalePlugin");34 qmlRegisterType<LocalePlugin>(uri, 0, 1, "LocalePlugin");
34}35}

Subscribers

People subscribed via source and target branches