0ce264893fb5aca4fd6311a8c7c56bbecbe40113
[roobuilder] / src / Builder4 / WindowLeftTree.vala
1 static Xcls_WindowLeftTree  _WindowLeftTree;
2
3 public class Xcls_WindowLeftTree : Object
4 {
5     public Gtk.Box el;
6     private Xcls_WindowLeftTree  _this;
7
8     public static Xcls_WindowLeftTree singleton()
9     {
10         if (_WindowLeftTree == null) {
11             _WindowLeftTree= new Xcls_WindowLeftTree();
12         }
13         return _WindowLeftTree;
14     }
15     public Xcls_viewwin viewwin;
16     public Xcls_view view;
17     public Xcls_model model;
18     public Xcls_maincol maincol;
19     public Xcls_iconrender iconrender;
20     public Xcls_renderer renderer;
21     public Xcls_addiconrender addiconrender;
22     public Xcls_LeftTreeMenu LeftTreeMenu;
23
24         // my vars (def)
25     public signal bool before_node_change ();
26     public Xcls_MainWindow main_window;
27     public signal void changed ();
28     public signal void node_selected (JsRender.Node? node, string source);
29
30     // ctor
31     public Xcls_WindowLeftTree()
32     {
33         _this = this;
34         this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
35
36         // my vars (dec)
37         this.main_window = null;
38
39         // set gobject values
40         var child_0 = new Xcls_viewwin( _this );
41         child_0.ref();
42         this.el.add (  child_0.el  );
43     }
44
45     // user defined functions
46     public string getActivePath () {
47         
48         var view = this.view.el;
49         if (view.get_selection().count_selected_rows() < 1) {
50             return "";
51         }
52         Gtk.TreeIter iter;
53         Gtk.TreeModel mod;
54         view.get_selection().get_selected(out mod, out iter);
55         return mod.get_path(iter).to_string();
56     }
57     public JsRender.Node? getActiveElement () { // return path to actie node.
58     
59          var path = this.getActivePath();
60          if (path.length < 1) {
61             return null;
62          }
63          return _this.model.pathToNode(path);
64          
65     }
66     public JsRender.JsRender getActiveFile () {
67         return this.main_window.windowstate.file;
68     }
69     public class Xcls_viewwin : Object
70     {
71         public Gtk.ScrolledWindow el;
72         private Xcls_WindowLeftTree  _this;
73
74
75             // my vars (def)
76
77         // ctor
78         public Xcls_viewwin(Xcls_WindowLeftTree _owner )
79         {
80             _this = _owner;
81             _this.viewwin = this;
82             this.el = new Gtk.ScrolledWindow( null, null );
83
84             // my vars (dec)
85
86             // set gobject values
87             this.el.shadow_type = Gtk.ShadowType.IN;
88             var child_0 = new Xcls_view( _this );
89             child_0.ref();
90             this.el.add (  child_0.el  );
91             var child_1 = new Xcls_LeftTreeMenu( _this );
92             child_1.ref();
93
94             // init method
95
96             this.el.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
97
98             //listeners
99             this.el.size_allocate.connect( (allocation) => {
100             
101                  
102                 //GLib.debug("Got allocation width of scrolled view %d", allocation.width );
103                 _this.maincol.el.set_max_width(allocation.width - 32);
104             });
105         }
106
107         // user defined functions
108     }
109     public class Xcls_view : Object
110     {
111         public Gtk.TreeView el;
112         private Xcls_WindowLeftTree  _this;
113
114
115             // my vars (def)
116         public bool blockChanges;
117         public bool drag_in_motion;
118         public string lastEventSource;
119         public string dragData;
120         public bool button_is_pressed;
121         public bool key_is_pressed;
122         public int drag_x;
123         public int drag_y;
124         public string[] dropList;
125
126         // ctor
127         public Xcls_view(Xcls_WindowLeftTree _owner )
128         {
129             _this = _owner;
130             _this.view = this;
131             this.el = new Gtk.TreeView();
132
133             // my vars (dec)
134             this.blockChanges = false;
135             this.lastEventSource = "";
136             this.button_is_pressed = false;
137             this.key_is_pressed = false;
138
139             // set gobject values
140             this.el.expand = true;
141             this.el.tooltip_column = 1;
142             this.el.enable_tree_lines = true;
143             this.el.headers_visible = false;
144             var child_0 = new Xcls_model( _this );
145             child_0.ref();
146             this.el.set_model (  child_0.el  );
147             var child_1 = new Xcls_maincol( _this );
148             child_1.ref();
149             this.el.append_column (  child_1.el  );
150             var child_2 = new Xcls_TreeViewColumn8( _this );
151             child_2.ref();
152             this.el.append_column (  child_2.el  );
153
154             // init method
155
156             {
157                 var description = new Pango.FontDescription();
158                 description.set_size(8000);
159                 this.el.override_font(description);
160             
161                 var selection = this.el.get_selection();
162                 selection.set_mode( Gtk.SelectionMode.SINGLE);
163             
164             
165                 // is this really needed??
166                 /*
167                 this.selection.signal['changed'].connect(function() {
168                     _this.get('/LeftTree.view').listeners.cursor_changed.apply(
169                         _this.get('/LeftTree.view'), [ _this.get('/LeftTree.view'), '']
170                     );
171                 });
172                 */
173                 Gtk.drag_source_set (
174                     this.el,            /* widget will be drag-able */
175                     Gdk.ModifierType.BUTTON1_MASK,       /* modifier that will start a drag */
176                     BuilderApplication.targetList,            /* lists of target to support */
177                     Gdk.DragAction.COPY   | Gdk.DragAction.MOVE    |  Gdk.DragAction.LINK           /* what to do with data after dropped */
178                 );
179             
180                 // ?? needed??
181                 //Gtk.drag_source_add_text_targets(this.el); 
182             
183                 Gtk.drag_dest_set
184                 (
185                     this.el,              /* widget that will accept a drop */
186                     Gtk.DestDefaults.MOTION  | Gtk.DestDefaults.HIGHLIGHT,
187                     BuilderApplication.targetList,            /* lists of target to support */
188                     Gdk.DragAction.COPY   | Gdk.DragAction.MOVE   | Gdk.DragAction.LINK     /* what to do with data after dropped */
189                 );
190             
191                 //Gtk.drag_dest_set_target_list(this.el, Builder.Application.targetList);
192                 //Gtk.drag_dest_add_text_targets(this.el);
193                 
194                 
195                
196                 
197             }
198
199             //listeners
200             this.el.button_release_event.connect( (ev) => { 
201                 this.button_is_pressed = false;
202               return false;
203             });
204             this.el.button_press_event.connect( ( ev) => {
205                 //console.log("button press?");
206                 this.button_is_pressed = true;
207                 print("BUTTON DOWN\n");
208                 
209                 this.lastEventSource = "tree";
210                 if (! _this.before_node_change() ) {
211                 
212                    return true;
213                 }
214                 
215                 if (ev.type != Gdk.EventType.BUTTON_PRESS) {
216                         return false;
217                 }
218                 if (_this.model.el.iter_n_children(null) < 1) {
219                     _this.main_window.windowstate.showAddObject(_this.view.el);
220                     return true;
221                 }
222                 
223                
224                 Gtk.TreePath res;
225                 Gtk.TreeViewColumn col;
226                 if (!_this.view.el.get_path_at_pos((int)ev.x,(int)ev.y, out res, out col, null, null) ) {
227                     return true;
228                 }
229                 
230                 if (col.title == "Add") {
231                      _this.main_window.windowstate.leftTreeBeforeChange();
232                      this.el.get_selection().select_path(res);
233                         _this.main_window.windowstate.showAddObject(this.el);
234                         return true;
235                  }
236                 
237                 if (  ev.button != 3) {
238                     //print("click" + ev.type);
239                     return false;
240                  }
241                 _this.main_window.windowstate.leftTreeBeforeChange();
242             
243                 
244                  
245                 this.el.get_selection().select_path(res);
246                  
247                   
248                  
249                   //if (!this.get('/LeftTreeMenu').el)  { 
250                   //      this.get('/LeftTreeMenu').init(); 
251                   //  }
252                     
253                  _this.LeftTreeMenu.el.set_screen(Gdk.Screen.get_default());
254                  _this.LeftTreeMenu.el.show_all();
255                   _this.LeftTreeMenu.el.popup(null, null, null,  3, ev.time);
256                  //   print("click:" + res.path.to_string());
257                   return true;
258             });
259             this.el.cursor_changed.connect( ( ) => {
260                 print("LEFT TREE Cursor Changed\n");
261                 if (!this.button_is_pressed && !this.key_is_pressed) {
262                         // then event was started by some other action
263                         // which should manually trigger all the events..
264                         print("SKIPPING select - no button or key pressed\n");
265                         return;
266                 }
267             
268             
269                  if (this.blockChanges) { // probably not needed.. 
270                         print("SKIPPING select - blockchanges set..\n");     
271                    return  ;
272                  }
273                   if (!_this.before_node_change( ) ) {
274                      this.blockChanges = true;
275                      this.el.get_selection().unselect_all();
276                      this.blockChanges = false;
277                      
278                      return;
279                  }
280                  if (_this.main_window.windowstate.file == null) {
281                         print("SKIPPING select windowstate file is not set...\n");     
282                      return;
283                  } 
284                  
285                  //var render = this.get('/LeftTree').getRenderer();                
286                 print("LEFT TREE -> view -> selection changed called\n");
287                 
288                 
289                 // -- it appears that the selection is not updated.
290                   
291                 GLib.Timeout.add_full(GLib.Priority.DEFAULT,10 , () => {
292                      print("LEFT TREE -> view -> selection changed TIMEOUT CALLED\n");
293             
294                         if (this.el.get_selection().count_selected_rows() < 1) {
295             
296                             print("selected rows < 1\n");
297                             //??this.model.load( false);
298                             _this.node_selected(null, this.lastEventSource);
299                             
300                             return false ;
301                         }
302                             
303                             //console.log('changed');
304                         var s = this.el.get_selection();
305                          Gtk.TreeIter iter;
306                          Gtk.TreeModel mod;
307                         s.get_selected(out mod, out iter);
308                         
309                         
310                         // var val = "";
311                         GLib.Value value;
312                         _this.model.el.get_value(iter, 2, out value);
313                         _this.model.activePath = mod.get_path(iter).to_string();
314                         
315                         var node = (JsRender.Node)value.dup_object();
316                         print ("calling left_tree.node_selected\n");
317                         _this.node_selected(node, this.lastEventSource);
318                         while (Gtk.events_pending()) {
319                             Gtk.main_iteration();
320                        }
321                         var cp = mod.get_path(iter);
322                         Gtk.TreePath sp, ep;
323                         this.el.get_visible_range(out sp, out ep);
324                         // if sp is before cp then retuns 1.
325                         // if cp is before ep then retuns 1.
326                         if (cp.compare(sp) >= 0 && ep.compare(cp) >=1) {
327                             return false;
328                         }
329                         
330                          
331                         
332                         this.el.scroll_to_cell(new Gtk.TreePath.from_string(_this.model.activePath), null, true, 0.1f,0.0f);
333                         
334                         return false;
335                   });  
336                 //_this.after_node_change(node);
337             
338             //        _this.model.file.changed(node, "tree");
339                
340                 //Seed.print( value.get_string());
341                 return  ;
342                             
343             });
344             this.el.drag_begin.connect( ( ctx)  => {
345                 //print('SOURCE: drag-begin');
346                     
347                     
348                     //this.targetData = "";
349                     
350                     // find what is selected in our tree...
351                     
352                     var s = _this.view.el.get_selection();
353                     if (s.count_selected_rows() < 1) {
354                         return;
355                     }
356                     Gtk.TreeIter iter;
357                     Gtk.TreeModel mod;
358                     s.get_selected(out mod, out iter);
359             
360                     
361             
362                     // set some properties of the tree for use by the dropped element.
363                     GLib.Value value;
364                     _this.model.el.get_value(iter, 2, out value);
365                     var tp = mod.get_path(iter).to_string();
366                     var data = (JsRender.Node)(value.dup_object());
367                     var xname = data.fqn();
368                     print ("XNAME  IS " + xname+ "\n");
369                     this.dragData = tp;
370                     this.dropList = _this.main_window.windowstate.file.palete().getDropList(xname);
371                     
372                     print ("DROP LIST IS " + string.joinv(", ", this.dropList) + "\n");
373                     
374             
375                     // make the drag icon a picture of the node that was selected
376                 
377                     
378                 // by default returns the path..
379                    var path = _this.model.el.get_path(iter);
380             
381                      
382                     var pix = this.el.create_row_drag_icon ( path);
383                     
384                     Gtk.drag_set_icon_surface (ctx, pix) ;
385                     
386                     return;
387             });
388             this.el.drag_data_get.connect( ( drag_context, data, info, time) => {
389                         
390             
391                 //print("drag-data-get");
392                 var s = this.el.get_selection();
393                 if (s.count_selected_rows() < 1) {
394                         data.set_text("",0);     
395                          print("return empty string - no selection..");
396                         return;
397                 }
398             
399                 Gtk.TreeIter iter;
400                 Gtk.TreeModel mod;
401             
402                 s.get_selected(out mod, out iter);
403             
404             
405             
406                 GLib.Value value;
407                 _this.model.el.get_value(iter, 2, out value);
408                 var ndata = (JsRender.Node)(value.dup_object());
409             
410             
411             
412                 var tp = mod.get_path(iter).to_string();
413                 // by default returns the path..
414             
415                 if ( info != Gdk.Atom.intern("STRING",true) ) {
416                         tp = ndata.toJsonString();
417                 }   
418             
419                 //data.set_text(tp,tp.length);   
420             
421                 data.set (data.get_target (), 8, (uchar[]) tp.to_utf8 ());
422             
423             
424                 //  print("return " + tp);
425                 });
426             this.el.drag_end.connect( (drag_context) => {
427                 //Seed.print('LEFT-TREE: drag-end');
428                     this.dragData = "";
429                     this.dropList = null;
430             //        this.targetData = "";
431                     this.highlightDropPath("",0);
432             //        return true;
433             });
434             this.el.drag_motion.connect( ( ctx, x, y, time)  => {
435                print("got drag motion\n");
436                 var src = Gtk.drag_get_source_widget(ctx);
437                this.drag_x = x;
438                this.drag_y = y;     
439             
440                if (src != this.el) {
441                
442              
443              
444                 // the point of this is to detect where an item could be dropped..
445                     print("requesting drag data\n");
446                    this.drag_in_motion = true;
447                    
448                         // request data that will be recieved by the recieve...              
449                     Gtk.drag_get_data
450                     (
451                             this.el,         // will receive 'drag-data-received' signal 
452                             ctx,        // represents the current state of the DnD 
453                             Gdk.Atom.intern("STRING",true),    // the target type we want 
454                             time            // time stamp 
455                     );
456                     return true;
457               }    
458             
459             
460               print("action: %d\n", ctx.get_actions());
461              //print("GETTING POS");
462                 var  targetData = "";
463             
464                 Gtk.TreePath path;
465                 Gtk.TreeViewDropPosition pos;
466                 var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
467             
468                 // if there are not items in the tree.. the we have to set isOver to true for anything..
469                 var isEmpty = false;
470                 if (_this.model.el.iter_n_children(null) < 1) {
471                     print("got NO children?\n");
472                     isOver = true; //??? 
473                     isEmpty = true;
474                     pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
475                 }
476             
477             
478                 // ------------- a drag from self..
479             
480             
481                 //var action = Gdk.DragAction.COPY;
482                     // unless we are copying!!! ctl button..
483                 
484                 var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ?
485                              Gdk.DragAction.COPY  : Gdk.DragAction.MOVE ;
486                             // Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;
487             
488             
489                 if (_this.model.el.iter_n_children(null) < 1) {
490                     // no children.. -- asume it's ok..
491                     
492                     targetData = "|%d|".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
493                        
494                     this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);        
495                     Gdk.drag_status(ctx, action ,time);
496                     return true;
497                     
498                     // continue through to allow drop...
499             
500                 } 
501                     
502                     
503             
504                 
505                 
506                 //print("ISOVER? " + isOver);
507                 if (!isOver) {
508               
509                     Gdk.drag_status(ctx, 0 ,time);
510                      this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);                    
511                      return false;
512             
513                 }
514                         
515                 // drag node is parent of child..
516                 //console.log("SRC TREEPATH: " + src.treepath);
517                 //console.log("TARGET TREEPATH: " + data.path.to_string());
518                 
519                 // nned to check a  few here..
520                 //Gtk.TreeViewDropPosition.INTO_OR_AFTER
521                 //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
522                 //Gtk.TreeViewDropPosition.AFTER
523                 //Gtk.TreeViewDropPosition.BEFORE
524                 
525                 // locally dragged items to not really use the 
526                 var selection_text = this.dragData;
527                 
528                         
529                         
530                 if (selection_text == null || selection_text.length < 1) {
531                             //print("Error  - drag selection text returned NULL");
532                          Gdk.drag_status(ctx, 0 ,time);
533                         this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
534                          return false;
535                  }
536                                    
537                         
538                         // see if we are dragging into ourself?
539                 var target_path = path.to_string();            
540                 print ("Drag  %s onto %s--%d\n ", selection_text, target_path, pos);
541                 
542                 // pos : 3 = ontop - 0 = after, 1 = before
543                 //print("target_path="+target_path);
544             
545                 // 
546                 if (selection_text  == target_path) {
547                     print("self drag ?? == we should perhaps allow copy onto self..\n");
548                             
549                      Gdk.drag_status(ctx, 0 ,time);
550                       this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
551                       return false;
552             //                 -- fixme -- this is not really correct..
553             
554                 }
555                         
556                 // check that 
557                 //print("DUMPING DATA");
558                 //console.dump(data);
559                 // path, pos
560                 
561                 //print(data.path.to_string() +' => '+  data.pos);
562                 
563                 // dropList is a list of xtypes that this node could be dropped on.
564                 // it is set up when we start to drag..
565                 
566                 
567                 targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);
568                     
569                 print("targetDAta: " + targetData +"\n");
570                 
571                 if (targetData.length < 1) {
572                     //print("Can not find drop node path");
573                    
574                     Gdk.drag_status(ctx, 0, time);
575                     this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
576                     return false;
577                 }
578                 
579                 var td_ar = targetData.split("|");
580                   
581                 
582             
583                 Gdk.drag_status(ctx, action ,time);
584                 this.highlightDropPath(td_ar[0], (Gtk.TreeViewDropPosition)int.parse(td_ar[1]));
585                 return true;
586                    
587                    
588             });
589             this.el.key_press_event.connect( (ev) => {
590                this.key_is_pressed = true;
591                 return false;
592             });
593             this.el.key_release_event.connect( (ev) => {
594                    this.key_is_pressed = false;
595                   return false;
596             });
597             this.el.drag_data_received.connect( (ctx, x, y, sel, info, time)  => {
598             
599                 // THIS CODE ONLY RELATES TO drag  or drop of "NEW" elements or "FROM another tree.."
600             
601             
602                 //  print("Tree: drag-data-received\n");
603                 var selection_text = (string)sel.get_data();
604                 //print("selection_text= %s\n",selection_text);
605             
606                 var is_drag = this.drag_in_motion;
607             
608             
609             
610                 GLib.debug("Is Drag %s\n", is_drag ? "Y": "N");
611                 var  targetData = "";
612             
613                 Gtk.TreePath path;
614                 Gtk.TreeViewDropPosition pos;
615                 var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
616             
617                 // if there are not items in the tree.. the we have to set isOver to true for anything..
618                 var isEmpty = false;
619                 if (_this.model.el.iter_n_children(null) < 1) {
620                         GLib.debug("got NO children?\n");
621                         isOver = true; //??? 
622                         isEmpty = true;
623                         pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
624                 }
625             
626             
627                 //console.log("LEFT-TREE: drag-motion");
628                 var src = Gtk.drag_get_source_widget(ctx);
629             
630                 // a drag from self - this should be handled by drop and motion.
631                 if (src == this.el) {
632                         GLib.debug("Source == this element should not happen.. ? \n");
633                         return;
634                 }
635                 //print("drag_data_recieved from another element");
636             
637                  
638             
639             
640                 if (selection_text == null || selection_text.length < 1 || !isOver) {
641                         // nothing valid foudn to drop...
642                            GLib.debug("empty sel text or not over");
643                         if (is_drag) {
644                             Gdk.drag_status(ctx, 0, time);
645                             this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
646                             return;
647                         }
648                         Gtk.drag_finish (ctx, false, false, time);        // drop failed..
649                         // no drop action...
650                         return;            
651             
652                 }
653                 var dropNode = new JsRender.Node(); 
654             
655                 var dropNodeType  = selection_text;
656                 var show_templates = true;
657                 // for drop
658                 if (dropNodeType[0] == '{') {
659                         var pa = new Json.Parser();
660                         try {
661                             pa.load_from_data(dropNodeType);
662                         } catch (Error e) {
663                             Gtk.drag_finish (ctx, false, false, time);        // drop failed..
664                             // no drop action...
665                             return;   
666                         }
667                          
668                         dropNode.loadFromJson( pa.get_root().get_object(), 2);
669                         dropNodeType = dropNode.fqn();
670                         show_templates = false;
671                         
672                         
673                 } else {
674                         // drop with property.
675                         if (selection_text.contains(":")) {
676                                 var bits = selection_text.split(":");
677                             dropNode.setFqn(bits[0]);
678                             dropNode.set_prop(new JsRender.NodeProp.special("prop", bits[1]));
679                             
680                             
681                             
682                         } else {
683                             dropNode.setFqn(selection_text);
684                         }
685                 }
686             
687                  
688                 // dropList --- need to gather this ... 
689                 GLib.debug("get dropList for : %s\n",dropNodeType);            
690                 var dropList = _this.main_window.windowstate.file.palete().getDropList(dropNodeType);
691             
692                 GLib.debug("dropList: %s\n", string.joinv(" , ", dropList));
693             
694                 // if drag action is link ... then we can drop it anywahere...
695                  if ((ctx.get_actions() & Gdk.DragAction.LINK) > 0) {
696                          // if path is null?? dragging into an empty tree?
697                          targetData = (path == null ? "" :  path.to_string()) + "|%d".printf((int)pos);
698                  } else {
699             
700             
701                         targetData = _this.model.findDropNodeByPath( isEmpty ? "" : path.to_string(), dropList, pos);
702                  }
703             
704             
705                         
706                 GLib.debug("targetDAta: %s", targetData );
707             
708                 if (targetData.length < 1) {
709                  
710                         // invalid drop path..
711                         if (this.drag_in_motion) {
712                             Gdk.drag_status(ctx, 0, time);
713                             this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
714                             return;
715                         }
716                         Gtk.drag_finish (ctx, false, false, time);        // drop failed..
717                         // no drop action...
718                         return;
719                 }
720             
721             
722             
723                  var td_ar = targetData.split("|");
724                   
725             
726                 if (this.drag_in_motion) { 
727                         Gdk.drag_status(ctx, Gdk.DragAction.COPY ,time);
728             
729                         this.highlightDropPath(  td_ar[0]  , (Gtk.TreeViewDropPosition)int.parse(td_ar[1]));
730                         return;
731                 }
732                 // continue on to allow drop..
733             
734             
735                 // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..
736                 //targetData
737                 //   {parent}|{pos}|{prop}
738             
739             
740                _this.model.dropNode(targetData, dropNode, show_templates);
741                 
742                 GLib.debug("ADD new node!!!\n");
743                         
744                 ///Xcls_DialogTemplateSelect.singleton().show( _this.model.file.palete(), node);
745             
746                 Gtk.drag_finish (ctx, false, false,time);
747             
748             
749                         
750                         
751             
752             });
753             this.el.drag_drop.connect( (  ctx, x, y, time)  => {
754                   //Seed.print("TARGET: drag-drop");
755                
756                
757                 var src = Gtk.drag_get_source_widget(ctx);
758                  
759                if (src != this.el) {
760                
761                 
762                    
763                    this.drag_in_motion = false;   
764                         // request data that will be recieved by the recieve...              
765                     Gtk.drag_get_data
766                     (
767                             this.el,         // will receive 'drag-data-received' signal 
768                             ctx,        // represents the current state of the DnD 
769                             Gdk.Atom.intern("application/json",true),    // the target type we want 
770                             time            // time stamp 
771                     );
772             
773                      
774                     // No target offered by source => error
775                
776             
777                      return  false;
778                  }
779                  
780                  // handle drop around self..
781                  
782                               
783                         
784                 //print("GETTING POS");
785                 var  targetData = "";
786                 
787                 Gtk.TreePath path;
788                 Gtk.TreeViewDropPosition pos;
789                 var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
790                 
791                 // if there are not items in the tree.. the we have to set isOver to true for anything..
792                 var isEmpty = false;
793                 if (_this.model.el.iter_n_children(null) < 1) {
794                     print("got NO children?\n");
795                     isOver = true; //??? 
796                     isEmpty = true;
797                     pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
798                 }
799                 
800                  
801                  
802                 //var action = Gdk.DragAction.COPY;
803                     // unless we are copying!!! ctl button..
804                 
805                 var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ?
806                              Gdk.DragAction.COPY  : Gdk.DragAction.MOVE ;
807                             // Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;
808             
809                   
810                 if (_this.model.el.iter_n_children(null) < 1) {
811                     // no children.. -- asume it's ok..
812                     
813                     targetData = "|%d|".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
814                      
815                     // continue through to allow drop...
816             
817                 } else {
818                             
819                             
820                 
821                             
822                             
823                             //print("ISOVER? " + isOver);
824                     if (!isOver) {
825                         
826                         Gtk.drag_finish (ctx, false, false, time);        // drop failed..
827                         return true; // not over apoint!?! - no action on drop or motion..
828                     }
829                             
830                     // drag node is parent of child..
831                     //console.log("SRC TREEPATH: " + src.treepath);
832                     //console.log("TARGET TREEPATH: " + data.path.to_string());
833                     
834                     // nned to check a  few here..
835                     //Gtk.TreeViewDropPosition.INTO_OR_AFTER
836                     //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
837                     //Gtk.TreeViewDropPosition.AFTER
838                     //Gtk.TreeViewDropPosition.BEFORE
839                     
840                     // locally dragged items to not really use the 
841                     var selection_text = this.dragData;
842                     
843                     
844                     
845                     if (selection_text == null || selection_text.length < 1) {
846                         //print("Error  - drag selection text returned NULL");
847                       
848                          Gtk.drag_finish (ctx, false, false, time);        // drop failed..
849                          return true; /// -- fixme -- this is not really correct..
850                     }                
851                             
852                             // see if we are dragging into ourself?
853                             print ("got selection text of  " + selection_text);
854                     
855                     var target_path = path.to_string();
856                     //print("target_path="+target_path);
857             
858                     // 
859                     if (selection_text  == target_path) {
860                         print("self drag ?? == we should perhaps allow copy onto self..\n");
861                         
862                          Gtk.drag_finish (ctx, false, false, time);        // drop failed..
863             
864                          return true; /// -- fixme -- this is not really correct..
865             
866                     }
867                             
868                     // check that 
869                     //print("DUMPING DATA");
870                     //console.dump(data);
871                     // path, pos
872                     
873                     //print(data.path.to_string() +' => '+  data.pos);
874                     
875                     // dropList is a list of xtypes that this node could be dropped on.
876                     // it is set up when we start to drag..
877                     
878                     
879                     targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);
880                         
881                     print("targetDAta: " + targetData +"\n");
882                     
883                     if (targetData.length < 1) {
884                         //print("Can not find drop node path");
885                          
886                         Gtk.drag_finish (ctx, false, false, time);        // drop failed..
887                         return true;
888                     }
889                                 
890                             
891                             
892                             // continue on to allow drop..
893               }
894                     // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..
895             
896             
897                  var delete_selection_data = false;
898                     
899                 if (action == Gdk.DragAction.ASK)  {
900                     /* Ask the user to move or copy, then set the ctx action. */
901                 }
902             
903                 if (action == Gdk.DragAction.MOVE) {
904                     delete_selection_data = true;
905                 }
906                   
907                             // drag around.. - reorder..
908                 _this.model.moveNode(targetData, action);
909                     
910                    
911                     
912                     
913                     
914                     // we can send stuff to souce here...
915             
916             
917             // do we always say failure, so we handle the reall drop?
918                 Gtk.drag_finish (ctx, false, false,time); //delete_selection_data, time);
919             
920                 return true;
921              
922              
923              
924              
925              
926              
927             });
928         }
929
930         // user defined functions
931         public void highlightDropPath ( string treepath, Gtk.TreeViewDropPosition pos) {
932         
933                 // highlighting for drag/drop
934                 if (treepath.length > 0) {
935                     this.el.set_drag_dest_row(  new  Gtk.TreePath.from_string( treepath ), pos);
936                   } else {
937                     this.el.set_drag_dest_row(null, Gtk.TreeViewDropPosition.INTO_OR_AFTER);
938                  }
939                      
940         }
941         public void selectNode (string treepath_str, string source) {
942                 this.lastEventSource = source;
943             //this.selection.select_path(new  Gtk.TreePath.from_string( treepath_str));
944              var tp = new Gtk.TreePath.from_string(treepath_str);
945              
946              this.el.set_cursor(tp, null, false);  
947              this.el.scroll_to_cell(tp, null, false, 0,0);
948         }
949         public void setCursor (string treepath, string sourceEvent)   {
950                 this.lastEventSource = sourceEvent;
951                 //this.blockChanges = true; << block changes prevents loading of 'node data' and firing of node_selected..
952             this.el.set_cursor(new Gtk.TreePath.from_string(treepath), null, false); 
953             // fire node_selected..
954             //this.blockChanges = false;
955                 this.lastEventSource = "";
956         }
957     }
958     public class Xcls_model : Object
959     {
960         public Gtk.TreeStore el;
961         private Xcls_WindowLeftTree  _this;
962
963
964             // my vars (def)
965         public DialogTemplateSelect template_select;
966         public string activePath;
967
968         // ctor
969         public Xcls_model(Xcls_WindowLeftTree _owner )
970         {
971             _this = _owner;
972             _this.model = this;
973             this.el = new Gtk.TreeStore.newv(  { typeof(string),
974 typeof(string),
975 typeof(Object),
976 typeof(Gdk.Pixbuf),
977 typeof(Gdk.Pixbuf) }  );
978
979             // my vars (dec)
980             this.template_select = null;
981             this.activePath = "";
982
983             // set gobject values
984
985             // init method
986
987             print("model initialized");
988         }
989
990         // user defined functions
991         public void loadFile (JsRender.JsRender f) {
992             //console.dump(f);
993             this.el.clear();
994             _this.main_window.windowstate.leftTreeNodeSelected(null, "");
995             // needed???
996             _this.main_window.windowstate.file = f;
997             
998            
999             if (f.tree == null) {
1000                     try {
1001                         f.loadItems( );
1002                 } catch (Error e) {
1003                         return;
1004                 }
1005             }
1006             // if it's still null?
1007             if (f.tree == null) {
1008                         _this.main_window.windowstate.showAddObject(_this.view.el);
1009             
1010                 return;
1011             }
1012           
1013             var o = new Gee.ArrayList<JsRender.Node>();
1014             o.add(f.tree);
1015             this.load(o,null);
1016             
1017             _this.view.el.expand_all();
1018         
1019             if (f.tree.items.size < 1) {
1020                 // single item..
1021                 
1022                 //this.get('/Window.leftvpaned').el.set_position(80);
1023                 // select first...
1024                 _this.view.el.set_cursor( 
1025                     new  Gtk.TreePath.from_string("0"), null, false);
1026                 
1027                 
1028             } else {
1029                   //this.get('/Window.leftvpaned').el.set_position(200);
1030             }
1031             
1032             
1033             while (Gtk.events_pending()) {
1034                 Gtk.main_iteration();
1035            }
1036         
1037             _this.maincol.el.set_max_width(_this.viewwin.el.get_allocated_width() - 32);
1038          
1039             
1040            
1041             return;
1042          
1043                     
1044         }
1045         public string findDropNodeByPath (string treepath_str, string[] targets, int in_pref = -1) {
1046         
1047             var path = treepath_str; // dupe it..
1048             
1049             
1050             // pref : 3 = ontop - 0 = after, 1 = before
1051             int pref = in_pref < 0  ?  Gtk.TreeViewDropPosition.INTO_OR_AFTER : in_pref;
1052             
1053             var last = "";
1054             
1055             //console.dump(this.treemap);
1056             
1057             print("findDropNodeByPath : got path length %d / %s\n", path.length, path);
1058             
1059             if (path.length == 0) {
1060                 // top drop. // just return empty..
1061                 return "|%d".printf((int)pref) ;
1062                 
1063             }
1064             
1065             
1066             while (path.length > 0) {
1067             
1068                 if (path.length == treepath_str.length && pref != Gtk.TreeViewDropPosition.INTO_OR_AFTER) {
1069                     if (path.last_index_of(":") < 0 ) {
1070                         return "";
1071                     }
1072                     path = path.substring(0, path.last_index_of(":"));
1073                     last = treepath_str;
1074                     print("DROP  before or after : using %s\n",path);
1075                     continue;
1076                 }
1077             
1078                 //print("LOOKING FOR PATH: " + path);
1079                 var node_data = this.pathToNode(path);
1080                 
1081                 if (node_data == null) {
1082                     print("node not found");
1083                     return "";
1084                 }
1085                 
1086                 var xname = node_data.fqn();
1087                 var match = "";
1088                 var prop = "";
1089                 
1090                 for (var i =0; i < targets.length; i++)  {
1091                     var tg = targets[i];
1092                     if ((tg == xname)  ) {
1093                         match = tg;
1094                         break;
1095                     }
1096                     // if target is "xxxx:name"
1097                     if (tg.contains(xname +":")) {
1098                         match = tg;
1099                         var ar = tg.split(":");
1100                         prop = ar[1];
1101                         break;
1102                     }
1103                 }
1104                 
1105                 if (match.length > 0) {
1106                     if (last.length > 0) { // pref is after/before..
1107                         // then it's after last
1108                         //if (pref > 1) {
1109                         //    return "";
1110                         //}
1111                         return last + "|%d".printf((int)pref) + "|" + prop;
1112         
1113                         
1114                     }
1115                     // we need to add prop - as :store -> needs to bee added when dropping onto.
1116                     return path + "|%d".printf( (int) Gtk.TreeViewDropPosition.INTO_OR_AFTER)  + "|" + prop;
1117                 }
1118                 /*
1119                 last = "" + path;
1120                 var par = path.split(":");
1121                 string [] ppar = {};
1122                 for (var i = 0; i < par.length-1; i++) {
1123                     ppar += par[i];
1124                 }
1125                 
1126                 path = string.joinv(":", ppar);
1127                 */
1128                 break;
1129         
1130             }
1131             
1132             return "";
1133                     
1134         }
1135         public void iterSetValues (Gtk.TreeIter iter, JsRender.Node node)   {
1136                 var ic = Gtk.IconTheme.get_default();
1137             Gdk.Pixbuf pix;
1138             
1139             var o =   GLib.Value(typeof(Object));
1140             o.set_object((Object)node);
1141             var clsname = node.fqn();
1142             
1143             var clsb = clsname.split(".");
1144             var sub = clsb.length > 1 ? clsb[1].down()  : "";
1145             
1146             var addi =  ic.load_icon("list-add", 16,0);
1147             var fn = "/usr/share/glade/pixmaps/hicolor/16x16/actions/widget-gtk-" + sub + ".png";
1148             if (FileUtils.test (fn, FileTest.IS_REGULAR)) {
1149                 pix = new Gdk.Pixbuf.from_file (fn);
1150             } else {
1151                 pix = ic.load_icon("emblem-new", 16,0);
1152             }
1153             
1154             this.el.set(
1155                         iter, 
1156                         0, node.nodeTitle(),
1157                     1, node.nodeTip(), 
1158                     -1
1159             );
1160             this.el.set_value(iter, 2,o);
1161             this.el.set_value(iter, 3,pix);    
1162                 this.el.set_value(iter, 4,addi);   
1163             
1164         
1165         }
1166         public string treePathFromNode (JsRender.Node node) {
1167             // iterate through the tree and find the node
1168             var ret = "";
1169             
1170             this.el.foreach((mod, pth, iter) => {
1171                 // get the node..
1172               
1173              
1174                  GLib.Value value;
1175                  _this.model.el.get_value(iter, 2, out value);
1176                  
1177         
1178                  
1179                  var n = (JsRender.Node)value;
1180         
1181                  print("compare %s to %s\n", n.fqn(), node.fqn());
1182                 if (node == n) {
1183                     ret = pth.to_string();
1184                     return true;
1185                 }
1186                 return false;
1187             });
1188             return ret;
1189         
1190         }
1191         public void deleteSelected () {
1192             
1193             print("DELETE SELECTED?");
1194             //_this.view.blockChanges = true;
1195             print("GET SELECTION?");
1196         
1197             var s = _this.view.el.get_selection();
1198             
1199             print("GET  SELECTED?");
1200            Gtk.TreeIter iter;
1201             Gtk.TreeModel mod;
1202         
1203             
1204             if (!s.get_selected(out mod, out iter)) {
1205                 return; // nothing seleted..
1206             }
1207               
1208         
1209         
1210             this.activePath= "";      
1211             print("GET  vnode value?");
1212         
1213             GLib.Value value;
1214             this.el.get_value(iter, 2, out value);
1215             var data = (JsRender.Node)(value.get_object());
1216             print("removing node from Render\n");
1217             if (data.parent == null) {
1218                _this.main_window.windowstate.file.tree = null;
1219             } else {
1220                 data.remove();
1221             }
1222             print("removing node from Tree\n");    
1223             s.unselect_all();
1224             this.el.remove(ref iter);
1225         
1226             
1227             
1228             
1229             // 
1230             
1231             
1232         
1233         
1234             this.activePath= ""; // again!?!?      
1235             //this.changed(null,true);
1236             
1237             _this.changed();
1238             
1239             _this.view.blockChanges = false;
1240         }
1241         public void dropNode (string target_data_str, JsRender.Node node, bool show_templates) {
1242         //         print("drop Node");
1243              // console.dump(node);
1244           //    console.dump(target_data);
1245           
1246                         //target_data_str
1247                         //   {parent}|{pos}|{prop}
1248           
1249           
1250                 // 0 = before , 1=after 2/3 onto
1251           
1252                         GLib.debug("dropNode %s", target_data_str);
1253                 
1254                 var target_data= target_data_str.split("|");
1255           
1256                 var parent_str = target_data[0].length > 0 ? target_data[0] : "";
1257                 var pos = target_data.length > 1 ? int.parse(target_data[1]) : 2; // ontop..
1258           
1259           
1260                 Gtk.TreePath tree_path  =   parent_str.length > 0 ? new  Gtk.TreePath.from_string( parent_str ) : null;
1261                 
1262                 
1263                 
1264                 //print("add " + tp + "@" + target_data[1]  );
1265                 
1266                 JsRender.Node parentNode = null;
1267                 
1268                 Gtk.TreeIter iter_after;
1269                 Gtk.TreeIter iter_par ;
1270                 
1271                 // this appears to be done in drag_ddata_recieved as well.
1272                  if (target_data.length == 3 && target_data[2].length > 0) {
1273                          node.set_prop(new JsRender.NodeProp.special("prop", target_data[2]));
1274         
1275                 }
1276         
1277                 Gtk.TreePath expand_parent = null;
1278                 
1279                 // we only need to show the template if it's come from else where?
1280                  if (show_templates) {
1281                  
1282                      var ts = _this.main_window.windowstate.template_select;
1283                  
1284                      var new_node = ts.show(
1285                           _this.main_window, // (Gtk.Window) _this.el.get_toplevel (),
1286                          _this.main_window.windowstate.file.palete(),
1287                             node,
1288                             _this.main_window.windowstate.project);
1289                            
1290                      if (new_node == null) {
1291                          return; // do not add?
1292                      }
1293                      node = new_node;
1294                 }        
1295                 
1296                  //print("pos is %d  \n".printf(pos));
1297                 
1298                  Gtk.TreeIter n_iter; 
1299                  
1300                  if ( parent_str.length < 1) {
1301                       this.el.append(out n_iter, null); // drop at top level..
1302                       node.parent = null;
1303                       _this.main_window.windowstate.file.tree = node;
1304                       
1305                       
1306                 } else   if (pos  < 2) {
1307                     //print(target_data[1]  > 0 ? 'insert_after' : 'insert_before');
1308                     
1309                     this.el.get_iter(out iter_after, tree_path );            
1310                     this.el.iter_parent(out iter_par, iter_after);
1311                     expand_parent = this.el.get_path(iter_par);
1312                     
1313                     
1314                     // not sure why all the 'dup_object()' stuff? did it crash before?
1315                     GLib.Value value;
1316                     this.el.get_value( iter_par, 2, out value);
1317                     parentNode =  (JsRender.Node)value.dup_object();
1318                     
1319                     
1320                     this.el.get_value( iter_after, 2, out value);
1321                     var relNode =  (JsRender.Node)value.dup_object();
1322                     
1323                     if ( pos  > 0 ) {
1324                      
1325                         this.el.insert_after(out n_iter,    iter_par  , iter_after);
1326                         var ix = parentNode.items.index_of(relNode);
1327                         parentNode.items.insert(ix+1, node);
1328                         
1329                     } else {
1330                         this.el.insert_before(out n_iter,  iter_par  , iter_after);
1331                         var ix = parentNode.items.index_of(relNode);
1332                         parentNode.items.insert(ix, node);
1333          
1334                     }
1335                     node.parent = parentNode;
1336                     
1337                     
1338                     
1339                 } else {
1340                    //  print("appending to  " + parent_str);
1341                     this.el.get_iter(out iter_par, tree_path);
1342                     this.el.append(out n_iter,   iter_par );
1343                     expand_parent = this.el.get_path(iter_par);
1344                     
1345                     GLib.Value value;
1346                     this.el.get_value( iter_par, 2, out value);
1347                     parentNode =  (JsRender.Node)value.dup_object();
1348                     node.parent = parentNode;
1349                     parentNode.items.add(node);
1350                 }
1351                 
1352                 
1353                 
1354                 
1355                 // work out what kind of packing to use.. -- should be in 
1356                
1357                     
1358                     //_this.main_window.windowstate.file.palete().fillPack(node,parentNode);
1359                 _this.main_window.windowstate.file.palete().on_child_added(parentNode,node);
1360                     
1361                   
1362                 this.iterSetValues(n_iter, node);
1363                 // add the node...
1364                  
1365                 
1366                 
1367                         // load children - if it has any..
1368               
1369                 if (node.items.size > 0) {
1370                     this.load(node.items, n_iter);
1371                     _this.view.el.expand_row(this.el.get_path(n_iter), true);
1372                 } else if (expand_parent != null && !_this.view.el.is_row_expanded(expand_parent)) {
1373                    _this.view.el.expand_row(expand_parent,true);
1374                 }
1375         
1376                 //if (tp != null && (node.items.length() > 0 || pos > 1)) {
1377                 //    _this.view.el.expand_row(this.el.get_path(iter_par), true);
1378                // }
1379                 // wee need to get the empty proptypes from somewhere..
1380                 
1381                 //var olditer = this.activeIter;
1382                 this.activePath = this.el.get_path(n_iter).to_string();
1383         
1384         
1385                 // pretend button was pressed, so that we can trigger select node...
1386                 _this.view.button_is_pressed = true;
1387                 _this.view.lastEventSource = "";
1388                 _this.view.el.set_cursor(this.el.get_path(n_iter), null, false);
1389                 _this.view.button_is_pressed = false;
1390                 _this.changed();
1391              
1392                 
1393                     
1394         }
1395         public void moveNode (string target_data, Gdk.DragAction action) 
1396         {
1397            
1398            /// target_data = "path|pos");
1399            
1400            
1401             //print("MOVE NODE");
1402             // console.dump(target_data);
1403             Gtk.TreeIter old_iter;
1404             Gtk.TreeModel mod;
1405             
1406             var s = _this.view.el.get_selection();
1407             s.get_selected(out mod , out old_iter);
1408             mod.get_path(old_iter);
1409             
1410             var node = this.pathToNode(mod.get_path(old_iter).to_string());
1411             //console.dump(node);
1412             if (node == null) {
1413                 GLib.debug("moveNode: ERROR - node is null?");
1414             }
1415             
1416             
1417         
1418             // needs to drop first, otherwise the target_data 
1419             // treepath will be invalid.
1420         
1421             
1422             if ((action & Gdk.DragAction.MOVE) > 0) {
1423                     GLib.debug("REMOVING OLD NODE : " + target_data + "\n");
1424                     node.remove();
1425                     this.dropNode(target_data, node, false);
1426                     this.el.remove(ref old_iter);
1427                     
1428                     
1429                                  
1430             } else {
1431                 GLib.debug("DROPPING NODE // copy: " + target_data + "\n");
1432                 node = node.deepClone();
1433                 this.dropNode(target_data, node, false);
1434             }
1435             _this.changed();
1436             this.activePath= "";
1437             //this.updateNode(false,true);
1438         }
1439         public void updateSelected () {
1440           
1441            
1442             var s = _this.view.el.get_selection();
1443             
1444              Gtk.TreeIter iter;
1445             Gtk.TreeModel mod;
1446             
1447             
1448             
1449             if (!s.get_selected(out mod, out iter)) {
1450                 return; // nothing seleted..
1451             }
1452           
1453           GLib.Value value;
1454             this.el.get_value(iter, 2, out value);
1455             var node = (JsRender.Node)(value.get_object());
1456             
1457               this.el.set(iter, 0, node.nodeTitle(),
1458                         1, node.nodeTip(), -1
1459                 );
1460         }
1461         public string findDropNode (string treepath_str, string[] targets) {
1462         
1463             // this is used by the dragdrop code in the roo version AFAIR..
1464         
1465             //var path = treepath_str.replace(/^builder-/, '');
1466             // treemap is depreciated... - should really check if model has any entries..
1467         
1468             if (this.el.iter_n_children(null) < 1) {
1469                 //print("NO KEYS");
1470                 return "|%d".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
1471             }
1472             //print("FIND treepath: " + path);
1473             //console.dump(this.treemap);
1474             
1475             //if (!treepath_str.match(/^builder-/)) {
1476             //    return []; // nothing!
1477             //}
1478             if (targets.length > 0 && targets[0] == "*") {
1479                 return  treepath_str;
1480             }
1481             return this.findDropNodeByPath(treepath_str,targets, -1);
1482         }
1483         public void load (Gee.ArrayList<JsRender.Node> tr, Gtk.TreeIter? iter) 
1484         {
1485             
1486                 
1487             Gtk.TreeIter citer;
1488             //this.insert(citer,iter,0);
1489            
1490             
1491             for(var i =0 ; i < tr.size; i++) {
1492                 if (iter != null) {
1493                     this.el.insert(out citer,iter,-1); // why not append?
1494                 } else {
1495                     this.el.append(out citer,null);
1496                 }
1497                 this.iterSetValues(citer, tr.get(i));
1498                 
1499          
1500                  
1501                 if (tr.get(i).items.size > 0) {
1502                     this.load(tr.get(i).items, citer);
1503                 }
1504              
1505             }
1506         
1507             
1508         }
1509         public JsRender.Node pathToNode (string path) {
1510          
1511              
1512              Gtk.TreeIter   iter;
1513              _this.model.el.get_iter_from_string(out iter, path);
1514              
1515              GLib.Value value;
1516              _this.model.el.get_value(iter, 2, out value);
1517              
1518              return (JsRender.Node)value.dup_object();
1519         
1520         }
1521     }
1522
1523     public class Xcls_maincol : Object
1524     {
1525         public Gtk.TreeViewColumn el;
1526         private Xcls_WindowLeftTree  _this;
1527
1528
1529             // my vars (def)
1530
1531         // ctor
1532         public Xcls_maincol(Xcls_WindowLeftTree _owner )
1533         {
1534             _this = _owner;
1535             _this.maincol = this;
1536             this.el = new Gtk.TreeViewColumn();
1537
1538             // my vars (dec)
1539
1540             // set gobject values
1541             this.el.title = "Node";
1542             this.el.sizing = Gtk.TreeViewColumnSizing.FIXED;
1543             this.el.expand = true;
1544             this.el.resizable = true;
1545             var child_0 = new Xcls_iconrender( _this );
1546             child_0.ref();
1547             this.el.pack_start (  child_0.el , false );
1548             var child_1 = new Xcls_renderer( _this );
1549             child_1.ref();
1550             this.el.pack_start (  child_1.el , true );
1551
1552             // init method
1553
1554             this.el.add_attribute(_this.renderer.el , "markup", 0 );
1555               this.el.add_attribute(_this.iconrender.el , "pixbuf",  3 );
1556         }
1557
1558         // user defined functions
1559     }
1560     public class Xcls_iconrender : Object
1561     {
1562         public Gtk.CellRendererPixbuf el;
1563         private Xcls_WindowLeftTree  _this;
1564
1565
1566             // my vars (def)
1567
1568         // ctor
1569         public Xcls_iconrender(Xcls_WindowLeftTree _owner )
1570         {
1571             _this = _owner;
1572             _this.iconrender = this;
1573             this.el = new Gtk.CellRendererPixbuf();
1574
1575             // my vars (dec)
1576
1577             // set gobject values
1578             this.el.width = 16;
1579         }
1580
1581         // user defined functions
1582     }
1583
1584     public class Xcls_renderer : Object
1585     {
1586         public Gtk.CellRendererText el;
1587         private Xcls_WindowLeftTree  _this;
1588
1589
1590             // my vars (def)
1591
1592         // ctor
1593         public Xcls_renderer(Xcls_WindowLeftTree _owner )
1594         {
1595             _this = _owner;
1596             _this.renderer = this;
1597             this.el = new Gtk.CellRendererText();
1598
1599             // my vars (dec)
1600
1601             // set gobject values
1602         }
1603
1604         // user defined functions
1605     }
1606
1607
1608     public class Xcls_TreeViewColumn8 : Object
1609     {
1610         public Gtk.TreeViewColumn el;
1611         private Xcls_WindowLeftTree  _this;
1612
1613
1614             // my vars (def)
1615
1616         // ctor
1617         public Xcls_TreeViewColumn8(Xcls_WindowLeftTree _owner )
1618         {
1619             _this = _owner;
1620             this.el = new Gtk.TreeViewColumn();
1621
1622             // my vars (dec)
1623
1624             // set gobject values
1625             this.el.max_width = 24;
1626             this.el.title = "Add";
1627             this.el.sizing = Gtk.TreeViewColumnSizing.FIXED;
1628             this.el.expand = false;
1629             var child_0 = new Xcls_addiconrender( _this );
1630             child_0.ref();
1631             this.el.pack_start (  child_0.el , true );
1632
1633             // init method
1634
1635             this.el.add_attribute(_this.addiconrender.el , "pixbuf",  4 );
1636         }
1637
1638         // user defined functions
1639     }
1640     public class Xcls_addiconrender : Object
1641     {
1642         public Gtk.CellRendererPixbuf el;
1643         private Xcls_WindowLeftTree  _this;
1644
1645
1646             // my vars (def)
1647
1648         // ctor
1649         public Xcls_addiconrender(Xcls_WindowLeftTree _owner )
1650         {
1651             _this = _owner;
1652             _this.addiconrender = this;
1653             this.el = new Gtk.CellRendererPixbuf();
1654
1655             // my vars (dec)
1656
1657             // set gobject values
1658             this.el.width = 16;
1659         }
1660
1661         // user defined functions
1662     }
1663
1664
1665
1666     public class Xcls_LeftTreeMenu : Object
1667     {
1668         public Gtk.Menu el;
1669         private Xcls_WindowLeftTree  _this;
1670
1671
1672             // my vars (def)
1673
1674         // ctor
1675         public Xcls_LeftTreeMenu(Xcls_WindowLeftTree _owner )
1676         {
1677             _this = _owner;
1678             _this.LeftTreeMenu = this;
1679             this.el = new Gtk.Menu();
1680
1681             // my vars (dec)
1682
1683             // set gobject values
1684             var child_0 = new Xcls_MenuItem11( _this );
1685             child_0.ref();
1686             this.el.add (  child_0.el  );
1687             var child_1 = new Xcls_MenuItem12( _this );
1688             child_1.ref();
1689             this.el.add (  child_1.el  );
1690             var child_2 = new Xcls_MenuItem13( _this );
1691             child_2.ref();
1692             this.el.add (  child_2.el  );
1693         }
1694
1695         // user defined functions
1696     }
1697     public class Xcls_MenuItem11 : Object
1698     {
1699         public Gtk.MenuItem el;
1700         private Xcls_WindowLeftTree  _this;
1701
1702
1703             // my vars (def)
1704
1705         // ctor
1706         public Xcls_MenuItem11(Xcls_WindowLeftTree _owner )
1707         {
1708             _this = _owner;
1709             this.el = new Gtk.MenuItem();
1710
1711             // my vars (dec)
1712
1713             // set gobject values
1714             this.el.label = "Delete Element";
1715
1716             //listeners
1717             this.el.activate.connect( ( ) => {
1718                 
1719                 print("ACTIVATE?");
1720                 
1721               
1722                  _this.model.deleteSelected();
1723             });
1724         }
1725
1726         // user defined functions
1727     }
1728
1729     public class Xcls_MenuItem12 : Object
1730     {
1731         public Gtk.MenuItem el;
1732         private Xcls_WindowLeftTree  _this;
1733
1734
1735             // my vars (def)
1736
1737         // ctor
1738         public Xcls_MenuItem12(Xcls_WindowLeftTree _owner )
1739         {
1740             _this = _owner;
1741             this.el = new Gtk.MenuItem();
1742
1743             // my vars (dec)
1744
1745             // set gobject values
1746             this.el.label = "Save as Template";
1747
1748             //listeners
1749             this.el.activate.connect( () => {
1750             
1751                  DialogSaveTemplate.singleton().show(
1752                         (Gtk.Window) _this.el.get_toplevel (), 
1753                         _this.main_window.windowstate.file.palete(), 
1754                         _this.getActiveElement()
1755                 );
1756                  
1757                 
1758             });
1759         }
1760
1761         // user defined functions
1762     }
1763
1764     public class Xcls_MenuItem13 : Object
1765     {
1766         public Gtk.MenuItem el;
1767         private Xcls_WindowLeftTree  _this;
1768
1769
1770             // my vars (def)
1771
1772         // ctor
1773         public Xcls_MenuItem13(Xcls_WindowLeftTree _owner )
1774         {
1775             _this = _owner;
1776             this.el = new Gtk.MenuItem();
1777
1778             // my vars (dec)
1779
1780             // set gobject values
1781             this.el.label = "Save as Module";
1782
1783             //listeners
1784             this.el.activate.connect( () => {
1785                 var node = _this.getActiveElement();
1786                  var name = DialogSaveModule.singleton().show(
1787                         (Gtk.Window) _this.el.get_toplevel (), 
1788                         _this.main_window.windowstate.project, 
1789                         node
1790                  );
1791                  if (name.length < 1) {
1792                         return;
1793               
1794                  }
1795                  node.set_prop( new JsRender.NodeProp.special("xinclude", name));
1796                  node.items.clear();
1797             
1798             
1799                 var s = _this.view.el.get_selection();
1800                 
1801                 print("GET  SELECTED?");
1802                 Gtk.TreeIter iter;
1803                 Gtk.TreeModel mod;
1804             
1805                 
1806                 if (!s.get_selected(out mod, out iter)) {
1807                     return; // nothing seleted..
1808                 }
1809                 Gtk.TreeIter citer;
1810                 var n_cn = mod.iter_n_children(iter) -1;
1811                 for (var i = n_cn; i > -1; i--) {
1812                     mod.iter_nth_child(out citer, iter, i);
1813                     
1814             
1815                     print("removing node from Tree\n");    
1816                 
1817                     _this.model.el.remove(ref citer);
1818                 }
1819                 _this.changed();
1820                 _this.node_selected(node, "tree");
1821                  
1822                 
1823             });
1824         }
1825
1826         // user defined functions
1827     }
1828
1829
1830
1831 }