From 9146432dc66d41f22548bbb425b61458d241d28e Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 5 Jul 2018 17:12:18 +0200 Subject: Allow loading of empty translation files Do not return false for loading an empty .qm file - that is, a valid file without any translations. We're already shipping empty .qm files for English translations of Qt since a while, mainly as a stop for the QTranslator::load(const QLocale &, ...) logic. Note that QCoreApplication::installTranslator() will still return false for an empty translation file - which is ok, because it arguably does not make much sense to install it. [ChangeLog][QtCore][QTranslator] It is now possible to load qm files without any translations. This is particularly useful for the language the untranslated strings are written in; logic to load translations can now handle the source language like all other languages. Task-number: QTBUG-31031 Change-Id: Ibcb84aa755538cb2fa21b14f8635295a58440bbb Reviewed-by: Oswald Buddenhagen --- src/corelib/kernel/qtranslator.cpp | 10 ++-- .../kernel/qtranslator/android_testdata.qrc | 1 + .../corelib/kernel/qtranslator/hellotr_empty.qm | 1 + .../corelib/kernel/qtranslator/hellotr_empty.ts | 3 ++ .../corelib/kernel/qtranslator/qtranslator.pro | 2 +- .../corelib/kernel/qtranslator/qtranslator.qrc | 1 + .../corelib/kernel/qtranslator/tst_qtranslator.cpp | 58 +++++++++++++--------- 7 files changed, 46 insertions(+), 30 deletions(-) create mode 100644 tests/auto/corelib/kernel/qtranslator/hellotr_empty.qm create mode 100644 tests/auto/corelib/kernel/qtranslator/hellotr_empty.ts diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 23985eb2e9..744bbfbff5 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -533,7 +533,7 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo // memory, so no need to use QFile to copy it again. Q_ASSERT(!d->resource); d->resource = new QResource(realname); - if (resource->isValid() && !resource->isCompressed() && resource->size() > MagicLength + if (resource->isValid() && !resource->isCompressed() && resource->size() >= MagicLength && !memcmp(resource->data(), magic, MagicLength)) { d->unmapLength = resource->size(); d->unmapPointer = reinterpret_cast(const_cast(resource->data())); @@ -553,7 +553,7 @@ bool QTranslatorPrivate::do_load(const QString &realname, const QString &directo return false; qint64 fileSize = file.size(); - if (fileSize <= MagicLength || quint32(-1) <= fileSize) + if (fileSize < MagicLength || quint32(-1) <= fileSize) return false; { @@ -858,8 +858,6 @@ bool QTranslatorPrivate::do_load(const uchar *data, int len, const QString &dire data += blockLen; } - if (dependencies.isEmpty() && (!offsetArray || !messageArray)) - ok = false; if (ok && !isValidNumerusRules(numerusRulesArray, numerusRulesLength)) ok = false; if (ok) { @@ -1138,8 +1136,8 @@ QString QTranslator::translate(const char *context, const char *sourceText, cons bool QTranslator::isEmpty() const { Q_D(const QTranslator); - return !d->unmapPointer && !d->unmapLength && !d->messageArray && - !d->offsetArray && !d->contextArray && d->subTranslators.isEmpty(); + return !d->messageArray && !d->offsetArray && !d->contextArray + && d->subTranslators.isEmpty(); } QT_END_NAMESPACE diff --git a/tests/auto/corelib/kernel/qtranslator/android_testdata.qrc b/tests/auto/corelib/kernel/qtranslator/android_testdata.qrc index b33995ef21..39b85db664 100644 --- a/tests/auto/corelib/kernel/qtranslator/android_testdata.qrc +++ b/tests/auto/corelib/kernel/qtranslator/android_testdata.qrc @@ -1,6 +1,7 @@ hellotr_la.qm + hellotr_empty.qm msgfmt_from_po.qm dependencies_la.qm diff --git a/tests/auto/corelib/kernel/qtranslator/hellotr_empty.qm b/tests/auto/corelib/kernel/qtranslator/hellotr_empty.qm new file mode 100644 index 0000000000..be651eede2 --- /dev/null +++ b/tests/auto/corelib/kernel/qtranslator/hellotr_empty.qm @@ -0,0 +1 @@ +<¸dÊÍ!¿`¡½Ý \ No newline at end of file diff --git a/tests/auto/corelib/kernel/qtranslator/hellotr_empty.ts b/tests/auto/corelib/kernel/qtranslator/hellotr_empty.ts new file mode 100644 index 0000000000..85e0d3992b --- /dev/null +++ b/tests/auto/corelib/kernel/qtranslator/hellotr_empty.ts @@ -0,0 +1,3 @@ + + + diff --git a/tests/auto/corelib/kernel/qtranslator/qtranslator.pro b/tests/auto/corelib/kernel/qtranslator/qtranslator.pro index d8924c2d5f..a985f35a14 100644 --- a/tests/auto/corelib/kernel/qtranslator/qtranslator.pro +++ b/tests/auto/corelib/kernel/qtranslator/qtranslator.pro @@ -5,5 +5,5 @@ SOURCES = tst_qtranslator.cpp RESOURCES += qtranslator.qrc android:!android-embedded: RESOURCES += android_testdata.qrc -else: TESTDATA += dependencies_la.qm hellotr_la.qm msgfmt_from_po.qm +else: TESTDATA += dependencies_la.qm hellotr_empty.qm hellotr_la.qm msgfmt_from_po.qm diff --git a/tests/auto/corelib/kernel/qtranslator/qtranslator.qrc b/tests/auto/corelib/kernel/qtranslator/qtranslator.qrc index 333dcfaa21..cb82c6cc95 100644 --- a/tests/auto/corelib/kernel/qtranslator/qtranslator.qrc +++ b/tests/auto/corelib/kernel/qtranslator/qtranslator.qrc @@ -1,5 +1,6 @@ hellotr_la.qm + hellotr_empty.qm diff --git a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp index 451f96339e..40a29c723c 100644 --- a/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp +++ b/tests/auto/corelib/kernel/qtranslator/tst_qtranslator.cpp @@ -41,13 +41,12 @@ protected: private slots: void initTestCase(); + void load_data(); void load(); - void load2(); void threadLoad(); void testLanguageChange(); void plural(); void translate_qm_file_generated_with_msgfmt(); - void loadFromResource(); void loadDirectory(); void dependencies(); void translationInThreadWhileInstallingTranslator(); @@ -106,24 +105,45 @@ bool tst_QTranslator::eventFilter(QObject *, QEvent *event) return false; } -void tst_QTranslator::load() +void tst_QTranslator::load_data() { + QTest::addColumn("filepath"); + QTest::addColumn("isEmpty"); + QTest::addColumn("translation"); - QTranslator tor( 0 ); - tor.load("hellotr_la"); - QVERIFY(!tor.isEmpty()); - QCOMPARE(tor.translate("QPushButton", "Hello world!"), QLatin1String("Hallo Welt!")); + QTest::newRow("hellotr_la") << "hellotr_la.qm" << false << "Hallo Welt!"; + QTest::newRow("hellotr_empty") << "hellotr_empty.qm" << true << ""; } -void tst_QTranslator::load2() +void tst_QTranslator::load() { - QTranslator tor( 0 ); - QFile file("hellotr_la.qm"); - file.open(QFile::ReadOnly); - QByteArray data = file.readAll(); - tor.load((const uchar *)data.constData(), data.length()); - QVERIFY(!tor.isEmpty()); - QCOMPARE(tor.translate("QPushButton", "Hello world!"), QLatin1String("Hallo Welt!")); + QFETCH(QString, filepath); + QFETCH(bool, isEmpty); + QFETCH(QString, translation); + + { + QTranslator tor; + QVERIFY(tor.load(QFileInfo(filepath).baseName())); + QCOMPARE(tor.isEmpty(), isEmpty); + QCOMPARE(tor.translate("QPushButton", "Hello world!"), translation); + } + + { + QFile file(filepath); + file.open(QFile::ReadOnly); + QByteArray data = file.readAll(); + QTranslator tor; + QVERIFY(tor.load((const uchar *)data.constData(), data.length())); + QCOMPARE(tor.isEmpty(), isEmpty); + QCOMPARE(tor.translate("QPushButton", "Hello world!"), translation); + } + + { + QTranslator tor; + QVERIFY(tor.load(QString(":/tst_qtranslator/%1").arg(filepath))); + QCOMPARE(tor.isEmpty(), isEmpty); + QCOMPARE(tor.translate("QPushButton", "Hello world!"), translation); + } } class TranslatorThread : public QThread @@ -240,14 +260,6 @@ void tst_QTranslator::translate_qm_file_generated_with_msgfmt() qApp->removeTranslator(&translator); } -void tst_QTranslator::loadFromResource() -{ - QTranslator tor; - tor.load(":/tst_qtranslator/hellotr_la.qm"); - QVERIFY(!tor.isEmpty()); - QCOMPARE(tor.translate("QPushButton", "Hello world!"), QLatin1String("Hallo Welt!")); -} - void tst_QTranslator::loadDirectory() { QString current_base = QDir::current().dirName(); -- cgit v1.2.3