1 /**********************************************************************
2 ** Copyright (C) 2002-2007 Detlev Offenbach <detlev@die-offenbachs.de>
3 **
4 ** This is a modified version of lupdate. The original is part of Qt-Linguist.
5 ** The copyright of the original file can be found below.
6 **
7 ** This version is modified to handle python sources.
8 **
9 **   The file is provided AS IS with NO WARRANTY OF ANY KIND,
10 **   INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR
11 **   A PARTICULAR PURPOSE.
12 ****************************************************************************/
13 
14 /****************************************************************************
15 **
16 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
17 ** Contact: http://www.qt-project.org/legal
18 **
19 ** This file is part of the tools applications of the Qt Toolkit.
20 **
21 ** $QT_BEGIN_LICENSE:LGPL$
22 ** Commercial License Usage
23 ** Licensees holding valid commercial Qt licenses may use this file in
24 ** accordance with the commercial license agreement provided with the
25 ** Software or, alternatively, in accordance with the terms contained in
26 ** a written agreement between you and Digia.  For licensing terms and
27 ** conditions see http://qt.digia.com/licensing.  For further information
28 ** use the contact form at http://qt.digia.com/contact-us.
29 **
30 ** GNU Lesser General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU Lesser
32 ** General Public License version 2.1 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.LGPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU Lesser General Public License version 2.1 requirements
36 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
37 **
38 ** In addition, as a special exception, Digia gives you certain additional
39 ** rights.  These rights are described in the Digia Qt LGPL Exception
40 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
41 **
42 ** GNU General Public License Usage
43 ** Alternatively, this file may be used under the terms of the GNU
44 ** General Public License version 3.0 as published by the Free Software
45 ** Foundation and appearing in the file LICENSE.GPL included in the
46 ** packaging of this file.  Please review the following information to
47 ** ensure the GNU General Public License version 3.0 requirements will be
48 ** met: http://www.gnu.org/copyleft/gpl.html.
49 **
50 **
51 ** $QT_END_LICENSE$
52 **
53 ****************************************************************************/
54 
55 #ifndef TRANSLATOR_H
56 #define TRANSLATOR_H
57 
58 #include "QtCore/qobject.h"
59 #include "QtCore/qbytearray.h"
60 #include "QtCore/qstringlist.h"
61 #include "QtCore/qlocale.h"
62 #include <qtranslator.h>
63 
64 class TranslatorPrivate;
65 
66 #if !defined(QT_BEGIN_NAMESPACE)
67 #define QT_BEGIN_NAMESPACE
68 #define QT_END_NAMESPACE
69 #endif
70 
71 QT_BEGIN_NAMESPACE
72 template <typename T> class QList;
73 QT_END_NAMESPACE
74 
75 class TranslatorMessage
76 {
77 public:
78     TranslatorMessage();
79     TranslatorMessage(const char * context, const char * sourceText,
80                        const char * comment,
81                        const QString &fileName,
82                        int lineNumber,
83                        const QStringList& translations = QStringList());
84     TranslatorMessage(const TranslatorMessage & m);
85 
86     TranslatorMessage & operator=(const TranslatorMessage & m);
87 
hash()88     uint hash() const { return h; }
context()89     const char *context() const { return cx.isNull() ? 0 : cx.constData(); }
sourceText()90     const char *sourceText() const { return st.isNull() ? 0 : st.constData(); }
comment()91     const char *comment() const { return cm.isNull() ? 0 : cm.constData(); }
92 
93     inline void setTranslations(const QStringList &translations);
translations()94     QStringList translations() const { return m_translations; }
setTranslation(const QString & translation)95     void setTranslation(const QString &translation) { m_translations = QStringList(translation); }
translation()96     QString translation() const { return m_translations.value(0); }
isTranslated()97     bool isTranslated() const { return m_translations.count() > 1 || !m_translations.value(0).isEmpty(); }
98 
99     enum Prefix { NoPrefix, Hash, HashContext, HashContextSourceText,
100                   HashContextSourceTextComment };
101     void write(QDataStream & s, bool strip = false,
102                 Prefix prefix = HashContextSourceTextComment) const;
103     Prefix commonPrefix(const TranslatorMessage&) const;
104 
105     bool operator==(const TranslatorMessage& m) const;
106     bool operator!=(const TranslatorMessage& m) const
107     { return !operator==(m); }
108     bool operator<(const TranslatorMessage& m) const;
109     bool operator<=(const TranslatorMessage& m) const
110     { return !m.operator<(*this); }
111     bool operator>(const TranslatorMessage& m) const
112     { return m.operator<(*this); }
113     bool operator>=(const TranslatorMessage& m) const
114     { return !operator<(m); }
115 
fileName(void)116     QString fileName(void) const { return m_fileName; }
setFileName(const QString & fileName)117     void setFileName(const QString &fileName) { m_fileName = fileName; }
lineNumber(void)118     int lineNumber(void) const { return m_lineNumber; }
setLineNumber(int lineNumber)119     void setLineNumber(int lineNumber) { m_lineNumber = lineNumber; }
isNull()120     bool isNull() const { return st.isNull() && m_lineNumber == -1 && m_translations.isEmpty(); }
121 
122 private:
123     uint h;
124     QByteArray cx;
125     QByteArray st;
126     QByteArray cm;
127     QStringList m_translations;
128     QString     m_fileName;
129     int         m_lineNumber;
130 
131     enum Tag { Tag_End = 1, Tag_SourceText16, Tag_Translation, Tag_Context16,
132                Tag_Hash, Tag_SourceText, Tag_Context, Tag_Comment,
133                Tag_Obsolete1 };
134 };
135 Q_DECLARE_TYPEINFO(TranslatorMessage, Q_MOVABLE_TYPE);
136 
setTranslations(const QStringList & translations)137 inline void TranslatorMessage::setTranslations(const QStringList &translations)
138 { m_translations = translations; }
139 
140 class Translator : public QTranslator
141 {
142     Q_OBJECT
143 public:
144     explicit Translator(QObject *parent = 0);
145     ~Translator();
146 
147     virtual TranslatorMessage findMessage(const char *context, const char *sourceText,
148                                           const char *comment = 0,
149                                           const QString &fileName = 0, int lineNumber = -1) const;
150     virtual QString translate(const char *context, const char *sourceText,
151                               const char *comment = 0, int = -1) const
152         { return findMessage(context, sourceText, comment).translation(); }
153 
154     bool load(const QString & filename,
155                const QString & directory = QString(),
156                const QString & search_delimiters = QString(),
157                const QString & suffix = QString());
158     bool load(const uchar *data, int len);
159 
160     void clear();
161 
162     enum SaveMode { Everything, Stripped };
163 
164     bool save(const QString & filename, SaveMode mode = Everything);
165 
166     void insert(const TranslatorMessage&);
insert(const char * context,const char * sourceText,const QString & fileName,int lineNo,const QStringList & translations)167     inline void insert(const char *context, const char *sourceText, const QString &fileName, int lineNo, const QStringList &translations) {
168         insert(TranslatorMessage(context, sourceText, "", fileName, lineNo, translations));
169     }
170     void remove(const TranslatorMessage&);
remove(const char * context,const char * sourceText)171     inline void remove(const char *context, const char *sourceText) {
172         remove(TranslatorMessage(context, sourceText, "", QLatin1String(""), -1));
173     }
174     bool contains(const char *context, const char *sourceText, const char * comment = 0) const;
175     bool contains(const char *context, const char *comment, const QString &fileName, int lineNumber) const;
176 
177     void squeeze(SaveMode = Everything);
178     void unsqueeze();
179 
180     QList<TranslatorMessage> messages() const;
181 
182     bool isEmpty() const;
183 
184 private:
185     Q_DISABLE_COPY(Translator)
186     TranslatorPrivate *d;
187 };
188 
189 static const char * const japaneseStyleForms[] = { "Unique Form", 0 };
190 static const char * const englishStyleForms[] = { "Singular", "Plural", 0 };
191 static const char * const frenchStyleForms[] = { "Singular", "Plural", 0 };
192 static const char * const latvianForms[] = { "Singular", "Plural", "Nullar", 0 };
193 static const char * const irishStyleForms[] = { "Singular", "Dual", "Plural", 0 };
194 static const char * const czechForms[] = { "Singular", "Dual", "Plural", 0 };
195 static const char * const slovakForms[] = { "Singular", "Dual", "Plural", 0 };
196 static const char * const macedonianForms[] = { "Singular", "Dual", "Plural", 0 };
197 static const char * const lithuanianForms[] = { "Singular", "Dual", "Plural", 0 };
198 static const char * const russianStyleForms[] = { "Singular", "Dual", "Plural", 0 };
199 static const char * const polishForms[] = { "Singular", "Paucal", "Plural", 0 };
200 static const char * const romanianForms[] =
201     { "Singular", "Plural Form for 2 to 19", "Plural", 0 };
202 static const char * const slovenianForms[] = { "Singular", "Dual", "Trial", "Plural", 0 };
203 static const char * const malteseForms[] =
204     { "Singular", "Plural Form for 2 to 10", "Plural Form for 11 to 19", "Plural", 0 };
205 static const char * const welshForms[] =
206     { "Nullar", "Singular", "Dual", "Sexal", "Plural", 0 };
207 static const char * const arabicForms[] =
208     { "Nullar", "Singular", "Dual", "Minority Plural", "Plural", "Plural Form for 100, 200, ...", 0 };
209 
210 #define EOL QLocale::C
211 
212 static const QLocale::Language japaneseStyleLanguages[] = {
213     QLocale::Afan,
214     QLocale::Armenian,
215     QLocale::Bhutani,
216     QLocale::Bislama,
217     QLocale::Burmese,
218     QLocale::Chinese,
219 #if QT_VERSION >= 0x050000
220     QLocale::Fijian,
221 #else
222     QLocale::FijiLanguage,
223 #endif
224     QLocale::Guarani,
225     QLocale::Hungarian,
226     QLocale::Indonesian,
227     QLocale::Japanese,
228     QLocale::Javanese,
229     QLocale::Korean,
230     QLocale::Malay,
231     QLocale::NauruLanguage,
232     QLocale::Persian,
233     QLocale::Sundanese,
234     QLocale::Thai,
235     QLocale::Tibetan,
236     QLocale::Vietnamese,
237     QLocale::Yoruba,
238     QLocale::Zhuang,
239     EOL
240 };
241 
242 static const QLocale::Language englishStyleLanguages[] = {
243     QLocale::Abkhazian,
244     QLocale::Afar,
245     QLocale::Afrikaans,
246     QLocale::Albanian,
247     QLocale::Amharic,
248     QLocale::Assamese,
249     QLocale::Aymara,
250     QLocale::Azerbaijani,
251     QLocale::Bashkir,
252     QLocale::Basque,
253     QLocale::Bengali,
254     QLocale::Bihari,
255     // Missing: Bokmal,
256     QLocale::Bulgarian,
257     QLocale::Cambodian,
258     QLocale::Catalan,
259     QLocale::Cornish,
260     QLocale::Corsican,
261     QLocale::Danish,
262     QLocale::Dutch,
263     QLocale::English,
264     QLocale::Esperanto,
265     QLocale::Estonian,
266     QLocale::Faroese,
267     QLocale::Finnish,
268     // Missing: Friulian,
269     QLocale::Frisian,
270     QLocale::Galician,
271     QLocale::Georgian,
272     QLocale::German,
273     QLocale::Greek,
274     QLocale::Greenlandic,
275     QLocale::Gujarati,
276     QLocale::Hausa,
277     QLocale::Hebrew,
278     QLocale::Hindi,
279     QLocale::Icelandic,
280     QLocale::Interlingua,
281     QLocale::Interlingue,
282     QLocale::Italian,
283     QLocale::Kannada,
284     QLocale::Kashmiri,
285     QLocale::Kazakh,
286     QLocale::Kinyarwanda,
287     QLocale::Kirghiz,
288     QLocale::Kurdish,
289     QLocale::Kurundi,
290 #if QT_VERSION >= 0x050000
291     QLocale::Lao,
292 #else
293     QLocale::Laothian,
294 #endif
295     QLocale::Latin,
296     // Missing: Letzeburgesch,
297     QLocale::Lingala,
298     QLocale::Malagasy,
299     QLocale::Malayalam,
300     QLocale::Marathi,
301     QLocale::Mongolian,
302     // Missing: Nahuatl,
303     QLocale::Nepali,
304     // Missing: Northern Sotho,
305     QLocale::Norwegian,
306 #if QT_VERSION >= 0x050000
307     QLocale::NorwegianNynorsk,
308 #else
309     QLocale::Nynorsk,
310 #endif
311     QLocale::Occitan,
312     QLocale::Oriya,
313     QLocale::Pashto,
314     QLocale::Portuguese,
315     QLocale::Punjabi,
316     QLocale::Quechua,
317     QLocale::RhaetoRomance,
318 #if QT_VERSION >= 0x050000
319     QLocale::SouthernSotho,
320     QLocale::Tswana,
321 #else
322     QLocale::Sesotho,
323     QLocale::Setswana,
324 #endif
325     QLocale::Shona,
326     QLocale::Sindhi,
327 #if QT_VERSION >= 0x050000
328     QLocale::Sinhala,
329     QLocale::Swati,
330 #else
331     QLocale::Singhalese,
332     QLocale::Siswati,
333 #endif
334     QLocale::Somali,
335     QLocale::Spanish,
336     QLocale::Swahili,
337     QLocale::Swedish,
338     QLocale::Tagalog,
339     QLocale::Tajik,
340     QLocale::Tamil,
341     QLocale::Tatar,
342     QLocale::Telugu,
343 #if QT_VERSION >= 0x050000
344     QLocale::Tongan,
345 #else
346     QLocale::TongaLanguage,
347 #endif
348     QLocale::Tsonga,
349     QLocale::Turkish,
350     QLocale::Turkmen,
351     QLocale::Twi,
352     QLocale::Uigur,
353     QLocale::Uzbek,
354     QLocale::Volapuk,
355     QLocale::Wolof,
356     QLocale::Xhosa,
357     QLocale::Yiddish,
358     QLocale::Zulu,
359     EOL
360 };
361 static const QLocale::Language frenchStyleLanguages[] = {
362     // keep synchronized with frenchStyleCountries
363     QLocale::Breton,
364     QLocale::French,
365     QLocale::Portuguese,
366     // Missing: Filipino,
367     QLocale::Tigrinya,
368     // Missing: Walloon
369     EOL
370 };
371 static const QLocale::Language latvianLanguage[] = { QLocale::Latvian, EOL };
372 static const QLocale::Language irishStyleLanguages[] = {
373     QLocale::Divehi,
374     QLocale::Gaelic,
375     QLocale::Inuktitut,
376     QLocale::Inupiak,
377     QLocale::Irish,
378     QLocale::Manx,
379     QLocale::Maori,
380     // Missing: Sami,
381     QLocale::Samoan,
382     QLocale::Sanskrit,
383     EOL
384 };
385 static const QLocale::Language czechLanguage[] = { QLocale::Czech, EOL };
386 static const QLocale::Language slovakLanguage[] = { QLocale::Slovak, EOL };
387 static const QLocale::Language macedonianLanguage[] = { QLocale::Macedonian, EOL };
388 static const QLocale::Language lithuanianLanguage[] = { QLocale::Lithuanian, EOL };
389 static const QLocale::Language russianStyleLanguages[] = {
390     QLocale::Bosnian,
391     QLocale::Byelorussian,
392     QLocale::Croatian,
393     QLocale::Russian,
394     QLocale::Serbian,
395     QLocale::SerboCroatian,
396     QLocale::Ukrainian,
397     EOL
398 };
399 static const QLocale::Language polishLanguage[] = { QLocale::Polish, EOL };
400 static const QLocale::Language romanianLanguages[] = {
401     QLocale::Moldavian,
402     QLocale::Romanian,
403     EOL
404 };
405 static const QLocale::Language slovenianLanguage[] = { QLocale::Slovenian, EOL };
406 static const QLocale::Language malteseLanguage[] = { QLocale::Maltese, EOL };
407 static const QLocale::Language welshLanguage[] = { QLocale::Welsh, EOL };
408 static const QLocale::Language arabicLanguage[] = { QLocale::Arabic, EOL };
409 
410 static const QLocale::Country frenchStyleCountries[] = {
411     // keep synchronized with frenchStyleLanguages
412     QLocale::AnyCountry,
413     QLocale::AnyCountry,
414     QLocale::Brazil,
415     QLocale::AnyCountry
416 };
417 
418 struct NumerusTableEntry {
419     const char * const *forms;
420     const QLocale::Language *languages;
421     const QLocale::Country *countries;
422 };
423 
424 static const NumerusTableEntry numerusTable[] = {
425     { japaneseStyleForms, japaneseStyleLanguages, 0 },
426     { englishStyleForms, englishStyleLanguages, 0 },
427     { frenchStyleForms, frenchStyleLanguages, frenchStyleCountries },
428     { latvianForms, latvianLanguage, 0 },
429     { irishStyleForms, irishStyleLanguages, 0 },
430     { czechForms, czechLanguage, 0 },
431     { slovakForms, slovakLanguage, 0 },
432     { macedonianForms, macedonianLanguage, 0 },
433     { lithuanianForms, lithuanianLanguage, 0 },
434     { russianStyleForms, russianStyleLanguages, 0 },
435     { polishForms, polishLanguage, 0 },
436     { romanianForms, romanianLanguages, 0 },
437     { slovenianForms, slovenianLanguage, 0 },
438     { malteseForms, malteseLanguage, 0 },
439     { welshForms, welshLanguage, 0 },
440     { arabicForms, arabicLanguage, 0 }
441 };
442 
443 static const int NumerusTableSize = sizeof(numerusTable) / sizeof(numerusTable[0]);
444 
445 bool getNumerusInfo(QLocale::Language language, QLocale::Country country,
446                            QStringList *forms);
447 
448 #endif // TRANSLATOR_H
449