OSDN Git Service

Moved translation support into MUtilities library + make clean-up of temporary files...
[mutilities/MUtilities.git] / src / Translation.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // MuldeR's Utilities for Qt
3 // Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 //
19 // http://www.gnu.org/licenses/lgpl-2.1.txt
20 //////////////////////////////////////////////////////////////////////////////////
21
22 //MUtils
23 #include <MUtils/Translation.h>
24
25 //Qt
26 #include <QPair>
27 #include <QReadWriteLock>
28 #include <QMap>
29 #include <QStringList>
30 #include <QTranslator>
31 #include <QFileInfo>
32 #include <QApplication>
33
34 //////////////////////////////////////////////////////////////////////////////////
35 // TYPES
36 //////////////////////////////////////////////////////////////////////////////////
37
38 typedef QPair<QString,QString> translation_info_t;
39 typedef QPair<quint32,quint32> translation_data_t;
40
41 typedef QPair<translation_info_t, translation_data_t> translation_entry_t;
42 typedef QMap<QString, translation_entry_t>            translation_store_t;
43
44 #define MAKE_ENTRY(NAME,PATH,SYSID,CNTRY) \
45         qMakePair(qMakePair((NAME),(PATH)),qMakePair((SYSID),(CNTRY)))
46
47 //////////////////////////////////////////////////////////////////////////////////
48 // TRANSLATIONS STORE
49 //////////////////////////////////////////////////////////////////////////////////
50
51 static QReadWriteLock                      g_translation_lock;
52 static QScopedPointer<translation_store_t> g_translation_data;
53 static QScopedPointer<QTranslator>         g_translation_inst;
54
55 //////////////////////////////////////////////////////////////////////////////////
56 // CONSTANT
57 //////////////////////////////////////////////////////////////////////////////////
58
59 namespace MUtils
60 {
61         namespace Translation
62         {
63                 const char *const DEFAULT_LANGID = "en";
64         }
65 }
66
67 //////////////////////////////////////////////////////////////////////////////////
68 // REGISTER TRANSLATION
69 //////////////////////////////////////////////////////////////////////////////////
70
71 bool MUtils::Translation::insert(const QString &langId, const QString &qmFile, const QString &langName, const quint32 &systemId, const quint32 &country)
72 {
73         QWriteLocker writeLockTranslations(&g_translation_lock);
74
75         const QString key = langId.simplified().toLower();
76         if(key.isEmpty() || qmFile.isEmpty() || langName.isEmpty() || (systemId < 1))
77         {
78                 return false;
79         }
80
81         if(g_translation_data.isNull())
82         {
83                 g_translation_data.reset(new translation_store_t());
84         }
85
86         if(g_translation_data->contains(key))
87         {
88                 qWarning("Translation store already contains entry for '%s', going to replace!", MUTILS_UTF8(key));
89         }
90
91         g_translation_data->insert(key, MAKE_ENTRY(langName, qmFile, systemId, country));
92         return true;
93 }
94
95 //////////////////////////////////////////////////////////////////////////////////
96 // GET TRANSLATION INFO
97 //////////////////////////////////////////////////////////////////////////////////
98
99 int MUtils::Translation::enumerate(QStringList &list)
100 {
101         QReadLocker readLockTranslations(&g_translation_lock);
102
103         if(g_translation_data.isNull())
104         {
105                 list.clear();
106                 return -1;
107         }
108
109         list.swap(g_translation_data->keys());
110         return list.count();
111 }
112
113 QString MUtils::Translation::get_name(const QString &langId)
114 {
115         QReadLocker readLockTranslations(&g_translation_lock);
116
117         const QString key = langId.simplified().toLower();
118         if(key.isEmpty() || g_translation_data.isNull() || (!g_translation_data->contains(key)))
119         {
120                 return QString();
121         }
122
123         return (*g_translation_data)[key].first.first;
124 }
125
126 quint32 MUtils::Translation::get_sysid(const QString &langId)
127 {
128         QReadLocker readLockTranslations(&g_translation_lock);
129
130         const QString key = langId.simplified().toLower();
131         if(key.isEmpty() || g_translation_data.isNull() || (!g_translation_data->contains(key)))
132         {
133                 return 0;
134         }
135
136         return (*g_translation_data)[key].second.first;
137 }
138
139 quint32 MUtils::Translation::get_country(const QString &langId)
140 {
141         QReadLocker readLockTranslations(&g_translation_lock);
142         const QString key = langId.simplified().toLower();
143         if(key.isEmpty() || g_translation_data.isNull() || (!g_translation_data->contains(key)))
144         {
145                 return 0;
146         }
147
148         return (*g_translation_data)[key].second.second;
149 }
150
151 //////////////////////////////////////////////////////////////////////////////////
152 // INSTALL TRANSLATION
153 //////////////////////////////////////////////////////////////////////////////////
154
155 bool MUtils::Translation::install_translator(const QString &langId)
156 {
157         QReadLocker readLockTranslations(&g_translation_lock);
158
159         const QString key = langId.simplified().toLower();
160         if(key.isEmpty() || g_translation_data.isNull() || (!g_translation_data->contains(key)))
161         {
162                 return false;
163         }
164
165         const QString qmFile = (*g_translation_data)[key].first.second;
166         readLockTranslations.unlock();
167         return install_translator_from_file(qmFile);
168 }
169
170 bool MUtils::Translation::install_translator_from_file(const QString &qmFile)
171 {
172         QWriteLocker writeLock(&g_translation_lock);
173
174         if(g_translation_inst.isNull())
175         {
176                 g_translation_inst.reset(new QTranslator());
177         }
178
179         if(qmFile.isEmpty())
180         {
181                 QApplication::removeTranslator(g_translation_inst.data());
182                 return true;
183         }
184
185         const QFileInfo qmFileInfo(qmFile);
186         if(!(qmFileInfo.exists() && qmFileInfo.isFile()))
187         {
188                 qWarning("Translation file not found:\n\"%s\"", MUTILS_UTF8(qmFile));
189                 return false;
190         }
191
192         const QString qmPath = QFileInfo(qmFile).canonicalFilePath();
193         if(!qmPath.isEmpty())
194         {
195                 QApplication::removeTranslator(g_translation_inst.data());
196                 if(g_translation_inst->load(qmPath))
197                 {
198                         QApplication::installTranslator(g_translation_inst.data());
199                         return true;
200                 }
201         }
202
203         qWarning("Failed to load translation:\n\"%s\"",  MUTILS_UTF8(qmFile));
204         return false;
205 }