change run to use meson/ninja and then exec. - remove libvala code from application...
[roobuilder] / src / JsRender / JsRender.vala
index 16b11eb..29d8df1 100644 (file)
@@ -14,16 +14,81 @@ namespace JsRender {
                 */
                public Gee.ArrayList<string> doubleStringProps;
                
-               public string id;
-               public string name;   // is the JS name of the file.
-               public string fullname;
-               public string path;  // is the full path to the file.
-               public string parent;  // JS parent.
-               public string region;  // RooJS - insert region.
-        
-               public string title;  // a title.. ?? nickname.. ??? -
-               public string build_module; // module to build if we compile (or are running tests...)
+               public string id  = "";
+               public string name { get; set; default = ""; }   // is the JS name of the file.
+               public string fullname = "";
+               public string path = "";  // is the full path to the file.
+               
+               public  string relpath {
+                       owned get { 
+                               return  this.project.path  == this.path ? "" : this.path.substring(this.project.path.length+1);
+                       } 
+                       private set {}
+               }
+               public  string reldir {
+                       owned get { 
+                               return  this.project.path == this.dir ? "" : this. dir.substring(this.project.path.length+1);
+                       } 
+                       private set {}
+               }
+               
+               public  string  dir {
+                       owned get { 
+                               return GLib.Path.get_dirname(this.path);
+                                
+                       } 
+                       private set {}
+               }
                
+               public string file_namespace {
+                       public owned get {
+                               if (!this.name.contains(".")) {
+                                       return "";
+                               }
+                               var bits = this.name.split(".");
+                               return bits[0];
+                       }
+                       private set {}
+               }
+               public string file_without_namespace {
+                       public  owned get {
+                               if (!this.name.contains(".")) {
+                                       return this.name;
+                               }
+                               var bits = this.name.split(".");
+                               return this.name.substring(bits[0].length +1);
+                       }
+                       private set {}
+               }
+               
+               public string file_ext {
+                       public owned get {
+                               if (!this.path.contains(".")) {
+                                       return "";
+                               }
+                               var bits = this.name.split(".");
+                               return bits[bits.length-1];
+                       }
+                       private set {}
+               }
+               public string parent = "";  // JS parent.
+               public string region = "";  // RooJS - insert region.
+        
+               public string title = "";  // a title.. ?? nickname.. ??? -
+
+               private int _version = 1;   // should we increment this based on the node..?
+               public int version {
+                       get {
+                               if (this.tree != null) {
+                                       return this.tree.updated_count;
+                               }
+                               return ++this._version; // increased on every call? - bit of a kludge until we do real versioning
+                       }
+                       private set {
+                               this._version = value;
+                       }
+                       
+               }
 
                public string permname;
                public string language;
@@ -31,41 +96,75 @@ namespace JsRender {
                public string modOrder;
                public string xtype;
                public uint64 webkit_page_id; // set by webkit view - used to extract extension/etc..
-                   
+               public bool gen_extended  = false; // nodetovala??
+
                public Project.Project project;
+
+               // GTK Specifc
+               public string build_module; // module to build if we compile (or are running tests...)      
+
                //Project : false, // link to container project!
                
                public Node tree; // the tree of nodes.
                
-               public GLib.List<JsRender> cn; // child files.. (used by project ... should move code here..)
+               //public GLib.List<JsRender> cn; // child files.. (used by project ... should move code here..)
 
                public bool hasParent; 
                
                public bool loaded;
                
                public Gee.HashMap<string,string> transStrings; // map of md5 -> string.
+               public  Gee.HashMap<string,string> namedStrings;
+               public  Gee.HashMap<string, GLib.ListStore> errorsByType;
+               
                
 
                public signal void changed (Node? node, string source); 
                
                 
                public signal void compile_notice(string type, string file, int line, string message);
+               
+               private  GLib.Icon? _icon = null;
+               
+               public GLib.Icon? icon { 
+                       private set {}
+                       get {
+                               if (this._icon !=  null) {
+                                       return this._icon;
+                               }
+                               
+                               if (this.path == "") {
+                                       return null;
+                               }
+                               if (!GLib.FileUtils.test(this.path, GLib.FileTest.EXISTS)) {
+                                       return null;
+                               }
+                               this._icon = File.new_for_path(this.path).query_info("standard::icon",GLib.FileQueryInfoFlags.NONE).get_icon();
+                               return this._icon;
+                       }
+               }
+               
                /**
                 * UI componenets
                 * 
                 */
                //public Xcls_Editor editor;
+               public GLib.ListStore childfiles; // used by directories..
                
                
+               //abstract JsRender(Project.Project project, string path); 
                
-               public JsRender(Project.Project project, string path) {
+               protected JsRender(Project.Project project, string path)
+               {
                    
-                       this.cn = new GLib.List<JsRender>();
+                       //this.cn = new GLib.List<JsRender>();
+                       GLib.debug("new jsrender %s", path);
                        this.path = path;
                        this.project = project;
                        this.hasParent = false;
                        this.parent = "";
-                       this.tree = null;
+                       this.tree = null; 
                        this.title = "";
                        this.region = "";
                        this.permname = "";
@@ -73,16 +172,16 @@ namespace JsRender {
                        this.language = "";
                        this.content_type = "";
                        this.build_module = "";
-                       this.loaded = false;
+                       //this.loaded = false;
                        //print("JsRender.cto() - reset transStrings\n");
-                       this.transStrings = new Gee.HashMap<string,string> ();
-                       
+                       this.transStrings = new Gee.HashMap<string,string>();
+                       this.namedStrings = new Gee.HashMap<string,string>();
                        // should use basename reallly...
                        
                        var ar = this.path.split("/");
                        // name is in theory filename without .bjs (or .js eventually...)
                        try {
-                               Regex regex = new Regex ("\\.(bjs|js)$");
+                               Regex regex = new Regex ("\\.(bjs)$");
 
                                this.name = ar.length > 0 ? regex.replace(ar[ar.length-1],ar[ar.length-1].length, 0 , "") : "";
                        } catch (GLib.Error e) {
@@ -91,6 +190,11 @@ namespace JsRender {
                        this.fullname = (this.parent.length > 0 ? (this.parent + ".") : "" ) + this.name;
 
                        this.doubleStringProps = new Gee.ArrayList<string>();
+                       this.childfiles = new GLib.ListStore(typeof(JsRender));
+                       this.errorsByType  = new Gee.HashMap<string, GLib.ListStore>();
+                        
+                       
+
 
                }
                
@@ -122,28 +226,19 @@ namespace JsRender {
                        switch (xt) {
                                case "Gtk":
                                        return new Gtk(project, path);
+                                       
                                case "Roo":
-                                       return new Roo(project, path);
+                                       return new Roo((Project.Roo) project, path);
+//                     case "Flutter":
+//                                     return new Flutter(project, path);
                                case "PlainFile":
                                        return new PlainFile(project, path);
                        }
                        throw new Error.INVALID_FORMAT("JsRender Factory called with xtype=%s", xt);
                        //return null;    
                }
-
-               public string toJsonString()
-               {
-                       if (this.xtype == "PlainFile") {
-                               return "";
-                       }
-                       var generator = new Json.Generator ();
-                       generator.indent = 4;
-                       generator.pretty = true;
-                       var node = new Json.Node(Json.NodeType.OBJECT);
-                       node.set_object(this.toJsonObject());
-                       generator.set_root(node);
-                       return generator.to_data(null);
-               }
+               
+       
        
                public string nickType()
                {
@@ -161,9 +256,134 @@ namespace JsRender {
                        return ar[ar.length-1];
                        
                }
+               
+               public string nickNameSplit()
+               {
+                       var n = this.nickName();
+                       var ret = "";
+                       var len = 0;
+                       for (var i = 0; i < n.length; i++) {
+                               if (i!=0 && n.get(i).isupper() && len > 10) {
+                                       ret +="\n";
+                                       len= 0;
+                               }
+                               ret += n.get(i).to_string();
+                               len++;
+                       }
+                       
 
+                       
+                       return ret;
+               
+               }
+               
+               Gdk.Pixbuf screenshot = null;
+               Gdk.Pixbuf screenshot92 = null;
+               Gdk.Pixbuf screenshot368 = null;
+               
+               public Gdk.Pixbuf? getIcon(int size = 0) {
+                   var fname = this.getIconFileName( );                
+                   if (!FileUtils.test(fname, FileTest.EXISTS)) {
+               GLib.debug("PIXBUF %s:  %s does not exist?", this.name, fname);
+                               return null;
+                       }
+                       
+                       switch (size) {
+                               case 0:
+                                       if (this.screenshot == null) {
+                                               try { 
+                                                       this.screenshot = new Gdk.Pixbuf.from_file(fname);
+                                               } catch (GLib.Error e) {}
+                                       }
+                                       return this.screenshot;
+                               
+                               case 92:
+                                       
+                                       if (this.screenshot == null) {
+                                               this.getIcon(0);
+                                               if (this.screenshot == null) {
+                                                       return null;
+                                               }
+                                       }
+                                       
+                                       this.screenshot92 = this.screenshot.scale_simple(92, (int) (this.screenshot.height * 92.0 /this.screenshot.width * 1.0 )
+                                               , Gdk.InterpType.NEAREST) ;
+                                   return this.screenshot92;
+                           
+                           case 368:
+                                       if (this.screenshot == null) {
+                                               this.getIcon(0);
+                                               if (this.screenshot == null) {
+                                                       return null;
+                                               }
+                                       }
+                                       
+                                       this.screenshot368 = this.screenshot.scale_simple(368, (int) (this.screenshot.height * 368.0 /this.screenshot.width * 1.0 )
+                                   , Gdk.InterpType.NEAREST) ;
+                                   return this.screenshot368;
+                   }
+                   return null;
+               }
+               
+               public void writeIcon(Gdk.Pixbuf pixbuf) {
+                       
+                       this.screenshot92 = null;
+                       this.screenshot368 = null;
+                       this.screenshot = null;
+                       try {
+                               GLib.debug("Wirte %s", this.getIconFileName( ));
+                               pixbuf.save(this.getIconFileName( ),"png");
+                               this.screenshot = pixbuf;
+                       
+                       } catch (GLib.Error e) {
+                               GLib.debug("failed to write pixbuf?");
+                       
+                       }
+                               
+                        
+                       
+               
+               }
+               public void widgetToIcon(global::Gtk.Widget widget) {
+                       
+                       this.screenshot92 = null;
+                       this.screenshot368 = null;
+                       this.screenshot = null;
+                       
+                       try {
+                       
+
+                       var filename = this.getIconFileName();
+                               
+
+                                var p = new global::Gtk.WidgetPaintable(widget);
+                                var s = new global::Gtk.Snapshot();
+                                GLib.debug("Width %d, Height %d", widget.get_width(), widget.get_height()); 
+                                p.snapshot(s, widget.get_width(), widget.get_height());
+                                var n = s.free_to_node();
+                                if (n == null) {
+                                       return;
+                               }
+                                var r = new  Gsk.CairoRenderer();
+                                r.realize(null);
+                                var t = r.render_texture(n,null);
+                                GLib.debug("write to %s", filename);
+                                t.save_to_png(filename);
+                                r.unrealize();
+                                        
+                       
+                       } catch (GLib.Error e) {
+                               GLib.debug("failed to write pixbuf?");
+                       
+                       }
+                               
+                        
+                       
                
-               public string getIconFileName(bool return_default)
+               }
+
+               
+               public string getIconFileName( )
                {
                         
                        var m5 = GLib.Checksum.compute_for_string(GLib.ChecksumType.MD5,this.path); 
@@ -178,49 +398,50 @@ namespace JsRender {
                        }
                        var fname = dir + "/" + m5 + ".png";
                        
-                       if (!return_default) {
-                               print("getIconFileName return %s\n", fname);
-                               return fname;
+                        
+                       return fname;
+                         
+               }
+               
+               public string toJsonString()
+               {
+                       if (this.xtype == "PlainFile") {
+                               return "";
                        }
+                       var node = new Json.Node(Json.NodeType.OBJECT);
+                       node.set_object(this.toJsonObject());                   
+                       var generator = new JsonGen(node);
+                   generator.indent = 1;
+                   generator.pretty = true;
+                   
                        
-                       if (FileUtils.test(fname, FileTest.EXISTS)) {
-                               print("getIconFileName return %s\n", fname);
-                               return fname;
-                       }
-                       // we need to create this somehow...
-                       print("getIconFileName return %s\n", GLib.Environment.get_home_dir() + "/.Builder/test.jpg");
-                       return  GLib.Environment.get_home_dir() + "/.Builder/test.jpg";
-
+                       return generator.to_data();
                }
                
-
                public void saveBJS()
                {
-                   if (!this.loaded) {
-                           return;
-                   }
+                  // if (!this.loaded) {
+                       ///     GLib.debug("saveBJS - skip - not loaded?");
+               //          return;
+                   //}
                    if (this.xtype == "PlainFile") {
                            return;
                    }
-                   var generator = new Json.Generator ();
-                   generator.indent = 1;
-                   generator.pretty = true;
-                   var node = new Json.Node(Json.NodeType.OBJECT);
-                   node.set_object(this.toJsonObject());
-                   generator.set_root(node);
+                  
+                    
                    
-                   print("WRITE :%s\n " , this.path);// + "\n" + JSON.stringify(write));
+                   GLib.debug("WRITE :%s\n " , this.path);// + "\n" + JSON.stringify(write));
                    try {
-                               this.writeFile(this.path, generator.to_data(null));
-                       //generator.to_file(this.path);
-                   } catch(Error e) {
+                               this.writeFile(this.path, this.toJsonString());
+                        
+                   } catch(GLib.Error e) {
                        print("Save failed");
                    }
                }
                 
                 
 
-               public abstract void loadItems() throws GLib.Error;
+
                 
                 
                 
@@ -242,15 +463,20 @@ namespace JsRender {
                        
                        //ret.set_string_member("id", this.id); // not relivant..
                        ret.set_string_member("name", this.name);
-                       ret.set_string_member("parent", this.parent == null ? "" : this.parent);
-                       ret.set_string_member("title", this.title == null ? "" : this.title);
-                       ret.set_string_member("path", this.path);
-                       //ret.set_string_member("items", this.items);
-                       ret.set_string_member("permname", this.permname  == null ? "" : this.permname);
-                       ret.set_string_member("modOrder", this.modOrder  == null ? "" : this.modOrder);
+                       
+                       if (this.project.xtype == "Roo") {
+                               ret.set_string_member("parent", this.parent == null ? "" : this.parent);
+                               ret.set_string_member("title", this.title == null ? "" : this.title);
+                               //ret.set_string_member("path", this.path);
+                               //ret.set_string_member("items", this.items);
+                               ret.set_string_member("permname", this.permname  == null ? "" : this.permname);
+                               ret.set_string_member("modOrder", this.modOrder  == null ? "" : this.modOrder);
+                       }
                        if (this.project.xtype == "Gtk") {
-                               ret.set_string_member("build_module", this.build_module  == null ? "" : this.build_module);
+                               ret.set_string_member("build_module", this.build_module  );
                        }
+                       ret.set_boolean_member("gen_extended", this.gen_extended);
                        
                        if (this.transStrings.size > 0) {
                                var tr =  new Json.Object();
@@ -260,8 +486,17 @@ namespace JsRender {
                                }
                                ret.set_object_member("strings", tr);
             }
-                       
-                       
+
+            
+            
+                       if (this.namedStrings.size > 0) {
+                               var tr =  new Json.Object();
+                               var iter = this.namedStrings.map_iterator();
+                               while (iter.next()) {
+                                       tr.set_string_member(iter.get_key(), iter.get_value());
+                               }
+                               ret.set_object_member("named_strings", tr);
+            }
                        
                        var ar = new Json.Array();
                        // empty files do not have a tree.
@@ -277,6 +512,9 @@ namespace JsRender {
 
                public string getTitle ()
                {
+                   if (this.title == null) { // not sure why this happens..
+                       return "";
+               }
                    if (this.title.length > 0) {
                        return this.title;
                    }
@@ -315,7 +553,7 @@ namespace JsRender {
                       return "";
                    }
                    
-                   return ar.get("* xns") + "." + ar.get("* xtype");
+                   return ar.get("xns") + "." + ar.get("xtype");
                                      
                                        
                }
@@ -346,7 +584,179 @@ namespace JsRender {
                        
                }
                
+               public GLib.ListStore toListStore()
+               {
+                       var ret = new GLib.ListStore(typeof(Node));
+                       ret.append(this.tree);
+                       return ret;
+               }
+                
                
+               // used to handle list of files in project editor (really Gtk only)
+               public bool compile_group_selected {
+                       get {
+                               var gproj = (Project.Gtk) this.project;
+                               
+                               if (gproj.active_cg == null) {
+                                       return false;
+                               }
+                               if (this.xtype == "Dir") {
+                                       // show ticked if all ticked..
+                                       var ticked = true;
+                                       for(var i = 0; i < this.childfiles.n_items; i++ ) {
+                                               var f = (JsRender) this.childfiles.get_item(i);
+                                               if (!f.compile_group_selected) {
+                                                       ticked = false;
+                                                       break;
+                                               }
+                                       }
+                                       return ticked;
+                               
+                               
+                               }
+                               if (gproj.active_cg.sources == null) {
+                                       GLib.debug("compile_group_selected - sources is null? ");
+                                       return false;
+                               }
+
+                               return gproj.active_cg.sources.contains(this.relpath);
+                               
+                       }
+                       set {
+                               
+                               var gproj = (Project.Gtk) this.project;
+                               
+                               if (gproj.active_cg == null) {
+                                       return;
+                               }
+                               if (gproj.active_cg.loading_ui) {
+                                       return;
+                               }
+                               
+                               if (this.xtype == "Dir") {
+                                       for(var i = 0; i < this.childfiles.n_items; i++ ) {
+                                               var f = (JsRender) this.childfiles.get_item(i);
+                                               f.compile_group_selected = value;
+                                       }
+                                       return;
+                                
+                               }
+                               
+                               
+                               
+                               if (value == false) {
+                                       GLib.debug("REMOVE %s", this.relpath);
+                                       
+                                       gproj.active_cg.sources.remove(this.relpath);
+                                       return;
+                               }
+                               if (!gproj.active_cg.sources.contains(this.relpath)) { 
+                                       GLib.debug("ADD %s", this.relpath);
+                                       gproj.active_cg.sources.add(this.relpath);
+                               }
+                       
+                       }
+               }
+               /*
+               public bool compile_group_hidden {
+                       get {
+                               var gproj = (Project.Gtk) this.project;
+                               
+                               
+                               return gproj.hidden.contains(this.relpath);
+                               
+                       }
+                       set {
+                               
+                               var gproj = (Project.Gtk) this.project;
+                               
+                               if (gproj.active_cg == null) {
+                                       return;
+                               }
+                               if (gproj.active_cg.loading_ui) {
+                                       return;
+                               } 
+                               if (value == false) {
+                                       GLib.debug("REMOVE %s", this.relpath);
+                                       
+                                       gproj.hidden.remove(this.relpath);
+                                       return;
+                               }
+                               if (!gproj.hidden.contains(this.relpath)) { 
+                                       gproj.hidden.add(this.relpath);
+                                       // hiding a project will auto clear it.
+                                       for(var i = 0; i < this.childfiles.n_items; i++ ) {
+                                               var f = (JsRender) this.childfiles.get_item(i);
+                                               f.compile_group_selected = false;
+                                       }
+                                       return;
+                                       
+                               }
+                       
+                       }
+               }
+               */
+               public void remove()
+               {
+                       if (this.xtype == "Dir") {
+                               return;
+                       }
+                       // cleans up build (should really be in children..
+                       this.removeFile(this.path);
+                       if (this.path.has_suffix(".bjs") && this.project.xtype == "Roo") {
+                               this.removeFile(this.path.substring(0, this.path.length-4) + ".js");
+                               return;
+                       }
+                       if (this.path.has_suffix(".bjs") && this.project.xtype == "Gtk") {
+                               this.removeFile(this.path.substring(0, this.path.length-4) + ".vala");
+                               this.removeFile(this.path.substring(0, this.path.length-4) + ".c");
+                               this.removeFile(this.path.substring(0, this.path.length-4) + ".o");                             
+                       }
+                       if (this.path.has_suffix(".vala") && this.project.xtype == "Gtk") {
+                               this.removeFile(this.path.substring(0, this.path.length-5) + ".c");
+                               this.removeFile(this.path.substring(0, this.path.length-5) + ".o");                             
+                       }       
+               
+               
+               }
+               
+               private void removeFile(string path)
+               {
+
+                       if (GLib.FileUtils.test(path, GLib.FileTest.EXISTS)) {
+                               GLib.FileUtils.unlink(path);
+                       }
+
+               }
+               public string relTargetName()
+               {
+                       return this.targetName().substring(this.project.path.length +1);
+               
+               }
+               
+               public string to_url()
+               {
+                       return File.new_for_path (this.targetName()).get_uri ();
+               }
+               public Palete.LanguageClient? getLanguageServer()
+               {
+                       
+                       return this.project.getLanguageServer(this.language_id());
+               
+               }
+               public GLib.ListStore getErrors(string n)
+               {
+                       var ls = this.errorsByType.get(n);
+                       if (ls == null) {
+                               ls = new GLib.ListStore(typeof(Palete.CompileError));
+                               this.errorsByType.set(n, ls );
+                       }
+                       return ls;
+               }
+               
+               
+               public abstract string language_id();
                public abstract void save();
                public abstract void saveHTML(string html);
                public abstract string toSource() ;
@@ -354,8 +764,12 @@ namespace JsRender {
                public abstract void setSource(string str);
                public abstract string toSourcePreview() ;
                public abstract void removeFiles() ;
-                public abstract void  findTransStrings(Node? node );
+               public abstract void  findTransStrings(Node? node );
+               public abstract string toGlade();
+               public abstract string targetName();
+               public abstract void loadItems() throws GLib.Error;
        } 
 
 }
  
+