Fix #8044 - fixing varous crashes, correct tree drop location and empty nodes after...
[roobuilder] / src / Builder4 / WindowLeftTree.vala
index b93c57d..a878cba 100644 (file)
@@ -27,6 +27,7 @@ public class Xcls_WindowLeftTree : Object
        public int last_error_counter;
        public signal void changed ();
        public signal void node_selected (JsRender.Node? node);
+       public Gee.ArrayList<Gtk.Widget>? error_widgets;
 
        // ctor
        public Xcls_WindowLeftTree()
@@ -37,6 +38,7 @@ public class Xcls_WindowLeftTree : Object
                // my vars (dec)
                this.main_window = null;
                this.last_error_counter = -1;
+               this.error_widgets = null;
 
                // set gobject values
                this.el.hexpand = true;
@@ -69,7 +71,7 @@ public class Xcls_WindowLeftTree : Object
                        return;
                }
                this.removeErrors();
-               
+               this.error_widgets = new Gee.ArrayList<Gtk.Widget>();
                foreach(var diag in ar) { 
                
                         
@@ -86,6 +88,7 @@ public class Xcls_WindowLeftTree : Object
                if (w == null) {
                        return;
                        }
+                       this.error_widgets.add(w);
                        // always show errors.
                        var ed = diag.category.down();
                        if (ed != "err" && w.has_css_class("node-err")) {
@@ -111,6 +114,26 @@ public class Xcls_WindowLeftTree : Object
        //      _this.maincol.el.set_max_width( _this.viewwin.el.get_width()  - 32 );
        }
        public void removeErrors () {
+               if (this.error_widgets == null || this.error_widgets.size < 1) {
+                       return;
+               }
+               foreach(var child in this.error_widgets) {
+               
+                       if (child.has_css_class("node-err")) {
+                               child.remove_css_class("node-err");
+                       }
+                       if (child.has_css_class("node-warn")) {
+                               child.remove_css_class("node-warn");
+                       }
+                       
+                       if (child.has_css_class("node-depr")) {
+                               child.remove_css_class("node-depr");
+                       }
+               }
+               this.error_widgets  = null;
+               return;
+               
+               /*
                var  child = this.view.el.get_first_child(); 
         
                var reading_header = true;
@@ -149,6 +172,7 @@ public class Xcls_WindowLeftTree : Object
                child = child.get_next_sibling(); 
                }
                //GLib.debug("Rturning null");
+               */
             
        }
        public JsRender.Node? getActiveElement () { // return path to actie node.
@@ -296,7 +320,7 @@ public class Xcls_WindowLeftTree : Object
                        // init method
 
                        {
-                        
+                        /*
                          this.css = new Gtk.CssProvider();
                        //      try {
                                        this.css.load_from_string("
@@ -350,7 +374,7 @@ public class Xcls_WindowLeftTree : Object
                                        this.css,
                                        Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
                                );
-                               
+                               */
                                  
                        }
                }
@@ -440,6 +464,7 @@ public class Xcls_WindowLeftTree : Object
                 }
                public int getRowAt (double x,  double  y, out string pos) {
                
+                       pos = "";
                        var w = this.el.pick(x, y, Gtk.PickFlags.DEFAULT);
                        //GLib.debug("got widget %s", w == null ? "nothing" : w.get_type().name());
                        if (w == null) {
@@ -1043,7 +1068,7 @@ public class Xcls_WindowLeftTree : Object
                         
                                var is_shift = _this.keystate.is_shift > 0;
                                
-                               GLib.debug("shift is    %s", _this.keystate.is_shift > 0 ? "SHIFT" : "-");
+                               //GLib.debug("shift is    %s", _this.keystate.is_shift > 0 ? "SHIFT" : "-");
                                string pos; // over / before / after..
                        
                            //GLib.debug("got drag motion");
@@ -1054,7 +1079,7 @@ public class Xcls_WindowLeftTree : Object
                                try {
                                        cont.get_value(ref v);
                                } catch (GLib.Error e) {
-                                   GLib.debug("failed to get drag value");
+                                  // GLib.debug("failed to get drag value");
                                        return Gdk.DragAction.COPY;      
                                
                                }
@@ -1076,7 +1101,7 @@ public class Xcls_WindowLeftTree : Object
                             foreach(var dp in drop_on_to) {
                                str += dp;
                                }
-                               GLib.debug("droplist: %s", string.joinv(", ", str));
+                               //GLib.debug("droplist: %s", string.joinv(", ", str));
                             
                             
                            // if there are not items in the tree.. the we have to set isOver to true for anything..
@@ -1094,13 +1119,14 @@ public class Xcls_WindowLeftTree : Object
                            }
                            
                            
-                               GLib.debug("check is over");
+                       
                                 
                            // if path of source and dest are inside each other..
                            // need to add source info to drag?
                            // the fail();
                                var row = _this.view.getRowAt(x,y, out pos);
-                               
+                               //GLib.debug("check is over %d, %d, %s", (int)x,(int)y, pos);
+                       
                                if (row < 0) {
                                        this.addHighlight(null, "");    
                                        return Gdk.DragAction.COPY;
@@ -1109,20 +1135,20 @@ public class Xcls_WindowLeftTree : Object
                                
                                var node =  (JsRender.Node)tr.get_item();
                                
-                               GLib.debug("Drop over node: %s", node.fqn());
+                               //GLib.debug("Drop over node: %s", node.fqn());
                                
                        
                                if (pos == "above" || pos == "below") {
                                        if (node.parent == null) {
-                                               GLib.debug("no parent try center");
+                                               //GLib.debug("no parent try center");
                                                pos = "over";
                                        } else {
                                                 
                                                if (!drop_on_to.contains(node.parent.fqn())) {
-                                                       GLib.debug("drop on does not contain %s - try center" , node.parent.fqn());
+                                                       //GLib.debug("drop on does not contain %s - try center" , node.parent.fqn());
                                                        pos = "over";
                                                } else {
-                                                       GLib.debug("drop  contains %s - using %s" , node.parent.fqn(), pos);
+                                                       //GLib.debug("drop  contains %s - using %s" , node.parent.fqn(), pos);
                                                        if (_this.view.dragNode  != null && is_shift) {
                                                                if (node.parent.oid == _this.view.dragNode.oid || node.parent.has_parent(_this.view.dragNode)) {
                                                                        GLib.debug("shift drop not self not allowed");
@@ -1142,13 +1168,13 @@ public class Xcls_WindowLeftTree : Object
                                }
                                if (pos == "over") {
                                        if (!drop_on_to.contains(node.fqn())) {
-                                               GLib.debug("drop on does not contain %s - try center" , node.fqn());
+                                               //GLib.debug("drop on does not contain %s - try center" , node.fqn());
                                                this.addHighlight(null, ""); 
                                                return is_shift ?  Gdk.DragAction.MOVE :  Gdk.DragAction.COPY;          
                                        }
                                        if (_this.view.dragNode  != null && is_shift) {
                                                if (node.oid == _this.view.dragNode.oid || node.has_parent(_this.view.dragNode)) {
-                                                       GLib.debug("shift drop not self not allowed");
+                                                       //GLib.debug("shift drop not self not allowed");
                                                        this.addHighlight(null, "");
                                                        return Gdk.DragAction.COPY;     
                                                }
@@ -1168,11 +1194,14 @@ public class Xcls_WindowLeftTree : Object
                        });
                        this.el.drop.connect( (v, x, y) => {
                                
+                               // must get the pos before we clear the hightlihg.
+                               var pos = "";
+                               var row = _this.view.getRowAt(x,y, out pos);
                                this.addHighlight(null,"");
                         
                                var is_shift = _this.keystate.is_shift > 0;
                         
-                               var pos = "";
+                       
                                // -- get position..
                                if (this.lastDragString != v.get_string() || this.lastDragNode == null) {
                                        // still dragging same node
@@ -1184,7 +1213,10 @@ public class Xcls_WindowLeftTree : Object
                                     
                               
                            var dropNode = new JsRender.Node(); 
-                               dropNode.loadFromJsonString(v.get_string(), 1);
+                               dropNode.loadFromJsonString(v.get_string(), 2);
+                               GLib.debug("dropped node %s", dropNode.toJsonString());
+                               
+                               
                                var drop_on_to = _this.main_window.windowstate.file.palete().getDropList(dropNode.fqn());
                           
                            // if there are not items in the tree.. the we have to set isOver to true for anything..
@@ -1196,7 +1228,7 @@ public class Xcls_WindowLeftTree : Object
                                                return false;   
                                        }
                                        // add new node to top..
-                                       
+                                       GLib.debug("adding to top");
                                        
                                         var m = (GLib.ListStore) _this.model.el.model;
                                _this.main_window.windowstate.file.tree = dropNode;  
@@ -1211,8 +1243,9 @@ public class Xcls_WindowLeftTree : Object
                        
                        
                        
-                               var row = _this.view.getRowAt(x,y, out pos);
+                       
                                if (row < 0) {
+                                       GLib.debug("could not get row %d,%d, %s", (int)x,(int)y,pos);
                                        return   false; //Gdk.DragAction.COPY;
                                }
                                var tr = (Gtk.TreeListRow)_this.view.el.model.get_object(row);
@@ -1254,12 +1287,12 @@ public class Xcls_WindowLeftTree : Object
                                
                                switch(pos) {
                                        case "over":
-                                               node.appendChild(dropNode);
+                       
                                                if (is_shift && _this.view.dragNode != null) {
                                                        _this.model.selectNode(null); 
                                                        _this.view.dragNode.remove();
                                                }
-                                                       
+                                               node.appendChild(dropNode);                     
                                                dropNode.updated_count++;
                                                _this.model.selectNode(dropNode); 
                                                
@@ -1269,11 +1302,12 @@ public class Xcls_WindowLeftTree : Object
                                        case "above":
                                                GLib.debug("Above - insertBefore");
                                        
-                                               node.parent.insertBefore(dropNode, node);
+                       
                                                if (is_shift && _this.view.dragNode != null) {
                                                        _this.model.selectNode(null);                   
                                                        _this.view.dragNode.remove();
                                                }
+                                               node.parent.insertBefore(dropNode, node);                       
                                                dropNode.updated_count++;
                                                _this.model.selectNode(dropNode);                       
                                                _this.changed();
@@ -1311,7 +1345,7 @@ public class Xcls_WindowLeftTree : Object
                public void addHighlight (Gtk.Widget? w, string hl) {
                        if (this.highlightWidget != null) {
                                var ww  = this.highlightWidget;
-                               GLib.debug("clear drag from previous highlight");
+                               //GLib.debug("clear drag from previous highlight");
                                if (ww.has_css_class("drag-below")) {
                                         ww.remove_css_class("drag-below");
                                }
@@ -1323,7 +1357,7 @@ public class Xcls_WindowLeftTree : Object
                                }
                        }
                        if (w != null) {
-                               GLib.debug("add drag=%s to widget", hl);        
+                               //GLib.debug("add drag=%s to widget", hl);      
                                if (!w.has_css_class("drag-" + hl)) {
                                        w.add_css_class("drag-" + hl);
                                }
@@ -1405,7 +1439,7 @@ public class Xcls_WindowLeftTree : Object
                                    // why dup_?
                                    
                        
-                                   GLib.debug ("calling left_tree.node_selected");
+                                   GLib.debug ("calling left_tree.node_selected %s", snode.toJsonString());
                                    _this.node_selected(snode);
                                   
                                     
@@ -1422,8 +1456,11 @@ public class Xcls_WindowLeftTree : Object
                public JsRender.Node? getSelectedNode () {
                  if (this.el.selected_item == null) {
                                return null;
-                 }                             
+                 }     
+                  
+                 
                   var tr = (Gtk.TreeListRow)this.el.selected_item;
+                 
                   return (JsRender.Node)tr.get_item();
                         
                }
@@ -1496,13 +1533,14 @@ public class Xcls_WindowLeftTree : Object
                }
                public int nodeToRow (JsRender.Node node) 
                {
-                       var row = -1;
+                
                        var s = _this.view.el.model as Gtk.SingleSelection;
                        for (var i = 0; i < s.n_items; i++) {
                                //GLib.debug("check node %s", s.get_item(i).get_type().name());
                                var lr = s.get_item(i) as Gtk.TreeListRow;
                                //GLib.debug("check node %s", lr.get_item().get_type().name());
-                               if ((lr.get_item() as JsRender.Node).oid == node.oid) {
+                               var nn = (lr.get_item() as JsRender.Node);
+                               if (nn != null && nn.oid == node.oid) {
                                        return i;
                                        
                                }
@@ -1593,14 +1631,20 @@ public class Xcls_WindowLeftTree : Object
                        _this.selmodel.el.set_model(this.el);
                        return this.el;
                }
-               public void selectNode (JsRender.Node node) 
+               public void selectNode (JsRender.Node node) 
                {
-                       var row = this.nodeToRow(node);
                        var s = _this.view.el.model as Gtk.SingleSelection;
+                       if (node == null) {
+                               s.selected=Gtk.INVALID_LIST_POSITION;
+                               return;
+                       }
+                       var row = this.nodeToRow(node);
+               
                         
                        if (row < 0) {
                                // select none?
                                GLib.debug("Could not find node");
+                               s.selected=Gtk.INVALID_LIST_POSITION;
                                return;
                        }
                        GLib.debug("Select %d", row);
@@ -1684,7 +1728,7 @@ public class Xcls_WindowLeftTree : Object
                                
                        });
                        this.el.bind.connect( (listitem) => {
-                                GLib.debug("listitme is is %s", ((Gtk.ListItem)listitem).get_type().name());
+                               // GLib.debug("listitme is is %s", ((Gtk.ListItem)listitem).get_type().name());
                                
                                //var expand = (Gtk.TreeExpander) ((Gtk.ListItem)listitem).get_child();
                                var expand = (Gtk.TreeExpander)  ((Gtk.ListItem)listitem).get_child();
@@ -1698,8 +1742,10 @@ public class Xcls_WindowLeftTree : Object
                                
                                var lr = (Gtk.TreeListRow)((Gtk.ListItem)listitem).get_item();
                                var node = (JsRender.Node) lr.get_item();
-                               
-                          GLib.debug("node is %s", node.get_type().name());
+                               if (node == null || node.fqn() == "") {
+                                       return;
+                               }
+                          //GLib.debug("node is %s", node.get_type().name());
                        // was item (1) in old layout
                        
                                
@@ -1847,6 +1893,7 @@ public class Xcls_WindowLeftTree : Object
 
                        // set gobject values
                        var child_1 = new Xcls_Box18( _this );
+                       child_1.ref();
                        this.el.child = child_1.el;
                }