File indexing completed on 2024-05-26 16:53:41

0001 /*
0002     optionsmodel.cpp
0003     SPDX-FileCopyrightText: 2021 Han Young <hanyoung@protonmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include <QLocale>
0009 
0010 #include <KLocalizedString>
0011 
0012 #include "exampleutility.h"
0013 #include "kcmregionandlang.h"
0014 #include "optionsmodel.h"
0015 #include "settingtype.h"
0016 
0017 using namespace KCM_RegionAndLang;
0018 
0019 OptionsModel::OptionsModel(KCMRegionAndLang *parent)
0020     : QAbstractListModel(parent)
0021     , m_settings(parent->settings())
0022 {
0023     m_staticNames = {{{i18nc("@info:title", "Language"), SettingType::Lang},
0024                       {i18nc("@info:title", "Numbers"), SettingType::Numeric},
0025                       {i18nc("@info:title", "Time"), SettingType::Time},
0026                       {i18nc("@info:title", "Currency"), SettingType::Currency},
0027                       {i18nc("@info:title", "Measurements"), SettingType::Measurement},
0028                       {i18nc("@info:title", "Paper Size"), SettingType::PaperSize}}};
0029 #ifdef LC_ADDRESS
0030     m_staticNames.push_back(std::make_pair(i18nc("@info:title", "Address"), SettingType::Address));
0031     m_staticNames.push_back(std::make_pair(i18nc("@info:title", "Name Style"), SettingType::NameStyle));
0032     m_staticNames.push_back(std::make_pair(i18nc("@info:title", "Phone Numbers"), SettingType::PhoneNumbers));
0033 #endif
0034 
0035     connect(m_settings, &RegionAndLangSettings::langChanged, this, &OptionsModel::handleLangChange);
0036     connect(m_settings, &RegionAndLangSettings::numericChanged, this, [this] {
0037         QLocale locale(m_settings->LC_LocaleWithLang(SettingType::Numeric));
0038         m_numberExample = Utility::numericExample(locale);
0039         Q_EMIT dataChanged(createIndex(1, 0), createIndex(1, 0), {Subtitle, Example});
0040     });
0041     connect(m_settings, &RegionAndLangSettings::timeChanged, this, [this] {
0042         QLocale locale(m_settings->LC_LocaleWithLang(SettingType::Time));
0043         m_timeExample = Utility::timeExample(locale);
0044         Q_EMIT dataChanged(createIndex(2, 0), createIndex(2, 0), {Subtitle, Example});
0045     });
0046     connect(m_settings, &RegionAndLangSettings::monetaryChanged, this, [this] {
0047         QLocale locale(m_settings->LC_LocaleWithLang(SettingType::Currency));
0048         m_currencyExample = Utility::monetaryExample(locale);
0049         Q_EMIT dataChanged(createIndex(3, 0), createIndex(3, 0), {Subtitle, Example});
0050     });
0051     connect(m_settings, &RegionAndLangSettings::measurementChanged, this, [this] {
0052         QLocale locale(m_settings->LC_LocaleWithLang(SettingType::Measurement));
0053         m_measurementExample = Utility::measurementExample(locale);
0054         Q_EMIT dataChanged(createIndex(4, 0), createIndex(4, 0), {Subtitle, Example});
0055     });
0056     connect(m_settings, &RegionAndLangSettings::paperSizeChanged, this, [this] {
0057         QLocale locale(m_settings->LC_LocaleWithLang(SettingType::PaperSize));
0058         m_paperSizeExample = Utility::paperSizeExample(locale);
0059         Q_EMIT dataChanged(createIndex(5, 0), createIndex(5, 0), {Subtitle, Example});
0060     });
0061 #ifdef LC_ADDRESS
0062     connect(m_settings, &RegionAndLangSettings::addressChanged, this, [this] {
0063         QLocale locale(m_settings->LC_LocaleWithLang(SettingType::Address));
0064         m_addressExample = Utility::addressExample(locale);
0065         Q_EMIT dataChanged(createIndex(6, 0), createIndex(6, 0), {Subtitle, Example});
0066     });
0067     connect(m_settings, &RegionAndLangSettings::nameStyleChanged, this, [this] {
0068         QLocale locale(m_settings->LC_LocaleWithLang(SettingType::NameStyle));
0069         m_nameStyleExample = Utility::nameStyleExample(locale);
0070         Q_EMIT dataChanged(createIndex(7, 0), createIndex(7, 0), {Subtitle, Example});
0071     });
0072     connect(m_settings, &RegionAndLangSettings::phoneNumbersChanged, this, [this] {
0073         QLocale locale(m_settings->LC_LocaleWithLang(SettingType::PhoneNumbers));
0074         m_phoneNumbersExample = Utility::phoneNumbersExample(locale);
0075         Q_EMIT dataChanged(createIndex(8, 0), createIndex(8, 0), {Subtitle, Example});
0076     });
0077 #endif
0078 
0079     // initialize examples
0080     m_numberExample = Utility::numericExample(QLocale(m_settings->LC_LocaleWithLang(SettingType::Numeric)));
0081     m_timeExample = Utility::timeExample(QLocale(m_settings->LC_LocaleWithLang(SettingType::Time)));
0082     m_measurementExample = Utility::measurementExample(QLocale(m_settings->LC_LocaleWithLang(SettingType::Measurement)));
0083     m_currencyExample = Utility::monetaryExample(QLocale(m_settings->LC_LocaleWithLang(SettingType::Currency)));
0084     m_paperSizeExample = Utility::paperSizeExample(QLocale(m_settings->LC_LocaleWithLang(SettingType::PaperSize)));
0085 #ifdef LC_ADDRESS
0086     m_addressExample = Utility::addressExample(QLocale(m_settings->LC_LocaleWithLang(SettingType::Address)));
0087     m_nameStyleExample = Utility::nameStyleExample(QLocale(m_settings->LC_LocaleWithLang(SettingType::NameStyle)));
0088     m_phoneNumbersExample = Utility::phoneNumbersExample(QLocale(m_settings->LC_LocaleWithLang(SettingType::PhoneNumbers)));
0089 #endif
0090 }
0091 
0092 int OptionsModel::rowCount(const QModelIndex &parent) const
0093 {
0094     Q_UNUSED(parent)
0095     return m_staticNames.size();
0096 }
0097 
0098 QVariant OptionsModel::data(const QModelIndex &index, int role) const
0099 {
0100     using namespace KCM_RegionAndLang;
0101     const int row = index.row();
0102     if (row < 0 || row >= (int)m_staticNames.size()) {
0103         return {};
0104     }
0105 
0106     switch (role) {
0107     case Name:
0108         return m_staticNames.at(row).first;
0109     case Subtitle: {
0110         switch (row) {
0111         case Lang:
0112             if (m_settings->defaultLangValue().isEmpty() && m_settings->isDefaultSetting(SettingType::Lang)) {
0113                 // no Lang configured, no $LANG in env
0114                 return i18nc("@info:title, the current setting is system default", "System Default");
0115             } else if (!m_settings->lang().isEmpty() && m_settings->lang() != m_settings->defaultLangValue()) {
0116                 // Lang configured and not empty
0117                 return getNativeName(m_settings->lang());
0118             } else {
0119                 // Lang configured but empty, try to read from $LANGUAGE first.
0120                 if (const QString languages = m_settings->defaultLanguageValue(); !languages.isEmpty()) {
0121                     // If the first language is invalid, just fall through to $LANG
0122                     const QStringList languageList = languages.split(QLatin1Char(':'));
0123                     if (const QString firstLanguage = getNativeName(languageList[0]); !firstLanguage.isEmpty()) {
0124                         return firstLanguage;
0125                     }
0126                 }
0127 
0128                 // Lang configured but empty, try to read from $LANG, shouldn't happen on a valid config file
0129                 return getNativeName(m_settings->defaultLangValue());
0130             }
0131         case Numeric:
0132             if (m_settings->isDefaultSetting(SettingType::Numeric)) {
0133                 return getNativeName(m_settings->numeric());
0134             }
0135             break;
0136         case Time:
0137             if (m_settings->isDefaultSetting(SettingType::Time)) {
0138                 return getNativeName(m_settings->time());
0139             }
0140             break;
0141         case Currency:
0142             if (m_settings->isDefaultSetting(SettingType::Currency)) {
0143                 return getNativeName(m_settings->monetary());
0144             }
0145             break;
0146         case Measurement:
0147             if (m_settings->isDefaultSetting(SettingType::Measurement)) {
0148                 return getNativeName(m_settings->measurement());
0149             }
0150             break;
0151         case PaperSize:
0152             if (m_settings->isDefaultSetting(SettingType::PaperSize)) {
0153                 return getNativeName(m_settings->paperSize());
0154             }
0155             break;
0156 #ifdef LC_ADDRESS
0157         case Address:
0158             if (m_settings->isDefaultSetting(SettingType::Address)) {
0159                 return getNativeName(m_settings->address());
0160             }
0161             break;
0162         case NameStyle:
0163             if (m_settings->isDefaultSetting(SettingType::NameStyle)) {
0164                 return getNativeName(m_settings->nameStyle());
0165             }
0166             break;
0167         case PhoneNumbers:
0168             if (m_settings->isDefaultSetting(SettingType::PhoneNumbers)) {
0169                 return getNativeName(m_settings->phoneNumbers());
0170             }
0171             break;
0172 #endif
0173         }
0174         return {}; // implicit locale
0175     }
0176     case Example: {
0177         switch (row) {
0178         case Lang:
0179             return {};
0180         case Numeric: {
0181             QString example = m_numberExample;
0182             if (m_settings->isDefaultSetting(SettingType::Numeric)) {
0183                 example += implicitFormatExampleMsg();
0184             }
0185             return example;
0186         }
0187         case Time: {
0188             QString example = m_timeExample;
0189             if (m_settings->isDefaultSetting(SettingType::Time)) {
0190                 example += implicitFormatExampleMsg();
0191             }
0192             return example;
0193         }
0194         case Currency: {
0195             QString example = m_currencyExample;
0196             if (m_settings->isDefaultSetting(SettingType::Currency)) {
0197                 example += implicitFormatExampleMsg();
0198             }
0199             return example;
0200         }
0201         case Measurement: {
0202             QString example = m_measurementExample;
0203             if (m_settings->isDefaultSetting(SettingType::Measurement)) {
0204                 example += implicitFormatExampleMsg();
0205             }
0206             return example;
0207         }
0208         case PaperSize: {
0209             QString example = m_paperSizeExample;
0210             if (m_settings->isDefaultSetting(SettingType::PaperSize)) {
0211                 example += implicitFormatExampleMsg();
0212             }
0213             return example;
0214         }
0215 #ifdef LC_ADDRESS
0216         case Address: {
0217             QString example = m_addressExample;
0218             if (m_settings->isDefaultSetting(SettingType::Address)) {
0219                 example += implicitFormatExampleMsg();
0220             }
0221             return example;
0222         }
0223         case NameStyle: {
0224             QString example = m_nameStyleExample;
0225             if (m_settings->isDefaultSetting(SettingType::NameStyle)) {
0226                 example += implicitFormatExampleMsg();
0227             }
0228             return example;
0229         }
0230         case PhoneNumbers: {
0231             QString example = m_phoneNumbersExample;
0232             if (m_settings->isDefaultSetting(SettingType::PhoneNumbers)) {
0233                 example += implicitFormatExampleMsg();
0234             }
0235             return example;
0236         }
0237 #endif
0238         }
0239         return {};
0240     }
0241     case Page:
0242         return m_staticNames.at(row).second;
0243     }
0244     return {};
0245 }
0246 
0247 QHash<int, QByteArray> OptionsModel::roleNames() const
0248 {
0249     return {{Name, QByteArrayLiteral("name")},
0250             {Subtitle, QByteArrayLiteral("localeName")},
0251             {Example, QByteArrayLiteral("example")},
0252             {Page, QByteArrayLiteral("page")}};
0253 }
0254 
0255 void OptionsModel::handleLangChange()
0256 {
0257     Q_EMIT dataChanged(createIndex(0, 0), createIndex(0, 0), {Subtitle, Example});
0258     QLocale lang = QLocale(m_settings->lang());
0259     if (m_settings->isDefaultSetting(SettingType::Numeric)) {
0260         m_numberExample = Utility::numericExample(lang);
0261         Q_EMIT dataChanged(createIndex(1, 0), createIndex(1, 0), {Subtitle, Example});
0262     }
0263     if (m_settings->isDefaultSetting(SettingType::Time)) {
0264         m_timeExample = Utility::timeExample(lang);
0265         Q_EMIT dataChanged(createIndex(2, 0), createIndex(2, 0), {Subtitle, Example});
0266     }
0267     if (m_settings->isDefaultSetting(SettingType::Currency)) {
0268         m_currencyExample = Utility::monetaryExample(lang);
0269         Q_EMIT dataChanged(createIndex(3, 0), createIndex(3, 0), {Subtitle, Example});
0270     }
0271     if (m_settings->isDefaultSetting(SettingType::Measurement)) {
0272         m_measurementExample = Utility::measurementExample(lang);
0273         Q_EMIT dataChanged(createIndex(4, 0), createIndex(4, 0), {Subtitle, Example});
0274     }
0275     if (m_settings->isDefaultSetting(SettingType::PaperSize)) {
0276         m_paperSizeExample = Utility::paperSizeExample(lang);
0277         Q_EMIT dataChanged(createIndex(5, 0), createIndex(5, 0), {Subtitle, Example});
0278     }
0279 #ifdef LC_ADDRESS
0280     if (m_settings->isDefaultSetting(SettingType::Address)) {
0281         m_addressExample = Utility::addressExample(lang);
0282         Q_EMIT dataChanged(createIndex(6, 0), createIndex(6, 0), {Subtitle, Example});
0283     }
0284     if (m_settings->isDefaultSetting(SettingType::NameStyle)) {
0285         m_nameStyleExample = Utility::nameStyleExample(lang);
0286         Q_EMIT dataChanged(createIndex(7, 0), createIndex(7, 0), {Subtitle, Example});
0287     }
0288     if (m_settings->isDefaultSetting(SettingType::PhoneNumbers)) {
0289         m_phoneNumbersExample = Utility::phoneNumbersExample(lang);
0290         Q_EMIT dataChanged(createIndex(8, 0), createIndex(8, 0), {Subtitle, Example});
0291     }
0292 #endif
0293 }
0294 
0295 QString OptionsModel::implicitFormatExampleMsg() const
0296 {
0297     QString locale;
0298 
0299     if (!m_settings->lang().isEmpty()) {
0300         locale = getNativeName(m_settings->lang());
0301     } else if (!m_settings->defaultLangValue().isEmpty()) {
0302         locale = getNativeName(m_settings->defaultLangValue());
0303     } else {
0304         locale = i18nc("@info:title, the current setting is system default", "System Default");
0305     }
0306     return i18nc("as subtitle, remind user that the format used now is inherited from locale %1", " (Standard format for %1)", locale);
0307 }
0308 
0309 QString OptionsModel::getNativeName(const QString &locale) const
0310 {
0311     return QLocale(locale).nativeLanguageName();
0312 }