aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autotests/kdesktopfiletest.cpp37
-rw-r--r--autotests/kdesktopfiletest.h1
-rw-r--r--src/core/kconfig.cpp2
-rw-r--r--src/core/kconfigdata.cpp13
-rw-r--r--src/core/kconfigdata.h9
-rw-r--r--src/core/kconfigini.cpp7
6 files changed, 59 insertions, 10 deletions
diff --git a/autotests/kdesktopfiletest.cpp b/autotests/kdesktopfiletest.cpp
index 6c3af4c2..12277331 100644
--- a/autotests/kdesktopfiletest.cpp
+++ b/autotests/kdesktopfiletest.cpp
@@ -50,6 +50,29 @@ void KDesktopFileTest::testRead()
QCOMPARE(df.fileName(), QFileInfo(fileName).canonicalFilePath());
}
+void KDesktopFileTest::testReadLocalized_data()
+{
+ QTest::addColumn<QLocale>("locale");
+ QTest::addColumn<QString>("translation");
+
+ const QString german = QStringLiteral("Meine Anwendung");
+ const QString swiss = QStringLiteral("Mein Anwendungsli");
+
+ QTest::newRow("de") << QLocale(QLocale::German) << german;
+ QTest::newRow("de_DE") << QLocale(QStringLiteral("de_DE")) << german;
+ QTest::newRow("de_DE@bayern") << QLocale(QStringLiteral("de_DE@bayern")) << german;
+ QTest::newRow("de@bayern") << QLocale(QStringLiteral("de@bayern")) << german;
+ QTest::newRow("de@freiburg") << QLocale(QStringLiteral("de@freiburg")) << QStringLiteral("Mein Anwendungsle");
+ // For CH we have a special translation
+ QTest::newRow("de_CH") << QLocale(QLocale::German, QLocale::Switzerland) << swiss;
+ QTest::newRow("de_CH@bern") << QLocale(QStringLiteral("de_CH@bern")) << swiss;
+ // Austria should fall back to "de"
+ QTest::newRow("de_AT") << QLocale(QLocale::German, QLocale::QLocale::Austria) << german;
+ QTest::newRow("de_AT@tirol") << QLocale(QStringLiteral("de_AT@tirol")) << german;
+ // no translation for French
+ QTest::newRow("fr") << QLocale(QLocale::French) << QStringLiteral("My Application");
+}
+
void KDesktopFileTest::testReadLocalized()
{
QTemporaryFile file("testReadLocalizedXXXXXX.desktop");
@@ -61,6 +84,8 @@ void KDesktopFileTest::testReadLocalized()
"Type=Application\n"
"Name=My Application\n"
"Name[de]=Meine Anwendung\n"
+ "Name[de@freiburg]=Mein Anwendungsle\n"
+ "Name[de_CH]=Mein Anwendungsli\n"
"Icon=foo\n"
"\n";
file.close();
@@ -68,15 +93,13 @@ void KDesktopFileTest::testReadLocalized()
QVERIFY(KDesktopFile::isDesktopFile(fileName));
DefaultLocale defaultLocale;
- // set language to German for which we have a translation
- QLocale::setDefault(QLocale(QLocale::German));
+
+ QFETCH(QLocale, locale);
+ QLocale::setDefault(locale);
KDesktopFile df(fileName);
- QCOMPARE(df.readName(), QString::fromLatin1("Meine Anwendung"));
- // set language to French for which we don't have a translation
- QLocale::setDefault(QLocale(QLocale::French));
- KDesktopFile df2(fileName);
- QCOMPARE(df2.readName(), QString::fromLatin1("My Application"));
+ QEXPECT_FAIL("de@freiburg", "QLocale doesn't support modifiers", Continue);
+ QTEST(df.readName(), "translation");
}
void KDesktopFileTest::testSuccessfulTryExec()
diff --git a/autotests/kdesktopfiletest.h b/autotests/kdesktopfiletest.h
index f854d6cc..f4e0c96b 100644
--- a/autotests/kdesktopfiletest.h
+++ b/autotests/kdesktopfiletest.h
@@ -26,6 +26,7 @@ class KDesktopFileTest : public QObject
Q_OBJECT
private Q_SLOTS:
void testRead();
+ void testReadLocalized_data();
void testReadLocalized();
void testUnsuccessfulTryExec();
void testSuccessfulTryExec();
diff --git a/src/core/kconfig.cpp b/src/core/kconfig.cpp
index b9319994..484a9a97 100644
--- a/src/core/kconfig.cpp
+++ b/src/core/kconfig.cpp
@@ -95,7 +95,7 @@ KConfigPrivate::KConfigPrivate(KConfig::OpenFlags flags,
// mappingsRegistered = true;
// }
- setLocale(QLocale().name().split(QStringLiteral("_")).at(0));
+ setLocale(QLocale().name());
}
bool KConfigPrivate::lockLocal()
diff --git a/src/core/kconfigdata.cpp b/src/core/kconfigdata.cpp
index 109063d6..6ef6af07 100644
--- a/src/core/kconfigdata.cpp
+++ b/src/core/kconfigdata.cpp
@@ -145,6 +145,11 @@ bool KEntryMap::setEntry(const QByteArray &group, const QByteArray &key, const Q
}
e.bExpand = (options & EntryExpansion);
e.bReverted = false;
+ if (options & EntryLocalized) {
+ e.bLocalizedCountry = (options & EntryLocalizedCountry);
+ } else {
+ e.bLocalizedCountry = false;
+ }
if (newKey) {
//qDebug() << "inserting" << k << "=" << value;
@@ -158,6 +163,14 @@ bool KEntryMap::setEntry(const QByteArray &group, const QByteArray &key, const Q
return true;
} else {
// KEntry e2 = it.value();
+ if (options & EntryLocalized) {
+ // fast exit checks for cases where the existing entry is more specific
+ const KEntry &e2 = it.value();
+ if (e2.bLocalizedCountry && !e.bLocalizedCountry) {
+ // lang_COUNTRY > lang
+ return false;
+ }
+ }
if (it.value() != e) {
//qDebug() << "changing" << k << "from" << e.mValue << "to" << value;
it.value() = e;
diff --git a/src/core/kconfigdata.h b/src/core/kconfigdata.h
index fdec85dc..3b70c24f 100644
--- a/src/core/kconfigdata.h
+++ b/src/core/kconfigdata.h
@@ -36,7 +36,8 @@ struct KEntry {
/** Constructor. @internal */
KEntry()
: mValue(), bDirty(false),
- bGlobal(false), bImmutable(false), bDeleted(false), bExpand(false), bReverted(false) {}
+ bGlobal(false), bImmutable(false), bDeleted(false), bExpand(false), bReverted(false),
+ bLocalizedCountry(false) {}
/** @internal */
QByteArray mValue;
/**
@@ -63,6 +64,11 @@ struct KEntry {
* Entry has been reverted to its default value (from a more global file).
*/
bool bReverted: 1;
+ /**
+ * Entry is for a localized key. If @c false the value references just language e.g. "de",
+ * if @c true the value references language and country, e.g. "de_DE".
+ **/
+ bool bLocalizedCountry: 1;
};
// These operators are used to check whether an entry which is about
@@ -165,6 +171,7 @@ public:
EntryDeleted = 8,
EntryExpansion = 16,
EntryRawKey = 32,
+ EntryLocalizedCountry = 64,
EntryDefault = (SearchDefaults << 16),
EntryLocalized = (SearchLocalized << 16)
};
diff --git a/src/core/kconfigini.cpp b/src/core/kconfigini.cpp
index f4ce9410..5fe4de03 100644
--- a/src/core/kconfigini.cpp
+++ b/src/core/kconfigini.cpp
@@ -85,6 +85,8 @@ KConfigIniBackend::parseConfig(const QByteArray &currentLocale, KEntryMap &entry
return ParseOk;
}
+ const QByteArray currentLanguage = currentLocale.split('_').first();
+
bool bDefault = options & ParseDefaults;
bool allowExecutableValues = options & ParseExpansions;
@@ -251,7 +253,7 @@ KConfigIniBackend::parseConfig(const QByteArray &currentLocale, KEntryMap &entry
}
printableToString(&aKey, file, lineNo);
if (!locale.isEmpty()) {
- if (locale != currentLocale) {
+ if (locale != currentLocale && locale != currentLanguage) {
// backward compatibility. C == en_US
if (locale.at(0) != 'C' || currentLocale != "en_US") {
if (merging) {
@@ -275,6 +277,9 @@ KConfigIniBackend::parseConfig(const QByteArray &currentLocale, KEntryMap &entry
}
if (!locale.isNull()) {
entryOptions |= KEntryMap::EntryLocalized;
+ if (locale.indexOf('_') != -1) {
+ entryOptions |= KEntryMap::EntryLocalizedCountry;
+ }
}
printableToString(&line, file, lineNo);
if (entryOptions & KEntryMap::EntryRawKey) {