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

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 (static_cast<Roles>(role)) {
0107     case Name:
0108         return m_staticNames.at(row).first;
0109     case Subtitle: {
0110         switch (static_cast<SettingType>(row)) {
0111         case Language:
0112             Q_ASSERT(false); // shouldn't happen
0113             return {};
0114         case Lang:
0115             if (m_settings->defaultLangValue().isEmpty() && m_settings->isDefaultSetting(SettingType::Lang)) {
0116                 // no Lang configured, no $LANG in env
0117                 return i18nc("@info:title, the current setting is system default", "System Default");
0118             } else if (!m_settings->lang().isEmpty() && m_settings->lang() != m_settings->defaultLangValue()) {
0119                 // Lang configured and not empty
0120                 return getNativeName(m_settings->lang());
0121             } else {
0122                 // Lang configured but empty, try to read from $LANGUAGE first.
0123                 if (const QString languages = m_settings->defaultLanguageValue(); !languages.isEmpty()) {
0124                     // If the first language is invalid, just fall through to $LANG
0125                     const QStringList languageList = languages.split(QLatin1Char(':'));
0126                     if (const QString firstLanguage = getNativeName(languageList[0]); !firstLanguage.isEmpty()) {
0127                         return firstLanguage;
0128                     }
0129                 }
0130 
0131                 // Lang configured but empty, try to read from $LANG, shouldn't happen on a valid config file
0132                 return getNativeName(m_settings->defaultLangValue());
0133             }
0134         case Numeric:
0135             if (m_settings->isDefaultSetting(SettingType::Numeric)) {
0136                 return getNativeName(m_settings->numeric());
0137             }
0138             break;
0139         case Time:
0140             if (m_settings->isDefaultSetting(SettingType::Time)) {
0141                 return getNativeName(m_settings->time());
0142             }
0143             break;
0144         case Currency:
0145             if (m_settings->isDefaultSetting(SettingType::Currency)) {
0146                 return getNativeName(m_settings->monetary());
0147             }
0148             break;
0149         case Measurement:
0150             if (m_settings->isDefaultSetting(SettingType::Measurement)) {
0151                 return getNativeName(m_settings->measurement());
0152             }
0153             break;
0154         case PaperSize:
0155             if (m_settings->isDefaultSetting(SettingType::PaperSize)) {
0156                 return getNativeName(m_settings->paperSize());
0157             }
0158             break;
0159 #ifdef LC_ADDRESS
0160         case Address:
0161             if (m_settings->isDefaultSetting(SettingType::Address)) {
0162                 return getNativeName(m_settings->address());
0163             }
0164             break;
0165         case NameStyle:
0166             if (m_settings->isDefaultSetting(SettingType::NameStyle)) {
0167                 return getNativeName(m_settings->nameStyle());
0168             }
0169             break;
0170         case PhoneNumbers:
0171             if (m_settings->isDefaultSetting(SettingType::PhoneNumbers)) {
0172                 return getNativeName(m_settings->phoneNumbers());
0173             }
0174             break;
0175 #endif
0176         }
0177         return {}; // implicit locale
0178     }
0179     case Example: {
0180         switch (static_cast<SettingType>(row)) {
0181         case Language:
0182             Q_ASSERT(false); // shouldn't happen
0183             return {};
0184         case Lang:
0185             return {};
0186         case Numeric: {
0187             QString example = m_numberExample;
0188             if (m_settings->isDefaultSetting(SettingType::Numeric)) {
0189                 example += implicitFormatExampleMsg();
0190             }
0191             return example;
0192         }
0193         case Time: {
0194             QString example = m_timeExample;
0195             if (m_settings->isDefaultSetting(SettingType::Time)) {
0196                 example += implicitFormatExampleMsg();
0197             }
0198             return example;
0199         }
0200         case Currency: {
0201             QString example = m_currencyExample;
0202             if (m_settings->isDefaultSetting(SettingType::Currency)) {
0203                 example += implicitFormatExampleMsg();
0204             }
0205             return example;
0206         }
0207         case Measurement: {
0208             QString example = m_measurementExample;
0209             if (m_settings->isDefaultSetting(SettingType::Measurement)) {
0210                 example += implicitFormatExampleMsg();
0211             }
0212             return example;
0213         }
0214         case PaperSize: {
0215             QString example = m_paperSizeExample;
0216             if (m_settings->isDefaultSetting(SettingType::PaperSize)) {
0217                 example += implicitFormatExampleMsg();
0218             }
0219             return example;
0220         }
0221 #ifdef LC_ADDRESS
0222         case Address: {
0223             QString example = m_addressExample;
0224             if (m_settings->isDefaultSetting(SettingType::Address)) {
0225                 example += implicitFormatExampleMsg();
0226             }
0227             return example;
0228         }
0229         case NameStyle: {
0230             QString example = m_nameStyleExample;
0231             if (m_settings->isDefaultSetting(SettingType::NameStyle)) {
0232                 example += implicitFormatExampleMsg();
0233             }
0234             return example;
0235         }
0236         case PhoneNumbers: {
0237             QString example = m_phoneNumbersExample;
0238             if (m_settings->isDefaultSetting(SettingType::PhoneNumbers)) {
0239                 example += implicitFormatExampleMsg();
0240             }
0241             return example;
0242         }
0243 #endif
0244         }
0245         return {};
0246     }
0247     case Page:
0248         return m_staticNames.at(row).second;
0249     }
0250     return {};
0251 }
0252 
0253 QHash<int, QByteArray> OptionsModel::roleNames() const
0254 {
0255     return {{Name, QByteArrayLiteral("name")},
0256             {Subtitle, QByteArrayLiteral("localeName")},
0257             {Example, QByteArrayLiteral("example")},
0258             {Page, QByteArrayLiteral("page")}};
0259 }
0260 
0261 void OptionsModel::handleLangChange()
0262 {
0263     Q_EMIT dataChanged(createIndex(0, 0), createIndex(0, 0), {Subtitle, Example});
0264     QLocale lang = QLocale(m_settings->lang());
0265     if (m_settings->isDefaultSetting(SettingType::Numeric)) {
0266         m_numberExample = Utility::numericExample(lang);
0267         Q_EMIT dataChanged(createIndex(1, 0), createIndex(1, 0), {Subtitle, Example});
0268     }
0269     if (m_settings->isDefaultSetting(SettingType::Time)) {
0270         m_timeExample = Utility::timeExample(lang);
0271         Q_EMIT dataChanged(createIndex(2, 0), createIndex(2, 0), {Subtitle, Example});
0272     }
0273     if (m_settings->isDefaultSetting(SettingType::Currency)) {
0274         m_currencyExample = Utility::monetaryExample(lang);
0275         Q_EMIT dataChanged(createIndex(3, 0), createIndex(3, 0), {Subtitle, Example});
0276     }
0277     if (m_settings->isDefaultSetting(SettingType::Measurement)) {
0278         m_measurementExample = Utility::measurementExample(lang);
0279         Q_EMIT dataChanged(createIndex(4, 0), createIndex(4, 0), {Subtitle, Example});
0280     }
0281     if (m_settings->isDefaultSetting(SettingType::PaperSize)) {
0282         m_paperSizeExample = Utility::paperSizeExample(lang);
0283         Q_EMIT dataChanged(createIndex(5, 0), createIndex(5, 0), {Subtitle, Example});
0284     }
0285 #ifdef LC_ADDRESS
0286     if (m_settings->isDefaultSetting(SettingType::Address)) {
0287         m_addressExample = Utility::addressExample(lang);
0288         Q_EMIT dataChanged(createIndex(6, 0), createIndex(6, 0), {Subtitle, Example});
0289     }
0290     if (m_settings->isDefaultSetting(SettingType::NameStyle)) {
0291         m_nameStyleExample = Utility::nameStyleExample(lang);
0292         Q_EMIT dataChanged(createIndex(7, 0), createIndex(7, 0), {Subtitle, Example});
0293     }
0294     if (m_settings->isDefaultSetting(SettingType::PhoneNumbers)) {
0295         m_phoneNumbersExample = Utility::phoneNumbersExample(lang);
0296         Q_EMIT dataChanged(createIndex(8, 0), createIndex(8, 0), {Subtitle, Example});
0297     }
0298 #endif
0299 }
0300 
0301 QString OptionsModel::implicitFormatExampleMsg() const
0302 {
0303     QString locale;
0304 
0305     if (!m_settings->lang().isEmpty()) {
0306         locale = getNativeName(m_settings->lang());
0307     } else if (!m_settings->defaultLangValue().isEmpty()) {
0308         locale = getNativeName(m_settings->defaultLangValue());
0309     } else {
0310         locale = i18nc("@info:title, the current setting is system default", "System Default");
0311     }
0312     return i18nc("as subtitle, remind user that the format used now is inherited from locale %1", " (Standard format for %1)", locale);
0313 }
0314 
0315 QString OptionsModel::getNativeName(const QString &locale) const
0316 {
0317     return QLocale(locale).nativeLanguageName();
0318 }