diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -9,5 +9,32 @@ 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 --- /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 --- /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 --- /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 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 --- /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 --- /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 --- /dev/null +++ b/autotests/klanguagenametest.cpp @@ -0,0 +1,92 @@ +/* + Copyright (c) 2018 Harald Sitter + + 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 . +*/ + +#include +#include + +#include "klanguagename.h" + +static void setEnvironment() +{ + qputenv("LOCALE", "C.UTF-8"); + qputenv("LANG", "en"); + qputenv("XDG_DATA_DIRS", qUtf8Printable(QFINDTESTDATA("kf5_entry_data"))); + + // 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"), "US English"); + + QCOMPARE(KLanguageName::nameForCode("de"), "German"); + QCOMPARE(KLanguageName::nameForCode("pt"), "Portuguese"); + QCOMPARE(KLanguageName::nameForCode("ca"), "Catalan"); + } + + void testNameForCodeInLocale() + { + // This is somewhat wrong, it should not say US. + QCOMPARE(KLanguageName::nameForCodeInLocale("en", "de"), "US-Englisch"); + + QCOMPARE(KLanguageName::nameForCodeInLocale("de", "de"), "Deutsch"); + QCOMPARE(KLanguageName::nameForCodeInLocale("pt", "de"), "Portugiesisch"); + QCOMPARE(KLanguageName::nameForCodeInLocale("ca", "de"), "Katalanisch"); + } + + void testNoTranslation() + { + // This has an entry file but no translation => QLocale. + QCOMPARE(KLanguageName::nameForCode("fr"), "French"); + QCOMPARE(KLanguageName::nameForCodeInLocale("fr", "de"), "French"); + // When in the same language, use the native name. + QCOMPARE(KLanguageName::nameForCodeInLocale("fr", "fr"), "français"); + } + + void testNoEntry() + { + // This has no entry file => QLocale. + QCOMPARE(KLanguageName::nameForCode("es"), "Spanish"); + QCOMPARE(KLanguageName::nameForCodeInLocale("es", "de"), "Spanish"); + // When in the same language, use the native name. + QCOMPARE(KLanguageName::nameForCodeInLocale("es", "es"), "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 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,7 @@ kcmodule.cpp khelpclient.cpp klanguagebutton.cpp + klanguagename.cpp kpastetextaction.cpp krecentfilesaction.cpp kstandardaction.cpp @@ -52,6 +53,7 @@ KCModule KHelpClient KLanguageButton + KLanguageName KPasteTextAction KRecentFilesAction KViewStateMaintainer diff --git a/src/klanguagename.h b/src/klanguagename.h new file mode 100644 --- /dev/null +++ b/src/klanguagename.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 1999-2003 Hans Petter Bieker + * (c) 2001 Martijn Klingens + * (c) 2007 David Jarvie + * + * 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 diff --git a/src/klanguagename.cpp b/src/klanguagename.cpp new file mode 100644 --- /dev/null +++ b/src/klanguagename.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 1999-2003 Hans Petter Bieker + * (c) 2007 David Jarvie + * + * 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 +#include + +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(); +}