diff options
-rw-r--r-- | autotests/kdesktopfiletest.cpp | 37 | ||||
-rw-r--r-- | autotests/kdesktopfiletest.h | 1 | ||||
-rw-r--r-- | src/core/kconfig.cpp | 2 | ||||
-rw-r--r-- | src/core/kconfigdata.cpp | 13 | ||||
-rw-r--r-- | src/core/kconfigdata.h | 9 | ||||
-rw-r--r-- | src/core/kconfigini.cpp | 7 |
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 ¤tLocale, 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 ¤tLocale, 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 ¤tLocale, KEntryMap &entry } if (!locale.isNull()) { entryOptions |= KEntryMap::EntryLocalized; + if (locale.indexOf('_') != -1) { + entryOptions |= KEntryMap::EntryLocalizedCountry; + } } printableToString(&line, file, lineNo); if (entryOptions & KEntryMap::EntryRawKey) { |