1 /* BEGIN_COMMON_COPYRIGHT_HEADER
2 * (c)LGPL2+
3 *
4 * LXQt - a lightweight, Qt based, desktop toolset
5 * https://lxqt.org
6 *
7 * Copyright: 2013 LXQt team
8 * Authors:
9 * Alexander Sokoloff <sokoloff.a@gmail.com>
10 Luís Pereira <luis.artur.pereira@gmail.com>
11 *
12 * This program or library is free software; you can redistribute it
13 * and/or modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21
22 * You should have received a copy of the GNU Lesser General
23 * Public License along with this library; if not, write to the
24 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 * Boston, MA 02110-1301 USA
26 *
27 * END_COMMON_COPYRIGHT_HEADER */
28
29 #include "lxqttranslator.h"
30 #include <QTranslator>
31 #include <QLocale>
32 #include <QDebug>
33 #include <QCoreApplication>
34 #include <QLibraryInfo>
35 #include <QStringList>
36 #include <QStringBuilder>
37 #include <QFileInfo>
38
39 #include <XdgDirs>
40
41 using namespace LXQt;
42
43 bool translate(const QString &name, const QString &owner = QString());
44 /************************************************
45
46 ************************************************/
getSearchPaths()47 QStringList *getSearchPaths()
48 {
49 static QStringList *searchPath = nullptr;
50
51 if (searchPath == nullptr)
52 {
53 searchPath = new QStringList();
54 *searchPath << XdgDirs::dataDirs(QL1C('/') + QL1S(LXQT_RELATIVE_SHARE_TRANSLATIONS_DIR));
55 *searchPath << QL1S(LXQT_SHARE_TRANSLATIONS_DIR);
56 searchPath->removeDuplicates();
57 }
58
59 return searchPath;
60 }
61
62
63 /************************************************
64
65 ************************************************/
translationSearchPaths()66 QStringList LXQt::Translator::translationSearchPaths()
67 {
68 return *(getSearchPaths());
69 }
70
71
72 /************************************************
73
74 ************************************************/
setTranslationSearchPaths(const QStringList & paths)75 void Translator::setTranslationSearchPaths(const QStringList &paths)
76 {
77 QStringList *p = getSearchPaths();
78 p->clear();
79 *p << paths;
80 }
81
82
83 /************************************************
84
85 ************************************************/
translate(const QString & name,const QString & owner)86 bool translate(const QString &name, const QString &owner)
87 {
88 const QString locale = QLocale::system().name();
89 QTranslator *appTranslator = new QTranslator(qApp);
90
91 QStringList *paths = getSearchPaths();
92 for(const QString &path : qAsConst(*paths))
93 {
94 QStringList subPaths;
95
96 if (!owner.isEmpty())
97 {
98 subPaths << path + QL1C('/') + owner + QL1C('/') + name;
99 }
100 else
101 {
102 subPaths << path + QL1C('/') + name;
103 subPaths << path;
104 }
105
106 for(const QString &p : qAsConst(subPaths))
107 {
108 if (appTranslator->load(name + QL1C('_') + locale, p))
109 {
110 QCoreApplication::installTranslator(appTranslator);
111 return true;
112 }
113 else if (locale == QLatin1String("C") ||
114 locale.startsWith(QLatin1String("en")))
115 {
116 // English is the default. Even if there isn't an translation
117 // file, we return true. It's translated anyway.
118 delete appTranslator;
119 return true;
120 }
121 }
122 }
123
124 // If we got here, no translation was loaded. appTranslator has no use.
125 delete appTranslator;
126 return false;
127 }
128
129
130 /************************************************
131
132 ************************************************/
translateApplication(const QString & applicationName)133 bool Translator::translateApplication(const QString &applicationName)
134 {
135 const QString locale = QLocale::system().name();
136 QTranslator *qtTranslator = new QTranslator(qApp);
137
138 if (qtTranslator->load(QL1S("qt_") + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
139 {
140 qApp->installTranslator(qtTranslator);
141 }
142 else
143 {
144 delete qtTranslator;
145 }
146
147 if (!applicationName.isEmpty())
148 return translate(applicationName);
149 else
150 return translate(QFileInfo(QCoreApplication::applicationFilePath()).baseName());
151 }
152
153
154 /************************************************
155
156 ************************************************/
translateLibrary(const QString & libraryName)157 bool Translator::translateLibrary(const QString &libraryName)
158 {
159 static QSet<QString> loadedLibs;
160
161 if (loadedLibs.contains(libraryName))
162 return true;
163
164 loadedLibs.insert(libraryName);
165
166 return translate(libraryName);
167 }
168
translatePlugin(const QString & pluginName,const QString & type)169 bool Translator::translatePlugin(const QString &pluginName, const QString& type)
170 {
171 static QSet<QString> loadedPlugins;
172
173 const QString fullName = type % QL1C('/') % pluginName;
174 if (loadedPlugins.contains(fullName))
175 return true;
176
177 loadedPlugins.insert(pluginName);
178 return translate(pluginName, type);
179 }
180
loadSelfTranslation()181 static void loadSelfTranslation()
182 {
183 Translator::translateLibrary(QLatin1String("liblxqt"));
184 }
185
186 Q_COREAPP_STARTUP_FUNCTION(loadSelfTranslation)
187