diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index 56ce25476c5..c9bd7ddfeab 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -9,6 +9,7 @@ import re import simplejson import textwrap import xmlrpclib +import time from xml.etree import ElementTree from cStringIO import StringIO @@ -20,6 +21,8 @@ import openerpweb.nonliterals from babel.messages.pofile import read_po +_REPORT_POLLER_DELAY = 0.05 + # Should move to openerpweb.Xml2Json class Xml2Json: # xml2json-direct @@ -432,10 +435,13 @@ def load_actions_from_ir_values(req, key, key2, models, meta): for id, name, action in actions] def clean_action(req, action): + action.setdefault('flags', {}) + if action['type'] != 'ir.actions.act_window': + return action + context = req.session.eval_context(req.context) eval_ctx = req.session.evaluation_context(context) - action.setdefault('flags', {}) - + # values come from the server, we can just eval them if isinstance(action.get('context'), basestring): action['context'] = eval( action['context'], eval_ctx ) or {} @@ -1272,3 +1278,25 @@ class Export(View): return export_xls(field, result) else: return export_csv(field, result) + +class Export(View): + _cp_path = "/base/report" + + @openerpweb.jsonrequest + def get_report(self, req, action): + report_srv = req.session.proxy("report") + context = req.session.eval_context(openerpweb.nonliterals.CompoundContext(req.context, \ + action["context"])) + + args = [req.session._db, req.session._uid, req.session._password, action["report_name"], context["active_ids"], {"id": context["active_id"], "model": context["active_model"], "report_type": action["report_type"]}, context] + report_id = report_srv.report(*args) + report = None + while True: + args2 = [req.session._db, req.session._uid, req.session._password, report_id] + report = report_srv.report_get(*args2) + if report["state"]: + break + time.sleep(_REPORT_POLLER_DELAY) + + #TODO: ok now we've got the report, and so what? + return False diff --git a/addons/base/static/lib/jquery.contextmenu/jquery.contextmenu.r2.packed.js b/addons/base/static/lib/jquery.contextmenu/jquery.contextmenu.r2.packed.js index cb456eed14c..2356f3b606b 100644 --- a/addons/base/static/lib/jquery.contextmenu/jquery.contextmenu.r2.packed.js +++ b/addons/base/static/lib/jquery.contextmenu/jquery.contextmenu.r2.packed.js @@ -32,7 +32,7 @@ if(!menu) { menu=$('
').hide().css({ position:'absolute', - zIndex:'500' + zIndex:'2000' }).appendTo('body').bind('click', function(e) { e.stopPropagation() }) diff --git a/addons/base/static/src/css/base.css b/addons/base/static/src/css/base.css index 46364c4fa1d..b0a7dd3c8c8 100644 --- a/addons/base/static/src/css/base.css +++ b/addons/base/static/src/css/base.css @@ -895,6 +895,9 @@ label.error { position: relative; top: 4px; } +.openerp .oe_trad_field.touched { + border: 1px solid green !important; +} /* http://www.quirksmode.org/dom/inputfile.html * http://stackoverflow.com/questions/2855589/replace-input-type-file-by-an-image diff --git a/addons/base/static/src/js/data.js b/addons/base/static/src/js/data.js index 668898dd66c..e95adaf8870 100644 --- a/addons/base/static/src/js/data.js +++ b/addons/base/static/src/js/data.js @@ -355,12 +355,13 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data * @param {Function} error_callback function called in case of write error * @returns {$.Deferred} */ - write: function (id, data, callback, error_callback) { + write: function (id, data, options, callback, error_callback) { + var options = options || {}; return this.rpc('/base/dataset/save', { model: this.model, id: id, data: data, - context: this.get_context() + context: this.get_context(options.context) }, callback, error_callback); }, /** diff --git a/addons/base/static/src/js/form.js b/addons/base/static/src/js/form.js index e2d1f88bfd8..78a51a8c220 100644 --- a/addons/base/static/src/js/form.js +++ b/addons/base/static/src/js/form.js @@ -157,6 +157,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormVi this.do_update_pager(record.id == null); if (this.sidebar) { this.sidebar.attachments.do_update(); + this.sidebar.$element.find('.oe_sidebar_translate').toggleClass('oe_hide', !record.id); } if (this.default_focus_field && !this.embedded_view) { this.default_focus_field.focus(); @@ -342,7 +343,7 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormVi self.on_created(r, success, prepend_on_create); }); } else { - return this.dataset.write(this.datarecord.id, values, function(r) { + return this.dataset.write(this.datarecord.id, values, {}, function(r) { self.on_saved(r, success); }); } @@ -880,6 +881,9 @@ openerp.base.form.Field = openerp.base.form.Widget.extend({ }, update_dom: function() { this._super.apply(this, arguments); + if (this.field.translate) { + this.$element.find('.oe_field_translate').toggle(!!this.view.datarecord.id); + } if (!this.disable_utility_classes) { this.$element.toggleClass('disabled', this.readonly); this.$element.toggleClass('required', this.required); @@ -1520,12 +1524,14 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({ }, set_value: function(value) { value = value || null; + this.invalid = false; var self = this; - var _super = this._super; this.tmp_value = value; + self.update_dom(); + self.on_value_changed(); var real_set_value = function(rval) { self.tmp_value = undefined; - _super.apply(self, rval); + self.value = rval; self.original_value = undefined; self._change_int_ext_value(rval); }; @@ -1551,7 +1557,8 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({ }, validate: function() { this.invalid = false; - if (this.value === null) { + var val = this.tmp_value !== undefined ? this.tmp_value : this.value; + if (val === null) { this.invalid = this.required; } }, @@ -1559,14 +1566,16 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({ var self = this; if (!self.value) return; - self.rpc("/base/action/load", { - action_id: related[2].id, - context: { + var additional_context = { active_id: self.value[0], active_ids: [self.value[0]], active_model: self.field.relation - } + }; + self.rpc("/base/action/load", { + action_id: related[2].id, + context: additional_context }, function(result) { + result.result.context = _.extend(result.result.context || {}, additional_context); self.do_action(result.result); }); } @@ -1864,10 +1873,13 @@ openerp.base.form.One2ManyListView = openerp.base.ListView.extend({ pop.show_element(self.o2m.field.relation, id, self.o2m.build_context(),{ auto_write: false, alternative_form_view: self.o2m.field.views ? self.o2m.field.views["form"] : undefined, - parent_view: self.o2m.view + parent_view: self.o2m.view, + read_function: function() { + return self.o2m.dataset.read_ids.apply(self.o2m.dataset, arguments); + } }); pop.on_write.add(function(id, data) { - self.o2m.dataset.write(id, data, function(r) { + self.o2m.dataset.write(id, data, {}, function(r) { self.o2m.reload_current_view(); }); }); @@ -2136,6 +2148,7 @@ openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({ * options: * - alternative_form_view * - auto_write (default true) + * - read_function * - parent_view */ show_element: function(model, row_id, context, options) { @@ -2151,7 +2164,8 @@ openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({ }, start: function() { this._super(); - this.dataset = new openerp.base.ReadOnlyDataSetSearch(this, this.model, this.context); + this.dataset = new openerp.base.form.FormOpenDataset(this, this.model, this.context); + this.dataset.fop = this; this.dataset.ids = [this.row_id]; this.dataset.index = 0; this.dataset.parent_view = this.options.parent_view; @@ -2164,7 +2178,7 @@ openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({ var self = this; var wdataset = new openerp.base.DataSetSearch(this, this.model, this.context, this.domain); wdataset.parent_view = this.options.parent_view; - wdataset.write(id, data, function(r) { + wdataset.write(id, data, {}, function(r) { self.on_write_completed(); }); }, @@ -2193,6 +2207,16 @@ openerp.base.form.FormOpenPopup = openerp.base.OldWidget.extend({ } }); +openerp.base.form.FormOpenDataset = openerp.base.ReadOnlyDataSetSearch.extend({ + read_ids: function() { + if (this.fop.options.read_function) { + return this.fop.options.read_function.apply(null, arguments); + } else { + return this._super.apply(this, arguments); + } + } +}); + openerp.base.form.FieldReference = openerp.base.form.Field.extend({ init: function(view, node) { this._super(view, node); diff --git a/addons/base/static/src/js/views.js b/addons/base/static/src/js/views.js index 689a72ef7f1..1fc04bf8965 100644 --- a/addons/base/static/src/js/views.js +++ b/addons/base/static/src/js/views.js @@ -123,6 +123,14 @@ openerp.base.ActionManager = openerp.base.Widget.extend({ this.content_stop(); var ClientWidget = openerp.base.client_actions.get_object(action.tag); (this.client_widget = new ClientWidget(this, action.params)).appendTo(this); + }, + ir_actions_report_xml: function(action) { + this.rpc('/base/report/get_report', { + action: action, + context: {} + }).then(function(result) { + debugger; + }); } }); @@ -438,14 +446,17 @@ openerp.base.Sidebar = openerp.base.Widget.extend({ //TODO niv: maybe show a warning? return false; } + var additional_context = { + active_id: ids[0], + active_ids: ids, + active_model: self.widget_parent.dataset.model + }; self.rpc("/base/action/load", { action_id: item.action.id, - context: { - active_id: ids[0], - active_ids: ids, - active_model: self.widget_parent.dataset.model - } + context: additional_context }, function(result) { + result.result.context = _.extend(result.result.context || {}, + additional_context); result.result.flags = result.result.flags || {}; result.result.flags.new_window = true; self.do_action(result.result); @@ -472,6 +483,9 @@ openerp.base.Sidebar = openerp.base.Widget.extend({ openerp.base.TranslateDialog = openerp.base.Dialog.extend({ dialog_title: _t("Translations"), init: function(view) { + // TODO fme: should add the language to fields_view_get because between the fields view get + // and the moment the user opens the translation dialog, the user language could have been changed + this.view_language = view.session.user_context.lang; this['on_button' + _t("Save")] = this.on_button_Save; this['on_button' + _t("Close")] = this.on_button_Close; this._super(view, { @@ -500,6 +514,9 @@ openerp.base.TranslateDialog = openerp.base.Dialog.extend({ self.select_tab('view'); } self.$fields_form = self.$element.find('.oe_translation_form'); + self.$fields_form.find('.oe_trad_field').change(function() { + $(this).toggleClass('touched', ($(this).val() != $(this).attr('data-value'))); + }); }); return this; }, @@ -514,19 +531,27 @@ openerp.base.TranslateDialog = openerp.base.Dialog.extend({ _.each(self.languages, function(lg) { var deff = $.Deferred(); deffered.push(deff); - self.rpc('/base/dataset/get', { - model: self.view.dataset.model, - ids: [self.view.datarecord.id], - fields: self.translatable_fields_keys, - context: self.view.dataset.get_context({ - 'lang': lg.code - }) - }, function(values) { + var callback = function(values) { _.each(self.translatable_fields_keys, function(f) { - self.$fields_form.find('.oe_trad_field[name="' + lg.code + '-' + f + '"]').val(values[0][f] || ''); + self.$fields_form.find('.oe_trad_field[name="' + lg.code + '-' + f + '"]').val(values[0][f] || '').attr('data-value', values[0][f] || ''); }); deff.resolve(); - }); + } + if (lg.code === self.view_language) { + var values = {}; + _.each(self.translatable_fields_keys, function(field) { + values[field] = self.view.fields[field].get_value(); + }); + callback([values]); + } else { + self.rpc('/base/dataset/get', { + model: self.view.dataset.model, + ids: [self.view.datarecord.id], + fields: self.translatable_fields_keys, + context: self.view.dataset.get_context({ + 'lang': lg.code + })}, callback); + } }); $.when.apply(null, deffered).then(callback); }, @@ -562,6 +587,24 @@ openerp.base.TranslateDialog = openerp.base.Dialog.extend({ }); }, on_button_Save: function() { + var trads = {}, + self = this; + self.$fields_form.find('.oe_trad_field.touched').each(function() { + var field = $(this).attr('name').split('-'); + if (!trads[field[0]]) { + trads[field[0]] = {}; + } + trads[field[0]][field[1]] = $(this).val(); + }); + _.each(trads, function(data, code) { + if (code === self.view_language) { + _.each(data, function(value, field) { + self.view.fields[field].set_value(value); + }); + } else { + self.view.dataset.write(self.view.datarecord.id, data, { 'lang': code }); + } + }); this.close(); }, on_button_Close: function() { @@ -667,7 +710,7 @@ openerp.base.View = openerp.base.Widget.extend({ }, { label: "Translate", callback: this.on_sidebar_translate, - classname: 'oe_sidebar_translate' + classname: 'oe_sidebar_translate oe_hide' }, { label: "View Log", callback: this.on_sidebar_view_log, diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml index 0c17e70cfc7..40bc7cb4c5a 100644 --- a/addons/base/static/src/xml/base.xml +++ b/addons/base/static/src/xml/base.xml @@ -474,8 +474,8 @@