File indexing completed on 2024-12-08 03:38:43
0001 /* 0002 SPDX-FileCopyrightText: 1999-2003 Hans Petter Bieker <bieker@kde.org> 0003 SPDX-FileCopyrightText: 2007 David Jarvie <software@astrojar.org.uk> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "klanguagename.h" 0009 0010 #include <KConfig> 0011 #include <KConfigGroup> 0012 0013 #include <QDir> 0014 #include <QLocale> 0015 0016 QString KLanguageName::nameForCode(const QString &code) 0017 { 0018 const QStringList parts = QLocale().name().split(QLatin1Char('_')); 0019 return nameForCodeInLocale(code, parts.at(0)); 0020 } 0021 0022 static std::tuple<QString, QString> namesFromEntryFile(const QString &realCode, const QString &realOutputCode) 0023 { 0024 const QString entryFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, 0025 QStringLiteral("locale") + QLatin1Char('/') + realCode + QStringLiteral("/kf6_entry.desktop")); 0026 0027 if (!entryFile.isEmpty()) { 0028 KConfig entry(entryFile, KConfig::SimpleConfig); 0029 entry.setLocale(realOutputCode); 0030 const KConfigGroup group(&entry, QStringLiteral("KCM Locale")); 0031 const QString name = group.readEntry("Name"); 0032 0033 entry.setLocale(QStringLiteral("en_US")); 0034 const QString englishName = group.readEntry("Name"); 0035 return std::make_tuple(name, englishName); 0036 } 0037 return {}; 0038 } 0039 0040 QString KLanguageName::nameForCodeInLocale(const QString &code, const QString &outputCode) 0041 { 0042 const QString realCode = code == QLatin1String("en") ? QStringLiteral("en_US") : code; 0043 const QString realOutputCode = outputCode == QLatin1String("en") ? QStringLiteral("en_US") : outputCode; 0044 0045 const std::tuple<QString, QString> nameAndEnglishName = namesFromEntryFile(realCode, realOutputCode); 0046 const QString name = std::get<0>(nameAndEnglishName); 0047 const QString englishName = std::get<1>(nameAndEnglishName); 0048 0049 if (!name.isEmpty()) { 0050 // KConfig doesn't have a way to say it didn't find the entry in 0051 // realOutputCode. When it doesn't find it in the locale you ask for, it just returns the english version 0052 // so we compare the returned name against the english version, if they are different we return it, if they 0053 // are equal we defer to QLocale (with a final fallback to name/englishName if QLocale doesn't know about it) 0054 if (name != englishName || realOutputCode == QLatin1String("en_US")) { 0055 return name; 0056 } 0057 } 0058 0059 const QLocale locale(realCode); 0060 if (locale != QLocale::c()) { 0061 if (realCode == realOutputCode) { 0062 return locale.nativeLanguageName(); 0063 } 0064 return QLocale::languageToString(locale.language()); 0065 } 0066 0067 // We get here if QLocale doesn't know about realCode (at the time of writing this happens for crh, csb, hne, mai) and name and englishName are the same. 0068 // So what we do here is return name, which can be either empty if the KDE side doesn't know about the code, or otherwise will be the name/englishName 0069 return name; 0070 } 0071 0072 QStringList KLanguageName::allLanguageCodes() 0073 { 0074 QStringList systemLangList; 0075 const QStringList localeDirs = QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("locale"), QStandardPaths::LocateDirectory); 0076 for (const QString &localeDir : localeDirs) { 0077 const QStringList entries = QDir(localeDir).entryList(QDir::Dirs); 0078 auto languageExists = [&localeDir](const QString &language) { 0079 return QFile::exists(localeDir + QLatin1Char('/') + language + QLatin1String("/kf6_entry.desktop")); 0080 }; 0081 std::copy_if(entries.begin(), entries.end(), std::back_inserter(systemLangList), languageExists); 0082 } 0083 if (localeDirs.count() > 1) { 0084 systemLangList.removeDuplicates(); 0085 } 0086 return systemLangList; 0087 }