1 #include <stdio.h>
2 #include <QtCore/QMap>
3 #include <QtCore/QLocale>
4 #include <QtCore/QTranslator>
5 #include <QApplication>
6 #include <QtCore/QString>
7 #include "ADM_default.h"
8 #include "ADM_inttype.h"
9 #include "ADM_files.h"
10 #include "ADM_coreTranslator.h"
11 #include "prefs.h"
12 
13 #define MAX_UNLOADED_MSG_LENGTH 400
14 static QTranslator *qtTranslator;
15 static QTranslator *avidemuxTranslator;
16 static QMap<QString, char*> *map = NULL;
17 static bool translatorLoaded = false;
18 
loadTranslation(QTranslator * qTranslator,QString translation)19 static int loadTranslation(QTranslator *qTranslator, QString translation)
20 {
21     ADM_info("[Locale] Loading language file %s ", translation.toUtf8().constData());
22 
23     if (qTranslator->load(translation))
24     {
25         QApplication::installTranslator(qTranslator);
26         ADM_info("succeeded\n");
27         return 1;
28     }
29     ADM_warning("FAILED\n");
30     return 0;
31 }
32 
qt4Translate(const char * __domainname,const char * __msgid)33 const char* qt4Translate(const char *__domainname, const char *__msgid)
34 {
35     QString msgid = QString(__domainname) + QString("#") + QString(__msgid);
36 
37     if (!map)
38         map = new QMap<QString, char*>;
39 
40     if (!map->contains(msgid))
41     {
42         QByteArray translatedMessage = QApplication::translate(__domainname, __msgid).toUtf8();
43         int copyLength = translatedMessage.length() + 1;
44         char* buffer = new char[translatorLoaded ? copyLength : MAX_UNLOADED_MSG_LENGTH + 1];
45 
46         if (!translatorLoaded && copyLength > MAX_UNLOADED_MSG_LENGTH + 1)
47 	{
48             copyLength = MAX_UNLOADED_MSG_LENGTH;
49             buffer[MAX_UNLOADED_MSG_LENGTH] = '\0';
50         }
51 
52         memcpy(buffer, translatedMessage.constData(), copyLength);
53 
54         (*map)[msgid] = buffer;
55     }
56 //#warning DANGEROUS FIXME
57     return map->value(msgid); // dangerous
58 }
59 /**
60  * \fn initTranslator
61  */
initTranslator(void)62 void initTranslator(void)
63 {
64     ADM_InitTranslator(qt4Translate);
65 }
66 
67 #define HIDE_STRING_FROM_QT(domainname, msgid)  QApplication::translate(domainname, msgid) // to hide string from lupdate so a true test can be conducted
68 static std::string flavor=std::string(
69 #if QT_VERSION < QT_VERSION_CHECK(5,0,0)
70         "qt4"
71 #else
72         "qt5"
73 #endif
74 );
75 
loadTranslator(void)76 void loadTranslator(void)
77 {
78     std::string lang;
79     bool autoSelect=true;
80     if(prefs->get(DEFAULT_LANGUAGE,lang))
81     {
82         if(lang.size() && lang.compare("auto"))
83             autoSelect=false;
84     }
85     if(autoSelect)
86     {
87         ADM_info("Using system language\n");
88         lang=std::string(QLocale::system().name().toUtf8().constData());
89     }else
90     {
91         ADM_info("Language forced \n");
92     }
93     ADM_info("Initializing language %s\n",lang.c_str());
94     std::string i18nFolder=ADM_getI8NDir(flavor);
95     ADM_info("Translation folder is <%s>\n",i18nFolder.c_str());
96     QString appdir = QString(i18nFolder.c_str());
97     QString languageFile;
98     if(lang.size())
99     {
100         languageFile=QString(lang.c_str());
101     }
102     int nbLoaded=0;
103     qtTranslator=new QTranslator();
104     avidemuxTranslator=new QTranslator();
105 #if QT_VERSION < QT_VERSION_CHECK(5,0,0)
106     nbLoaded+=loadTranslation(qtTranslator, appdir + "qt_" + languageFile);
107 #else
108     nbLoaded+=loadTranslation(qtTranslator, appdir + "qtbase_" + languageFile);
109 #endif
110     nbLoaded+=loadTranslation(avidemuxTranslator, appdir + "avidemux_" + languageFile);
111     translatorLoaded = true;
112     if(!nbLoaded) // Nothing to translate..
113     {
114         ADM_info("No translation loaded.\n");
115         return;
116     }
117     ADM_info("Updating translations...\n");
118     // Re-translate existing map (to take care of global strings already allocated)
119     if(!map)
120         map = new QMap<QString, char*>;
121     QMapIterator<QString, char*> mapIterator(*map);
122 
123     while (mapIterator.hasNext())
124     {
125         mapIterator.next();
126 
127         QByteArray translatedMessage = QApplication::translate("", mapIterator.key().toLatin1().constData()).toUtf8();
128         char *buffer = mapIterator.value();
129         int copyLength = translatedMessage.length() + 1;
130 
131         if (copyLength > MAX_UNLOADED_MSG_LENGTH + 1)
132         {
133             copyLength = MAX_UNLOADED_MSG_LENGTH;
134             buffer[MAX_UNLOADED_MSG_LENGTH] = '\0';
135         }
136 
137         memcpy(buffer, translatedMessage.constData(), copyLength);
138     }
139 
140     ADM_info("[Locale] Test: &Edit -> %s\n\n", HIDE_STRING_FROM_QT("MainWindow", "&Edit").toUtf8().data());
141 }
142 
destroyTranslator(void)143 void destroyTranslator(void)
144 {
145     if (map)
146     {
147         QMapIterator<QString, char*> mapIterator(*map);
148 
149         while (mapIterator.hasNext())
150         {
151             mapIterator.next();
152             delete [] mapIterator.value();
153         }
154 
155         delete map;
156     }
157 }
158 
159