KSeExpr
6.0.0.0
KSeExprUI
ECMQmLoader-seexpr2_qt.cpp
Go to the documentation of this file.
1
/* This file was generated by ecm_create_qm_loader().
2
* It was edited for KSeExpr.
3
*
4
* Building this file in a library ensures translations are automatically loaded
5
* when an application makes use of the library.
6
*
7
*
8
* SPDX-FileCopyrightText: 2014 Aurélien Gâteau <agateau@kde.org>
9
* SPDX-FileCopyrightText: 2015 Alex Merry <alex.merry@kde.org>
10
* SPDX-FileCopyrightText: 2020-2021 L. E. Segovia <amy@amyspark.me>
11
*
12
* SPDX-License-Identifier: BSD-3-Clause
13
*/
14
#include <
Debug.h
>
15
16
#include <QCoreApplication>
17
#include <QDir>
18
#include <QLocale>
19
#include <QObject>
20
#include <QStandardPaths>
21
#include <QThread>
22
#include <QTranslator>
23
24
#if defined(KSeExpr_HAVE_I18N_FALLBACK_LANGUAGES_DETECTION)
25
#include <KLocalizedString>
26
#include <algorithm>
27
#endif
28
29
namespace
KSeExpr
{
30
31
bool
loadTranslation
(
const
QString
&
localeDirName
)
32
{
33
QString
subPath
=
QStringLiteral
(
"locale/"
) +
localeDirName
+
QStringLiteral
(
"/LC_MESSAGES/seexpr2_qt.qm"
);
34
35
dbgSeExpr
<<
"Attempting to load: "
<<
subPath
;
36
37
#if defined(Q_OS_ANDROID)
38
const
QString
fullPath
=
QStringLiteral
(
"assets:/share/"
) +
subPath
;
39
if
(!QFile::exists(
fullPath
)) {
40
return
false
;
41
}
42
#else
43
// Use application's own data directory (e.g. Krita on AppImage, Windows)
44
QString
fullPath
= QStandardPaths::locate(QStandardPaths::AppLocalDataLocation,
subPath
);
45
if
(
fullPath
.isEmpty()) {
46
// Try falling back to stock folder
47
fullPath
= QStandardPaths::locate(QStandardPaths::GenericDataLocation,
subPath
);
48
if
(
fullPath
.isEmpty())
49
return
false
;
50
}
51
#endif
52
QTranslator
*
translator
=
new
QTranslator
(QCoreApplication::instance());
53
if
(!
translator
->load(
fullPath
)) {
54
delete
translator
;
55
return
false
;
56
}
57
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
58
dbgSeExpr
<<
"Installing translation for: "
<<
fullPath
<<
"("
<<
translator
->language() <<
")"
;
59
#else
60
dbgSeExpr
<<
"Installing translation for: "
<<
fullPath
;
61
#endif
62
dbgSeExpr
<<
"Test: "
<<
translator
->translate(
"ExprControlCollection"
,
"Add new variable"
);
63
64
QCoreApplication::instance()->installTranslator(
translator
);
65
return
true
;
66
}
67
68
void
load
()
69
{
70
#if defined(Q_OS_ANDROID)
71
const
auto
paths =
QStringLiteral
(
"assets:/share/"
);
72
#else
73
auto
paths = QStandardPaths::standardLocations(QStandardPaths::AppLocalDataLocation);
74
paths << QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
75
#endif
76
dbgSeExpr
<<
"Base paths for translations: "
<< paths;
77
78
#if defined(KSeExpr_HAVE_I18N_FALLBACK_LANGUAGES_DETECTION)
79
dbgSeExpr
<<
"Qt UI languages: "
<< KLocalizedString::languages() <<
QLocale
().uiLanguages() <<
qgetenv
(
"LANG"
);
80
#else
81
dbgSeExpr
<<
"Qt UI languages: "
<<
QLocale
().uiLanguages() <<
qgetenv
(
"LANG"
);
82
#endif
83
84
// The way Qt translation system handles plural forms makes it necessary to
85
// have a translation file which contains only plural forms for `en`. That's
86
// why we load the `en` translation unconditionally, then load the
87
// translation for the current locale to overload it.
88
loadTranslation
(
QStringLiteral
(
"en"
));
89
90
// Use the default locale and any available fallback languages.
91
// Fallback languages must be reverse iterated in order of priority.
92
#if defined(KSeExpr_HAVE_I18N_FALLBACK_LANGUAGES_DETECTION)
93
const
auto
fallbackLanguages
{ KLocalizedString::languages()};
94
for
(
auto
it
=
fallbackLanguages
.rbegin();
it
!=
fallbackLanguages
.rend(); ++
it
) {
95
if
(!
loadTranslation
(*
it
)) {
96
const
auto
localeParts
=
it
->split(
'@'
);
97
QLocale
locale
(
localeParts
.constFirst());
98
if
(!
loadTranslation
(
locale
.name())) {
99
if
(!
loadTranslation
(
locale
.bcp47Name())) {
100
const
int
i
=
locale
.name().indexOf(
QLatin1Char
(
'_'
));
101
if
(
i
> 0) {
102
loadTranslation
(
locale
.name().left(
i
));
103
}
104
}
105
}
106
}
107
}
108
#else
109
for
(
const
auto
&
locale
: {
QLocale
() }) {
110
dbgSeExpr
<<
"Attempting to load translations for locale: "
<<
locale
.name();
111
if
(!
loadTranslation
(
locale
.name())) {
112
if
(!
loadTranslation
(
locale
.bcp47Name())) {
113
const
int
i
=
locale
.name().indexOf(
QLatin1Char
(
'_'
));
114
if
(
i
> 0) {
115
loadTranslation
(
locale
.name().left(
i
));
116
}
117
}
118
}
119
}
120
#endif
121
122
dbgSeExpr
<<
"Test: "
<< QCoreApplication::translate(
"ExprControlCollection"
,
"Add new variable"
);
123
}
124
125
// Helper to call load() on the main thread.
126
//
127
// Calling functions on another thread without using moc is non-trivial in
128
// Qt until 5.4 (when some useful QTimer::singleShot overloads were added).
129
//
130
// Instead, we have to use QEvents. Ideally, we'd use a custom QEvent, but
131
// there's a chance this could cause trouble with applications that claim
132
// QEvent codes themselves, but don't register them with Qt (and we also
133
// want to avoid registering a new QEvent code for every plugin that might
134
// be loaded). We use QTimer because it's unlikely to be filtered by
135
// applications, and is also unlikely to cause Qt to do something it
136
// shouldn't.
137
class
Loader
:
public
QObject
138
{
139
protected
:
140
void
timerEvent
(
QTimerEvent
*)
Q_DECL_OVERRIDE
141
{
142
load
();
143
this->
deleteLater
();
144
}
145
};
146
147
void
loadOnMainThread
()
148
{
149
// If this library is loaded after the QCoreApplication instance is
150
// created (eg: because it is brought in by a plugin), there is no
151
// guarantee this function will be called on the main thread.
152
// QCoreApplication::installTranslator needs to be called on the main
153
// thread, because it uses QCoreApplication::sendEvent.
154
if
(QThread::currentThread() == QCoreApplication::instance()->
thread
()) {
155
load
();
156
}
else
{
157
// QObjects inherit their parent object's thread
158
Loader
*
loader
=
new
Loader
();
159
loader
->moveToThread(QCoreApplication::instance()->
thread
());
160
QCoreApplication::instance()->postEvent(
loader
,
new
QTimerEvent
(0), Qt::HighEventPriority);
161
}
162
}
163
164
Q_COREAPP_STARTUP_FUNCTION(
loadOnMainThread
)
165
}
// namespace KSeExpr
Debug.h
dbgSeExpr
#define dbgSeExpr
Definition
Debug.h:17
KSeExpr::Loader
Definition
ECMQmLoader-seexpr2_qt.cpp:138
KSeExpr::Loader::timerEvent
void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE
Definition
ECMQmLoader-seexpr2_qt.cpp:140
KSeExpr::Vec
Definition
Vec.h:31
KSeExpr
Definition
Context.h:13
KSeExpr::load
void load()
Definition
ECMQmLoader-seexpr2_qt.cpp:68
KSeExpr::loadOnMainThread
void loadOnMainThread()
Definition
ECMQmLoader-seexpr2_qt.cpp:147
KSeExpr::loadTranslation
bool loadTranslation(const QString &localeDirName)
Definition
ECMQmLoader-seexpr2_qt.cpp:31
Generated by
1.9.8