From 91077def022a999ce46c91347f1167626266f460 Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <aacid@kde.org>
Date: Mon, 7 Jan 2019 11:42:28 +0100
Subject: Add KLanguageName

Summary: KLanguageName is a helper namespace that returns the name of a given language code.

Reviewers: apol

Reviewed By: apol

Subscribers: hein, kde-frameworks-devel, sitter, markg, apol

Tags: #frameworks

Differential Revision: https://phabricator.kde.org/D10446
---
 autotests/CMakeLists.txt                           | 27 ++++++
 .../kf5_entry_data.cmake/locale/ca/kf5_entry.cmake | 98 ++++++++++++++++++++++
 .../kf5_entry_data.cmake/locale/de/kf5_entry.cmake | 98 ++++++++++++++++++++++
 .../locale/en_US/kf5_entry.cmake                   | 44 ++++++++++
 autotests/kf5_entry_data.cmake/locale/es/.keep     |  0
 .../kf5_entry_data.cmake/locale/fr/kf5_entry.cmake |  2 +
 .../kf5_entry_data.cmake/locale/pt/kf5_entry.cmake | 98 ++++++++++++++++++++++
 autotests/klanguagenametest.cpp                    | 92 ++++++++++++++++++++
 src/CMakeLists.txt                                 |  2 +
 src/klanguagename.cpp                              | 67 +++++++++++++++
 src/klanguagename.h                                | 63 ++++++++++++++
 11 files changed, 591 insertions(+)
 create mode 100644 autotests/kf5_entry_data.cmake/locale/ca/kf5_entry.cmake
 create mode 100644 autotests/kf5_entry_data.cmake/locale/de/kf5_entry.cmake
 create mode 100644 autotests/kf5_entry_data.cmake/locale/en_US/kf5_entry.cmake
 create mode 100644 autotests/kf5_entry_data.cmake/locale/es/.keep
 create mode 100644 autotests/kf5_entry_data.cmake/locale/fr/kf5_entry.cmake
 create mode 100644 autotests/kf5_entry_data.cmake/locale/pt/kf5_entry.cmake
 create mode 100644 autotests/klanguagenametest.cpp
 create mode 100644 src/klanguagename.cpp
 create mode 100644 src/klanguagename.h

diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt
index 1917ecb..37caaf9 100644
--- a/autotests/CMakeLists.txt
+++ b/autotests/CMakeLists.txt
@@ -9,5 +9,32 @@ set(kconfigdialog_unittest_SRCS kconfigdialog_unittest.cpp)
 kconfig_add_kcfg_files(kconfigdialog_unittest_SRCS GENERATE_MOC signaltest.kcfgc)
 ecm_add_test(${kconfigdialog_unittest_SRCS} TEST_NAME "kconfigdialog_unittest" LINK_LIBRARIES Qt5::Test KF5::ConfigWidgets)
 
+set(lang_entries
+  ca
+  de
+  en_US
+  es # must not have file!
+  fr
+  pt
+)
+
+# scripty would mangle all *.desktop files, since that'd have potential of
+# breaking the test we'll need to bypass scripty by not having our files called
+# .desktop!
+# Do note that we pop these into CMAKE_LIBRARY_OUTPUT_DIRECTORY so QFINDTESTDATA
+# is able to find the fixtures in the bin dir as KDECMakeSettings sets a special
+# output dir.
+foreach(lang ${lang_entries})
+    set(src_dir "${CMAKE_CURRENT_SOURCE_DIR}/kf5_entry_data.cmake/locale/${lang}")
+    set(src_file "${src_dir}/kf5_entry.cmake")
+    set(bin_dir "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/kf5_entry_data/locale/${lang}")
+    set(bin_file "${bin_dir}/kf5_entry.desktop")
+    file(MAKE_DIRECTORY ${bin_dir})
+    if(EXISTS ${src_file}) # not all languages have entries
+        configure_file(${src_file} ${bin_file} COPYONLY)
+    endif()
+endforeach()
+
+ecm_add_test(klanguagenametest.cpp LINK_LIBRARIES Qt5::Test KF5::ConfigWidgets)
 
 ecm_add_test(krecentfilesactiontest.cpp TEST_NAME "krecentfilesaction_test" LINK_LIBRARIES Qt5::Test KF5::ConfigWidgets)
diff --git a/autotests/kf5_entry_data.cmake/locale/ca/kf5_entry.cmake b/autotests/kf5_entry_data.cmake/locale/ca/kf5_entry.cmake
new file mode 100644
index 0000000..a81564c
--- /dev/null
+++ b/autotests/kf5_entry_data.cmake/locale/ca/kf5_entry.cmake
@@ -0,0 +1,98 @@
+[KCM Locale]
+Name=Catalan
+Name[af]=Katelaans
+Name[ar]=الكاتالانيّة
+Name[as]=কাটালান
+Name[be]=Каталонская
+Name[be@latin]=Katalanskaja
+Name[bg]=Каталонски
+Name[bn]=ক্যাটালান
+Name[bn_IN]=ক্যাটালান
+Name[br]=Katalaneg
+Name[bs]=katalonski
+Name[ca]=Català
+Name[ca@valencia]=Català
+Name[cs]=Katalánský
+Name[csb]=Katalońsczi
+Name[cy]=Catalaneg
+Name[da]=Catalansk
+Name[de]=Katalanisch
+Name[el]=Καταλανικά
+Name[en_GB]=Catalan
+Name[eo]=Kataluna
+Name[es]=Catalán
+Name[et]=Katalaani
+Name[eu]=Katalaniera
+Name[fa]=کاتالان
+Name[fi]=Katalaani
+Name[fr]=Catalan
+Name[fy]=Katalaansk
+Name[ga]=Catalóinis
+Name[gd]=Catalanais
+Name[gl]=Catalán
+Name[gu]=કેટેલાન
+Name[he]=קטלונית
+Name[hi]=केटेलन
+Name[hne]=केटेलन
+Name[hr]=Katalonski
+Name[hsb]=Katalansce
+Name[hu]=Katalán
+Name[ia]=Catalan 
+Name[id]=Catalan
+Name[is]=Katalónska
+Name[it]=Catalano
+Name[ja]=カタロニア語
+Name[kk]=Каталанша
+Name[km]=កាតាឡាន
+Name[kn]=ಕ್ಯಾಟಲಾನ್
+Name[ko]=카탈루냐어
+Name[ku]=Katalan
+Name[lb]=Katalanesch
+Name[lt]=Katalonų
+Name[lv]=Kataloņu
+Name[mai]=केटालान
+Name[mk]=Каталонски
+Name[ml]=കറ്റാലന്‍
+Name[mr]=केटेलन
+Name[ms]=Catalan
+Name[nb]=Katalansk
+Name[nds]=Katalaansch
+Name[ne]=कातालान
+Name[nl]=Catalaans
+Name[nn]=Katalansk
+Name[oc]=Catalan
+Name[or]=କେଟାଲାନ
+Name[pa]=ਕਾਟਾਲਾਨ
+Name[pl]=Kataloński
+Name[ps]=کېټېلېن
+Name[pt]=Catalão
+Name[pt_BR]=Catalão
+Name[ro]=Catalană
+Name[ru]=Каталонский
+Name[se]=Katalánagiella
+Name[si]=කැටලන්
+Name[sk]=Katalánčina
+Name[sl]=Katalonščina
+Name[sq]=Katalanisht
+Name[sr]=каталонски
+Name[sr@ijekavian]=каталонски
+Name[sr@ijekavianlatin]=katalonski
+Name[sr@latin]=katalonski
+Name[sv]=Katalanska
+Name[ta]=கெடலான்
+Name[te]=కెటలన్
+Name[tg]=Каталанӣ
+Name[th]=ภาษาคาตาลัน
+Name[tr]=Katalanca
+Name[tt]=Каталон
+Name[ug]=كاتالانچە
+Name[uk]=Каталанська
+Name[uz]=Katalancha
+Name[uz@cyrillic]=Каталанча
+Name[vi]=Catalan
+Name[wa]=Catalan
+Name[xh]=Catalan
+Name[x-test]=xxCatalanxx
+Name[zh_CN]=加泰罗尼亚语
+Name[zh_HK]=加泰隆尼亞語
+Name[zh_TW]=加泰羅尼亞語
diff --git a/autotests/kf5_entry_data.cmake/locale/de/kf5_entry.cmake b/autotests/kf5_entry_data.cmake/locale/de/kf5_entry.cmake
new file mode 100644
index 0000000..e8146cb
--- /dev/null
+++ b/autotests/kf5_entry_data.cmake/locale/de/kf5_entry.cmake
@@ -0,0 +1,98 @@
+[KCM Locale]
+Name=German
+Name[af]=Duits
+Name[ar]=الألمانيّة
+Name[as]=জাৰ্মান
+Name[be]=Нямецкая
+Name[be@latin]=Niamieckaja
+Name[bg]=Немски
+Name[bn]=জার্মান
+Name[bn_IN]=জার্মান
+Name[br]=Alamaneg
+Name[bs]=njemački
+Name[ca]=Alemany
+Name[ca@valencia]=Alemany
+Name[cs]=Německý
+Name[csb]=Miemiecczi
+Name[cy]=Almaeneg
+Name[da]=Tysk
+Name[de]=Deutsch
+Name[el]=Γερμανικά
+Name[en_GB]=German
+Name[eo]=Germana
+Name[es]=Alemán
+Name[et]=Saksa
+Name[eu]=Alemana
+Name[fa]=آلمانی
+Name[fi]=Saksa
+Name[fr]=Allemand
+Name[fy]=Dútsk
+Name[ga]=Gearmáinis
+Name[gd]=Gearmailtis
+Name[gl]=Alemán
+Name[gu]=જર્મન
+Name[he]=גרמנית
+Name[hi]=जर्मन
+Name[hne]=जर्मन
+Name[hr]=Njemački
+Name[hsb]=Němsce
+Name[hu]=Német
+Name[ia]=Germano 
+Name[id]=Jerman
+Name[is]=Þýska
+Name[it]=Tedesco
+Name[ja]=ドイツ語
+Name[kk]=Немісше
+Name[km]=អាល្លឺម៉ង់
+Name[kn]=ಜರ್ಮನ್
+Name[ko]=독일어
+Name[ku]=Almanî
+Name[lb]=Däitsch
+Name[lt]=Vokiečių
+Name[lv]=Vācu
+Name[mai]=जर्मन
+Name[mk]=Германски
+Name[ml]=ജര്‍മ്മന്‍
+Name[mr]=जर्मन
+Name[ms]=Jerman
+Name[nb]=Tysk
+Name[nds]=Hoochdüütsch
+Name[ne]=जर्मनी
+Name[nl]=Duits
+Name[nn]=Tysk
+Name[oc]=Aleman
+Name[or]=ଜର୍ମାନ
+Name[pa]=ਜਰਮਨ
+Name[pl]=Niemiecki
+Name[ps]=جرمني
+Name[pt]=Alemão
+Name[pt_BR]=Alemão
+Name[ro]=Germană
+Name[ru]=Немецкий
+Name[se]=Duiskkagiella
+Name[si]=ජර්මානු
+Name[sk]=Nemčina
+Name[sl]=Nemščina
+Name[sq]=Gjermanisht
+Name[sr]=немачки
+Name[sr@ijekavian]=њемачки
+Name[sr@ijekavianlatin]=njemački
+Name[sr@latin]=nemački
+Name[sv]=Tyska
+Name[ta]=ஜெர்மன்
+Name[te]=జెర్మన్
+Name[tg]=Олмонӣ
+Name[th]=ภาษาเยอรมัน
+Name[tr]=Almanca
+Name[tt]=Алман
+Name[ug]=گېرمانچە
+Name[uk]=Німецька
+Name[uz]=Olmoncha
+Name[uz@cyrillic]=Олмонча
+Name[vi]=Đức
+Name[wa]=Almand
+Name[xh]=German
+Name[x-test]=xxGermanxx
+Name[zh_CN]=德语
+Name[zh_HK]=德語
+Name[zh_TW]=德語
diff --git a/autotests/kf5_entry_data.cmake/locale/en_US/kf5_entry.cmake b/autotests/kf5_entry_data.cmake/locale/en_US/kf5_entry.cmake
new file mode 100644
index 0000000..6033ad4
--- /dev/null
+++ b/autotests/kf5_entry_data.cmake/locale/en_US/kf5_entry.cmake
@@ -0,0 +1,44 @@
+[KCM Locale]
+Name=US English
+Name[ar]=الإنجليزية الأمريكية
+Name[bs]=Američki engleski
+Name[ca]=Anglès US
+Name[ca@valencia]=Anglés US
+Name[cs]=US Angličtina
+Name[da]=US Engelsk
+Name[de]=US-Englisch
+Name[el]=US English
+Name[en_GB]=US English
+Name[es]=Inglés de EE. UU.
+Name[et]=USA inglise
+Name[eu]=AEBtako ingelesa
+Name[fi]=Amerikanenglanti
+Name[fr]=Anglais (États-Unis)
+Name[gd]=Beurla (SA)
+Name[gl]=Inglés americano
+Name[he]=אנגלית ארה"ב
+Name[hu]=Angol (amerikai)
+Name[ia]=Anglese de S.U.A.
+Name[id]=Inggris US
+Name[it]=Inglese US
+Name[ko]=미국 영어
+Name[lt]=JAV anglų
+Name[nb]=Engelsk (USA)
+Name[nl]=VS Engels
+Name[nn]=Engelsk (USA)
+Name[pl]=Angielski amerykański
+Name[pt]=Inglês dos EUA
+Name[pt_BR]=Inglês dos EUA
+Name[ru]=Английский (США)
+Name[sk]=Americká angličtina
+Name[sl]=ameriško angleško
+Name[sr]=амерички енглески
+Name[sr@ijekavian]=амерички енглески
+Name[sr@ijekavianlatin]=američki engleski
+Name[sr@latin]=američki engleski
+Name[sv]=Amerikansk engelska
+Name[tr]=ABD İngilizcesi
+Name[uk]=Англійська (США)
+Name[x-test]=xxUS Englishxx
+Name[zh_CN]=美国英语
+Name[zh_TW]=美式英文
diff --git a/autotests/kf5_entry_data.cmake/locale/es/.keep b/autotests/kf5_entry_data.cmake/locale/es/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/autotests/kf5_entry_data.cmake/locale/fr/kf5_entry.cmake b/autotests/kf5_entry_data.cmake/locale/fr/kf5_entry.cmake
new file mode 100644
index 0000000..4f248b9
--- /dev/null
+++ b/autotests/kf5_entry_data.cmake/locale/fr/kf5_entry.cmake
@@ -0,0 +1,2 @@
+[KCM Locale]
+Name=French
diff --git a/autotests/kf5_entry_data.cmake/locale/pt/kf5_entry.cmake b/autotests/kf5_entry_data.cmake/locale/pt/kf5_entry.cmake
new file mode 100644
index 0000000..6e555d0
--- /dev/null
+++ b/autotests/kf5_entry_data.cmake/locale/pt/kf5_entry.cmake
@@ -0,0 +1,98 @@
+[KCM Locale]
+Name=Portuguese
+Name[af]=Portugese
+Name[ar]=البرتغاليّة
+Name[as]=প'ৰ্টুগিছ্‌
+Name[be]=Партугальская
+Name[be@latin]=Partuhalskaja
+Name[bg]=Португалски
+Name[bn]=পর্তুগীজ
+Name[bn_IN]=পোর্তুগিজ
+Name[br]=Portugaleg
+Name[bs]=portugalski
+Name[ca]=Portuguès
+Name[ca@valencia]=Portugués
+Name[cs]=Portugalský
+Name[csb]=Pòrtugalsczi
+Name[cy]=Portiwgaleg
+Name[da]=Portugisisk
+Name[de]=Portugiesisch
+Name[el]=Πορτογαλικά
+Name[en_GB]=Portuguese
+Name[eo]=Portugala
+Name[es]=Portugués
+Name[et]=Portugali
+Name[eu]=Portugesa
+Name[fa]=پرتغالی
+Name[fi]=Portugali
+Name[fr]=Portugais
+Name[fy]=Portugeesk
+Name[ga]=Portaingéilis
+Name[gd]=Portagailis
+Name[gl]=Portugués
+Name[gu]=પોર્ટુગીઝ
+Name[he]=פורטוגזית
+Name[hi]=पुर्तगाली
+Name[hne]=पुर्तगाली
+Name[hr]=Portugalski
+Name[hsb]=Portugalsce
+Name[hu]=Portugál
+Name[ia]=Portugese 
+Name[id]=Portugis
+Name[is]=Portúgalska
+Name[it]=Portoghese
+Name[ja]=ポルトガル語
+Name[kk]=Португалша
+Name[km]=ព័រទុយហ្គាល់
+Name[kn]=ಪೋರ್ಚುಗೀಸ್
+Name[ko]=포르투갈어
+Name[ku]=Portûgalî
+Name[lb]=Portugisesch
+Name[lt]=Portugalų
+Name[lv]=Portugāļu
+Name[mai]=पुर्तगाली
+Name[mk]=Португалски
+Name[ml]=പോര്‍ച്ചുഗീസ്
+Name[mr]=पोर्तुगीज
+Name[ms]=Portugis
+Name[nb]=Portugisisk
+Name[nds]=Portugeesch
+Name[ne]=पोर्तुगाली
+Name[nl]=Portugees
+Name[nn]=Portugisisk
+Name[oc]=Portugués
+Name[or]=ପର୍ତ୍ତୁଗିଜ
+Name[pa]=ਪੁਰਤਗਾਲੀ
+Name[pl]=Portugalski
+Name[ps]=پورټګيز
+Name[pt]=Português
+Name[pt_BR]=Português
+Name[ro]=Portugheză
+Name[ru]=Португальский
+Name[se]=Portugálagiella
+Name[si]=පෘතුගීසි
+Name[sk]=Portugalčina
+Name[sl]=Portugalščina
+Name[sq]=Portugalisht
+Name[sr]=португалски
+Name[sr@ijekavian]=португалски
+Name[sr@ijekavianlatin]=portugalski
+Name[sr@latin]=portugalski
+Name[sv]=Portugisiska
+Name[ta]=போர்த்துக்கீசிய
+Name[te]=పొర్ట్యుగీస్
+Name[tg]=Португалӣ
+Name[th]=ภาษาโปรตุเกส
+Name[tr]=Portekizce
+Name[tt]=Португал
+Name[ug]=پورتۇگالچە
+Name[uk]=Португальська
+Name[uz]=Portugalcha
+Name[uz@cyrillic]=Португалча
+Name[vi]=Bồ Đào Nha
+Name[wa]=Portuguès
+Name[xh]=Portuguese
+Name[x-test]=xxPortuguesexx
+Name[zh_CN]=葡萄牙语
+Name[zh_HK]=葡萄牙語
+Name[zh_TW]=葡萄牙語
diff --git a/autotests/klanguagenametest.cpp b/autotests/klanguagenametest.cpp
new file mode 100644
index 0000000..bb2b3d9
--- /dev/null
+++ b/autotests/klanguagenametest.cpp
@@ -0,0 +1,96 @@
+/*
+    Copyright (c) 2018 Harald Sitter <sitter@kde.org>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) version 3, or any
+    later version accepted by the membership of KDE e.V. (or its
+    successor approved by the membership of KDE e.V.), which shall
+    act as a proxy defined in Section 6 of version 3 of the license.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <QObject>
+#include <QtTest>
+
+#include "klanguagename.h"
+
+static void setEnvironment()
+{
+    qputenv("LANG", "C.UTF-8");
+    qputenv("LANGUAGE", "en");
+    qputenv("XDG_DATA_DIRS", qUtf8Printable(QFINDTESTDATA("kf5_entry_data")));
+    // There is a distinct chance of the envionrment setup being to late and
+    // causing flakey results based on the execution env.
+    // Make sure we definitely default to english.
+    QLocale::setDefault(QLocale::English);
+
+    // NOTE
+    // - fr has no translations
+    // - es has no kf5_entry at all
+    // - other languages under testing are complete
+}
+
+class KLanguageNameTest : public QObject
+{
+    Q_OBJECT
+
+private Q_SLOTS:
+    void testNameForCode()
+    {
+        // This is somewhat wrong, it should not say US.
+        QCOMPARE(KLanguageName::nameForCode("en"), QString("US English"));
+
+        QCOMPARE(KLanguageName::nameForCode("de"), QString("German"));
+        QCOMPARE(KLanguageName::nameForCode("pt"), QString("Portuguese"));
+        QCOMPARE(KLanguageName::nameForCode("ca"), QString("Catalan"));
+    }
+
+    void testNameForCodeInLocale()
+    {
+        // This is somewhat wrong, it should not say US.
+        QCOMPARE(KLanguageName::nameForCodeInLocale("en", "de"), QString("US-Englisch"));
+
+        QCOMPARE(KLanguageName::nameForCodeInLocale("de", "de"), QString("Deutsch"));
+        QCOMPARE(KLanguageName::nameForCodeInLocale("pt", "de"), QString("Portugiesisch"));
+        QCOMPARE(KLanguageName::nameForCodeInLocale("ca", "de"), QString("Katalanisch"));
+    }
+
+    void testNoTranslation()
+    {
+        // This has an entry file but no translation => QLocale.
+        QCOMPARE(KLanguageName::nameForCode("fr"), QString("French"));
+        QCOMPARE(KLanguageName::nameForCodeInLocale("fr", "de"), QString("French"));
+        // When in the same language, use the native name.
+        QCOMPARE(KLanguageName::nameForCodeInLocale("fr", "fr"), QString("français"));
+    }
+
+    void testNoEntry()
+    {
+        // This has no entry file => QLocale.
+        QCOMPARE(KLanguageName::nameForCode("es"), QString("Spanish"));
+        QCOMPARE(KLanguageName::nameForCodeInLocale("es", "de"), QString("Spanish"));
+        // When in the same language, use the native name.
+        QCOMPARE(KLanguageName::nameForCodeInLocale("es", "es"), QString("español de España"));
+    }
+
+    void testNoString()
+    {
+        // Qt doesn't have za support, we have no test fixture, so no string.
+        QCOMPARE(KLanguageName::nameForCode("za"), QString());
+    }
+};
+
+Q_COREAPP_STARTUP_FUNCTION(setEnvironment)
+
+QTEST_GUILESS_MAIN(KLanguageNameTest)
+
+#include "klanguagenametest.moc"
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a35cf3c..09fe50b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -8,6 +8,7 @@ set(kconfigwidgets_SRCS
   kcmodule.cpp
   khelpclient.cpp
   klanguagebutton.cpp
+  klanguagename.cpp
   kpastetextaction.cpp
   krecentfilesaction.cpp
   kstandardaction.cpp
@@ -52,6 +53,7 @@ ecm_generate_headers(KConfigWidgets_HEADERS
   KCModule
   KHelpClient
   KLanguageButton
+  KLanguageName
   KPasteTextAction
   KRecentFilesAction
   KViewStateMaintainer
diff --git a/src/klanguagename.cpp b/src/klanguagename.cpp
new file mode 100644
index 0000000..6e1a519
--- /dev/null
+++ b/src/klanguagename.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1999-2003 Hans Petter Bieker <bieker@kde.org>
+ *           (c) 2007      David Jarvie <software@astrojar.org.uk>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ */
+
+#include "klanguagename.h"
+#include "kconfigwidgets_debug.h"
+
+#include <kconfig.h>
+#include <kconfiggroup.h>
+
+QString KLanguageName::nameForCode(const QString &code)
+{
+    const QStringList parts = QLocale().name().split(QChar('_'));
+    return nameForCodeInLocale(code, parts.at(0));
+}
+
+QString KLanguageName::nameForCodeInLocale(const QString &code, const QString &outputCode)
+{
+    const QString realCode = code == QStringLiteral("en") ? QStringLiteral("en_US") : code;
+    const QString realOutputCode = outputCode == QStringLiteral("en") ? QStringLiteral("en_US") : outputCode;
+
+    const QString entryFile =
+            QStandardPaths::locate(QStandardPaths::GenericDataLocation,
+                                   QStringLiteral("locale") + QLatin1Char('/') + realCode + QStringLiteral("/kf5_entry.desktop"));
+    if (!entryFile.isEmpty()) {
+        KConfig entry(entryFile, KConfig::SimpleConfig);
+        entry.setLocale(realOutputCode);
+        const KConfigGroup group(&entry, "KCM Locale");
+        const QString name = group.readEntry("Name");
+
+        // KConfig doesn't have a way to say it didn't find the entry in
+        // realOutputCode and returned the english version so we check for the
+        // english version, if it's equal to the "non-english" version we'll use
+        // otherwise we defer to QLocale.
+        entry.setLocale("en_US");
+        const QString englishName = group.readEntry("Name");
+        if (name != englishName || realOutputCode == QStringLiteral("en_US")) {
+            return name;
+        }
+    }
+
+    const QLocale locale(realCode);
+    if (locale != QLocale::c()) {
+        if (realCode == realOutputCode) {
+            return locale.nativeLanguageName();
+        }
+        return QLocale::languageToString(locale.language());
+    }
+
+    return QString();
+}
diff --git a/src/klanguagename.h b/src/klanguagename.h
new file mode 100644
index 0000000..51dc6dd
--- /dev/null
+++ b/src/klanguagename.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1999-2003 Hans Petter Bieker <bieker@kde.org>
+ *           (c) 2001      Martijn Klingens <klingens@kde.org>
+ *           (c) 2007      David Jarvie <software@astrojar.org.uk>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Library General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this library; see the file COPYING.LIB.  If not, write to
+ *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ */
+
+#ifndef KLANGUAGENAME_H
+#define KLANGUAGENAME_H
+
+#include "kconfigwidgets_export.h"
+
+class QString;
+
+/**
+ * @class KLanguageName klanguagename.h KLanguageName
+ *
+ * KLanguageName is a helper namespace that returns the name of a given language code.
+ *
+ * @since 5.55
+ *
+ */
+namespace KLanguageName
+{
+    /**
+     * Returns the name of the given language code in the current locale.
+     *
+     * If it can't be found in the current locale it returns the name in English.
+     *
+     * It it can't be found in English either it returns an empty QString.
+     *
+     * @param code code (ISO 639-1) of the language whose name is wanted.
+     */
+    KCONFIGWIDGETS_EXPORT QString nameForCode(const QString &code);
+
+    /**
+     * Returns the name of the given language code in the other given locale code.
+     *
+     * If it can't be found in the given locale it returns the name in English.
+     *
+     * It it can't be found in English either it returns an empty QString.
+     *
+     * @param code code (ISO 639-1) of the language whose name is wanted.
+     * @param outputLocale code (ISO 639-1) of the language in which we want the name in.
+     */
+    KCONFIGWIDGETS_EXPORT QString nameForCodeInLocale(const QString &code, const QString &outputLocale);
+}
+
+#endif
-- 
cgit v1.1