// SPDX-FileCopyrightText: 2014 Kai Uwe Broulik // SPDX-FileCopyrightText: 2014 Martin Klapetek // SPDX-FileCopyrightText: 2023 Devin Lin // SPDX-License-Identifier: GPL-2.0-or-later #include "timezonemodel.h" #include #include #include #include #include #include #include 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 seenZones; const QList 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 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()); }