From 009c480413910e8c1a18f4d1420f4a517ea606e6 Mon Sep 17 00:00:00 2001 From: Alex Merry Date: Wed, 14 Oct 2015 12:18:40 +0100 Subject: Make sure we load translations on the main thread. BUG: 346188 REVIEW: 123726 --- modules/ECMQmLoader.cpp.in | 90 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 63 insertions(+), 27 deletions(-) (limited to 'modules/ECMQmLoader.cpp.in') diff --git a/modules/ECMQmLoader.cpp.in b/modules/ECMQmLoader.cpp.in index bc01bf98..f6b98e7b 100644 --- a/modules/ECMQmLoader.cpp.in +++ b/modules/ECMQmLoader.cpp.in @@ -5,41 +5,77 @@ */ #include #include +#include #include +#include #include -#include +namespace { -static bool loadTranslation(const QString &localeDirName) -{ - QString subPath = QStringLiteral("locale/") + localeDirName + QStringLiteral("/LC_MESSAGES/@catalog_name@.qm"); - QString fullPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, subPath); - if (fullPath.isEmpty()) { - return false; + bool loadTranslation(const QString &localeDirName) + { + QString subPath = QStringLiteral("locale/") + localeDirName + QStringLiteral("/LC_MESSAGES/@catalog_name@.qm"); + QString fullPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, subPath); + if (fullPath.isEmpty()) { + return false; + } + QTranslator *translator = new QTranslator(QCoreApplication::instance()); + if (!translator->load(fullPath)) { + delete translator; + return false; + } + QCoreApplication::instance()->installTranslator(translator); + return true; } - QTranslator *translator = new QTranslator(QCoreApplication::instance()); - if (!translator->load(fullPath)) { - delete translator; - return false; + + void load() + { + // The way Qt translation system handles plural forms makes it necessary to + // have a translation file which contains only plural forms for `en`. That's + // why we load the `en` translation unconditionally, then load the + // translation for the current locale to overload it. + loadTranslation(QStringLiteral("en")); + + QLocale locale = QLocale::system(); + if (locale.name() != QStringLiteral("en")) { + if (!loadTranslation(locale.name())) { + loadTranslation(locale.bcp47Name()); + } + } } - QCoreApplication::instance()->installTranslator(translator); - return true; -} -static void load() -{ - // The way Qt translation system handles plural forms makes it necessary to - // have a translation file which contains only plural forms for `en`. That's - // why we load the `en` translation unconditionally, then load the - // translation for the current locale to overload it. - loadTranslation(QStringLiteral("en")); - - QLocale locale = QLocale::system(); - if (locale.name() != QStringLiteral("en")) { - if (!loadTranslation(locale.name())) { - loadTranslation(locale.bcp47Name()); + // helper to call load() on the correct thread + class Loader : public QObject + { + Q_OBJECT + + public Q_SLOTS: + void callLoadAndDeleteSelf() + { + load(); + this->deleteLater(); + } + }; + + void loadOnMainThread() + { + // If this library is loaded after the QCoreApplication instance is created + // (eg: because it is brought in by a plugin), there is no guarantee this + // function will be called on the main thread. + // QCoreApplication::installTranslator needs to be called on the main + // thread, because it uses QCoreApplication::sendEvent. + if (QThread::currentThread() == QCoreApplication::instance()->thread()) { + load(); + } else { + // QObjects inherit their parent object's thread + Loader *loader = new Loader(); + loader->moveToThread(QCoreApplication::instance()->thread()); + QMetaObject::invokeMethod(loader, "callLoadAndDeleteSelf", Qt::AutoConnection); } } + } -Q_COREAPP_STARTUP_FUNCTION(load) +Q_COREAPP_STARTUP_FUNCTION(loadOnMainThread) + +#include "ECMQmLoader.moc" -- cgit v1.2.1 From a76e17ab8f527930c7c6b90f7d87f35c8ceb0ad2 Mon Sep 17 00:00:00 2001 From: Alex Merry Date: Tue, 3 Nov 2015 17:32:04 +0000 Subject: Add BSD license to ECMQmLoader.cpp.in. CCMAIL: kde-licensing@kde.org CCMAIL: agateau@kde.org --- modules/ECMQmLoader.cpp.in | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'modules/ECMQmLoader.cpp.in') diff --git a/modules/ECMQmLoader.cpp.in b/modules/ECMQmLoader.cpp.in index f6b98e7b..fc667ba2 100644 --- a/modules/ECMQmLoader.cpp.in +++ b/modules/ECMQmLoader.cpp.in @@ -2,6 +2,33 @@ * * Building this file in a library ensures translations are automatically loaded * when an application makes use of the library. + * + * + * Copyright 2014 Aurélien Gâteau + * Copyright 2015 Alex Merry + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include -- cgit v1.2.1 From 6745bd7e4796560959bb67e33b7c7f86f96a5a94 Mon Sep 17 00:00:00 2001 From: Alex Merry Date: Sun, 8 Nov 2015 19:23:22 +0000 Subject: Revert "Make sure we load translations on the main thread." This broke the build for projects which used ecm_create_qm_loader in unusual ways. A better approach is coming, but won't be in e-c-m 5.16. This reverts commit 009c480413910e8c1a18f4d1420f4a517ea606e6. CCBUG: 346188 CCMAIL: release-team@kde.org CCMAIL: kde-buildsystem@kde.org --- modules/ECMQmLoader.cpp.in | 88 ++++++++++++++-------------------------------- 1 file changed, 26 insertions(+), 62 deletions(-) (limited to 'modules/ECMQmLoader.cpp.in') diff --git a/modules/ECMQmLoader.cpp.in b/modules/ECMQmLoader.cpp.in index fc667ba2..423d1c93 100644 --- a/modules/ECMQmLoader.cpp.in +++ b/modules/ECMQmLoader.cpp.in @@ -32,77 +32,41 @@ */ #include #include -#include #include -#include #include -namespace { +#include - bool loadTranslation(const QString &localeDirName) - { - QString subPath = QStringLiteral("locale/") + localeDirName + QStringLiteral("/LC_MESSAGES/@catalog_name@.qm"); - QString fullPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, subPath); - if (fullPath.isEmpty()) { - return false; - } - QTranslator *translator = new QTranslator(QCoreApplication::instance()); - if (!translator->load(fullPath)) { - delete translator; - return false; - } - QCoreApplication::instance()->installTranslator(translator); - return true; +static bool loadTranslation(const QString &localeDirName) +{ + QString subPath = QStringLiteral("locale/") + localeDirName + QStringLiteral("/LC_MESSAGES/@catalog_name@.qm"); + QString fullPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, subPath); + if (fullPath.isEmpty()) { + return false; } - - void load() - { - // The way Qt translation system handles plural forms makes it necessary to - // have a translation file which contains only plural forms for `en`. That's - // why we load the `en` translation unconditionally, then load the - // translation for the current locale to overload it. - loadTranslation(QStringLiteral("en")); - - QLocale locale = QLocale::system(); - if (locale.name() != QStringLiteral("en")) { - if (!loadTranslation(locale.name())) { - loadTranslation(locale.bcp47Name()); - } - } + QTranslator *translator = new QTranslator(QCoreApplication::instance()); + if (!translator->load(fullPath)) { + delete translator; + return false; } + QCoreApplication::instance()->installTranslator(translator); + return true; +} - // helper to call load() on the correct thread - class Loader : public QObject - { - Q_OBJECT - - public Q_SLOTS: - void callLoadAndDeleteSelf() - { - load(); - this->deleteLater(); - } - }; +static void load() +{ + // The way Qt translation system handles plural forms makes it necessary to + // have a translation file which contains only plural forms for `en`. That's + // why we load the `en` translation unconditionally, then load the + // translation for the current locale to overload it. + loadTranslation(QStringLiteral("en")); - void loadOnMainThread() - { - // If this library is loaded after the QCoreApplication instance is created - // (eg: because it is brought in by a plugin), there is no guarantee this - // function will be called on the main thread. - // QCoreApplication::installTranslator needs to be called on the main - // thread, because it uses QCoreApplication::sendEvent. - if (QThread::currentThread() == QCoreApplication::instance()->thread()) { - load(); - } else { - // QObjects inherit their parent object's thread - Loader *loader = new Loader(); - loader->moveToThread(QCoreApplication::instance()->thread()); - QMetaObject::invokeMethod(loader, "callLoadAndDeleteSelf", Qt::AutoConnection); + QLocale locale = QLocale::system(); + if (locale.name() != QStringLiteral("en")) { + if (!loadTranslation(locale.name())) { + loadTranslation(locale.bcp47Name()); } } - } -Q_COREAPP_STARTUP_FUNCTION(loadOnMainThread) - -#include "ECMQmLoader.moc" +Q_COREAPP_STARTUP_FUNCTION(load) -- cgit v1.2.1