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