dc2d1489f80dfd8108399b46dde38a6675631125
[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             dataset = new openerp.web.DataSetSearch(self, 'ir.ui.view', null, null);
156             dataset.read_slice([],{domain : [['inherit_id','=',parseInt(view_id)]]},function (result) {
157
158             return self.edit_view({"main_object": one_object,
159                          "parent_child_id": self.parent_child_list(one_object, [])});
160             });
161         });
162     },
163     parent_child_list: function(one_object, p_list) {
164         var self = this;
165         _.each(one_object , function(element){
166             if(element.child_id.length != 0){
167                 p_list.push({"key":element.id,"value":_.pluck(element.child_id, 'id')});
168                 self.parent_child_list(element.child_id,p_list);
169             }
170         });
171         return p_list;
172     },
173     inherit_view: function(one_object, result){
174         var self = this;
175         var root = $(result.arch).filter('*');
176         var xml_list = [];
177         var xpath_object ;
178         if (root[0].tagName.toLowerCase() == "data") {
179             xml_list = $(root[0]).children();
180         } else {
181             xml_list.push(root[0]);
182         }
183         _.each(xml_list , function(xml){
184             var parent_id;
185             var check_list = [];
186             var position = $(xml).attr('position');
187             if (xml.tagName.toLowerCase() == "xpath") {
188                 var part_expr = _.without($(xml).attr('expr').split("/"),"");;
189                 xpath_object = self.parse_xml(xml,result.id); 
190                 if (part_expr[part_expr.length-1].search("@")!=-1) {
191                     check_list = $.trim(part_expr[part_expr.length-1].replace(/[^a-zA-Z 0-9 _]+/g,' ')).split(" ");
192                     
193                 }else{
194                     //search full path...
195                 }
196             } else {
197                 var xml_child = $(xml).children();
198                 check_list.push(xml.tagName.toLowerCase());
199                     if ($(root[0]).attr('name')){
200                         check_list.push($(root[0]).attr('name'));
201                         check_list.push("name");
202                     }
203                 xpath_object = self.parse_xml(xml,result.id);
204             }
205             $.each(function(){
206             });
207             self.search_object(val,check_list,[],position,xpath_object['main_object'],[]);
208         });
209     },
210     search_object: function(val ,list ,p_list ,position, xpath_object){
211         var self = this;
212         var main_list = $.trim(val.name.replace(/[^a-zA-Z 0-9 _]+/g,' ')).split(" ");
213         var insert = _.intersection(main_list,list);
214         var check = _.indexOf(p_list.child_id,xpath_object[0]);
215         if(check == -1){
216             if(insert.length == list.length){
217                 var level = val.level;
218                 $.each(xpath_object, function(key, val) {
219                     self.increase_level(val, level)
220                 });   
221                 var index = _.indexOf(p_list.child_id,val);
222                 switch (position)
223                 {
224                     case "before":
225                         if (index != 0) { index--; }
226                         p_list.child_id.splice(index,0,xpath_object[0]);
227                         break;
228                     case "after":
229                          index++;
230                          p_list.child_id.splice(index,0,xpath_object[0]);
231                         break;
232                     case "inside":
233                         val.child_id.push(xpath_object[0]);
234                         break;
235                     case "replace":
236                         break;
237                 }
238                 
239             }else{
240                 if ( val.child_id.length != 0) { p_list = val; }
241                 $.each(val.child_id, function(key, val) {
242                    self.search_object(val, list, p_list, position, xpath_object);
243                 });
244             }
245         }
246         return return_list;
247     },
248
249     increase_level :function(val, level){
250         var self = this;
251         val.level = level; 
252         $.each(val.child_id, function(key, val) {
253             self.increase_level(val,level+1);
254         });
255     },
256
257     edit_view : function(one_object){
258         var self = this;
259         console.log("++++++++++++++++++++++",one_object);
260         this.dialog = new openerp.web.Dialog(this,{
261             modal: true,
262             title: 'Edit Xml',
263             width: 750,
264             height: 500,
265             buttons: {
266                 "Inherited View": function(){
267                     //todo
268                 },
269                 "Preview": function(){
270                     //todo
271                 },
272                 "Close": function(){
273                     $(this).dialog('destroy');
274                 }
275             }
276         });
277     this.dialog.start().open();
278     this.dialog.$element.html(QWeb.render('view_editor', {
279        'data': one_object['main_object'],
280     }));
281
282     $("tr[id^='viewedit-']").click(function() {
283         $("tr[id^='viewedit-']").removeClass('ui-selected');
284         $(this).addClass('ui-selected');
285     });
286
287     $("img[id^='parentimg-']").click(function() {
288         if ($(this).attr('src') == '/web/static/src/img/collapse.gif'){
289             $(this).attr('src', '/web/static/src/img/expand.gif');
290             self.on_expand(this);
291         }else{
292             $(this).attr('src', '/web/static/src/img/collapse.gif');
293             var id = this.id.split('-')[1];
294             self.on_collapse(this,one_object['parent_child_id'],one_object['main_object']);
295         }
296     });
297     $("img[id^='side-']").click(function() {
298         var side = $(this).closest("tr[id^='viewedit-']")
299         var id_tr = (side.attr('id')).split('-')[1];
300         var img = side.find("img[id='parentimg-"+id_tr+"']").attr('src'); ;
301         var level = side.attr('level');
302         var list_shift =[];
303         var last_tr;
304         var cur_tr = side;
305         list_shift.push(side);
306         var next_tr;
307         switch (this.id)
308         {
309             case "side-add":
310                 break;
311             case "side-remove":
312                 break;
313             case "side-edit":
314                 break;
315            case "side-up":
316                 while(1){
317                     var prev_tr = cur_tr.prev();
318                     if(level >= prev_tr.attr('level') || prev_tr.length==0){
319                        last_tr = prev_tr;
320                        break;
321                     }
322                     cur_tr = prev_tr;
323                 }
324                 if(img){
325                     while(1){
326                         next_tr = side.next();
327                         if(next_tr.attr('level') <= level || next_tr.length==0){
328                             break;
329                         }else{
330                             list_shift.push(next_tr);
331                             side = next_tr;
332                         } 
333                     }
334                 }
335                 if(last_tr.length!=0 && last_tr.attr('level') == level){
336                     _.each(list_shift,function(rec){
337                          $(last_tr).before(rec); 
338                     });
339                 }
340             break;
341         case "side-down":
342             if(img){
343                 while(1){
344                     next_tr = cur_tr.next();
345                     if(next_tr.attr('level') <= level || next_tr.length==0){
346                         last_tr = next_tr;
347                     break;
348                     }else{
349                         list_shift.push(next_tr);
350                         cur_tr = next_tr;
351                     } 
352                }
353             }
354             else{
355                 last_tr = cur_tr.next();
356             }
357             if(last_tr.length != 0 && last_tr.attr('level')==level){
358                 var last_tr_id = (last_tr.attr('id')).split('-')[1];  
359                 img = last_tr.find("img[id='parentimg-"+last_tr_id+"']").attr('src');
360                 if(img){
361                     $("img[id='parentimg-"+last_tr_id+"']").attr('src', '/web/static/src/img/expand.gif');
362                     while(1){
363                         var next_tr = last_tr.next();
364                         if (next_tr.attr('level') <= level || next_tr.length==0){break;}
365                         next_tr.hide();
366                         last_tr = next_tr;
367                     }
368                 }
369                 list_shift.reverse();
370                 _.each(list_shift,function(rec){
371                    $(last_tr).after(rec); 
372                 });
373             }
374             break;
375         }
376     });
377     },
378     on_expand: function(self){
379         var level = $(self).closest("tr[id^='viewedit-']").attr('level');
380         var cur_tr = $(self).closest("tr[id^='viewedit-']");
381         while (1){
382             var nxt_tr = cur_tr.next();
383             if (nxt_tr.attr('level') > level){
384                 cur_tr = nxt_tr;
385                 nxt_tr.hide();
386             }else return nxt_tr;
387         }
388     },
389     on_collapse: function(self,parent_child_id,id,main_object){
390         var id = self.id.split('-')[1];
391         var datas = _.detect(parent_child_id,function(res){
392             return res.key == id;
393         });
394         _.each(datas.value,function(rec){
395             var tr = $("tr[id='viewedit-"+rec+"']");
396             tr.find("img[id='parentimg-"+rec+"']").attr('src','/web/static/src/img/expand.gif');
397             tr.show();
398         });
399     }
400 });
401 };