[IMP]Render data in add node functionality.

bzr revid: vme@tinyerp.com-20111110122914-qjjh7gf9dq5i5208
This commit is contained in:
Vidhin Mehta (OpenERP) 2011-11-10 17:59:14 +05:30
commit 7a4fe3ddb8
18 changed files with 601 additions and 156 deletions

View File

@ -23,6 +23,7 @@
"static/lib/jquery.ui/js/jquery-ui-timepicker-addon.js",
"static/lib/jquery.ui.notify/js/jquery.notify.js",
"static/lib/jquery.deferred-queue/jquery.deferred-queue.js",
"static/lib/jquery.scrollTo/jquery.scrollTo-min.js",
"static/lib/json/json2.js",
"static/lib/qweb/qweb2.js",
"static/lib/underscore/underscore.js",

View File

@ -1193,19 +1193,26 @@ class Export(View):
@openerpweb.jsonrequest
def get_fields(self, req, model, prefix='', parent_name= '',
import_compat=True, parent_field_type=None):
import_compat=True, parent_field_type=None,
exclude=None):
if import_compat and parent_field_type == "many2one":
fields = {}
else:
fields = self.fields_get(req, model)
fields['.id'] = fields.pop('id') if 'id' in fields else {'string': 'ID'}
if import_compat:
fields.pop('id', None)
else:
fields['.id'] = fields.pop('id', {'string': 'ID'})
fields_sequence = sorted(fields.iteritems(),
key=lambda field: field[1].get('string', ''))
records = []
for field_name, field in fields_sequence:
if import_compat and (exclude and field_name in exclude):
continue
if import_compat and field.get('readonly'):
# If none of the field's states unsets readonly, skip the field
if all(dict(attrs).get('readonly', True)
@ -1217,7 +1224,8 @@ class Export(View):
record = {'id': id, 'string': name,
'value': id, 'children': False,
'field_type': field.get('type'),
'required': field.get('required')}
'required': field.get('required'),
'relation_field': field.get('relation_field')}
records.append(record)
if len(name.split('/')) < 3 and 'relation' in field:
@ -1249,7 +1257,6 @@ class Export(View):
def fields_info(self, req, model, export_fields):
info = {}
fields = self.fields_get(req, model)
fields['.id'] = fields.pop('id') if 'id' in fields else {'string': 'ID'}
# To make fields retrieval more efficient, fetch all sub-fields of a
# given field at the same time. Because the order in the export list is

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-08 06:12+0000\n"
"X-Generator: Launchpad (build 14231)\n"
"X-Launchpad-Export-Date: 2011-11-09 05:09+0000\n"
"X-Generator: Launchpad (build 14263)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
"PO-Revision-Date: 2011-10-11 14:21+0000\n"
"PO-Revision-Date: 2011-11-08 21:58+0000\n"
"Last-Translator: Jonas Mortensen <Unknown>\n"
"Language-Team: Danish <da@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: 2011-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\n"
"X-Launchpad-Export-Date: 2011-11-09 05:09+0000\n"
"X-Generator: Launchpad (build 14263)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
@ -264,7 +264,7 @@ msgstr "oe_secondary_menu_item"
#: addons/web/static/src/xml/base.xml:0
msgid "oe_secondary_submenu_item"
msgstr ""
msgstr "oe_secondary_submenu_item"
#: addons/web/static/src/xml/base.xml:0
msgid "Hide this tip"

View File

@ -0,0 +1,91 @@
1.4.2
[Feature]
- The plugin support percentages as target ('50%' or {top:'50%', left:'45%'})
- Exposed the max() calculation as $.scrollTo.max
[Enhancement]
- Renamed $.fn.scrollable to $.fn._scrollable to avoid conflicts with other plugins
[Fix]
- Fixing max calculations for regular DOM elements
1.4.1
[Feature]
- The target can be 'max' to scroll to the end while keeping it elegant.
[Enhancement]
- Default duration is 0 for jquery +1.3. Means sync animation
- The plugin works on all major browsers, on compat & quirks modes, including iframes.
- In addition to window/document, if html or body are received, the plugin will choose the right one.
[Fix]
- The plugin accepts floating numbers, Thanks Ramin
- Using jQuery.nodeName where neccessary so that this works on xml+xhtml
- The max() internal function wasn't completely accurrate, now it is 98% (except for IE on quirks mode and it's not too noticeable).
1.4
[Fix]
- Fixed the problem when scrolling the window to absolute positioned elements on Safari.
- Fixed the problem on Opera 9.5 when scrolling the window. That it always scrolls to 0.
[Feature]
- Added the settings object as 2nd argument to the onAfter callback.
- The 3rd argument of scrollTo can be just a function and it's used as the onAfter.
- Added full support for iframes (even max scroll calculation).
- Instead of $.scrollTo, $(window).scrollTo() and $(document).scrollTo() can be used.
- Added $().scrollable() that returns the real element to scroll, f.e: $(window).scrollable() == [body|html], works for iframes.
[Enhancement]
- Cleaned the code a bit, specially the comments
1.3.3
[Change]
- Changed the licensing from GPL to GPL+MIT.
1.3.2
[Enhancement]
- Small improvements to make the code shorter.
[Change]
- Removed the last argument received by onAfter as it was the same as the 'this' but jqueryfied.
1.3.1
[Feature]
- Exposed $.scrollTo.window() to get the element that needs to be animated, to scroll the window.
- Added option 'over'.
[Enhancement]
- Made the code as short as possible.
[Change]
- Changed the arguments received by onAfter
1.3
[Enhancement]
- Added semicolon to the start, for safe file concatenation
- Added a limit check, values below 0 or over the maximum are fixed.
- Now it should work faster, only one of html or body go through all the processing, instead of both for all browsers.
[Fix]
- Fixed the behavior for Opera, which seemed to react to both changes on <html> and <body>.
- The border is also reduced, when 'margin' is set to true.
[Change]
- The option speed has been renamed to duration.
[Feature]
- The duration can be specified with a number as 2nd argument, and the rest of the settings as the third ( like $().animate )
- Remade the demo
1.2.4
[Enhancement]
- The target can be in the form of { top:x, left:y } allowing different position for each axis.
[Feature]
- The option 'offset' has been added, to scroll behind or past the target. Can be a number(both axes) or { top:x, left:y }.
1.2.3
[Feature]
- Exposed the defaults.
[Enhancement]
- Made the callback functions receive more parameters.
1.2.2
[Fix]
- Fixed a bug, I didn't have to add the scrolled amount if it was body or html.
1.2
[Change]
- The option 'onafter' is now called 'onAfter'.
[Feature]
- Two axes can be scrolled together, this is set with the option 'axis'.
- In case 2 axes are chosen, the scrolling can be queued: one scrolls, and then the other.
- There's an intermediary event, 'onAfterFirst' called in case the axes are queued, after the first ends.
- If the option 'margin' is set to true, the plugin will take in account, the margin of the target(no use if target is a value).

View File

@ -0,0 +1,11 @@
/**
* jQuery.ScrollTo - Easy element scrolling using jQuery.
* Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
* Dual licensed under MIT and GPL.
* Date: 5/25/2009
* @author Ariel Flesler
* @version 1.4.2
*
* http://flesler.blogspot.com/2007/10/jqueryscrollto.html
*/
;(function(d){var k=d.scrollTo=function(a,i,e){d(window).scrollTo(a,i,e)};k.defaults={axis:'xy',duration:parseFloat(d.fn.jquery)>=1.3?0:1};k.window=function(a){return d(window)._scrollable()};d.fn._scrollable=function(){return this.map(function(){var a=this,i=!a.nodeName||d.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!i)return a;var e=(a.contentWindow||a).document||a.ownerDocument||a;return d.browser.safari||e.compatMode=='BackCompat'?e.body:e.documentElement})};d.fn.scrollTo=function(n,j,b){if(typeof j=='object'){b=j;j=0}if(typeof b=='function')b={onAfter:b};if(n=='max')n=9e9;b=d.extend({},k.defaults,b);j=j||b.speed||b.duration;b.queue=b.queue&&b.axis.length>1;if(b.queue)j/=2;b.offset=p(b.offset);b.over=p(b.over);return this._scrollable().each(function(){var q=this,r=d(q),f=n,s,g={},u=r.is('html,body');switch(typeof f){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(f)){f=p(f);break}f=d(f,this);case'object':if(f.is||f.style)s=(f=d(f)).offset()}d.each(b.axis.split(''),function(a,i){var e=i=='x'?'Left':'Top',h=e.toLowerCase(),c='scroll'+e,l=q[c],m=k.max(q,i);if(s){g[c]=s[h]+(u?0:l-r.offset()[h]);if(b.margin){g[c]-=parseInt(f.css('margin'+e))||0;g[c]-=parseInt(f.css('border'+e+'Width'))||0}g[c]+=b.offset[h]||0;if(b.over[h])g[c]+=f[i=='x'?'width':'height']()*b.over[h]}else{var o=f[h];g[c]=o.slice&&o.slice(-1)=='%'?parseFloat(o)/100*m:o}if(/^\d+$/.test(g[c]))g[c]=g[c]<=0?0:Math.min(g[c],m);if(!a&&b.queue){if(l!=g[c])t(b.onAfterFirst);delete g[c]}});t(b.onAfter);function t(a){r.animate(g,j,b.easing,a&&function(){a.call(this,n,b)})}}).end()};k.max=function(a,i){var e=i=='x'?'Width':'Height',h='scroll'+e;if(!d(a).is('html,body'))return a[h]-d(a)[e.toLowerCase()]();var c='client'+e,l=a.ownerDocument.documentElement,m=a.ownerDocument.body;return Math.max(l[h],m[h])-Math.min(l[c],m[c])};function p(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery);

View File

@ -0,0 +1,215 @@
/**
* jQuery.ScrollTo
* Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
* Dual licensed under MIT and GPL.
* Date: 5/25/2009
*
* @projectDescription Easy element scrolling using jQuery.
* http://flesler.blogspot.com/2007/10/jqueryscrollto.html
* Works with jQuery +1.2.6. Tested on FF 2/3, IE 6/7/8, Opera 9.5/6, Safari 3, Chrome 1 on WinXP.
*
* @author Ariel Flesler
* @version 1.4.2
*
* @id jQuery.scrollTo
* @id jQuery.fn.scrollTo
* @param {String, Number, DOMElement, jQuery, Object} target Where to scroll the matched elements.
* The different options for target are:
* - A number position (will be applied to all axes).
* - A string position ('44', '100px', '+=90', etc ) will be applied to all axes
* - A jQuery/DOM element ( logically, child of the element to scroll )
* - A string selector, that will be relative to the element to scroll ( 'li:eq(2)', etc )
* - A hash { top:x, left:y }, x and y can be any kind of number/string like above.
* - A percentage of the container's dimension/s, for example: 50% to go to the middle.
* - The string 'max' for go-to-end.
* @param {Number} duration The OVERALL length of the animation, this argument can be the settings object instead.
* @param {Object,Function} settings Optional set of settings or the onAfter callback.
* @option {String} axis Which axis must be scrolled, use 'x', 'y', 'xy' or 'yx'.
* @option {Number} duration The OVERALL length of the animation.
* @option {String} easing The easing method for the animation.
* @option {Boolean} margin If true, the margin of the target element will be deducted from the final position.
* @option {Object, Number} offset Add/deduct from the end position. One number for both axes or { top:x, left:y }.
* @option {Object, Number} over Add/deduct the height/width multiplied by 'over', can be { top:x, left:y } when using both axes.
* @option {Boolean} queue If true, and both axis are given, the 2nd axis will only be animated after the first one ends.
* @option {Function} onAfter Function to be called after the scrolling ends.
* @option {Function} onAfterFirst If queuing is activated, this function will be called after the first scrolling ends.
* @return {jQuery} Returns the same jQuery object, for chaining.
*
* @desc Scroll to a fixed position
* @example $('div').scrollTo( 340 );
*
* @desc Scroll relatively to the actual position
* @example $('div').scrollTo( '+=340px', { axis:'y' } );
*
* @dec Scroll using a selector (relative to the scrolled element)
* @example $('div').scrollTo( 'p.paragraph:eq(2)', 500, { easing:'swing', queue:true, axis:'xy' } );
*
* @ Scroll to a DOM element (same for jQuery object)
* @example var second_child = document.getElementById('container').firstChild.nextSibling;
* $('#container').scrollTo( second_child, { duration:500, axis:'x', onAfter:function(){
* alert('scrolled!!');
* }});
*
* @desc Scroll on both axes, to different values
* @example $('div').scrollTo( { top: 300, left:'+=200' }, { axis:'xy', offset:-20 } );
*/
;(function( $ ){
var $scrollTo = $.scrollTo = function( target, duration, settings ){
$(window).scrollTo( target, duration, settings );
};
$scrollTo.defaults = {
axis:'xy',
duration: parseFloat($.fn.jquery) >= 1.3 ? 0 : 1
};
// Returns the element that needs to be animated to scroll the window.
// Kept for backwards compatibility (specially for localScroll & serialScroll)
$scrollTo.window = function( scope ){
return $(window)._scrollable();
};
// Hack, hack, hack :)
// Returns the real elements to scroll (supports window/iframes, documents and regular nodes)
$.fn._scrollable = function(){
return this.map(function(){
var elem = this,
isWin = !elem.nodeName || $.inArray( elem.nodeName.toLowerCase(), ['iframe','#document','html','body'] ) != -1;
if( !isWin )
return elem;
var doc = (elem.contentWindow || elem).document || elem.ownerDocument || elem;
return $.browser.safari || doc.compatMode == 'BackCompat' ?
doc.body :
doc.documentElement;
});
};
$.fn.scrollTo = function( target, duration, settings ){
if( typeof duration == 'object' ){
settings = duration;
duration = 0;
}
if( typeof settings == 'function' )
settings = { onAfter:settings };
if( target == 'max' )
target = 9e9;
settings = $.extend( {}, $scrollTo.defaults, settings );
// Speed is still recognized for backwards compatibility
duration = duration || settings.speed || settings.duration;
// Make sure the settings are given right
settings.queue = settings.queue && settings.axis.length > 1;
if( settings.queue )
// Let's keep the overall duration
duration /= 2;
settings.offset = both( settings.offset );
settings.over = both( settings.over );
return this._scrollable().each(function(){
var elem = this,
$elem = $(elem),
targ = target, toff, attr = {},
win = $elem.is('html,body');
switch( typeof targ ){
// A number will pass the regex
case 'number':
case 'string':
if( /^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(targ) ){
targ = both( targ );
// We are done
break;
}
// Relative selector, no break!
targ = $(targ,this);
case 'object':
// DOMElement / jQuery
if( targ.is || targ.style )
// Get the real position of the target
toff = (targ = $(targ)).offset();
}
$.each( settings.axis.split(''), function( i, axis ){
var Pos = axis == 'x' ? 'Left' : 'Top',
pos = Pos.toLowerCase(),
key = 'scroll' + Pos,
old = elem[key],
max = $scrollTo.max(elem, axis);
if( toff ){// jQuery / DOMElement
attr[key] = toff[pos] + ( win ? 0 : old - $elem.offset()[pos] );
// If it's a dom element, reduce the margin
if( settings.margin ){
attr[key] -= parseInt(targ.css('margin'+Pos)) || 0;
attr[key] -= parseInt(targ.css('border'+Pos+'Width')) || 0;
}
attr[key] += settings.offset[pos] || 0;
if( settings.over[pos] )
// Scroll to a fraction of its width/height
attr[key] += targ[axis=='x'?'width':'height']() * settings.over[pos];
}else{
var val = targ[pos];
// Handle percentage values
attr[key] = val.slice && val.slice(-1) == '%' ?
parseFloat(val) / 100 * max
: val;
}
// Number or 'number'
if( /^\d+$/.test(attr[key]) )
// Check the limits
attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max );
// Queueing axes
if( !i && settings.queue ){
// Don't waste time animating, if there's no need.
if( old != attr[key] )
// Intermediate animation
animate( settings.onAfterFirst );
// Don't animate this axis again in the next iteration.
delete attr[key];
}
});
animate( settings.onAfter );
function animate( callback ){
$elem.animate( attr, duration, settings.easing, callback && function(){
callback.call(this, target, settings);
});
};
}).end();
};
// Max scrolling position, works on quirks mode
// It only fails (not too badly) on IE, quirks mode.
$scrollTo.max = function( elem, axis ){
var Dim = axis == 'x' ? 'Width' : 'Height',
scroll = 'scroll'+Dim;
if( !$(elem).is('html,body') )
return elem[scroll] - $(elem)[Dim.toLowerCase()]();
var size = 'client' + Dim,
html = elem.ownerDocument.documentElement,
body = elem.ownerDocument.body;
return Math.max( html[scroll], body[scroll] )
- Math.min( html[size] , body[size] );
};
function both( val ){
return typeof val == 'object' ? val : { top:val, left:val };
};
})( jQuery );

View File

@ -654,6 +654,9 @@ label.error {
display: none;
}
.openerp .oe_search-view-buttons {
padding: 10px 0 10px 0;
}
.openerp .oe_search-view-custom-filter-btn span {
background: url(/web/static/src/img/icons/gtk-add.png) repeat-y;
padding-left: 18px;
@ -1080,11 +1083,16 @@ label.error {
}
.openerp .oe-view-manager-logs {
clear: both;
font-size: 85%;
margin: 0.25em 0;
background: #fff;
padding: 0 10px;
margin: 0.25em 0;
font-size: 85%;
color: #4C4C4C;
position: relative;
overflow: hidden;
}
.openerp .oe-view-manager-logs ul {
margin: 0;
padding: 0 10px;
list-style: none;
}
.openerp .oe-view-manager-logs li:before {
@ -1094,6 +1102,24 @@ label.error {
text-decoration: none;
color: inherit;
}
/* only display first three log items of a folded logs list */
.openerp .oe-view-manager-logs.oe-folded li:nth-child(n+4) {
display: none;
}
/* display link to more logs if there are more logs to view and the logview is
currently folded */
.openerp .oe-view-manager-logs a.oe-more-logs {
display: none;
}
.openerp .oe-view-manager-logs.oe-folded.oe-has-more a.oe-more-logs {
display: block;
}
.openerp .oe-view-manager-logs a.oe-remove-everything {
position: absolute;
top: 0;
right: 0;
cursor: pointer;
}
.openerp .view-manager-main-sidebar {
width: 180px;

View File

@ -65,6 +65,11 @@ openerp.web = function(instance) {
openerp.web[files[i]](instance);
}
}
instance.log = function() {
if (instance.connection.debug && window.console) {
console.log.apply(console, arguments);
}
}
};
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:

View File

@ -109,7 +109,7 @@ openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog#
}
},
start: function () {
this.$dialog = $('<div id="' + this.element_id + '"></div>').dialog(this.dialog_options);
this.$dialog = $(this.$element).dialog(this.dialog_options);
this._super();
return this;
},

View File

@ -792,6 +792,11 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
* @type string
*/
identifier_prefix: 'generic-identifier-',
/**
* Tag name when creating a default $element.
* @type string
*/
tag_name: 'div',
/**
* Construct the widget and set its parent if a parent is given.
*
@ -814,7 +819,7 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
this.element_id = element_id;
this.element_id = this.element_id || _.uniqueId(this.identifier_prefix);
var tmp = document.getElementById(this.element_id);
this.$element = tmp ? $(tmp) : undefined;
this.$element = tmp ? $(tmp) : $(document.createElement(this.tag_name));
this.widget_parent = parent;
this.widget_children = [];
@ -869,8 +874,7 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
}, target);
},
_render_and_insert: function(insertion, target) {
var rendered = this.render();
this.$element = $(rendered);
this.render_element();
if (target instanceof openerp.web.Widget)
target = target.$element;
insertion(target);
@ -878,6 +882,15 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
return this.start();
},
on_inserted: function(element, widget) {},
/**
* Renders the element and insert the result of the render() method in this.$element.
*/
render_element: function() {
var rendered = this.render();
if (rendered || rendered === "")
this.$element = $(rendered);
return this;
},
/**
* Renders the widget using QWeb, `this.template` must be defined.
* The context given to QWeb contains the "widget" key that references `this`.
@ -885,7 +898,9 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W
* @param {Object} additional Additional context arguments to pass to the template.
*/
render: function (additional) {
return openerp.web.qweb.render(this.template, _.extend({widget: this}, additional || {}));
if (this.template)
return openerp.web.qweb.render(this.template, _.extend({widget: this}, additional || {}));
return false;
},
/**
* Method called after rendering. Mostly used to bind actions, perform asynchronous

View File

@ -165,7 +165,11 @@ openerp.web.DataExport = openerp.web.Dialog.extend({
}
var model = record['params']['model'],
prefix = record['params']['prefix'],
name = record['params']['name'];
name = record['params']['name'],
exclude_fields = [];
if (record['relation_field']) {
exclude_fields.push(record['relation_field']);
}
if (!record.loaded) {
var import_comp = self.$element.find("#import_compat").val();
@ -174,7 +178,8 @@ openerp.web.DataExport = openerp.web.Dialog.extend({
prefix: prefix,
parent_name: name,
import_compat: Boolean(import_comp),
parent_field_type : record['field_type']
parent_field_type : record['field_type'],
exclude: exclude_fields
}, function(results) {
record.loaded = true;
self.on_show_data(results, record.id);

View File

@ -336,11 +336,16 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
}
switch (this.id) {
case "side-add":
var tr = $(this).closest("tr[id^='viewedit-']").find('a').text();
var tr = $(this).closest("tr[id^='viewedit-']").find('a').text();
var tag = _.detect(_.keys(_CHILDREN),function(res){
return _.includes(tr, res);
});
var properties = _CHILDREN[tag];
self.rpc("/web/searchview/fields_get", {model:self.model}, function(result) {
var fields = _.keys(result.fields);
fields.push(" ");
fields.sort();
self.on_add_node(_CHILDREN[tag],fields);
});
break;
case "side-remove":
break;
@ -480,7 +485,6 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
_.each(update_values, function(val){
if(val[0] == "required"){
$(arch1).attr("required", "true");
console.log(arch1);
}else{
$(arch1).attr(val[0],val[1]);
}
@ -504,7 +508,7 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
});
}
}
},
},
on_expand: function(expand_img){
var level = parseInt($(expand_img).closest("tr[id^='viewedit-']").attr('level'));
var cur_tr = $(expand_img).closest("tr[id^='viewedit-']");
@ -539,9 +543,8 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
"Update": function(){
var update_values = [];
_.each(self.edit_widget, function(widget) {
var value = widget.get_value();
if (value) {
update_values.push(value);
if (widget.dirty) {
update_values.push(widget.get_value());
}
});
self.do_save_update_arch(obj, view_id, view_xml_id, clicked_tr_id, clicked_tr_level, "update_node", update_values);
@ -562,9 +565,9 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
type_widget;
self.ready = $.when(self.on_groups(id)).then(function () {
if (_.include(widget,id)){
type_widget = new (self.property.get_any(['undefined' , id, arch_val[0]['att_list'][0]])) (self.edit_node_dialog, arch_val, id);
type_widget = new (self.property.get_any(['undefined' , id, arch_val[0]['att_list'][0]])) (self.edit_node_dialog, id);
} else {
type_widget = new openerp.web.ViewEditor.FieldChar (self.edit_node_dialog,arch_val, id);
type_widget = new openerp.web.ViewEditor.FieldChar (self.edit_node_dialog, id);
}
var value = _.detect(arch_val[0]['att_list'],function(res) {
return _.include(res, id);
@ -609,12 +612,85 @@ openerp.web.ViewEditor = openerp.web.Widget.extend({
});
})
return def.promise();
},
on_add_node: function(properties,fields){
var self = this;
var positions = ['After','Before','Inside'];
var render_list = [];
render_list.push(["node_type",(_.keys(_CHILDREN)).sort()]);
render_list.push(["position",positions]);
render_list.push([" ",fields]);
this.add_node_dialog = new openerp.web.Dialog(this,{
modal: true,
title: 'Properties',
width: 500,
height: 300,
buttons: {
"Update": function(){
},
"Cancel": function(){
self.add_node_dialog.close();
}
}
}).start().open();
this.add_node_dialog.$element.
append('<table id="rec_table" style="width:400px" class="oe_forms"></table>');
var table_selector = self.add_node_dialog.$element.find('table[id=rec_table]');
_.each(render_list,function(node){
type_widget = new openerp.web.ViewEditor.FieldSelect (self.add_node_dialog, node[0]);
type_widget.value = node[1];
table_selector.append('<tr><td align="right">'+node[0]+'</td><td>'+type_widget.render()+'</td></tr>');
type_widget.start();
});
table_selector.append('<tr><td align="right"> <button id="new_field">New Field</button></td></tr>');
self.add_node_dialog.$element.find("select[id=node_type] option[value=field]").attr("selected",1)
self.add_node_dialog.$element.find('#new_field').click(function() {
//to do
self.Add_new_field();
});
},
Add_new_field : function(){
var self = this;
var action = {
name: _.sprintf("Manage Views (%s)", this.model),
res_model: 'ir.model.fields',
views: [['form']],
type: 'ir.actions.act_window',
target: "new",
limit: this.dataset.limit || 80,
auto_search: true,
flags: {
sidebar: false,
deletable: false,
views_switcher: false,
action_buttons: false,
search_view: false,
pager: false,
radio: true
},
};
this.add_new_field = new openerp.web.Dialog(this, {
modal: true,
title: 'ViewEditor',
width: 750,
height: 500,
buttons: {
"Save": function(){
//to do
},
"Close": function(){
self.add_new_field.close();
}
},
}).start().open();
var action_manager = new openerp.web.ActionManager(this);
action_manager.appendTo(this.add_new_field);
action_manager.do_action(action);
}
});
openerp.web.ViewEditor.Field = openerp.web.Class.extend({
init: function(view, node, id) {
init: function(view, id) {
this.$element = view.$element;
this.node = node;
this.dirty = false;
this.name = id;
this.value = undefined;
@ -640,9 +716,6 @@ openerp.web.ViewEditor.FieldBoolean = openerp.web.ViewEditor.Field.extend({
}
},
get_value: function() {
if (!this.dirty) {
return false;
}
var value = this.$element.find("input[id=" + this.name + "]").is(':checked');
return value ? [this.name, value] : [this.name, null];
}
@ -659,9 +732,6 @@ openerp.web.ViewEditor.FieldChar = openerp.web.ViewEditor.Field.extend({
value ? this.$element.find("input[id=" + this.name + "]").val(value[1]): this.$element.find("tr[id=" + this.name + "] input").val();
},
get_value: function() {
if (!this.dirty) {
return false;
}
var value= this.$element.find("input[id=" + this.name + "]").val();
return value ? [this.name, value] : [this.name, ""];
}
@ -684,16 +754,13 @@ openerp.web.ViewEditor.FieldSelect = openerp.web.ViewEditor.Field.extend({
this.$element.find("select[id=" + this.name + "]")[0].selectedIndex = index;
},
get_value: function() {
if (!this.dirty) {
return false;
}
var value = this.$element.find("select[id=" + this.name + "]").val();
return value ? [this.name, value] : [this.name, ""];
}
});
openerp.web.ViewEditor.WidgetProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, node, id) {
this._super(view, node, id);
init: function(view, id) {
this._super(view, id);
this.registry = openerp.web.form.widgets;
var values = _.keys(this.registry.map);
values.push('');
@ -702,44 +769,44 @@ openerp.web.ViewEditor.WidgetProperty = openerp.web.ViewEditor.FieldSelect.exten
},
});
openerp.web.ViewEditor.IconProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, node, id) {
this._super(view, node, id);
init: function(view, id) {
this._super(view, id);
this.value = icons;
},
});
openerp.web.ViewEditor.ButtonTargetProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, node, id) {
this._super(view, node, id);
init: function(view, id) {
this._super(view, id);
this.value = [['', ''], ['new', 'New Window']];
},
});
openerp.web.ViewEditor.ButtonTypeProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, node, id) {
this._super(view, node, id);
init: function(view, id) {
this._super(view, id);
this.value = [['', ''], ['action', 'Action'], ['object', 'Object'], ['workflow', 'Workflow'], ['server_action', 'Server Action']];
},
});
openerp.web.ViewEditor.AlignProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, node, id) {
this._super(view, node, id);
init: function(view, id) {
this._super(view, id);
this.value = [['', ''], ['0.0', 'Left'], ['0.5', 'Center'], ['1.0', 'Right']];
},
});
openerp.web.ViewEditor.ButtonSpecialProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, node, id) {
this._super(view, node, id);
init: function(view, id) {
this._super(view, id);
this.value = [['',''],['save', 'Save Button'], ['cancel', 'Cancel Button'], ['open', 'Open Button']];
},
});
openerp.web.ViewEditor.PositionProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, node, id) {
this._super(view, node, id);
init: function(view, id) {
this._super(view, id);
this.value = [['',''],['after', 'After'],['before', 'Before'],['inside', 'Inside'],['replace', 'Replace']];
},
});
openerp.web.ViewEditor.GroupsProperty = openerp.web.ViewEditor.FieldSelect.extend({
init: function(view, node, id) {
this._super(view, node, id);
init: function(view, id) {
this._super(view, id);
this.multiple = true;
},
start: function () {

View File

@ -102,7 +102,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
self.on_pager_action(action);
});
this.$form_header.find('button.oe_form_button_save').click(this.do_save_then_readonly);
this.$form_header.find('button.oe_form_button_save').click(this.on_button_save);
this.$form_header.find('button.oe_form_button_new').click(this.on_button_new);
this.$form_header.find('button.oe_form_button_duplicate').click(this.on_button_duplicate);
this.$form_header.find('button.oe_form_button_delete').click(this.on_button_delete);
@ -197,7 +197,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
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();
@ -295,7 +294,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
return self.on_processed_onchange(response, processed);
});
} else {
console.log("Wrong on_change format", on_change);
console.warn("Wrong on_change format", on_change);
}
}
} catch(e) {
@ -346,6 +345,9 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
return $.Deferred().reject();
}
},
on_button_save: function() {
return this.do_save().then(this.do_set_readonly);
},
on_button_new: function() {
var self = this;
var def = $.Deferred();
@ -404,9 +406,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
* @param {Function} success callback on save success
* @param {Boolean} [prepend_on_create=false] if ``do_save`` creates a new record, should that record be inserted at the start of the dataset (by default, records are added at the end)
*/
do_save_then_readonly: function(success, prepend_on_create) {
return this.do_save(success, prepend_on_create).then(this.do_set_readonly);
},
do_save: function(success, prepend_on_create) {
var self = this;
var action = function() {
@ -435,12 +434,18 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
self.on_invalid();
return $.Deferred().reject();
} else {
console.log("About to save", values);
if (!self.datarecord.id) {
openerp.log("FormView(", self, ") : About to create", values);
return self.dataset.create(values).pipe(function(r) {
return self.on_created(r, undefined, prepend_on_create);
}).then(success);
} else if (_.isEmpty(values)) {
openerp.log("FormView(", self, ") : Nothing to save");
if (success) {
success();
}
} else {
openerp.log("FormView(", self, ") : About to save", values);
return self.dataset.write(self.datarecord.id, values, {}).pipe(function(r) {
return self.on_saved(r);
}).then(success);
@ -503,7 +508,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
if (this.sidebar) {
this.sidebar.attachments.do_update();
}
console.debug("The record has been created with id #" + this.datarecord.id);
openerp.log("The record has been created with id #" + this.datarecord.id);
this.reload();
return $.when(_.extend(r, {created: true})).then(success);
}
@ -697,7 +702,7 @@ openerp.web.form.compute_domain = function(expr, fields) {
stack.push(!_(val).contains(field_value));
break;
default:
console.log("Unsupported operator in modifiers :", op);
console.warn("Unsupported operator in modifiers :", op);
}
}
return _.all(stack, _.identity);
@ -1097,7 +1102,7 @@ openerp.web.form.WidgetLabel = openerp.web.form.Widget.extend({
var self = this;
this.$element.find("label").dblclick(function() {
var widget = self['for'] || self;
console.log(widget.element_class , widget);
openerp.log(widget.element_class , widget);
window.w = widget;
});
}

View File

@ -441,6 +441,16 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
}
}
var $res_logs = this.$element.find('.oe-view-manager-logs:first');
$res_logs.delegate('a.oe-more-logs', 'click', function () {
$res_logs.removeClass('oe-folded');
return false;
}).delegate('a.oe-remove-everything', 'click', function () {
$res_logs.removeClass('oe-has-more')
.find('ul').empty();
return false;
});
return manager_ready;
},
on_mode_switch: function (view_type) {
@ -518,10 +528,14 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
*/
do_display_log: function (log_records) {
var self = this,
$logs = this.$element.find('ul.oe-view-manager-logs:first').empty();
_(log_records).each(function (record) {
cutoff = 3,
$logs = this.$element.find('.oe-view-manager-logs:first')
.addClass('oe-folded'),
$logs_list = $logs.find('ul').empty();
$logs.toggleClass('oe-has-more', log_records.length > cutoff);
_(log_records.reverse()).each(function (record) {
$(_.sprintf('<li><a href="#">%s</a></li>', record.name))
.appendTo($logs)
.appendTo($logs_list)
.delegate('a', 'click', function (e) {
self.do_action({
type: 'ir.actions.act_window',
@ -564,36 +578,38 @@ session.web.Sidebar = session.web.Widget.extend({
},
add_default_sections: function() {
this.add_section(_t('Customize'), 'customize');
this.add_items('customize', [
{
label: _t("Manage Views"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object")
}, {
label: _t("Edit Workflow"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object"),
classname: 'oe_hide oe_sidebar_edit_workflow'
}, {
label: _t("Customize Object"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object")
}
]);
if (this.session.uid === 1) {
this.add_section(_t('Customize'), 'customize');
this.add_items('customize', [
{
label: _t("Manage Views"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object")
}, {
label: _t("Edit Workflow"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object"),
classname: 'oe_hide oe_sidebar_edit_workflow'
}, {
label: _t("Customize Object"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object")
}, {
label: _t("Translate"),
callback: this.call_default_on_sidebar,
title: _t("Technical translation")
}
]);
}
this.add_section(_t('Other Options'), 'other');
this.add_items('other', [
this.add_items('other', [
{
label: _t("Import"),
callback: this.call_default_on_sidebar
}, {
label: _t("Export"),
callback: this.call_default_on_sidebar
}, {
label: _t("Translate"),
callback: this.call_default_on_sidebar,
classname: 'oe_sidebar_translate oe_hide'
}, {
label: _t("View Log"),
callback: this.call_default_on_sidebar,
@ -619,14 +635,14 @@ session.web.Sidebar = session.web.Widget.extend({
}
});
},
add_section: function(name, code) {
if(!code) code = _.underscored(name);
var $section = this.sections[code];
if(!$section) {
section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
var $section = $(session.web.qweb.render("Sidebar.section", {
var section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
$section = $(session.web.qweb.render("Sidebar.section", {
section_id: section_id,
name: name,
classname: 'oe_sidebar_' + code
@ -740,11 +756,6 @@ session.web.TranslateDialog = session.web.Dialog.extend({
this._super();
$.when(this.languages_loaded).then(function() {
self.$element.html(session.web.qweb.render('TranslateDialog', { widget: self }));
self.$element.tabs();
if (!(self.view.translatable_fields && self.view.translatable_fields.length)) {
self.hide_tabs('fields');
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')));
@ -787,21 +798,6 @@ session.web.TranslateDialog = session.web.Dialog.extend({
});
$.when.apply(null, deffered).then(callback);
},
show_tabs: function() {
for (var i = 0; i < arguments.length; i++) {
this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().show();
}
},
hide_tabs: function() {
for (var i = 0; i < arguments.length; i++) {
this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().hide();
}
},
select_tab: function(name) {
this.show_tabs(name);
var index = this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().index() - 1;
this.$element.tabs('select', index);
},
open: function(field) {
var self = this,
sup = this._super;
@ -810,7 +806,9 @@ session.web.TranslateDialog = session.web.Dialog.extend({
self.do_load_fields_values(function() {
sup.call(self);
if (field) {
// TODO: focus and scroll to field
var $field_input = self.$element.find('tr[data-field="' + field.name + '"] td:nth-child(2) *:first-child');
self.$element.scrollTo($field_input);
$field_input.focus();
}
});
} else {
@ -963,7 +961,15 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{
export_view.start();
},
on_sidebar_translate: function() {
this.open_translate_dialog();
return this.do_action({
res_model : 'ir.translation',
domain : [['type', '!=', 'object'], '|', ['name', '=', this.dataset.model], ['name', 'ilike', this.dataset.model + ',']],
views: [[false, 'list'], [false, 'form']],
type : 'ir.actions.act_window',
auto_search : true,
view_type : "list",
view_mode : "list"
});
},
on_sidebar_view_log: function() {
}

View File

@ -457,7 +457,11 @@
</button>
</t>
<t t-jquery=".oe-view-manager-header" t-operation="after">
<ul class="oe-view-manager-logs"></ul>
<div class="oe-view-manager-logs oe-folded">
<ul></ul>
<a class="oe-more-logs" href="#">More…</a>
<a class="oe-remove-everything ui-icon ui-icon-closethick"/>
</div>
</t>
</t>
@ -482,38 +486,25 @@
</t>
<t t-name="TranslateDialog">
<ul class="oe_translate_tabs">
<li><a t-attf-href="##{widget.element_id}_fields">Fields</a></li>
<li><a t-attf-href="##{widget.element_id}_view">View labels</a></li>
<li><a t-attf-href="##{widget.element_id}_sidebar">Sidebar Relates</a></li>
</ul>
<div t-attf-id="#{widget.element_id}_fields">
<table t-if="widget.view.translatable_fields" class="oe_frame oe_forms oe_translation_form" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="oe_form_separator" width="1%" nowrap="nowrap">
<div class="separator horizontal">Field</div>
</td>
<th t-foreach="widget.languages" align="left">
<div class="separator horizontal"><t t-esc="name"/></div>
</th>
</tr>
<tr t-foreach="widget.view.translatable_fields" t-as="field">
<td class="oe_form_frame_cell" width="1%" nowrap="nowrap">
<label class="oe_label"><t t-esc="field.string"/>:</label>
</td>
<td t-foreach="widget.languages" t-as="lg" class="oe_form_frame_cell">
<input t-if="field.type == 'char'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" data-value="" class="oe_trad_field" style="width: 100%"/>
<textarea t-if="field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" data-value="" class="oe_trad_field" style="width: 100%"></textarea>
</td>
</tr>
</table>
</div>
<div t-attf-id="#{widget.element_id}_view">
Translate view
</div>
<div t-attf-id="#{widget.element_id}_sidebar">
Translate sidebar
</div>
<table t-if="widget.view.translatable_fields" class="oe_frame oe_forms oe_translation_form" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="oe_form_separator" width="1%" nowrap="nowrap">
<div class="separator horizontal">Field</div>
</td>
<th t-foreach="widget.languages" align="left">
<div class="separator horizontal"><t t-esc="name"/></div>
</th>
</tr>
<tr t-foreach="widget.view.translatable_fields" t-as="field" t-att-data-field="field.name">
<td class="oe_form_frame_cell" width="1%" nowrap="nowrap">
<label class="oe_label"><t t-esc="field.string"/>:</label>
</td>
<td t-foreach="widget.languages" t-as="lg" class="oe_form_frame_cell">
<input t-if="field.type == 'char'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" data-value="" class="oe_trad_field" style="width: 100%"/>
<textarea t-if="field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" data-value="" class="oe_trad_field" style="width: 100%"></textarea>
</td>
</tr>
</table>
</t>
<t t-name="TreeView">
<select t-if="toolbar" style="width: 30%">
@ -1015,7 +1006,7 @@
<t t-name="SearchView">
<form class="oe_forms">
<t t-call="SearchView.render_lines"/>
<div class="oe_search-view-buttons" style="text-align: right;">
<div class="oe_search-view-buttons">
<input type="submit" value="Search"/>
<input type="reset" value="Clear"/>
<button class="oe_search-view-custom-filter-btn"><span>Advanced Filter</span></button>

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-08 06:12+0000\n"
"X-Generator: Launchpad (build 14231)\n"
"X-Launchpad-Export-Date: 2011-11-09 05:09+0000\n"
"X-Generator: Launchpad (build 14263)\n"
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Welcome to your new OpenERP instance."

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
"PO-Revision-Date: 2011-10-11 14:05+0000\n"
"PO-Revision-Date: 2011-11-08 21:59+0000\n"
"Last-Translator: Jonas Mortensen <Unknown>\n"
"Language-Team: Danish <da@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: 2011-11-01 05:10+0000\n"
"X-Generator: Launchpad (build 14197)\n"
"X-Launchpad-Export-Date: 2011-11-09 05:09+0000\n"
"X-Generator: Launchpad (build 14263)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
@ -23,7 +23,7 @@ msgstr "Ny tilstand"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Edge"
msgstr ""
msgstr "Ny kant"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Show Grid:"