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