]> SALOME platform Git repositories - tools/eficas.git/blob - Extensions/translationQT5.py
Salome HOME
reindent + copyright + merge manuel avec la V9_dev sauf repertoires metier
[tools/eficas.git] / Extensions / translationQT5.py
1 # -*- coding: utf-8 -*-
2 # copyright 2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
3 # contact http://www.logilab.fr -- mailto:contact@logilab.fr
4 #
5 # This program is free software: you can redistribute it and/or modify it under
6 # the terms of the GNU Lesser General Public License as published by the Free
7 # Software Foundation, either version 2.1 of the License, or (at your option)
8 # any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 # details.
14 #
15 # You should have received a copy of the GNU Lesser General Public License along
16 # with this program. If not, see <http://www.gnu.org/licenses/>.
17 """
18 Main module of the ``i18n`` package, for internationalizing strings via the Qt
19 mechanism, in the ``Eficas`` application of EDF. Handles unformatted and
20 formatted strings, according to all formatting schemes: via dictionaries,
21 tuples, or atoms.
22
23 """
24 from __future__ import absolute_import
25 try :
26     from builtins import zip
27     from builtins import map
28     from builtins import range
29 except :
30     pass
31 from .eficas_exception import EficasException
32
33 import re
34 regex=re.compile(r"% *[0-9]+")
35
36 import six
37 from six.moves import map
38 from six.moves import range
39 from six.moves import zip
40
41
42
43
44 def _reformat_qstring_from_tuple(qstring, params):
45     """
46     _reformat_qstring_from_tuple(string, tuple) -> string
47
48     Module-internal method.
49     Returns a formatted string from an unformatted string
50     and a tuple specifying the parameters of the string.
51     """
52     from PyQt5.QtCore import QRegExp
53     reg = QRegExp("\%\.[1-9]{1,2}f")
54     for p, j in zip(params, list(range(len(params)))):
55         try:
56             i += 1 + qstring[i + 1:].indexOf("%")
57         except NameError:
58             i = qstring.indexOf("%")
59         if i == reg.indexIn(qstring):
60             precision = reg.cap(0).split('.')[1].split('f')[0]
61             qstring = qstring[:i + 2 + len(precision)].\
62                       replace("%." + precision, "%" + six.text_type(1 + j)) + \
63                       qstring[i + 3 + len(precision):]
64             qstring=regex.sub("{}",qstring)
65             #qstring = qstring.format(QString.number(float(params[j]), 'f', int(precision)))
66             qstring = qstring.format(float(params[j]))
67         else:
68             qstring = qstring[:i + 1].replace("%", "%" + six.text_type(1 + j)) + \
69                       qstring[i + 2:]
70             if isinstance(params[j], six.text_type):
71                 qstring=regex.sub("{}",qstring)
72                 qstring = qstring.format(params[j])
73             elif isinstance(params[j], float):
74                 qstring=regex.sub("{}",qstring)
75                 #qstring = qstring.format(QString.number(params[j], 'f',\ len(unicode(params[j]).\
76                 #                                         split('.')[1])))
77                 qstring = qstring.format(params[j])
78             elif isinstance(params[j], int):
79                 qstring=regex.sub("{}",qstring)
80                 #qstring = qstring.format(QString.number(params[j], 10))
81                 qstring = qstring.format(params[j])
82             elif isinstance(params[j], list):
83                 qstring=regex.sub("{}",qstring)
84                 qstring = qstring.format(repr(params[j]))
85             else:
86                 raise EficasException("TypeError: i18n.translation: \
87                                       Unicode, list or number expected!")
88     return qstring
89
90 def _reformat_qstring_from_dict(qstring, params):
91     """
92     _reformat_qstring_from_dict(string, dict) -> string
93
94     Module-internal method.
95     Returns a formatted string from an unformatted string
96     and a dictionary specifying the parameters of the string.
97     """
98     from PyQt5.QtCore import QRegExp
99     for p, j in zip(params, list(range(len(params)))):
100         p_reg = QRegExp("\%\("+ p + "\)\.[1-9]{1,2}f")
101         p_index = p_reg.indexIn(qstring)
102         if p_index != -1:
103             precision = p_reg.cap(0).split('.')[1].split('f')[0]
104             #qstring = qstring.replace("%(" + p + ")." + precision + "f",\
105             #                          "%" + unicode(1 + j)).\
106             #                          arg(QString.number(float(params[p]), \
107             #                                             'f', \
108             #                                             int(precision)))
109             qstring = qstring.replace("%(" + p + ")." + precision + "f","%" + six.text_type(1 + j))
110             qstring=regex.sub("{}",qstring)
111             qstring = qstring.format(float(params[p]))
112         else:
113             qstring.remove(QRegExp("\\)[sdf]{1}"))
114             qstring = qstring.replace("%(" + p, "%" + six.text_type(1 + j))
115             if isinstance(params[p], six.text_type):
116                 qstring=regex.sub("{}",qstring)
117                 qstring = qstring.format(params[p])
118             elif isinstance(params[p], float):
119                 qstring=regex.sub("{}",qstring)
120                 qstring = qstring.format(params[p])
121                 #qstring = qstring.format(QString.number(params[p], 'f', \
122                 #          len(unicode(params[p]).split('.')[1])))
123             elif isinstance(params[p], int):
124                 qstring=regex.sub("{}",qstring)
125                 qstring = qstring.format(params[p])
126             elif isinstance(params[p], list):
127                 qstring=regex.sub("{}",qstring)
128                 qstring = qstring.format(repr(params[p]))
129             else:
130                 raise EficasException("TypeError: i18n.translation: \
131                                       Improper string parameter type.")
132     return qstring
133
134 def _reformat_qstring_from_atom(qstring, params):
135     """
136     _reformat_qstring_from_atom(string, int-or-float) -> string
137
138     Module-internal method.
139     Returns a formatted string from an unformatted string
140     and an integer or a float specifying the parameter of
141     the string.
142     """
143     from PyQt5.QtCore import QRegExp
144     reg = QRegExp("\%\.[1-9]{1,2}f")
145     if qstring.count("%") == 0:
146         qstring.append("%1")
147         try:
148             qstring=regex.sub("{}",qstring)
149             qstring = qstring.format(six.text_type(params))
150         except AttributeError:
151             qstring=regex.sub("{}",qstring)
152             qstring = qstring.format(params)
153     elif qstring.count("%") == 1:
154         i = qstring.indexOf("%")
155         if i == reg.indexIn(qstring):
156             precision = reg.cap(0).split('.')[1].split('f')[0]
157             qstring = qstring[: i + 2 + len(precision)].\
158                       replace("%." + precision, "%1") + \
159                       qstring[i + 3 + len(precision):]
160             qstring=regex.sub("{}",qstring)
161             qstring = qstring.format((params))
162             #qstring = qstring.format(QString.number(float(params), 'f',\
163             #                                     int(precision)))
164         else:
165             qstring = qstring[:i + 1].replace("%", "%1") + \
166                       qstring[i + 2:]
167             if isinstance(params, (six.text_type, str)):
168                 qstring = qstring.format(_preprocess_atom(params))
169             elif isinstance(params, float):
170                 #qstring = qstring.format(QString.number(params, 'f', \
171                 #                                     len(unicode(params).\
172                 #                                         split('.')[1])))
173                 qstring = qstring.format(params)
174             elif isinstance(params, int):
175                 qstring=regex.sub("{}",qstring)
176                 #qstring = qstring.format(QString.number(params, 10))
177                 qstring = qstring.format(params)
178             else:
179                 raise EficasException("TypeError: i18n.translation: Unicode, \
180                                       string or number expected!")
181     return qstring
182
183 def _reformat_qstring_from_list(qstring, params):
184     """
185     _reformat_qstring_from_list(string, tuple) -> string
186
187     Module-internal method.
188     Returns a formatted string from an unformatted string
189     and a list whose concatenation specifies the parameter
190     of the string.
191     """
192     # XXX to add further functionality, e.g. list processing
193     # when ``%`` not at the end.
194     if qstring.count("%") == 1 and \
195        six.text_type(qstring).strip()[:-1].endswith("%"):
196         qstring = qstring[:qstring.indexOf("%") + 1].append("1")
197         qstring=regex.sub("{}",qstring)
198         qstring = qstring.format(u' '.join(map(six.text_type, params)))
199     elif qstring.count("%") == 0:
200         qstring.append("%1")
201         qstring=regex.sub("{}",qstring)
202         qstring = qstring.format(u' '.join(map(six.text_type, params)))
203     else:
204         raise EficasException("ValueError: i18n.translation: \
205                               At most one '%' expected!")
206     return qstring
207
208 def _preprocess_atom(string):
209     """
210     _preprocess_atom(string-or-number-or-unicode) -> unicode
211     Test if input is a Unicode object or a number; if so, then return it;
212     otherwise, test if the input is a string; if so, then try to create
213     a Unicode object out of it. To this end, assume the string is encoded
214     in utf-8; if this fails, then assume the string is encoded in Latin-9.
215     """
216     if isinstance(string, (six.text_type, int, float, complex)):
217         return string
218     elif isinstance(string, str):
219         return _str_toUnicode(string)
220     else:
221         raise EficasException("TypeError: Expected number, string or\
222                               Unicode object!")
223
224 def _str_toUnicode(string):
225     """
226     _str_toUnicode(string) -> unicode
227     Tries to create a Unicode object out of the input string; assumes
228     the string is UTF-8 encoded; if not, then assume the string is
229     Latin-9 encoded.
230     """
231     try:
232         string = six.text_type(string, "utf-8")
233     except UnicodeDecodeError:
234         try:
235             string = six.text_type(string, "iso-8859-15")
236         except UnicodeDecodeError:
237             raise EficasException("UnicodeDecodeError: UTF-8, Latin-1 \
238                                   or Latin-9 expected")
239     return string
240
241 def tr(string, *args):
242     """tr(string-or-unicode, iterable-or-float-or-int) -> unicode
243        tr(string-or-unicode) -> unicode
244
245        Returns a formatted Unicode object from an unformatted
246        string or Unicode object with formatting specifications, and,
247        optionally, an iterable or an int or float.
248        Lets Python do the string formatting."""
249     try :
250         from PyQt5.QtWidgets import QApplication
251     except :
252         return string
253
254     string = _preprocess_atom(string)
255     if len(args) == 0:
256         r = six.text_type(QApplication.translate("@default", string))
257     elif len(args) == 1:
258         if isinstance(args[0], (dict, tuple)):
259             if string.count("%") == len(args[0]):
260                 r = six.text_type(QApplication.translate("@default", string)) % args[0]
261             elif string.count("%") == 1 and string.count("%(") == 0:
262                 r = six.text_type(QApplication.translate("@default", string))\
263                     % _preprocess_atom(repr(args[0]))
264             elif string.count("%") == 0:
265                 r = (six.text_type(QApplication.translate("@default", string)), args[0])
266             else:
267                 raise EficasException("ValueError: i18n.translate.tr: \
268                                       Improper input string formatting")
269         elif isinstance(args[0], (six.text_type, str, int, float, complex)):
270             if string.count("%") == 1:
271                 r = six.text_type(QApplication.translate("@default", string))\
272                     % _preprocess_atom(args[0])
273             else:
274                 r = six.text_type(QApplication.translate("@default", string)) +\
275                     six.text_type(_preprocess_atom(args[0]))
276         elif isinstance(args[0], list) or args[0] is None:
277             if string.count("%") == 1:
278                 r = six.text_type(QApplication.translate("@default", string))\
279                     % _preprocess_atom(repr(args[0]))
280             else:
281                 r = (six.text_type(QApplication.translate("@default", string)), args[0])
282
283         else:
284             raise EficasException("ValueError: i18n.translation.tr: \
285                                   Wrong type for formatted string \
286                                   arguments: %s" % type(args[0]))
287     else:
288         raise EficasException("ValueError: i18n.translation.tr: \
289                               Wrong formatted string arguments")
290     return r
291
292
293 def tr_qt(string, *args):
294     """tr_qt(string, iterable-or-float-or-int) -> unicode
295        t_qtr(string) -> unicode
296
297        Returns a formatted string from an unformatted
298        Unicode string with formatting specifications, and,
299        optionally, an iterable or an int or float.
300        Lets PyQt4 do the string formatting. To this end,
301        a conversion from Python to Qt string formatting
302        syntax is performed."""
303     string = _preprocess_atom(string)
304     from PyQt5.QtWidgets import QApplication
305     if len(args) == 0:
306         r = QApplication.translate("@default", string)
307     elif len(args) == 1:
308         r = QApplication.translate("@default", string)
309         if isinstance(args[0], (dict, tuple)):
310             if r.count("%") == len(args[0]):
311                 if isinstance(args[0], dict):
312                     r = _reformat_qstring_from_dict(r, args[0])
313                 elif isinstance(args[0], tuple):
314                     r = _reformat_qstring_from_tuple(r, args[0])
315             # XXX Pay attention to this: distinguish between tuple,
316             # dict and dict with key given in string.
317             elif r.count("%") in range(2) and r.count("%(") == 0:
318                 r = _reformat_qstring_from_atom(r, _preproces_atom(repr(args[0])))
319             else:
320                 raise EficasException("ValueError: i18n.translation.tr_qt: \
321                                       Improper formatting string parameters")
322         elif isinstance(args[0], (six.text_type, str, int, float, complex)):
323             r = _reformat_qstring_from_atom(r, args[0])
324         elif isinstance(args[0], list):
325             r = _reformat_qstring_from_list(r, args[0])
326         elif args[0] is None:
327             r = _reformat_qstring_from_atom(r, _preprocess_string_from_atom(repr(args[0])))
328         else:
329             raise EficasException("ValueError: i18n.translation.tr_qt: \
330                                   Wrong string formatting parameter types")
331     else:
332         raise EficasException("ValueError: i18n.translation.tr_qt: \
333                               Improper formatted string parameter set")
334     return six.text_type(r)
335
336
337 if __name__ == "__main__":
338     import sys
339     tr(sys.argv[1], *args)
340     tr_qt(sys.argv[1], *args)