File indexing completed on 2024-05-19 05:38:24

0001 /*
0002  *  localelistmodel.cpp
0003  *  Copyright 2014 Sebastian Kügler <sebas@kde.org>
0004  *  Copyright 2021 Han Young <hanyoung@protonmail.com>
0005  *
0006  *  This program is free software; you can redistribute it and/or modify
0007  *  it under the terms of the GNU General Public License as published by
0008  *  the Free Software Foundation; either version 2 of the License, or
0009  *  (at your option) any later version.
0010  *
0011  *  This program is distributed in the hope that it will be useful,
0012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014  *  GNU General Public License for more details.
0015  *
0016  *  You should have received a copy of the GNU General Public License
0017  *  along with this program; if not, write to the Free Software
0018  */
0019 
0020 #include "localelistmodel.h"
0021 #include "exampleutility.h"
0022 #include "kcmregionandlang.h"
0023 
0024 using namespace Qt::StringLiterals;
0025 using namespace KCM_RegionAndLang;
0026 
0027 LocaleListModel::LocaleListModel(QObject *parent)
0028     : QAbstractListModel(parent)
0029 {
0030     const QList<QLocale> m_locales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
0031     m_localeData.reserve(m_locales.size() + 1);
0032     // we use first QString for title in Unset option
0033     m_localeData.push_back(LocaleData{i18n("Default for System"), QString(), QString(), QString(), i18n("Default"), QLocale()});
0034     for (auto &locale : m_locales) {
0035         m_localeData.push_back(LocaleData{.nativeName = locale.nativeLanguageName(),
0036                                           .englishName = QLocale::languageToString(locale.language()),
0037                                           .nativeCountryName = locale.nativeCountryName(),
0038                                           .englishCountryName = QLocale::countryToString(locale.country()),
0039                                           .countryCode = locale.name(),
0040                                           .locale = locale});
0041     }
0042 }
0043 
0044 int LocaleListModel::rowCount(const QModelIndex &parent) const
0045 {
0046     Q_UNUSED(parent)
0047     return m_localeData.size();
0048 }
0049 
0050 QVariant LocaleListModel::data(const QModelIndex &index, int role) const
0051 {
0052     int dataIndex = index.row();
0053     const auto &data = m_localeData.at(dataIndex);
0054     switch (static_cast<RoleName>(role)) {
0055     case FlagIcon: {
0056         QString countryCode;
0057         const QStringList split = data.countryCode.split(QLatin1Char('_'));
0058         if (split.size() > 1) {
0059             countryCode = split[1].toLower();
0060         }
0061         return "image://flags/%1"_L1.arg(countryCode);
0062     }
0063     case DisplayName: {
0064         // 0 is unset option, 1 is locale C
0065         if (dataIndex == 1) {
0066             return data.countryCode;
0067         }
0068         const QString clabel = !data.nativeCountryName.isEmpty() ? data.nativeCountryName : data.englishCountryName;
0069         QString languageName;
0070         if (!data.nativeName.isEmpty()) {
0071             languageName = data.nativeName;
0072         } else {
0073             languageName = data.englishName;
0074         }
0075         if (dataIndex == 0) {
0076             return languageName;
0077         }
0078         return i18nc("the first is language name, the second is the country name, like 'English (America)'", "%1 (%2)", languageName, clabel);
0079     }
0080     case LocaleName: {
0081         QString cvalue = data.countryCode;
0082         if (!cvalue.contains(QLatin1Char('.')) && cvalue != QLatin1Char('C') && cvalue != i18n("Default")) {
0083             // explicitly add the encoding,
0084             // otherwise Qt doesn't accept dead keys and garbles the output as well
0085             cvalue.append(QLatin1String(".UTF-8"));
0086         }
0087         return cvalue;
0088     }
0089     case Example: {
0090         switch (m_configType) {
0091         case Lang:
0092         case Language:
0093             return {};
0094         case Numeric:
0095             return Utility::numericExample(data.locale);
0096         case Time:
0097             return Utility::timeExample(data.locale);
0098         case Currency:
0099             return Utility::monetaryExample(data.locale);
0100         case Measurement:
0101             return Utility::measurementExample(data.locale);
0102         case PaperSize:
0103             return Utility::paperSizeExample(data.locale);
0104 #ifdef LC_ADDRESS
0105         case Address:
0106             return Utility::addressExample(data.locale);
0107         case NameStyle:
0108             return Utility::nameStyleExample(data.locale);
0109         case PhoneNumbers:
0110             return Utility::phoneNumbersExample(data.locale);
0111 #endif
0112         }
0113         return {};
0114     }
0115     case FilterRole: {
0116         return data.englishCountryName.toLower() + data.nativeCountryName.toLower() + data.nativeName.toLower() + data.englishName.toLower()
0117             + data.countryCode.toLower();
0118     }
0119     }
0120     Q_UNREACHABLE();
0121     return {};
0122 }
0123 
0124 QHash<int, QByteArray> LocaleListModel::roleNames() const
0125 {
0126     return {{LocaleName, QByteArrayLiteral("localeName")},
0127             {DisplayName, QByteArrayLiteral("display")},
0128             {FlagIcon, QByteArrayLiteral("flag")},
0129             {Example, QByteArrayLiteral("example")},
0130             {FilterRole, QByteArrayLiteral("filter")}};
0131 }
0132 
0133 int LocaleListModel::selectedConfig() const
0134 {
0135     return m_configType;
0136 }
0137 
0138 void LocaleListModel::setSelectedConfig(int config)
0139 {
0140     if (config != m_configType) {
0141         m_configType = static_cast<SettingType>(config);
0142     }
0143     Q_EMIT selectedConfigChanged();
0144     Q_EMIT dataChanged(createIndex(0, 0), createIndex(rowCount(), 0), QList<int>(1, Example));
0145 }
0146 
0147 void LocaleListModel::setLang(const QString &lang)
0148 {
0149     QString tmpLang = lang;
0150     bool isC = false;
0151     if (lang.isEmpty()) {
0152         tmpLang = qgetenv("LANG");
0153         if (tmpLang.isEmpty()) {
0154             tmpLang = QStringLiteral("C");
0155             isC = true;
0156         }
0157     }
0158 
0159     LocaleData &data = m_localeData.front();
0160     if (isC) {
0161         data.nativeName = i18nc("@info:title, meaning the current locale is system default(which is `C`)", "System Default C");
0162     } else {
0163         data.nativeName =
0164             i18nc("@info:title the current locale is the default for %1, %1 is the country name", "Default for %1", QLocale(tmpLang).nativeLanguageName());
0165     }
0166     data.locale = QLocale(tmpLang);
0167 
0168     Q_EMIT dataChanged(createIndex(0, 0), createIndex(0, 0));
0169 }