fix path to roodata
[roobuilder] / src / Palete / Roo.vala
1 using Gtk;
2
3 namespace Palete {
4
5         
6 /*      
7         
8         
9     public class Introspect.El : Object
10     {
11         public enum eltype { 
12             NS,
13             CLASS,
14             METHOD,
15             PROP
16         }
17                 
18             
19         public eltype type;
20     }
21
22 */
23     public class Roo : Palete {
24                 
25                 Gee.ArrayList<string> top_classes;
26                 public static Gee.HashMap<string,GirObject>? classes_cache = null;
27                 public static Gee.ArrayList<string>? top_classes_cache = null;
28  
29         public Roo(Project.Project project)
30         {
31
32
33             
34             aconstruct(project);
35             this.name = "Roo";
36                         this.top_classes =  new Gee.ArrayList<string>();
37  
38                         
39                         this.load(); // ? initialize the roodata?
40
41         }
42
43                 Gee.HashMap<string,GirObject> propsFromJSONArray(string type, Json.Array ar, GirObject cls)
44                 {
45
46                         var ret = new Gee.HashMap<string,GirObject>();
47                         
48                         for (var i =0 ; i < ar.get_length(); i++) {
49                                 var o = ar.get_object_element(i);
50                                 var name = o.get_string_member("name"); 
51                                 var prop = new GirObject(type, name );  
52                                  
53                                 prop.type        = o.get_string_member("type");
54                                 prop.doctxt  = o.get_string_member("desc");
55                                 prop.propertyof = o.has_member("memberOf") ? o.get_string_member("memberOf") : "";
56                                 if (prop.propertyof.length < 1)  {
57                                         prop.propertyof = cls.name;
58                                 }
59                                 
60                                 // this is the function default.
61                                 prop.sig = o.has_member("sig") ? o.get_string_member("sig") : "";
62                                 
63                                 if (o.has_member("optvals")  ) {
64                                         var oar = o.get_array_member("optvals");
65                                         
66                                         for (var oi = 0; oi < oar.get_length(); oi++) {
67                                                 prop.optvalues.add(oar.get_string_element(oi));
68                                         }
69                                         
70                                 }       
71                                 
72                                 //print(type + ":" + name +"\n");
73                                 ret.set(name,prop);
74                         }
75                         return ret;
76                 }
77                 
78                 
79                 public override void  load () {
80
81                         if (this.classes != null) {
82                                 return;
83                         }
84                         if (Roo.classes_cache != null) {
85                                 this.classes = Roo.classes_cache;
86                                 this.top_classes = Roo.top_classes_cache ;
87                                 return;
88                         }
89                         
90                         
91  
92                         this.classes = new Gee.HashMap<string,GirObject>();
93                         var add_to =  new Gee.HashMap<string,Gee.ArrayList<string>>();
94                         
95                         var f = GLib. File.new_for_path(BuilderApplication.configDirectory() + "/resources/roodata.json");
96                         if (!f.query_exists(null)) {
97                                 f = GLib. File.new_for_uri("resources:///data/roodata.json");   
98                         }                       
99
100                         
101                         
102                         var pa = new Json.Parser();
103                         try { 
104                                 uint8[] data;
105                                 f.load_contents( null, out data, null );
106                                 pa.load_from_data((string) data);
107                         } catch(GLib.Error e) {
108                                 GLib.error("Could not load %s",f.get_uri());
109                         }
110                         var node = pa.get_root();
111
112                         var clist =  node.get_object(); /// was in data... .get_object_member("data");
113                         clist.foreach_member((o , key, value) => {
114                                 //print("cls:" + key+"\n");
115                          
116                                 var cls = new GirObject("class", key);  
117                                 cls.props = this.propsFromJSONArray("prop", value.get_object().get_array_member("props"),cls);
118                                 cls.signals = this.propsFromJSONArray("signal", value.get_object().get_array_member("events"),cls);
119                                 
120                                 
121                                 if (value.get_object().has_member("methods")) {
122                                         cls.methods = this.propsFromJSONArray("method", value.get_object().get_array_member("methods"),cls);
123                                 }
124                                 if (value.get_object().has_member("implementations")) {
125                                         var vcn = value.get_object().get_array_member("implementations");
126                                         for (var i =0 ; i < vcn.get_length(); i++) {
127                                                 cls.implementations.add(vcn.get_string_element(i));
128                                                 //break; << why!?!
129                                         }                               
130                                 }
131                                 // tree children = 
132                                 
133                                 if (value.get_object().has_member("tree_children")) {
134                                         var vcn = value.get_object().get_array_member("tree_children");                         
135                                         for (var i =0 ; i < vcn.get_length(); i++) {
136                                                 var ad_c = vcn.get_string_element(i);
137                                                 if (!cls.valid_cn.contains(ad_c)) {
138                                                         cls.valid_cn.add( ad_c );
139                                                 }
140                                                 if (!add_to.has_key(ad_c)) {
141                                                         add_to.set(ad_c, new Gee.ArrayList<string>());
142                                                 }
143                                                 if (!add_to.get(ad_c).contains(cls.name)) {
144                                                         add_to.get(ad_c).add(cls.name);
145                                                 }
146                                         }
147                                 }
148                                 
149                                 
150                                 
151                                 
152                                 // tree parent
153                                 
154                                 if (value.get_object().has_member("tree_parent")) {
155                                         var vcn = value.get_object().get_array_member("tree_parent");
156                                         for (var i =0 ; i < vcn.get_length(); i++) {
157                                                 if ("builder" == vcn.get_string_element(i)) {
158                                                         // this class can be added to the top level.
159                                                         GLib.debug("Add %s to *top", cls.name);
160                                                         
161                                                         this.top_classes.add(cls.name);
162                                                         break;
163                                                 }
164                                                 
165                                         }
166                                 }
167  
168                                 this.classes.set(key, cls);
169                         });
170                         
171                         // look for properties of classes, that are atually clasess
172                         // eg. Roo.data.Store has proxy and reader..
173                         
174                         
175                         foreach(var cls in this.classes.values) {
176                                 foreach(var gir_obj in cls.props.values) {
177                                         var types = gir_obj.type.split("|");
178                                         for(var i =0; i < types.length; i++) {
179                                                 var type = types[i];
180                                         
181                                                 if (/^Roo\./.match(type) && classes.has_key(type)) {
182                                                         
183                                                          
184                                                         cls.valid_cn.add(type + ":" +   gir_obj.name );
185                                                         // Roo.bootstrap.panel.Content:east
186                                                         // also means that  Roo.bootstrap.panel.Grid:east works
187                                                         var prop_type = classes.get(type);
188                                                         foreach(var imp_str in prop_type.implementations) {
189                                                                 //GLib.debug("addChild for %s - child=  %s:%s", cls.name, imp_str, gir_obj.name);
190                                                                 cls.valid_cn.add(imp_str + ":" +    gir_obj.name);
191                                                                 if (!add_to.has_key(imp_str)) {
192                                                                         add_to.set( imp_str, new Gee.ArrayList<string>());
193                                                                 }
194                                                                 if (!add_to.get( imp_str).contains(cls.name)) {
195                                                                         add_to.get( imp_str ).add(cls.name );
196                                                                 }
197                                                                 
198                                                         }
199                                                         
200                                                         
201                                                         if (!add_to.has_key( type)) {
202                                                                 add_to.set( type, new Gee.ArrayList<string>());
203                                                         }
204                                                         if (!add_to.get(type).contains(cls.name)) {
205                                                                 add_to.get( type ).add(cls.name );
206                                                         }
207                                                 }
208                                         }
209                                 }
210                                  
211                         }
212                         foreach(var cls in this.classes.values) {
213                                 if (add_to.has_key(cls.name)) {
214                                         cls.can_drop_onto = add_to.get(cls.name);
215                                 }
216                         }
217                         Roo.classes_cache = this.classes;
218                         Roo.top_classes_cache  = this.top_classes;
219                 }
220                   
221                         
222                 public string doc(string what) {
223                         return "";
224                         /*var ns = what.split(".")[0];
225
226
227                         
228                         
229                                 var gir =  Gir.factory(ns);
230                                 return   gir.doc(what);
231                                 */
232                                 
233                         //return typeof(this.comments[ns][what]) == 'undefined' ?  '' : this.comments[ns][what];
234                 }
235
236                 // does not handle implements...
237                 public override GirObject? getClass(string ename)
238                 {
239                         this.load();
240                         return this.classes.get(ename);
241                         
242                 }
243                 
244                  
245                 
246                 public override Gee.HashMap<string,GirObject> getPropertiesFor(string ename, JsRender.NodePropType ptype)
247                 {
248                         //print("Loading for " + ename);
249                         
250
251                         this.load();
252                                         // if (typeof(this.proplist[ename]) != 'undefined') {
253                                         //print("using cache");
254                                  //   return this.proplist[ename][type];
255                                 //}
256                                 // use introspection to get lists..
257                  
258                         
259                         var cls = this.classes.get(ename);
260                         var ret = new Gee.HashMap<string,GirObject>();
261                         if (cls == null) {
262                                 print("could not find class: %s\n", ename);
263                                 return ret;
264                                 //throw new Error.INVALID_VALUE( "Could not find class: " + ename);
265                 
266                         }
267
268                         //cls.parseProps();
269                         //cls.parseSignals(); // ?? needed for add handler..
270                         //cls.parseMethods(); // ?? needed for ??..
271                         //cls.parseConstructors(); // ?? needed for ??..
272
273                         //cls.overlayParent();
274
275                         switch  (ptype) {
276                                 
277                                 
278                                 case JsRender.NodePropType.PROP:
279                                         return  this.filterProps(cls.props);
280                                 case JsRender.NodePropType.LISTENER:
281                                         return cls.signals;
282                                 case JsRender.NodePropType.METHOD:
283                                         return ret;
284                                 case JsRender.NodePropType.CTOR:
285                                         return ret;
286                                 default:
287                                         GLib.error( "getPropertiesFor called with: " + ptype.to_string()); 
288                                         //var ret = new Gee.HashMap<string,GirObject>();
289                                         //return ret;
290                         
291                         }
292                 
293         
294                 //cls.overlayInterfaces(gir);
295
296
297                          
298                 }
299                 
300                 // removes all the properties where the type contains '.' ?? << disabled now..
301                 
302                 public Gee.HashMap<string,GirObject>  filterProps(Gee.HashMap<string,GirObject> props)
303                 {
304                         // we shold probably cache this??
305                         
306                         var outprops = new Gee.HashMap<string,GirObject>(); 
307                         
308                         foreach(var k in props.keys) {
309                                 var val = props.get(k);
310                                 
311                                 // special props..
312                                 switch(k) {
313                                         case "listeners" : 
314                                                 continue;
315                                         default:
316                                                 break;
317                                 }
318                                 
319                                  
320                                  //if (!val.type.contains(".")) {
321                                         outprops.set(k,val);
322                                         continue;
323                                  //}
324                                 
325                                 
326                                  
327                                 // do nothing? - classes not allowed?
328                                 
329                         }
330                         
331                         
332                         return outprops;
333                 
334                 
335                 }
336                 
337                 
338                 public string[] getInheritsFor(string ename)
339                 {
340                         string[] ret = {};
341                         var es = ename.split(".");
342                         var gir = Gir.factory(null, es[0]);
343                         
344                         var cls = gir.classes.get(es[1]);
345                         if (cls == null) {
346                                 return ret;
347                         }
348                         return cls.inheritsToStringArray();
349                         
350
351                 }
352
353  
354                 /*
355                  *  Pulldown options for type
356                  */
357                 public override bool typeOptions(string fqn, string key, string type, out string[] opts) 
358                 {
359                         opts = {};
360                         print("get typeOptions %s (%s)%s", fqn, type, key);
361                         if (type.up() == "BOOL" || type.up() == "BOOLEAN") {
362                                 opts = { "true", "false" };
363                                 return true;
364                          }
365                          
366                          var props = this.getPropertiesFor(fqn, JsRender.NodePropType.PROP);
367                          if (!props.has_key(key)) {
368                                  print("prop %s does not have key %s\n", fqn, key);
369                                  return false;
370                          }
371                          var pr = props.get(key);
372                          if (pr.optvalues.size < 1) {
373                                  print("prop %s no optvalues for %s\n", fqn, key);
374                                  return false;
375                          }
376                          string[] ret = {};
377                          for(var i = 0; i < pr.optvalues.size; i++) {
378                                  ret += pr.optvalues.get(i);
379                          }
380                          opts = ret;
381                          print("prop %s returning optvalues for %s\n", fqn, key);
382                          return true;
383                          
384                 }
385                  
386                 
387                 
388                 public override Gee.ArrayList<string> getChildList(string in_rval, bool with_prop)
389         {
390                 if (this.top_classes.size < 1) {
391                         this.load();
392                 }
393                  
394                  
395                  
396                 var ar = this.top_classes;
397                 if (in_rval != "*top") {
398                         if (this.classes.has_key(in_rval)) {
399                            // some of these children will be eg: Roo.bootstrap.layout.Region:center
400                                 ar = this.classes.get(in_rval).valid_cn;
401                         } else {
402                                 ar = new Gee.ArrayList<string>();
403                         }
404                 }
405                 
406                 if (!with_prop) {
407                         var ret = new Gee.ArrayList<string>();
408                         foreach(var v in ar) {
409                                 if (v.contains(":")) {
410                                         continue;
411                                 }
412                                 ret.add(v);
413                         }
414                         return ret;
415                 }
416                  
417                 GLib.debug("getChildList for %s returns %d items",  in_rval, ar.size);
418                 return ar;      
419                 
420                 //return this.original_getChildList(  in_rval);
421         }
422         
423
424         
425                 public override Gee.ArrayList<string> getDropList(string rval)
426                 {
427                         
428                         if (this.dropCache.has_key(rval)) {
429                                 return this.dropCache.get(rval);
430                         }
431                         // we might be dragging  Roo.bootstrap.layout.Region:center
432                         // in which case we need to lookup Roo.bootstrap.layout.Region
433                         // and see if it's has can_drop_onto
434                         var  ret = new Gee.ArrayList<string>();
435                         var cls = this.classes.get(rval);
436                         // cls can be null.
437                         if (cls == null && rval.contains(":")) {
438                                 var rr = rval.substring(0,rval.index_of(":"));
439                                 GLib.debug("Converted classname to %s", rr);
440                                 cls = this.classes.get(rr);
441                     }
442                         if (cls == null) {
443                                 return ret; //nothing..
444                         }
445                         
446                         foreach(var str in cls.can_drop_onto) {
447
448                                 ret.add(str);
449                         }
450                         //GLib.debug("getDropList for %s return[] %s", rval, string.joinv(", ", ret));
451                         this.dropCache.set(rval,ret);
452                         return ret;
453                                 
454                         
455                         
456                         //return this.default_getDropList(rval);
457                 }       
458                 public override JsRender.Node fqnToNode(string fqn) 
459                 {
460                         var ret = new JsRender.Node();
461                         ret.setFqn(fqn);
462                         // any default requred proerties?
463                         
464                         return ret;
465                         
466                         
467                         
468                 }
469                 
470     }
471     
472     
473                 
474                 
475     
476 }
477