Merge lp:~tsabi/openerp-web/trunk-properi18nmark into lp:openerp-web
- trunk-properi18nmark
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Xavier (Open ERP) |
Approved revision: | 3524 |
Merged at revision: | 3531 |
Proposed branch: | lp:~tsabi/openerp-web/trunk-properi18nmark |
Merge into: | lp:openerp-web |
Diff against target: |
702 lines (+88/-82) 12 files modified
addons/web/controllers/main.py (+11/-10) addons/web/static/src/js/chrome.js (+17/-17) addons/web/static/src/js/dates.js (+7/-6) addons/web/static/src/js/formats.js (+7/-7) addons/web/static/src/js/pyeval.js (+10/-8) addons/web/static/src/js/view_form.js (+12/-12) addons/web/static/src/js/view_list.js (+7/-7) addons/web/static/src/js/view_list_editable.js (+3/-1) addons/web/static/src/js/views.js (+6/-6) addons/web_calendar/static/src/js/calendar.js (+2/-2) addons/web_kanban/static/src/js/kanban.js (+1/-1) addons/web_view_editor/static/src/js/view_editor.js (+5/-5) |
To merge this branch: | bzr merge lp:~tsabi/openerp-web/trunk-properi18nmark |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Xavier (Open ERP) (community) | Needs Fixing | ||
Stefan Rijnhart (Opener) (community) | Needs Fixing | ||
Review via email: mp+136875@code.launchpad.net |
Commit message
Description of the change
Marked every (missed some only technical error message) string as translatable. See bug report 1084306
Stefan Rijnhart (Opener) (stefan-opener) wrote : | # |
Xavier (Open ERP) (xmo-deactivatedaccount) wrote : | # |
Nothing to add to Stefan's review, if these two points are fixed there should be no problem with merging this proposal.
- 3521. By Csaba TOTH
-
[MERGE] trunk
- 3522. By Csaba TOTH
-
[MERGE] trunk
- 3523. By Csaba TOTH
-
fix tab problem
- 3524. By Csaba TOTH
-
some more change in the new pyeval.js file
Csaba TOTH (tsabi) wrote : | # |
Ok, updated to trunk, and fixed the tab problem.
Xavier (Open ERP) (xmo-deactivatedaccount) wrote : | # |
I fear you'll have to revert part of the last change (to pyeval), it accesses _t using the full dotted path because it is loaded before _t being made available. Thus the base aliasing `var _t = instance.web._t;` will result in _t always being `undefined`.
Xavier (Open ERP) (xmo-deactivatedaccount) wrote : | # |
Furthermore the untranslated strings were actually the strings taken directly from the corresponding Python exceptions and messages, and untranslated on purpose.
Xavier (Open ERP) (xmo-deactivatedaccount) wrote : | # |
(nm, I'll just revert it locally while merging)
Csaba TOTH (tsabi) wrote : | # |
wow, that was quick :) Thanks!
yes you right, in pyeval.js there is not too much real end user message, except pyeval.js:344:348 lines, and it has hardcoded english language specific code. Please look how i resolved that conflict, i feel that needs to fixed too.
Xavier (Open ERP) (xmo-deactivatedaccount) wrote : | # |
> yes you right, in pyeval.js there is not too much real end user message, except pyeval.js:344:348 lines, and it has hardcoded english language specific code.
Well I don't know, it's the string representation of a Python timedelta object, which I don't know to be translated. If you have an OS in a non-english language, try creating a timedelta object and see what it prints to:
> python -c 'import datetime; print datetime.
1 day, 0:00:01
if it returns some sort of localized string localizing it in pyeval could be considered, but if it does not I'd rather stick to the original behavior in the translation to javascript.
Csaba TOTH (tsabi) wrote : | # |
Ok, i am not a big javascript tumbler, as i getted out it includes text to translate, but didn't getted out the real meaning of the code. Now i understand, if this will piped to a python evaluation process, than this is in good format.
from my python windows console with hungarian local:
import datetime; print datetime.
1 day, 0:00:04
import datetime; print datetime.
913 days, 0:32:48
The same result under linux with hu_HU.UTF-8 locale.
Xavier (Open ERP) (xmo-deactivatedaccount) wrote : | # |
> Ok, i am not a big javascript tumbler, as i getted out it includes text to translate, but didn't getted out the real meaning of the code.
No problem.
> Now i understand, if this will piped to a python evaluation process
Yeah technically it *is* a python evaluation process (partial), to avoid doing the evaluation on the server.
> The same result under linux with hu_HU.UTF-8 locale.
OK, I'll leave the current output then. But thanks a lot for having wondered about it and checked.
Preview Diff
1 | === modified file 'addons/web/controllers/main.py' |
2 | --- addons/web/controllers/main.py 2012-11-29 09:10:38 +0000 |
3 | +++ addons/web/controllers/main.py 2012-11-29 11:56:19 +0000 |
4 | @@ -28,6 +28,7 @@ |
5 | xlwt = None |
6 | |
7 | import openerp |
8 | +from openerp.tools.translate import _ |
9 | |
10 | from .. import http |
11 | openerpweb = http |
12 | @@ -762,7 +763,7 @@ |
13 | except xmlrpclib.Fault, e: |
14 | if e.faultCode and e.faultCode.split(':')[0] == 'AccessDenied': |
15 | return {'error': e.faultCode, 'title': 'Drop Database'} |
16 | - return {'error': 'Could not drop database !', 'title': 'Drop Database'} |
17 | + return {'error': _('Could not drop database !'), 'title': _('Drop Database')} |
18 | |
19 | @openerpweb.httprequest |
20 | def backup(self, req, backup_db, backup_pwd, token): |
21 | @@ -780,7 +781,7 @@ |
22 | {'fileToken': int(token)} |
23 | ) |
24 | except xmlrpclib.Fault, e: |
25 | - return simplejson.dumps([[],[{'error': e.faultCode, 'title': 'backup Database'}]]) |
26 | + return simplejson.dumps([[],[{'error': e.faultCode, 'title': _('Backup Database')}]]) |
27 | |
28 | @openerpweb.httprequest |
29 | def restore(self, req, db_file, restore_pwd, new_db): |
30 | @@ -801,8 +802,8 @@ |
31 | return req.session.proxy("db").change_admin_password(old_password, new_password) |
32 | except xmlrpclib.Fault, e: |
33 | if e.faultCode and e.faultCode.split(':')[0] == 'AccessDenied': |
34 | - return {'error': e.faultCode, 'title': 'Change Password'} |
35 | - return {'error': 'Error, password not changed !', 'title': 'Change Password'} |
36 | + return {'error': e.faultCode, 'title': _('Change Password')} |
37 | + return {'error': _('Error, password not changed !'), 'title': _('Change Password')} |
38 | |
39 | class Session(openerpweb.Controller): |
40 | _cp_path = "/web/session" |
41 | @@ -838,16 +839,16 @@ |
42 | old_password, new_password,confirm_password = operator.itemgetter('old_pwd', 'new_password','confirm_pwd')( |
43 | dict(map(operator.itemgetter('name', 'value'), fields))) |
44 | if not (old_password.strip() and new_password.strip() and confirm_password.strip()): |
45 | - return {'error':'You cannot leave any password empty.','title': 'Change Password'} |
46 | + return {'error':_('You cannot leave any password empty.'),'title': _('Change Password')} |
47 | if new_password != confirm_password: |
48 | - return {'error': 'The new password and its confirmation must be identical.','title': 'Change Password'} |
49 | + return {'error': _('The new password and its confirmation must be identical.'),'title': _('Change Password')} |
50 | try: |
51 | if req.session.model('res.users').change_password( |
52 | old_password, new_password): |
53 | return {'new_password':new_password} |
54 | except Exception: |
55 | - return {'error': 'The old password you provided is incorrect, your password was not changed.', 'title': 'Change Password'} |
56 | - return {'error': 'Error, password not changed !', 'title': 'Change Password'} |
57 | + return {'error': _('The old password you provided is incorrect, your password was not changed.'), 'title': _('Change Password')} |
58 | + return {'error': _('Error, password not changed !'), 'title': _('Change Password')} |
59 | |
60 | @openerpweb.jsonrequest |
61 | def sc_list(self, req): |
62 | @@ -859,7 +860,7 @@ |
63 | try: |
64 | return req.session.proxy("db").list_lang() or [] |
65 | except Exception, e: |
66 | - return {"error": e, "title": "Languages"} |
67 | + return {"error": e, "title": _("Languages")} |
68 | |
69 | @openerpweb.jsonrequest |
70 | def modules(self, req): |
71 | @@ -1302,7 +1303,7 @@ |
72 | res = Model.default_get(fields, context) |
73 | filecontent = base64.b64decode(res.get(field, '')) |
74 | if not filecontent: |
75 | - raise ValueError("No content found for field '%s' on '%s:%s'" % |
76 | + raise ValueError(_("No content found for field '%s' on '%s:%s'") % |
77 | (field, model, id)) |
78 | else: |
79 | filename = '%s_%s' % (model.replace('.', '_'), id) |
80 | |
81 | === modified file 'addons/web/static/src/js/chrome.js' |
82 | --- addons/web/static/src/js/chrome.js 2012-11-29 09:10:38 +0000 |
83 | +++ addons/web/static/src/js/chrome.js 2012-11-29 11:56:19 +0000 |
84 | @@ -289,7 +289,7 @@ |
85 | }); |
86 | |
87 | instance.web.Loading = instance.web.Widget.extend({ |
88 | - template: 'Loading', |
89 | + template: _t("Loading"), |
90 | init: function(parent) { |
91 | this._super(parent); |
92 | this.count = 0; |
93 | @@ -390,11 +390,11 @@ |
94 | self.$el.find("form[name=restore_db_form]").validate({ submitHandler: self.do_restore }); |
95 | self.$el.find("form[name=change_pwd_form]").validate({ |
96 | messages: { |
97 | - old_pwd: "Please enter your previous password", |
98 | - new_pwd: "Please enter your new password", |
99 | + old_pwd: _t("Please enter your previous password"), |
100 | + new_pwd: _t("Please enter your new password"), |
101 | confirm_pwd: { |
102 | - required: "Please confirm your new password", |
103 | - equalTo: "The confirmation does not match the password" |
104 | + required: _t("Please confirm your new password"), |
105 | + equalTo: _t("The confirmation does not match the password") |
106 | } |
107 | }, |
108 | submitHandler: self.do_change_password |
109 | @@ -478,7 +478,7 @@ |
110 | self.display_error(result); |
111 | return; |
112 | } |
113 | - self.do_notify("Duplicating database", "The database has been duplicated."); |
114 | + self.do_notify(_t("Duplicating database"), _t("The database has been duplicated.")); |
115 | self.start(); |
116 | }); |
117 | }, |
118 | @@ -488,7 +488,7 @@ |
119 | fields = $form.serializeArray(), |
120 | $db_list = $form.find('[name=drop_db]'), |
121 | db = $db_list.val(); |
122 | - if (!db || !confirm("Do you really want to delete the database: " + db + " ?")) { |
123 | + if (!db || !confirm(_.str.sprintf(_t("Do you really want to delete the database: %s ?"), db))) { |
124 | return; |
125 | } |
126 | self.rpc("/web/database/drop", {'fields': fields}).done(function(result) { |
127 | @@ -496,7 +496,7 @@ |
128 | self.display_error(result); |
129 | return; |
130 | } |
131 | - self.do_notify("Dropping database", "The database '" + db + "' has been dropped"); |
132 | + self.do_notify(_t("Dropping database"), _.str.sprintf(_t("The database %s has been dropped"), db)); |
133 | self.start(); |
134 | }); |
135 | }, |
136 | @@ -511,7 +511,7 @@ |
137 | error: function(error){ |
138 | if(error){ |
139 | self.display_error({ |
140 | - title: 'Backup Database', |
141 | + title: _t("Backup Database"), |
142 | error: 'AccessDenied' |
143 | }); |
144 | } |
145 | @@ -534,13 +534,13 @@ |
146 | |
147 | if (body.indexOf('403 Forbidden') !== -1) { |
148 | self.display_error({ |
149 | - title: 'Access Denied', |
150 | - error: 'Incorrect super-administrator password' |
151 | + title: _t("Access Denied"), |
152 | + error: _t("Incorrect super-administrator password") |
153 | }); |
154 | } else { |
155 | self.display_error({ |
156 | - title: 'Restore Database', |
157 | - error: 'Could not restore the database' |
158 | + title: _t("Restore Database"), |
159 | + error: _t("Could not restore the database") |
160 | }); |
161 | } |
162 | }, |
163 | @@ -560,7 +560,7 @@ |
164 | return; |
165 | } |
166 | self.unblockUI(); |
167 | - self.do_notify("Changed Password", "Password has been changed successfully"); |
168 | + self.do_notify(_t("Changed Password"), _t("Password has been changed successfully")); |
169 | }); |
170 | }, |
171 | do_exit: function () { |
172 | @@ -642,7 +642,7 @@ |
173 | } |
174 | var db = this.$("form [name=db]").val(); |
175 | if (!db) { |
176 | - this.do_warn("Login", "No database selected !"); |
177 | + this.do_warn(_t("Login"), _t("No database selected !")); |
178 | return false; |
179 | } |
180 | var login = this.$("form input[name=login]").val(); |
181 | @@ -678,7 +678,7 @@ |
182 | self.trigger('login_successful'); |
183 | }, function () { |
184 | self.$(".oe_login_pane").fadeIn("fast", function() { |
185 | - self.show_error("Invalid username or password"); |
186 | + self.show_error(_t("Invalid username or password")); |
187 | }); |
188 | }); |
189 | }, |
190 | @@ -765,7 +765,7 @@ |
191 | template: "ChangePassword", |
192 | start: function() { |
193 | var self = this; |
194 | - this.getParent().dialog_title = "Change Password"; |
195 | + this.getParent().dialog_title = _t("Change Password"); |
196 | var $button = self.$el.find('.oe_form_button'); |
197 | $button.appendTo(this.getParent().$buttons); |
198 | $button.eq(2).click(function(){ |
199 | |
200 | === modified file 'addons/web/static/src/js/dates.js' |
201 | --- addons/web/static/src/js/dates.js 2012-04-17 11:58:05 +0000 |
202 | +++ addons/web/static/src/js/dates.js 2012-11-29 11:56:19 +0000 |
203 | @@ -1,5 +1,6 @@ |
204 | |
205 | openerp.web.dates = function(instance) { |
206 | +var _t = instance.web._t; |
207 | |
208 | /** |
209 | * Converts a string to a Date javascript object using OpenERP's |
210 | @@ -18,11 +19,11 @@ |
211 | var regex = /^(\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d)(?:\.\d+)?$/; |
212 | var res = regex.exec(str); |
213 | if ( !res ) { |
214 | - throw new Error("'" + str + "' is not a valid datetime"); |
215 | + throw new Error(_.str.sprintf(_t("'%s' is not a valid datetime"), str)); |
216 | } |
217 | var obj = Date.parseExact(res[1] + " UTC", 'yyyy-MM-dd HH:mm:ss zzz'); |
218 | if (! obj) { |
219 | - throw new Error("'" + str + "' is not a valid datetime"); |
220 | + throw new Error(_.str.sprintf(_t("'%s' is not a valid datetime"), str)); |
221 | } |
222 | return obj; |
223 | }; |
224 | @@ -45,11 +46,11 @@ |
225 | var regex = /^\d\d\d\d-\d\d-\d\d$/; |
226 | var res = regex.exec(str); |
227 | if ( !res ) { |
228 | - throw new Error("'" + str + "' is not a valid date"); |
229 | + throw new Error(_.str.sprintf(_t("'%s' is not a valid date"), str)); |
230 | } |
231 | var obj = Date.parseExact(str, 'yyyy-MM-dd'); |
232 | if (! obj) { |
233 | - throw new Error("'" + str + "' is not a valid date"); |
234 | + throw new Error(_.str.sprintf(_t("'%s' is not a valid date"), str)); |
235 | } |
236 | return obj; |
237 | }; |
238 | @@ -72,11 +73,11 @@ |
239 | var regex = /^(\d\d:\d\d:\d\d)(?:\.\d+)?$/; |
240 | var res = regex.exec(str); |
241 | if ( !res ) { |
242 | - throw new Error("'" + str + "' is not a valid time"); |
243 | + throw new Error(_.str.sprintf(_t("'%s' is not a valid time"), str)); |
244 | } |
245 | var obj = Date.parseExact("1970-01-01 " + res[1], 'yyyy-MM-dd HH:mm:ss'); |
246 | if (! obj) { |
247 | - throw new Error("'" + str + "' is not a valid time"); |
248 | + throw new Error(_.str.sprintf(_t("'%s' is not a valid time"), str)); |
249 | } |
250 | return obj; |
251 | }; |
252 | |
253 | === modified file 'addons/web/static/src/js/formats.js' |
254 | --- addons/web/static/src/js/formats.js 2012-11-12 17:11:28 +0000 |
255 | +++ addons/web/static/src/js/formats.js 2012-11-29 11:56:19 +0000 |
256 | @@ -224,7 +224,7 @@ |
257 | } while(tmp !== value); |
258 | tmp = Number(value); |
259 | if (isNaN(tmp)) |
260 | - throw new Error(value + " is not a correct integer"); |
261 | + throw new Error(_.str.sprintf(_t("'%s' is not a correct integer"), value)); |
262 | return tmp; |
263 | case 'float': |
264 | var tmp = Number(value); |
265 | @@ -239,7 +239,7 @@ |
266 | var reformatted_value = tmp.replace(instance.web._t.database.parameters.decimal_point, "."); |
267 | var parsed = Number(reformatted_value); |
268 | if (isNaN(parsed)) |
269 | - throw new Error(value + " is not a correct float"); |
270 | + throw new Error(_.str.sprintf(_t("'%s' is not a correct float"), value)); |
271 | return parsed; |
272 | case 'float_time': |
273 | var factor = 1; |
274 | @@ -263,7 +263,7 @@ |
275 | datetime = Date.parse(value); |
276 | if (datetime !== null) |
277 | return instance.web.datetime_to_str(datetime); |
278 | - throw new Error(value + " is not a valid datetime"); |
279 | + throw new Error(_.str.sprintf(_t("'%s' is not a correct datetime"), value)); |
280 | case 'date': |
281 | var date = Date.parseExact(value, date_pattern); |
282 | if (date !== null) |
283 | @@ -271,7 +271,7 @@ |
284 | date = Date.parse(value); |
285 | if (date !== null) |
286 | return instance.web.date_to_str(date); |
287 | - throw new Error(value + " is not a valid date"); |
288 | + throw new Error(_.str.sprintf(_t("'%s' is not a correct date"), value)); |
289 | case 'time': |
290 | var time = Date.parseExact(value, time_pattern); |
291 | if (time !== null) |
292 | @@ -279,7 +279,7 @@ |
293 | time = Date.parse(value); |
294 | if (time !== null) |
295 | return instance.web.time_to_str(time); |
296 | - throw new Error(value + " is not a valid time"); |
297 | + throw new Error(_.str.sprintf(_t("'%s' is not a correct time"), value)); |
298 | } |
299 | return value; |
300 | }; |
301 | @@ -294,7 +294,7 @@ |
302 | try { |
303 | return instance.web.str_to_time(value); |
304 | } catch(e) {} |
305 | - throw new Error("'" + value + "' is not a valid date, datetime nor time"); |
306 | + throw new Error(_.str.sprintf(_t("'%s' is not a correct date, datetime nor time"), value)); |
307 | }; |
308 | |
309 | instance.web.auto_date_to_str = function(value, type) { |
310 | @@ -306,7 +306,7 @@ |
311 | case 'time': |
312 | return instance.web.time_to_str(value); |
313 | default: |
314 | - throw new Error(type + " is not convertible to date, datetime nor time"); |
315 | + throw new Error(_.str.sprintf(_t("'%s' is not convertible to date, datetime nor time"), type)); |
316 | } |
317 | }; |
318 | |
319 | |
320 | === modified file 'addons/web/static/src/js/pyeval.js' |
321 | --- addons/web/static/src/js/pyeval.js 2012-11-28 11:05:42 +0000 |
322 | +++ addons/web/static/src/js/pyeval.js 2012-11-29 11:56:19 +0000 |
323 | @@ -2,6 +2,7 @@ |
324 | * py.js helpers and setup |
325 | */ |
326 | openerp.web.pyeval = function (instance) { |
327 | + var _t = instance.web._t; |
328 | instance.web.pyeval = {}; |
329 | |
330 | var obj = function () {}; |
331 | @@ -71,7 +72,7 @@ |
332 | var ymd2ord = function (year, month, day) { |
333 | var dim = days_in_month(year, month); |
334 | if (!(1 <= day && day <= dim)) { |
335 | - throw new Error("ValueError: day must be in 1.." + dim); |
336 | + throw new Error(_.str.sprintf(_t("ValueError: day must be in 1..%d"), dim)); |
337 | } |
338 | return days_before_year(year) |
339 | + days_before_month(year, month) |
340 | @@ -277,10 +278,11 @@ |
341 | }); |
342 | var s = _.str.sprintf("%d:%02d:%02d", hh, mm, ss); |
343 | if (this.days) { |
344 | - s = _.str.sprintf("%d day%s, %s", |
345 | - this.days, |
346 | - (this.days != 1 && this.days != -1) ? 's' : '', |
347 | - s); |
348 | + if (this.days != 1 && this.days != -1) { |
349 | + s = _.str.sprintf(_t("%d days, %s"), this.days, s); |
350 | + } else { |
351 | + s = _.str.sprintf(_t("%d day, %s"), this.days, s); |
352 | + }; |
353 | } |
354 | if (this.microseconds) { |
355 | s = _.str.sprintf("%s.%06d", s, this.microseconds); |
356 | @@ -726,7 +728,7 @@ |
357 | case 'context': case 'compound_context': |
358 | return instance.web.pyeval.eval('contexts', [arg]); |
359 | default: |
360 | - throw new Error(instance.web._t("Unknown nonliteral type " + arg.__ref)); |
361 | + throw new Error(_t("Unknown nonliteral type ") + arg.__ref); |
362 | } |
363 | }; |
364 | /** |
365 | @@ -760,11 +762,11 @@ |
366 | } catch (e) { |
367 | d.resolve({ error: { |
368 | code: 400, |
369 | - message: instance.web._t("Evaluation Error"), |
370 | + message: _t("Evaluation Error"), |
371 | data: { |
372 | type: 'local_exception', |
373 | debug: _.str.sprintf( |
374 | - instance.web._t("Local evaluation failure\n%s\n\n%s"), |
375 | + _t("Local evaluation failure\n%s\n\n%s"), |
376 | e.message, JSON.stringify(source)) |
377 | } |
378 | }}); |
379 | |
380 | === modified file 'addons/web/static/src/js/view_form.js' |
381 | --- addons/web/static/src/js/view_form.js 2012-11-29 09:10:38 +0000 |
382 | +++ addons/web/static/src/js/view_form.js 2012-11-29 11:56:19 +0000 |
383 | @@ -148,7 +148,7 @@ |
384 | load_form: function(data) { |
385 | var self = this; |
386 | if (!data) { |
387 | - throw new Error("No data provided."); |
388 | + throw new Error(_t("No data provided.")); |
389 | } |
390 | if (this.arch) { |
391 | throw "Form view does not support multiple calls to load_form"; |
392 | @@ -316,12 +316,12 @@ |
393 | var self = this, set_values = []; |
394 | if (!record) { |
395 | this.set({ 'title' : undefined }); |
396 | - this.do_warn("Form", "The record could not be found in the database.", true); |
397 | + this.do_warn(_t("Form"), _t("The record could not be found in the database."), true); |
398 | return $.Deferred().reject(); |
399 | } |
400 | this.datarecord = record; |
401 | this._actualize_mode(); |
402 | - this.set({ 'title' : record.id ? record.display_name : "New" }); |
403 | + this.set({ 'title' : record.id ? record.display_name : _t("New") }); |
404 | |
405 | _(this.fields).each(function (field, f) { |
406 | field._dirty_flag = false; |
407 | @@ -431,7 +431,7 @@ |
408 | var onchange = _.str.trim(on_change); |
409 | var call = onchange.match(/^\s?(.*?)\((.*?)\)\s?$/); |
410 | if (!call) { |
411 | - throw new Error("Wrong on change format: " + onchange); |
412 | + throw new Error(_.str.sprintf( _t("Wrong on change format: %s"), onchange )); |
413 | } |
414 | |
415 | var method = call[1]; |
416 | @@ -866,7 +866,7 @@ |
417 | }).value(); |
418 | warnings.unshift('<ul>'); |
419 | warnings.push('</ul>'); |
420 | - this.do_warn("The following fields are invalid :", warnings.join('')); |
421 | + this.do_warn(_t("The following fields are invalid:"), warnings.join('')); |
422 | }, |
423 | /** |
424 | * Reload the form after saving |
425 | @@ -1235,11 +1235,11 @@ |
426 | _.each(this.fields_to_init, function($elem) { |
427 | var name = $elem.attr("name"); |
428 | if (!self.fvg.fields[name]) { |
429 | - throw new Error("Field '" + name + "' specified in view could not be found."); |
430 | + throw new Error(_.str.sprintf(_t("Field '%s' specified in view could not be found."), name)); |
431 | } |
432 | var obj = self.fields_registry.get_any([$elem.attr('widget'), self.fvg.fields[name].type]); |
433 | if (!obj) { |
434 | - throw new Error("Widget type '"+ $elem.attr('widget') + "' is not implemented"); |
435 | + throw new Error(_.str.sprintf(_t("Widget type '%s' is not implemented"), $elem.attr('widget'))); |
436 | } |
437 | var w = new (obj)(self.view, instance.web.xml_to_json($elem[0])); |
438 | var $label = self.labels[$elem.attr("name")]; |
439 | @@ -2313,7 +2313,7 @@ |
440 | }, |
441 | on_button_clicked: function() { |
442 | if (!this.get('value') || !this.is_syntax_valid()) { |
443 | - this.do_warn("E-mail error", "Can't send email to invalid e-mail address"); |
444 | + this.do_warn(_t("E-mail error"), _t("Can't send email to invalid e-mail address")); |
445 | } else { |
446 | location.href = 'mailto:' + this.get('value'); |
447 | } |
448 | @@ -2342,7 +2342,7 @@ |
449 | }, |
450 | on_button_clicked: function() { |
451 | if (!this.get('value')) { |
452 | - this.do_warn("Resource error", "This resource is empty"); |
453 | + this.do_warn(_t("Resource error"), _t("This resource is empty")); |
454 | } else { |
455 | var url = $.trim(this.get('value')); |
456 | if(/^www\./i.test(url)) |
457 | @@ -3379,7 +3379,7 @@ |
458 | var views = []; |
459 | _.each(modes, function(mode) { |
460 | if (! _.include(["list", "tree", "graph", "kanban"], mode)) { |
461 | - throw new Error(_.str.sprintf("View type '%s' is not supported in One2Many.", mode)); |
462 | + throw new Error(_.str.sprintf(_t("View type '%s' is not supported in One2Many."), mode)); |
463 | } |
464 | var view = { |
465 | view_id: false, |
466 | @@ -4834,7 +4834,7 @@ |
467 | }, |
468 | on_file_uploaded: function(size, name, content_type, file_base64) { |
469 | if (size === false) { |
470 | - this.do_warn("File Upload", "There was a problem while uploading your file"); |
471 | + this.do_warn(_t("File Upload"), _t("There was a problem while uploading your file")); |
472 | // TODO: use openerp web crashmanager |
473 | console.warn("Error while uploading file : ", name); |
474 | } else { |
475 | @@ -5003,7 +5003,7 @@ |
476 | this.field_manager = field_manager; |
477 | this.node = node; |
478 | if(this.field.type != "many2many" || this.field.relation != 'ir.attachment') { |
479 | - throw "The type of the field '"+this.field.string+"' must be a many2many field with a relation to 'ir.attachment' model."; |
480 | + throw _.str.sprintf(_t("The type of the field '%s' must be a many2many field with a relation to 'ir.attachment' model."), this.field.string); |
481 | } |
482 | this.ds_file = new instance.web.DataSetSearch(this, 'ir.attachment'); |
483 | this.fileupload_id = _.uniqueId('oe_fileupload_temp'); |
484 | |
485 | === modified file 'addons/web/static/src/js/view_list.js' |
486 | --- addons/web/static/src/js/view_list.js 2012-11-29 09:10:38 +0000 |
487 | +++ addons/web/static/src/js/view_list.js 2012-11-29 11:56:19 +0000 |
488 | @@ -389,7 +389,7 @@ |
489 | if (range_stop > total) { |
490 | range_stop = total; |
491 | } |
492 | - spager = _.str.sprintf('%d-%d of %d', range_start, range_stop, total); |
493 | + spager = _.str.sprintf(_t("%d-%d of %d"), range_start, range_stop, total); |
494 | } |
495 | |
496 | this.$pager.find('.oe_list_pager_state').text(spager); |
497 | @@ -887,8 +887,8 @@ |
498 | var $row; |
499 | if (attribute === 'id') { |
500 | if (old_value) { |
501 | - throw new Error("Setting 'id' attribute on existing record " |
502 | - + JSON.stringify(record.attributes)); |
503 | + throw new Error(_.str.sprintf( _t("Setting 'id' attribute on existing record %s"), |
504 | + JSON.stringify(record.attributes) )); |
505 | } |
506 | if (!_.contains(self.dataset.ids, value)) { |
507 | // add record to dataset if not already in (added by |
508 | @@ -956,7 +956,7 @@ |
509 | if (row_id) { |
510 | e.stopPropagation(); |
511 | if (!self.dataset.select_id(row_id)) { |
512 | - throw new Error("Could not find id in dataset"); |
513 | + throw new Error(_t("Could not find id in dataset")); |
514 | } |
515 | self.row_clicked(e); |
516 | } |
517 | @@ -1016,7 +1016,7 @@ |
518 | var command = value[0]; |
519 | // 1. an array of m2m commands (usually (6, false, ids)) |
520 | if (command[0] !== 6) { |
521 | - throw new Error(_t("Unknown m2m command ") + command[0]); |
522 | + throw new Error(_.str.sprintf( _t("Unknown m2m command %s"), command[0])); |
523 | } |
524 | ids = command[2]; |
525 | } else { |
526 | @@ -1324,7 +1324,7 @@ |
527 | } |
528 | // group_label is html-clean (through format or explicit |
529 | // escaping if format failed), can inject straight into HTML |
530 | - $group_column.html(_.str.sprintf("%s (%d)", |
531 | + $group_column.html(_.str.sprintf(_t("%s (%d)"), |
532 | group_label, group.length)); |
533 | |
534 | if (group.length && group.openable) { |
535 | @@ -1743,7 +1743,7 @@ |
536 | } else if (val instanceof Array) { |
537 | output[k] = val[0]; |
538 | } else { |
539 | - throw new Error("Can't convert value " + val + " to context"); |
540 | + throw new Error(_.str.sprintf(_t("Can't convert value %s to context"), val)); |
541 | } |
542 | } |
543 | return output; |
544 | |
545 | === modified file 'addons/web/static/src/js/view_list_editable.js' |
546 | --- addons/web/static/src/js/view_list_editable.js 2012-11-29 09:10:38 +0000 |
547 | +++ addons/web/static/src/js/view_list_editable.js 2012-11-29 11:56:19 +0000 |
548 | @@ -3,6 +3,8 @@ |
549 | * @namespace |
550 | */ |
551 | openerp.web.list_editable = function (instance) { |
552 | + var _t = instance.web._t; |
553 | + |
554 | // editability status of list rows |
555 | instance.web.ListView.prototype.defaults.editable = null; |
556 | |
557 | @@ -775,7 +777,7 @@ |
558 | cancel: function (force) { |
559 | if (!(force || this.form.can_be_discarded())) { |
560 | return $.Deferred().reject({ |
561 | - message: "The form's data can not be discarded"}).promise(); |
562 | + message: _t("The form's data can not be discarded")}).promise(); |
563 | } |
564 | var record = this.record; |
565 | this.record = null; |
566 | |
567 | === modified file 'addons/web/static/src/js/views.js' |
568 | --- addons/web/static/src/js/views.js 2012-11-29 10:11:37 +0000 |
569 | +++ addons/web/static/src/js/views.js 2012-11-29 11:56:19 +0000 |
570 | @@ -807,7 +807,7 @@ |
571 | break; |
572 | case 'tests': |
573 | this.do_action({ |
574 | - name: "JS Tests", |
575 | + name: _t("JS Tests"), |
576 | target: 'new', |
577 | type : 'ir.actions.act_url', |
578 | url: '/web/tests?mod=*' |
579 | @@ -835,7 +835,7 @@ |
580 | break; |
581 | case 'translate': |
582 | this.do_action({ |
583 | - name: "Technical Translation", |
584 | + name: _t("Technical Translation"), |
585 | res_model : 'ir.translation', |
586 | domain : [['type', '!=', 'object'], '|', ['name', '=', this.dataset.model], ['name', 'ilike', this.dataset.model + ',']], |
587 | views: [[false, 'list'], [false, 'form']], |
588 | @@ -1418,7 +1418,7 @@ |
589 | return sindent + node; |
590 | } else if (typeof(node.tag) !== 'string' || !node.children instanceof Array || !node.attrs instanceof Object) { |
591 | throw new Error( |
592 | - _.str.sprintf("Node [%s] is not a JSONified XML node", |
593 | + _.str.sprintf(_t("Node [%s] is not a JSONified XML node"), |
594 | JSON.stringify(node))); |
595 | } |
596 | for (var attr in node.attrs) { |
597 | @@ -1452,7 +1452,7 @@ |
598 | } else if (window.ActiveXObject) { |
599 | return node.xml; |
600 | } else { |
601 | - throw new Error("Could not serialize XML"); |
602 | + throw new Error(_t("Could not serialize XML")); |
603 | } |
604 | }; |
605 | instance.web.str_to_xml = function(s) { |
606 | @@ -1460,7 +1460,7 @@ |
607 | var dp = new DOMParser(); |
608 | var r = dp.parseFromString(s, "text/xml"); |
609 | if (r.body && r.body.firstChild && r.body.firstChild.nodeName == 'parsererror') { |
610 | - throw new Error("Could not parse string to xml"); |
611 | + throw new Error(_t("Could not parse string to xml")); |
612 | } |
613 | return r; |
614 | } |
615 | @@ -1468,7 +1468,7 @@ |
616 | try { |
617 | xDoc = new ActiveXObject("MSXML2.DOMDocument"); |
618 | } catch (e) { |
619 | - throw new Error("Could not find a DOM Parser: " + e.message); |
620 | + throw new Error(_.str.sprintf( _t("Could not find a DOM Parser: %s"), e.message)); |
621 | } |
622 | xDoc.async = false; |
623 | xDoc.preserveWhiteSpace = true; |
624 | |
625 | === modified file 'addons/web_calendar/static/src/js/calendar.js' |
626 | --- addons/web_calendar/static/src/js/calendar.js 2012-11-21 16:04:52 +0000 |
627 | +++ addons/web_calendar/static/src/js/calendar.js 2012-11-29 11:56:19 +0000 |
628 | @@ -88,7 +88,7 @@ |
629 | this.fields = this.fields_view.fields; |
630 | |
631 | if (!this.date_start) { |
632 | - throw new Error("Calendar view has not defined 'date_start' attribute."); |
633 | + throw new Error(_t("Calendar view has not defined 'date_start' attribute.")); |
634 | } |
635 | |
636 | //* Calendar Fields * |
637 | @@ -96,7 +96,7 @@ |
638 | |
639 | if (this.date_delay) { |
640 | if (this.fields[this.date_delay].type != 'float') { |
641 | - throw new Error("Calendar view has a 'date_delay' type != float"); |
642 | + throw new Error(_t("Calendar view has a 'date_delay' type != float")); |
643 | } |
644 | this.calendar_fields.date_delay = {'name': this.date_delay, 'kind': this.fields[this.date_delay].type}; |
645 | } |
646 | |
647 | === modified file 'addons/web_kanban/static/src/js/kanban.js' |
648 | --- addons/web_kanban/static/src/js/kanban.js 2012-11-28 17:13:25 +0000 |
649 | +++ addons/web_kanban/static/src/js/kanban.js 2012-11-29 11:56:19 +0000 |
650 | @@ -409,7 +409,7 @@ |
651 | new_group.do_save_sequences(); |
652 | }).fail(function(error, evt) { |
653 | evt.preventDefault(); |
654 | - alert("An error has occured while moving the record to this group."); |
655 | + alert(_t("An error has occured while moving the record to this group.")); |
656 | self.do_reload(); // TODO: use draggable + sortable in order to cancel the dragging when the rcp fails |
657 | }); |
658 | } |
659 | |
660 | === modified file 'addons/web_view_editor/static/src/js/view_editor.js' |
661 | --- addons/web_view_editor/static/src/js/view_editor.js 2012-11-05 09:30:13 +0000 |
662 | +++ addons/web_view_editor/static/src/js/view_editor.js 2012-11-29 11:56:19 +0000 |
663 | @@ -161,7 +161,7 @@ |
664 | } |
665 | }); |
666 | msg += "</ul>"; |
667 | - this.do_warn("The following fields are invalid :", msg); |
668 | + this.do_warn(_t("The following fields are invalid :"), msg); |
669 | }, |
670 | add_node_name : function(node) { |
671 | if(node.tagName.toLowerCase() == "button" || node.tagName.toLowerCase() == "field"){ |
672 | @@ -260,7 +260,7 @@ |
673 | "arch": view_arch_list}); |
674 | }); |
675 | } else { |
676 | - self.do_warn("Please select view in list :"); |
677 | + self.do_warn(_t("Please select view in list :")); |
678 | } |
679 | }); |
680 | }, |
681 | @@ -387,10 +387,10 @@ |
682 | self.inherited_view(selected_row); |
683 | } |
684 | }else{ |
685 | - alert("Can't Update View"); |
686 | + alert(_t("Can't Update View")); |
687 | } |
688 | }else{ |
689 | - alert("Select an element"); |
690 | + alert(_t("Select an element")); |
691 | } |
692 | }}, |
693 | {text: _t("Preview"), click: function() { |
694 | @@ -983,7 +983,7 @@ |
695 | } else { |
696 | table_selector.append('<td align="right">' + node.string + '</td>' + type_widget.render() ); |
697 | if (node.name == "field_value") { |
698 | - table_selector.append('<td id="new_field" align="right" width="100px"> <button>New Field</button></td>'); |
699 | + table_selector.append('<td id="new_field" align="right" width="100px"> <button>' + _t("New Field") + '</button></td>'); |
700 | } |
701 | } |
702 | type_widget.start(); |
Hi Csaba,
great work! Two issues that should be easy to solve:
Please merge the latest revisions of lp:openerp-web and resolve the conflict in your branch.
Spacing around line 546 in the patch looks dubious. Do you perhaps use tabs instead of spaces?
Thanks,
Stefan.