Fix #8003 - undo code
[roobuilder] / src / JsRender / JsRender.vala
index 29d8df1..593d8ff 100644 (file)
@@ -85,11 +85,14 @@ namespace JsRender {
                                return ++this._version; // increased on every call? - bit of a kludge until we do real versioning
                        }
                        private set {
+                               
                                this._version = value;
+                               this.updateUndo();
                        }
                        
                }
 
+
                public string permname;
                public string language;
                public string content_type;
@@ -116,11 +119,16 @@ namespace JsRender {
                
                public Gee.HashMap<string,string> transStrings; // map of md5 -> string.
                public  Gee.HashMap<string,string> namedStrings;
-               public  Gee.HashMap<string, GLib.ListStore> errorsByType;
                
+               public Gee.HashMap<int,string> undo_json;
                
+               //public        Gee.HashMap<string, GLib.ListStore> errorsByType;
+               private Gee.ArrayList<Lsp.Diagnostic> errors;
+               public int error_counter {
+                       get; private set; default = 0;
+               }
 
-               public signal void changed (Node? node, string source); 
+               //public signal void changed (Node? node, string source);  (not used?)
                
                 
                public signal void compile_notice(string type, string file, int line, string message);
@@ -145,6 +153,7 @@ namespace JsRender {
                        }
                }
                
+               
                /**
                 * UI componenets
                 * 
@@ -191,9 +200,9 @@ namespace JsRender {
 
                        this.doubleStringProps = new Gee.ArrayList<string>();
                        this.childfiles = new GLib.ListStore(typeof(JsRender));
-                       this.errorsByType  = new Gee.HashMap<string, GLib.ListStore>();
-                        
-                       
+                       //this.errorsByType  = new Gee.HashMap<string, GLib.ListStore>();
+                       this.errors = new Gee.ArrayList<Lsp.Diagnostic>((a,b) => { return a.equals(b); }); 
+                       this.undo_json = new Gee.HashMap<int,string>();
 
 
                }
@@ -438,13 +447,48 @@ namespace JsRender {
                        print("Save failed");
                    }
                }
-                
-                
-
-
-                
-                
-                
+               
+               bool in_undo = false;
+               protected void updateUndo()
+               {
+                       if (this.in_undo) {
+                               return;
+                       }
+                       if (this.xtype == "PlainFile") {
+                               // handled by gtk sourceview buffer...
+                               return;
+                       }
+                       //GLib.debug("UNDO store %d", this.version);
+                       this.undo_json.set(this.version, this.tree.toJsonString());
+                       if (this.undo_json.has_key(this.version+1)) {
+                               var n = this.version +1;
+                               while (this.undo_json.has_key(n)) {
+                                       this.undo_json.unset(n++);
+                               }
+                       
+                       }
+                       
+               }
+               
+               public bool undoStep(int step = -1) // undo back/next
+               {
+                       if (!this.undo_json.has_key(this.version + step)) {
+                               //GLib.debug("UNDO step %d failed - no version available", this.version + step);
+                               return false;
+                       }
+                       var new_version = this.version + step;
+                       var pa = new Json.Parser();
+                       //GLib.debug("UNDO RESTORE : %d",  this.version + step);
+                       
+                       pa.load_from_data(this.undo_json.get(new_version));
+                       var node = pa.get_root();
+                       this.in_undo = true;
+                       this.loadTree(node.get_object(),2); 
+                       this.tree.updated_count = new_version;
+                       this.in_undo = false;
+                       return true;
+               }
                  
                public string jsonHasOrEmpty(Json.Object obj, string key) {
                        return obj.has_member(key) ? 
@@ -745,15 +789,87 @@ namespace JsRender {
                        return this.project.getLanguageServer(this.language_id());
                
                }
-               public GLib.ListStore getErrors(string n)
+                
+               public void updateErrors(Gee.ArrayList<Lsp.Diagnostic> new_errors) 
                {
-                       var ls = this.errorsByType.get(n);
-                       if (ls == null) {
-                               ls = new GLib.ListStore(typeof(Palete.CompileError));
-                               this.errorsByType.set(n, ls );
+                       var oc = this.error_counter;
+                       var skip = new Gee.ArrayList<Lsp.Diagnostic>((a,b) => { return a.equals(b); });
+                       var rem = new Gee.ArrayList<Lsp.Diagnostic>((a,b) => { return a.equals(b); });
+                       foreach(var old in this.errors) {
+                               if (new_errors.contains(old)) {
+                                       skip.add(old);
+                                       continue;
+                               }
+                               rem.add(old);
+                                
+                       }
+                       foreach(var old in  rem) {
+                               this.removeError(old);
                        }
-                       return ls;
+                       foreach(var err in new_errors) {
+                               if (skip.contains(err)) {
+                                       continue;
+                               }
+                               this.addError(err);
+                       }
+                       if (oc != this.error_counter) {
+                               BuilderApplication.updateCompileResults();
+                       }
+                       
+               }
+               
+               
+               
+               public Gee.ArrayList<Lsp.Diagnostic> getErrors()
+               {
+                       return this.errors;
+               }
+               
+               private void addError(Lsp.Diagnostic diag)
+               {
+                       
+                       GLib.debug("ADD Error %s", diag.to_string());
+                       this.errors.add(diag);
+                       this.project.addError(this, diag);
+                       
+                       this.error_counter++;
+                        
+               }
+                
+               public void removeError(Lsp.Diagnostic diag) 
+               {
+                       GLib.debug("REMOVE Error %s", diag.to_string());
+                       this.errors.remove(diag);
+                       this.project.removeError(this, diag);
+                       this.error_counter++;
                }
+               public int getErrorsTotal(string category) 
+               {
+                       var  ret = 0;
+                       foreach(var diag in this.errors) {
+                               if (diag.category == category) {
+                                       ret++;
+                               }
+                       }
+                       return ret;
+                       
+               
+               } 
+               
+               public void loadTree(Json.Object obj, int bjs_version = 2)
+               {
+                       if (this.xtype == "PlainFile" ){
+                               return;
+                       }
+                       Node.uid_count = 0;
+                       this.tree = new Node();
+                       this.tree.loadFromJson(obj,bjs_version);
+                       this.tree.version_changed.connect(() => {
+                               this.updateUndo();
+                       });
+               
+               }
+               
                
                
                public abstract string language_id();
@@ -768,7 +884,10 @@ namespace JsRender {
                public abstract string toGlade();
                public abstract string targetName();
                public abstract void loadItems() throws GLib.Error;
+
        } 
+       
+        
 
 }