OSDN Git Service

Reorganized global functions: The file "Global.h" was split into multiple file in...
[lamexp/LameXP.git] / src / Global_Tools.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2013 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version, but always including the *additional*
9 // restrictions defined in the "License.txt" file.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 //
20 // http://www.gnu.org/licenses/gpl-2.0.txt
21 ///////////////////////////////////////////////////////////////////////////////
22
23 #include "Global.h"
24
25 //Qt includes
26 #include <QApplication>
27 #include <QMap>
28 #include <QReadWriteLock>
29 #include <QReadLocker>
30 #include <QWriteLocker>
31 #include <QString>
32 #include <QStringList>
33 #include <QTranslator>
34 #include <QFileInfo>
35
36 //LameXP includes
37 #include "LockedFile.h"
38
39 ///////////////////////////////////////////////////////////////////////////////
40 // GLOBAL VARS
41 ///////////////////////////////////////////////////////////////////////////////
42
43 //Tools
44 static struct
45 {
46         QMap<QString, LockedFile*> *registry;
47         QMap<QString, unsigned int> *versions;
48         QMap<QString, QString> *tags;
49         QReadWriteLock lock;
50 }
51 g_lamexp_tools;
52
53 //Supported languages
54 static struct
55 {
56         QMap<QString, QString> *files;
57         QMap<QString, QString> *names;
58         QMap<QString, unsigned int> *sysid;
59         QMap<QString, unsigned int> *cntry;
60         QReadWriteLock lock;
61 }
62 g_lamexp_translation;
63
64 //Translator
65 static struct
66 {
67         QTranslator *instance;
68         QReadWriteLock lock;
69 }
70 g_lamexp_currentTranslator;
71
72 ///////////////////////////////////////////////////////////////////////////////
73 // GLOBAL FUNCTIONS
74 ///////////////////////////////////////////////////////////////////////////////
75
76 /*
77  * Register tool
78  */
79 void lamexp_register_tool(const QString &toolName, LockedFile *file, unsigned int version, const QString *tag)
80 {
81         QWriteLocker writeLock(&g_lamexp_tools.lock);
82         
83         if(!g_lamexp_tools.registry) g_lamexp_tools.registry = new QMap<QString, LockedFile*>();
84         if(!g_lamexp_tools.versions) g_lamexp_tools.versions = new QMap<QString, unsigned int>();
85         if(!g_lamexp_tools.tags) g_lamexp_tools.tags = new QMap<QString, QString>();
86
87         if(g_lamexp_tools.registry->contains(toolName.toLower()))
88         {
89                 THROW("lamexp_register_tool: Tool is already registered!");
90         }
91
92         g_lamexp_tools.registry->insert(toolName.toLower(), file);
93         g_lamexp_tools.versions->insert(toolName.toLower(), version);
94         g_lamexp_tools.tags->insert(toolName.toLower(), (tag) ? (*tag) : QString());
95 }
96
97 /*
98  * Check for tool
99  */
100 bool lamexp_check_tool(const QString &toolName)
101 {
102         QReadLocker readLock(&g_lamexp_tools.lock);
103         return (g_lamexp_tools.registry) ? g_lamexp_tools.registry->contains(toolName.toLower()) : false;
104 }
105
106 /*
107  * Lookup tool path
108  */
109 const QString lamexp_lookup_tool(const QString &toolName)
110 {
111         QReadLocker readLock(&g_lamexp_tools.lock);
112
113         if(g_lamexp_tools.registry)
114         {
115                 if(g_lamexp_tools.registry->contains(toolName.toLower()))
116                 {
117                         return g_lamexp_tools.registry->value(toolName.toLower())->filePath();
118                 }
119                 else
120                 {
121                         return QString();
122                 }
123         }
124         else
125         {
126                 return QString();
127         }
128 }
129
130 /*
131  * Lookup tool version
132  */
133 unsigned int lamexp_tool_version(const QString &toolName, QString *tag)
134 {
135         QReadLocker readLock(&g_lamexp_tools.lock);
136         if(tag) tag->clear();
137
138         if(g_lamexp_tools.versions)
139         {
140                 if(g_lamexp_tools.versions->contains(toolName.toLower()))
141                 {
142                         if(tag)
143                         {
144                                 if(g_lamexp_tools.tags->contains(toolName.toLower())) *tag = g_lamexp_tools.tags->value(toolName.toLower());
145                         }
146                         return g_lamexp_tools.versions->value(toolName.toLower());
147                 }
148                 else
149                 {
150                         return UINT_MAX;
151                 }
152         }
153         else
154         {
155                 return UINT_MAX;
156         }
157 }
158
159 /*
160  * Version number to human-readable string
161  */
162 const QString lamexp_version2string(const QString &pattern, unsigned int version, const QString &defaultText, const QString *tag)
163 {
164         if(version == UINT_MAX)
165         {
166                 return defaultText;
167         }
168         
169         QString result = pattern;
170         int digits = result.count("?", Qt::CaseInsensitive);
171         
172         if(digits < 1)
173         {
174                 return result;
175         }
176         
177         int pos = 0;
178         QString versionStr = QString().sprintf(QString().sprintf("%%0%du", digits).toLatin1().constData(), version);
179         int index = result.indexOf("?", Qt::CaseInsensitive);
180         
181         while(index >= 0 && pos < versionStr.length())
182         {
183                 result[index] = versionStr[pos++];
184                 index = result.indexOf("?", Qt::CaseInsensitive);
185         }
186
187         if(tag)
188         {
189                 result.replace(QChar('#'), *tag, Qt::CaseInsensitive);
190         }
191
192         return result;
193 }
194
195 /*
196  * Free all registered tools (final clean-up)
197  */
198 void lamexp_clean_all_tools(void)
199 {
200         if(g_lamexp_tools.registry)
201         {
202                 QStringList keys = g_lamexp_tools.registry->keys();
203                 for(int i = 0; i < keys.count(); i++)
204                 {
205                         LockedFile *lf = g_lamexp_tools.registry->take(keys.at(i));
206                         LAMEXP_DELETE(lf);
207                 }
208                 g_lamexp_tools.registry->clear();
209                 g_lamexp_tools.versions->clear();
210                 g_lamexp_tools.tags->clear();
211         }
212
213         LAMEXP_DELETE(g_lamexp_tools.registry);
214         LAMEXP_DELETE(g_lamexp_tools.versions);
215         LAMEXP_DELETE(g_lamexp_tools.tags);
216 }
217
218 /*
219  * Initialize translations and add default language
220  */
221 bool lamexp_translation_init(void)
222 {
223         QWriteLocker writeLockTranslations(&g_lamexp_translation.lock);
224
225         if((!g_lamexp_translation.files) && (!g_lamexp_translation.names))
226         {
227                 g_lamexp_translation.files = new QMap<QString, QString>();
228                 g_lamexp_translation.names = new QMap<QString, QString>();
229                 g_lamexp_translation.files->insert(LAMEXP_DEFAULT_LANGID, "");
230                 g_lamexp_translation.names->insert(LAMEXP_DEFAULT_LANGID, "English");
231                 return true;
232         }
233         else
234         {
235                 qWarning("[lamexp_translation_init] Error: Already initialized!");
236                 return false;
237         }
238 }
239
240 /*
241  * Register a new translation
242  */
243 bool lamexp_translation_register(const QString &langId, const QString &qmFile, const QString &langName, unsigned int &systemId, unsigned int &country)
244 {
245         QWriteLocker writeLockTranslations(&g_lamexp_translation.lock);
246
247         if(qmFile.isEmpty() || langName.isEmpty() || systemId < 1)
248         {
249                 return false;
250         }
251
252         if(!g_lamexp_translation.files) g_lamexp_translation.files = new QMap<QString, QString>();
253         if(!g_lamexp_translation.names) g_lamexp_translation.names = new QMap<QString, QString>();
254         if(!g_lamexp_translation.sysid) g_lamexp_translation.sysid = new QMap<QString, unsigned int>();
255         if(!g_lamexp_translation.cntry) g_lamexp_translation.cntry = new QMap<QString, unsigned int>();
256
257         g_lamexp_translation.files->insert(langId, qmFile);
258         g_lamexp_translation.names->insert(langId, langName);
259         g_lamexp_translation.sysid->insert(langId, systemId);
260         g_lamexp_translation.cntry->insert(langId, country);
261
262         return true;
263 }
264
265 /*
266  * Get list of all translations
267  */
268 QStringList lamexp_query_translations(void)
269 {
270         QReadLocker readLockTranslations(&g_lamexp_translation.lock);
271         return (g_lamexp_translation.files) ? g_lamexp_translation.files->keys() : QStringList();
272 }
273
274 /*
275  * Get translation name
276  */
277 QString lamexp_translation_name(const QString &langId)
278 {
279         QReadLocker readLockTranslations(&g_lamexp_translation.lock);
280         return (g_lamexp_translation.names) ? g_lamexp_translation.names->value(langId.toLower(), QString()) : QString();
281 }
282
283 /*
284  * Get translation system id
285  */
286 unsigned int lamexp_translation_sysid(const QString &langId)
287 {
288         QReadLocker readLockTranslations(&g_lamexp_translation.lock);
289         return (g_lamexp_translation.sysid) ? g_lamexp_translation.sysid->value(langId.toLower(), 0) : 0;
290 }
291
292 /*
293  * Get translation script id
294  */
295 unsigned int lamexp_translation_country(const QString &langId)
296 {
297         QReadLocker readLockTranslations(&g_lamexp_translation.lock);
298         return (g_lamexp_translation.cntry) ? g_lamexp_translation.cntry->value(langId.toLower(), 0) : 0;
299 }
300
301 /*
302  * Install a new translator
303  */
304 bool lamexp_install_translator(const QString &langId)
305 {
306         bool success = false;
307         const QString qmFileToPath(":/localization/%1");
308
309         if(langId.isEmpty() || langId.toLower().compare(LAMEXP_DEFAULT_LANGID) == 0)
310         {
311                 success = lamexp_install_translator_from_file(qmFileToPath.arg(LAMEXP_DEFAULT_TRANSLATION));
312         }
313         else
314         {
315                 QReadLocker readLock(&g_lamexp_translation.lock);
316                 QString qmFile = (g_lamexp_translation.files) ? g_lamexp_translation.files->value(langId.toLower(), QString()) : QString();
317                 readLock.unlock();
318
319                 if(!qmFile.isEmpty())
320                 {
321                         success = lamexp_install_translator_from_file(qmFileToPath.arg(qmFile));
322                 }
323                 else
324                 {
325                         qWarning("Translation '%s' not available!", langId.toLatin1().constData());
326                 }
327         }
328
329         return success;
330 }
331
332 /*
333  * Install a new translator from file
334  */
335 bool lamexp_install_translator_from_file(const QString &qmFile)
336 {
337         QWriteLocker writeLock(&g_lamexp_currentTranslator.lock);
338         bool success = false;
339
340         if(!g_lamexp_currentTranslator.instance)
341         {
342                 g_lamexp_currentTranslator.instance = new QTranslator();
343         }
344
345         if(!qmFile.isEmpty())
346         {
347                 QString qmPath = QFileInfo(qmFile).canonicalFilePath();
348                 QApplication::removeTranslator(g_lamexp_currentTranslator.instance);
349                 if(success = g_lamexp_currentTranslator.instance->load(qmPath))
350                 {
351                         QApplication::installTranslator(g_lamexp_currentTranslator.instance);
352                 }
353                 else
354                 {
355                         qWarning("Failed to load translation:\n\"%s\"", qmPath.toLatin1().constData());
356                 }
357         }
358         else
359         {
360                 QApplication::removeTranslator(g_lamexp_currentTranslator.instance);
361                 success = true;
362         }
363
364         return success;
365 }
366
367 /*
368  * Free all registered translations (final clean-up)
369  */
370 void lamexp_clean_all_translations(void)
371 {
372         QWriteLocker writeLockTranslator(&g_lamexp_currentTranslator.lock);
373
374         if(g_lamexp_currentTranslator.instance)
375         {
376                 QApplication::removeTranslator(g_lamexp_currentTranslator.instance);
377                 LAMEXP_DELETE(g_lamexp_currentTranslator.instance);
378         }
379         
380         writeLockTranslator.unlock();
381         QWriteLocker writeLockTranslations(&g_lamexp_translation.lock);
382
383         LAMEXP_DELETE(g_lamexp_translation.files);
384         LAMEXP_DELETE(g_lamexp_translation.names);
385         LAMEXP_DELETE(g_lamexp_translation.cntry);
386         LAMEXP_DELETE(g_lamexp_translation.sysid);
387 }
388
389 ///////////////////////////////////////////////////////////////////////////////
390 // INITIALIZATION
391 ///////////////////////////////////////////////////////////////////////////////
392
393 extern "C" void _lamexp_global_init_tools(void)
394 {
395         LAMEXP_ZERO_MEMORY(g_lamexp_tools);
396         LAMEXP_ZERO_MEMORY(g_lamexp_currentTranslator);
397         LAMEXP_ZERO_MEMORY(g_lamexp_translation);
398 }