8a08fdc24eaf4ac97fd6dfea9a5cfeba7e495e96
[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_keystate keystate;
18         public Xcls_drop drop;
19         public Xcls_selmodel selmodel;
20         public Xcls_model model;
21         public Xcls_maincol maincol;
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 int last_error_counter;
28         public signal void changed ();
29         public signal void node_selected (JsRender.Node? node);
30         public Gee.ArrayList<Gtk.Widget>? error_widgets;
31
32         // ctor
33         public Xcls_WindowLeftTree()
34         {
35                 _this = this;
36                 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
37
38                 // my vars (dec)
39                 this.main_window = null;
40                 this.last_error_counter = -1;
41                 this.error_widgets = null;
42
43                 // set gobject values
44                 this.el.hexpand = true;
45                 this.el.vexpand = true;
46                 var child_1 = new Xcls_ListView1( _this );
47                 child_1.ref();
48                 this.el.append( child_1.el );
49                 new Xcls_viewwin( _this );
50                 this.el.append( _this.viewwin.el );
51         }
52
53         // user defined functions
54         public void updateErrors () {
55                 var file = this.getActiveFile();
56                 if (file == null) {
57                         return;
58                 }
59                 
60                 var ar = file.getErrors();
61                 if (ar == null || ar.size < 1) {
62                         if (this.last_error_counter != file.error_counter) {
63                                 this.removeErrors();
64                         }
65                 
66                         this.last_error_counter = file.error_counter ;
67         
68                         return;
69                 }
70                 if (this.last_error_counter == file.error_counter) {
71                         return;
72                 }
73                 this.removeErrors();
74                 this.error_widgets = new Gee.ArrayList<Gtk.Widget>();
75                 foreach(var diag in ar) { 
76                 
77                          
78         //        print("get inter\n");
79                     var node= file.lineToNode( (int)diag.range.start.line) ;
80                     if (node == null) {
81                         continue;
82                 }
83                 var row = _this.model.nodeToRow(node);
84                 if (row < 0) {
85                         continue;
86                         }
87                 var w = this.view.getWidgetAtRow(row);
88                 if (w == null) {
89                         return;
90                         }
91                         this.error_widgets.add(w);
92                         // always show errors.
93                         var ed = diag.category.down();
94                         if (ed != "err" && w.has_css_class("node-err")) {
95                                 continue;
96                         }
97                         if (ed == "err" && w.has_css_class("node-warn")) {
98                                 w.remove_css_class("node-warn");
99                         }
100                         if (ed == "err" && w.has_css_class("node-depr")) {
101                                 w.remove_css_class("node-depr");
102                         }
103                         if (!w.has_css_class("node-"+ ed)) {
104                                 w.add_css_class("node-" + ed);
105                         }
106                         
107                 }
108                 
109         }
110         public void onresize () {
111          
112                  
113                 //GLib.debug("Got allocation width of scrolled view %d", allocation.width );
114         //      _this.maincol.el.set_max_width( _this.viewwin.el.get_width()  - 32 );
115         }
116         public void removeErrors () {
117                 if (this.error_widgets == null || this.error_widgets.size < 1) {
118                         return;
119                 }
120                 foreach(var child in this.error_widgets) {
121                 
122                         if (child.has_css_class("node-err")) {
123                                 child.remove_css_class("node-err");
124                         }
125                         if (child.has_css_class("node-warn")) {
126                                 child.remove_css_class("node-warn");
127                         }
128                         
129                         if (child.has_css_class("node-depr")) {
130                                 child.remove_css_class("node-depr");
131                         }
132                 }
133                 this.error_widgets  = null;
134                 return;
135                 
136                 /*
137                 var  child = this.view.el.get_first_child(); 
138          
139                 var reading_header = true;
140          
141                 while (child != null) {
142                         //GLib.debug("Got %s", child.get_type().name());
143                    
144                    if (reading_header) {
145                                 
146         
147                                 if (child.get_type().name() != "GtkColumnListView") {
148                                    
149                                         child = child.get_next_sibling();
150                                         continue;
151                                 }
152                                 // should be columnlistview
153                                 child = child.get_first_child(); 
154                          
155                          
156                                 
157                                 reading_header = false;
158                                  continue;
159                     }
160                     
161                         if (child.has_css_class("node-err")) {
162                                 child.remove_css_class("node-err");
163                         }
164                         if (child.has_css_class("node-warn")) {
165                                 child.remove_css_class("node-warn");
166                         }
167                         
168                         if (child.has_css_class("node-depr")) {
169                                 child.remove_css_class("node-depr");
170                         }
171                         
172                 child = child.get_next_sibling(); 
173                 }
174                 //GLib.debug("Rturning null");
175                 */
176              
177         }
178         public JsRender.Node? getActiveElement () { // return path to actie node.
179         
180              
181                 return _this.selmodel.getSelectedNode();
182             
183             
184         }
185         public JsRender.JsRender getActiveFile () {
186             return this.main_window.windowstate.file;
187             
188         }
189         public class Xcls_ListView1 : Object
190         {
191                 public Gtk.ListView el;
192                 private Xcls_WindowLeftTree  _this;
193
194
195                         // my vars (def)
196
197                 // ctor
198                 public Xcls_ListView1(Xcls_WindowLeftTree _owner )
199                 {
200                         _this = _owner;
201                         var child_1 = new Xcls_SignalListItemFactory2( _this );
202                         child_1.ref();
203                         this.el = new Gtk.ListView( null, child_1.el );
204
205                         // my vars (dec)
206
207                         // set gobject values
208                 }
209
210                 // user defined functions
211         }
212         public class Xcls_SignalListItemFactory2 : Object
213         {
214                 public Gtk.SignalListItemFactory el;
215                 private Xcls_WindowLeftTree  _this;
216
217
218                         // my vars (def)
219
220                 // ctor
221                 public Xcls_SignalListItemFactory2(Xcls_WindowLeftTree _owner )
222                 {
223                         _this = _owner;
224                         this.el = new Gtk.SignalListItemFactory();
225
226                         // my vars (dec)
227
228                         // set gobject values
229                 }
230
231                 // user defined functions
232         }
233
234
235         public class Xcls_viewwin : Object
236         {
237                 public Gtk.ScrolledWindow el;
238                 private Xcls_WindowLeftTree  _this;
239
240
241                         // my vars (def)
242
243                 // ctor
244                 public Xcls_viewwin(Xcls_WindowLeftTree _owner )
245                 {
246                         _this = _owner;
247                         _this.viewwin = this;
248                         this.el = new Gtk.ScrolledWindow();
249
250                         // my vars (dec)
251
252                         // set gobject values
253                         this.el.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
254                         this.el.has_frame = true;
255                         this.el.hexpand = true;
256                         this.el.vexpand = true;
257                         this.el.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
258                         new Xcls_view( _this );
259                         this.el.child = _this.view.el;
260                         new Xcls_LeftTreeMenu( _this );
261                 }
262
263                 // user defined functions
264         }
265         public class Xcls_view : Object
266         {
267                 public Gtk.ColumnView el;
268                 private Xcls_WindowLeftTree  _this;
269
270
271                         // my vars (def)
272                 public bool blockChanges;
273                 public bool headers_visible;
274                 public string lastEventSource;
275                 public bool button_is_pressed;
276                 public Gtk.CssProvider css;
277                 public JsRender.Node? dragNode;
278
279                 // ctor
280                 public Xcls_view(Xcls_WindowLeftTree _owner )
281                 {
282                         _this = _owner;
283                         _this.view = this;
284                         new Xcls_selmodel( _this );
285                         this.el = new Gtk.ColumnView( _this.selmodel.el );
286
287                         // my vars (dec)
288                         this.blockChanges = false;
289                         this.headers_visible = false;
290                         this.lastEventSource = "";
291                         this.button_is_pressed = false;
292                         this.dragNode = null;
293
294                         // set gobject values
295                         this.el.name = "left-tree-view";
296                         this.el.hexpand = false;
297                         this.el.vexpand = true;
298                         var child_2 = new Xcls_GestureClick5( _this );
299                         child_2.ref();
300                         this.el.add_controller(  child_2.el );
301                         var child_3 = new Xcls_GestureClick6( _this );
302                         child_3.ref();
303                         this.el.add_controller(  child_3.el );
304                         var child_4 = new Xcls_DragSource7( _this );
305                         child_4.ref();
306                         this.el.add_controller(  child_4.el );
307                         var child_5 = new Xcls_EventControllerKey8( _this );
308                         child_5.ref();
309                         this.el.add_controller(  child_5.el );
310                         new Xcls_keystate( _this );
311                         this.el.add_controller(  _this.keystate.el );
312                         new Xcls_drop( _this );
313                         this.el.add_controller(  _this.drop.el );
314                         new Xcls_maincol( _this );
315                         this.el.append_column ( _this.maincol.el  );
316                         var child_9 = new Xcls_ColumnViewColumn15( _this );
317                         child_9.ref();
318                         this.el.append_column ( child_9.el  );
319
320                         // init method
321
322                         {
323                          /*
324                           this.css = new Gtk.CssProvider();
325                         //      try {
326                                         this.css.load_from_string("
327                         #left-tree-view { font-size: 12px;}     
328                         .drag-over  { background-color:#88a3bc; }
329                         .drag-below  {   
330                          border-bottom-width: 5px; 
331                          border-bottom-style: solid;
332                          border-bottom-color: #88a3bc;
333                         }
334                         .drag-above  {
335                          border-top-width: 5px;
336                          border-top-style: solid;
337                          border-top-color: #88a3bc;
338                         }
339                         .node-err  {
340                          border-top-width: 5px;
341                          border-top-style: solid;
342                          border-top-color: red;
343                          border-bottom-width: 5px; 
344                          border-bottom-style: solid;
345                          border-bottom-color: red;
346                         }
347                         .node-warn  {
348                          border-top-width: 5px;
349                          border-top-style: solid;
350                          border-top-color: #ABF4EB;
351                          border-bottom-width: 5px; 
352                          border-bottom-style: solid;
353                          border-bottom-color: #ABF4EB;
354                         }
355                         .node-depr  {
356                          border-top-width: 5px;
357                          border-top-style: solid;
358                          border-top-color: #EEA9FF;
359                          border-bottom-width: 5px; 
360                          border-bottom-style: solid;
361                          border-bottom-color: #EEA9FF;
362                         }
363                         
364                         #left-tree-view indent {
365                         -gtk-icon-size : 2px;
366                         }
367                         #left-tree-view indent:nth-last-child(2)  {
368                         min-width: 24px;
369                         }
370                         ");
371                         
372                                 Gtk.StyleContext.add_provider_for_display(
373                                         this.el.get_display(),
374                                         this.css,
375                                         Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
376                                 );
377                                 */
378                                   
379                         }
380                 }
381
382                 // user defined functions
383                 public Gtk.Widget? getWidgetAtRow (uint row) {
384                 /*
385                         
386                 from            https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
387                         var colview = gesture.widget;
388                         var line_no = check_list_widget(colview, x,y);
389                          if (line_no > -1) {
390                                 var item = colview.model.get_item(line_no);
391                                  
392                         }
393                         */
394                                 //GLib.debug("Get Widget At Row %d", (int)row);
395                         var  child = this.el.get_first_child(); 
396                         var line_no = -1; 
397                         var reading_header = true;
398                          
399                         while (child != null) {
400                                         //GLib.debug("Got %s", child.get_type().name());
401                            
402                            if (reading_header) {
403                                                 
404                 
405                                                 if (child.get_type().name() != "GtkColumnListView") {
406                                                    
407                                                         child = child.get_next_sibling();
408                                                         continue;
409                                                 }
410                                                 // should be columnlistview
411                                                 child = child.get_first_child(); 
412                                          
413                                          
414                                                 
415                                                 reading_header = false;
416                                                 continue;
417                                     }
418                                     
419                                   
420                             
421                                     line_no++;
422                                         if (line_no == row) {
423                                                 //GLib.debug("Returning widget %s", child.get_type().name());
424                                             return (Gtk.Widget)child;
425                                     }
426                                 child = child.get_next_sibling(); 
427                         }
428                                 //GLib.debug("Rturning null");
429                         return null;
430                 
431                  }
432                 public int getColAt (double x,  double y) {
433                         /*
434                                         
435                         from            https://discourse.gnome.org/t/gtk4-finding-a-row-data-on-gtkcolumnview/8465
436                           
437                         */
438                         //Gtk.Allocation alloc = { 0, 0, 0, 0 };
439                         //GLib.debug("Cehck %d, %d", x,y);
440                     var  child = this.el.get_first_child(); 
441                          
442                         var col = 0;
443                         var offx = 0;
444                         while (child != null) {
445                                 
446                                 if (child.get_type().name() == "GtkColumnViewRowWidget") {
447                                         child = child.get_first_child();
448                                         continue;
449                                 }
450                                 
451                                 //child.get_allocation(out alloc);
452                                 if (x <  (child.get_width() + offx)) {
453                                         return col;
454                                 }
455                                 return 1;
456                                 //offx += child.get_width();
457                                 //col++;
458                                 //child = child.get_next_sibling();
459                         }
460                              
461                                   
462                     return -1;
463                 
464                  }
465                 public int getRowAt (double x,  double  y, out string pos) {
466                 
467                         pos = "";
468                         var w = this.el.pick(x, y, Gtk.PickFlags.DEFAULT);
469                         //GLib.debug("got widget %s", w == null ? "nothing" : w.get_type().name());
470                         if (w == null) {
471                                 return -1;
472                         }
473                         
474                         var row= w.get_ancestor(GLib.Type.from_name("GtkColumnViewRowWidget"));
475                         if (row == null) {
476                                 return -1;
477                         }
478                         
479                         //GLib.debug("got colview %s", row == null ? "nothing" : row.get_type().name());
480                          
481                         var rn = 0;
482                         var cr = row;
483                          
484                         while (cr.get_prev_sibling() != null) {
485                                 rn++;
486                                 cr = cr.get_prev_sibling();
487                         }
488                         
489                         //GLib.debug("row number is %d", rn);
490                         //GLib.debug("click %d, %d", (int)x, (int)y);
491                         // above or belw
492                         Graphene.Rect  bounds;
493                         row.compute_bounds(this.el, out bounds);
494                         //GLib.debug("click x=%d, y=%d, w=%d, h=%d", 
495                         //      (int)bounds.get_x(), (int)bounds.get_y(),
496                         //      (int)bounds.get_width(), (int)bounds.get_height()
497                         //      );
498                         var ypos = y - bounds.get_y();
499                         //GLib.debug("rel ypos = %d", (int)ypos);       
500                         var rpos = 100.0 * (ypos / bounds.get_height());
501                         //GLib.debug("rel pos = %d %%", (int)rpos);
502                         pos = "over";
503                         
504                         if (rpos > 80) {
505                                 pos = "below";
506                         } else if (rpos < 20) {
507                                 pos = "above";
508                         } 
509                         return rn;
510                  }
511                 public Gtk.Widget? getWidgetAt (double x,  double  y) {
512                 
513                         var w = this.el.pick(x, y, Gtk.PickFlags.DEFAULT);
514                         //GLib.debug("got widget %s", w == null ? "nothing" : w.get_type().name());
515                         if (w == null) {
516                                 return null;
517                         }
518                         
519                         var row= w.get_ancestor(GLib.Type.from_name("GtkColumnViewRowWidget"));
520                         if (row == null) {
521                                 return null;
522                         }
523                         return row;
524                  
525                 
526                  }
527         }
528         public class Xcls_GestureClick5 : Object
529         {
530                 public Gtk.GestureClick el;
531                 private Xcls_WindowLeftTree  _this;
532
533
534                         // my vars (def)
535
536                 // ctor
537                 public Xcls_GestureClick5(Xcls_WindowLeftTree _owner )
538                 {
539                         _this = _owner;
540                         this.el = new Gtk.GestureClick();
541
542                         // my vars (dec)
543
544                         // set gobject values
545
546                         //listeners
547                         this.el.released.connect( (n_press, x, y) => {
548                          
549                             _this.view.button_is_pressed = false;
550                         
551                         
552                         });
553                         this.el.pressed.connect( (n_press, x, y) => {
554                          
555                             //console.log("button press?");
556                             
557                             //this.el.set_state(Gtk.EventSequenceState.CLAIMED);
558                         
559                         
560                             
561                             _this.view.button_is_pressed = true;
562                               
563                             _this.view.lastEventSource = "tree";
564                             if (! _this.before_node_change() ) {
565                                 GLib.debug("before_node_change return false");
566                                return ;
567                             }
568                             
569                                  // nothing there -show dialog
570                             if (_this.model.el.get_n_items() < 1) {
571                                     _this.main_window.windowstate.showAddObject(_this.view.el, null);
572                                 GLib.debug("no items");
573                                     return ;
574                             }
575                             string pos;
576                             var row = _this.view.getRowAt(x,y, out pos );
577                             if (row < 0) {
578                                     GLib.debug("no row selected items");
579                                     return;
580                             }
581                             
582                             var node =   _this.selmodel.getNodeAt(row);
583                             if (node == null) {
584                                 GLib.warning("No node found at row %d", row);
585                                 return;
586                                 }
587                         
588                              
589                              
590                             if (_this.view.getColAt(x,y) > 0 ) {
591                                     GLib.debug("add colum clicked.");
592                                 var fqn = node.fqn();
593                                 var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
594                                         if (cn.size < 1) {
595                                                 return ;
596                                         }
597                         
598                                         _this.main_window.windowstate.leftTreeBeforeChange();
599                                         //_this.view.el.get_selection().select_path(res);
600                                         GLib.debug("Button Pressed - start show window");
601                                         _this.main_window.windowstate.showAddObject(_this.view.el, node);
602                                         GLib.debug("Button Pressed - finsihed show window");
603                                 return ;
604                                 }
605                             
606                                  
607                              
608                         });
609                 }
610
611                 // user defined functions
612         }
613
614         public class Xcls_GestureClick6 : Object
615         {
616                 public Gtk.GestureClick el;
617                 private Xcls_WindowLeftTree  _this;
618
619
620                         // my vars (def)
621
622                 // ctor
623                 public Xcls_GestureClick6(Xcls_WindowLeftTree _owner )
624                 {
625                         _this = _owner;
626                         this.el = new Gtk.GestureClick();
627
628                         // my vars (dec)
629
630                         // set gobject values
631                         this.el.button = 3;
632
633                         //listeners
634                         this.el.pressed.connect( (n_press, x, y) => {
635                         
636                                 
637                                   
638                                  
639                             if (_this.model.el.get_n_items() < 1) {
640                          
641                                 GLib.debug("no items");
642                                     return ;
643                             }
644                             string pos;
645                             var row = _this.view.getRowAt(x,y, out pos );
646                             if (row < 0) {
647                                     GLib.debug("no row selected items");
648                                     return;
649                             }
650                             
651                             var node =   _this.selmodel.getNodeAt(row);
652                             if (node == null) {
653                                 GLib.warning("No node found at row %d", row);
654                                 return;
655                                 }
656                                 
657                                 
658                                 _this.model.selectNode(node);
659                              
660                              
661                              
662                                 GLib.debug("Prssed %d", (int)  this.el.get_current_button());
663                                 //_this.deletemenu.el.set_parent(_this.view.el);
664                                 _this.LeftTreeMenu.el.set_parent(_this.view.el);
665                                 
666                                 
667                                 //Gtk.Allocation rect;
668                                 //_this.view.el.get_allocation(out rect);
669                                 //_this.deletemenu.el.set_has_arrow(false);
670                                 _this.LeftTreeMenu.el.set_position(Gtk.PositionType.BOTTOM); 
671                                 
672                                         
673                                 _this.LeftTreeMenu.el.set_offset( 
674                                                 (int)x  ,
675                                                 (int)y - (int)_this.view.el.get_height());
676                         
677                             _this.LeftTreeMenu.el.popup();
678                               
679                         });
680                 }
681
682                 // user defined functions
683         }
684
685         public class Xcls_DragSource7 : Object
686         {
687                 public Gtk.DragSource el;
688                 private Xcls_WindowLeftTree  _this;
689
690
691                         // my vars (def)
692
693                 // ctor
694                 public Xcls_DragSource7(Xcls_WindowLeftTree _owner )
695                 {
696                         _this = _owner;
697                         this.el = new Gtk.DragSource();
698
699                         // my vars (dec)
700
701                         // set gobject values
702                         this.el.actions = Gdk.DragAction.COPY   | Gdk.DragAction.MOVE   ;
703
704                         //listeners
705                         this.el.drag_cancel.connect( (drag, reason) => {
706                         
707                                 _this.view.dragNode = null;
708                                 return true;
709                         });
710                         this.el.prepare.connect( (x, y) => {
711                         
712                                 
713                                 
714                         ///     ( drag_context, data, info, time) => {
715                                     
716                         
717                                 //print("drag-data-get");
718                                 var ndata = _this.selmodel.getSelectedNode();
719                                 if (ndata == null) {
720                                         GLib.debug("return empty string - no selection..");
721                                         return null;
722                                  
723                                 }
724                         
725                           
726                                 //data.set_text(tp,tp.length);   
727                         
728                                 var     str = ndata.toJsonString();
729                                 GLib.debug("prepare  store: %s", str);
730                                 GLib.Value ov = GLib.Value(typeof(string));
731                                 ov.set_string(str);
732                                 var cont = new Gdk.ContentProvider.for_value(ov);
733                             /*
734                                 GLib.Value v = GLib.Value(typeof(string));
735                                 //var str = drop.read_text( [ "text/plain" ] 0);
736                                  
737                                         cont.get_value(ref v);
738                                  
739                                 }
740                                 GLib.debug("set %s", v.get_string());
741                               */  
742                                 return cont;
743                                  
744                                  
745                         });
746                         this.el.drag_begin.connect( ( drag )  => {
747                                 GLib.debug("SOURCE: drag-begin");
748                                  
749                             // find what is selected in our tree...
750                             var data = _this.selmodel.getSelectedNode();
751                                 if (data == null) {
752                                         return  ;
753                                 }
754                                 _this.view.dragNode = data;
755                             var xname = data.fqn();
756                             GLib.debug ("XNAME  IS %s", xname);
757                         
758                                 var widget = _this.view.getWidgetAtRow(_this.selmodel.el.selected);
759                                 
760                                 
761                             var paintable = new Gtk.WidgetPaintable(widget);
762                             this.el.set_icon(paintable, 0,0);
763                                     
764                          
765                         });
766                         this.el.drag_end.connect( (drag, delete_data) => {
767                         
768                         _this.view.dragNode = null;
769                         });
770                 }
771
772                 // user defined functions
773         }
774
775         public class Xcls_EventControllerKey8 : Object
776         {
777                 public Gtk.EventControllerKey el;
778                 private Xcls_WindowLeftTree  _this;
779
780
781                         // my vars (def)
782
783                 // ctor
784                 public Xcls_EventControllerKey8(Xcls_WindowLeftTree _owner )
785                 {
786                         _this = _owner;
787                         this.el = new Gtk.EventControllerKey();
788
789                         // my vars (dec)
790
791                         // set gobject values
792
793                         //listeners
794                         this.el.key_pressed.connect( (keyval, keycode, state) => {
795                         
796                          
797                         
798                                 if (keyval != Gdk.Key.Delete && keyval != Gdk.Key.BackSpace)  {
799                                         return true;
800                                 }
801                         
802                                 _this.model.deleteSelected();
803                                 return true;
804                         
805                         });
806                 }
807
808                 // user defined functions
809         }
810
811         public class Xcls_keystate : Object
812         {
813                 public Gtk.EventControllerKey el;
814                 private Xcls_WindowLeftTree  _this;
815
816
817                         // my vars (def)
818                 public int is_shift;
819
820                 // ctor
821                 public Xcls_keystate(Xcls_WindowLeftTree _owner )
822                 {
823                         _this = _owner;
824                         _this.keystate = this;
825                         this.el = new Gtk.EventControllerKey();
826
827                         // my vars (dec)
828                         this.is_shift = 0;
829
830                         // set gobject values
831
832                         //listeners
833                         this.el.key_released.connect( (keyval, keycode, state) => {
834                                 GLib.debug("key release %d, %d, %d" , (int) keyval, (int)  keycode, state);
835                                 if (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {
836                                         this.is_shift = 0;
837                                 }
838                                 //GLib.debug("set state %d , shift = %d", (int)this.el.get_current_event_state(), Gdk.ModifierType.SHIFT_MASK);
839                         
840                         
841                          
842                         });
843                         this.el.key_pressed.connect( (keyval, keycode, state) => {
844                         
845                                 if (keyval == Gdk.Key.Shift_L || keyval == Gdk.Key.Shift_R) {
846                                         this.is_shift = 1;
847                                 }
848                                 return true;
849                         });
850                 }
851
852                 // user defined functions
853         }
854
855         public class Xcls_drop : Object
856         {
857                 public Gtk.DropTarget el;
858                 private Xcls_WindowLeftTree  _this;
859
860
861                         // my vars (def)
862                 public Gtk.Widget? highlightWidget;
863                 public JsRender.Node? lastDragNode;
864                 public string lastDragString;
865
866                 // ctor
867                 public Xcls_drop(Xcls_WindowLeftTree _owner )
868                 {
869                         _this = _owner;
870                         _this.drop = this;
871                         this.el = new Gtk.DropTarget ( typeof(string) ,
872                 Gdk.DragAction.COPY   | Gdk.DragAction.MOVE   );
873
874                         // my vars (dec)
875                         this.highlightWidget = null;
876                         this.lastDragNode = null;
877                         this.lastDragString = "\"\"";
878
879                         // set gobject values
880
881                         //listeners
882                         this.el.accept.connect( (drop) => {
883                         
884                                 GLib.debug("got DropTarget:accept");
885                          
886                         // NOT REALLY NEEDED? = put stuff in drop?
887                         
888                         
889                         /* (  ctx, x, y, time)  => {
890                               //Seed.print("TARGET: drag-drop");
891                            
892                            
893                             var src = Gtk.drag_get_source_widget(ctx);
894                              
895                            if (src != this.el) {
896                            
897                             
898                                
899                                this.drag_in_motion = false;   
900                                     // request data that will be recieved by the recieve...              
901                                 Gtk.drag_get_data
902                                 (
903                                         this.el,         // will receive 'drag-data-received' signal 
904                                         ctx,        // represents the current state of the DnD 
905                                         Gdk.Atom.intern("application/json",true),    // the target type we want 
906                                         time            // time stamp 
907                                 );
908                         
909                                  
910                                 // No target offered by source => error
911                            
912                         
913                                  return  false;
914                              }
915                              
916                              // handle drop around self..
917                              
918                                           
919                                     
920                             //print("GETTING POS");
921                             var  targetData = "";
922                             
923                             Gtk.TreePath path;
924                             Gtk.TreeViewDropPosition pos;
925                             var isOver = _this.view.el.get_dest_row_at_pos(this.drag_x,this.drag_y, out path, out pos);
926                             
927                             // if there are not items in the tree.. the we have to set isOver to true for anything..
928                             var isEmpty = false;
929                             if (_this.model.el.iter_n_children(null) < 1) {
930                                 print("got NO children?\n");
931                                 isOver = true; //??? 
932                                 isEmpty = true;
933                                 pos = Gtk.TreeViewDropPosition.INTO_OR_AFTER;
934                             }
935                             
936                              
937                              
938                             //var action = Gdk.DragAction.COPY;
939                                 // unless we are copying!!! ctl button..
940                             
941                             var action = (ctx.get_actions() & Gdk.DragAction.MOVE) > 0 ?
942                                          Gdk.DragAction.COPY  : Gdk.DragAction.MOVE ;
943                                         // Gdk.DragAction.MOVE : Gdk.DragAction.COPY ;
944                         
945                               
946                             if (_this.model.el.iter_n_children(null) < 1) {
947                                 // no children.. -- asume it's ok..
948                                 
949                                 targetData = "|%d|".printf((int)Gtk.TreeViewDropPosition.INTO_OR_AFTER);
950                                  
951                                 // continue through to allow drop...
952                         
953                             } else {
954                                         
955                                         
956                             
957                                         
958                                         
959                                         //print("ISOVER? " + isOver);
960                                 if (!isOver) {
961                                     
962                                     Gtk.drag_finish (ctx, false, false, time);        // drop failed..
963                                     return true; // not over apoint!?! - no action on drop or motion..
964                                 }
965                                         
966                                 // drag node is parent of child..
967                                 //console.log("SRC TREEPATH: " + src.treepath);
968                                 //console.log("TARGET TREEPATH: " + data.path.to_string());
969                                 
970                                 // nned to check a  few here..
971                                 //Gtk.TreeViewDropPosition.INTO_OR_AFTER
972                                 //Gtk.TreeViewDropPosition.INTO_OR_BEFORE
973                                 //Gtk.TreeViewDropPosition.AFTER
974                                 //Gtk.TreeViewDropPosition.BEFORE
975                                 
976                                 // locally dragged items to not really use the 
977                                 var selection_text = this.dragData;
978                                 
979                                 
980                                 
981                                 if (selection_text == null || selection_text.length < 1) {
982                                     //print("Error  - drag selection text returned NULL");
983                                   
984                                      Gtk.drag_finish (ctx, false, false, time);        // drop failed..
985                                      return true; /// -- fixme -- this is not really correct..
986                                 }                
987                                         
988                                         // see if we are dragging into ourself?
989                                         print ("got selection text of  " + selection_text);
990                                 
991                                 var target_path = path.to_string();
992                                 //print("target_path="+target_path);
993                         
994                                 // 
995                                 if (selection_text  == target_path) {
996                                     print("self drag ?? == we should perhaps allow copy onto self..\n");
997                                     
998                                      Gtk.drag_finish (ctx, false, false, time);        // drop failed..
999                         
1000                                      return true; /// -- fixme -- this is not really correct..
1001                         
1002                                 }
1003                                         
1004                                 // check that 
1005                                 //print("DUMPING DATA");
1006                                 //console.dump(data);
1007                                 // path, pos
1008                                 
1009                                 //print(data.path.to_string() +' => '+  data.pos);
1010                                 
1011                                 // dropList is a list of xtypes that this node could be dropped on.
1012                                 // it is set up when we start to drag..
1013                                 
1014                                 
1015                                 targetData = _this.model.findDropNodeByPath( path.to_string(), this.dropList, pos);
1016                                     
1017                                 print("targetDAta: " + targetData +"\n");
1018                                 
1019                                 if (targetData.length < 1) {
1020                                     //print("Can not find drop node path");
1021                                      
1022                                     Gtk.drag_finish (ctx, false, false, time);        // drop failed..
1023                                     return true;
1024                                 }
1025                                             
1026                                         
1027                                         
1028                                         // continue on to allow drop..
1029                           }
1030                                 // at this point, drag is not in motion... -- as checked above... - so it's a real drop event..
1031                         
1032                         
1033                              var delete_selection_data = false;
1034                                 
1035                             if (action == Gdk.DragAction.ASK)  {
1036                                 // Ask the user to move or copy, then set the ctx action. 
1037                             }
1038                         
1039                             if (action == Gdk.DragAction.MOVE) {
1040                                 delete_selection_data = true;
1041                             }
1042                               
1043                                         // drag around.. - reorder..
1044                             _this.model.moveNode(targetData, action);
1045                                 
1046                                
1047                                 
1048                                 
1049                                 
1050                                 // we can send stuff to souce here...
1051                         
1052                         
1053                         // do we always say failure, so we handle the reall drop?
1054                             Gtk.drag_finish (ctx, false, false,time); //delete_selection_data, time);
1055                         
1056                             return true;
1057                          
1058                          
1059                          
1060                          
1061                          
1062                          
1063                         }
1064                         */
1065                                 return true;
1066                         });
1067                         this.el.motion.connect( (  x, y) => {
1068                          
1069                                 var is_shift = _this.keystate.is_shift > 0;
1070                                 
1071                                 //GLib.debug("shift is    %s", _this.keystate.is_shift > 0 ? "SHIFT" : "-");
1072                                 string pos; // over / before / after..
1073                         
1074                             //GLib.debug("got drag motion");
1075                         
1076                             GLib.Value v = GLib.Value(typeof(string));
1077                                 //var str = drop.read_text( [ "text/plain" ] 0);
1078                                 var cont = this.el.current_drop.get_drag().content ;
1079                                 try {
1080                                         cont.get_value(ref v);
1081                                 } catch (GLib.Error e) {
1082                                    // GLib.debug("failed to get drag value");
1083                                         return Gdk.DragAction.COPY;      
1084                                 
1085                                 }
1086                          
1087                                 //GLib.debug("got %s", v.get_string());
1088                                   
1089                                 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
1090                                         // still dragging same node
1091                          
1092                                         this.lastDragNode = new JsRender.Node(); 
1093                                         this.lastDragNode.loadFromJsonString(v.get_string(), 1);
1094                                 }
1095                             
1096                         
1097                                 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(
1098                                                         this.lastDragNode.fqn());
1099                              
1100                              string[] str = {};
1101                              foreach(var dp in drop_on_to) {
1102                                 str += dp;
1103                                 }
1104                                 //GLib.debug("droplist: %s", string.joinv(", ", str));
1105                              
1106                              
1107                             // if there are not items in the tree.. the we have to set isOver to true for anything..
1108                          
1109                             if (_this.model.el.n_items < 1) {
1110                                 // FIXME check valid drop types?
1111                                 if (drop_on_to.contains("*top")) {
1112                                                 this.addHighlight(_this.view.el, "over");
1113                                         } else {
1114                                                 this.addHighlight(null, "");            
1115                                         }
1116                         
1117                                         return Gdk.DragAction.COPY; // no need to highlight?
1118                              
1119                             }
1120                             
1121                             
1122                         
1123                                  
1124                             // if path of source and dest are inside each other..
1125                             // need to add source info to drag?
1126                             // the fail();
1127                                 var row = _this.view.getRowAt(x,y, out pos);
1128                                 //GLib.debug("check is over %d, %d, %s", (int)x,(int)y, pos);
1129                         
1130                                 if (row < 0) {
1131                                         this.addHighlight(null, "");    
1132                                         return Gdk.DragAction.COPY;
1133                                 }
1134                                 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1135                                 
1136                                 var node =  (JsRender.Node)tr.get_item();
1137                                 
1138                                 //GLib.debug("Drop over node: %s", node.fqn());
1139                                 
1140                         
1141                                 if (pos == "above" || pos == "below") {
1142                                         if (node.parent == null) {
1143                                                 //GLib.debug("no parent try center");
1144                                                 pos = "over";
1145                                         } else {
1146                                                  
1147                                                 if (!drop_on_to.contains(node.parent.fqn())) {
1148                                                         //GLib.debug("drop on does not contain %s - try center" , node.parent.fqn());
1149                                                         pos = "over";
1150                                                 } else {
1151                                                         //GLib.debug("drop  contains %s - using %s" , node.parent.fqn(), pos);
1152                                                         if (_this.view.dragNode  != null && is_shift) {
1153                                                                 if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
1154                                                                         GLib.debug("shift drop not self not allowed");
1155                                                                         this.addHighlight(null, "");
1156                                                                         return Gdk.DragAction.COPY;     
1157                                                                 }
1158                                                                 
1159                                                         }
1160                                                         
1161                                                 }
1162                                                 
1163                                                 
1164                                                 
1165                                         }
1166                                         
1167                                         
1168                                 }
1169                                 if (pos == "over") {
1170                                         if (!drop_on_to.contains(node.fqn())) {
1171                                                 //GLib.debug("drop on does not contain %s - try center" , node.fqn());
1172                                                 this.addHighlight(null, ""); 
1173                                                 return is_shift ?  Gdk.DragAction.MOVE :  Gdk.DragAction.COPY;          
1174                                         }
1175                                         if (_this.view.dragNode  != null && is_shift) {
1176                                                 if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
1177                                                         //GLib.debug("shift drop not self not allowed");
1178                                                         this.addHighlight(null, "");
1179                                                         return Gdk.DragAction.COPY;     
1180                                                 }
1181                                         }
1182                                                 
1183                                 }
1184                                 
1185                                 
1186                                     // _this.view.highlightDropPath("", (Gtk.TreeViewDropPosition)0);
1187                                 var w = _this.view.getWidgetAt(x,y);
1188                                 this.addHighlight(w, pos); 
1189                                 return is_shift ?  Gdk.DragAction.MOVE :  Gdk.DragAction.COPY;          
1190                         });
1191                         this.el.leave.connect( ( ) => {
1192                                 this.addHighlight(null,"");
1193                         
1194                         });
1195                         this.el.drop.connect( (v, x, y) => {
1196                                 
1197                                 // must get the pos before we clear the hightlihg.
1198                                 var pos = "";
1199                                 var row = _this.view.getRowAt(x,y, out pos);
1200                                 this.addHighlight(null,"");
1201                          
1202                                 var is_shift = _this.keystate.is_shift > 0;
1203                          
1204                         
1205                                 // -- get position..
1206                                 if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
1207                                         // still dragging same node
1208                          
1209                                         this.lastDragNode = new JsRender.Node(); 
1210                                         this.lastDragNode.loadFromJsonString(v.get_string(), 1);
1211                                 }
1212                             
1213                                      
1214                                
1215                             var dropNode = new JsRender.Node(); 
1216                                 dropNode.loadFromJsonString(v.get_string(), 2);
1217                                 GLib.debug("dropped node %s", dropNode.toJsonString());
1218                                 
1219                                 
1220                                 var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(dropNode.fqn());
1221                            
1222                             // if there are not items in the tree.. the we have to set isOver to true for anything..
1223                          
1224                             if (_this.model.el.n_items < 1) {
1225                                 // FIXME check valid drop types?
1226                                 if (!drop_on_to.contains("*top")) {
1227                                                 GLib.debug("drop on to list does not contain top?");
1228                                                 return false;   
1229                                         }
1230                                         // add new node to top..
1231                                         GLib.debug("adding to top");
1232                                         
1233                                          var m = (GLib.ListStore) _this.model.el.model;
1234                                 _this.main_window.windowstate.file.tree = dropNode;  
1235                                 dropNode.updated_count++;
1236                            
1237                                         m.append(dropNode);
1238                                         _this.model.selectNode(dropNode);       
1239                                         _this.changed();
1240                                         _this.node_selected(dropNode);
1241                                         return true; // no need to highlight?
1242                              
1243                             }
1244                         
1245                         
1246                         
1247                         
1248                                 if (row < 0) {
1249                                         GLib.debug("could not get row %d,%d, %s", (int)x,(int)y,pos);
1250                                         return   false; //Gdk.DragAction.COPY;
1251                                 }
1252                                 var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
1253                                 
1254                                 var node =  (JsRender.Node)tr.get_item();
1255                         
1256                                 if (pos == "above" || pos == "below") {
1257                                         if (node.parent == null) {
1258                                                 pos = "over";
1259                                         } else {
1260                                                 if (!drop_on_to.contains(node.parent.fqn())) {
1261                                                         pos = "over";
1262                                                 } else {
1263                                                         GLib.debug("drop  contains %s - using %s" , node.parent.fqn(), pos);
1264                                                         if (_this.view.dragNode  != null && is_shift) {
1265                                                                 if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
1266                                                                         GLib.debug("shift drop not self not allowed");
1267                                                                         return false;   
1268                                                                 }
1269                                                                 
1270                                                         }
1271                                                         
1272                                                         
1273                                                 }
1274                                         }
1275                                         
1276                                 }
1277                                 if (pos == "over") {
1278                                         if (!drop_on_to.contains(node.fqn())) {
1279                                                 GLib.debug("drop on does not contain %s - try center" , node.fqn());
1280                                                 return false;
1281                         
1282                                         }
1283                                         if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
1284                                                 GLib.debug("shift drop not self not allowed");
1285                                                 return false;   
1286                                         }
1287                                 }
1288                                 
1289                                 switch(pos) {
1290                                         case "over":
1291                         
1292                                                 if (is_shift && _this.view.dragNode != null) {
1293                                                         _this.model.selectNode(null); 
1294                                                         _this.view.dragNode.remove();
1295                                                 }
1296                                                 node.appendChild(dropNode);                     
1297                                                 dropNode.updated_count++;
1298                                                 _this.model.selectNode(dropNode); 
1299                                                 
1300                                                 _this.changed();                                                
1301                                                 return true;
1302                                                 
1303                                         case "above":
1304                                                 GLib.debug("Above - insertBefore");
1305                                         
1306                         
1307                                                 if (is_shift && _this.view.dragNode != null) {
1308                                                         _this.model.selectNode(null);                   
1309                                                         _this.view.dragNode.remove();
1310                                                 }
1311                                                 node.parent.insertBefore(dropNode, node);                       
1312                                                 dropNode.updated_count++;
1313                                                 _this.model.selectNode(dropNode);                       
1314                                                 _this.changed();
1315                                                 return true;
1316                                                 
1317                                         case "below":
1318                                                 GLib.debug("Below - insertAfter");              
1319                                                 if (is_shift && _this.view.dragNode != null) {
1320                                                         _this.model.selectNode(null);                   
1321                                                         _this.view.dragNode.remove();
1322                                                 }
1323                                 
1324                                                 
1325                                                 node.parent.insertAfter(dropNode, node);
1326                                                 dropNode.updated_count++;
1327                                                 _this.model.selectNode(dropNode);       
1328                                                 _this.changed();
1329                                                 // select it
1330                                                 return true;
1331                                                 
1332                                         default:
1333                                                 // should not happen
1334                                                 return false;
1335                                 }
1336                                 
1337                                 
1338                              
1339                                         
1340                                         
1341                         
1342                         });
1343                 }
1344
1345                 // user defined functions
1346                 public void addHighlight (Gtk.Widget? w, string hl) {
1347                         if (this.highlightWidget != null) {
1348                                 var ww  = this.highlightWidget;
1349                                 //GLib.debug("clear drag from previous highlight");
1350                                 if (ww.has_css_class("drag-below")) {
1351                                          ww.remove_css_class("drag-below");
1352                                 }
1353                                 if (ww.has_css_class("drag-above")) {
1354                                          ww.remove_css_class("drag-above");
1355                                 }
1356                                 if (ww.has_css_class("drag-over")) {
1357                                          ww.remove_css_class("drag-over");
1358                                 }
1359                         }
1360                         if (w != null) {
1361                                 //GLib.debug("add drag=%s to widget", hl);      
1362                                 if (!w.has_css_class("drag-" + hl)) {
1363                                         w.add_css_class("drag-" + hl);
1364                                 }
1365                         }
1366                         this.highlightWidget = w;
1367                 }
1368         }
1369
1370         public class Xcls_selmodel : Object
1371         {
1372                 public Gtk.SingleSelection el;
1373                 private Xcls_WindowLeftTree  _this;
1374
1375
1376                         // my vars (def)
1377
1378                 // ctor
1379                 public Xcls_selmodel(Xcls_WindowLeftTree _owner )
1380                 {
1381                         _this = _owner;
1382                         _this.selmodel = this;
1383                         new Xcls_model( _this );
1384                         this.el = new Gtk.SingleSelection( _this.model.el );
1385
1386                         // my vars (dec)
1387
1388                         // set gobject values
1389                         this.el.can_unselect = true;
1390
1391                         //listeners
1392                         this.el.selection_changed.connect( (position, n_items) => {
1393                         
1394                                 
1395                                         
1396                                         //if (!this.button_is_pressed && !this.key_is_pressed) {
1397                                                 // then event was started by some other action
1398                                                 // which should manually trigger all the events..
1399                                         //      print("SKIPPING select - no button or key pressed\n");
1400                                         //      return;
1401                                         //}
1402                         
1403                         
1404                                          if (_this.view.blockChanges) { // probably not needed.. 
1405                                                 GLib.debug("SKIPPING select - blockchanges set..");     
1406                                            return  ;
1407                                          }
1408                         
1409                                           if (!_this.before_node_change( ) ) {
1410                                                  _this.view.blockChanges = true;
1411                                                  _this.selmodel.el.unselect_all();
1412                                                  _this.view.blockChanges = false;
1413                                                  
1414                                                  return;
1415                                          }
1416                                          if (_this.main_window.windowstate.file == null) {
1417                                                 GLib.debug("SKIPPING select windowstate file is not set...");     
1418                                                 return;
1419                                          } 
1420                                          
1421                                          //var render = this.get('/LeftTree').getRenderer();                
1422                                         GLib.debug("LEFT TREE -> view -> selection changed called");
1423                                         
1424                                         
1425                                         // -- it appears that the selection is not updated.
1426                                          // select the node...
1427                                          //_this.selmodel.el.set_selected(row);
1428                          
1429                                          GLib.debug("LEFT TREE -> view -> selection changed TIMEOUT CALLED");
1430                         
1431                                     var snode = _this.selmodel.getSelectedNode();
1432                                     if (snode == null) {
1433                         
1434                                          GLib.debug("selected rows < 1");
1435                                         //??this.model.load( false);
1436                                         _this.node_selected(null);
1437                                         
1438                                         return   ;
1439                                     }
1440                                  
1441                                     // why dup_?
1442                                     
1443                         
1444                                     GLib.debug ("calling left_tree.node_selected %s", snode.toJsonString());
1445                                     _this.node_selected(snode);
1446                                    
1447                                      
1448                                     
1449                                      
1450                                     // no need to scroll. it's in the view as we clicked on it.
1451                                    // _this.view.el.scroll_to_cell(new Gtk.TreePath.from_string(_this.model.activePath), null, true, 0.1f,0.0f);
1452                                     
1453                                     return  ;
1454                         });
1455                 }
1456
1457                 // user defined functions
1458                 public JsRender.Node? getSelectedNode () {
1459                   if (this.el.selected_item == null) {
1460                                 return null;
1461                   }     
1462                    
1463                   
1464                    var tr = (Gtk.TreeListRow)this.el.selected_item;
1465                   
1466                    return (JsRender.Node)tr.get_item();
1467                          
1468                 }
1469                 public JsRender.Node getNodeAt (uint row) {
1470                 
1471                    var tr = (Gtk.TreeListRow)this.el.get_item(row);
1472                    
1473                    var a = tr.get_item();;   
1474                    GLib.debug("get_item (2) = %s", a.get_type().name());
1475                         
1476                    
1477                    return (JsRender.Node)tr.get_item();
1478                          
1479                 }
1480         }
1481         public class Xcls_model : Object
1482         {
1483                 public Gtk.TreeListModel el;
1484                 private Xcls_WindowLeftTree  _this;
1485
1486
1487                         // my vars (def)
1488
1489                 // ctor
1490                 public Xcls_model(Xcls_WindowLeftTree _owner )
1491                 {
1492                         _this = _owner;
1493                         _this.model = this;
1494                         this.el = this.updateModel(null);
1495
1496                         // my vars (dec)
1497
1498                         // set gobject values
1499                 }
1500
1501                 // user defined functions
1502                 public void loadFile (JsRender.JsRender f) {
1503                     //console.dump(f);
1504                     
1505                     _this.drop.highlightWidget = null;
1506                     
1507                     var m = (GLib.ListStore) this.el.model;
1508                         m.remove_all();
1509                     _this.main_window.windowstate.leftTreeNodeSelected(null);
1510                     // needed???
1511                     _this.main_window.windowstate.file = f;
1512                     _this.last_error_counter = -1;
1513                    
1514                     if (f.tree == null) {
1515                             try {
1516                                 f.loadItems( );
1517                         } catch (Error e) {
1518                                 return;
1519                         }
1520                     }
1521                     // if it's still null?
1522                     if (f.tree == null) {
1523                                 _this.main_window.windowstate.showAddObject(_this.view.el, null);
1524                         _this.updateErrors();
1525                         return;
1526                     }
1527                         m.append(f.tree);
1528                         _this.updateErrors();
1529                  
1530                     _this.selmodel.el.set_selected(Gtk.INVALID_LIST_POSITION);
1531                    
1532                     return;
1533                  
1534                             
1535                 }
1536                 public int nodeToRow (JsRender.Node node) 
1537                 {
1538                  
1539                         var s = _this.view.el.model as Gtk.SingleSelection;
1540                         for (var i = 0; i < s.n_items; i++) {
1541                                 //GLib.debug("check node %s", s.get_item(i).get_type().name());
1542                                 var lr = s.get_item(i) as Gtk.TreeListRow;
1543                                 //GLib.debug("check node %s", lr.get_item().get_type().name());
1544                                 var nn = (lr.get_item() as JsRender.Node);
1545                                 if (nn != null && nn.oid == node.oid) {
1546                                         return i;
1547                                         
1548                                 }
1549                         }
1550                         return -1;                      
1551                         
1552                 
1553                 }
1554                 public void deleteSelected () {
1555                 
1556                 
1557                         
1558                         var node = _this.selmodel.getSelectedNode();
1559                         
1560                 
1561                      if (node == null) {
1562                         GLib.debug("delete Selected - no node slected?");
1563                              return;
1564                      }
1565                     _this.selmodel.el.unselect_all();
1566                     if (node.parent != null) {
1567                                 node.remove();
1568                                 GLib.debug("delete Selected - done");
1569                                 _this.changed();
1570                                 return;
1571                         }
1572                         this.updateModel(null);
1573                         _this.main_window.windowstate.file.tree = null;
1574                         _this.changed();
1575                         _this.node_selected(null);
1576                 /*    
1577                     print("DELETE SELECTED?");
1578                     //_this.view.blockChanges = true;
1579                     print("GET SELECTION?");
1580                 
1581                     var s = _this.view.el.get_selection();
1582                     
1583                     print("GET  SELECTED?");
1584                    Gtk.TreeIter iter;
1585                     Gtk.TreeModel mod;
1586                 
1587                     
1588                     if (!s.get_selected(out mod, out iter)) {
1589                         return; // nothing seleted..
1590                     }
1591                       
1592                 
1593                 
1594                     this.activePath= "";      
1595                     print("GET  vnode value?");
1596                 
1597                     GLib.Value value;
1598                     this.el.get_value(iter, 2, out value);
1599                     var data = (JsRender.Node)(value.get_object());
1600                     print("removing node from Render\n");
1601                     if (data.parent == null) {
1602                        _this.main_window.windowstate.file.tree = null;
1603                     } else {
1604                         data.remove();
1605                     }
1606                     print("removing node from Tree\n");    
1607                     s.unselect_all();
1608                     this.el.remove(ref iter);
1609                 
1610                     
1611                     
1612                     
1613                     // 
1614                     
1615                     
1616                 
1617                 
1618                     this.activePath= ""; // again!?!?      
1619                     //this.changed(null,true);
1620                     
1621                     _this.changed();
1622                     
1623                     _this.view.blockChanges = false;
1624                     */
1625                 }
1626                 public Gtk.TreeListModel updateModel (GLib.ListStore? m) {
1627                         this.el = new Gtk.TreeListModel(
1628                                 m != null ? m : new GLib.ListStore(typeof(JsRender.Node)), //..... << that's our store..
1629                                 false, // passthru
1630                                 true, // autexpand
1631                                 (item) => {
1632                                         return ((JsRender.Node)item).childstore;
1633                                 
1634                                 }
1635                         );
1636                         if (_this.selmodel.el == null) {
1637                                 return this.el;
1638                         }
1639                         _this.selmodel.el.set_model(this.el);
1640                         return this.el;
1641                 }
1642                 public void selectNode (JsRender.Node?  node) 
1643                 {
1644                         var s = _this.view.el.model as Gtk.SingleSelection;
1645                         if (node == null) {
1646                                 s.selected=Gtk.INVALID_LIST_POSITION;
1647                                 return;
1648                         }
1649                         var row = this.nodeToRow(node);
1650                 
1651                          
1652                         if (row < 0) {
1653                                 // select none?
1654                                 GLib.debug("Could not find node");
1655                                 s.selected=Gtk.INVALID_LIST_POSITION;
1656                                 return;
1657                         }
1658                         GLib.debug("Select %d", row);
1659                         s.set_selected(row);
1660                         _this.view.el.scroll_to(row, null, Gtk.ListScrollFlags.SELECT, null);
1661                         //_this.node_selected(node);                    
1662                         
1663                 
1664                 }
1665         }
1666
1667
1668         public class Xcls_maincol : Object
1669         {
1670                 public Gtk.ColumnViewColumn el;
1671                 private Xcls_WindowLeftTree  _this;
1672
1673
1674                         // my vars (def)
1675
1676                 // ctor
1677                 public Xcls_maincol(Xcls_WindowLeftTree _owner )
1678                 {
1679                         _this = _owner;
1680                         _this.maincol = this;
1681                         var child_1 = new Xcls_SignalListItemFactory14( _this );
1682                         child_1.ref();
1683                         this.el = new Gtk.ColumnViewColumn( "Property", child_1.el );
1684
1685                         // my vars (dec)
1686
1687                         // set gobject values
1688                         this.el.id = "maincol";
1689                         this.el.expand = true;
1690                         this.el.resizable = true;
1691                 }
1692
1693                 // user defined functions
1694         }
1695         public class Xcls_SignalListItemFactory14 : Object
1696         {
1697                 public Gtk.SignalListItemFactory el;
1698                 private Xcls_WindowLeftTree  _this;
1699
1700
1701                         // my vars (def)
1702
1703                 // ctor
1704                 public Xcls_SignalListItemFactory14(Xcls_WindowLeftTree _owner )
1705                 {
1706                         _this = _owner;
1707                         this.el = new Gtk.SignalListItemFactory();
1708
1709                         // my vars (dec)
1710
1711                         // set gobject values
1712
1713                         //listeners
1714                         this.el.setup.connect( (listitem) => {
1715                                 
1716                                 var expand = new Gtk.TreeExpander();
1717                                  
1718                                 expand.set_indent_for_depth(true);
1719                                 expand.set_indent_for_icon(true);
1720                                 var hbox = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);
1721                                 var icon = new Gtk.Image();
1722                                 var lbl = new Gtk.Label("");
1723                                 lbl.use_markup = true;
1724                                 lbl.ellipsize = Pango.EllipsizeMode.END;
1725                                 
1726                                 icon.margin_end = 4;
1727                                 lbl.justify = Gtk.Justification.LEFT;
1728                                 lbl.xalign = 0;
1729                         
1730                         //      listitem.activatable = true; ??
1731                                 
1732                                 hbox.append(icon);
1733                                 hbox.append(lbl);
1734                                 expand.set_child(hbox);
1735                                 ((Gtk.ListItem)listitem).set_child(expand);
1736                                 
1737                         });
1738                         this.el.bind.connect( (listitem) => {
1739                                 // GLib.debug("listitme is is %s", ((Gtk.ListItem)listitem).get_type().name());
1740                                 
1741                                 //var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
1742                                 var expand = (Gtk.TreeExpander)  ((Gtk.ListItem)listitem).get_child();
1743                                  
1744                                  
1745                                 var hbox = (Gtk.Box) expand.child;
1746                          
1747                                 
1748                                 var img = (Gtk.Image) hbox.get_first_child();
1749                                 var lbl = (Gtk.Label) img.get_next_sibling();
1750                                 
1751                                 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1752                                 var node = (JsRender.Node) lr.get_item();
1753                                 if (node == null || node.fqn() == "") {
1754                                         return;
1755                                 }
1756                            //GLib.debug("node is %s", node.get_type().name());
1757                         // was item (1) in old layout
1758                         
1759                                 
1760                          
1761                                  /* 
1762                                 var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1763                             var clsname = node.fqn();
1764                             
1765                             var clsb = clsname.split(".");
1766                             var sub = clsb.length > 1 ? clsb[1].down()  : "";
1767                              
1768                             var fn = "/usr/share/glade/pixmaps/hicolor/16x16/actions/widget-gtk-" + sub + ".png";
1769                             try { 
1770                                  
1771                                          
1772                                         if (FileUtils.test (fn, FileTest.IS_REGULAR)) {
1773                                             img.set_from_file(fn);
1774                                                  
1775                                         } else {
1776                                                 img.set_from_paintable(
1777                                                         ic.lookup_icon (
1778                                                                 "media-playback-stop", null,  16,1, 
1779                                                          Gtk.TextDirection.NONE, 0
1780                                                 )
1781                                                  );
1782                                         }
1783                                 } catch (GLib.Error e) {}
1784                             */
1785                             expand.set_hide_expander( !node.hasChildren() );
1786                                 expand.set_list_row(lr);
1787                                 
1788                                 node.bind_property("iconResourceName",
1789                                             img, "resource",
1790                                            GLib.BindingFlags.SYNC_CREATE);
1791                                 
1792                                 node.bind_property("nodeTitleProp",
1793                                             lbl, "label",
1794                                            GLib.BindingFlags.SYNC_CREATE);
1795                                 node.bind_property("nodeTipProp",
1796                                             lbl, "tooltip_markup",
1797                                            GLib.BindingFlags.SYNC_CREATE);
1798                                 // bind image...
1799                                 
1800                         });
1801                 }
1802
1803                 // user defined functions
1804         }
1805
1806
1807         public class Xcls_ColumnViewColumn15 : Object
1808         {
1809                 public Gtk.ColumnViewColumn el;
1810                 private Xcls_WindowLeftTree  _this;
1811
1812
1813                         // my vars (def)
1814
1815                 // ctor
1816                 public Xcls_ColumnViewColumn15(Xcls_WindowLeftTree _owner )
1817                 {
1818                         _this = _owner;
1819                         var child_1 = new Xcls_SignalListItemFactory16( _this );
1820                         child_1.ref();
1821                         this.el = new Gtk.ColumnViewColumn( "Add", child_1.el );
1822
1823                         // my vars (dec)
1824
1825                         // set gobject values
1826                         this.el.fixed_width = 25;
1827                 }
1828
1829                 // user defined functions
1830         }
1831         public class Xcls_SignalListItemFactory16 : Object
1832         {
1833                 public Gtk.SignalListItemFactory el;
1834                 private Xcls_WindowLeftTree  _this;
1835
1836
1837                         // my vars (def)
1838
1839                 // ctor
1840                 public Xcls_SignalListItemFactory16(Xcls_WindowLeftTree _owner )
1841                 {
1842                         _this = _owner;
1843                         this.el = new Gtk.SignalListItemFactory();
1844
1845                         // my vars (dec)
1846
1847                         // set gobject values
1848
1849                         //listeners
1850                         this.el.setup.connect( (listitem) => {
1851                         
1852                                  
1853                                 var icon = new Gtk.Image();
1854                                  
1855                                 ((Gtk.ListItem)listitem).set_child(icon);
1856                         });
1857                         this.el.bind.connect( (listitem) => {
1858                         
1859                                 var img = (Gtk.Image) ((Gtk.ListItem)listitem).get_child(); 
1860                                 var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
1861                                 var node = (JsRender.Node) lr.get_item();
1862                                 
1863                           
1864                             var ic = Gtk.IconTheme.get_for_display(_this.el.get_display());
1865                                 img.set_from_paintable(
1866                                         ic.lookup_icon (
1867                                                 "list-add", null,  16,1, 
1868                                                  Gtk.TextDirection.NONE, 0
1869                                         )
1870                                  );
1871                                  
1872                                 var fqn = node.fqn();
1873                             var cn = _this.main_window.windowstate.project.palete.getChildList(fqn, false);
1874                         
1875                                 img.set_visible(cn.size > 0 ? true : false);
1876                                  
1877                         });
1878                 }
1879
1880                 // user defined functions
1881         }
1882
1883
1884
1885         public class Xcls_LeftTreeMenu : Object
1886         {
1887                 public Gtk.Popover el;
1888                 private Xcls_WindowLeftTree  _this;
1889
1890
1891                         // my vars (def)
1892
1893                 // ctor
1894                 public Xcls_LeftTreeMenu(Xcls_WindowLeftTree _owner )
1895                 {
1896                         _this = _owner;
1897                         _this.LeftTreeMenu = this;
1898                         this.el = new Gtk.Popover();
1899
1900                         // my vars (dec)
1901
1902                         // set gobject values
1903                         var child_1 = new Xcls_Box18( _this );
1904                         child_1.ref();
1905                         this.el.child = child_1.el;
1906                 }
1907
1908                 // user defined functions
1909         }
1910         public class Xcls_Box18 : Object
1911         {
1912                 public Gtk.Box el;
1913                 private Xcls_WindowLeftTree  _this;
1914
1915
1916                         // my vars (def)
1917
1918                 // ctor
1919                 public Xcls_Box18(Xcls_WindowLeftTree _owner )
1920                 {
1921                         _this = _owner;
1922                         this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
1923
1924                         // my vars (dec)
1925
1926                         // set gobject values
1927                         var child_1 = new Xcls_Button19( _this );
1928                         child_1.ref();
1929                         this.el.append( child_1.el );
1930                         var child_2 = new Xcls_Button20( _this );
1931                         child_2.ref();
1932                         this.el.append( child_2.el );
1933                         var child_3 = new Xcls_Button21( _this );
1934                         child_3.ref();
1935                         this.el.append( child_3.el );
1936                 }
1937
1938                 // user defined functions
1939         }
1940         public class Xcls_Button19 : Object
1941         {
1942                 public Gtk.Button el;
1943                 private Xcls_WindowLeftTree  _this;
1944
1945
1946                         // my vars (def)
1947
1948                 // ctor
1949                 public Xcls_Button19(Xcls_WindowLeftTree _owner )
1950                 {
1951                         _this = _owner;
1952                         this.el = new Gtk.Button();
1953
1954                         // my vars (dec)
1955
1956                         // set gobject values
1957                         this.el.has_frame = false;
1958                         this.el.label = "Delete Element";
1959
1960                         //listeners
1961                         this.el.clicked.connect( ( ) => {
1962                         _this.LeftTreeMenu.el.hide();
1963                          _this.model.deleteSelected();
1964                         _this.changed();
1965                         });
1966                 }
1967
1968                 // user defined functions
1969         }
1970
1971         public class Xcls_Button20 : Object
1972         {
1973                 public Gtk.Button el;
1974                 private Xcls_WindowLeftTree  _this;
1975
1976
1977                         // my vars (def)
1978
1979                 // ctor
1980                 public Xcls_Button20(Xcls_WindowLeftTree _owner )
1981                 {
1982                         _this = _owner;
1983                         this.el = new Gtk.Button();
1984
1985                         // my vars (dec)
1986
1987                         // set gobject values
1988                         this.el.has_frame = false;
1989                         this.el.label = "Save as Template";
1990
1991                         //listeners
1992                         this.el.clicked.connect( () => {
1993                         _this.LeftTreeMenu.el.hide();
1994                              DialogSaveTemplate.singleton().showIt(
1995                                     (Gtk.Window) _this.el.get_root (), 
1996                                     _this.main_window.windowstate.file.palete(), 
1997                                     _this.getActiveElement()
1998                             );
1999                              
2000                             
2001                         });
2002                 }
2003
2004                 // user defined functions
2005         }
2006
2007         public class Xcls_Button21 : Object
2008         {
2009                 public Gtk.Button el;
2010                 private Xcls_WindowLeftTree  _this;
2011
2012
2013                         // my vars (def)
2014
2015                 // ctor
2016                 public Xcls_Button21(Xcls_WindowLeftTree _owner )
2017                 {
2018                         _this = _owner;
2019                         this.el = new Gtk.Button();
2020
2021                         // my vars (dec)
2022
2023                         // set gobject values
2024                         this.el.has_frame = false;
2025                         this.el.label = "Save as Module";
2026
2027                         //listeners
2028                         this.el.clicked.connect( () => {
2029                             
2030                             _this.LeftTreeMenu.el.hide();
2031                             var node = _this.getActiveElement();
2032                               
2033                              
2034                              var sm = DialogSaveModule.singleton();
2035                              
2036                              
2037                             sm.showIt(
2038                                     (Gtk.Window) _this.el.get_root (), 
2039                                     _this.main_window.windowstate.project, 
2040                                     node
2041                              );
2042                              /*
2043                              gtk4 migration - disabled this part.. probably not used muchanyway
2044                              
2045                              
2046                              if (name.length < 1) {
2047                                     return;
2048                           
2049                              }
2050                              node.set_prop( new JsRender.NodeProp.special("xinclude", name));
2051                              node.items.clear();
2052                         
2053                         
2054                             var s = _this.view.el.get_selection();
2055                             
2056                             print("GET  SELECTED?");
2057                             Gtk.TreeIter iter;
2058                             Gtk.TreeModel mod;
2059                         
2060                             
2061                             if (!s.get_selected(out mod, out iter)) {
2062                                 return; // nothing seleted..
2063                             }
2064                             Gtk.TreeIter citer;
2065                             var n_cn = mod.iter_n_children(iter) -1;
2066                             for (var i = n_cn; i > -1; i--) {
2067                                 mod.iter_nth_child(out citer, iter, i);
2068                                 
2069                         
2070                                 print("removing node from Tree\n");    
2071                             
2072                                 _this.model.el.remove(ref citer);
2073                             }
2074                             _this.changed();
2075                             _this.node_selected(node, "tree");
2076                              */
2077                             
2078                         });
2079                 }
2080
2081                 // user defined functions
2082         }
2083
2084
2085
2086
2087 }