tests/menu.vala
[app.Builder.js] / tests / menu.vala
1 /* -- to compile
2 valac  --pkg gio-2.0  --pkg posix  --pkg gtk+-3.0 --pkg libnotify --pkg gtksourceview-3.0  --pkg  libwnck-3.0 \
3     /tmp/WindowLeftTree.vala  -o /tmp/WindowLeftTree
4 */
5
6
7 /* -- to test class
8 static int main (string[] args) {
9     Gtk.init (ref args);
10     new Xcls_WindowLeftTree();
11     WindowLeftTree.show_all();
12      Gtk.main ();
13     return 0;
14 }
15 */
16
17
18 public static Xcls_WindowLeftTree  WindowLeftTree;
19
20 public class Xcls_WindowLeftTree : Object 
21 {
22     public Gtk.Window el;
23     private Xcls_WindowLeftTree  _this;
24
25     public Xcls_LeftTreeMenu LeftTreeMenu;
26
27         // ctor 
28     public Xcls_WindowLeftTree()
29     {
30         this.el = new Gtk.Window( null, null );
31         _this = this;
32         WindowLeftTree = this;
33
34         // my vars
35
36         // set gobject values
37         this.el.shadow_type = Gtk.ShadowType.IN;
38         var child_0 = new Xcls_view(_this);
39         this.el.add (  child_0.el  );
40         _this.LeftTreeMenu = new Xcls_LeftTreeMenu(_this);
41
42         // init method 
43          this.el.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
44          
45     }
46
47     // userdefined functions 
48
49     // skip .signal:void:after_node_change(JsRender.Node? node) - already used 
50
51     // skip .signal:void:before_node_change(JsRender.Node? node) - already used 
52
53     // skip id - not pipe 
54
55     // skip pack - not pipe 
56
57     // skip xtype - not pipe 
58     public JsRender.JsRender getActiveFile() {
59             return this.model.file;
60         }
61     public JsRender.Node? getActiveElement () { // return path to actie node.
62         
63              var path = this.getActivePath();
64              if (path.length < 1) {
65                 return null;
66              }
67              return _this.model.pathToNode(path);
68         }
69
70     // skip |init - already used 
71
72     // skip |shadow_type - already used 
73     public string getActivePath () {
74            
75             var view = this.view.el;
76             if (view.get_selection().count_selected_rows() < 1) {
77                 return "";
78             }
79             Gtk.TreeIter iter;
80             Gtk.TreeModel mod;
81             view.get_selection().get_selected(out mod, out iter);
82             return mod.get_path(iter).to_string();
83         }
84
85     // skip |xns - no return type
86
87     // skip items - not pipe 
88
89     // skip xvala_cls - not pipe 
90
91     // skip xvala_xcls - not pipe 
92
93     // skip xvala_id - not pipe 
94     public class Xcls_view : Object 
95     {
96         public Gtk.TreeView el;
97         private Xcls_WindowLeftTree  _this;
98
99
100             // my vars
101         public bool blockChanges;
102         public bool drag_in_motion;
103         public int drag_x;
104         public int drag_y;
105         public string dragData;
106         public string[] dropList;
107
108             // ctor 
109         public Xcls_view(Xcls_WindowLeftTree _owner)
110         {
111             this.el = new Gtk.TreeView();
112             _this = _owner;
113             _this.view = this;
114
115             // my vars
116             this.blockChanges = false;
117
118             // set gobject values
119             this.el.enable_tree_lines = true;
120             this.el.headers_visible = false;
121             this.el.tooltip_column = 1;
122             var child_0 = new Xcls_model(_this);
123             this.el.set_model (  child_0.el  );
124             var child_1 = new Xcls_TreeViewColumn4(_this);
125             this.el.append_column (  child_1.el  );
126
127             // init method 
128             {
129                 var description = new Pango.FontDescription();
130                 description.set_size(8000);
131                 this.el.modify_font(description);
132             
133                 var selection = this.el.get_selection();
134                 selection.set_mode( Gtk.SelectionMode.SINGLE);
135             
136             
137                 // is this really needed??
138                 /*
139                 this.selection.signal['changed'].connect(function() {
140                     _this.get('/LeftTree.view').listeners.cursor_changed.apply(
141                         _this.get('/LeftTree.view'), [ _this.get('/LeftTree.view'), '']
142                     );
143                 });
144                 */
145                 Gtk.drag_source_set (
146                     this.el,            /* widget will be drag-able */
147                     Gdk.ModifierType.BUTTON1_MASK,       /* modifier that will start a drag */
148                     Builder4.Application.targetList,            /* lists of target to support */
149                     Gdk.DragAction.COPY   | Gdk.DragAction.MOVE           /* what to do with data after dropped */
150                 );
151             
152                 // ?? needed??
153                 //Gtk.drag_source_add_text_targets(this.el); 
154             
155                 Gtk.drag_dest_set
156                 (
157                     this.el,              /* widget that will accept a drop */
158                     Gtk.DestDefaults.MOTION  | Gtk.DestDefaults.HIGHLIGHT,
159                     Builder4.Application.targetList,            /* lists of target to support */
160                     Gdk.DragAction.COPY   | Gdk.DragAction.MOVE       /* what to do with data after dropped */
161                 );
162             
163                 //Gtk.drag_dest_set_target_list(this.el, Builder.Application.targetList);
164                 //Gtk.drag_dest_add_text_targets(this.el);
165             }
166
167             // listeners 
168             this.el.button_press_event.connect(   ( ev) => {
169                 //console.log("button press?");
170             
171                 
172                 _this.before_node_change(null);
173                 if (ev.type != Gdk.EventType.BUTTON_PRESS  || ev.button != 3) {
174                     //print("click" + ev.type);
175                     return false;
176                 }
177                 Gtk.TreePath res;
178                 _this.view.el.get_path_at_pos((int)ev.x,(int)ev.y, out res, null, null, null);
179                     
180                   //if (!this.get('/LeftTreeMenu').el)  { 
181                   //      this.get('/LeftTreeMenu').init(); 
182                   //  }
183                     
184                  _this.LeftTreeMenu.el.set_screen(Gdk.Screen.get_default());
185                  _this.LeftTreeMenu.el.show_all();
186                   _this.LeftTreeMenu.el.popup(null, null, null,  ev.button, ev.time);
187                  //   print("click:" + res.path.to_string());
188                   return true;
189             } );
190             this.el.drag_begin.connect( ( ctx)  => {
191                 //print('SOURCE: drag-begin');
192                     
193                     
194                     //this.targetData = "";
195                     
196                     // find what is selected in our tree...
197                     
198                     var s = _this.view.el.get_selection();
199                     if (s.count_selected_rows() < 1) {
200                         return;
201                     }
202                     Gtk.TreeIter iter;
203                     Gtk.TreeModel mod;
204                     s.get_selected(out mod, out iter);
205             
206                     
207             
208                     // set some properties of the tree for use by the dropped element.
209                     GLib.Value value;
210                     _this.model.el.get_value(iter, 2, out value);
211                     var data = (JsRender.Node)(value.dup_object());
212                     var xname = data.fqn();
213                      print ("XNAME  IS " + xname+ "\n");
214                     this.dragData = xname;
215                     this.dropList = _this.model.file.palete().getDropList(xname);
216                     
217                     print ("DROP LIST IS " + string.joinv(", ", this.dropList) + "\n");
218                     
219             
220                     // make the drag icon a picture of the node that was selected
221                     var path = _this.model.el.get_path(iter);
222             
223                     //this.treepath = path.to_string();
224                     
225                     var pix = this.el.create_row_drag_icon ( path);
226                     
227                     Gtk.drag_set_icon_surface (ctx, pix) ;
228                     
229                     return;
230             } );
231             this.el.drag_end.connect(   (drag_context) => {
232                 //Seed.print('LEFT-TREE: drag-end');
233                     this.dragData = "";
234                     this.dropList = null;
235             //        this.targetData = "";
236                     this.highlightDropPath("",0);
237             //        return true;
238             } );
239             this.el.drag_motion.connect(  ( ctx, x, y, time)  => {
240              
241                 // the point of this is to detect where an item could be dropped..
242                 
243                    this.drag_in_motion = true;
244                    this.drag_x = x;
245                    this.drag_y = y;
246                    
247                         // request data that will be recieved by the recieve...              
248                     Gtk.drag_get_data
249                     (
250                             this.el,         // will receive 'drag-data-received' signal 
251                             ctx,        // represents the current state of the DnD 
252                             Gdk.Atom.intern("STRING",true),    // the target type we want 
253                             time            // time stamp 
254                     );
255                 return true;
256                    
257             } );
258             this.el.drag_drop.connect(  (  ctx, x, y, time)  => {
259                   //Seed.print("TARGET: drag-drop");
260                    this.drag_in_motion = false;   
261                     // request data that will be recieved by the recieve...              
262                 Gtk.drag_get_data
263                 (
264                         this.el,         // will receive 'drag-data-received' signal 
265                         ctx,        // represents the current state of the DnD 
266                         Gdk.Atom.intern("STRING",true),    // the target type we want 
267                         time            // time stamp 
268                 );
269             
270                  
271                 // No target offered by source => error
272                
273             
274                 return  false;
275             } );
276             this.el.drag_data_received.connect(   (ctx, x, y, sel, info, time)  => {
277                   //print("Tree: drag-data-received");
278             
279             
280                  
281                  
282                     //console.log("LEFT-TREE: drag-motion");
283                     var src = Gtk.drag_get_source_widget(ctx);
284                     
285                     // a drag from  elsewhere...- prevent drop..
286                     if (src != this.el) {
287                         //print("no drag data!");
288                         // fix-me - this.. needs to handle comming from the palete...
289                         if (this.drag_in_motion) {
290                             Gdk.drag_status(ctx, 0, time);
291                             this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
292                             return;
293                         }
294                         Gtk.drag_finish (ctx, false, false, time);        // drop failed..
295                         // no drop action...
296                         return;
297                     }
298                         
299                     var  targetData = "";
300                     //var action = Gdk.DragAction.COPY;
301                         // unless we are copying!!! ctl button..
302                     var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ? Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;
303                     
304                     
305                     if (_this.model.el.iter_n_children(null) < 1) {
306                         // no children.. -- asume it's ok..
307                         
308                         targetData = "|%d|".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
309                         if (this.drag_in_motion) {    
310                             this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);        
311                             Gdk.drag_status(ctx, action ,time);
312                             return;
313                         }
314                         // continue through to allow drop...
315             
316                     } else {
317                         
318                         
319             
320                         //print("GETTING POS");
321                         Gtk.TreePath path;
322                         Gtk.TreeViewDropPosition pos;
323                         var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
324                         
325                         //print("ISOVER? " + isOver);
326                         if (!isOver) {
327                             if (this.drag_in_motion) {
328                                 Gdk.drag_status(ctx, 0 ,time);
329                                  this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);                    
330                                  return;
331                             }
332                             Gtk.drag_finish (ctx, false, false, time);        // drop failed..
333                             return; // not over apoint!?! - no action on drop or motion..
334                         }
335                         
336                         // drag node is parent of child..
337                         //console.log("SRC TREEPATH: " + src.treepath);
338                         //console.log("TARGET TREEPATH: " + data.path.to_string());
339                         
340                         // nned to check a  few here..
341                         //Gtk.TreeViewDropPosition.INTO_OR_AFTER
342                         //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
343                         //Gtk.TreeViewDropPosition.AFTER
344                         //Gtk.TreeViewDropPosition.BEFORE
345                         
346                         // what's in the selected data....
347                         var selection_text = sel.get_text();
348                         
349                         
350                         
351                         if (selection_text == null || selection_text.length < 1) {
352                             //print("Error  - drag selection text returned NULL");
353                             if (this.drag_in_motion) {
354                                  Gdk.drag_status(ctx, 0 ,time);
355                                 this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
356                                  return;
357                              }
358                              Gtk.drag_finish (ctx, false, false, time);        // drop failed..
359                              return; /// -- fixme -- this is not really correct..
360                         }                
361                         
362                         // see if we are dragging into ourself?
363                         print ("got selection text of  " + selection_text);
364                         
365                         var target_path = path.to_string();
366                         //print("target_path="+target_path);
367             
368                         // 
369                         if (selection_text  == target_path) {
370                             print("self drag ?? == we should perhaps allow copy onto self..\n");
371                             if (this.drag_in_motion) {
372                                  Gdk.drag_status(ctx, 0 ,time);
373                                   this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
374                                   return;
375                              }
376                              Gtk.drag_finish (ctx, false, false, time);        // drop failed..
377             
378                              return; /// -- fixme -- this is not really correct..
379             
380                         }
381                         
382                         // check that 
383                         //print("DUMPING DATA");
384                         //console.dump(data);
385                         // path, pos
386                         
387                         //print(data.path.to_string() +' => '+  data.pos);
388                         
389                         // dropList is a list of xtypes that this node could be dropped on.
390                         // it is set up when we start to drag..
391                         
392                         
393                         targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);
394                             
395                         print("targetDAta: " + targetData +"\n");
396                         
397                         if (targetData.length < 1) {
398                             //print("Can not find drop node path");
399                             if (this.drag_in_motion) {
400                                 Gdk.drag_status(ctx, 0, time);
401                                 this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
402                                 return;
403                             }
404                             Gtk.drag_finish (ctx, false, false, time);        // drop failed..
405                             return;
406                         }
407                         
408                         var td_ar = targetData.split("|");
409                         //print ("highlight drop path\n");
410                         // drop ontop of same node?
411             /*            if (ctx.get_actions() == Gdk.DragAction.MOVE && td_ar[0] == selection_text && td_ar[1] == "0" ) {
412                             if (this.drag_in_motion) {
413                                 Gdk.drag_status(ctx, 0, time);
414                                 this.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
415                                 return;
416                             }
417                             Gtk.drag_finish (ctx, false, false, time);        // drop failed..
418                             return;
419                             
420                         }
421               */          
422                         
423                         //console.dump(tg);
424                            
425                         
426                         if (this.drag_in_motion) { 
427                             Gdk.drag_status(ctx, action ,time);
428                             this.highlightDropPath(td_ar[0], (Gtk.TreeViewDropPosition)int.parse(td_ar[1]));
429                             return;
430                         }
431                         // continue on to allow drop..
432                     }
433             
434                     // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..
435             
436             
437                      var delete_selection_data = false;
438                         
439                     if (ctx.get_actions() == Gdk.DragAction.ASK)  {
440                         /* Ask the user to move or copy, then set the ctx action. */
441                     }
442             
443                     if (ctx.get_actions() == Gdk.DragAction.MOVE) {
444                         delete_selection_data = true;
445                     }
446                     
447                         
448                                 // drag around.. - reorder..
449                     _this.model.moveNode(targetData, ctx.get_actions());
450                         
451                        
452                         
453                         
454                         
455                         // we can send stuff to souce here...
456             
457             
458                 // do we always say failure, so we handle the reall drop?
459                     Gtk.drag_finish (ctx, false, false,time); //delete_selection_data, time);
460                    
461             } );
462             this.el.cursor_changed.connect(  ( ) => {
463             
464             
465                  if (this.blockChanges) { // probably not needed.. 
466                    return  ;
467                  }
468                  _this.before_node_change(null);
469                  
470                  if (_this.model.file == null) {
471                      return;
472                  } 
473                  
474                  //var render = this.get('/LeftTree').getRenderer();                
475                
476                 
477                 if (this.el.get_selection().count_selected_rows() < 1) {
478             
479             
480                     //??this.model.load( false);
481                     _this.after_node_change(null);
482                     
483                     return  ;
484                 }
485                         
486                         //console.log('changed');
487                     var s = this.el.get_selection();
488                      Gtk.TreeIter iter;
489                      Gtk.TreeModel mod;
490                     s.get_selected(out mod, out iter);
491                     
492                     
493                     // var val = "";
494                     GLib.Value value;
495                     _this.model.el.get_value(iter, 2, out value);
496                     _this.model.activePath = mod.get_path(iter).to_string();
497                     
498                     var node = (JsRender.Node)value.dup_object();
499             
500                     _this.after_node_change(node);
501             
502             //        _this.model.file.changed(node, "tree");
503                    
504                     //Seed.print( value.get_string());
505                     return  ;
506                             
507             } );
508             this.el.drag_data_get.connect(  ( drag_context, data, info, time) => {
509             
510             
511                  print("drag-data-get");
512                  var s = this.el.get_selection();
513                  if (s.count_selected_rows() < 1) {
514                         data.set_text("",0);     
515                          print("return empty string - no selection..");
516                         return;
517                     }
518                  
519                  Gtk.TreeIter iter;
520                  Gtk.TreeModel mod;
521                  
522                  s.get_selected(out mod, out iter);
523                  
524                 
525                 var tp = mod.get_path(iter).to_string();
526                 data.set_text(tp,tp.length);
527                  print("return " + tp);
528             } );
529         }
530
531         // userdefined functions 
532
533         // skip listeners - not pipe 
534
535         // skip .bool:blockChanges - already used 
536
537         // skip .bool:drag_in_motion - already used 
538
539         // skip .int:drag_x - already used 
540
541         // skip .int:drag_y - already used 
542
543         // skip .string:dragData - already used 
544
545         // skip .string[]:dropList - already used 
546
547         // skip id - not pipe 
548
549         // skip pack - not pipe 
550
551         // skip tooltip_column - already used 
552
553         // skip xtype - not pipe 
554
555         // skip |enable_tree_lines - already used 
556
557         // skip |headers_visible - already used 
558
559         // skip |init - already used 
560         public void highlightDropPath ( string treepath, Gtk.TreeViewDropPosition pos) {
561             
562                     // highlighting for drag/drop
563                     if (treepath.length > 0) {
564                         this.el.set_drag_dest_row(  new  Gtk.TreePath.from_string( treepath ), pos);
565                       } else {
566                             this.el.set_drag_dest_row(null, Gtk.TreeViewDropPosition.INTO_OR_AFTER);
567                      }
568                          
569             }
570         public void selectNode(string treepath_str) {
571                 //this.selection.select_path(new  Gtk.TreePath.from_string( treepath_str));
572                  var tp = new Gtk.TreePath.from_string(treepath_str);
573                  
574                  this.el.set_cursor(tp, null, false);  
575                  this.el.scroll_to_cell(tp, null, false, 0,0);
576             }
577
578         // skip |xns - no return type
579
580         // skip items - not pipe 
581
582         // skip xvala_cls - not pipe 
583
584         // skip xvala_xcls - not pipe 
585
586         // skip xvala_id - not pipe 
587     }
588     public class Xcls_model : Object 
589     {
590         public Gtk.TreeStore el;
591         private Xcls_WindowLeftTree  _this;
592
593
594             // my vars
595         public JsRender.JsRender? file;
596         public string activePath;
597
598             // ctor 
599         public Xcls_model(Xcls_WindowLeftTree _owner)
600         {
601             this.el = new Gtk.TreeStore( 3, typeof(string),typeof(string),typeof(Object) );
602             _this = _owner;
603             _this.model = this;
604
605             // my vars
606             this.file = null;
607             this.activePath = "";
608
609             // set gobject values
610
611             // init method 
612             print("model initialized");
613         }
614
615         // userdefined functions 
616
617         // skip .JsRender.JsRender?:file - already used 
618
619         // skip .string:activePath - already used 
620
621         // skip currentTree - not pipe 
622
623         // skip id - not pipe 
624
625         // skip n_columns - already used 
626
627         // skip pack - not pipe 
628
629         // skip xtype - not pipe 
630         public JsRender.Node pathToNode(string path) {
631              
632                  
633                  Gtk.TreeIter   iter;
634                  _this.model.el.get_iter_from_string(out iter, path);
635                  
636                  GLib.Value value;
637                  _this.model.el.get_value(iter, 2, out value);
638                  
639                  return (JsRender.Node)value.dup_object();
640             
641             }
642
643         // skip |columns - already used 
644
645         // skip |init - already used 
646
647         // skip |listAllTypes - no return type
648         public string findDropNode (string treepath_str, string[] targets) {
649             
650                 // this is used by the dragdrop code in the roo version AFAIR..
651             
652                 //var path = treepath_str.replace(/^builder-/, '');
653                 // treemap is depreciated... - should really check if model has any entries..
654             
655                 if (this.el.iter_n_children(null) < 1) {
656                     //print("NO KEYS");
657                     return "|%d".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
658                 }
659                 //print("FIND treepath: " + path);
660                 //console.dump(this.treemap);
661                 
662                 //if (!treepath_str.match(/^builder-/)) {
663                 //    return []; // nothing!
664                 //}
665                 if (targets.length > 0 && targets[0] == "*") {
666                     return  treepath_str;
667                 }
668                 return this.findDropNodeByPath(treepath_str,targets, -1);
669             }
670         public string findDropNodeByPath (string treepath_str, string[] targets, int in_pref = -1) {
671             
672                 var path = treepath_str; // dupe it..
673                 
674                 int pref = in_pref < 0  ?  Gtk.TreeViewDropPosition.INTO_OR_AFTER : in_pref;
675                 
676                 var last = "";
677                 
678                 //console.dump(this.treemap);
679                 
680                 while (path.length > 0) {
681                     //print("LOOKING FOR PATH: " + path);
682                     var node_data = this.pathToNode(path);
683                     
684                     if (node_data == null) {
685                         print("node not found");
686                         return null;
687                     }
688                     
689                     var xname = node_data.fqn();
690                     var match = "";
691                     var prop = "";
692                     
693                     for (var i =0; i < targets.length; i++)  {
694                         var tg = targets[i];
695                         if ((tg == xname)  ) {
696                             match = tg;
697                             break;
698                         }
699                         // if target is "xxxx:name"
700                         if (tg.contains(xname +":")) {
701                             match = tg;
702                             var ar = tg.split(":");
703                             prop = ar[1];
704                             break;
705                         }
706                     }
707                     
708                     if (match.length > 0) {
709                         if (last.length > 0) { // pref is after/before..
710                             // then it's after last
711                             if (pref > 1) {
712                                 return "";
713                             }
714                             return last + "|%d".printf((int)pref) + "|" + prop;
715             
716                             
717                         }
718                         return path + "|%d".printf( (int) Gtk.TreeViewDropPosition.INTO_OR_AFTER) + "|" + prop;
719                     }
720                     last = "" + path;
721                     var par = path.split(":");
722                     string [] ppar = {};
723                     for (var i = 0; i < par.length-1; i++) {
724                         ppar += par[i];
725                     }
726                     
727                     path = string.joinv(":", ppar);
728             
729             
730                 }
731                 
732                 return "";
733                         
734             }
735         public void deleteSelected() {
736                 
737                 print("DELETE SELECTED?");
738                 //_this.view.blockChanges = true;
739                 print("GET SELECTION?");
740             
741                 var s = _this.view.el.get_selection();
742                 
743                 print("GET  SELECTED?");
744                Gtk.TreeIter iter;
745                 Gtk.TreeModel mod;
746             
747                 
748                 if (!s.get_selected(out mod, out iter)) {
749                     return; // nothing seleted..
750                 }
751                   
752             
753             
754                 this.activePath= "";      
755                 print("GET  vnode value?");
756             
757                 GLib.Value value;
758                 this.el.get_value(iter, 2, out value);
759                 var data = (JsRender.Node)(value.get_object());
760                 print("removing node from Render\n");
761                 
762                 data.remove();
763                     print("removing node from Tree\n");    
764                 s.unselect_all();
765                 this.el.remove(ref iter);
766             
767                 
768                 
769                 
770                 // 
771                 
772                 
773             
774             
775                 this.activePath= ""; // again!?!?      
776                 //this.changed(null,true);
777                 
778                 this.file.changed(null, "tree");
779                 
780                 _this.view.blockChanges = false;
781             }
782         public void dropNode(string target_data_str, JsRender.Node node) {
783             //         print("drop Node");
784                  // console.dump(node);
785               //    console.dump(target_data);
786               
787               
788                     // 0 = before , 1=after 2/3 onto
789               
790               
791                     var target_data= target_data_str.split("|");
792               
793                     var parent_str = target_data[0].length > 0 ? target_data[0] : "";
794                     var pos = target_data.length > 1 ? int.parse(target_data[1]) : 2; // ontop..
795               
796               
797                     Gtk.TreePath tree_path  =   parent_str.length > 0 ? new  Gtk.TreePath.from_string( parent_str ) : null;
798                     
799                     
800                     
801                     //print("add " + tp + "@" + target_data[1]  );
802                     
803                     JsRender.Node parentNode = null;
804                     
805                     Gtk.TreeIter iter_after;
806                     Gtk.TreeIter iter_par ;
807                     
808                    
809             
810             
811                     
812                      //print("pos is %d  \n".printf(pos));
813                     
814                      Gtk.TreeIter n_iter; 
815                      
816                      if ( parent_str.length < 1) {
817                           this.el.append(out n_iter, null);
818                            node.parent = null;
819                     } else   if (pos  < 2) {
820                         //print(target_data[1]  > 0 ? 'insert_after' : 'insert_before');
821                         
822                         this.el.get_iter(out iter_after, tree_path );            
823                         this.el.iter_parent(out iter_par, iter_after);
824                          
825                         if ( pos  > 0 ) {
826                          
827                             this.el.insert_after(out n_iter,    iter_par  , iter_after);
828                         } else {
829                             this.el.insert_before(out n_iter,  iter_par  , iter_after);
830                         }
831                         GLib.Value value;
832                         this.el.get_value( iter_par, 2, out value);
833                         parentNode =  (JsRender.Node)value.dup_object();
834                         node.parent = parentNode;
835                     } else {
836                        //  print("appending to  " + parent_str);
837                         this.el.get_iter(out iter_par, tree_path);
838                         this.el.append(out n_iter,   iter_par );
839                         GLib.Value value;
840                         this.el.get_value( iter_par, 2, out value);
841                         parentNode =  (JsRender.Node)value.dup_object();
842                         node.parent = parentNode;
843                     }
844                     
845                     // reparent node in tree...
846                    
847                     
848                     
849                     if (node.parent == null) {
850                         
851                         if (target_data.length == 3 && target_data[2].length > 0) {
852                             node.props.set("*prop", target_data[2]);
853                         }
854                         
855                         var new_node = DialogTemplateSelect.show(this.file.palete(), node);
856                         node = new_node;
857                         
858                     }
859                     
860                     
861                     // work out what kind of packing to use.. -- should be in 
862                     if (!node.has("pack")   && parent_str.length > 1) {
863                         
864                         this.file.palete().fillPack(node,parentNode);
865                         
866                         
867                     }
868                     
869                     
870                     
871             // load children - if it has any..
872                   
873                     if (node.items.size > 0) {
874                         this.load(node.items, n_iter);
875                         _this.view.el.expand_row(this.el.get_path(n_iter), true);
876                     }
877                     
878                     //if (tp != null && (node.items.length() > 0 || pos > 1)) {
879                     //    _this.view.el.expand_row(this.el.get_path(iter_par), true);
880                    // }
881                     // wee need to get the empty proptypes from somewhere..
882                     
883                     //var olditer = this.activeIter;
884                     this.activePath = this.el.get_path(n_iter).to_string();
885             
886               // changed actually set's the node data..
887                     this.updateNode(node, true);
888                     
889                     
890                     _this.view.el.set_cursor(this.el.get_path(n_iter), null, false);
891                     
892                     //Builder.MidPropTree._model.load(node);
893                     //Builder.MidPropTree._win.hideWin();
894                     //Builder.LeftPanel._model.load( node);
895                     
896                         
897             }
898         public void load(Gee.ArrayList<JsRender.Node> tr, Gtk.TreeIter? iter) 
899             {
900                 Gtk.TreeIter citer;
901                 //this.insert(citer,iter,0);
902                 for(var i =0 ; i < tr.size; i++) {
903                     if (iter != null) {
904                         this.el.insert(out citer,iter,-1); // why not append?
905                     } else {
906                         this.el.append(out citer,null);
907                     }
908                     
909                     this.el.set(citer, 0, tr.get(i).nodeTitle(),
910                             1, tr.get(i).nodeTip(), -1
911                     );
912                     var o = new GLib.Value(typeof(Object));
913                     o.set_object((Object)tr.get(i));
914                     
915                     this.el.set_value(citer, 2, o);
916                     
917                     if (tr.get(i).items.size > 0) {
918                         this.load(tr.get(i).items, citer);
919                     }
920                  
921                 }
922             }
923         public void loadFile(JsRender.JsRender f) {
924                 //console.dump(f);
925                 this.el.clear();
926                 this.file = f;
927                 
928             //    if (!f) {
929             //        console.log('missing file');
930             //        return;
931             //    }
932                 
933                 // load the file if not loaded..
934                 if (f.tree == null) {
935                     f.loadItems( );
936                 }
937                 
938                 
939                 
940                 /// this.get('/Window').setTitle(f.project.getName() + ' - ' + f.name);
941                 
942                 //if (f.items.length && typeof(f.items[0]) == 'string') {
943                 
944                     //this.get('/RightEditor').el.show();
945                     //this.get('/RightEditor.view').load( f.items[0]);
946                 //    return;
947                 //}
948                 //print("LOAD");
949                 //print(JSON.stringify(f.items, null,4));
950                 //console.dump(f.items);
951                 var o = new Gee.ArrayList<JsRender.Node>();
952                 o.add(f.tree);
953                 this.load(o,null);
954                 
955                 _this.view.el.expand_all();
956             
957                 if (f.tree.items.size < 1) {
958                     // single item..
959                     
960                     //this.get('/Window.leftvpaned').el.set_position(80);
961                     // select first...
962                     _this.view.el.set_cursor( 
963                         new  Gtk.TreePath.from_string("0"), null, false);
964                     
965                     
966                 } else {
967                       //this.get('/Window.leftvpaned').el.set_position(200);
968                 }
969                 
970                 return;
971                 /*    
972                 
973                 //print("hide right editior");
974                 //this.get('/RightEditor').el.hide();
975                 //this.get('/Editor').el.hide();
976                 //print("set current tree");
977                 //this.currentTree = this.toJS(false, false)[0];
978                 //console.dump(this.currentTree);
979                 //this.currentTree = this.currentTree || { items: [] };
980                 //_this.renderView();
981                 //console.dump(this.map);
982                 //var RightPalete     = imports.Builder.RightPalete.RightPalete;
983                 
984                 
985                 var pm = this.get('/RightPalete.model');
986                 // set up provider..
987                 
988                 this.get('/RightPalete').provider = this.get('/LeftTree').getPaleteProvider();
989                 
990                 if (!this.get('/RightPalete').provider) {
991                     print ("********* PALETE PROVIDER MISSING?!!");
992                 }
993                 this.get('/LeftTree').renderView();
994                 
995                 pm.load( this.get('/LeftTree').getPaleteProvider().gatherList(this.listAllTypes()));
996                 
997                 
998                         
999                 this.get('/Window.view-notebook').el.set_current_page(
1000                     this.get('/LeftTree.model').file.getType()== 'Roo' ? 0 : -1);
1001                     */
1002                         
1003             }
1004         public void moveNode(string target_data, Gdk.DragAction action) 
1005             {
1006                
1007                /// target_data = "path|pos");
1008                
1009                
1010                 //print("MOVE NODE");
1011                 // console.dump(target_data);
1012                 Gtk.TreeIter old_iter;
1013                 Gtk.TreeModel mod;
1014                 
1015                 var s = _this.view.el.get_selection();
1016                 s.get_selected(out mod , out old_iter);
1017                 mod.get_path(old_iter);
1018                 
1019                 var node = this.pathToNode(mod.get_path(old_iter).to_string());
1020                 //console.dump(node);
1021                 if (node == null) {
1022                     print("moveNode: ERROR - node is null?");
1023                 }
1024                 
1025                 
1026             
1027                 // needs to drop first, otherwise the target_data 
1028                 // treepath will be invalid.
1029             
1030                 
1031                 if ((action & Gdk.DragAction.MOVE) > 0) {
1032                         print("REMOVING OLD NODE : " + target_data + "\n");
1033                         node.remove();
1034                         this.dropNode(target_data, node);
1035                         this.el.remove(ref old_iter);
1036                         
1037                         
1038                                      
1039                 } else {
1040                     print("DROPPING NODE // copy: " + target_data + "\n");
1041                     node = node.deepClone();
1042                     this.dropNode(target_data, node);
1043                 }
1044             
1045                 this.activePath= "";
1046                 //this.updateNode(false,true);
1047             }
1048         public void updateNode(JsRender.Node? n, bool refresh)
1049              {
1050                 //     print("MODEL CHANGED CALLED" + this.activePath);
1051                  if (n != null && this.activePath.length > 0) {
1052                     Gtk.TreeIter iter;
1053                     this.el.get_iter(out iter, new Gtk.TreePath.from_string(this.activePath));
1054                     this.el.set(iter, 0, n.nodeTitle(), 1, n.nodeTip(), -1);
1055                     var v = new Value(typeof(Object));
1056                     v.set_object((Object)n);
1057                     this.el.set_value(iter, 2, v);
1058                 }
1059                           
1060             }
1061
1062         // skip |xns - no return type
1063
1064         // skip xvala_cls - not pipe 
1065
1066         // skip xvala_xcls - not pipe 
1067
1068         // skip xvala_id - not pipe 
1069     }
1070     public class Xcls_TreeViewColumn4 : Object 
1071     {
1072         public Gtk.TreeViewColumn el;
1073         private Xcls_WindowLeftTree  _this;
1074
1075
1076             // my vars
1077
1078             // ctor 
1079         public Xcls_TreeViewColumn4(Xcls_WindowLeftTree _owner)
1080         {
1081             this.el = new Gtk.TreeViewColumn();
1082             _this = _owner;
1083
1084             // my vars
1085
1086             // set gobject values
1087             var child_0 = new Xcls_renderer(_this);
1088             this.el.pack_start (  child_0.el , true );
1089
1090             // init method 
1091               this.el.add_attribute(_this.renderer.el , "markup", 0 );
1092              
1093         }
1094
1095         // userdefined functions 
1096
1097         // skip pack - not pipe 
1098
1099         // skip xtype - not pipe 
1100
1101         // skip |init - already used 
1102
1103         // skip |xns - no return type
1104
1105         // skip items - not pipe 
1106
1107         // skip xvala_cls - not pipe 
1108
1109         // skip xvala_xcls - not pipe 
1110
1111         // skip xvala_id - not pipe 
1112     }
1113     public class Xcls_renderer : Object 
1114     {
1115         public Gtk.CellRendererText el;
1116         private Xcls_WindowLeftTree  _this;
1117
1118
1119             // my vars
1120
1121             // ctor 
1122         public Xcls_renderer(Xcls_WindowLeftTree _owner)
1123         {
1124             this.el = new Gtk.CellRendererText();
1125             _this = _owner;
1126             _this.renderer = this;
1127
1128             // my vars
1129
1130             // set gobject values
1131         }
1132
1133         // userdefined functions 
1134
1135         // skip id - not pipe 
1136
1137         // skip pack - not pipe 
1138
1139         // skip xtype - not pipe 
1140
1141         // skip |xns - no return type
1142
1143         // skip xvala_cls - not pipe 
1144
1145         // skip xvala_xcls - not pipe 
1146
1147         // skip xvala_id - not pipe 
1148     }
1149     public class Xcls_LeftTreeMenu : Object 
1150     {
1151         public Gtk.Menu el;
1152         private Xcls_WindowLeftTree  _this;
1153
1154
1155             // my vars
1156
1157             // ctor 
1158         public Xcls_LeftTreeMenu(Xcls_WindowLeftTree _owner)
1159         {
1160             print("Xcls_LeftTreeMenu:Ctor called\n");
1161             _this = _owner;
1162                  
1163                         
1164                         this.el = new Gtk.Menu();
1165             _this.LeftTreeMenu = this;
1166
1167             // my vars
1168
1169             // set gobject values
1170             var child_0 = new Xcls_MenuItem7(_this);
1171             this.el.add (  child_0.el  );
1172             var child_1 = new Xcls_MenuItem8(_this);
1173             this.el.add (  child_1.el  );
1174         }
1175
1176         // userdefined functions 
1177
1178         // skip id - not pipe 
1179
1180         // skip pack - not pipe 
1181
1182         // skip xtype - not pipe 
1183
1184         // skip |xns - no return type
1185
1186         // skip items - not pipe 
1187
1188         // skip xvala_cls - not pipe 
1189
1190         // skip xvala_xcls - not pipe 
1191
1192         // skip xvala_id - not pipe 
1193     }
1194     public class Xcls_MenuItem7 : Object 
1195     {
1196         public Gtk.MenuItem el;
1197         private Xcls_WindowLeftTree  _this;
1198
1199
1200             // my vars
1201
1202             // ctor 
1203         public Xcls_MenuItem7(Xcls_WindowLeftTree _owner)
1204         {
1205             
1206             _this = _owner;
1207                  
1208                         this.el = new Gtk.MenuItem.with_label("Delete Element");
1209             // my vars
1210
1211             // set gobject values
1212             //this.el.label = "Delete Element";
1213                         print("add activate\n");
1214             // listeners 
1215                         
1216                         
1217             this.el.select.connect(   ( ) => {
1218                 
1219                 print("SELECT?");
1220                 
1221                                 return  ;
1222             } );
1223         }
1224
1225         // userdefined functions 
1226
1227         // skip listeners - not pipe 
1228
1229         // skip label - already used 
1230
1231         // skip pack - not pipe 
1232
1233         // skip xtype - not pipe 
1234
1235         // skip |xns - no return type
1236
1237         // skip xvala_cls - not pipe 
1238
1239         // skip xvala_xcls - not pipe 
1240
1241         // skip xvala_id - not pipe 
1242     }
1243     public class Xcls_MenuItem8 : Object 
1244     {
1245         public Gtk.MenuItem el;
1246         private Xcls_WindowLeftTree  _this;
1247
1248
1249             // my vars
1250
1251             // ctor 
1252         public Xcls_MenuItem8(Xcls_WindowLeftTree _owner)
1253         {
1254             this.el = new Gtk.MenuItem();
1255             _this = _owner;
1256
1257             // my vars
1258
1259             // set gobject values
1260             this.el.label = "Save as Template";
1261
1262             // listeners 
1263             this.el.activate.connect(   () => {
1264             
1265                  DialogSaveTemplate.show(_this.model.file.palete(), _this.getActiveElement());
1266                  
1267                 
1268             } );
1269         }
1270
1271         // userdefined functions 
1272
1273         // skip listeners - not pipe 
1274
1275         // skip label - already used 
1276
1277         // skip pack - not pipe 
1278
1279         // skip xtype - not pipe 
1280
1281         // skip |xns - no return type
1282
1283         // skip xvala_cls - not pipe 
1284
1285         // skip xvala_xcls - not pipe 
1286
1287         // skip xvala_id - not pipe 
1288     }
1289 }