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