shift-shell/initialstart/modules/time/timezonemodel.cpp

122 lines
3.3 KiB
C++
Raw Normal View History

// SPDX-FileCopyrightText: 2014 Kai Uwe Broulik <kde@privat.broulik.de>
// SPDX-FileCopyrightText: 2014 Martin Klapetek <mklapetek@kde.org>
// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "timezonemodel.h"
#include <KLocalizedString>
#include <QDebug>
#include <QSet>
#include <QStringList>
#include <QStringMatcher>
#include <QTimeZone>
#include <algorithm>
TimeZoneFilterProxy::TimeZoneFilterProxy(QObject *parent)
: QSortFilterProxyModel(parent)
{
m_stringMatcher.setCaseSensitivity(Qt::CaseInsensitive);
}
bool TimeZoneFilterProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
if (!sourceModel() || m_filterString.isEmpty()) {
return true;
}
const QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
const QString id = index.data(TimeZoneModel::TimeZoneIdRole).toString();
const QString displayName = index.data(TimeZoneModel::DisplayNameRole).toString();
return m_stringMatcher.indexIn(id) != -1 || m_stringMatcher.indexIn(displayName) != -1;
}
void TimeZoneFilterProxy::setFilterString(const QString &filterString)
{
m_filterString = filterString;
m_stringMatcher.setPattern(filterString);
Q_EMIT filterStringChanged();
invalidateFilter();
}
TimeZoneModel::TimeZoneModel(QObject *parent)
: QAbstractListModel(parent)
{
update();
}
TimeZoneModel::~TimeZoneModel()
{
}
int TimeZoneModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_data.count();
}
QVariant TimeZoneModel::data(const QModelIndex &index, int role) const
{
if (index.isValid()) {
switch (role) {
case TimeZoneIdRole:
return m_data[index.row()];
case DisplayNameRole:
return displayNameForId(m_data[index.row()]);
}
}
return QVariant();
}
void TimeZoneModel::update()
{
beginResetModel();
m_data.clear();
QString localZone = QString::fromUtf8(QTimeZone::systemTimeZoneId());
if (localZone.isEmpty() || !QTimeZone(localZone.toUtf8()).isValid()) {
localZone = QStringLiteral("UTC");
}
QSet<QString> seenZones;
const QList<QByteArray> systemTimeZones = QTimeZone::availableTimeZoneIds();
for (const QByteArray &timeZoneId : systemTimeZones) {
const QString zone = QString::fromUtf8(timeZoneId);
if (!seenZones.contains(zone)) {
seenZones.insert(zone);
m_data.append(zone);
}
}
std::sort(m_data.begin(), m_data.end(), [](const QString &left, const QString &right) {
return QString::localeAwareCompare(left, right) < 0;
});
const int localIndex = m_data.indexOf(localZone);
if (localIndex > 0) {
m_data.move(localIndex, 0);
}
endResetModel();
}
QHash<int, QByteArray> TimeZoneModel::roleNames() const
{
return {{TimeZoneIdRole, "timeZoneId"}, {DisplayNameRole, "displayName"}};
}
QString TimeZoneModel::displayNameForId(const QString &timeZoneId) const
{
QString displayName = timeZoneId;
displayName.replace(QLatin1Char('_'), QLatin1Char(' '));
const QStringList parts = displayName.split(QLatin1Char('/'), Qt::SkipEmptyParts);
if (parts.size() <= 1) {
return displayName;
}
return i18nc("timezone city and region", "%1 (%2)", parts.mid(1).join(QStringLiteral(" / ")), parts.first());
}