Palete/Palete.vala
[app.Builder.js] / Palete / Palete.vala
1
2 namespace Palete 
3 {
4
5         public static JSCore.Object class_constructor(JSCore.Context ctx, JSCore.Object constructor,  JSCore.Value[] arguments, out JSCore.Value exception) 
6             {
7                 var c = new JSCore.Class (class_definition);
8                 var o = new JSCore.Object (ctx, c, null);
9
10                 /*
11                     Do something with object
12                 */
13
14                 return o;
15             }
16         static const JSCore.StaticFunction[] class_functions = {
17                  { null, null, 0 }
18             };
19         static const JSCore.ClassDefinition class_definition = {
20             0,
21             JSCore.ClassAttribute.None,
22             "App",
23             null,
24
25             null,
26             class_functions,
27
28             null,
29             null,
30
31             null,
32             null,
33             null,
34             null,
35
36             null,
37             null,
38             class_constructor,
39             null,
40             null
41             };
42
43
44         public errordomain Error {
45                 INVALID_TYPE,
46                 NEED_IMPLEMENTING,
47                 MISSING_FILE,
48                 INVALID_VALUE
49         }
50
51         public class Usage : Object 
52         {
53                 public Gee.ArrayList<string> left;
54                 public Gee.ArrayList<string> right;
55                 public Usage(Gee.ArrayList<string> ileft, Gee.ArrayList<string> iright)
56                 {
57                         this.left = ileft;
58                         this.right=  iright;
59                 }
60                 public bool leftHas(string s)
61                 {
62                         for(var i = 0 ; i < this.left.size; i++) {
63                                 var m = this.left.get(i);
64                                 if (s == m) {
65                                         return true;
66                                 }
67                                 if (!m.contains(":")) {
68                                         continue;
69                                 }
70                                 var ar = m.split(":");
71                                 if (ar[0] == s) {
72                                         return true;
73                                 }
74                         }
75                         return false;
76                                 
77                 }
78
79                 
80         }
81
82         
83
84     static Gee.HashMap<string,Palete>? cache = null;
85     
86     public static Palete factory(string xtype)
87     {
88         if (cache == null) {
89             cache = new Gee.HashMap<string,Palete>();
90         }
91         if (cache.get(xtype) != null) {
92             return cache.get(xtype);
93         }
94         switch(xtype) {
95             case "Gtk":
96                 cache.set(xtype, new Gtk());
97                 break;
98             case "Roo":
99                 cache.set(xtype, new Roo());
100                 break;
101             default:
102                 throw new Error.INVALID_TYPE("invalid argument to Palete factory");
103         }
104         return cache.get(xtype);
105     }
106        
107
108     public abstract class Palete : Object 
109     {
110         
111        
112         public string name;
113
114         public Gee.ArrayList<Usage> map;
115                 
116         public Palete()
117         {
118             // nothing?
119                 this.map = null;
120         }
121         
122         
123         //map : false, // array of mappings   left: [] , right : []
124         
125         //items : false, // the tree of nodes.
126         
127         
128
129
130         string  guessName(JsRender.Node ar) throws Error // turns the object into full name.
131         {
132             throw new Error.NEED_IMPLEMENTING("xxx. guessName needs implimenting");
133         }
134             
135
136             
137         /**
138          * gather a  list of potentional objects that can be added..
139          * 
140          */
141         /*
142         listChildren: function (existing) {
143             existing = existing || [];
144            // existing.push('*top'); // always have top
145             var ret  = []; 
146             console.log("GATHER LIST? " + this.map.length);
147             
148             
149             function addRight(right) {
150                 right.forEach(function(r) {
151                     if (ret.indexOf(r) > -1) {
152                         return;
153                     }
154                     ret.push(r);
155                 });
156             }
157             
158             this.map.forEach(function(m) {
159                 var done = false
160                 m.left.forEach( function(left) {
161                     if (done) return; 
162                     
163                     var l = left.replace(/:.*$/, '');
164                    // print("chk:" + l + " in " + existing.join(',')); 
165                     if (existing.indexOf(l) > -1) {
166                         addRight(m.right);
167                         done =true;
168                         //return true; // no more needed..
169                     }
170                 });
171                 
172             });
173             ret.sort();
174             
175            // console.dump(ret);
176             return ret;
177             
178             
179             
180         },
181         */
182         
183
184             
185         public string[] getChildList(string in_rval)
186         {
187
188                 if (this.map == null) {
189                         this.load();
190                 }
191                 // empty == *top
192                 
193                 var rval = in_rval == "" ? "*top" : in_rval; 
194                                 
195                                 // should be a bit more than this..
196                         // -> it should look for all elements that inherit 
197                 string[] ret = {};
198                 var rt = new Gee.ArrayList<string>();
199                 for (var i = 0; i < this.map.size; i++) {
200                         var m = this.map.get(i);
201                                 
202                         if (!m.leftHas(rval)) {
203                                 continue;
204                         }
205                         print("found LEFT, adding right\n");
206                 
207                         for(var ii =0; ii < m.right.size; ii++) {
208                                 var l = m.right.get(ii);
209                                         
210                                 if (rt.index_of(l) > -1) {
211                                     continue;
212                                 }
213                                 //print("ADD " + string.joinv(", ", ret) + "\n");
214                                 ret += l;
215                                 rt.add(l);
216                         }
217                         
218                 
219                 }
220                 print ("drop list for %s is:\n%s\n", rval, string.joinv("\n", ret));
221                 //console.log("DROP LIST:");
222                 //console.dump(ret);
223                 return ret;
224             
225         }
226
227             
228         public string[] getDropList(string rval)
229         {
230
231                 if (this.map == null) {
232                         this.load();
233                 }
234
235                                 
236                                 // should be a bit more than this..
237                         // -> it should look for all elements that inherit 
238                 string[] ret = {};
239                 var rt = new Gee.ArrayList<string>();
240                 for (var i = 0; i < this.map.size; i++) {
241                         var m = this.map.get(i);
242                                 
243                         if (m.right.index_of(rval) < 0) {
244                                 continue;
245                         }
246                         //print("found RIGHT, adding left\n");
247                 
248                         for(var ii =0; ii < m.left.size; ii++) {
249                                 var l = m.left.get(ii);
250                                         
251                                 if (rt.index_of(l) > -1) {
252                                     continue;
253                                 }
254                                 //print("ADD " + string.joinv(", ", ret) + "\n");
255                                 ret += l;
256                                 rt.add(l);
257                         }
258                         
259                 
260                 }
261                  print ("drop list for %s is:\n%s\n", rval, string.joinv("\n", ret));
262                 //console.log("DROP LIST:");
263                 //console.dump(ret);
264                 return ret;
265             
266         }
267         /**
268          * basic guess type.. 
269          * 
270          * /
271         findType : function (data, prop, value)
272         {
273             if (prop[0] == '|') {
274                 return 'function';
275             }
276             return typeof(value);
277         },
278         
279         
280         findOptions : function(ename)
281         {
282             switch(ename.toLowerCase()) {
283                 case 'boolean': 
284                     return [ 'true', 'false' ];
285                 // everything else does not have options.
286                 case 'string': 
287                 case 'utf8': 
288                 case 'int': 
289                 case 'uint': 
290                 case 'function': 
291                     return false;
292                 default: 
293                     console.log("OOPS: = unknown type: " + ename);
294                     return false;
295             }
296         },
297         confirmCanAdd: function(parent, child) {
298             // confirms that one obj can be added to another.
299             // returns true, for items, or list of properties that can hold it..
300             return true;
301             
302         },
303         getDefaultPack: function(pname, cname) {
304             return 'add';
305         },
306         */
307         public void saveTemplate (string name, JsRender.Node data)
308         {
309
310                         var gn = data.fqn();
311             // store it in user's directory..
312             var appdir =  GLib.Environment.get_home_dir() + "/.Builder"; 
313
314                         
315             if (!GLib.FileUtils.test(appdir+ "/" + gn, GLib.FileTest.IS_DIR)) {
316                                 GLib.File.new_for_path (appdir+ "/" + gn).make_directory ();
317                                 
318             }
319             GLib.FileUtils.set_contents(appdir+ "/" + gn + "/" +  name + ".json", data.toJsonString());
320             
321         }
322         
323         /**
324          * list templates - in home directory (and app dir in future...)
325          * @param {String} name  - eg. Gtk.Window..
326          * @return {Array} list of templates available..
327          */
328           
329         public  GLib.List<string> listTemplates (JsRender.Node node)
330         {
331             
332                 var gn = node.fqn();
333             
334                 var ret = new GLib.List<string>();
335                 var dir= GLib.Environment.get_home_dir() + "/.Builder/" + gn;
336                 if (!GLib.FileUtils.test(dir, GLib.FileTest.IS_DIR)) {
337                         return ret;
338                 }
339                         
340
341
342                                     
343                 var f = File.new_for_path(dir);
344         
345             var file_enum = f.enumerate_children(GLib.FileAttribute.STANDARD_DISPLAY_NAME, GLib.FileQueryInfoFlags.NONE, null);
346              
347             FileInfo next_file; 
348             while ((next_file = file_enum.next_file(null)) != null) {
349                 var n = next_file.get_display_name();
350                         if (!Regex.match_simple ("\\.json$", n)) {
351                                         continue;
352                                 }
353                                 ret.append( dir + "/" + n);
354             }
355             return ret;
356             
357         }
358  
359         public JsRender.Node? loadTemplate(string path)
360         {
361
362                 var pa = new Json.Parser();
363                 pa.load_from_file(path);
364                 var node = pa.get_root();
365
366                 if (node.get_node_type () != Json.NodeType.OBJECT) {
367                         return null;
368                 }
369                 var obj = node.get_object ();
370
371                 var ret = new JsRender.Node();
372
373
374                 ret.loadFromJson(obj, 1);
375                 ret.ref(); // not sure if needed -- but we had a case where ret became uninitialized?
376                 
377                 return ret;
378          }
379           public   void  loadUsageFile (string fname) {
380
381
382
383                         
384                 print("Palete Load called\n");
385                 string raw;
386                 if (!FileUtils.test (fname, FileTest.EXISTS)) {
387                         throw new Error.MISSING_FILE(fname + " not found");
388                 }
389         
390                 FileUtils.get_contents(fname, out raw);
391               // print(data);
392                 var data  = raw.split("\n");
393                 var state = 0;
394                 var cfg = new Gee.ArrayList<Usage>();
395                 var left = new Gee.ArrayList<string>();
396                 var right = new Gee.ArrayList<string>();
397         
398                 for (var i = 0; i < data.length; i++) {
399                         var d = data[i].strip();
400                         //print("READ " + d + "\n");
401                         if (
402                                 d.length < 1
403                             ||
404                              Regex.match_simple ("^\\s+$", d)
405                             ||
406                                 Regex.match_simple ("^\\s*/", d)
407                      ){
408                             continue;
409                         }
410                                 
411                         if (Regex.match_simple ("^left:", d)) { 
412                             state = 1;
413                             if (left.size > 0 ){
414                                 cfg.add(new Usage( left, right));
415                                                 }
416                             left = new Gee.ArrayList<string>();
417                                         right = new Gee.ArrayList<string>();
418                             continue;
419                         }
420                          if (Regex.match_simple ("^right:", d)) { 
421                             state = 2;
422                             continue;
423                         }
424                         if (state == 1) {
425                                                 //print("add left: " + d + "\n");
426                             left.add(d);
427                             continue;
428                         }
429                                         //print("add Right: " + d + "\n");
430                         right.add(d);
431                         //Seed.quit();
432                        
433                 }
434                 if (left.size > 0 ){
435                         cfg.add(new Usage( left, right));
436                 }
437                 this.map = cfg;
438
439         }
440         public string validateCode(string code, string language) 
441         {   
442                 if (language == "javascript") {
443                         //var cd = new JSCore.ClassDefinitionEmpty();
444                         var goc = new JSCore.Class(  class_definition ); 
445                         var cs = new JSCore.GlobalContext(goc);
446                         JSCore.Value ex;
447                         
448                         var ret = cs.check_script_syntax(
449                                    new JSCore.String.with_utf8_c_string(code),
450                                    null,
451                                    0,
452                                    out ex
453                         );
454                         return "";
455                 }
456                 return "";
457
458         }
459
460             
461           
462         public abstract void fillPack(JsRender.Node node,JsRender.Node parent);
463         public abstract void load();
464         public abstract Gee.HashMap<string,GirObject> getPropertiesFor(string ename, string type);
465         public abstract GirObject? getClass(string ename);
466     }
467
468
469 }
470
471
472