[IMP]reduce code and implement for field position.
[odoo/odoo.git] / addons / web / static / src / js / view_editor.js
1 openerp.web.view_editor = function(openerp) {
2 var QWeb = openerp.web.qweb;
3 openerp.web.ViewEditor =   openerp.web.Widget.extend({
4     init: function(parent, element_id, dataset, view, options) {
5         this._super(parent);
6         this.element_id = element_id
7         this.parent = parent
8         this.dataset = dataset;
9         this.model = dataset.model;
10         this.xml_id = 0;
11     },
12
13     start: function() {
14         this.View_editor();
15     },
16
17     View_editor : function(){
18     var self = this;
19     var action = {
20         name:'ViewEditor',
21         context:this.session.user_context,
22         domain: [["model", "=", this.dataset.model]],
23         res_model : 'ir.ui.view',
24         views : [[false, 'list']],
25         type: 'ir.actions.act_window',
26         target: "current",
27         limit : 80,
28         auto_search : true,
29         flags: {
30             sidebar: false,
31             views_switcher: false,
32             action_buttons:false,
33             search_view:false,
34             pager:false,
35             radio:true 
36         },
37     };
38     var action_manager = new openerp.web.ActionManager(this);
39     this.dialog = new openerp.web.Dialog(this,{
40         modal: true,
41         title: 'ViewEditor',
42         width: 750,
43         height: 500,
44         buttons: {
45         "Create": function(){
46             //to do
47         },
48         "Edit": function(){
49             self.xml_id = 0 ;
50             self.get_data();
51         },
52         "Close": function(){
53             $(this).dialog('destroy');
54         }
55     },
56     });
57     this.dialog.start();
58     this.dialog.open();
59     action_manager.appendTo(this.dialog);
60     action_manager.do_action(action);
61     },
62
63     check_attr: function(xml ,tag,level) {
64         var obj = new Object();
65         obj.child_id = [];
66         obj.id = this.xml_id++;
67         obj.level = level+1;
68         var render_name = "<" + tag;
69         $(xml).each(function() {
70             _.each(this.attributes, function(attrs){
71             if (tag != 'button') {
72                 if (attrs.nodeName == "string" || attrs.nodeName == "name" || attrs.nodeName == "index") {
73                 render_name += ' ' +attrs.nodeName+'='+'"'+attrs.nodeValue+'"';}
74             } else {
75                 if (attrs.nodeName == "name") {
76                 render_name += ' ' +attrs.nodeName+'='+'"'+attrs.nodeValue+'"';}
77             }
78         });
79         render_name+= ">";
80         });
81         obj.name = render_name;
82         return obj;
83     },
84
85     save_object: function(val, parent_list, child_obj_list){
86         var self = this;
87         var check_id = parent_list[0];
88         var p_list = parent_list.slice(1);
89         if (val.child_id.length != 0) {
90             $.each(val.child_id, function(key, val) {
91                 if (val.id == check_id) {
92                     if (p_list.length!=0) {
93                         self.save_object(val, p_list, child_obj_list);
94                     } else {
95                         val.child_id = child_obj_list;
96                     return;
97                     }
98                 }
99             });
100         }else{
101             val.child_id = child_obj_list;
102         }
103     },
104
105     children_function: function(xml, root, parent_list, parent_id, main_object){
106         var self = this;
107         var child_obj_list = [];
108         var children_list = $(xml).filter(root).children();
109         var parents = $(children_list[0]).parents().get();
110             _.each(children_list, function(child_node){
111             var string = self.check_attr(child_node,child_node.tagName.toLowerCase(),parents.length);
112             child_obj_list.push(string);
113         });
114         if (children_list.length != 0) {
115             var parents = $(children_list[0]).parents().get();
116             if (parents.length <= parent_list.length) {
117                 parent_list.splice(parents.length-1);
118             }
119             parent_list.push(parent_id);
120             $.each(main_object, function(key, val) {
121                 self.save_object(val, parent_list.slice(1), child_obj_list);
122             });
123         }
124         for (var i=0;i<children_list.length;i++) {
125             self.children_function
126             (children_list[i], children_list[i].tagName.toLowerCase(),
127                 parent_list, child_obj_list[i].id, main_object);
128         }
129         return main_object;
130     },
131
132     parse_xml: function(arch,view_id) {
133         var self = this;
134         var root = $(arch).filter(":first")[0];
135         var tag = root.tagName.toLowerCase();
136         var obj = new Object();
137         obj.child_id = [];
138         obj.id = this.xml_id++;
139         obj.level = 0;
140         obj.name = "<view view_id='"+view_id+"'>"
141         var root_object = self.check_attr(root,tag,0);
142         f_obj = self.children_function(arch, tag, [], this.xml_id-1, [root_object], [])        
143         obj.child_id.push(f_obj[0]);
144         f_obj.pop();    
145         f_obj.push(obj);
146         return f_obj;
147     },
148
149     get_data: function() {
150         var self = this;
151         var view_id =(($("input[name='radiogroup']:checked").parent()).parent()).attr('data-id');
152         var ve_dataset = new openerp.web.DataSet(this,'ir.ui.view');       
153         ve_dataset.read_ids([parseInt(view_id)], ['arch'], function (arch) {
154             one_object = self.parse_xml(arch[0].arch,view_id);
155             one_object.arch = arch[0].arch; 
156             dataset = new openerp.web.DataSetSearch(self, 'ir.ui.view', null, null);
157             dataset.read_slice([],{domain : [['inherit_id','=',parseInt(view_id)]]},function (result) {
158                 _.each(result,function(res){
159                     self.inherit_view(one_object,res);
160                 });
161                 return self.edit_view(one_object);
162             });
163         });
164     },
165
166     inherit_view: function(one_object, result){
167         var self = this;
168         var root = $(result.arch).filter('*');
169         var xml_list = [];
170         var xpath_object ;
171         if (root[0].tagName.toLowerCase() == "data") {
172             xml_list = $(root[0]).children();
173         } else {
174             xml_list.push(root[0]);
175         }
176         _.each(xml_list , function(xml){
177             var parent_id;
178             var check_list = [];
179             var position = $(xml).attr('position');
180             if (xml.tagName.toLowerCase() == "xpath") {
181                 var part_expr = _.without($(xml).attr('expr').split("/"),"");;
182                 xpath_object = self.parse_xml(xml,result.id); 
183                 if (part_expr[part_expr.length-1].search("@")!=-1) {
184                     check_list = $.trim(part_expr[part_expr.length-1].replace(/[^a-zA-Z 0-9 _]+/g,' ')).split(" ");
185                     
186                 }else{
187                     //search full path...
188                 }
189             } else {
190                 var xml_child = $(xml).children();
191                 check_list.push(xml.tagName.toLowerCase());
192                     if ($(root[0]).attr('name')){
193                         check_list.push($(root[0]).attr('name'));
194                         check_list.push("name");
195                     }
196                 xpath_object = self.parse_xml(xml,result.id);
197             }
198             $.each(function(){
199             });
200             self.search_object(val,check_list,[],position,xpath_object['main_object'],[]);
201         });
202     },
203     search_object: function(val ,list ,p_list ,position, xpath_object){
204         var self = this;
205         var main_list = $.trim(val.name.replace(/[^a-zA-Z 0-9 _]+/g,' ')).split(" ");
206         var insert = _.intersection(main_list,list);
207         var check = _.indexOf(p_list.child_id,xpath_object[0]);
208         if(check == -1){
209             if(insert.length == list.length){
210                 var level = val.level;
211                 $.each(xpath_object, function(key, val) {
212                     self.increase_level(val, level)
213                 });   
214                 var index = _.indexOf(p_list.child_id,val);
215                 switch (position)
216                 {
217                     case "before":
218                         if (index != 0) { index--; }
219                         p_list.child_id.splice(index,0,xpath_object[0]);
220                         break;
221                     case "after":
222                          index++;
223                          p_list.child_id.splice(index,0,xpath_object[0]);
224                         break;
225                     case "inside":
226                         val.child_id.push(xpath_object[0]);
227                         break;
228                     case "replace":
229                         break;
230                 }
231                 
232             }else{
233                 if ( val.child_id.length != 0) { p_list = val; }
234                 $.each(val.child_id, function(key, val) {
235                    self.search_object(val, list, p_list, position, xpath_object);
236                 });
237             }
238         }
239         return return_list;
240     },
241
242     increase_level :function(val, level){
243         var self = this;
244         val.level = level; 
245         $.each(val.child_id, function(key, val) {
246             self.increase_level(val,level+1);
247         });
248     },
249
250     edit_view : function(one_object){
251         var self = this;
252         this.dialog = new openerp.web.Dialog(this,{
253             modal: true,
254             title: 'Edit Xml',
255             width: 750,
256             height: 500,
257             buttons: {
258                 "Inherited View": function(){
259                     //todo
260                 },
261                 "Preview": function(){
262                     //todo
263                 },
264                 "Close": function(){
265                     $(this).dialog('destroy');
266                 }
267             }
268         });
269     this.dialog.start().open();
270     this.dialog.$element.html(QWeb.render('view_editor', {
271        'data': one_object,
272     }));
273
274     $("tr[id^='viewedit-']").click(function() {
275         $("tr[id^='viewedit-']").removeClass('ui-selected');
276         $(this).addClass('ui-selected');
277     });
278
279     $("img[id^='parentimg-']").click(function() {
280         if ($(this).attr('src') == '/web/static/src/img/collapse.gif'){
281             $(this).attr('src', '/web/static/src/img/expand.gif');
282             self.on_expand(this);
283         }else{
284             $(this).attr('src', '/web/static/src/img/collapse.gif');
285             var id = this.id.split('-')[1];
286             self.on_collapse(this,one_object['parent_child_id'],one_object['main_object']);
287         }
288     });
289     $("img[id^='side-']").click(function() {
290         var side = $(this).closest("tr[id^='viewedit-']")
291         var id_tr = (side.attr('id')).split('-')[1];
292         var img = side.find("img[id='parentimg-"+id_tr+"']").attr('src'); ;
293         var level = side.attr('level');
294         var list_shift =[];
295         var last_tr;
296         var cur_tr = side;
297         list_shift.push(side);
298         var next_tr;
299         switch (this.id)
300         {
301             case "side-add":
302                 break;
303             case "side-remove":
304                 break;
305             case "side-edit":
306                 break;
307            case "side-up":
308                 while(1){
309                     var prev_tr = cur_tr.prev();
310                     if(level >= prev_tr.attr('level') || prev_tr.length==0){
311                        last_tr = prev_tr;
312                        break;
313                     }
314                     cur_tr = prev_tr;
315                 }
316                 if(img){
317                     while(1){
318                         next_tr = side.next();
319                         if(next_tr.attr('level') <= level || next_tr.length==0){
320                             break;
321                         }else{
322                             list_shift.push(next_tr);
323                             side = next_tr;
324                         } 
325                     }
326                 }
327                 if(last_tr.length!=0 && last_tr.attr('level') == level){
328                     _.each(list_shift,function(rec){
329                          $(last_tr).before(rec); 
330                     });
331                 }
332             break;
333         case "side-down":
334             if(img){
335                 while(1){
336                     next_tr = cur_tr.next();
337                     if(next_tr.attr('level') <= level || next_tr.length==0){
338                         last_tr = next_tr;
339                     break;
340                     }else{
341                         list_shift.push(next_tr);
342                         cur_tr = next_tr;
343                     } 
344                }
345             }
346             else{
347                 last_tr = cur_tr.next();
348             }
349             if(last_tr.length != 0 && last_tr.attr('level')==level){
350                 var last_tr_id = (last_tr.attr('id')).split('-')[1];  
351                 img = last_tr.find("img[id='parentimg-"+last_tr_id+"']").attr('src');
352                 if(img){
353                     $("img[id='parentimg-"+last_tr_id+"']").attr('src', '/web/static/src/img/expand.gif');
354                     while(1){
355                         var next_tr = last_tr.next();
356                         if (next_tr.attr('level') <= level || next_tr.length==0){break;}
357                         next_tr.hide();
358                         last_tr = next_tr;
359                     }
360                 }
361                 list_shift.reverse();
362                 _.each(list_shift,function(rec){
363                    $(last_tr).after(rec); 
364                 });
365             }
366             break;
367         }
368     });
369     },
370     on_expand: function(self){
371         var level = $(self).closest("tr[id^='viewedit-']").attr('level');
372         var cur_tr = $(self).closest("tr[id^='viewedit-']");
373         while (1){
374             var nxt_tr = cur_tr.next();
375             if (nxt_tr.attr('level') > level){
376                 cur_tr = nxt_tr;
377                 nxt_tr.hide();
378             }else return nxt_tr;
379         }
380     },
381     on_collapse: function(self,parent_child_id,id,main_object){
382         var id = self.id.split('-')[1];
383         var datas = _.detect(parent_child_id,function(res){
384             return res.key == id;
385         });
386         _.each(datas.value,function(rec){
387             var tr = $("tr[id='viewedit-"+rec+"']");
388             tr.find("img[id='parentimg-"+rec+"']").attr('src','/web/static/src/img/expand.gif');
389             tr.show();
390         });
391     }
392 });
393 };