on 246c47b help sign in
unity8/plugins/Wizard/timezonemodel.cpp
206 lines 5.7 kB history raw
1/*
2 * Copyright (C) 2016 Canonical Ltd.
3 *
4 * 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 published
6 * by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
17#include <QDebug>
19#include <glib.h>
20#include <glib-object.h>
22#include "LocalePlugin.h"
23#include "timezonemodel.h"
25TimeZoneLocationModel::TimeZoneLocationModel(QObject *parent):
26 QAbstractListModel(parent),
27 m_listUpdating(false),
28 m_cancellable(nullptr)
30 m_roleNames[Qt::DisplayRole] = "displayName";
31 m_roleNames[TimeZoneRole] = "timeZone";
32 m_roleNames[CityRole] = "city";
33 m_roleNames[CountryRole] = "country";
34 m_roleNames[OffsetRole] = "offset";
35 m_roleNames[LatitudeRole] = "latitude";
36 m_roleNames[LongitudeRole] = "longitude";
39int TimeZoneLocationModel::rowCount(const QModelIndex &parent) const
41 if (parent.isValid())
42 return 0;
43 return m_locations.count();
46QVariant TimeZoneLocationModel::data(const QModelIndex &index, int role) const
48 if (index.row() >= m_locations.count() || index.row() < 0)
49 return QVariant();
51 GeonamesCity *city = m_locations[index.row()];
53 switch (role) {
54 case Qt::DisplayRole:
55 return QVariant(QString("%1, %2, %3").arg(geonames_city_get_name(city))
56 .arg(geonames_city_get_state(city))
57 .arg(geonames_city_get_country(city)));
58 case SimpleRole:
59 return QVariant(QString("%1, %2").arg(geonames_city_get_name(city))
60 .arg(geonames_city_get_country(city)));
61 case TimeZoneRole:
62 return geonames_city_get_timezone(city);
63 case CountryRole:
64 return geonames_city_get_country(city);
65 case CityRole:
66 return geonames_city_get_name(city);
67 case OffsetRole: {
68 QTimeZone tmp(geonames_city_get_timezone(city));
69 return static_cast<double>(tmp.standardTimeOffset(QDateTime::currentDateTime())) / 3600;
70 }
71 case LatitudeRole:
72 return geonames_city_get_latitude(city);
73 case LongitudeRole:
74 return geonames_city_get_longitude(city);
75 default:
76 qWarning() << Q_FUNC_INFO << "Unknown role";
77 return QVariant();
78 }
81QHash<int, QByteArray> TimeZoneLocationModel::roleNames() const
83 return m_roleNames;
86void TimeZoneLocationModel::setModel(QList<GeonamesCity *> locations)
88 beginResetModel();
90 Q_FOREACH(GeonamesCity *city, m_locations) {
91 geonames_city_free(city);
92 }
94 m_locations = locations;
95 endResetModel();
98void TimeZoneLocationModel::filterFinished(GObject *source_object,
99 GAsyncResult *res,
100 gpointer user_data)
102 Q_UNUSED(source_object);
104 g_autofree gint *cities = nullptr;
105 guint cities_len = 0;
106 g_autoptr(GError) error = nullptr;
108 cities = geonames_query_cities_finish(res, &cities_len, &error);
109 if (error) {
110 if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
111 TimeZoneLocationModel *model = static_cast<TimeZoneLocationModel *>(user_data);
112 g_clear_object(&model->m_cancellable);
113 qWarning() << "Could not filter timezones:" << error->message;
114 }
115 return;
116 }
118 QList<GeonamesCity *> locations;
120 for (guint i = 0; i < cities_len; ++i) {
121 GeonamesCity *city = geonames_get_city(cities[i]);
122 if (city) {
123 locations.append(city);
124 }
125 }
127 TimeZoneLocationModel *model = static_cast<TimeZoneLocationModel *>(user_data);
129 g_clear_object(&model->m_cancellable);
131 model->setModel(locations);
132 model->setListUpdating(false);
135bool TimeZoneLocationModel::listUpdating() const
137 return m_listUpdating;
140void TimeZoneLocationModel::setListUpdating(bool listUpdating)
142 if (m_listUpdating != listUpdating) {
143 m_listUpdating = listUpdating;
144 Q_EMIT listUpdatingChanged();
145 }
148QString TimeZoneLocationModel::filter() const
150 return m_filter;
153void TimeZoneLocationModel::setFilter(const QString &filter)
155 if (filter != m_filter) {
156 m_filter = filter;
157 Q_EMIT filterChanged();
158 }
160 setListUpdating(true);
162 if (m_cancellable) {
163 g_cancellable_cancel(m_cancellable);
164 g_clear_object(&m_cancellable);
165 }
167 setModel(QList<GeonamesCity *>());
169 if (filter.isEmpty()) {
170 setListUpdating(false);
171 return;
172 }
174 m_cancellable = g_cancellable_new();
175 geonames_query_cities(filter.toUtf8().data(),
176 GEONAMES_QUERY_DEFAULT,
177 m_cancellable,
178 filterFinished,
179 this);
182QString TimeZoneLocationModel::country() const
184 return m_country;
187void TimeZoneLocationModel::setCountry(const QString &country)
189 if (m_country == country)
190 return;
192 m_country = country;
193 Q_EMIT countryChanged(country);
196TimeZoneLocationModel::~TimeZoneLocationModel()
198 if (m_cancellable) {
199 g_cancellable_cancel(m_cancellable);
200 g_clear_object(&m_cancellable);
201 }
203 Q_FOREACH(GeonamesCity *city, m_locations) {
204 geonames_city_free(city);
205 }