90f1cdac5d479fbdf833b133921f8bf9d9550fe5
[app.Builder.js] / Builder / LeftTree.js
1 //<Script type="text/javascript">
2 //<Script type="text/javascript">
3 Gio = imports.gi.Gio;
4 Gtk = imports.gi.Gtk;
5 Gdk = imports.gi.Gdk;
6 GObject = imports.gi.GObject;
7 Pango = imports.gi.Pango ;
8
9 XObject = imports.XObject.XObject;
10 console = imports.console;
11
12 // recursive imports here break!!?
13 Roo             = imports.Builder.Provider.Palete.Roo.Roo;
14 LeftTreeMenu    = imports.Builder.LeftTreeMenu.LeftTreeMenu;
15 LeftPanel       = imports.Builder.LeftPanel.LeftPanel;
16 MidPropTree     = imports.Builder.MidPropTree.MidPropTree;
17
18 RightEditor     = imports.Builder.RightEditor.RightEditor;
19 // http://www.google.com/codesearch/p?hl=en#EKZaOgYQHwo/unstable/sources/sylpheed-2.2.9.tar.bz2%7C1erxr_ilM1o/sylpheed-2.2.9/src/folderview.c&q=gtk_tree_view_get_drag_dest_row
20
21 var idSeed = 0;
22 function id(el, prefix){
23     prefix = prefix || "left-tree";
24     //el = Roo.getDom(el);
25     var ret = prefix + (++idSeed);
26     return ret;
27     //return el ? (el.id ? el.id : (el.id = id)) : id;
28 }
29
30 LeftTree = new XObject(
31 {
32         id : 'LeftTree',
33         xtype: Gtk.ScrolledWindow,
34         smooth_scroll : true,
35         
36         shadow_type :  Gtk.ShadowType.IN,
37         init : function() {
38             this.targetList.add( this.atoms["STRING"], 0 , 1);
39             // will not work without changes to gir..
40            // var ta_ar = Gtk.target_table_new_from_list(this.targetList,r);
41             
42             XObject.prototype.init.call(this); 
43             this.el.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
44             
45              
46         },
47         
48         getPaleteProvider: function ()
49         {
50             var model = this.get('model');
51             var pm = imports.Builder.Provider.ProjectManager.ProjectManager;
52             return pm.getPalete(model.file.getType());
53             
54         },
55         
56         renderView: function() // renders into the preview pane..
57         {
58             var model = this.get('model');
59             print("RENDER VIEW?" + model.file.getType());
60             switch( model.file.getType()) {
61                 case 'Roo':
62                     var RightBrowser    = imports.Builder.RightBrowser.RightBrowser;
63                     RightBrowser.get('view').renderJS(model.toJS(false,true)[0]);
64                 case 'Gtk':
65                     var RightGtkView = imports.Builder.RightGtkView.RightGtkView ;
66                     RightGtkView.renderJS(model.toJS(false,true)[0]);
67             }
68             
69         },
70         
71         atoms : {
72            "STRING" : Gdk.atom_intern("STRING")
73         },
74                         
75         targetList :  new Gtk.TargetList(),
76         
77         items : [        
78             {
79                 id : 'view',
80                 xtype: Gtk.TreeView,
81                 headers_visible :  false,
82                 enable_tree_lines :  true,
83                 tooltip_column : 0,
84                 // selection  -- set by init..
85                 init : function() {
86                     XObject.prototype.init.call(this); 
87                     
88                     var description = new Pango.FontDescription.c_new();
89                     description.set_size(8000);
90                     this.el.modify_font(description);
91                     
92                     this.selection = this.el.get_selection();
93                     this.selection.set_mode( Gtk.SelectionMode.SINGLE);
94                     this.selection.signal['changed'].connect(function() {
95                         LeftTree.get('view').listeners['cursor-changed'].apply(
96                             LeftTree.get('view'), [ LeftTree.get('view'), '']
97                         );
98                     });
99                     
100                     Gtk.drag_source_set (
101                         this.el,            /* widget will be drag-able */
102                         Gdk.ModifierType.BUTTON1_MASK,       /* modifier that will start a drag */
103                         null,            /* lists of target to support */
104                         0,              /* size of list */
105                         Gdk.DragAction.COPY   | Gdk.DragAction.MOVE           /* what to do with data after dropped */
106                     );
107                     var targets = new Gtk.TargetList();
108                     targets.add( LeftTree.atoms["STRING"], 0, 0);
109                     Gtk.drag_source_set_target_list(this.el, targets);
110
111                     Gtk.drag_source_add_text_targets(this.el); 
112                     Gtk.drag_dest_set
113                     (
114                             this.el,              /* widget that will accept a drop */
115                             Gtk.DestDefaults.MOTION  | Gtk.DestDefaults.HIGHLIGHT,
116                             null,            /* lists of target to support */
117                             0,              /* size of list */
118                             Gdk.DragAction.COPY   | Gdk.DragAction.MOVE       /* what to do with data after dropped */
119                     );
120                      
121                     Gtk.drag_dest_set_target_list(this.el, targets);
122                     Gtk.drag_dest_add_text_targets(this.el);
123                     
124                     
125                 },
126                 
127                 highlight : function(treepath_ar) {
128                     if (treepath_ar.length && treepath_ar[0].length ) {
129                         this.el.set_drag_dest_row( 
130                             new  Gtk.TreePath.from_string( treepath_ar[0] ),  treepath_ar[1]);
131                     } else {
132                         this.el.set_drag_dest_row(null, Gtk.TreeViewDropPosition.INTO_OR_AFTER);
133                     }
134                      
135                 },
136                 
137                 selectNode : function(treepath_str) 
138                 {
139                     
140                    this.selection.select_path(new  Gtk.TreePath.from_string( treepath_str));
141                 },
142                 
143                 listeners : {
144                     
145                     
146                     
147                     'button-press-event' : function(tv, ev) {
148                         console.log("button press?");
149                         if (ev.type != Gdk.EventType.BUTTON_PRESS  || ev.button.button != 3) {
150                             Seed.print("click" + ev.type);
151                             return false;
152                         }
153                       
154                     
155                         var res = {}; 
156                         LeftTree.get('view').el.get_path_at_pos(ev.button.x,ev.button.y, res);
157                         
158                         if (!LeftTreeMenu.el)  LeftTreeMenu.init();
159                         
160                         LeftTreeMenu.el.set_screen(Gdk.Screen.get_default());
161                         LeftTreeMenu.el.show_all();
162                         LeftTreeMenu.el.popup(null, null, null, null, 3, ev.button.time);
163                         Seed.print("click:" + res.path.to_string());
164                         return false;
165                         
166                     },
167                     
168                      'drag-begin' : function (w, ctx, ud) 
169                     {
170                            // we could fill this in now...
171                         Seed.print('SOURCE: drag-begin');
172                          this.targetData = false;
173                         // find what is selected in our tree...
174                         var iter = new Gtk.TreeIter();
175                         var s = this.selection;
176                         s.get_selected(LeftTree.get('model').el, iter);
177
178                         // set some properties of the tree for use by the dropped element.
179                         var value = new GObject.Value('');
180                         LeftTree.get('model').el.get_value(iter, 2, value);
181                         var data = JSON.parse(value.value);
182                         var xname = LeftTree.get('model').file.guessName(data);
183                         
184                         this.el.dragData = xname;
185                         this.el.dropList = LeftTree.getPaleteProvider().getDropList(xname);
186                         
187
188                         // make the drag icon a picture of the node that was selected
189                         var path = LeftTree.get('model').el.get_path(iter);
190                         this.el.treepath = path.to_string();
191                         
192                         var pix = this.el.create_row_drag_icon ( path);
193                         
194                         Gtk.drag_set_icon_pixmap (ctx,
195                             pix.get_colormap(),
196                             pix,
197                             null,
198                             -10,
199                             -10);
200                         
201                         return true;
202                       
203                         
204                     },
205                     
206                     'drag-end' : function ( w,  drag_context, x, y, time, user_data)   
207                     {
208                         // i'm not sure if this would work, without implementing the whole kaboodle.
209                         Seed.print('LEFT-TREE: drag-end');
210                         this.el.dragData = false;
211                         this.el.dropList = false;
212                         this.targetData = false;
213                         LeftTree.get('view').highlight(false);
214                         return true;
215                       
216                       
217                     },
218                     'drag-motion' : function (w, ctx,  x,   y,   time, ud) 
219                     {
220                         
221                         console.log("LEFT-TREE: drag-motion");
222                         var src = Gtk.drag_get_source_widget(ctx);
223
224                         // a drag from  elsewhere...- prevent drop..
225                         if (!src.dragData) {
226                             print("no drag data!");
227                             Gdk.drag_status(ctx, 0, time);
228                             this.targetData = false;
229                             return true;
230                         }
231                         var action = Gdk.DragAction.COPY;
232                         if (src == this.el) {
233                             // unless we are copying!!! ctl button..
234                             action = Gdk.DragAction.MOVE;
235                         }
236                         var data = {};
237                         print("GETTING POS");
238                         var isOver = LeftTree.get('view').el.get_dest_row_at_pos(x,y, data);
239                         print("ISOVER? " + isOver);
240                         if (!isOver) {
241                             Gdk.drag_status(ctx, 0 ,time);
242                             return false; // not over apoint!?!
243                         }
244                         // drag node is parent of child..
245                         console.log("SRC TREEPATH: " + src.treepath);
246                         console.log("TARGET TREEPATH: " + data.path.to_string());
247                         
248                         // nned to check a  few here..
249                         //Gtk.TreeViewDropPosition.INTO_OR_AFTER
250                         //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
251                         //Gtk.TreeViewDropPosition.AFTER
252                         //Gtk.TreeViewDropPosition.BEFORE
253                         
254                         if (typeof(src.treepath) != 'undefined'  && 
255                             src.treepath == data.path.to_string().substring(0,src.treepath.length)) {
256                             print("subpath drag");
257                              Gdk.drag_status(ctx, 0 ,time);
258                             return false;
259                         }
260                         
261                         // check that 
262                         //print("DUMPING DATA");
263                         //console.dump(data);
264                         // path, pos
265                         
266                         Seed.print(data.path.to_string() +' => '+  data.pos);
267                         var tg = LeftTree.get('model').findDropNodeByPath(
268                             data.path.to_string(), src.dropList, data.pos);
269                             
270                         LeftTree.get('view').highlight(tg);
271                         if (!tg.length) {
272                             print("Can not find drop node path");
273                             this.targetData = false;
274                             Gdk.drag_status(ctx, 0, time);
275                             return true;
276                         }
277                         //console.dump(tg);
278                         this.targetData = tg;    
279                         
280                         
281                         Gdk.drag_status(ctx, action ,time);
282                          
283                         return true;
284                     },
285                     
286                     'drag-drop'  : function (w, ctx, x, y,time, ud) 
287                     {
288                                 
289                         Seed.print("TARGET: drag-drop");
290                        
291                         Gtk.drag_get_data
292                         (
293                                 w,         /* will receive 'drag-data-received' signal */
294                                 ctx,        /* represents the current state of the DnD */
295                                 LeftTree.atoms["STRING"],    /* the target type we want */
296                                 time            /* time stamp */
297                         );
298                         
299                          
300                         /* No target offered by source => error */
301                        
302
303                         return  true;
304                         
305
306                     },
307                    'drag-data-received' : function (w, ctx,  x,  y, sel_data,  target_type,  time, ud) 
308                     {
309                         Seed.print("Tree: drag-data-received");
310                         delete_selection_data = false;
311                         dnd_success = false;
312                         /* Deal with what we are given from source */
313                         if( sel_data && sel_data.length ) {
314                             
315                             if (ctx.action == Gdk.DragAction.ASK)  {
316                                 /* Ask the user to move or copy, then set the ctx action. */
317                             }
318
319                             if (ctx.action == Gdk.DragAction.MOVE) {
320                                 //delete_selection_data = true;
321                             }
322                             
323                             var source = Gtk.drag_get_source_widget(ctx);
324  
325                             if (this.targetData) {
326                                 if (source != this.el) {
327                                     LeftTree.get('model').dropNode(this.targetData,  source.dragData);
328                                 } else {
329                                     // drag around.. - reorder..
330                                     LeftTree.get('model').moveNode(this.targetData);
331                                     
332                                     
333                                 }
334                                 //Seed.print(this.targetData);
335                               
336                             }
337                             
338                             
339                             
340                             // we can send stuff to souce here...
341
342                             dnd_success = true;
343
344                         }
345
346                         if (dnd_success == false)
347                         {
348                                 Seed.print ("DnD data transfer failed!\n");
349                         }
350
351                         Gtk.drag_finish (ctx, dnd_success, delete_selection_data, time);
352                         return true;
353                     },
354                     
355                     'cursor-changed'  : function(tv, a) {
356                         var iter = new Gtk.TreeIter();
357                         
358                         if (this.selection.count_selected_rows() < 1) {
359                             LeftPanel.get('model').load( false);
360                             MidPropTree.activeElement =  false;
361                             MidPropTree.hideWin();
362                             var RightPalete     = imports.Builder.RightPalete.RightPalete;
363                             var pm = RightPalete.get('model');
364                             if (!LeftTree.getPaleteProvider()) {
365                                 // it may not be loaded yet..
366                                 return  true;
367                             }
368                             pm.load( LeftTree.getPaleteProvider().gatherList(
369                                 LeftTree.get('model').listAllTypes()));
370                            
371                             return true;
372                         }
373                         
374                         //console.log('changed');
375                         var s = this.selection;
376                         s.get_selected(LeftTree.get('model').el, iter);
377                         
378                         
379                         // var val = "";
380                         value = new GObject.Value('');
381                         LeftTree.get('model').el.get_value(iter, 2, value);
382                         LeftTree.get('model').activeIter = iter;
383                         
384                         var data = JSON.parse(value.value);
385                         MidPropTree.activeElement =  data;
386                         MidPropTree.hideWin();
387                         LeftPanel.get('model').load( data);
388                         
389                         console.log(value.value);
390                        // _g.button.set_label(''+value.get_string());
391                         var RightPalete     = imports.Builder.RightPalete.RightPalete;
392                         var pm = RightPalete.get('model');
393                         pm.load( RightPalete.provider.gatherList(
394                             LeftTree.get('model').listAllTypes()));
395                        
396                         
397                        
398                        
399                         //Seed.print( value.get_string());
400                         return true;
401                         
402                         
403                     
404                     }
405                 },
406                 
407                 items  : [
408                     {
409                         id : 'model',
410                         pack : ['set_model'],
411                         
412                         
413                         xtype: Gtk.TreeStore,
414                          
415                         init : function() {
416                             XObject.prototype.init.call(this); 
417                  
418                             
419                             this.el.set_column_types ( 3, [
420                                                     GObject.TYPE_STRING, // title 
421                                                     GObject.TYPE_STRING, // tip
422                                                     GObject.TYPE_STRING // source..
423                                                     ] );
424                             
425                             //if (LeftProjectTree.project).getProvider()
426                             
427                            
428                         },
429                         activeIter : false,
430                         
431                         
432                         changed : function( n, refresh) 
433                         {
434                             print("MODEL CHANGED CALLED" + this.activeIter);
435                             if (this.activeIter) {
436                                     
437                                 this.el.set_value(this.activeIter, 0, [GObject.TYPE_STRING, this.nodeTitle(n)]);
438                                 this.el.set_value(this.activeIter, 1, [GObject.TYPE_STRING, this.nodeTitle(n)]);
439                                 
440                                 this.el.set_value(this.activeIter, 2, [GObject.TYPE_STRING, this.nodeToJSON(n)]);
441                             }
442                                 //this.currentTree = this.toJS(false, true)[0];
443                             this.file.items = this.toJS(false, false);
444                             print("AFTER CHANGED")
445                             //console.dump(this.file.items);
446                             this.file.save();
447                             this.currentTree = this.file.items[0];
448                             //console.log(this.file.toSource());
449                             
450                             if (refresh) {
451                                 print("REDNER BROWSER?!");
452                                 LeftTree.renderView();
453                                 
454                                 var RightPalete     = imports.Builder.RightPalete.RightPalete;
455                                 var pm = RightPalete.get('model');
456                                 if (!RightPalete.provider) {
457                                     pm.load([]);
458                                     return;
459                                 }
460                                 
461                                 
462                                 pm.load( RightPalete.provider.gatherList(this.listAllTypes()));
463                                 //imports['Builder/RightBrowser.js'].renderJS(this.toJS());
464                             }
465                              
466                         },
467                         
468                         
469                         loadFile : function(f)
470                         {
471                             //console.dump(f);
472                             this.el.clear();
473                             this.file = f;
474                             
475                             if (!f) {
476                                 console.log('missing file');
477                                 return;
478                             }
479                             
480                             // load the file if not loaded..
481                             if (f.items === false) {
482                                 var _this = this;
483                                 f.loadItems(function() {
484                                     _this.loadFile(f);
485                                 });
486                                 return;
487                                 
488                             }
489                             if (f.items.length && typeof(f.items[0]) == 'string') {
490                             
491                                 RightEditor.el.show();
492                                 RightEditor.get('view').load( f.items[0]);
493                                 return;
494                             }
495                             print("LOAD");
496                             //console.dump(f.items);
497                             this.load(f.items);
498                             LeftTree.get('view').el.expand_all();
499                             var Window = imports.Builder.Window.Window;
500                             if (!f.items.length) {
501                                 // single item..
502                                 
503                                 Window.get('leftvpaned').el.set_position(80);
504                                 // select first...
505                                 LeftTree.get('view').el.set_cursor( 
506                                     new  Gtk.TreePath.from_string('0'), null, false);
507                                 
508                                 
509                             } else {
510                                   Window.get('leftvpaned').el.set_position(200);
511                             }
512                             
513                             
514                             print("hide right editior");
515                             RightEditor.el.hide();
516                             print("set current tree");
517                             this.currentTree = this.toJS(false, false)[0];
518                             //console.dump(this.currentTree);
519                             this.currentTree = this.currentTree || { items: [] };
520                             LeftTree.renderView();
521                             //console.dump(this.map);
522                             var RightPalete     = imports.Builder.RightPalete.RightPalete;
523                             var pm = RightPalete.get('model');
524                             // set up provider..
525                             
526                             RightPalete.provider = LeftTree.getPaleteProvider();
527                             
528                             if (!RightPalete.provider) {
529                                 print ("********* PALETE PROVIDER MISSING?!!");
530                             }
531                             LeftTree.renderView();
532                             
533                             pm.load( LeftTree.getPaleteProvider().gatherList(this.listAllTypes()));
534                             
535                             
536                                     
537                             Window.get('view-notebook').el.set_current_page(
538                                 LeftTree.get('model').file.getType()== 'Roo' ? 0 : -1);
539                                     
540                             
541                             
542                         },
543                         
544                         findDropNode : function (treepath_str, targets)
545                         {
546                             
547                             
548                             var path = treepath_str.replace(/^builder-/, '');
549                             
550                             if (!XObject.keys(this.treemap).length) {
551                                 print("NO KEYS");
552                                 return [ '',  Gtk.TreeViewDropPosition.INTO_OR_AFTER];
553                             }
554                             print("FIND treepath: " + path);
555                             //console.dump(this.treemap);
556                             
557                             if (!treepath_str.match(/^builder-/)) {
558                                 return []; // nothing!
559                             }
560                             if (targets === true) {
561                                 return [ path ];
562                             }
563                             return this.findDropNodeByPath(path,targets) 
564                         },
565                         findDropNodeByPath : function (treepath_str, targets, pref)
566                         {
567                             
568                             var path = treepath_str + ''; // dupe it..
569                             pref = typeof(pref) == 'undefined' ?  Gtk.TreeViewDropPosition.INTO_OR_AFTER : pref;
570                             var last = false;
571                             //console.dump(this.treemap);
572                             while (path.length) {
573                                 print("LOOKING FOR PATH: " + path);
574                                 var node_data = this.singleNodeToJS(path);
575                                 if (node_data === false) {
576                                     print("node not found");
577                                     return [];
578                                 }
579                                 
580                                 var xname = LeftTree.get('model').file.guessName(node_data);
581                                 var match = false;
582                                 var prop = '';
583                                 targets.forEach(function(tg) {
584                                     if (match) {
585                                         return;;
586                                     }
587                                     if ((tg == xname)  ) {
588                                         match = tg;
589                                     }
590                                     if (tg.indexOf(xname +':') === 0) {
591                                         match = tg;
592                                         prop = tg.split(':').pop();
593                                     }
594                                 });
595                                 
596                                 if (match) {
597                                     if (last) { // pref is after/before..
598                                         // then it's after last
599                                         if (pref > 1) {
600                                             return []; // do not allow..
601                                         }
602                                         return [ last, pref , prop];
603                                         
604                                     }
605                                     return [ path , Gtk.TreeViewDropPosition.INTO_OR_AFTER , prop];
606                                 }
607                                 var par = path.split(':');
608                                 last = path;
609                                 par.pop();
610                                 path = par.join(':');
611                             }
612                             
613                             return [];
614                             
615                             
616                         },
617                         /** 
618                         * drop a node.. - tecncially add node..
619                         * 
620                         * @param {Array} target_data - [ treepath_string,  before/after/ , property (to add as)]
621                         * @param {Object} node with data..
622                         */
623                         
624                         dropNode: function(target_data, node) {
625                             
626                             console.dump(target_data);
627                             var tp = target_data[0].length ? new  Gtk.TreePath.from_string( target_data[0] ) : false;
628                             
629                             print("add where: " + target_data[1]  );
630                             var parent = tp;
631                             var after = false;
632                             if (target_data[1]  < 2) { // before or after..
633                                 var ar = target_data[0].split(':');
634                                 ar.pop();
635                                 parent  = new  Gtk.TreePath.from_string( ar.join(':') );
636                                 after = tp;
637                             }
638                             var n_iter = new Gtk.TreeIter();
639                             var iter_par = new Gtk.TreeIter();
640                             var iter_after = after ? new Gtk.TreeIter() : false;
641                             if (parent !== false) {
642                                 this.el.get_iter(iter_par, parent);
643                             } else {
644                                 iter_par = null;
645                             }
646                             
647                             
648                             if (after) {
649                                 Seed.print(target_data[1]  > 0 ? 'insert_after' : 'insert_before');
650                                 this.el.get_iter(iter_after, after);
651                                 this.el[ target_data[1]  > 0 ? 'insert_after' : 'insert_before'](
652                                         n_iter, iter_par, iter_after);
653                                 
654                             } else {
655                                 this.el.append(n_iter, iter_par);
656                                 
657                             }
658                             
659                             if (typeof(node) == 'string') {
660                                 var ar = node.split('.');
661                                 var xtype = ar.pop();
662                                 
663                                 node = {
664                                     '|xns' : ar.join('.'),
665                                     'xtype' : xtype
666                                 };
667                                 if (target_data.length == 3 && target_data[2].length) {
668                                     node['*prop'] = target_data[2];
669                                 }
670                                 
671                             }
672                             // work out what kind of packing to use..
673                             if (typeof(node.pack) == 'undefined'  && parent !== false) {
674                                 var pal = this.get('/LeftTree').getPaleteProvider();
675                                 
676                                 var pname = pal.guessName(this.singleNodeToJS(parent));
677                                 var cname = pal.file.guessName(node);
678                                 
679                                 node.pack = pal.getDefaultPack(pname, cname);
680                                 
681                                 
682                             }
683                             
684                             
685                             var xitems = [];
686                             if (node.items) {
687                                 xitems = node.items;
688                                 delete node.items;
689                             }
690                             if (xitems) {
691                                 this.load(xitems, n_iter);
692                             }
693                             if (xitems || after) {
694                                 LeftTree.get('view').el.expand_row(this.el.get_path(iter_par), true);
695                             }
696                             // wee need to get the empty proptypes from somewhere..
697                             
698                             //var olditer = this.activeIter;
699                             this.activeIter = n_iter;
700                             this.changed(node, true);
701                             
702                             
703                             
704                             LeftTree.get('view').el.set_cursor(this.el.get_path(n_iter), null, false);
705                             
706                             //Builder.MidPropTree._model.load(node);
707                             //Builder.MidPropTree._win.hideWin();
708                             //Builder.LeftPanel._model.load( node);
709                             
710                             
711                             
712                             
713                         },
714                         moveNode: function(target_data) {
715                             
716                             //print("MOVE NODE");
717                            // console.dump(target_data);
718                             var old_iter = new Gtk.TreeIter();
719                             var s = LeftTree.get('view').selection;
720                             s.get_selected(this.el, old_iter);
721                             var node = this.nodeToJS(old_iter,false);
722                             //console.dump(node);
723                             
724                             
725                             // needs to drop first, otherwise the target_data 
726                             // treepath will be invalid.
727                             
728                             this.dropNode(target_data, node);
729                             this.el.remove(old_iter);
730                             
731                             
732                         },
733                         
734                         deleteSelected: function() {
735                             
736                             
737                             
738                             var old_iter = new Gtk.TreeIter();
739                             var s = LeftTree.get('view').selection;
740                             s.get_selected(this.el, old_iter);
741                             s.unselect_all();
742                             
743                             this.el.remove(old_iter);
744                             
745                             // rebuild treemap.
746                             this.map = {};
747                             this.treemap = { };
748                             //this.toJS(null, true) // does not do anything?
749                             this.activeIter = false;
750                             this.changed(false,true);
751                             
752                             
753                             
754                         },    
755                         
756                         
757                         currentTree  : false,
758                          
759                         treemap: false, // map of treepath to nodes.
760                         
761                         listAllTypes : function()
762                         {
763                             
764                             
765                             var s = LeftTree.get('view').selection;
766                             print ("LIST ALL TYPES: " + s.count_selected_rows() );
767                             
768                             if (s.count_selected_rows() > 0) {
769                                 var iter = new Gtk.TreeIter();    
770                                 s.get_selected(LeftTree.get('model').el, iter);
771
772                                 // set some properties of the tree for use by the dropped element.
773                                 var value = new GObject.Value('');
774                                 LeftTree.get('model').el.get_value(iter, 2, value);
775                                 var data = JSON.parse(value.value);
776                                 
777                                 
778                                 var xname = LeftTree.get('model').file.guessName(data);
779                                 console.log('selected:' + xname);
780                                 if (xname.length) {
781                                     return [ xname ];
782                                 }
783                                 return []; // could not find it..
784                             }
785                             
786                             var ret = [ ];
787                             
788                             function addall(li)
789                             {
790                                 li.forEach(function(el) {
791                                     // this is specific to roo!!!?
792                                     
793                                     var fullpath =  LeftTree.get('model').file.guessName(el);
794                                     if (fullpath.length && ret.indexOf(fullpath) < 0) {
795                                         ret.push(fullpath);
796                                     }
797                                     
798                                     
799                                     if (el.items && el.items.length) {
800                                         addall(el.items);
801                                     }
802                                     
803                                 })
804                                 
805                                 
806                             }
807                             
808                             addall([this.currentTree]);
809                             
810                             // only if we have nothing, should we add '*top'
811                             if (!ret.length) {
812                                 ret = [ '*top' ];
813                             }
814                             console.log('all types in tree');
815                             console.dump(ret);
816                             
817                             return ret;
818                             
819                             
820                         },
821                         singleNodeToJS: function (treepath) 
822                         {
823                             var iter = new Gtk.TreeIter(); 
824                             if (!this.el.get_iter(iter, new Gtk.TreePath.from_string(treepath))) {
825                                 return false;
826                             }
827                             
828                             var iv = this.getValue(iter, 2);
829                            
830                             return JSON.parse(iv);
831                             
832                         },
833                         
834                         /**
835                          * convert tree into a javascript array
836                          * 
837                          */
838                         nodeToJS: function (iter, with_id) 
839                         {
840                             var par = new Gtk.TreeIter(); 
841                             var iv = this.getValue(iter, 2);
842                            // print("IV" + iv);
843                             var k = JSON.parse(iv);
844                             if (k.json && !this.el.iter_parent( par, iter  )) {
845                                 delete k.json;
846                             }
847                             
848                             if (with_id) {
849                                 var treepath_str = this.el.get_path(iter).to_string();
850                                 k.id =  'builder-'+ treepath_str ;
851                                
852                                 this.treemap[  treepath_str ] = k;
853                                 k.xtreepath = treepath_str ;
854                                 
855                             }
856                             if (this.el.iter_has_child(iter)) {
857                                 citer = new Gtk.TreeIter();
858                                 this.el.iter_children(citer, iter);
859                                 k.items = this.toJS(citer,with_id);
860                             }
861                             return k;
862                         },
863                          /**
864                           * iterates through child nodes (or top..)
865                           * 
866                           */
867                         toJS: function(iter, with_id)
868                         {
869                             Seed.print("WITHID: "+ with_id);
870                             
871                             var first = false;
872                             if (!iter) {
873                                 
874                                 this.treemap = { }; 
875                                 
876                                 iter = new Gtk.TreeIter();
877                                 if (!this.el.get_iter_first(iter)) {
878                                     return [];
879                                 }
880                                 first = true;
881                             } 
882                             
883                             var ar = [];
884                                
885                             while (true) {
886                                 
887                                 var k = this.nodeToJS(iter, with_id); 
888                                 ar.push(k);
889                                 
890                                 
891                                 if (!this.el.iter_next(iter)) {
892                                     break;
893                                 }
894                             }
895                             
896                             return ar;
897                             // convert the list into a json string..
898                         
899                             
900                         },
901                         getValue: function (iter, col) {
902                             var gval = new GObject.Value('');
903                             this.el.get_value(iter, col ,gval);
904                             return  gval.value;
905                             
906                             
907                         },
908                         
909                         nodeTitle: function(c)
910                         {
911                               
912                             var txt = [];
913                             c = c || {};
914                             var sr = (typeof(c['+buildershow']) != 'undefined') &&  !c['+buildershow'] ? true : false;
915                             if (sr) txt.push('<s>');
916                             if (typeof(c['*prop']) != 'undefined')   { txt.push(c['*prop']+ ':'); }
917                             if (c.xtype)      { txt.push(c.xtype); }
918                             if (c.id)      { txt.push('<b>[id=' + c.id + ']</b>'); }
919                             if (c.fieldLabel) { txt.push('[' + c.fieldLabel + ']'); }
920                             if (c.boxLabel)   { txt.push('[' + c.boxLabel + ']'); }
921                             
922                             
923                             if (c.layout)     { txt.push('<i>' + c.layout + '</i>'); }
924                             if (c.title)      { txt.push('<b>' + c.title + '</b>'); }
925                             if (c.label)      { txt.push('<b>' + c.label+ '</b>'); }
926                             if (c.header)    { txt.push('<b>' + c.header + '</b>'); }
927                             if (c.legend)      { txt.push('<b>' + c.legend + '</b>'); }
928                             if (c.text)       { txt.push('<b>' + c.text + '</b>'); }
929                             if (c.name)       { txt.push('<b>' + c.name+ '</b>'); }
930                             if (c.region)     { txt.push('<i>(' + c.region + ')</i>'); }
931                             if (c.dataIndex) { txt.push('[' + c.dataIndex+ ']'); }
932                             
933                             // for flat classes...
934                             if (typeof(c['*class']) != 'undefined')  { txt.push('<b>' +  c['*class']+  '</b>'); }
935                             if (typeof(c['*extends']) != 'undefined')  { txt.push(': <i>' +  c['*extends']+  '</i>'); }
936                             
937                             
938                             if (sr) txt.push('</s>');
939                             return (txt.length == 0 ? "Element" : txt.join(" "));
940                         
941                       //console.log(n.xtype);
942                            // return n.xtype;
943                         },
944                         
945                         nodeToJSON : function(c) {
946                             var o  = {}
947                             for (var i in c) {
948                                 if (i == 'items') {
949                                      continue;
950                                 }
951                                 o[i] = c[i];
952                             }
953                             return JSON.stringify(o);
954                         },
955                         /**
956                          * load javascript array onto an iter..
957                          * @param tr = array of elements
958                          * @param iter = iter of parent (or null if not..)
959                          */
960                         
961                         
962                          
963                         
964                         load : function(tr,iter)
965                         {
966                             var citer = new Gtk.TreeIter();
967                             //this.insert(citer,iter,0);
968                             for(var i =0 ; i < tr.length; i++) {
969                                 if (iter) {
970                                     this.el.insert(citer,iter,-1);
971                                 } else {
972                                     this.el.append(citer);
973                                 }
974                                 
975                                 this.el.set_value(citer, 0, [GObject.TYPE_STRING, this.nodeTitle(tr[i]) ]);
976                                 this.el.set_value(citer, 1, [GObject.TYPE_STRING, this.nodeTitle(tr[i]) ]);
977                                 this.el.set_value(citer, 2, [GObject.TYPE_STRING, this.nodeToJSON(tr[i])]);
978                                 if (tr[i].items && tr[i].items.length) {
979                                     this.load(tr[i].items, citer);
980                                 }
981                             }
982                             
983                             
984                             
985                             
986                         },
987                         
988                         
989                         
990                       //  this.expand_all();
991                     },
992                     
993                       
994                     {
995                         xtype: Gtk.TreeViewColumn,
996                         pack : ['append_column'],
997                         init : function(){
998                             XObject.prototype.init.call(this); 
999                             this.el.add_attribute(this.items[0].el , 'markup', 0 );
1000                            
1001                         },
1002                         items : [
1003                             {
1004                                 
1005                                 xtype: Gtk.CellRendererText,
1006                                 pack: [ 'pack_start']
1007                                   
1008                             } 
1009                         ],
1010                      
1011                       
1012                     }
1013                     
1014                ]
1015             }
1016         ]
1017                 
1018          
1019     }
1020 );
1021