Merge lp:~xmo-deactivatedaccount/openobject-client-web/iframe-resize-events into lp:~openerp-dev/openobject-client-web/trunk-dev-web

Proposed by Xavier (Open ERP)
Status: Merged
Merged at revision: 2998
Proposed branch: lp:~xmo-deactivatedaccount/openobject-client-web/iframe-resize-events
Merge into: lp:~openerp-dev/openobject-client-web/trunk-dev-web
Diff against target: 2626 lines (+1047/-577) (has conflicts)
10 files modified
addons/openerp/controllers/templates/menu.mako (+38/-52)
addons/openerp/static/javascript/ajax_stat.js (+0/-1)
addons/openerp/static/javascript/form.js (+1/-0)
addons/openerp/static/javascript/listgrid.js (+196/-201)
addons/openerp/static/javascript/menubar.js (+0/-29)
addons/openerp/static/javascript/notebook/notebook.js (+16/-0)
addons/openerp/static/javascript/openerp/openerp.ui.textarea.js (+31/-27)
addons/openerp/static/javascript/search.js (+407/-12)
addons/openerp/static/javascript/treegrid.js (+253/-232)
openobject/static/javascript/openobject/openobject.base.js (+105/-23)
Text conflict in addons/openerp/static/javascript/search.js
To merge this branch: bzr merge lp:~xmo-deactivatedaccount/openobject-client-web/iframe-resize-events
Reviewer Review Type Date Requested Status
Sananaz (Open ERP) (community) Approve
Review via email: mp+22692@code.launchpad.net

This proposal has been superseded by a proposal from 2010-04-06.

Description of the change

Currently, the iframe is resized based on a timer which, every 10mn, does a full pass to re-set the height of #appFrame to ensure the scrollbar is on the page itself, not in the iframe.

This poses performance problems as the resizing operations are fairly expensive and restarted very often.

The current branch tries to fix that by hooking into specific events (which can change the size of the iframe's content and therefore require that the iframe element itself be resized to match) and removes the timer.

Could you:
* Check that I didn't introduce any outstanding bug (and review as "needs-fixing")
* See if you find obvious cases that I missed, and report them (and review as "needs-fixing")

To post a comment you must log in.
2980. By Vaibhav Darji

Clean up(code review).

2981. By Vaibhav Darji

Clean up.

2982. By Navrang Oza

[FIX] Code cleanup (Review code.)

2983. By Sananaz (Open ERP)

[FIX] Fixed display problem for custom filter.

2984. By Sananaz (Open ERP)

[IMP] Improve custom filter when pass context.

2985. By Nitesh Vaghani

[Add] Addons CKEditor

2986. By Navrang Oza

[IMP] Removed use of search_count.

2987. By Sananaz (Open ERP)

[IMP] Removed regression, Improved process view.

2988. By Navrang Oza

[FIX] Minor changes.

2989. By Sananaz (Open ERP)

[MERGE] iframe resizing problem, code optimization.

2990. By Xavier (Open ERP)

[REM] revert merge of events-based iframe resizing

Broken merge

2991. By Sananaz (Open ERP)

[FIX] Fixed minor problem for search view.

Revision history for this message
Sananaz (Open ERP) (sma-tiny) wrote :

Fixed iframe resizing problem.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'addons/openerp/controllers/templates/menu.mako'
2--- addons/openerp/controllers/templates/menu.mako 2010-03-29 05:47:49 +0000
3+++ addons/openerp/controllers/templates/menu.mako 2010-04-02 13:09:19 +0000
4@@ -2,53 +2,39 @@
5
6 <%def name="header()">
7 <title>OpenERP</title>
8-
9+
10 <link href="/openerp/static/css/accordion.css" rel="stylesheet" type="text/css"/>
11 <link href="/openerp/static/css/treegrid.css" rel="stylesheet" type="text/css"/>
12 <link href="/openerp/static/css/notebook.css" rel="stylesheet" type="text/css"/>
13-
14- <script type="text/javascript" src="/openerp/static/javascript/menubar.js"></script>
15+
16 <script type="text/javascript" src="/openerp/static/javascript/accordion.js"></script>
17 <script type="text/javascript" src="/openerp/static/javascript/treegrid.js"></script>
18 <script type="text/javascript" src="/openerp/static/javascript/notebook/notebook.js"></script>
19-
20- <script type="text/javascript">
21-
22- // call adjustAppFrame every 0.5 second
23- function adjustFrame(wait) {
24- try {
25- adjustAppFrame();
26- } catch(e){}
27- setTimeout(adjustFrame, wait);
28- }
29- adjustFrame(0.5);
30-
31-</script>
32-
33- <style>
34+
35+ <style type="text/css">
36 .accordion-content {
37 }
38-
39+
40 .accordion {
41 border: none;
42 }
43-
44+
45 .accordion-title {
46 padding: 2px;
47 }
48-
49+
50 #menubar_container {
51 overflow: auto;
52- border: 1px solid black;
53+ border: 1px solid black;
54 }
55-
56+
57 #content_iframe {
58- overflow-x: auto;
59- overflow-y: hidden;
60+ overflow-x: auto;
61+ overflow-y: hidden;
62 }
63-
64+
65 </style>
66-
67+
68 </%def>
69
70 <%def name="content()">
71@@ -57,39 +43,39 @@
72
73 <div id="menutabs" class="notebook menu-tabs">
74 %for parent in parents:
75- <div id="${parent['id']}" title="${parent['name']}"></div>
76+ <div id="${parent['id']}" title="${parent['name']}"></div>
77 %endfor
78 </div>
79
80 <script type="text/javascript">
81-
82+
83 var nb = new Notebook('menutabs', {
84 'closable': false,
85 'scrollable': true
86 });
87-
88- MochiKit.Signal.connect(nb, 'click', function(nb, tab){
89+
90+ MochiKit.Signal.connect(nb, 'click', function(nb, tab) {
91 window.location.href = openobject.http.getURL("/menu", {active: tab.id});
92 });
93-
94+
95 </script>
96-
97+
98 <table id="contents" width="100%">
99 <tr>
100 <td width="250" valign="top">
101 <div id="menubar" class="accordion">
102 % for tool in tools:
103- <div class="accordion-block">
104- <table class="accordion-title">
105- <tr>
106- <td><img src="${tool['icon']}" width="16" height="16" align="left"/></td>
107- <td>${tool['name']}</td>
108- </tr>
109- </table>
110- <div class="accordion-content">
111- ${tool['tree'].display()}
112+ <div class="accordion-block">
113+ <table class="accordion-title">
114+ <tr>
115+ <td><img alt="" src="${tool['icon']}" width="16" height="16" align="left"/></td>
116+ <td>${tool['name']}</td>
117+ </tr>
118+ </table>
119+ <div class="accordion-content">
120+ ${tool['tree'].display()}
121+ </div>
122 </div>
123- </div>
124 % endfor
125 </div>
126 <script type="text/javascript">
127@@ -97,16 +83,16 @@
128 </script>
129 </td>
130 <td valign="top">
131- % if setup:
132- <iframe id="appFrame" width="100%"
133- scrolling="no"
134- frameborder="0"
135- name="appFrame" src="${py.url('/home')}"></iframe>
136+ % if setup:
137+ <iframe id="appFrame" width="100%"
138+ scrolling="no"
139+ frameborder="0"
140+ name="appFrame" src="${py.url('/home')}"></iframe>
141 % else:
142- <iframe id="appFrame" width="100%"
143- scrolling="no"
144- frameborder="0"
145- name="appFrame"></iframe>
146+ <iframe id="appFrame" width="100%"
147+ scrolling="no"
148+ frameborder="0"
149+ name="appFrame"></iframe>
150 % endif
151 </td>
152 </tr>
153
154=== modified file 'addons/openerp/static/javascript/ajax_stat.js'
155--- addons/openerp/static/javascript/ajax_stat.js 2009-10-30 08:59:56 +0000
156+++ addons/openerp/static/javascript/ajax_stat.js 2010-04-02 13:09:19 +0000
157@@ -79,7 +79,6 @@
158
159 MochiKit.Signal.connect(window, "onresize", onAjaxStatPosition);
160 MochiKit.Signal.connect(window, "onscroll", onAjaxStatPosition);
161-
162 onAjaxStatPosition();
163 });
164
165
166=== modified file 'addons/openerp/static/javascript/form.js'
167--- addons/openerp/static/javascript/form.js 2010-04-02 06:44:11 +0000
168+++ addons/openerp/static/javascript/form.js 2010-04-02 13:09:19 +0000
169@@ -593,6 +593,7 @@
170 }
171
172 MochiKit.Signal.signal(fld, 'onchange');
173+ MochiKit.Signal.signal(window.document, 'onfieldchange', fld);
174 }
175
176 fld.__lock_onchange = false;
177
178=== modified file 'addons/openerp/static/javascript/listgrid.js'
179--- addons/openerp/static/javascript/listgrid.js 2010-04-02 06:44:11 +0000
180+++ addons/openerp/static/javascript/listgrid.js 2010-04-02 13:09:19 +0000
181@@ -40,11 +40,11 @@
182 }
183
184 this.__init__(name);
185-}
186+};
187
188 ListView.prototype = {
189
190- __init__: function(name){
191+ __init__: function(name) {
192
193 var prefix = name == '_terp_list' ? '' : name + '/';
194
195@@ -69,130 +69,125 @@
196 openobject.dom.get(name).__listview = this;
197 },
198
199- checkAll: function(clear){
200+ checkAll: function(clear) {
201
202 clear = clear ? false : true;
203
204 boxes = openobject.dom.get(this.name).getElementsByTagName('input');
205- forEach(boxes, function(box){
206+ forEach(boxes, function(box) {
207 box.checked = clear;
208 });
209 },
210
211 getRecords: function() {
212- var records = map(function(row){
213+ var records = map(function(row) {
214 return parseInt(getNodeAttribute(row, 'record')) || 0;
215 }, openobject.dom.select('tr.grid-row', this.name));
216
217- return filter(function(rec){
218+ return filter(function(rec) {
219 return rec;
220 }, records);
221 },
222
223 getSelectedRecords: function() {
224- return map(function(box){
225+ return map(function(box) {
226 return box.value;
227 }, this.getSelectedItems());
228 },
229
230 getSelectedItems: function() {
231- return filter(function(box){
232+ return filter(function(box) {
233 return box.id && box.checked;
234 }, openobject.dom.select('input.grid-record-selector', this.name));
235 },
236
237- getColumns: function(dom){
238+ getColumns: function(dom) {
239 dom = dom || this.name;
240 var header = openobject.dom.select('tr.grid-header', dom)[0];
241
242- return filter(function(c){
243+ return filter(function(c) {
244 return c.id ? true : false;
245 }, openobject.dom.select('th.grid-cell', header));
246 },
247-
248- makeArgs: function(){
249
250+ makeArgs: function() {
251 var args = {};
252- var name = '/' + this.name;
253- var names = name.split('/');
254+ var names = ('/' + this.name).split('/');
255
256 var prefix = '';
257 var items = openobject.dom.select('input');
258
259- while(names.length) {
260+ while (names.length) {
261
262 var name = names.shift();
263 prefix = prefix + (name ? name + '/' : '');
264
265- var patern = prefix + '_terp_';
266+ var pattern = prefix + '_terp_';
267
268- forEach(items, function(item){
269- if(item.name.match("^"+ patern) == patern && !item.name.match('^_terp_listfields/')) {
270- args[item.name] = item.value;
271+ forEach(items, function(item) {
272+ if (item.name.match("^" + pattern) == pattern && !item.name.match('^_terp_listfields/')) {
273+ args[item.name] = item.value;
274 }
275 });
276 }
277
278 return args;
279 }
280-}
281+};
282
283 // inline editor related functions
284 MochiKit.Base.update(ListView.prototype, {
285
286- adjustEditors: function(newlist){
287+ adjustEditors: function(newlist) {
288
289 var editors = this.getEditors(false, newlist);
290-
291 forEach(editors, function(e) {
292 // disable autocomplete (Firefox < 2.0 focus bug)
293 setNodeAttribute(e, 'autocomplete', 'OFF');
294 });
295
296- if (/MSIE/.test(navigator.userAgent)){
297+ if (/MSIE/.test(navigator.userAgent)) {
298 return editors;
299 }
300
301- var widths = {};
302-
303+ var columnWidths = {};
304 // set the column widths of the newlist
305- forEach(this.getColumns(), function(c){
306- widths[c.id] = parseInt(c.offsetWidth) - 8;
307- });
308-
309- forEach(this.getColumns(newlist), function(c){
310- c.style.width = widths[c.id] + 'px';
311- });
312-
313- var widths = {};
314- forEach(this.getEditors(), function(e){
315- widths[e.id] = parseInt(e.offsetWidth);
316+ forEach(this.getColumns(), function(c) {
317+ columnWidths[c.id] = parseInt(c.offsetWidth) - 8;
318+ });
319+
320+ forEach(this.getColumns(newlist), function(c) {
321+ c.style.width = columnWidths[c.id] + 'px';
322+ });
323+
324+ var editorWidths = {};
325+ forEach(this.getEditors(), function(e) {
326+ editorWidths[e.id] = parseInt(e.offsetWidth);
327 });
328
329 return editors;
330 },
331
332- bindKeyEventsToEditors: function(editors){
333+ bindKeyEventsToEditors: function(editors) {
334 var self = this;
335- var editors = filter(function(e){
336+ var enabledEditors = filter(function(e) {
337 return e.type != 'hidden' && !e.disabled
338 }, editors);
339
340- forEach(editors, function(e){
341+ forEach(enabledEditors, function(e) {
342 connect(e, 'onkeydown', self, self.onKeyDown);
343 addElementClass(e, 'listfields');
344 });
345 },
346
347- getEditors: function(named, dom){
348- var editors = [];
349+ getEditors: function(named, dom) {
350 var dom = dom ? dom : this.name;
351
352- editors = openobject.dom.select("input, select, textarea", dom);
353+ var editors = openobject.dom.select("input, select, textarea", dom);
354
355- return filter(function(e){
356+ return filter(function(e) {
357 name = named ? e.name : e.id;
358- return name && name.indexOf('_terp_listfields') == 0;
359+ return name && name.indexOf('_terp_listfields') == 0;
360 }, editors);
361 }
362
363@@ -200,49 +195,49 @@
364
365 // pagination & reordering
366 MochiKit.Base.update(ListView.prototype, {
367- sort_by_order: function(id) {
368- var self = this
369- var domain = [];
370- var args = {}
371- if(getElement('_'+this.name+'_button1'))
372- domain = getNodeAttribute(getElement('_'+this.name+'_button1'),'domain')
373-
374- args['_terp_model'] = this.model
375- args['_terp_sort_order'] = id
376- args['_terp_sort_domain'] = domain
377- var _terp_id = openobject.dom.get(self.name + '/_terp_id') || openobject.dom.get('_terp_id');
378+ sort_by_order: function(id) {
379+ var self = this;
380+ var domain = [];
381+ var args = {};
382+ if (getElement('_' + this.name + '_button1')) {
383+ domain = getNodeAttribute(getElement('_' + this.name + '_button1'), 'domain');
384+ }
385+
386+ args['_terp_model'] = this.model;
387+ args['_terp_sort_order'] = id;
388+ args['_terp_sort_domain'] = domain;
389+ var _terp_id = openobject.dom.get(self.name + '/_terp_id') || openobject.dom.get('_terp_id');
390 var _terp_ids = openobject.dom.get(self.name + '/_terp_ids') || openobject.dom.get('_terp_ids');
391-
392- if(this.ids!='[]')
393- {
394- var req = openobject.http.postJSON('/listgrid/sort_by_order', args);
395- req.addCallback(function(obj) {
396- if(obj.ids) {
397- _terp_ids.value = '[' + obj.ids.join(',') + ']';
398- self.reload();
399- }
400- else
401- alert(obj.error)
402- })
403- }
404- },
405-
406- dragRow: function(drag,drop,event) {
407- var args = {}
408- var _list_view = new ListView(drag.parentNode.parentNode.id.split("_grid")[0]);
409- var _terp_model = getElement(drag.parentNode.parentNode.id.split("_grid")[0]+'/_terp_model') || getElement('_terp_model')
410- args['_terp_model'] = _terp_model.value
411- var _terp_ids = getElement(drag.parentNode.parentNode.id.split("_grid")[0]+'/_terp_ids') || getElement('_terp_ids')
412- args['_terp_ids'] = _terp_ids.value
413- args['_terp_id'] = getNodeAttribute(drag,'record')
414- args['_terp_swap_id'] = getNodeAttribute(drop,'record')
415-
416- var req = openobject.http.postJSON('/listgrid/dragRow', args);
417- req.addCallback(function() {
418- _list_view.reload()
419- })
420- },
421-
422+
423+ if (this.ids != '[]') {
424+ var req = openobject.http.postJSON('/listgrid/sort_by_order', args);
425+ req.addCallback(function(obj) {
426+ if (obj.ids) {
427+ _terp_ids.value = '[' + obj.ids.join(',') + ']';
428+ self.reload();
429+ } else {
430+ alert(obj.error);
431+ }
432+ })
433+ }
434+ },
435+
436+ dragRow: function(drag, drop, event) {
437+ var args = {};
438+ var _list_view = new ListView(drag.parentNode.parentNode.id.split("_grid")[0]);
439+ var _terp_model = getElement(drag.parentNode.parentNode.id.split("_grid")[0] + '/_terp_model') || getElement('_terp_model');
440+ args['_terp_model'] = _terp_model.value;
441+ var _terp_ids = getElement(drag.parentNode.parentNode.id.split("_grid")[0] + '/_terp_ids') || getElement('_terp_ids');
442+ args['_terp_ids'] = _terp_ids.value;
443+ args['_terp_id'] = getNodeAttribute(drag, 'record');
444+ args['_terp_swap_id'] = getNodeAttribute(drop, 'record');
445+
446+ var req = openobject.http.postJSON('/listgrid/dragRow', args);
447+ req.addCallback(function() {
448+ _list_view.reload();
449+ })
450+ },
451+
452 moveUp: function(id) {
453
454 var self = this;
455@@ -250,11 +245,11 @@
456
457 args['_terp_model'] = this.model;
458 args['_terp_ids'] = this.ids;
459-
460+
461 args['_terp_id'] = id;
462
463 var req = openobject.http.postJSON('/listgrid/moveUp', args);
464- req.addCallback(function(){
465+ req.addCallback(function() {
466 self.reload();
467 });
468 },
469@@ -262,14 +257,14 @@
470 moveDown: function(id) {
471
472 var self = this;
473- var args = {};
474-
475- args['_terp_model'] = this.model;
476- args['_terp_ids'] = this.ids;
477- args['_terp_id'] = id;
478+ var args = {
479+ '_terp_model': this.model,
480+ '_terp_ids': this.ids,
481+ '_terp_id': id
482+ };
483
484 var req = openobject.http.postJSON('/listgrid/moveDown', args);
485- req.addCallback(function(){
486+ req.addCallback(function() {
487 self.reload();
488 });
489 }
490@@ -278,7 +273,7 @@
491 // event handlers
492 MochiKit.Base.update(ListView.prototype, {
493
494- onKeyDown: function(evt){
495+ onKeyDown: function(evt) {
496 var key = evt.key();
497 var src = evt.src();
498
499@@ -286,19 +281,19 @@
500 return;
501 }
502
503- if (key.string == "KEY_ESCAPE"){
504+ if (key.string == "KEY_ESCAPE") {
505 evt.stop();
506 return this.reload();
507 }
508
509- if (key.string == "KEY_ENTER"){
510+ if (key.string == "KEY_ENTER") {
511
512- if (hasElementClass(src, "m2o")){
513+ if (hasElementClass(src, "m2o")) {
514
515 var k = src.id;
516 k = k.slice(0, k.length - 5);
517
518- if (src.value && !openobject.dom.get(k).value){
519+ if (src.value && !openobject.dom.get(k).value) {
520 return;
521 }
522 }
523@@ -311,21 +306,21 @@
524 return this.save(this.current_record);
525 }
526
527- var editors = openobject.dom.select('listfields',this.name);
528+ var editors = openobject.dom.select('listfields', this.name);
529
530 var first = editors.shift();
531 var last = editors.pop();
532
533- if (src == last){
534+ if (src == last) {
535 evt.stop();
536 first.focus();
537 first.select();
538 }
539 },
540
541- onButtonClick: function(name, btype, id, sure, context){
542+ onButtonClick: function(name, btype, id, sure, context) {
543
544- if (sure && !confirm(sure)){
545+ if (sure && !confirm(sure)) {
546 return;
547 }
548
549@@ -334,15 +329,15 @@
550
551 if (btype == "open") {
552 return window.open(get_form_action('/form/edit', {
553- id: id,
554- ids: openobject.dom.get(prefix + '_terp_ids').value,
555- model: openobject.dom.get(prefix + '_terp_model').value,
556- view_ids: openobject.dom.get(prefix + '_terp_view_ids').value,
557- domain: openobject.dom.get(prefix + '_terp_domain').value,
558- context: openobject.dom.get(prefix + '_terp_context').value,
559- limit: openobject.dom.get(prefix + '_terp_limit').value,
560- offset: openobject.dom.get(prefix + '_terp_offset').value,
561- count: openobject.dom.get(prefix + '_terp_count').value}));
562+ id: id,
563+ ids: openobject.dom.get(prefix + '_terp_ids').value,
564+ model: openobject.dom.get(prefix + '_terp_model').value,
565+ view_ids: openobject.dom.get(prefix + '_terp_view_ids').value,
566+ domain: openobject.dom.get(prefix + '_terp_domain').value,
567+ context: openobject.dom.get(prefix + '_terp_context').value,
568+ limit: openobject.dom.get(prefix + '_terp_limit').value,
569+ offset: openobject.dom.get(prefix + '_terp_offset').value,
570+ count: openobject.dom.get(prefix + '_terp_count').value}));
571 }
572
573 name = name.split('.').pop();
574@@ -352,14 +347,14 @@
575 _terp_id : id,
576 _terp_button_name : name,
577 _terp_button_type : btype
578- }
579+ };
580
581 var req = eval_domain_context_request({source: this.name, context : context || '{}'});
582- req.addCallback(function(res){
583+ req.addCallback(function(res) {
584 params['_terp_context'] = res.context;
585 var req = openobject.http.postJSON('/listgrid/button_action', params);
586- req.addCallback(function(obj){
587- if (obj.error){
588+ req.addCallback(function(obj) {
589+ if (obj.error) {
590 return alert(obj.error);
591 }
592
593@@ -369,8 +364,9 @@
594
595 if (obj.reload) {
596 window.location.reload();
597- } else
598+ } else {
599 self.reload();
600+ }
601 });
602 });
603 }
604@@ -379,15 +375,15 @@
605 // standard actions
606 MochiKit.Base.update(ListView.prototype, {
607
608- create: function(default_get_ctx){
609+ create: function(default_get_ctx) {
610 this.edit(-1, default_get_ctx);
611 },
612
613- edit: function(edit_inline, default_get_ctx){
614+ edit: function(edit_inline, default_get_ctx) {
615 this.reload(edit_inline, null, default_get_ctx);
616 },
617
618- save: function(id){
619+ save: function(id) {
620
621 if (openobject.http.AJAX_COUNT > 0) {
622 return callLater(1, bind(this.save, this), id);
623@@ -397,7 +393,7 @@
624 var data = getFormData(true);
625 var args = getFormParams('_terp_concurrency_info');
626
627- for(var k in data) {
628+ for (var k in data) {
629 if (k.indexOf(this.name + '/') == 0 || this.name == '_terp_list') {
630 args[k] = data[k];
631 }
632@@ -409,7 +405,7 @@
633 args['_terp_ids'] = openobject.dom.get(prefix + '_terp_ids').value;
634 args['_terp_model'] = this.model;
635
636- if (parent_field.length > 0){
637+ if (parent_field.length > 0) {
638 parent_field.pop();
639 }
640
641@@ -422,17 +418,18 @@
642 args['_terp_source'] = this.name;
643
644 var self = this;
645- var req= openobject.http.postJSON('/listgrid/save', args);
646+ var req = openobject.http.postJSON('/listgrid/save', args);
647
648- req.addCallback(function(obj){
649- if (obj.error){
650+ req.addCallback(function(obj) {
651+ if (obj.error) {
652 alert(obj.error);
653
654 if (obj.error_field) {
655 var fld = openobject.dom.get('_terp_listfields/' + obj.error_field);
656
657- if (fld && getNodeAttribute(fld, 'kind') == 'many2one')
658+ if (fld && getNodeAttribute(fld, 'kind') == 'many2one') {
659 fld = openobject.dom.get(fld.id + '_text');
660+ }
661
662 if (fld) {
663 fld.focus();
664@@ -445,26 +442,26 @@
665 openobject.dom.get(prefix + '_terp_ids').value = obj.ids;
666
667 self.reload(id > 0 ? null : -1, prefix ? 1 : 0);
668- }
669- });
670+ }
671+ });
672 },
673
674- remove: function(ids){
675+ remove: function(ids) {
676
677 var self = this;
678- var args = getFormParams('_terp_concurrency_info');;
679-
680- if(!ids) {
681+ var args = getFormParams('_terp_concurrency_info');
682+
683+
684+ if (!ids) {
685 var ids = this.getSelectedRecords();
686- if(ids.length > 0){
687+ if (ids.length > 0) {
688 ids = '[' + ids.join(', ') + ']';
689 }
690 }
691
692 if (ids.length == 0) {
693 return alert(_('You must select at least one record.'));
694- }
695- else if (!confirm(_('Do you really want to delete selected record(s) ?'))) {
696+ } else if (!confirm(_('Do you really want to delete selected record(s) ?'))) {
697 return false;
698 }
699
700@@ -473,8 +470,8 @@
701
702 var req = openobject.http.postJSON('/listgrid/remove', args);
703
704- req.addCallback(function(obj){
705- if (obj.error){
706+ req.addCallback(function(obj) {
707+ if (obj.error) {
708 alert(obj.error);
709 } else {
710 self.reload();
711@@ -482,9 +479,9 @@
712 });
713 },
714
715- go: function(action){
716+ go: function(action) {
717
718- if (openobject.http.AJAX_COUNT > 0){
719+ if (openobject.http.AJAX_COUNT > 0) {
720 return;
721 }
722
723@@ -498,7 +495,7 @@
724 var lv = l.value ? parseInt(l.value) : 0;
725 var cv = c.value ? parseInt(c.value) : 0;
726
727- switch(action) {
728+ switch (action) {
729 case 'next':
730 o.value = ov + lv;
731 break;
732@@ -516,7 +513,7 @@
733 this.reload();
734 },
735
736- reload: function(edit_inline, concurrency_info, default_get_ctx){
737+ reload: function(edit_inline, concurrency_info, default_get_ctx) {
738
739 if (openobject.http.AJAX_COUNT > 0) {
740 return callLater(1, bind(this.reload, this), edit_inline, concurrency_info);
741@@ -524,7 +521,7 @@
742
743 var self = this;
744 var args = this.makeArgs();
745-
746+
747 // add args
748 args['_terp_source'] = this.name;
749 args['_terp_edit_inline'] = edit_inline;
750@@ -537,15 +534,15 @@
751 args['_terp_search_data'] = openobject.dom.get('_terp_search_data').value;
752 args['_terp_filter_domain'] = openobject.dom.get('_terp_filter_domain').value;
753 }
754-
755+
756 var req = openobject.http.postJSON('/listgrid/get', args);
757- req.addCallback(function(obj){
758+ req.addCallback(function(obj) {
759
760 var _terp_id = openobject.dom.get(self.name + '/_terp_id') || openobject.dom.get('_terp_id');
761 var _terp_ids = openobject.dom.get(self.name + '/_terp_ids') || openobject.dom.get('_terp_ids');
762 var _terp_count = openobject.dom.get(self.name + '/_terp_count') || openobject.dom.get('_terp_count');
763
764- if(obj.ids) {
765+ if (obj.ids) {
766 _terp_id.value = obj.ids.length ? obj.ids[0] : 'False';
767 _terp_ids.value = '[' + obj.ids.join(',') + ']';
768 _terp_count.value = obj.count;
769@@ -557,8 +554,9 @@
770 var newlist = d.getElementsByTagName('table')[0];
771 var editors = self.adjustEditors(newlist);
772
773- if (editors.length > 0)
774+ if (editors.length > 0) {
775 self.bindKeyEventsToEditors(editors);
776+ }
777
778 self.current_record = edit_inline;
779
780@@ -571,20 +569,21 @@
781 if ((navigator.appName != 'Netscape') || (ua.indexOf('safari') != -1)) {
782 // execute JavaScript
783 var scripts = openobject.dom.select('script', newlist);
784- forEach(scripts, function(s){
785+ forEach(scripts, function(s) {
786 eval(s.innerHTML);
787 });
788 }
789
790 // update concurrency info
791- for(var key in obj.info) {
792+ for (var key in obj.info) {
793 try {
794 var items = openobject.dom.select("[name=_terp_concurrency_info][value*=" + key + "]")
795 var value = "('" + key + "', '" + obj.info[key] + "')";
796- for(var i=0; i<items.length;i++) {
797+ for (var i = 0; i < items.length; i++) {
798 items[i].value = value;
799 }
800- }catch(e){}
801+ } catch(e) {
802+ }
803 }
804
805 // set focus on the first field
806@@ -596,7 +595,7 @@
807
808 // call on_change for default values
809 if (editors.length && edit_inline == -1) {
810- forEach(editors, function(e){
811+ forEach(editors, function(e) {
812 if (e.value && getNodeAttribute(e, 'callback')) {
813 MochiKit.Signal.signal(e, 'onchange');
814 }
815@@ -612,7 +611,7 @@
816 // export/import functions
817 MochiKit.Base.update(ListView.prototype, {
818
819- exportData: function(){
820+ exportData: function() {
821
822 var ids = this.getSelectedRecords();
823
824@@ -623,69 +622,65 @@
825 ids = '[' + ids.join(',') + ']';
826
827 openobject.tools.openWindow(openobject.http.getURL('/impex/exp', {_terp_model: this.model,
828- _terp_source: this.name,
829- _terp_search_domain: openobject.dom.get('_terp_search_domain').value,
830- _terp_ids: ids,
831- _terp_view_ids : this.view_ids,
832- _terp_view_mode : this.view_mode}));
833+ _terp_source: this.name,
834+ _terp_search_domain: openobject.dom.get('_terp_search_domain').value,
835+ _terp_ids: ids,
836+ _terp_view_ids : this.view_ids,
837+ _terp_view_mode : this.view_mode}));
838 },
839
840- importData: function(){
841+ importData: function() {
842 openobject.tools.openWindow(openobject.http.getURL('/impex/imp', {_terp_model: this.model,
843- _terp_source: this.name,
844- _terp_view_ids : this.view_ids,
845- _terp_view_mode : this.view_mode}));
846+ _terp_source: this.name,
847+ _terp_view_ids : this.view_ids,
848+ _terp_view_mode : this.view_mode}));
849 }
850 });
851
852 var toggle_group_data = function(id) {
853-
854- img = openobject.dom.get('img_'+id);
855- rows = openobject.dom.select('tr.'+id);
856-
857- forEach(rows, function(rw){
858- if (rw.style.display == 'none') {
859- rw.style.display = '';
860- setNodeAttribute(img, 'src', '/openerp/static/images/treegrid/collapse.gif');
861- }
862- else {
863- rw.style.display = 'none';
864- setNodeAttribute(img, 'src', '/openerp/static/images/treegrid/expand.gif');
865- }
866- });
867-}
868+
869+ img = openobject.dom.get('img_' + id);
870+ rows = openobject.dom.select('tr.' + id);
871+
872+ forEach(rows, function(rw) {
873+ if (rw.style.display == 'none') {
874+ rw.style.display = '';
875+ setNodeAttribute(img, 'src', '/openerp/static/images/treegrid/collapse.gif');
876+ }
877+ else {
878+ rw.style.display = 'none';
879+ setNodeAttribute(img, 'src', '/openerp/static/images/treegrid/expand.gif');
880+ }
881+ });
882+};
883
884 var row_edit = function(evt) {
885- var row = [];
886- row = getElementsByTagAndClassName('tr', 'grid-row');
887-
888- forEach(row, function(e){
889- MochiKit.Signal.connect(e, 'ondblclick', e, select_row_edit);
890+ var row = getElementsByTagAndClassName('tr', 'grid-row');
891+
892+ forEach(row, function(e) {
893+ MochiKit.Signal.connect(e, 'ondblclick', e, select_row_edit);
894 });
895-}
896+};
897
898-var select_row_edit = function(e){
899- src = e.src();
900- src_record = getNodeAttribute(src, 'record');
901- target = e.target();
902- target_class = getNodeAttribute(target,'class');
903+var select_row_edit = function(e) {
904+ src = e.src();
905+ src_record = getNodeAttribute(src, 'record');
906+ target = e.target();
907+ target_class = getNodeAttribute(target, 'class');
908
909 var view_type = getElement('_terp_view_type').value;
910 var editable = getElement('_terp_editable').value;
911
912- if (!(target_class == 'checkbox grid-record-selector' || target_class == 'listImage')) {
913- if ((view_type == 'tree' && editable != 'True')) {
914- do_select(src_record);
915- }
916- if ((view_type == 'tree' && editable == 'True')){
917- editRecord(src_record);
918- }
919- }
920-}
921+ if (!(target_class == 'checkbox grid-record-selector' || target_class == 'listImage')) {
922+ if ((view_type == 'tree' && editable != 'True')) {
923+ do_select(src_record);
924+ }
925+ if ((view_type == 'tree' && editable == 'True')) {
926+ editRecord(src_record);
927+ }
928+ }
929+};
930
931-MochiKit.DOM.addLoadEvent(function(evt){
932- row_edit(evt);
933+MochiKit.DOM.addLoadEvent(function(evt) {
934+ row_edit(evt);
935 });
936-
937-// vim: ts=4 sts=4 sw=4 si et
938-
939
940=== removed file 'addons/openerp/static/javascript/menubar.js'
941--- addons/openerp/static/javascript/menubar.js 2010-03-30 12:48:36 +0000
942+++ addons/openerp/static/javascript/menubar.js 1970-01-01 00:00:00 +0000
943@@ -1,29 +0,0 @@
944-/**
945- * Allowable width for the left-hand menu (for the current application)
946- */
947-var MENU_WIDTH = 250;
948-/**
949- * Tries to fit the size of the #appFrame frame to better fit its current
950- * content.extend
951- * Has to be called from the document outside of the frame itself.
952- *
953- * Probably won't get it exactly right, you might want to call it
954- * several times
955- */
956-function adjustAppFrame() {
957- var frameHeight = jQuery("#appFrame").contents().find("body").height();
958- var frameWidth = jQuery("#appFrame").contents().width();
959-
960- jQuery("#menubar").width(MENU_WIDTH);
961- jQuery("#appFrame").height(Math.max(0, frameHeight));
962-
963- var menuWidth = jQuery("#menubar").height();
964- var windowWidth = jQuery(window).width();
965- var totalWidth = jQuery("#menubar").width() + frameWidth;
966- var rw = windowWidth - jQuery("#menubar").width();
967-
968- var newWidth = totalWidth > windowWidth ? frameWidth : rw - 16;
969-
970- jQuery("#appFrame").width(Math.max(0, newWidth));
971- jQuery("table#contents").height(Math.max(frameHeight, menuWidth));
972-}
973
974=== modified file 'addons/openerp/static/javascript/notebook/notebook.js'
975--- addons/openerp/static/javascript/notebook/notebook.js 2010-02-11 05:30:34 +0000
976+++ addons/openerp/static/javascript/notebook/notebook.js 2010-04-02 13:09:19 +0000
977@@ -27,6 +27,22 @@
978 //
979 ////////////////////////////////////////////////////////////////////////////////
980
981+/**
982+ *
983+ * @event show triggered when a tab of the notebook is displayed
984+ * @argument notebook the notebook instance this
985+ * event was triggered from
986+ * @argument tab the (DOM element) tab being showed
987+ * @event hide triggered when a tab of the notebook is hidden
988+ * @arguments 'see show'
989+ * @event activate triggered when a tab is set as the active tab
990+ * @arguments 'see show'
991+ * @event remove triggered when a tab is removed from the notebook
992+ * @arguments 'see show'
993+ * @event click triggered when the notebook's tab bar is clicked
994+ * @arguments 'see show'
995+ *
996+ */
997 var Notebook = function(element, options) {
998
999 var cls = arguments.callee;
1000
1001=== modified file 'addons/openerp/static/javascript/openerp/openerp.ui.textarea.js'
1002--- addons/openerp/static/javascript/openerp/openerp.ui.textarea.js 2010-01-12 05:05:16 +0000
1003+++ addons/openerp/static/javascript/openerp/openerp.ui.textarea.js 2010-04-02 13:09:19 +0000
1004@@ -32,55 +32,59 @@
1005 throw "openerp.ui is required by 'openerp.ui.textarea'.";
1006 }
1007
1008-openerp.ui.TextArea = function(ta){
1009+/**
1010+ * @event onresize triggered when the widget's grip is moved (to resize the text area)
1011+ * @parameter 'the TextArea instance'
1012+ */
1013+openerp.ui.TextArea = function(ta) {
1014 this.__init__(ta);
1015-}
1016+};
1017
1018 openerp.ui.TextArea.prototype = {
1019-
1020- __init__ : function(ta){
1021+
1022+ __init__ : function(ta) {
1023 this.textarea = openobject.dom.get(ta);
1024 this.gripper = DIV({'class' : 'grip'});
1025-
1026+
1027 this.ta = this.textarea.cloneNode(true);
1028-
1029- MochiKit.DOM.swapDOM(this.textarea, DIV({'class' : 'resizable-textarea'}, this.ta, this.gripper));
1030-
1031- this.textarea = openobject.dom.get(this.ta);
1032+
1033+ MochiKit.DOM.swapDOM(this.textarea,
1034+ DIV({'class' : 'resizable-textarea'},
1035+ this.ta, this.gripper)).textarea = this;
1036+
1037+ this.textarea = openobject.dom.get(this.ta);
1038 this.draggin = false;
1039-
1040+
1041 this.evtMouseDn = MochiKit.Signal.connect(this.gripper, 'onmousedown', this, "dragStart");
1042 },
1043-
1044- __delete__ : function(){
1045+
1046+ __delete__ : function() {
1047 MochiKit.Signal.disconnect(this.evtMouseDn);
1048 },
1049-
1050- dragStart : function(evt){
1051-
1052- if (!evt.mouse().button.left)
1053+
1054+ dragStart : function(evt) {
1055+ if (!evt.mouse().button.left) {
1056 return;
1057+ }
1058
1059 this.offset = openobject.dom.height(this.textarea) - evt.mouse().page.y;
1060-
1061+
1062 this.evtMouseMv = MochiKit.Signal.connect(document, 'onmousemove', this, "dragUpdate");
1063 this.evtMouseUp = MochiKit.Signal.connect(document, 'onmouseup', this, "dragStop");
1064 },
1065-
1066- dragUpdate : function(evt){
1067+
1068+ dragUpdate : function(evt) {
1069 var h = Math.max(32, this.offset + evt.mouse().page.y);
1070 this.textarea.style.height = h + 'px';
1071- evt.stop();
1072+ MochiKit.Signal.signal(this, 'onresize', this);
1073+ evt.stop();
1074 },
1075-
1076- dragStop : function(evt){
1077+
1078+ dragStop : function(evt) {
1079 //MochiKit.Signal.disconnect(this.evtMouseMv);
1080 //MochiKit.Signal.disconnect(this.evtMouseUp);
1081 MochiKit.Signal.disconnectAll(document, 'onmousemove', this, "dragUpdate");
1082 MochiKit.Signal.disconnectAll(document, 'onmouseup', this, "dragStop");
1083- evt.stop();
1084+ evt.stop();
1085 }
1086-}
1087-
1088-// vim: ts=4 sts=4 sw=4 si et
1089-
1090+};
1091
1092=== modified file 'addons/openerp/static/javascript/search.js'
1093--- addons/openerp/static/javascript/search.js 2010-04-02 06:44:11 +0000
1094+++ addons/openerp/static/javascript/search.js 2010-04-02 13:09:19 +0000
1095@@ -27,6 +27,7 @@
1096 //
1097 ////////////////////////////////////////////////////////////////////////////////
1098
1099+<<<<<<< TREE
1100 var add_filter_row = function() {
1101
1102 var filter_table = $('filter_table');
1103@@ -120,27 +121,133 @@
1104 $('qstring/0').value = '';
1105 $('qstring/0').style.background = '#FFFFFF';
1106 }
1107+=======
1108+/**
1109+ * gets the first section of the forward-slash-separated
1110+ * id attribute of the provided element, and returns it
1111+ *
1112+ * @param element the element whose id should be split
1113+ */
1114+function first_id_section(element) {
1115+ return element.id.split('/')[0];
1116+}
1117+/**
1118+ * @event onaddfilter triggered when adding a filter row
1119+ * @target #filter_table the element holding the filter rows
1120+ * @argument 'the newly added (or showed for first row?) filter row'
1121+ */
1122+function add_filter_row() {
1123+ var filter_table = $('filter_table');
1124+ var first_row = $('filter_row');
1125+
1126+ if (filter_table.style.display == 'none') {
1127+ filter_table.style.display = '';
1128+ } else if (first_row.style.display == 'none') {
1129+ first_row.style.display = ''
1130+ } else {
1131+ var old_tr = MochiKit.DOM.getFirstElementByTagAndClassName('tr', null, filter_table);
1132+ var old_qstring = MochiKit.DOM.getFirstElementByTagAndClassName('input', 'qstring', old_tr);
1133+ old_qstring.style.background = '#FFFFFF';
1134+
1135+ var new_tr = old_tr.cloneNode(true);
1136+
1137+ var filter_column = MochiKit.DOM.getFirstElementByTagAndClassName(
1138+ 'td', 'filter_column', new_tr);
1139+ var filter_fields = MochiKit.DOM.getFirstElementByTagAndClassName(
1140+ 'select', 'filter_fields', new_tr);
1141+ var expr = MochiKit.DOM.getFirstElementByTagAndClassName(
1142+ 'select', 'expr', new_tr);
1143+ var qstring = MochiKit.DOM.getFirstElementByTagAndClassName(
1144+ 'input', 'qstring', new_tr);
1145+ qstring.style.background = '#FFFFFF';
1146+ qstring.value = '';
1147+ var and_or = MochiKit.DOM.getFirstElementByTagAndClassName(
1148+ 'td', 'and_or', new_tr);
1149+ var select_andor;
1150+
1151+ if (new_tr.id.indexOf('/') != -1) {
1152+ var keys = new_tr.id.split('/');
1153+ var id = parseInt(keys[1], 10) + 1;
1154+ new_tr.id = keys[0] + '/' + id;
1155+
1156+ and_or.id = first_id_section(and_or) + '/' + id;
1157+
1158+ filter_column.id = first_id_section(filter_column) + '/' + id;
1159+ filter_fields.id = first_id_section(filter_fields) + '/' + id;
1160+ expr.id = first_id_section(expr) + '/' + id;
1161+
1162+ qstring.id = first_id_section(qstring) + '/' + id;
1163+ select_andor = MochiKit.DOM.getFirstElementByTagAndClassName(
1164+ 'select', 'select_andor', and_or);
1165+ select_andor.id = first_id_section(select_andor) + '/' + id;
1166+
1167+ insertSiblingNodesBefore(old_tr, new_tr);
1168+ } else {
1169+ var first_row_id = 1;
1170+ new_tr.id = new_tr.id + '/' + first_row_id;
1171+
1172+ and_or.id = and_or.id + '/' + first_row_id;
1173+ filter_column.id = filter_column.id + '/' + first_row_id;
1174+ filter_fields.id = filter_fields.id + '/' + first_row_id;
1175+ expr.id = expr.id + '/' + first_row_id;
1176+ qstring.id = qstring.id + '/' + first_row_id;
1177+
1178+ select_andor = document.createElement('select');
1179+ select_andor.id = 'select_andor/' + first_row_id;
1180+ select_andor.className = 'select_andor';
1181+
1182+ var options = map(function(x) {
1183+ return OPTION({'value': x}, x)
1184+ }, ['AND', 'OR']);
1185+
1186+ appendChildNodes(select_andor, options);
1187+ appendChildNodes(and_or, select_andor);
1188+ insertSiblingNodesBefore(old_tr, new_tr);
1189+ }
1190+ }
1191+ MochiKit.Signal.signal(filter_table, 'onaddfilter', new_tr || first_row);
1192+}
1193+
1194+/**
1195+ * @event onremovefilter triggered when removing a filter row
1196+ * @target #filter_table the element holding the filter rows
1197+ * @argument 'the removed (or hidden) filter row'
1198+ */
1199+function remove_row(id) {
1200+ var filter_table = $('filter_table');
1201+
1202+ var node = MochiKit.DOM.getFirstParentByTagAndClassName(id, 'tr', 'filter_row_class');
1203+
1204+ if (node.id.indexOf('/') != -1) {
1205+ removeElement(node);
1206+ } else {
1207+ node.style.display = 'none';
1208+ $('qstring').value = '';
1209+ $('qstring').style.background = '#FFFFFF';
1210+ }
1211+ MochiKit.Signal.signal(filter_table, 'onremovefilter', node);
1212+>>>>>>> MERGE-SOURCE
1213 }
1214 // Direct click on icon.
1215-var search_image_filter = function(src, id) {
1216- domain = getNodeAttribute(id, 'value');
1217- search_filter(src);
1218+function search_image_filter(src, id) {
1219+ domain = getNodeAttribute(id, 'value');
1220+ search_filter(src);
1221 }
1222
1223-var onKey_Event = function(evt) {
1224-
1225- dom = $('search_filter_data');
1226-
1227- var editors = [];
1228-
1229- editors = editors.concat(getElementsByTagAndClassName('input', null, dom));
1230+function onKey_Event(evt) {
1231+ var dom = $('search_filter_data');
1232+
1233+ var editors = [];
1234+
1235+ editors = editors.concat(getElementsByTagAndClassName('input', null, dom));
1236 editors = editors.concat(getElementsByTagAndClassName('select', null, dom));
1237 editors = editors.concat(getElementsByTagAndClassName('textarea', null, dom));
1238-
1239- var editors = filter(function(e){
1240+
1241+ var active_editors = filter(function(e) {
1242 return e.type != 'hidden' && !e.disabled
1243 }, editors);
1244
1245+<<<<<<< TREE
1246 forEach(editors, function(e){
1247 connect(e, 'onkeydown', self, onKeyDown_search);
1248 });
1249@@ -387,4 +494,292 @@
1250
1251 onKey_Event(evt);
1252 search_filter();
1253+=======
1254+ forEach(active_editors, function(e) {
1255+ MochiKit.Signal.connect(e, 'onkeydown', self, onKeyDown_search);
1256+ });
1257+}
1258+
1259+function onKeyDown_search(evt) {
1260+ if (evt.key().string == "KEY_ENTER") {
1261+ search_filter();
1262+ }
1263+}
1264+
1265+function search_filter(src, id) {
1266+ all_domains = {};
1267+ check_domain = 'None';
1268+ domains = {};
1269+ search_context = {};
1270+ var group_by_ctx = [];
1271+
1272+
1273+ domain = 'None';
1274+ if (src) {
1275+ src.checked = !src.checked;
1276+ id.className = src.checked ? 'active_filter' : 'inactive_filter';
1277+ }
1278+ var filter_table = $('filter_table');
1279+ datas = $$('[name]', 'search_filter_data');
1280+
1281+ forEach(datas, function(d) {
1282+ if (d.type != 'checkbox' && d.name && d.value && d.name.indexOf('_terp_') == -1 && d.name != 'filter_list') {
1283+ value = d.value;
1284+ if (getNodeAttribute(d, 'kind') == 'selection') {
1285+ value = parseInt(d.value);
1286+ if (getNodeAttribute(d, 'search_context')) {
1287+ search_context['context'] = getNodeAttribute(d, 'search_context');
1288+ search_context['value'] = value;
1289+ }
1290+ }
1291+ domains[d.name] = value;
1292+ }
1293+ });
1294+
1295+ domains = serializeJSON(domains);
1296+ all_domains['domains'] = domains;
1297+ all_domains['search_context'] = search_context;
1298+ selected_boxes = getElementsByTagAndClassName('input', 'grid-domain-selector');
1299+
1300+ all_boxes = [];
1301+
1302+ forEach(selected_boxes, function(box) {
1303+ if (box.id && box.checked && box.value != '[]') {
1304+ all_boxes = all_boxes.concat(box.value);
1305+ }
1306+ if (box.id && box.checked && getNodeAttribute(box, 'group_by_ctx').length > 0) {
1307+ group = getNodeAttribute(box, 'group_by_ctx');
1308+ group_by_ctx = group_by_ctx.concat(group);
1309+ }
1310+ });
1311+
1312+ openobject.dom.get('_terp_group_by_ctx').value = group_by_ctx;
1313+
1314+ checked_button = all_boxes.toString();
1315+
1316+ if (checked_button.length > 0) {
1317+ check_domain = checked_button.replace(/(]\,\[)/g, ', ');
1318+ }
1319+ else {
1320+ check_domain = 'None';
1321+ }
1322+
1323+ all_domains['check_domain'] = check_domain;
1324+
1325+ var selection_domain = $('filter_list').value;
1326+
1327+ if (selection_domain) {
1328+ all_domains['selection_domain'] = selection_domain;
1329+ }
1330+
1331+ if (filter_table.style.display != 'none') {
1332+ var custom_domains = [];
1333+ var params = {};
1334+ var record = {};
1335+
1336+ children = MochiKit.DOM.getElementsByTagAndClassName('tr', 'filter_row_class', filter_table);
1337+ forEach(children, function(ch) {
1338+
1339+ var ids = ch['id']; // row id...
1340+ if (ids && ids.indexOf('/') != -1) {
1341+ id = ids.split('/')[1];
1342+ var qid = 'qstring/' + id;
1343+ var fid = 'filter_fields/' + id;
1344+ var eid = 'expr/' + id;
1345+
1346+ if ($(qid) && $(qid).value) {
1347+ var rec = {};
1348+ rec[$(fid).value] = $(qid).value;
1349+ params['_terp_model'] = openobject.dom.get('_terp_model').value;
1350+ }
1351+ }
1352+
1353+ else {
1354+ var qid = 'qstring';
1355+ var fid = 'filter_fields';
1356+ var eid = 'expr';
1357+
1358+ var q_val = '';
1359+
1360+ if ($(qid) && $(qid).value) {
1361+ var rec = {};
1362+ rec[$(fid).value] = $(qid).value;
1363+ params['_terp_model'] = openobject.dom.get('_terp_model').value;
1364+ }
1365+ }
1366+ if (rec) {
1367+ record[ids] = rec;
1368+ }
1369+ });
1370+
1371+ record = serializeJSON(record);
1372+ params['record'] = record;
1373+
1374+ var search_req = openobject.http.postJSON('/search/get', params);
1375+
1376+ var custom_domain = [];
1377+ search_req.addCallback(function(obj) {
1378+ if (obj.error) {
1379+ forEach(children, function(child) {
1380+ var cids = child['id'];
1381+ if (cids && cids.indexOf('/') != -1) {
1382+ id = cids.split('/')[1];
1383+ var fid = 'filter_fields/' + id;
1384+ }
1385+ else {
1386+ var fid = 'filter_fields';
1387+ }
1388+ if ($(fid).value == obj.error_field) {
1389+ if (fid.indexOf('/') != -1) {
1390+ f = fid.split('/')[1];
1391+ $('qstring/' + f).style.background = '#FF6666';
1392+ }
1393+ else {
1394+ $('qstring').style.background = '#FF6666';
1395+ }
1396+ }
1397+ });
1398+ }
1399+ if (obj.frm) {
1400+ for (var i in obj.frm) {
1401+ var temp_domain = [];
1402+ var operator = 'None';
1403+
1404+ row_id = serializeJSON(i);
1405+
1406+ if (row_id && row_id.indexOf('/') != -1) {
1407+
1408+ id = row_id.split('/')[1];
1409+ id = parseInt(id);
1410+
1411+ var fid = 'filter_fields/' + id;
1412+ var eid = 'expr/' + id;
1413+ var select_andor = 'select_andor/' + id;
1414+ var type = obj.frm[i].type;
1415+
1416+ if ($(select_andor).value == 'AND') {
1417+ operator = '&';
1418+ } else {
1419+ operator = '|';
1420+ }
1421+ }
1422+ else {
1423+ var fid = 'filter_fields';
1424+ var eid = 'expr';
1425+ var type = obj.frm[i].type;
1426+ }
1427+
1428+ if (operator != 'None') {
1429+ temp_domain.push(operator);
1430+ }
1431+
1432+ var first_text = obj.frm[i].rec;
1433+ var expression = $(eid).value;
1434+ var right_text = obj.frm[i].rec_val;
1435+ if (expression == 'ilike' || expression == 'not ilike') {
1436+ if (type == 'integer' || type == 'float' || type == 'date' || type == 'datetime' || type == 'boolean') {
1437+ if (expression == 'ilike') {
1438+ expression = '=';
1439+ } else {
1440+ expression = '!=';
1441+ }
1442+ }
1443+ }
1444+ if ((expression == '<' || expression == '>') && (type != 'integer' || type != 'float' || type != 'date' || type != 'datetime' || type != 'boolean')) {
1445+ expression = '=';
1446+ }
1447+ if (expression == 'in' || expression == 'not in') {
1448+ right_text = right_text.split(',');
1449+ }
1450+
1451+ temp_domain.push(first_text);
1452+ temp_domain.push(expression);
1453+ temp_domain.push(right_text);
1454+
1455+ custom_domain.push(temp_domain);
1456+ }
1457+ }
1458+ custom_domain = serializeJSON(custom_domain);
1459+ all_domains = serializeJSON(all_domains);
1460+
1461+ final_search_domain(custom_domain, all_domains, group_by_ctx);
1462+ });
1463+ }
1464+ else {
1465+ custom_domain = [];
1466+ all_domains = serializeJSON(all_domains);
1467+ final_search_domain(custom_domain, all_domains, group_by_ctx);
1468+ }
1469+}
1470+
1471+function final_search_domain(custom_domain, all_domain, group_by_ctx) {
1472+ var req = openobject.http.postJSON('/search/eval_domain_filter', {
1473+ source: '_terp_list',
1474+ model: $('_terp_model').value,
1475+ custom_domain: custom_domain,
1476+ all_domains: all_domains,
1477+ group_by_ctx: group_by_ctx
1478+ });
1479+
1480+ req.addCallback(function(obj) {
1481+ if (obj.flag) {
1482+ var params = {'domain': obj.sf_dom,
1483+ 'model': openobject.dom.get('_terp_model').value,
1484+ 'flag': obj.flag};
1485+ if (group_by_ctx != '') {
1486+ params['group_by'] = group_by_ctx;
1487+ }
1488+ openobject.tools.openWindow(openobject.http.getURL('/search/save_filter', params), {width: 400, height: 250});
1489+ }
1490+ if (obj.action) { // For manage Filter
1491+ action = serializeJSON(obj.action);
1492+ window.location.href = openobject.http.getURL('/search/manage_filter', {action: action});
1493+ }
1494+ if (obj.domain) { // For direct search
1495+ var in_req = eval_domain_context_request({
1496+ source: '_terp_list',
1497+ domain: obj.domain,
1498+ context: obj.context
1499+ });
1500+
1501+ in_req.addCallback(function(in_obj) {
1502+ openobject.dom.get('_terp_search_domain').value = in_obj.domain;
1503+ openobject.dom.get('_terp_search_data').value = obj.search_data;
1504+ openobject.dom.get('_terp_context').value = in_obj.context;
1505+ if (getElement('_terp_list') != null) {
1506+ var lst = new ListView('_terp_list');
1507+ lst.reload();
1508+ }
1509+ });
1510+ }
1511+ });
1512+}
1513+
1514+/**
1515+ * @event groupby-toggle triggered when changing the display state of the groupby options
1516+ * @target #search_filter_data the element holding the filter rows
1517+ * @argument 'the action performed ("expand" or "collapse")
1518+ */
1519+function expand_group_option(id, event) {
1520+ var groupbyElement = getElement(id);
1521+ var action;
1522+ if (groupbyElement.style.display == '') {
1523+ groupbyElement.style.display = 'none';
1524+ event.target.className = 'group-expand';
1525+ action = 'collapse';
1526+ } else {
1527+ groupbyElement.style.display = '';
1528+ event.target.className = 'group-collapse';
1529+ action = 'expand';
1530+ }
1531+ MochiKit.Signal.signal(
1532+ $('search_filter_data'),
1533+ 'groupby-toggle',
1534+ action);
1535+}
1536+
1537+MochiKit.DOM.addLoadEvent(function(evt) {
1538+ onKey_Event(evt);
1539+ search_filter();
1540+>>>>>>> MERGE-SOURCE
1541 });
1542
1543=== modified file 'addons/openerp/static/javascript/treegrid.js'
1544--- addons/openerp/static/javascript/treegrid.js 2010-03-17 07:24:58 +0000
1545+++ addons/openerp/static/javascript/treegrid.js 2010-04-02 13:09:19 +0000
1546@@ -31,184 +31,203 @@
1547 var KEY_ARROW_UP = 38;
1548 var KEY_ARROW_DOWN = 40;
1549
1550-var TreeGrid = function(elem, options){
1551+/**
1552+ * @event treegrid-render triggered on treegrid rendering
1553+ * @target document
1554+ * @argument 'the treegrid instance being rendered'
1555+ *
1556+ * @event treenode-expand triggered when a sub-node is expanded
1557+ * @target document
1558+ * @argument 'the treenode being expanded'
1559+ *
1560+ * @event treenode-collapse triggered when a sub-node is collaped
1561+ * @target document
1562+ * @argument 'the treenode being collapsed'
1563+ */
1564+var TreeGrid = function(elem, options) {
1565 this.__init__(elem, options);
1566 };
1567
1568 TreeGrid.prototype = {
1569-
1570+
1571 __init__ : function(elem, options) {
1572-
1573 this.id = openobject.dom.get(elem).id;
1574-
1575+
1576 this.options = MochiKit.Base.update({
1577 'showheaders': true,
1578 'expandall' : false,
1579- 'onselect' : function(){},
1580- 'onbuttonclick' : function(){},
1581- 'onheaderclick' : function(){},
1582+ 'onselect' : function() {
1583+ },
1584+ 'onbuttonclick' : function() {
1585+ },
1586+ 'onheaderclick' : function() {
1587+ },
1588 'linktarget': null
1589 }, options || {});
1590-
1591+
1592 // a dummy root node
1593 this.rootNode = null;
1594-
1595+
1596 // selection info
1597 this.selection = [];
1598 this.selection_last = null;
1599-
1600+
1601 // ajax call counter
1602 this._ajax_counter = 0;
1603-
1604+
1605 // references to ajax url and params
1606 this.ajax_url = null;
1607 this.ajax_params = {};
1608+
1609+ // receive some events from the treenodes and redispatch to the document
1610+ MochiKit.Signal.connect(this, 'onNodeExpand', function (tree, node) {
1611+ MochiKit.Signal.signal(window.document, 'treenode-expand', node);
1612+ });
1613+ MochiKit.Signal.connect(this, 'onNodeCollapse', function (tree, node) {
1614+ MochiKit.Signal.signal(window.document, 'treenode-collapse', node);
1615+ });
1616 },
1617-
1618+
1619 setHeaders : function(headers/*, params */) {
1620-
1621 this.headers = headers;
1622-
1623- if (typeof(headers) == 'string'){
1624-
1625- var self = this;
1626- var req = openobject.http.postJSON(headers, arguments[1]);
1627-
1628- self._ajax_counter += 1;
1629-
1630- req.addCallback(function(obj){
1631- self.headers = obj.headers;
1632- });
1633-
1634- req.addBoth(function(){
1635- self._ajax_counter -= 1;
1636- });
1637-
1638+
1639+ if (typeof(headers) == 'string') {
1640+
1641+ var self = this;
1642+ var req = openobject.http.postJSON(headers, arguments[1]);
1643+
1644+ self._ajax_counter += 1;
1645+
1646+ req.addCallback(function(obj) {
1647+ self.headers = obj.headers;
1648+ });
1649+
1650+ req.addBoth(function() {
1651+ self._ajax_counter -= 1;
1652+ });
1653+
1654 }
1655 },
1656-
1657+
1658 setRecords : function(records/*, params */) {
1659-
1660 if (!this.headers) {
1661 return;
1662 }
1663-
1664+
1665 this.records = records;
1666-
1667- if (typeof(records) == 'string'){
1668-
1669+
1670+ if (typeof(records) == 'string') {
1671+
1672 this.ajax_url = records;
1673 this.ajax_params = arguments[1] || {};
1674-
1675+
1676 var self = this;
1677 var req = openobject.http.postJSON(this.ajax_url, this.ajax_params);
1678-
1679+
1680 var div = DIV({id: this.id}, _("Loading..."));
1681 MochiKit.DOM.swapDOM(this.id, div);
1682-
1683+
1684 self._ajax_counter += 1;
1685-
1686- req.addCallback(function(obj){
1687+
1688+ req.addCallback(function(obj) {
1689 self.records = obj.records;
1690 MochiKit.Signal.signal(self, 'onDataLoad', self, null);
1691 });
1692-
1693- req.addBoth(function(obj){
1694+
1695+ req.addBoth(function() {
1696 self._ajax_counter -= 1;
1697 });
1698-
1699+
1700 }
1701-
1702+
1703 },
1704-
1705- render : function(){
1706-
1707+
1708+ render : function() {
1709 // wait till ajax calls finish
1710 if (this._ajax_counter > 0) {
1711 return MochiKit.Async.callLater(0.01, MochiKit.Base.bind(this.render, this));
1712 }
1713-
1714+
1715 this.thead = MochiKit.DOM.THEAD({'class': 'tree-head'});
1716 this.tbody = MochiKit.DOM.TBODY({'class': 'tree-body'});
1717 this.table = MochiKit.DOM.TABLE({id: this.id, 'class': 'tree-grid'}, this.thead, this.tbody);
1718-
1719+
1720 if (this.options.showheaders) {
1721 this._makeHeader();
1722 }
1723-
1724+
1725 this._makeBody();
1726
1727 if (openobject.dom.get(this.id) != this.table) {
1728 MochiKit.DOM.swapDOM(this.id, this.table);
1729 }
1730+ MochiKit.Signal.signal(window.document, 'treegrid-render', this);
1731 },
1732-
1733+
1734 reload : function() {
1735 this.rootNode.__delete__();
1736 this.setRecords(this.ajax_url || this.records, this.ajax_params);
1737 this.render();
1738 },
1739-
1740+
1741 createNode : function(record) {
1742- return new TreeNode(this, record);
1743+ return new TreeNode(this, record);
1744 },
1745-
1746- _makeHeader : function(){
1747-
1748+
1749+ _makeHeader : function() {
1750 var tr = MochiKit.DOM.TR({'class':'header'});
1751-
1752- for(var i in this.headers){
1753-
1754+
1755+ for (var i in this.headers) {
1756+
1757 var header = this.headers[i];
1758 var th = MochiKit.DOM.TH(null, header.string);
1759-
1760+
1761 MochiKit.DOM.setNodeAttribute(th, 'title', header.help ? header.help : '');
1762 MochiKit.DOM.setNodeAttribute(th, 'class', header.type);
1763 MochiKit.DOM.setNodeAttribute(th, 'width', header.width);
1764 MochiKit.DOM.setNodeAttribute(th, 'align', header.align);
1765-
1766- if (this.options.onheaderclick){
1767- th.onclick = MochiKit.Base.bind(MochiKit.Base.partial(this._onHeaderClick, header), this);
1768- th.style.cursor = 'pointer';
1769+
1770+ if (this.options.onheaderclick) {
1771+ th.onclick = MochiKit.Base.bind(MochiKit.Base.partial(this._onHeaderClick, header), this);
1772+ th.style.cursor = 'pointer';
1773 }
1774-
1775+
1776 header.tree = this;
1777-
1778+
1779 MochiKit.DOM.appendChildNodes(tr, th);
1780 }
1781-
1782+
1783 MochiKit.DOM.appendChildNodes(this.thead, tr);
1784 },
1785-
1786+
1787 _makeBody : function() {
1788 this.rootNode = this.createNode({children: this.records});
1789 this.rootNode.expand(this.options.expandall);
1790 },
1791-
1792+
1793 _onHeaderClick : function(header) {
1794 var evt = arguments[1] || window.event;
1795 this.options.onheaderclick(new MochiKit.Signal.Event(evt.target || evt.srcElement, evt), header);
1796 },
1797-
1798+
1799 copy: function(elem, options, ids) {
1800-
1801 var tree = new TreeGrid(elem, options);
1802 MochiKit.Base.update(tree.options, this.options);
1803-
1804+
1805 var headers = MochiKit.Base.map(function(h) {
1806 return MochiKit.Base.clone(h);
1807 }, this.headers);
1808-
1809+
1810 tree.setHeaders(headers);
1811 tree.ajax_url = this.ajax_url;
1812 tree.ajax_params = MochiKit.Base.clone(this.ajax_params);
1813-
1814+
1815 if (ids) {
1816 tree.ajax_params.ids = ids;
1817 }
1818-
1819+
1820 tree.setRecords(tree.ajax_url, tree.ajax_params);
1821-
1822+
1823 return tree;
1824 }
1825 };
1826@@ -221,64 +240,64 @@
1827
1828 __init__ : function(tree, record) {
1829 this.tree = tree;
1830- this.record = record;
1831-
1832+ this.record = record;
1833+
1834 this.name = record['id'] || null;
1835-
1836+
1837 this.element = null; // the row (tr) element
1838 this.element_a = null; // the link element
1839 this.element_b = null; // the expand/collapse element
1840 this.element_i = null; // the image
1841-
1842+
1843 this.childNodes = [];
1844-
1845+
1846 this.parentNode = null;
1847-
1848+
1849 this.firstChild = null;
1850 this.lastChild = null;
1851 this.previousSibling = null;
1852 this.nextSibling = null;
1853-
1854+
1855 this.hasChildren = record.children ? record.children.length > 0 : false;
1856-
1857+
1858 this.expanded = false;
1859 },
1860-
1861+
1862 __delete__ : function() {
1863-
1864-
1865- while(this.childNodes.length > 0) {
1866+
1867+
1868+ while (this.childNodes.length > 0) {
1869 this.childNodes[0].__delete__();
1870 }
1871-
1872+
1873 if (!this.element) {
1874 return;
1875 }
1876-
1877+
1878 var pn = this.parentNode;
1879 var idx = MochiKit.Base.findIdentical(pn.childNodes, this);
1880-
1881- pn.childNodes.splice(idx,1);
1882-
1883+
1884+ pn.childNodes.splice(idx, 1);
1885+
1886 if (pn.firsChild == this) {
1887 pn.firstChild = pn.childNodes[0] || null;
1888 }
1889-
1890+
1891 if (pn.lastChild == this) {
1892- pn.lastChild = pn.childNodes[pn.childNodes.length-1] || null;
1893+ pn.lastChild = pn.childNodes[pn.childNodes.length - 1] || null;
1894 }
1895-
1896+
1897 if (this.previousSibling) {
1898 this.previousSibling.nextSibling = this.nextSibling;
1899 }
1900-
1901+
1902 if (this.nextSibling) {
1903 this.nextSibling.previousSibling = this.previousSibling;
1904 }
1905-
1906- this.tree.selection.splice(MochiKit.Base.findIdentical(this.tree.selection, this),1);
1907+
1908+ this.tree.selection.splice(MochiKit.Base.findIdentical(this.tree.selection, this), 1);
1909 this.tree.selection_last = this.selection_last == this ? null : this.selection_last;
1910-
1911+
1912 var table = this.tree.table;
1913 table.deleteRow(MochiKit.Base.findIdentical(table.rows, this.element));
1914
1915@@ -287,32 +306,32 @@
1916 MochiKit.Signal.disconnect(this.eventOnClick);
1917 MochiKit.Signal.disconnect(this.eventOnDblClick);
1918 }
1919-
1920+
1921 if (pn.childNodes.length == 0 && pn.element_b) {
1922 pn.collapse();
1923 pn.hasChildren = false;
1924 pn.element_b.className = 'indent';
1925 }
1926 },
1927-
1928- __repr__ : function(){
1929+
1930+ __repr__ : function() {
1931 return '<TreeNode ' + this.name + '>';
1932 },
1933-
1934+
1935 createDOM : function() {
1936 this.element = MochiKit.DOM.TR({'class' : 'row'});
1937 this.element.style.display = this.parentNode ? (this.parentNode.expanded ? "" : "none") : "";
1938-
1939+
1940 var record = this.record;
1941 var indent = this.getPath().length - 1;
1942
1943 var len = this.tree.headers.length;
1944- for (var i=0; i<len; ++i) {
1945+ for (var i = 0; i < len; ++i) {
1946 var header = this.tree.headers[i];
1947-
1948+
1949 var key = header.name;
1950 var value = this.record.items[key];
1951-
1952+
1953 var td = MochiKit.DOM.TD({'class': header.type || null, 'width' : header.width || null});
1954 if (i == 0) { // first column
1955
1956@@ -345,9 +364,9 @@
1957 MochiKit.Signal.connect(value, 'onclick', function (e) {
1958 MochiKit.Signal.signal(e.src().tree, "onaction", e.src());
1959 var frame = $('appFrame');
1960- if(frame.contentWindow) {
1961+ if (frame.contentWindow) {
1962 frame.contentWindow.location.replace(record.action);
1963- } else if(frame.contentDocument) {
1964+ } else if (frame.contentDocument) {
1965 frame.contentDocument.location.replace(record.action);
1966 } else {
1967 // just in case there's still a browser needing DOM0 frames
1968@@ -404,58 +423,58 @@
1969 MochiKit.DOM.appendChildNodes(td, value);
1970 MochiKit.DOM.appendChildNodes(this.element, td);
1971 }
1972-
1973+
1974 // register OnClick, OnDblClick event
1975 this.eventOnClick = MochiKit.Signal.connect(this.element, 'onclick', this, this.onSelect);
1976 this.eventOnDblClick = MochiKit.Signal.connect(this.element, 'ondblclick', this, this.toggle);
1977
1978 return this.element;
1979 },
1980-
1981+
1982 updateDOM : function(record) {
1983-
1984+
1985 MochiKit.Base.update(this.record, record || {});
1986-
1987- var record = this.record;
1988-
1989- for (var i in this.tree.headers){
1990-
1991+
1992+ var current_record = this.record;
1993+
1994+ for (var i in this.tree.headers) {
1995+
1996 var header = this.tree.headers[i];
1997-
1998+
1999 var key = header.name;
2000- var value = record.items[key];
2001-
2002+ var value = current_record.items[key];
2003+
2004 var td = this.element.cells[i];
2005-
2006+
2007 if (i == 0) { // first column
2008-
2009- if (record.icon && this.element_i) {
2010- this.element_i.src = record.icon;
2011+
2012+ if (current_record.icon && this.element_i) {
2013+ this.element_i.src = current_record.icon;
2014 }
2015-
2016+
2017 this.element_a.innerHTML = MochiKit.DOM.escapeHTML(value);
2018-
2019- if (record.action) {
2020- MochiKit.DOM.setNodeAttribute(this.element_a, 'href', openobject.http.getURL(record.action));
2021- }
2022-
2023- if (record.target) {
2024- MochiKit.DOM.setNodeAttribute(this.element_a, 'target', openobject.http.getURL(record.target));
2025- }
2026-
2027- if(record.required) {
2028+
2029+ if (current_record.action) {
2030+ MochiKit.DOM.setNodeAttribute(this.element_a, 'href', openobject.http.getURL(current_record.action));
2031+ }
2032+
2033+ if (current_record.target) {
2034+ MochiKit.DOM.setNodeAttribute(this.element_a, 'target', openobject.http.getURL(current_record.target));
2035+ }
2036+
2037+ if (current_record.required) {
2038 MochiKit.DOM.setNodeAttribute(this.element_a, 'class', 'requiredfield');
2039 }
2040
2041 }
2042-
2043+
2044 if (i > 0) {
2045 switch (header.type) {
2046 case 'url':
2047 case 'email':
2048 var link = openobject.dom.select('a', td)[0];
2049 MochiKit.DOM.setNodeAttribute(link, 'href', value);
2050- MochiKit.DOM.setNodeAttribute(link, 'target', record.target || '_blank');
2051+ MochiKit.DOM.setNodeAttribute(link, 'target', current_record.target || '_blank');
2052
2053 link.innerHTML = MochiKit.DOM.escapeHTML(value);
2054 break;
2055@@ -472,22 +491,22 @@
2056 }
2057 }
2058 }
2059-
2060+
2061 return this.element;
2062- },
2063+ },
2064
2065 onKeyDown : function(evt) {
2066 var visible_nodes;
2067- switch (evt.event().keyCode) {
2068+ switch (evt.event().keyCode) {
2069 case KEY_ARROW_LEFT:
2070 if (this.expanded) {
2071 this.collapse();
2072- } else if (this.parentNode.element){
2073+ } else if (this.parentNode.element) {
2074 this.parentNode.onSelect(evt);
2075 }
2076 return evt.stop();
2077-
2078- case KEY_ARROW_RIGHT:
2079+
2080+ case KEY_ARROW_RIGHT:
2081 if (!this.expanded) {
2082 this.expand();
2083 } else if (this.firstChild) {
2084@@ -496,7 +515,7 @@
2085 return evt.stop();
2086
2087 case KEY_ARROW_UP:
2088- visible_nodes = MochiKit.Base.filter(function(node){
2089+ visible_nodes = MochiKit.Base.filter(function(node) {
2090 return node.element && "none" != node.element.style.display;
2091 }, this.tree.rootNode.getAllChildren());
2092
2093@@ -507,201 +526,202 @@
2094 }
2095
2096 return evt.stop();
2097-
2098+
2099 case KEY_ARROW_DOWN:
2100- visible_nodes = MochiKit.Base.filter(function(node){
2101+ visible_nodes = MochiKit.Base.filter(function(node) {
2102 return node.element && "none" != node.element.style.display;
2103 }, this.tree.rootNode.getAllChildren());
2104-
2105- visible_nodes = visible_nodes.slice(MochiKit.Base.findIdentical(visible_nodes, this)+1);
2106+
2107+ visible_nodes = visible_nodes.slice(MochiKit.Base.findIdentical(visible_nodes, this) + 1);
2108
2109 if (visible_nodes.length > 0) {
2110 visible_nodes[0].onSelect(evt);
2111 }
2112-
2113+
2114 return evt.stop();
2115-
2116+
2117 default:
2118 return;
2119 }
2120-
2121+
2122 },
2123-
2124+
2125 onSelect : function(evt) {
2126
2127 if (this.tree._ajax_counter > 0) {
2128 return;
2129 }
2130-
2131+
2132 var trg = evt ? evt.target() : this.element;
2133-
2134- if (MochiKit.Base.findValue(['collapse', 'expand', 'loading'], trg.className) > -1){
2135+
2136+ if (MochiKit.Base.findValue(['collapse', 'expand', 'loading'], trg.className) > -1) {
2137 return;
2138 }
2139-
2140+
2141 var tree = this.tree;
2142- var src = this.element;
2143-
2144+
2145 var ctr = evt ? evt.modifier().ctrl : null;
2146 var sft = evt ? evt.modifier().shift : null;
2147-
2148+
2149 if (this.element_a) {
2150 this.element_a.focus();
2151 }
2152-
2153- forEach(tree.selection, function(node){
2154+
2155+ forEach(tree.selection, function(node) {
2156 MochiKit.DOM.removeElementClass(node.element, "selected");
2157 });
2158-
2159+
2160 if (ctr) {
2161- if (MochiKit.Base.findIdentical(tree.selection, this) == -1){
2162+ if (MochiKit.Base.findIdentical(tree.selection, this) == -1) {
2163 tree.selection.push(this);
2164 } else {
2165 tree.selection.splice(MochiKit.Base.findIdentical(tree.selection, this), 1);
2166 }
2167 } else if (sft) {
2168-
2169+
2170 var nodes = tree.rootNode.getAllChildren();
2171- nodes = MochiKit.Base.filter(function(node){
2172+ nodes = MochiKit.Base.filter(function(node) {
2173 return node.element.style.display != 'none';
2174 }, nodes);
2175-
2176+
2177 var last = tree.selection_last;
2178 last = last ? last : this;
2179-
2180+
2181 var begin = MochiKit.Base.findIdentical(nodes, this);
2182 var end = MochiKit.Base.findIdentical(nodes, last);
2183-
2184- tree.selection = begin > end ? nodes.slice(end, begin+1) : nodes.slice(begin, end+1);
2185-
2186+
2187+ tree.selection = begin > end ? nodes.slice(end, begin + 1) : nodes.slice(begin, end + 1);
2188+
2189 } else {
2190 tree.selection = [this];
2191 }
2192-
2193- if (!sft){
2194- tree.selection_last = tree.selection[tree.selection.length-1];
2195+
2196+ if (!sft) {
2197+ tree.selection_last = tree.selection[tree.selection.length - 1];
2198 }
2199-
2200- forEach(tree.selection, function(node){
2201+
2202+ forEach(tree.selection, function(node) {
2203 MochiKit.DOM.addElementClass(node.element, "selected");
2204 });
2205-
2206+
2207 if (evt && tree.options.onselect) {
2208 tree.options.onselect(evt, this);
2209 }
2210
2211 MochiKit.Signal.signal(self.tree, 'onNodeSelect', evt, this);
2212 },
2213-
2214+
2215 onButtonClick : function() {
2216 if (this.tree.options.onbuttonclick) {
2217 var evt = arguments[0] || window.event;
2218 this.tree.options.onbuttonclick(new MochiKit.Signal.Event(evt.target || evt.srcElement, evt), this);
2219- }
2220+ }
2221 },
2222
2223 getAllChildren : function() {
2224-
2225+
2226 var result = [];
2227-
2228- forEach(this.childNodes, function(n){
2229+
2230+ forEach(this.childNodes, function(n) {
2231 result = result.concat(n);
2232 result = result.concat(n.getAllChildren());
2233 });
2234-
2235+
2236 return result;
2237 },
2238-
2239+
2240 toggle : function() {
2241-
2242+
2243 if (this._ajax_counter) {
2244 return false;
2245 }
2246
2247- if (this.expanded) {
2248+ if (this.expanded) {
2249 this.collapse();
2250 } else {
2251-
2252+
2253 this.expand();
2254 }
2255
2256 return true;
2257 },
2258-
2259+
2260 _loadChildNodes : function(/* optional */expandall) {
2261-
2262- if (this._ajax_counter > 0)
2263- return;
2264-
2265+ if (this._ajax_counter > 0) {
2266+ return;
2267+ }
2268+
2269 var self = this;
2270-
2271+
2272 function _makeChildNodes(records) {
2273-
2274- MochiKit.Iter.forEach(records, function(record){
2275+
2276+ MochiKit.Iter.forEach(records, function(record) {
2277 self.appendChild(self.tree.createNode(record));
2278 });
2279-
2280- if (!expandall) { return; }
2281-
2282- forEach(self.childNodes, function(child){
2283+
2284+ if (!expandall) {
2285+ return;
2286+ }
2287+
2288+ forEach(self.childNodes, function(child) {
2289 child.expand(expandall);
2290 });
2291 }
2292-
2293+
2294 if (!this.record.children) {
2295 return;
2296 }
2297-
2298+
2299 if (this.record.children.length > 0 && !this.record.children[0].id) {
2300-
2301+
2302 var params = {};
2303 MochiKit.Base.update(params, this.tree.ajax_params || {});
2304 MochiKit.Base.update(params, this.record.params || {});
2305-
2306+
2307 params['ids'] = this.record.children.join(',');
2308
2309 var req = openobject.http.postJSON(this.tree.ajax_url, params);
2310 self.tree._ajax_counter += 1;
2311-
2312+
2313 this.setState('loading');
2314-
2315- req.addCallback(function(obj){
2316+
2317+ req.addCallback(function(obj) {
2318 _makeChildNodes(obj.records);
2319 MochiKit.Signal.signal(self.tree, 'onDataLoad', self.tree, self);
2320 MochiKit.Signal.signal(self.tree, 'onNodeExpand', self.tree, self);
2321 });
2322-
2323- req.addBoth(function(obj){
2324+
2325+ req.addBoth(function(obj) {
2326 self.tree._ajax_counter -= 1;
2327 self.setState('collapse');
2328 });
2329-
2330+
2331 } else {
2332 _makeChildNodes(this.record.children);
2333 MochiKit.Signal.signal(this.tree, 'onNodeExpand', this.tree, this);
2334 }
2335-
2336+
2337 },
2338-
2339+
2340 expand : function(/* optional */all) {
2341-
2342+
2343 if (!this.hasChildren) {
2344 return;
2345 }
2346-
2347+
2348 all = all || false;
2349-
2350+
2351 this.setState('collapse');
2352 this.expanded = true;
2353-
2354+
2355 if (this.childNodes.length == 0) {
2356- return this._loadChildNodes(all);
2357+ return this._loadChildNodes(all);
2358 }
2359-
2360+
2361 forEach(this.childNodes, function(node) {
2362-
2363+
2364 node.element.style.display = "";
2365-
2366+
2367 if (all) {
2368 node.expand(all);
2369 }
2370@@ -709,9 +729,9 @@
2371
2372 MochiKit.Signal.signal(this.tree, 'onNodeExpand', this.tree, this);
2373 },
2374-
2375+
2376 collapse : function() {
2377-
2378+
2379 if (!this.hasChildren) {
2380 return;
2381 }
2382@@ -720,40 +740,41 @@
2383 node.element.style.display = "none";
2384 node.collapse();
2385 });
2386-
2387+
2388 this.setState('expand');
2389 this.expanded = false;
2390
2391 MochiKit.Signal.signal(this.tree, 'onNodeCollapse', this.tree, this);
2392 },
2393-
2394+
2395 setState : function(state/* can be 'expand', 'collapse', 'loading' */) {
2396-
2397+
2398 if (!(this.hasChildren && this.element)) {
2399 return;
2400 }
2401
2402- var span = this.element.getElementsByTagName('span'); span = span[span.length-1];
2403+ var span = this.element.getElementsByTagName('span');
2404+ span = span[span.length - 1];
2405 MochiKit.DOM.setNodeAttribute(span, 'class', state);
2406 },
2407-
2408+
2409 getPath : function() {
2410-
2411+
2412 // check for dummyNode
2413 if (!this.record.items) {
2414 return [];
2415 }
2416-
2417+
2418 var path = this.parentNode ? this.parentNode.getPath() : [];
2419 path.push(this);
2420-
2421+
2422 return path;
2423 },
2424-
2425+
2426 appendChild : function(newChild) {
2427 return this.insertBefore(newChild);
2428 },
2429-
2430+
2431 insertBefore : function(newChild, refChild) {
2432
2433 if (!this.expanded && this.hasChildren && this.childNodes.length == 0) {
2434@@ -816,7 +837,7 @@
2435
2436 return newChild;
2437 },
2438-
2439+
2440 removeChild : function(refChild) {
2441 refChild.__delete__();
2442 }
2443
2444=== modified file 'openobject/static/javascript/openobject/openobject.base.js'
2445--- openobject/static/javascript/openobject/openobject.base.js 2009-10-14 11:38:53 +0000
2446+++ openobject/static/javascript/openobject/openobject.base.js 2010-04-02 13:09:19 +0000
2447@@ -31,67 +31,66 @@
2448 throw "MochiKit is required.";
2449 }
2450
2451+var openobject;
2452 if (typeof(openobject) == "undefined") {
2453- window.openobject = openobject = {};
2454+ openobject = {};
2455+ window.openobject = openobject;
2456 }
2457
2458 openobject.base = {
2459-
2460 filter: function(items, callback, instance) {
2461 if (instance) {
2462 callback = MochiKit.Base.bind(callback, instance);
2463 }
2464 return MochiKit.Base.filter(callback, items);
2465 },
2466-
2467+
2468 map: function(items, callback, instance) {
2469 if (instance) {
2470 callback = MochiKit.Base.bind(callback, instance);
2471 }
2472 return MochiKit.Base.map(callback, items);
2473 },
2474-
2475+
2476 each: function(items, callback, instance) {
2477 return MochiKit.Iter.forEach(items, callback, instance);
2478 },
2479-
2480+
2481 find: function(items, value, start, end) {
2482 return MochiKit.Base.findIdentical(items, value, start, end);
2483 }
2484-
2485-}
2486+};
2487
2488 // browser information
2489 openobject.browser = {
2490-
2491 // Internet Explorer
2492 isIE: /msie/.test(navigator.userAgent.toLowerCase()),
2493-
2494+
2495 // Internet Explorer 6
2496 isIE6: /msie 6/.test(navigator.userAgent.toLowerCase()),
2497-
2498+
2499 // Internet Explorer 7
2500 isIE7: /msie 7/.test(navigator.userAgent.toLowerCase()),
2501-
2502+
2503 // Gecko(Mozilla) derived
2504 isGecko: /gecko\//.test(navigator.userAgent.toLowerCase()),
2505-
2506+
2507 isGecko18: /rv:1.9.*gecko\//.test(navigator.userAgent.toLowerCase()),
2508-
2509+
2510 isGecko19: /rv:1.9.*gecko\//.test(navigator.userAgent.toLowerCase()),
2511-
2512+
2513 // Apple WebKit derived
2514 isWebKit: /webkit/.test(navigator.userAgent.toLowerCase()),
2515
2516 // Opera
2517 isOpera: /opera/.test(navigator.userAgent.toLowerCase())
2518-}
2519-
2520-window.browser = openobject.browser
2521-
2522-// hack to prevent cross-domain secutiry errors, if window is opened
2523+};
2524+
2525+window.browser = openobject.browser;
2526+
2527+// hack to prevent cross-domain security errors, if window is opened
2528 // from different domain.
2529-MochiKit.DOM.addLoadEvent(function(evt){
2530+MochiKit.DOM.addLoadEvent(function() {
2531 try {
2532 window.opener.document.domain;
2533 } catch (e) {
2534@@ -99,6 +98,89 @@
2535 }
2536 });
2537
2538-
2539-// vim: ts=4 sts=4 sw=4 si et
2540-
2541+var MENU_WIDTH = 250;
2542+/**
2543+ * Tries to fit the size of the #appFrame frame to better fit its current
2544+ * content.extend
2545+ * Has to be called from the document outside of the frame itself.
2546+ *
2547+ * Probably won't get it exactly right, you might want to call it
2548+ * several times
2549+ */
2550+function adjustAppFrame() {
2551+ var frameHeight = jQuery("#appFrame").contents().find("body").height();
2552+ var frameWidth = jQuery("#appFrame").contents().width();
2553+
2554+ jQuery("#menubar").width(MENU_WIDTH);
2555+ jQuery("#appFrame").height(Math.max(0, frameHeight));
2556+
2557+ var menuWidth = jQuery("#menubar").height();
2558+ var windowWidth = jQuery(window).width();
2559+ var totalWidth = jQuery("#menubar").width() + frameWidth;
2560+ var rw = windowWidth - jQuery("#menubar").width();
2561+
2562+ var newWidth = totalWidth > windowWidth ? frameWidth : rw - 16;
2563+
2564+ jQuery("#appFrame").width(Math.max(0, newWidth));
2565+ jQuery("table#contents").height(Math.max(frameHeight, menuWidth));
2566+}
2567+function adjust(count) {
2568+ if (!count) {
2569+ count = 0;
2570+ }
2571+ if (count < 3) {
2572+ try {
2573+ adjustAppFrame();
2574+ } catch (e) {
2575+ // don't do anything when adjustment blows up.
2576+ }
2577+ setTimeout(adjust, 10, count + 1);
2578+ }
2579+}
2580+if (window !== window.parent) {
2581+ MochiKit.DOM.addLoadEvent(function () {
2582+ // Gecko blows up if we try to directly call window.parent.adjust()
2583+ // and cross-frame events don't seem to work either
2584+ // so use intermediate function.
2585+ var do_adjust = function () {
2586+ window.parent.adjust();
2587+ };
2588+ setTimeout(do_adjust, 10);
2589+ // bind on all modifying events of notebooks
2590+ forEach($$('.notebook'), function (notebook_element) {
2591+ forEach(['remove', 'show', 'hide', 'activate', 'click'], function (event) {
2592+ MochiKit.Signal.connect(notebook_element.notebook,
2593+ event, do_adjust);
2594+ });
2595+ });
2596+ // bind to resize event of text area
2597+ forEach($$('.resizable-textarea'), function (textarea_element) {
2598+ MochiKit.Signal.connect(textarea_element.textarea, 'onresize', do_adjust);
2599+ });
2600+ // bind to alterations of the list views
2601+ forEach($$('.gridview'), function (listview_element) {
2602+ var name = listview_element.getAttribute('id');
2603+ MochiKit.Signal.connect(ListView(name), 'onreload', do_adjust);
2604+ });
2605+ // bind to addition and removal of filter rows in search widget
2606+ var filter_table = $('filter_table');
2607+ if (filter_table) {
2608+ MochiKit.Signal.connect(filter_table, 'onaddfilter',
2609+ do_adjust);
2610+ MochiKit.Signal.connect(filter_table, 'onremovefilter',
2611+ do_adjust);
2612+ }
2613+ // bind to change of the groupby display state in search widget
2614+ var search_filter = $('search_filter_data');
2615+ if(search_filter) {
2616+ MochiKit.Signal.connect(search_filter, 'groupby-toggle',
2617+ do_adjust);
2618+ }
2619+ // bind to changes to treegrids and treenodes
2620+ MochiKit.Signal.connect(window.document, 'treegrid-render', do_adjust);
2621+ MochiKit.Signal.connect(window.document, 'treenode-expand', do_adjust);
2622+ MochiKit.Signal.connect(window.document, 'treenode-collapse', do_adjust);
2623+ // bind to "onchange" attributes on view/form fields, maybe
2624+ MochiKit.Signal.connect(window.document, 'onfieldchange', do_adjust);
2625+ });
2626+}

Subscribers

People subscribed via source and target branches