Commit ce73be7e authored by Nicolas Fella's avatar Nicolas Fella
Browse files

Extract saved timezones into a separate model

This extracts the model for the saved timezones into its own class.

This way we have a better separation between the parts that only need to
know the saved timezones and the parts that need access to all system
timezones.
parent bb1d00e1
Pipeline #76115 passed with stage
in 18 seconds
......@@ -18,6 +18,7 @@ set(kclock_SRCS
timezoneselectormodel.cpp
resources.qrc
timerpresetmodel.cpp
savedtimezonesmodel.cpp
)
set(SettingsXML ${CMAKE_CURRENT_BINARY_DIR}/../kclockd/org.kde.kclockd.KClockSettings.xml)
......
......@@ -10,6 +10,7 @@
#include "alarmmodel.h"
#include "alarmplayer.h"
#include "kclockformat.h"
#include "savedtimezonesmodel.h"
#include "settingsmodel.h"
#include "stopwatchtimer.h"
#include "timer.h"
......@@ -68,11 +69,6 @@ int main(int argc, char *argv[])
// initialize models
auto *timeZoneModel = new TimeZoneSelectorModel();
auto *timeZoneViewModel = new QSortFilterProxyModel();
timeZoneViewModel->setFilterFixedString("true");
timeZoneViewModel->setSourceModel(timeZoneModel);
timeZoneViewModel->setFilterRole(TimeZoneSelectorModel::ShownRole);
auto *timeZoneFilterModel = new TimeZoneFilterModel(timeZoneModel);
auto *stopwatchTimer = new StopwatchTimer();
auto *weekModel = new WeekModel();
......@@ -80,6 +76,7 @@ int main(int argc, char *argv[])
// register QML types
qmlRegisterType<Alarm>("kclock", 1, 0, "Alarm");
qmlRegisterType<Timer>("kclock", 1, 0, "Timer");
qmlRegisterType<SavedTimeZonesModel>("kclock", 1, 0, "SavedTimeZonesModel");
qmlRegisterSingletonType<TimerPresetModel>("kclock", 1, 0, "TimerPresetModel", [](QQmlEngine *, QJSEngine *) -> QObject * {
return TimerPresetModel::instance();
});
......@@ -88,8 +85,6 @@ int main(int argc, char *argv[])
engine->rootContext()->setContextObject(new KLocalizedContext(engine));
// models
engine->rootContext()->setContextProperty("timeZoneSelectorModel", timeZoneModel);
engine->rootContext()->setContextProperty("timeZoneShowModel", timeZoneViewModel);
engine->rootContext()->setContextProperty("timeZoneFilterModel", timeZoneFilterModel);
engine->rootContext()->setContextProperty("alarmModel", AlarmModel::instance());
engine->rootContext()->setContextProperty("timerModel", TimerModel::instance());
......
......@@ -11,6 +11,8 @@ import QtQuick.Layouts 1.2
import QtQuick.Shapes 1.12
import org.kde.kirigami 2.15 as Kirigami
import kclock 1.0
Kirigami.ScrollablePage {
id: timePage
......@@ -28,7 +30,6 @@ Kirigami.ScrollablePage {
}
function openEditSheet() {
timeZoneSelectorModel.update();
timeZoneSelect.active = true;
timeZoneSelect.item.open();
}
......@@ -97,7 +98,7 @@ Kirigami.ScrollablePage {
// time zones
ListView {
model: timeZoneShowModel
model: SavedTimeZonesModel {}
id: zoneList
currentIndex: -1 // no default selection
transform: Translate { y: yTranslate }
......@@ -132,7 +133,7 @@ Kirigami.ScrollablePage {
activeBackgroundColor: "transparent"
activeTextColor: Kirigami.Theme.textColor
label: model.id
label: model.name
subtitle: model.relativeTime
bold: true
......
/*
* Copyright 2020 Han Young <hanyoung@protonmail.com>
* Copyright 2020 Devin Lin <espidev@gmail.com>
* Copyright 2021 Nicolas Fella <nicolas.fella@gmx.de>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "savedtimezonesmodel.h"
#include <QDebug>
#include <QTimeZone>
#include <KConfigGroup>
#include <KLocalizedString>
#include <KSharedConfig>
#include "kclockformat.h"
const QString TZ_CFG_GROUP = "Timezones";
SavedTimeZonesModel::SavedTimeZonesModel(QObject *parent)
: QAbstractListModel(parent)
{
auto config = KSharedConfig::openConfig();
KConfigGroup timezoneGroup = config->group(TZ_CFG_GROUP);
for (const QString &timezoneId : timezoneGroup.keyList()) {
QTimeZone z(timezoneId.toUtf8());
m_timeZones.push_back(z);
}
connect(KclockFormat::instance(), &KclockFormat::timeChanged, this, [this] {
QVector<int> roles = {TimeStringRole};
Q_EMIT dataChanged(index(0), index(m_timeZones.size() - 1), roles);
});
}
int SavedTimeZonesModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_timeZones.size();
}
QVariant SavedTimeZonesModel::data(const QModelIndex &index, int role) const
{
const int row = index.row();
switch (role) {
case NameRole:
return m_timeZones[row].displayName(QDateTime::currentDateTime());
case TimeStringRole: {
QDateTime time = QDateTime::currentDateTime();
time = time.toTimeZone(m_timeZones[row]);
// apply 12 hour or 24 hour settings
if (m_settings.value(QStringLiteral("Global/use24HourTime")).toBool()) {
return time.time().toString("hh:mm");
} else {
return time.time().toString("h:mm ap");
}
}
case RelativeTimeRole: {
int offset = m_timeZones[row].offsetFromUtc(QDateTime::currentDateTime()) - QTimeZone::systemTimeZone().offsetFromUtc(QDateTime::currentDateTime());
offset /= 60; // convert to minutes
QString hour = abs(offset) / 60 == 1 ? i18n("hour") : i18n("hours");
if (offset > 0) {
if (offset % 60) { // half an hour ahead
return QVariant(i18n("%1 and a half hours ahead", offset / 60));
} else { // full hours ahead
return QVariant(i18n("%1 %2 ahead", offset / 60, hour));
}
} else if (offset < 0) {
offset = abs(offset);
if (offset % 60) { // half an hour behind
return QVariant(i18n("%1 and a half hours behind", offset / 60));
} else { // full hours behind
return QVariant(i18n("%1 %2 behind", offset / 60, hour));
}
} else {
return QVariant(i18n("Local time"));
}
}
}
return {};
}
QHash<int, QByteArray> SavedTimeZonesModel::roleNames() const
{
return {
{NameRole, "name"},
{TimeStringRole, "timeString"},
{RelativeTimeRole, "relativeTime"},
};
}
/*
* Copyright 2020 Han Young <hanyoung@protonmail.com>
* Copyright 2020 Devin Lin <espidev@gmail.com>
* Copyright 2021 Nicolas Fella <nicolas.fella@gmx.de>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <QAbstractListModel>
#include <QSettings>
#include <QTimeZone>
class SavedTimeZonesModel : public QAbstractListModel
{
Q_OBJECT
public:
enum Roles {
NameRole = Qt::DisplayRole,
TimeStringRole = Qt::UserRole + 1,
RelativeTimeRole,
};
explicit SavedTimeZonesModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent) const override;
QVariant data(const QModelIndex &index, int role) const override;
QHash<int, QByteArray> roleNames() const override;
private:
std::vector<QTimeZone> m_timeZones;
QSettings m_settings;
};
......@@ -16,7 +16,6 @@
#include <KSharedConfig>
#include <QDebug>
#include <QSettings>
#include <QTimeZone>
const QString TZ_CFG_GROUP = "Timezones";
......@@ -32,8 +31,6 @@ TimeZoneSelectorModel::TimeZoneSelectorModel(QObject *parent)
bool show = timezoneGroup.readEntry(id.data(), false);
m_list.append(std::make_tuple(QTimeZone(id), show));
}
connect(KclockFormat::instance(), &KclockFormat::timeChanged, this, &TimeZoneSelectorModel::update);
}
int TimeZoneSelectorModel::rowCount(const QModelIndex &parent) const
......@@ -48,8 +45,6 @@ QVariant TimeZoneSelectorModel::data(const QModelIndex &index, int role) const
return QVariant();
auto tuple = m_list[index.row()];
QSettings settings;
switch (role) {
case NameRole:
return std::get<0>(tuple).displayName(QDateTime::currentDateTime());
......@@ -59,40 +54,6 @@ QVariant TimeZoneSelectorModel::data(const QModelIndex &index, int role) const
return std::get<0>(tuple).id();
case ShortNameRole:
return std::get<0>(tuple).displayName(QDateTime::currentDateTime(), QTimeZone::ShortName);
case RelativeTimeRole: {
int offset = std::get<0>(tuple).offsetFromUtc(QDateTime::currentDateTime()) - QTimeZone::systemTimeZone().offsetFromUtc(QDateTime::currentDateTime());
offset /= 60; // convert to minutes
QString hour = abs(offset) / 60 == 1 ? i18n("hour") : i18n("hours");
if (offset > 0) {
if (offset % 60) { // half an hour ahead
return QVariant(i18n("%1 and a half hours ahead", offset / 60));
} else { // full hours ahead
return QVariant(i18n("%1 %2 ahead", offset / 60, hour));
}
} else if (offset < 0) {
offset = abs(offset);
if (offset % 60) { // half an hour behind
return QVariant(i18n("%1 and a half hours behind", offset / 60));
} else { // full hours behind
return QVariant(i18n("%1 %2 behind", offset / 60, hour));
}
} else {
return QVariant(i18n("Local time"));
}
}
case TimeStringRole: {
QDateTime time = QDateTime::currentDateTime();
time = time.toTimeZone(std::get<0>(tuple));
// apply 12 hour or 24 hour settings
if (settings.value(QStringLiteral("Global/use24HourTime")).toBool()) {
return time.time().toString("hh:mm");
} else {
return time.time().toString("h:mm ap");
}
}
}
return QVariant();
}
......@@ -104,18 +65,10 @@ QHash<int, QByteArray> TimeZoneSelectorModel::roleNames() const
roles[ShownRole] = "shown";
roles[OffsetRole] = "offset";
roles[ShortNameRole] = "shortName";
roles[TimeStringRole] = "timeString";
roles[RelativeTimeRole] = "relativeTime";
roles[IDRole] = "id";
return roles;
}
void TimeZoneSelectorModel::update()
{
QVector<int> roles = {TimeStringRole};
Q_EMIT dataChanged(index(0), index(m_list.size() - 1), roles);
}
Qt::ItemFlags TimeZoneSelectorModel::flags(const QModelIndex &index) const
{
Q_UNUSED(index)
......@@ -144,10 +97,3 @@ TimeZoneFilterModel::TimeZoneFilterModel(TimeZoneSelectorModel *model, QObject *
setFilterRole(TimeZoneSelectorModel::IDRole);
}
TimeZoneViewModel::TimeZoneViewModel(TimeZoneSelectorModel *model, QObject *parent)
: QSortFilterProxyModel(parent)
{
setSourceModel(model);
setFilterRole(TimeZoneSelectorModel::ShownRole);
setFilterFixedString(QStringLiteral("true"));
}
......@@ -26,8 +26,6 @@ public:
ShownRole = Qt::UserRole + 0,
OffsetRole = Qt::UserRole + 1,
ShortNameRole = Qt::UserRole + 2,
TimeStringRole,
RelativeTimeRole,
IDRole
};
......@@ -37,9 +35,6 @@ public:
Qt::ItemFlags flags(const QModelIndex &index) const override;
QHash<int, QByteArray> roleNames() const override;
public Q_SLOTS:
Q_INVOKABLE void update();
private:
QList<std::tuple<QTimeZone, bool>> m_list;
};
......@@ -52,12 +47,4 @@ public:
explicit TimeZoneFilterModel(TimeZoneSelectorModel *model, QObject *parent = nullptr);
};
class TimeZoneViewModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit TimeZoneViewModel(TimeZoneSelectorModel *model, QObject *parent = nullptr);
};
#endif // KCLOCK_TIMEZONESELECTORMODEL_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment