File indexing completed on 2024-04-28 04:52:01

0001 /*
0002 SPDX-FileCopyrightText: 2020 Simon A. Eugster <simon.eu@gmail.com>
0003 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 */
0005 
0006 #include "localeHandling.h"
0007 #include <QtCore/QDebug>
0008 #include <QtCore/QList>
0009 #include <QtGlobal>
0010 #include <clocale>
0011 
0012 auto LocaleHandling::setLocale(const QString &lcName) -> QString
0013 {
0014     QString newLocale;
0015     QList<QString> localesToTest;
0016     localesToTest << lcName << lcName + ".utf-8" << lcName + ".UTF-8" << lcName + ".utf8" << lcName + ".UTF8";
0017     for (const auto &locale : qAsConst(localesToTest)) {
0018 #ifdef Q_OS_FREEBSD
0019         auto *result = setlocale(MLT_LC_CATEGORY, locale.toStdString().c_str());
0020 #else
0021         auto *result = std::setlocale(MLT_LC_CATEGORY, locale.toStdString().c_str());
0022 #endif
0023         if (result != nullptr) {
0024             ::qputenv(MLT_LC_NAME, locale.toStdString().c_str());
0025             newLocale = locale;
0026             break;
0027         }
0028     }
0029     if (newLocale.isEmpty()) {
0030         resetLocale();
0031     }
0032     return newLocale;
0033 }
0034 
0035 void LocaleHandling::resetLocale()
0036 {
0037 #if defined(Q_OS_WIN) || defined(Q_OS_MAC)
0038     // const QString decimalPoint = QLocale().decimalPoint();
0039     std::setlocale(MLT_LC_CATEGORY, "en_US.UTF-8");
0040     ::qputenv(MLT_LC_NAME, "en_US.UTF-8");
0041 #elif defined(Q_OS_FREEBSD)
0042     setlocale(MLT_LC_CATEGORY, "C");
0043     ::qputenv(MLT_LC_NAME, "C");
0044 #else
0045     std::setlocale(MLT_LC_CATEGORY, "C");
0046     ::qputenv(MLT_LC_NAME, "C");
0047 #endif
0048 }
0049 
0050 void LocaleHandling::resetAllLocale()
0051 {
0052 #ifdef Q_OS_FREEBSD
0053     setlocale(LC_ALL, "C.UTF-8");
0054 #else
0055     std::setlocale(LC_ALL, "C.UTF-8");
0056 #endif
0057     ::qputenv("LC_ALL", "C.UTF-8");
0058 }
0059 
0060 QPair<QLocale, LocaleHandling::MatchType> LocaleHandling::getQLocaleForDecimalPoint(const QString &requestedLocale, const QString &decimalPoint)
0061 {
0062     QLocale locale; // Best matching locale
0063     MatchType matchType = MatchType::NoMatch;
0064 
0065     // Parse installed locales to find one matching. Check matching language first
0066     QList<QLocale> list = QLocale::matchingLocales(QLocale().language(), QLocale().script(), QLocale::AnyCountry);
0067     for (const QLocale &loc : qAsConst(list)) {
0068         if (loc.decimalPoint() == decimalPoint) {
0069             locale = loc;
0070             matchType = MatchType::Exact;
0071             break;
0072         }
0073     }
0074 
0075     if (matchType == MatchType::NoMatch) {
0076         // Parse installed locales to find one matching. Check in all languages
0077         list = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale().script(), QLocale::AnyCountry);
0078         for (const QLocale &loc : qAsConst(list)) {
0079             if (loc.decimalPoint() == decimalPoint) {
0080                 locale = loc;
0081                 matchType = MatchType::DecimalOnly;
0082                 break;
0083             }
0084         }
0085     }
0086     if (matchType == MatchType::NoMatch && requestedLocale == QLatin1String("C")) {
0087         locale = QLocale::c();
0088         matchType = MatchType::DecimalOnly;
0089     }
0090     return QPair<QLocale, LocaleHandling::MatchType>(locale, matchType);
0091 }