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