[MERGE] from trunk
bzr revid: fva@openerp.com-20121004094429-hq4lcntvkycytnj6
This commit is contained in:
commit
28a8768a63
|
@ -227,6 +227,8 @@ def module_installed_bypass_session(dbname):
|
|||
return sorted_modules
|
||||
|
||||
def module_boot(req):
|
||||
return [m for m in req.config.server_wide_modules if m in openerpweb.addons_manifest]
|
||||
# TODO the following will be enabled once we separate the module code and translation loading
|
||||
serverside = []
|
||||
dbside = []
|
||||
for i in req.config.server_wide_modules:
|
||||
|
@ -531,6 +533,20 @@ def parse_context(context, session):
|
|||
except ValueError:
|
||||
return common.nonliterals.Context(session, context)
|
||||
|
||||
|
||||
def _local_web_translations(trans_file):
|
||||
messages = []
|
||||
try:
|
||||
with open(trans_file) as t_file:
|
||||
po = babel.messages.pofile.read_po(t_file)
|
||||
except Exception:
|
||||
return
|
||||
for x in po:
|
||||
if x.id and x.string and "openerp-web" in x.auto_comments:
|
||||
messages.append({'id': x.id, 'string': x.string})
|
||||
return messages
|
||||
|
||||
|
||||
#----------------------------------------------------------
|
||||
# OpenERP Web web Controllers
|
||||
#----------------------------------------------------------
|
||||
|
@ -576,6 +592,7 @@ class Home(openerpweb.Controller):
|
|||
def login(self, req, db, login, key):
|
||||
return login_and_redirect(req, db, login, key)
|
||||
|
||||
|
||||
class WebClient(openerpweb.Controller):
|
||||
_cp_path = "/web/webclient"
|
||||
|
||||
|
@ -658,41 +675,53 @@ class WebClient(openerpweb.Controller):
|
|||
last_modified, checksum)
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def translations(self, req, mods, lang):
|
||||
lang_model = req.session.model('res.lang')
|
||||
ids = lang_model.search([("code", "=", lang)])
|
||||
if ids:
|
||||
lang_obj = lang_model.read(ids[0], ["direction", "date_format", "time_format",
|
||||
"grouping", "decimal_point", "thousands_sep"])
|
||||
else:
|
||||
lang_obj = None
|
||||
def bootstrap_translations(self, req, mods):
|
||||
""" Load local translations from *.po files, as a temporary solution
|
||||
until we have established a valid session. This is meant only
|
||||
for translating the login page and db management chrome, using
|
||||
the browser's language. """
|
||||
lang = req.httprequest.accept_languages.best or 'en'
|
||||
# For performance reasons we only load a single translation, so for
|
||||
# sub-languages (that should only be partially translated) we load the
|
||||
# main language PO instead - that should be enough for the login screen.
|
||||
if '-' in lang: # RFC2616 uses '-' separators for sublanguages
|
||||
lang = [lang.split('-',1)[0], lang]
|
||||
|
||||
if "_" in lang:
|
||||
separator = "_"
|
||||
else:
|
||||
separator = "@"
|
||||
langs = lang.split(separator)
|
||||
langs = [separator.join(langs[:x]) for x in range(1, len(langs) + 1)]
|
||||
|
||||
transs = {}
|
||||
translations_per_module = {}
|
||||
for addon_name in mods:
|
||||
transl = {"messages":[]}
|
||||
transs[addon_name] = transl
|
||||
addons_path = openerpweb.addons_manifest[addon_name]['addons_path']
|
||||
for l in langs:
|
||||
f_name = os.path.join(addons_path, addon_name, "i18n", l + ".po")
|
||||
if not os.path.exists(f_name):
|
||||
continue
|
||||
try:
|
||||
with open(f_name) as t_file:
|
||||
po = babel.messages.pofile.read_po(t_file)
|
||||
except Exception:
|
||||
continue
|
||||
for x in po:
|
||||
if x.id and x.string and "openerp-web" in x.auto_comments:
|
||||
transl["messages"].append({'id': x.id, 'string': x.string})
|
||||
return {"modules": transs,
|
||||
"lang_parameters": lang_obj}
|
||||
f_name = os.path.join(addons_path, addon_name, "i18n", lang + ".po")
|
||||
if not os.path.exists(f_name):
|
||||
continue
|
||||
translations_per_module[addon_name] = {'messages': _local_web_translations(f_name)}
|
||||
|
||||
return {"modules": translations_per_module,
|
||||
"lang_parameters": None}
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def translations(self, req, mods, lang):
|
||||
res_lang = req.session.model('res.lang')
|
||||
ids = res_lang.search([("code", "=", lang)])
|
||||
lang_params = None
|
||||
if ids:
|
||||
lang_params = res_lang.read(ids[0], ["direction", "date_format", "time_format",
|
||||
"grouping", "decimal_point", "thousands_sep"])
|
||||
|
||||
# Regional languages (ll_CC) must inherit/override their parent lang (ll), but this is
|
||||
# done server-side when the language is loaded, so we only need to load the user's lang.
|
||||
ir_translation = req.session.model('ir.translation')
|
||||
translations_per_module = {}
|
||||
messages = ir_translation.search_read([('module','in',mods),('lang','=',lang),
|
||||
('comments','like','openerp-web'),('value','!=',False),
|
||||
('value','!=','')],
|
||||
['module','src','value','lang'], order='module')
|
||||
for mod, msg_group in itertools.groupby(messages, key=operator.itemgetter('module')):
|
||||
translations_per_module.setdefault(mod,{'messages':[]})
|
||||
translations_per_module[mod]['messages'].extend({'id': m['src'],
|
||||
'string': m['value']} \
|
||||
for m in msg_group)
|
||||
return {"modules": translations_per_module,
|
||||
"lang_parameters": lang_params}
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def version_info(self, req):
|
||||
|
@ -769,7 +798,7 @@ class Database(openerpweb.Controller):
|
|||
{'fileToken': int(token)}
|
||||
)
|
||||
except xmlrpclib.Fault, e:
|
||||
return simplejson.dumps([[],[{'error': e.faultCode, 'title': 'backup Database'}]])
|
||||
return simplejson.dumps([[],[{'error': e.faultCode, 'title': 'backup Database'}]])
|
||||
|
||||
@openerpweb.httprequest
|
||||
def restore(self, req, db_file, restore_pwd, new_db):
|
||||
|
|
|
@ -57,7 +57,12 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess
|
|||
if(self.session_is_valid()) {
|
||||
return deferred.pipe(function() { return self.load_modules(); });
|
||||
}
|
||||
return deferred;
|
||||
return $.when(
|
||||
deferred,
|
||||
self.rpc('/web/webclient/bootstrap_translations', {mods: instance._modules}).pipe(function(trans) {
|
||||
instance.web._t.database.set_bundle(trans);
|
||||
})
|
||||
);
|
||||
});
|
||||
},
|
||||
/**
|
||||
|
@ -537,13 +542,9 @@ instance.web.qweb.preprocess_node = function() {
|
|||
if (translation && translation.value === 'off') {
|
||||
return;
|
||||
}
|
||||
var ts = _.str.trim(this.node.data);
|
||||
if (ts.length === 0) {
|
||||
return;
|
||||
}
|
||||
var tr = instance.web._t(ts);
|
||||
if (tr !== ts) {
|
||||
this.node.data = tr;
|
||||
var match = /^(\s*)(.+?)(\s*)$/.exec(this.node.data);
|
||||
if (match) {
|
||||
this.node.data = match[1] + instance.web._t(match[2]) + match[3];
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
|
@ -600,8 +601,7 @@ var messages_by_seconds = function() {
|
|||
[120, _t("Don't leave yet,<br />it's still loading...")],
|
||||
[300, _t("You may not believe it,<br />but the application is actually loading...")],
|
||||
[420, _t("Take a minute to get a coffee,<br />because it's loading...")],
|
||||
[600, _t("It's loading...<br />By the way, did you tried the kitten mode?")],
|
||||
[3600, _t("Maybe you should consider pressing F5...")],
|
||||
[3600, _t("Maybe you should consider reloading the application by pressing F5...")],
|
||||
];
|
||||
};
|
||||
|
||||
|
|
|
@ -1494,7 +1494,7 @@ instance.web.search.ManyToOneField = instance.web.search.CharField.extend({
|
|||
return $.when(facet_from(this, value));
|
||||
}
|
||||
assert(value.length <= 1,
|
||||
_("M2O search fields do not currently handle multiple default values"));
|
||||
_t("M2O search fields do not currently handle multiple default values"));
|
||||
// there are many cases of {search_default_$m2ofield: [id]}, need
|
||||
// to handle this as if it were a single value.
|
||||
value = value[0];
|
||||
|
@ -1578,7 +1578,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
|
|||
|
||||
$filter.unbind('click').click(function () {
|
||||
self.view.query.reset([{
|
||||
category: _("Custom Filter"),
|
||||
category: _t("Custom Filter"),
|
||||
icon: 'M',
|
||||
field: {
|
||||
get_context: function () { return filter.context; },
|
||||
|
|
|
@ -2081,7 +2081,7 @@ instance.web.form.AbstractField = instance.web.form.FormWidget.extend(instance.w
|
|||
var self = this;
|
||||
var trans = new instance.web.DataSet(this, 'ir.translation');
|
||||
return trans.call_button('translate_fields', [this.view.dataset.model, this.view.datarecord.id, this.name, this.view.dataset.get_context()]).then(function(r) {
|
||||
self.do_action(r.result);
|
||||
self.do_action(r);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@ -4282,7 +4282,7 @@ instance.web.form.AbstractFormPopup = instance.web.Widget.extend({
|
|||
this.dataset.create_function = function(data, sup) {
|
||||
var fct = self.options.create_function || sup;
|
||||
return fct.call(this, data).then(function(r) {
|
||||
self.created_elements.push(r.result);
|
||||
self.created_elements.push(r);
|
||||
});
|
||||
};
|
||||
this.dataset.write_function = function(id, data, options, sup) {
|
||||
|
|
|
@ -1190,7 +1190,7 @@ instance.web.View = instance.web.Widget.extend({
|
|||
var context = new instance.web.CompoundContext(dataset.get_context(), action_data.context || {});
|
||||
|
||||
var handler = function (r) {
|
||||
var action = r.result;
|
||||
var action = r;
|
||||
if (action && action.constructor == Object) {
|
||||
var ncontext = new instance.web.CompoundContext(context);
|
||||
if (record_id) {
|
||||
|
|
|
@ -2,12 +2,6 @@
|
|||
<!-- vim:fdl=1:
|
||||
-->
|
||||
<templates id="template" xml:space="preserve">
|
||||
<t t-name="ui.Header">
|
||||
<header>
|
||||
<t t-raw="__content__"/>
|
||||
</header>
|
||||
</t>
|
||||
|
||||
<t t-name="EmptyComponent">
|
||||
<div></div>
|
||||
</t>
|
||||
|
@ -413,7 +407,7 @@
|
|||
<a class="oe_logo" href="#"><img t-att-src='_s + "/web/static/src/img/logo.png"'/></a>
|
||||
<div class="oe_secondary_menus_container"/>
|
||||
<div class="oe_footer">
|
||||
Powered by <a href="http://www.openerp.com" target="_blank"><span>Open</span>ERP</a>
|
||||
Powered by <a href="http://www.openerp.com" target="_blank"><span>OpenERP</span></a>
|
||||
</div>
|
||||
</td>
|
||||
<td class="oe_application">
|
||||
|
@ -1128,7 +1122,7 @@
|
|||
<td>
|
||||
<t t-call="HiddenInputFile">
|
||||
<t t-set="fileupload_id" t-value="widget.fileupload_id"/>
|
||||
<t t-set="fileupload_style">width: 83px;</t>
|
||||
<t t-set="fileupload_style" t-translation="off">width: 83px;</t>
|
||||
<button class="oe_button oe_field_button" type="button">
|
||||
<img t-att-src='_s + "/web/static/src/img/icons/STOCK_DIRECTORY.png"'/>
|
||||
<span>Select</span>
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
# Persian translation for openerp-web
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openerp-web package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openerp-web\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-07-02 09:06+0200\n"
|
||||
"PO-Revision-Date: 2012-10-03 10:24+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Persian <fa@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-04 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16061)\n"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:11
|
||||
msgid "Calendar"
|
||||
msgstr "تقویم"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:70
|
||||
msgid "Filter"
|
||||
msgstr "فیلتر"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:144
|
||||
msgid "Today"
|
||||
msgstr "امروز"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:145
|
||||
msgid "Day"
|
||||
msgstr "روز"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:146
|
||||
msgid "Week"
|
||||
msgstr "هفته"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:147
|
||||
msgid "Month"
|
||||
msgstr "ماه"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:148
|
||||
msgid "New event"
|
||||
msgstr "رویداد جدید"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:149
|
||||
msgid "Save"
|
||||
msgstr "ذخیره"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:150
|
||||
msgid "Cancel"
|
||||
msgstr "لغو کردن"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:151
|
||||
msgid "Details"
|
||||
msgstr "جزئیات "
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:152
|
||||
msgid "Edit"
|
||||
msgstr "ویرایش"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:153
|
||||
msgid "Delete"
|
||||
msgstr "حذف"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:155
|
||||
msgid "Event will be deleted permanently, are you sure?"
|
||||
msgstr "رویداد حذف خواهد شد. آیا مطمئن هستید؟"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:156
|
||||
#: addons/web_calendar/static/src/js/calendar.js:169
|
||||
msgid "Description"
|
||||
msgstr "توضیحات"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:157
|
||||
msgid "Time period"
|
||||
msgstr "بازه زمانی"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:158
|
||||
msgid "Full day"
|
||||
msgstr "تمام روز"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:161
|
||||
msgid "Do you want to edit the whole set of repeated events?"
|
||||
msgstr "آیا میخواهید مجموعه کامل رویدادهای تکراری را ویرایش کنید؟"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:162
|
||||
msgid "Repeat event"
|
||||
msgstr "تکرار رویداد"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:163
|
||||
msgid "Disabled"
|
||||
msgstr "غیرفعال"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:164
|
||||
msgid "Enabled"
|
||||
msgstr "فعال"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:167
|
||||
#: addons/web_calendar/static/src/js/calendar.js:175
|
||||
msgid "Agenda"
|
||||
msgstr "دستور کار"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:168
|
||||
msgid "Date"
|
||||
msgstr "تاریخ"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/js/calendar.js:172
|
||||
msgid "Year"
|
||||
msgstr "سال"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:5
|
||||
#: addons/web_calendar/static/src/xml/web_calendar.xml:6
|
||||
msgid " "
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "Navigator"
|
||||
#~ msgstr "هدایتگر"
|
|
@ -0,0 +1,81 @@
|
|||
# Persian translation for openerp-web
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openerp-web package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openerp-web\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-07-02 09:06+0200\n"
|
||||
"PO-Revision-Date: 2012-10-03 10:07+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Persian <fa@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-04 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16061)\n"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_diagram/static/src/js/diagram.js:11
|
||||
msgid "Diagram"
|
||||
msgstr "نمودار"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_diagram/static/src/js/diagram.js:165
|
||||
msgid "Are you sure?"
|
||||
msgstr "آیا مطمئن هستید؟"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_diagram/static/src/js/diagram.js:195
|
||||
msgid ""
|
||||
"Deleting this node cannot be undone.\n"
|
||||
"It will also delete all connected transitions.\n"
|
||||
"\n"
|
||||
"Are you sure ?"
|
||||
msgstr ""
|
||||
"عمل حذف برگشت پذیر نیست.\n"
|
||||
"همچنین تمام اتصال ها را نیز حذف میکند.\n"
|
||||
"\n"
|
||||
"آیا مطمئن هستید؟"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_diagram/static/src/js/diagram.js:213
|
||||
msgid ""
|
||||
"Deleting this transition cannot be undone.\n"
|
||||
"\n"
|
||||
"Are you sure ?"
|
||||
msgstr ""
|
||||
"حذف این انتقال برگشت پذیر نیست.\n"
|
||||
"\n"
|
||||
"آیا از خذف مطمئن هستید؟"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_diagram/static/src/js/diagram.js:224
|
||||
#: addons/web_diagram/static/src/js/diagram.js:257
|
||||
msgid "Activity"
|
||||
msgstr "فعالیت"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_diagram/static/src/js/diagram.js:232
|
||||
#: addons/web_diagram/static/src/js/diagram.js:296
|
||||
msgid "Open: "
|
||||
msgstr "باز: "
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_diagram/static/src/js/diagram.js:262
|
||||
#: addons/web_diagram/static/src/js/diagram.js:314
|
||||
msgid "Create:"
|
||||
msgstr "ایجاد کردن"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_diagram/static/src/js/diagram.js:289
|
||||
#: addons/web_diagram/static/src/js/diagram.js:308
|
||||
msgid "Transition"
|
||||
msgstr "انتقال"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_diagram/static/src/xml/base_diagram.xml:6
|
||||
msgid "New Node"
|
||||
msgstr "گره جدید"
|
|
@ -0,0 +1,28 @@
|
|||
# Persian translation for openerp-web
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openerp-web package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openerp-web\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-07-02 09:06+0200\n"
|
||||
"PO-Revision-Date: 2012-10-03 10:11+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Persian <fa@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-04 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16061)\n"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_gantt/static/src/js/gantt.js:11
|
||||
msgid "Gantt"
|
||||
msgstr "گانت"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_gantt/static/src/xml/web_gantt.xml:10
|
||||
msgid "Create"
|
||||
msgstr "ایجاد کردن"
|
|
@ -0,0 +1,98 @@
|
|||
# Persian translation for openerp-web
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openerp-web package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openerp-web\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-07-02 09:06+0200\n"
|
||||
"PO-Revision-Date: 2012-10-03 10:12+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Persian <fa@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-04 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16061)\n"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/js/graph.js:19
|
||||
msgid "Graph"
|
||||
msgstr "گراف"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:5
|
||||
msgid "Graph Options"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:7
|
||||
msgid "Graph Mode"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:11
|
||||
msgid "Pie"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:12
|
||||
msgid "Bars"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:14
|
||||
msgid "Lines"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:15
|
||||
msgid "Areas"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:18
|
||||
msgid "Radar"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:20
|
||||
msgid "Legend"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:24
|
||||
msgid "Hidden"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:25
|
||||
msgid "Inside"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:26
|
||||
msgid "Top"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:28
|
||||
msgid "Actions"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:32
|
||||
msgid "Switch Axis"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:33
|
||||
msgid "Show Data"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_graph/static/src/xml/web_graph.xml:34
|
||||
msgid "Download as PNG"
|
||||
msgstr ""
|
|
@ -0,0 +1,66 @@
|
|||
# Persian translation for openerp-web
|
||||
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
|
||||
# This file is distributed under the same license as the openerp-web package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openerp-web\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2012-07-02 09:06+0200\n"
|
||||
"PO-Revision-Date: 2012-10-03 10:14+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Persian <fa@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2012-10-04 05:33+0000\n"
|
||||
"X-Generator: Launchpad (build 16061)\n"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_kanban/static/src/js/kanban.js:10
|
||||
msgid "Kanban"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_kanban/static/src/js/kanban.js:293
|
||||
msgid "Undefined"
|
||||
msgstr "تعریف نشده"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_kanban/static/src/js/kanban.js:471
|
||||
msgid "Are you sure you want to delete this record ?"
|
||||
msgstr "آیا از حذف این رکورد مطمئن هستید؟"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_kanban/static/src/js/kanban.js:839
|
||||
msgid "Create: "
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_kanban/static/src/xml/web_kanban.xml:41
|
||||
msgid "Show more... ("
|
||||
msgstr "نمایش بیشتر"
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_kanban/static/src/xml/web_kanban.xml:41
|
||||
msgid "remaining)"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_kanban/static/src/xml/web_kanban.xml:71
|
||||
msgid "Add"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_kanban/static/src/xml/web_kanban.xml:71
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
|
||||
#. openerp-web
|
||||
#: addons/web_kanban/static/src/xml/web_kanban.xml:72
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "Create"
|
||||
#~ msgstr "ایجاد کردن"
|
|
@ -1,6 +0,0 @@
|
|||
[extractors]
|
||||
qweb = npybabel:extract_qweb
|
||||
javascript = npybabel:extract_javascript
|
||||
[javascript: static/src/js/**.js]
|
||||
[qweb: static/src/xml/**.xml]
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 2.8 KiB |
|
@ -22,8 +22,6 @@ Contents:
|
|||
list-view
|
||||
form-notes
|
||||
|
||||
templates
|
||||
|
||||
guides/client-action
|
||||
|
||||
Indices and tables
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
.. highlight:: xml
|
||||
|
||||
Generic templates
|
||||
=================
|
||||
|
||||
Generic template names should be prefixed by ``ui.`` to indicate their
|
||||
special role.
|
||||
|
||||
Global Header: ``ui.Header``
|
||||
----------------------------
|
||||
|
||||
Role
|
||||
++++
|
||||
|
||||
This template is mostly dedicated to client actions taking over the
|
||||
whole content area, and full-HTML form views (especially those opening
|
||||
in the ``inline`` target).
|
||||
|
||||
It is used to display a buttons container (and can also be used for
|
||||
status bars). The buttons should simply be placed inside the
|
||||
``ui.Header`` body.
|
||||
|
||||
Arguments
|
||||
+++++++++
|
||||
|
||||
The template only uses its body as argument.
|
||||
|
||||
Example
|
||||
+++++++
|
||||
|
||||
::
|
||||
|
||||
<t t-call="ui.Header">
|
||||
<button string="Apply" type="object" name="execute" class="oe_highlight"/>
|
||||
or
|
||||
<button string="Cancel" type="object" name="cancel" class="oe_link"/>
|
||||
</t>
|
||||
|
||||
This block demonstrates a common pattern in OpenERP views and widgets:
|
||||
a highlighted button, and a discard button styled as a link to cancel
|
||||
the action:
|
||||
|
||||
.. image:: ./images/templates/ui.Header.*
|
||||
|
||||
In this case, both buttons are OpenERP action buttons.
|
|
@ -1,66 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
usage() {
|
||||
cat << EOF
|
||||
usage: $0 -a [DIR]
|
||||
usage: $0 <ADDON_DIR> <OUTPUT_FILE>
|
||||
|
||||
OPTIONS:
|
||||
-a [DIR] export the .pot files for all web addons found
|
||||
at target path (default: ./addons)
|
||||
-h print this message
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
do_all=
|
||||
|
||||
while getopts "a" opt
|
||||
do
|
||||
case "$opt" in
|
||||
a)
|
||||
do_all=true;;
|
||||
h)
|
||||
usage;;
|
||||
\?)
|
||||
usage;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $((OPTIND-1))
|
||||
|
||||
if [ -n "$do_all" ]
|
||||
then
|
||||
if [ "x$(which msgcat)" = "x" ]
|
||||
then
|
||||
echo "The msgcat command from the gettext tools is required in the PATH."
|
||||
echo "On a Debian/Ubuntu system you may install gettext via 'sudo apt-get install gettext'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Extracting all web addons translations"
|
||||
executable=$0
|
||||
target_dir=${1:-./addons}
|
||||
echo "Using target dir: ${target_dir}"
|
||||
for mod in $(find ${target_dir} -type d -name 'static' -exec sh -c 'basename $(dirname {})' \;); do
|
||||
echo ${mod}
|
||||
mod_pot=${target_dir}/${mod}/i18n/${mod}.pot
|
||||
web_pot=${mod_pot}.web
|
||||
mkdir -p $(dirname ${web_pot})
|
||||
$executable ${target_dir}/${mod} ${web_pot}
|
||||
if [ -f "${mod_pot}" ]; then
|
||||
echo "Merging with existing PO file: ${mod_pot}"
|
||||
msgcat --force-po -o "${mod_pot}.tmp" ${mod_pot} ${web_pot}
|
||||
mv ${mod_pot}.tmp ${mod_pot}
|
||||
rm ${web_pot}
|
||||
else
|
||||
echo "Renaming to final PO file: ${mod_pot}"
|
||||
mv ${web_pot} ${mod_pot}
|
||||
fi
|
||||
done
|
||||
elif [ -n "$2" ]
|
||||
then
|
||||
./npybabel.py extract -F babel.cfg -o $2 -k _t -k _lt --no-default-keywords $1
|
||||
else
|
||||
usage
|
||||
fi
|
140
npybabel.py
140
npybabel.py
|
@ -1,140 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# EASY-INSTALL-ENTRY-SCRIPT: 'Babel==0.9.6','console_scripts','pybabel'
|
||||
__requires__ = 'Babel==0.9.6'
|
||||
import sys
|
||||
from pkg_resources import load_entry_point
|
||||
import re
|
||||
import json
|
||||
from lxml import etree as elt
|
||||
from babel.messages import extract
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(
|
||||
load_entry_point('Babel==0.9.6', 'console_scripts', 'pybabel')()
|
||||
)
|
||||
|
||||
XMLJS_EXPR = re.compile(r"""(?:\_t *\( *((?:"(?:[^"\\]|\\.)*")|(?:'(?:[^'\\]|\\.)*')) *\))""")
|
||||
|
||||
TRANSLATION_FLAG_COMMENT = "openerp-web"
|
||||
|
||||
# List of etree._Element subclasses that we choose to ignore when parsing XML.
|
||||
# We include the *Base ones just in case, currently they seem to be subclasses of the _* ones.
|
||||
SKIPPED_ELEMENT_TYPES = (elt._Comment, elt._ProcessingInstruction, elt.CommentBase, elt.PIBase)
|
||||
|
||||
def extract_xmljs(fileobj, keywords, comment_tags, options):
|
||||
"""Extract messages from Javascript code embedded into XML documents.
|
||||
This complements the ``extract_javascript`` extractor which works
|
||||
only on pure .js files, and the``extract_qweb`` extractor, which only
|
||||
extracts XML text.
|
||||
|
||||
:param fileobj: the file-like object the messages should be extracted
|
||||
from
|
||||
:param keywords: a list of keywords (i.e. function names) that should
|
||||
be recognized as translation functions
|
||||
:param comment_tags: a list of translator tags to search for and
|
||||
include in the results
|
||||
:param options: a dictionary of additional options (optional)
|
||||
:return: an iterator over ``(lineno, funcname, message, comments)``
|
||||
tuples
|
||||
:rtype: ``iterator``
|
||||
"""
|
||||
assert False, """ the XMLJS extractor does not work and was removed:
|
||||
|
||||
* Babel apparently does not accept two extractors for the same set of files
|
||||
so it would not run the xmljs extractor at all, extraction of JS stuff
|
||||
needs to be done from the XML extractor
|
||||
* The regex above fails up if there are back-slashed quotes within the
|
||||
translatable string (the string marked with _t), it just won't match the
|
||||
string
|
||||
* While extraction succeeds on XML entities (e.g. "), translation
|
||||
matching will fail if those entities are kept in the PO msgid as the
|
||||
XML parser will get an un-escaped string, without those entities (so a
|
||||
text extractor will extract ``Found match "%s"``, but the msgid
|
||||
of the PO file must be ``Found match "%s"`` or the translation will fail
|
||||
* single-quoted strings are not valid JSON string, so single-quoted strings
|
||||
matched by the regex (likely since XML attributes are double-quoted,
|
||||
single quotes within them don't have to be escaped) will blow up when
|
||||
json-parsed for their content
|
||||
|
||||
I think that's about it.
|
||||
|
||||
If this extractor is reimplemented, it should be integrated into
|
||||
extract_qweb, either in the current pass (probably not a good idea) or as
|
||||
a separate pass using iterparse, matching either elements with t-js or
|
||||
some other kinds of t-* directives (@t-esc, @t-raw, @t-att, others?),
|
||||
shove the attribute content into a StringIO and pass *that* to Babel's
|
||||
own extract_javascript; then add a line offset in order to yield the
|
||||
correct line number.
|
||||
"""
|
||||
content = fileobj.read()
|
||||
found = XMLJS_EXPR.finditer(content)
|
||||
index = 0
|
||||
line_nbr = 0
|
||||
for f in found:
|
||||
msg = f.group(1)
|
||||
msg = json.loads(msg)
|
||||
while index < f.start():
|
||||
if content[index] == "\n":
|
||||
line_nbr += 1
|
||||
index += 1
|
||||
yield (line_nbr, None, msg, [TRANSLATION_FLAG_COMMENT])
|
||||
|
||||
def extract_qweb(fileobj, keywords, comment_tags, options):
|
||||
"""Extract messages from qweb template files.
|
||||
:param fileobj: the file-like object the messages should be extracted
|
||||
from
|
||||
:param keywords: a list of keywords (i.e. function names) that should
|
||||
be recognized as translation functions
|
||||
:param comment_tags: a list of translator tags to search for and
|
||||
include in the results
|
||||
:param options: a dictionary of additional options (optional)
|
||||
:return: an iterator over ``(lineno, funcname, message, comments)``
|
||||
tuples
|
||||
:rtype: ``iterator``
|
||||
"""
|
||||
result = []
|
||||
def handle_text(text, lineno):
|
||||
text = (text or "").strip()
|
||||
if len(text) > 1: # Avoid mono-char tokens like ':' ',' etc.
|
||||
result.append((lineno, None, text, [TRANSLATION_FLAG_COMMENT]))
|
||||
|
||||
# not using elementTree.iterparse because we need to skip sub-trees in case
|
||||
# the ancestor element had a reason to be skipped
|
||||
def iter_elements(current_element):
|
||||
for el in current_element:
|
||||
if isinstance(el, SKIPPED_ELEMENT_TYPES): continue
|
||||
if "t-js" not in el.attrib and \
|
||||
not ("t-jquery" in el.attrib and "t-operation" not in el.attrib) and \
|
||||
not ("t-translation" in el.attrib and el.attrib["t-translation"].strip() == "off"):
|
||||
handle_text(el.text, el.sourceline)
|
||||
for att in ('title', 'alt', 'label', 'placeholder'):
|
||||
if att in el.attrib:
|
||||
handle_text(el.attrib[att], el.sourceline)
|
||||
iter_elements(el)
|
||||
handle_text(el.tail, el.sourceline)
|
||||
|
||||
tree = elt.parse(fileobj)
|
||||
iter_elements(tree.getroot())
|
||||
|
||||
return result
|
||||
|
||||
def extract_javascript(fileobj, keywords, comment_tags, options):
|
||||
"""Extract messages from Javascript source files. This extractor delegates
|
||||
to babel's buit-in javascript extractor, but adds a special comment
|
||||
used as a flag to identify web translations.
|
||||
|
||||
:param fileobj: the file-like object the messages should be extracted
|
||||
from
|
||||
:param keywords: a list of keywords (i.e. function names) that should
|
||||
be recognized as translation functions
|
||||
:param comment_tags: a list of translator tags to search for and
|
||||
include in the results
|
||||
:param options: a dictionary of additional options (optional)
|
||||
:return: an iterator over ``(lineno, funcname, message, comments)``
|
||||
tuples
|
||||
:rtype: ``iterator``
|
||||
"""
|
||||
for (message_lineno, funcname, messages, comments) in \
|
||||
extract.extract_javascript(fileobj, keywords, comment_tags, options):
|
||||
comments.append(TRANSLATION_FLAG_COMMENT)
|
||||
yield (message_lineno, funcname, messages, comments)
|
Loading…
Reference in New Issue