src/Palete/Palete.vala
[app.Builder.js] / src / Palete / Palete.vala
1
2 namespace Palete 
3 {
4
5
6         public errordomain Error {
7                 INVALID_TYPE,
8                 NEED_IMPLEMENTING,
9                 MISSING_FILE,
10                 INVALID_VALUE
11         }
12
13         public class Usage : Object 
14         {
15                 public Gee.ArrayList<string> left;
16                 public Gee.ArrayList<string> right;
17                 public Usage(Gee.ArrayList<string> ileft, Gee.ArrayList<string> iright)
18                 {
19                         this.left = ileft;
20                         this.right=  iright;
21                 }
22                 public bool leftHas(string s)
23                 {
24                         for(var i = 0 ; i < this.left.size; i++) {
25                                 var m = this.left.get(i);
26                                 if (s == m) {
27                                         return true;
28                                 }
29                                 if (!m.contains(":")) {
30                                         continue;
31                                 }
32                                 var ar = m.split(":");
33                                 if (ar[0] == s) {
34                                         return true;
35                                 }
36                         }
37                         return false;
38                                 
39                 }
40
41                 
42         }
43
44         
45
46     static Gee.HashMap<string,Palete>? cache = null;
47     
48     public static Palete factory(string xtype)
49     {
50         if (cache == null) {
51             cache = new Gee.HashMap<string,Palete>();
52         }
53         if (cache.get(xtype) != null) {
54             return cache.get(xtype);
55         }
56         switch(xtype) {
57             case "Gtk":
58                 cache.set(xtype, new Gtk());
59                 break;
60             case "Roo":
61                 cache.set(xtype, new Roo());
62                 break;
63             default:
64                 throw new Error.INVALID_TYPE("invalid argument to Palete factory");
65         }
66         return cache.get(xtype);
67     }
68        
69
70     public abstract class Palete : Object 
71     {
72         
73        
74         public string name;
75
76         public Gee.ArrayList<Usage> map;
77
78         Gee.HashMap<string,GirObject> classes; // used in roo.. 
79         
80         public Palete()
81         {
82             // nothing?
83                 this.map = null;
84         }
85         
86         
87         //map : false, // array of mappings   left: [] , right : []
88         
89         //items : false, // the tree of nodes.
90         
91         
92
93
94         string  guessName(JsRender.Node ar) throws Error // turns the object into full name.
95         {
96             throw new Error.NEED_IMPLEMENTING("xxx. guessName needs implimenting");
97         }
98             
99
100             
101          
102
103             
104         public string[] getChildList(string in_rval)
105         {
106
107                 if (this.map == null) {
108                         this.load();
109                 }
110                 // empty == *top
111                 
112                 var rval = in_rval == "" ? "*top" : in_rval; 
113                                 
114                                 // should be a bit more than this..
115                         // -> it should look for all elements that inherit 
116                 string[] ret = {};
117                 var rt = new Gee.ArrayList<string>();
118                 for (var i = 0; i < this.map.size; i++) {
119                         var m = this.map.get(i);
120                                 
121                         if (!m.leftHas(rval)) {
122                                 continue;
123                         }
124                         print("found LEFT, adding right\n");
125                 
126                         for(var ii =0; ii < m.right.size; ii++) {
127                                 var l = m.right.get(ii);
128                                         
129                                 if (rt.index_of(l) > -1) {
130                                     continue;
131                                 }
132                                 //print("ADD " + string.joinv(", ", ret) + "\n");
133                                 ret += l;
134                                 rt.add(l);
135                         }
136                         
137                 
138                 }
139                 print ("drop list for %s is:\n%s\n", rval, string.joinv("\n", ret));
140                 //console.log("DROP LIST:");
141                 //console.dump(ret);
142                 return ret;
143             
144         }
145
146             
147         public string[] getDropList(string rval)
148         {
149
150                 if (this.map == null) {
151                         this.load();
152                 }
153
154                                 
155                                 // should be a bit more than this..
156                         // -> it should look for all elements that inherit 
157                 string[] ret = {};
158                 var rt = new Gee.ArrayList<string>();
159                 for (var i = 0; i < this.map.size; i++) {
160                         var m = this.map.get(i);
161                                 
162                         if (m.right.index_of(rval) < 0) {
163                                 continue;
164                         }
165                         //print("found RIGHT, adding left\n");
166                 
167                         for(var ii =0; ii < m.left.size; ii++) {
168                                 var l = m.left.get(ii);
169                                         
170                                 if (rt.index_of(l) > -1) {
171                                     continue;
172                                 }
173                                 //print("ADD " + string.joinv(", ", ret) + "\n");
174                                 ret += l;
175                                 rt.add(l);
176                         }
177                         
178                 
179                 }
180                  print ("drop list for %s is:\n%s\n", rval, string.joinv("\n", ret));
181                 //console.log("DROP LIST:");
182                 //console.dump(ret);
183                 return ret;
184             
185         }
186       
187         public void saveTemplate (string name, JsRender.Node data)
188         {
189
190                         var gn = data.fqn();
191             // store it in user's directory..
192             var appdir =  GLib.Environment.get_home_dir() + "/.Builder"; 
193
194                         
195             if (!GLib.FileUtils.test(appdir+ "/" + gn, GLib.FileTest.IS_DIR)) {
196                                 GLib.File.new_for_path (appdir+ "/" + gn).make_directory ();
197                                 
198             }
199             GLib.FileUtils.set_contents(appdir+ "/" + gn + "/" +  name + ".json", data.toJsonString());
200             
201         }
202         
203         /**
204          * list templates - in home directory (and app dir in future...)
205          * @param {String} name  - eg. Gtk.Window..
206          * @return {Array} list of templates available..
207          */
208           
209         public  GLib.List<string> listTemplates (JsRender.Node node)
210         {
211             
212                 var gn = node.fqn();
213             
214                 var ret = new GLib.List<string>();
215                 var dir= GLib.Environment.get_home_dir() + "/.Builder/" + gn;
216                 if (!GLib.FileUtils.test(dir, GLib.FileTest.IS_DIR)) {
217                         return ret;
218                 }
219                         
220
221
222                                     
223                 var f = File.new_for_path(dir);
224         
225             var file_enum = f.enumerate_children(GLib.FileAttribute.STANDARD_DISPLAY_NAME, GLib.FileQueryInfoFlags.NONE, null);
226              
227             FileInfo next_file; 
228             while ((next_file = file_enum.next_file(null)) != null) {
229                 var n = next_file.get_display_name();
230                         if (!Regex.match_simple ("\\.json$", n)) {
231                                         continue;
232                                 }
233                                 ret.append( dir + "/" + n);
234             }
235             return ret;
236             
237         }
238  
239         public JsRender.Node? loadTemplate(string path)
240         {
241
242                 var pa = new Json.Parser();
243                 pa.load_from_file(path);
244                 var node = pa.get_root();
245
246                 if (node.get_node_type () != Json.NodeType.OBJECT) {
247                         return null;
248                 }
249                 var obj = node.get_object ();
250
251                 var ret = new JsRender.Node();
252
253
254                 ret.loadFromJson(obj, 1);
255                 ret.ref(); // not sure if needed -- but we had a case where ret became uninitialized?
256                 
257                 return ret;
258          }
259
260
261
262     public   void  loadUsageFile (string fname) {
263
264
265
266                         
267                 print("Palete Load called\n");
268                 string raw;
269                 if (!FileUtils.test (fname, FileTest.EXISTS)) {
270                         throw new Error.MISSING_FILE(fname + " not found");
271                 }
272         
273                 FileUtils.get_contents(fname, out raw);
274               // print(data);
275                 var data  = raw.split("\n");
276                 var state = 0;
277                 var cfg = new Gee.ArrayList<Usage>();
278                 var left = new Gee.ArrayList<string>();
279                 var right = new Gee.ArrayList<string>();
280         
281                 for (var i = 0; i < data.length; i++) {
282                         var d = data[i].strip();
283                         //print("READ " + d + "\n");
284                         if (
285                                 d.length < 1
286                             ||
287                              Regex.match_simple ("^\\s+$", d)
288                             ||
289                                 Regex.match_simple ("^\\s*/", d)
290                      ){
291                             continue;
292                         }
293                                 
294                         if (Regex.match_simple ("^left:", d)) { 
295                             state = 1;
296                             if (left.size > 0 ){
297                                 cfg.add(new Usage( left, right));
298                                                 }
299                             left = new Gee.ArrayList<string>();
300                                         right = new Gee.ArrayList<string>();
301                             continue;
302                         }
303                          if (Regex.match_simple ("^right:", d)) { 
304                             state = 2;
305                             continue;
306                         }
307                         if (state == 1) {
308                                                 //print("add left: " + d + "\n");
309                             left.add(d);
310                             continue;
311                         }
312                                         //print("add Right: " + d + "\n");
313                         right.add(d);
314                         //Seed.quit();
315                        
316                 }
317                 if (left.size > 0 ){
318                         cfg.add(new Usage( left, right));
319                 }
320                 this.map = cfg;
321
322    }
323
324         
325           
326         public Gee.HashMap<int,string>  validateCode(
327                         string code, 
328                         string property, 
329                         string ptype,
330                         JsRender.JsRender file,
331                         JsRender.Node node
332                      ) 
333         {   
334
335                 //print("validate code (%s) %s\n", file.language, code);
336                  
337                 
338                 if (file.language == "js" && (ptype == "listener" || property[0] == '|')) {
339                         var ret = new Gee.HashMap<int,string>();
340                         
341                         //var cd = new JSCore.ClassDefinitionEmpty();
342                         string errmsg;
343                         var line = Javascript.singleton().validate(
344                                   "var __aaa___ = " + code, out errmsg);
345
346                         if (line < 0) {
347                                 return ret;
348                         }
349                         ret.set(line, errmsg);
350                         return ret;
351                 }
352                 if (file.language == "vala" ) { // not sure if we need to validate property
353                         
354                         var vs = new ValaSource(file);
355                         //var cd = new JSCore.ClassDefinitionEmpty();
356                         var ret = vs.checkFileWithNodePropChange(
357                                 node, 
358                                 property, 
359                                 ptype,
360                                 code
361                          );
362                         return ret;
363                 }
364                 var ret = new Gee.HashMap<int,string>();
365
366                 //print ("not javascript\n");
367                 return ret;
368
369         }
370
371             
372           
373         public abstract void fillPack(JsRender.Node node,JsRender.Node parent);
374         public abstract void load();
375         public abstract Gee.HashMap<string,GirObject> getPropertiesFor(string ename, string type);
376         public abstract GirObject? getClass(string ename);
377     }
378
379
380 }
381
382
383