summaryrefslogtreecommitdiff
path: root/addons/base/static
diff options
context:
space:
mode:
authornoz (OpenERP) <noz@tinyerp.com>2011-07-13 15:02:09 +0530
committernoz (OpenERP) <noz@tinyerp.com>2011-07-13 15:02:09 +0530
commitbcccef82d08ce5ecc626fa6a47f2d13f854bf176 (patch)
treeb041d9716df0a55e283c3feee5c327c3cd8015f3 /addons/base/static
parent59bb0fd4e637cd4100e53d24df184ad5c53ed86b (diff)
parent97966e8effa47972106d7f016532d80b64f96f99 (diff)
[Merge] Merged with main branch.
bzr revid: noz@tinyerp.com-20110713093209-3f2njjjhp0cgd5rj
Diffstat (limited to 'addons/base/static')
-rw-r--r--addons/base/static/lib/qweb/qweb2.js1
-rw-r--r--addons/base/static/src/js/chrome.js6
-rw-r--r--addons/base/static/src/js/data.js46
-rw-r--r--addons/base/static/src/js/form.js57
-rw-r--r--addons/base/static/src/js/list.js34
-rw-r--r--addons/base/static/src/js/views.js95
-rw-r--r--addons/base/static/src/xml/base.xml44
7 files changed, 183 insertions, 100 deletions
diff --git a/addons/base/static/lib/qweb/qweb2.js b/addons/base/static/lib/qweb/qweb2.js
index e617df60183..4f136f3c98a 100644
--- a/addons/base/static/lib/qweb/qweb2.js
+++ b/addons/base/static/lib/qweb/qweb2.js
@@ -304,6 +304,7 @@ QWeb2.Engine = (function() {
" /* START TEMPLATE */ try {\n" +
(e.compile()) + "\n" +
" /* END OF TEMPLATE */ } catch(error) {\n" +
+ " if (console && console.exception) console.exception(error);\n" +
" context.engine.tools.exception('Runtime Error: ' + error, context);\n" +
" }\n" +
" return r.join('');";
diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js
index 47e3de67677..98f0af5a8d1 100644
--- a/addons/base/static/src/js/chrome.js
+++ b/addons/base/static/src/js/chrome.js
@@ -845,6 +845,7 @@ openerp.base.Dialog = openerp.base.BaseWidget.extend({
this.$dialog.dialog('close');
},
stop: function () {
+ this.close();
this.$dialog.dialog('destroy');
}
});
@@ -1174,6 +1175,11 @@ openerp.base.Login = openerp.base.Controller.extend({
this.selected_db = localStorage.getItem('last_db_login_success');
this.selected_login = localStorage.getItem('last_login_login_success');
}
+ if (jQuery.deparam(jQuery.param.querystring()).debug != undefined) {
+ this.selected_db = this.selected_db || "trunk";
+ this.selected_login = this.selected_login || "admin";
+ this.selected_password = this.selected_password || "a";
+ }
},
start: function() {
var self = this;
diff --git a/addons/base/static/src/js/data.js b/addons/base/static/src/js/data.js
index 1eb9c0f0a0d..534fd356f06 100644
--- a/addons/base/static/src/js/data.js
+++ b/addons/base/static/src/js/data.js
@@ -120,29 +120,25 @@ openerp.base.ContainerDataGroup = openerp.base.DataGroup.extend(
aggregates: aggregates
};
},
- fetch: function () {
+ fetch: function (fields) {
// internal method
var d = new $.Deferred();
var self = this;
- // disable caching for now, not sure what I should do there
- if (false && this.groups) {
- d.resolveWith(this, [this.groups]);
- } else {
- this.rpc('/base/group/read', {
- model: this.model,
- context: this.context,
- domain: this.domain,
- group_by_fields: this.group_by
- }, function () { }).then(function (response) {
- var data_groups = _(response).map(
- _.bind(self.transform_group, self));
- self.groups = data_groups;
- d.resolveWith(self, [data_groups]);
- }, function () {
- d.rejectWith.apply(d, self, [arguments]);
- });
- }
+ this.rpc('/base/group/read', {
+ model: this.model,
+ context: this.context,
+ domain: this.domain,
+ fields: _.uniq(this.group_by.concat(fields)),
+ group_by_fields: this.group_by
+ }, function () { }).then(function (response) {
+ var data_groups = _(response).map(
+ _.bind(self.transform_group, self));
+ self.groups = data_groups;
+ d.resolveWith(self, [data_groups]);
+ }, function () {
+ d.rejectWith.apply(d, [self, arguments]);
+ });
return d.promise();
},
/**
@@ -163,10 +159,14 @@ openerp.base.ContainerDataGroup = openerp.base.DataGroup.extend(
* records have for the current ``grouped_on`` field name).
* ``aggregates``
* a mapping of other aggregation fields provided by ``read_group``
+ *
+ * @param {Array} fields the list of fields to aggregate in each group, can be empty
+ * @param {Function} ifGroups function executed if any group is found (DataGroup.group_by is non-null and non-empty), called with a (potentially empty) list of groups as parameters.
+ * @param {Function} ifRecords function executed if there is no grouping left to perform, called with a DataSet instance as parameter
*/
- list: function (ifGroups, ifRecords) {
+ list: function (fields, ifGroups, ifRecords) {
var self = this;
- this.fetch().then(function (group_records) {
+ this.fetch(fields).then(function (group_records) {
ifGroups(_(group_records).map(function (group) {
var child_context = _.extend({}, self.context, group.__context);
return _.extend(
@@ -195,7 +195,7 @@ openerp.base.GrouplessDataGroup = openerp.base.DataGroup.extend(
init: function (session, model, domain, context, level) {
this._super(session, model, domain, context, null, level);
},
- list: function (ifGroups, ifRecords) {
+ list: function (fields, ifGroups, ifRecords) {
ifRecords(_.extend(
new openerp.base.DataSetSearch(this.session, this.model),
{domain: this.domain, context: this.context}));
@@ -215,7 +215,7 @@ openerp.base.StaticDataGroup = openerp.base.GrouplessDataGroup.extend(
init: function (dataset) {
this.dataset = dataset;
},
- list: function (ifGroups, ifRecords) {
+ list: function (fields, ifGroups, ifRecords) {
ifRecords(this.dataset);
}
});
diff --git a/addons/base/static/src/js/form.js b/addons/base/static/src/js/form.js
index 7517ec23e01..7faa942c6b0 100644
--- a/addons/base/static/src/js/form.js
+++ b/addons/base/static/src/js/form.js
@@ -51,6 +51,11 @@ openerp.base.FormView = openerp.base.View.extend( /** @lends openerp.base.FormV
toolbar:!!this.flags.sidebar, context: context}, this.on_loaded);
}
},
+ stop: function() {
+ _.each(this.widgets, function(w) {
+ w.stop();
+ });
+ },
on_loaded: function(data) {
var self = this;
this.fields_view = data.fields_view;
@@ -532,6 +537,9 @@ openerp.base.form.Widget = openerp.base.Controller.extend({
start: function() {
this.$element = $('#' + this.element_id);
},
+ stop: function() {
+ this.$element.remove();
+ },
process_modifiers: function() {
var compute_domain = openerp.base.form.compute_domain;
for (var a in this.modifiers) {
@@ -590,7 +598,10 @@ openerp.base.form.WidgetFrame = openerp.base.form.Widget.extend({
}
},
handle_node: function(node) {
- var type = this.view.fields_view.fields[node.attrs.name] || {};
+ var type = {};
+ if (node.tag == 'field') {
+ type = this.view.fields_view.fields[node.attrs.name] || {};
+ }
var widget = new (this.view.registry.get_any(
[node.attrs.widget, type.type, node.tag])) (this.view, node);
if (node.tag == 'field') {
@@ -617,14 +628,14 @@ openerp.base.form.WidgetFrame = openerp.base.form.Widget.extend({
});
openerp.base.form.WidgetNotebook = openerp.base.form.Widget.extend({
+ template: 'WidgetNotebook',
init: function(view, node) {
this._super(view, node);
- this.template = "WidgetNotebook";
this.pages = [];
for (var i = 0; i < node.children.length; i++) {
var n = node.children[i];
if (n.tag == "page") {
- var page = new openerp.base.form.WidgetFrame(this.view, n);
+ var page = new openerp.base.form.WidgetNotebookPage(this.view, n, this, this.pages.length);
this.pages.push(page);
}
}
@@ -635,6 +646,28 @@ openerp.base.form.WidgetNotebook = openerp.base.form.Widget.extend({
}
});
+openerp.base.form.WidgetNotebookPage = openerp.base.form.WidgetFrame.extend({
+ template: 'WidgetNotebookPage',
+ init: function(view, node, notebook, index) {
+ this.notebook = notebook;
+ this.index = index;
+ this.element_name = 'page_' + index;
+ this._super(view, node);
+ this.element_tab_id = this.element_id + '_tab';
+ },
+ start: function() {
+ this._super.apply(this, arguments);
+ this.$element_tab = $('#' + this.element_tab_id);
+ },
+ update_dom: function() {
+ if (this.invisible) {
+ this.notebook.$element.tabs('select', 0);
+ }
+ this.$element_tab.toggle(!this.invisible);
+ this.$element.toggle(!this.invisible);
+ }
+});
+
openerp.base.form.WidgetSeparator = openerp.base.form.Widget.extend({
init: function(view, node) {
this._super(view, node);
@@ -902,6 +935,7 @@ openerp.base.form.FieldFloat = openerp.base.form.FieldChar.extend({
if (value === false || value === undefined) {
// As in GTK client, floats default to 0
value = 0;
+ this.touched = true;
}
var show_value = value.toFixed(2);
this.$element.find('input').val(show_value);
@@ -921,6 +955,7 @@ openerp.base.form.FieldInteger = openerp.base.form.FieldFloat.extend({
if (value === false || value === undefined) {
// TODO fme: check if GTK client default integers to 0 (like it does with floats)
value = 0;
+ this.touched = true;
}
var show_value = parseInt(value, 10);
this.$element.find('input').val(show_value);
@@ -967,7 +1002,7 @@ openerp.base.form.FieldDatetime = openerp.base.form.Field.extend({
},
update_dom: function() {
this._super.apply(this, arguments);
- this.$element.find('input').attr('disabled', this.readonly);
+ this.$element.find('input').datepicker(this.readonly ? 'disable' : 'enable');
},
validate: function() {
this.invalid = false;
@@ -1007,6 +1042,7 @@ openerp.base.form.FieldFloatTime = openerp.base.form.FieldChar.extend({
if (value === false || value === undefined) {
// As in GTK client, floats default to 0
value = 0;
+ this.touched = true;
}
var show_value = _.sprintf("%02d:%02d", Math.floor(value), Math.round((value % 1) * 60));
this.$element.find('input').val(show_value);
@@ -1285,10 +1321,12 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
}
this.$input.focusout(anyoneLoosesFocus);
+ var isSelecting = false;
// autocomplete
this.$input.autocomplete({
source: function(req, resp) { self.get_search_result(req, resp); },
select: function(event, ui) {
+ isSelecting = true;
var item = ui.item;
if (item.id) {
self._change_int_value([item.id, item.name]);
@@ -1306,6 +1344,14 @@ openerp.base.form.FieldMany2One = openerp.base.form.Field.extend({
minLength: 0,
delay: 0
});
+ // used to correct a bug when selecting an element by pushing 'enter' in an editable list
+ this.$input.keyup(function(e) {
+ if (e.which === 13) {
+ if (isSelecting)
+ e.stopPropagation();
+ }
+ isSelecting = false;
+ });
},
// autocomplete component content handling
get_search_result: function(request, response) {
@@ -1775,7 +1821,8 @@ openerp.base.form.SelectCreatePopup = openerp.base.BaseWidget.extend({
this.initial_ids = this.options.initial_ids;
jQuery(this.render()).dialog({title: '',
modal: true,
- minWidth: 800});
+ width: 960,
+ height: 600});
this.start();
},
start: function() {
diff --git a/addons/base/static/src/js/list.js b/addons/base/static/src/js/list.js
index c4aea837a4f..c1df8857f08 100644
--- a/addons/base/static/src/js/list.js
+++ b/addons/base/static/src/js/list.js
@@ -256,11 +256,12 @@ openerp.base.ListView = openerp.base.View.extend( /** @lends openerp.base.ListVi
if (column.modifiers) {
var modifiers = JSON.parse(column.modifiers);
column.modifiers_for = function (fields) {
- var result = {};
- for (var modifier in modifiers) {
- result[modifier] = domain_computer(modifiers[modifier], fields);
+ if (!modifiers.invisible) {
+ return {};
}
- return result;
+ return {
+ 'invisible': domain_computer(modifiers.invisible, fields)
+ };
};
} else {
column.modifiers_for = noop;
@@ -1074,18 +1075,23 @@ openerp.base.ListView.Groups = Class.extend( /** @lends openerp.base.ListView.Gr
var self = this;
var $element = $('<tbody>');
this.elements = [$element[0]];
- this.datagroup.list(function (groups) {
- $element[0].appendChild(
- self.render_groups(groups));
- if (post_render) { post_render(); }
- }, function (dataset) {
- self.render_dataset(dataset).then(function (list) {
- self.children[null] = list;
- self.elements =
- [list.$current.replaceAll($element)[0]];
+
+ this.datagroup.list(
+ _(this.view.visible_columns).chain()
+ .filter(function (column) { return column.tag === 'field' })
+ .pluck('name').value(),
+ function (groups) {
+ $element[0].appendChild(
+ self.render_groups(groups));
if (post_render) { post_render(); }
+ }, function (dataset) {
+ self.render_dataset(dataset).then(function (list) {
+ self.children[null] = list;
+ self.elements =
+ [list.$current.replaceAll($element)[0]];
+ if (post_render) { post_render(); }
+ });
});
- });
return $element;
},
/**
diff --git a/addons/base/static/src/js/views.js b/addons/base/static/src/js/views.js
index 9ed8886c1e5..a8ba8067bc0 100644
--- a/addons/base/static/src/js/views.js
+++ b/addons/base/static/src/js/views.js
@@ -9,7 +9,7 @@ openerp.base.ActionManager = openerp.base.Controller.extend({
init: function(session, element_id) {
this._super(session, element_id);
this.viewmanager = null;
- this.dialog_stack = [];
+ this.current_dialog = null;
// Temporary linking view_manager to session.
// Will use controller_parent to find it when implementation will be done.
session.action_manager = this;
@@ -22,34 +22,44 @@ openerp.base.ActionManager = openerp.base.Controller.extend({
var self = this;
action.flags = _.extend({
sidebar : action.target != 'new',
- search_view : true,
+ search_view : action.target != 'new',
new_window : false,
- views_switcher : true,
- action_buttons : true,
- pager : true
+ views_switcher : action.target != 'new',
+ action_buttons : action.target != 'new',
+ pager : action.target != 'new'
}, action.flags || {});
// instantiate the right controllers by understanding the action
+ if (this.current_dialog) {
+ this.current_dialog.stop();
+ this.current_dialog = null;
+ }
+ if (this.current_dialog) {
+ this.current_dialog.stop();
+ this.current_dialog = null;
+ } else if (this.view_manager && this.view_manager.current_dialog) {
+ this.view_manager.current_dialog.stop();
+ this.view_manager.current_dialog = null;
+ }
switch (action.type) {
case 'ir.actions.act_window':
- if (!action.target && this.dialog_stack.length) {
+ if (!action.target && this.current_dialog) {
action.flags.new_window = true;
}
if (action.target == 'new') {
- var element_id = _.uniqueId("act_window_dialog");
- $('<div>', {id: element_id}).dialog({
+ var dialog = this.current_dialog = new openerp.base.ActionDialog(this.session, {
title: action.name,
- modal: true,
- width: '50%',
- height: 'auto'
- }).bind('dialogclose', function(event) {
- // When dialog is closed with ESC key or close manually, branch to act_window_close logic
- self.do_action({ type: 'ir.actions.act_window_close' });
+ width: '50%'
});
- var viewmanager = new openerp.base.ViewManagerAction(this.session, element_id, action);
+ if (on_closed) {
+ dialog.on_closed.add_first(on_closed);
+ }
+ dialog.start(false);
+ var viewmanager = new openerp.base.ViewManagerAction(this.session, dialog.element_id, action);
viewmanager.start();
- viewmanager.on_act_window_closed.add(on_closed);
- viewmanager.is_dialog = true;
- this.dialog_stack.push(viewmanager);
+ // TODO: merge ActionManager & ViewManager in order to get rid of this circular reference
+ viewmanager.current_dialog = dialog;
+ dialog.viewmanager = viewmanager;
+ dialog.open();
} else if (action.flags.new_window) {
action.flags.new_window = false;
this.rpc("/base/session/save_session_action", { the_action : action}, function(key) {
@@ -66,12 +76,6 @@ openerp.base.ActionManager = openerp.base.Controller.extend({
}
break;
case 'ir.actions.act_window_close':
- var dialog = this.dialog_stack.pop();
- if (!action.special) {
- dialog.on_act_window_closed();
- }
- dialog.$element.dialog('destroy');
- dialog.stop();
break;
case 'ir.actions.server':
this.rpc('/base/action/run', {
@@ -100,7 +104,6 @@ openerp.base.ViewManager = openerp.base.Controller.extend({
this.flags = this.flags || {};
this.sidebar = new openerp.base.NullSidebar();
this.registry = openerp.base.views;
- this.is_dialog = false;
},
/**
* @returns {jQuery.Deferred} initial view loading promise
@@ -219,11 +222,6 @@ openerp.base.ViewManager = openerp.base.Controller.extend({
return this.searchview.start();
},
/**
- * Called when this view manager has been created by an action 'act_window@target=new' is closed
- */
- on_act_window_closed : function() {
- },
- /**
* Called when one of the view want to execute an action
*/
on_action: function(action) {
@@ -344,6 +342,22 @@ openerp.base.ViewManagerAction = openerp.base.ViewManager.extend({
}
});
+openerp.base.ActionDialog = openerp.base.Dialog.extend({
+ identifier_prefix: 'action_dialog',
+ close: function() {
+ this._super(this, arguments);
+ this.on_closed();
+ },
+ on_closed: function() {
+ },
+ stop: function() {
+ this._super(this, arguments);
+ if (this.viewmanager) {
+ this.viewmanager.stop();
+ }
+ }
+});
+
openerp.base.Sidebar = openerp.base.BaseWidget.extend({
template: "ViewManager.sidebar",
init: function(parent, view_manager) {
@@ -398,6 +412,7 @@ openerp.base.Sidebar = openerp.base.BaseWidget.extend({
}
});
+
openerp.base.NullSidebar = openerp.base.generate_null_object_class(openerp.base.Sidebar);
openerp.base.Export = openerp.base.Dialog.extend({
@@ -445,28 +460,22 @@ openerp.base.View = openerp.base.Controller.extend({
active_model: dataset.model
});
action.flags = {
- sidebar : false,
- search_view : false,
- views_switcher : false,
- action_buttons : false,
- pager : false,
new_window: true
};
action_manager.do_action(action, on_closed);
- if (self.view_manager.is_dialog && action.type != 'ir.actions.act_window_close') {
- handler({
- result : { type: 'ir.actions.act_window_close' }
- });
- }
} else {
on_no_action(action);
}
};
if (action_data.special) {
- handler({
- result : { type: 'ir.actions.act_window_close', special: action_data.special }
- });
+ if (action_manager.current_dialog) {
+ action_manager.current_dialog.stop();
+ action_manager.current_dialog = null;
+ } else if (this.view_manager.current_dialog) {
+ this.view_manager.current_dialog.stop();
+ this.view_manager.current_dialog = null;
+ }
} else {
var context = new openerp.base.CompoundContext(dataset.get_context(), action_data.context || {});
switch(action_data.type) {
diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml
index e2b67c3aa8e..035332d2961 100644
--- a/addons/base/static/src/xml/base.xml
+++ b/addons/base/static/src/xml/base.xml
@@ -270,7 +270,8 @@
</tr>
<tr>
<td><label for="password">Password:</label></td>
- <td><input type="password" name="password"/></td>
+ <td><input type="password" name="password"
+ t-att-value="selected_password || ''"/></td>
</tr>
<tr>
<td></td>
@@ -463,7 +464,7 @@
<t t-esc="column.string"/>
</th>
</t>
- <th t-if="options.selectable"/>
+ <th t-if="options.selectable" width="1"/>
<t t-foreach="columns" t-as="column">
<th t-if="!column.meta and column.invisible !== '1'" t-att-data-id="column.id"
t-att-class="((options.sortable and column.tag !== 'button') ? 'oe-sortable' : null)">
@@ -473,7 +474,7 @@
</t>
</th>
</t>
- <th t-if="options.deletable"/>
+ <th t-if="options.deletable" width="1"/>
</tr>
</thead>
<tfoot class="ui-widget-header">
@@ -501,7 +502,7 @@
</td>
</t>
- <th t-if="options.selectable" class="oe-record-selector">
+ <th t-if="options.selectable" class="oe-record-selector" width="1">
<input type="checkbox"/>
</th>
<t t-foreach="columns" t-as="column">
@@ -512,7 +513,7 @@
<t t-raw="render_cell(row.data, column)"/>
</td>
</t>
- <td t-if="options.deletable" class='oe-record-delete'>
+ <td t-if="options.deletable" class='oe-record-delete' width="1">
<button type="button" name="delete">♻</button>
</td>
</tr>
@@ -604,18 +605,21 @@
</t>
<t t-name="WidgetNotebook">
<ul>
- <li t-foreach="widget.pages" t-as="page">
- <a t-att-href="'#' + widget.element_id + '-' + page_index">
+ <li t-foreach="widget.pages" t-as="page" t-att-id="page.element_tab_id">
+ <a t-att-href="'#' + page.element_id">
<t t-esc="page.string"/>
</a>
</li>
</ul>
<t t-foreach="widget.pages" t-as="page">
- <div t-att-id="widget.element_id + '-' + page_index">
- <t t-raw="page.render()"/>
- </div>
+ <t t-raw="page.render()"/>
</t>
</t>
+<t t-name="WidgetNotebookPage">
+ <div t-att-id="widget.element_id">
+ <t t-call="WidgetFrame"/>
+ </div>
+</t>
<t t-name="WidgetSeparator">
<div t-att-class="'separator ' + (widget.node.attrs.orientation || 'horizontal')">
<t t-esc="widget.string"/>
@@ -704,9 +708,9 @@
<span class="oe-m2o-cm-button" t-att-id="widget.name + '_open'">
<img src="/base/static/src/img/icons/gtk-index.png"/></span>
<div t-att-id="widget.cm_id" class="contextMenu" style="display:none"><ul>
- <li t-att-id="widget.cm_id + '_search'">Search...</li>
- <li t-att-id="widget.cm_id + '_create'">Create New...</li>
<li t-att-id="widget.cm_id + '_open'" style="color:grey">Open...</li>
+ <li t-att-id="widget.cm_id + '_create'">Create and Edit...</li>
+ <li t-att-id="widget.cm_id + '_search'">Search...</li>
</ul></div>
</div>
</t>
@@ -1066,9 +1070,19 @@
</t>
<t t-name="SelectCreatePopup">
<div t-att-id="element_id">
- <div t-att-id="element_id + '_search'"></div>
- <div t-att-id="element_id + '_view_list'"></div>
- <div t-att-id="element_id + '_view_form'"></div>
+ <table style="width:100%">
+ <tr style="width:100%">
+ <td style="width:100%">
+ <div t-att-id="element_id + '_search'" style="width:100%"></div>
+ </td>
+ </tr>
+ <tr style="width:100%">
+ <td style="width:100%">
+ <div t-att-id="element_id + '_view_list'" style="width:100%"></div>
+ </td>
+ </tr>
+ </table>
+ <div t-att-id="element_id + '_view_form'" style="width:100%"></div>
</div>
</t>
<t t-name="SelectCreatePopup.search.buttons">