Palete/Gtk.vala
[app.Builder.js] / Palete / Gtk.vala
1 namespace Palete {
2
3         
4         
5         
6         
7     public class Introspect.El : Object
8     {
9         public enum eltype { 
10             NS,
11             CLASS,
12             METHOD,
13             PROP
14         }
15                 
16             
17         public eltype type;
18     }
19
20
21     public class Gtk : Palete {
22                 
23                 
24         public Gtk()
25         {
26
27
28             
29             base();
30             this.name = "Gtk";
31                         this.load();
32             // various loader methods..
33               //this.map = [];
34             //this.load();
35             //this.proplist = {};
36             //this.comments = { }; 
37             // no parent...
38         }
39       
40         void load () {
41                 
42          
43                 string raw;
44                         if (!FileUtils.test ("/usr/share/appBuilder/GtkUsage.txt", FileTest.EXISTS)) {
45                                 throw new Error.MISSING_FILE("/usr/share/appBuilder/GtkUsage.txt not found");
46                                 
47                         }
48                         
49             FileUtils.get_contents("/usr/share/appBuilder/GtkUsage.txt", out raw);
50           // print(data);
51             var data  = raw.split("\n");
52             var state = 0;
53             var cfg = new GLib.List<Usage>();
54             var left = new GLib.List<string>();
55             var right = new GLib.List<string>();
56
57                         for (var i = 0; i < data.length; i++) {
58                                 var d = data[0];
59                                 if (
60                                         d.length < 1
61                                     ||
62                                      Regex.match_simple ("^\\s+$", d)
63                                     ||
64                                         Regex.match_simple ("^\\s*/", d)
65                              ){
66                     continue;
67                 }
68                                 
69                 if (Regex.match_simple ("^left:", d)) { 
70                     state = 1;
71                     if (left.length() > 0 ){
72                         
73                         cfg.append(new Usage( left, right));
74                                         }
75                     left = new GLib.List<string>();
76                                 right = new GLib.List<string>();
77                     continue;
78                 }
79                  if (Regex.match_simple ("^right:", d)) { 
80                     state = 2;
81                     continue;
82                 }
83                 if (state == 1) {
84                     left.append(d.strip());
85                     return;
86                 }
87                 right.append(d.strip());
88                 //Seed.quit();
89                
90             }
91             if (left.length() > 0 ){
92                   cfg.append(new Usage( left, right));
93             }
94             this.map = cfg.copy();
95              
96         }
97         
98         public string doc(string what) {
99             var ns = what.split(".")[0];
100             var gir =  Gir.factory(ns);
101                         return   gir.doc(what);
102                         
103             //return typeof(this.comments[ns][what]) == 'undefined' ?  '' : this.comments[ns][what];
104         }
105
106                 // does not handle implements...
107                 
108         public Gee.HashMap<string,GirObject> getPropertiesFor(string ename, string type)
109         {
110             //print("Loading for " + ename);
111             
112
113
114                         // if (typeof(this.proplist[ename]) != 'undefined') {
115                 //print("using cache");
116              //   return this.proplist[ename][type];
117             //}
118             // use introspection to get lists..
119  
120             var es = ename.split(".");
121                         var gir = Gir.factory(es[0]);
122                         
123                         var cls = gir.classes.get(es[1]);
124                         if (cls == null) {
125                                 var ret = new Gee.HashMap<string,GirObject>();
126                                 return ret;
127                                 //throw new Error.INVALID_VALUE( "Could not find class: " + ename);
128                                 
129                         }
130
131                         //cls.parseProps();
132                         //cls.parseSignals(); // ?? needed for add handler..
133                         //cls.parseMethods(); // ?? needed for ??..
134                         //cls.parseConstructors(); // ?? needed for ??..
135
136                         cls.overlayParent();
137
138                         switch  (type) {
139                                 case "props":
140                                         return cls.props;
141                                 case "signals":
142                                         return cls.signals;
143                                 case "methods":
144                                         return cls.methods;
145                                 case "ctors":
146                                         return cls.ctors;
147                                 default:
148                                         var ret = new Gee.HashMap<string,GirObject>();
149                                         return ret;
150                                         
151                         }
152                                         
153                                 
154                         //cls.overlayInterfaces(gir);
155             
156             
157              
158         }
159                 public string[] getInheritsFor(string ename)
160                 {
161                         string[] = {};
162                         var es = ename.split(".");
163                         var gir = Gir.factory(es[0]);
164                         
165                         var cls = gir.classes.get(es[1]);
166                         if (cls == null) {
167                                 return ret;
168                         }
169                         return cls.inheritsToStringArray();
170                         
171
172                 }
173         /*
174         genParams: function(sig, meth)
175         {
176             var args = ['self'];
177             var ret = "\n";
178             meth.ret_type = this.typeToName(GIRepository.callable_info_get_return_type(sig));
179             // might be a numbeR??
180             meth.params = [];
181             for(var a_i  =0; a_i   < GIRepository.callable_info_get_n_args(sig); a_i++) {
182                 var arg = GIRepository.callable_info_get_arg(sig, a_i);
183                  
184                 meth.params.push({
185                     name  : arg.get_name(),
186                     type : this.typeToName(arg.get_type(), true)
187                 });
188             }
189             
190                 
191             
192             
193         },
194         genSkel: function(sig) // should really use genParams...
195         {
196             var args = ['self'];
197             var ret = "\n";
198             var ret_type = this.typeToName(GIRepository.callable_info_get_return_type(sig));
199             // might be a numbeR??
200             if (ret_type == 'boolean') {
201                 ret = "    return false;\n";
202             }
203             for(var a_i  =0; a_i   < GIRepository.callable_info_get_n_args(sig); a_i++) {
204                 var arg = GIRepository.callable_info_get_arg(sig, a_i);
205                 
206                 args.push(arg.get_name());
207             }
208             return 'function (' + args.join(', ') + ") {\n" + ret + "}"; 
209                 
210             
211             
212         },
213         typeToName  : function (type_info, allow_iface) // find type for properties or arguments.
214         {
215            var ty = GIRepository.type_tag_to_string( GIRepository.type_info_get_tag(type_info));
216            
217             if ((ty == 'void') && GIRepository.type_info_is_pointer(type_info)) {
218                 return false;
219             }
220             if (ty == 'array') {
221                 return false; // unspported   
222             }
223             if (ty != 'interface') {
224                 return ty;
225             }
226             // we can accept enum types here..
227             var interface_info = GIRepository.type_info_get_interface(type_info);
228             var interface_type = interface_info.get_type();
229             
230             if (!allow_iface && interface_type != GIRepository.InfoType.ENUM) {
231                 return false;
232             }
233             return interface_info.get_namespace() + '.' + interface_info.get_name();
234             
235         },
236         /**
237          * merge two proprety arrays' ignoring what's overrriden.
238          * 
239          * /
240         
241         
242         overrides : function (top, bottom)
243         {
244             function inTop(b)
245             {
246                 return !top.every(function(t) {
247                     if (t.name == b.name) {
248                         return false;
249                     }
250                     return true;
251                 });
252             }
253             bottom.forEach(function(e) {
254                 if (!inTop(e)) {
255                     top.push(e);
256                 }
257             });
258             
259         },
260         
261         /**
262          * guess type..
263          * 
264          * /
265         findType : function (data, prop, value)
266         {
267             // specials??
268             if ((prop == '|xns') || (prop == 'xtype'))  {
269                 return 'string';
270             }
271             
272             var qname = this.guessName(data);
273             if (prop[0] == '|') {
274                 prop= prop.substring(1);
275             }
276             
277             var prs = this.getPropertiesFor(qname, 'props');
278             var ret = false;
279             prs.forEach(function(e) {
280                 if (ret !== false) {
281                     return; // got it.
282                 }
283                 if (e.name == prop) {
284                     ret = e;
285                 }
286                 
287             });
288             if (!ret) {
289                 return Base.prototype.findType(data, prop,value);
290             }
291              
292             // got the type
293             return ret.type;
294         },
295         
296         findOptions : function(ename)
297         {
298             
299             var es = ename.split('.');
300             if (es.length !=2) {
301                 return Base.prototype.findOptions(ename);
302             }
303             var gi = GIRepository.Repository.get_default();
304             var bi = gi.find_by_name(es[0], es[1]);
305             var etype = GIRepository.object_info_get_type(bi);
306             if (etype != GIRepository.InfoType.ENUM) {
307                 console.log("Options not handled yet!!!");
308                 return false;
309             }
310             var ret = [];
311             // got an enum.. let's return the values..
312             for(var i =0; i < bi.get_n_values(); i++) {
313                  
314                   var prop = bi.get_value(i);
315                    
316                 
317                   ret.push( ename + '.' + prop.get_name().toUpperCase() ) 
318             }
319             return ret;
320         },
321         /**
322          * determine the packing types..
323          * /
324         getDefaultPack: function(pname, cname) {
325             var list = this.getPackingList(pname,cname);
326            // console.dump(list);
327             
328             
329             if (!list.every(function(e) { return e.name != 'add'; })) {
330                 return 'add'; // add is in our list..?? what about args..?!?
331             }
332             function toRet(e) {
333                 var ret = [e.name];
334                 e.params.forEach(function(p,i) {
335                     if (ret === false) { return; } // skip broken..
336                     if (i==0) { return; } // skip first..
337                     if (p.type == 'boolean') {
338                         ret.push('false');
339                         return;
340                     }
341                     if (p.type == 'number') {
342                         ret.push('0');
343                         return;
344                     }
345                     if (p.type == 'uint') {
346                         ret.push('0');
347                         return;
348                     }
349                     ret = false; // invalid!
350                 });
351                 return ret === false ? false : ret.join(',');
352             };
353             var packret = false;
354             list.every(function(e) {
355                 
356                 packret = toRet(e);
357                 //print("DEFAULT PACK TEST : " + e.name + " : " +packret);
358                 if (packret !== false) {
359                     return false;
360                 }
361                 return true; // continue
362             });
363             //print("DEFAULT PACK: " + packret);
364             // should we do best match..?
365             return packret;
366         },
367         /**
368          * get packing list..
369          * /
370         getPackingList :function (pname, cname)
371         {
372             var funcs = this.getPropertiesFor(pname,'methods');
373             //print("getPackingList : ALL FUNCS");
374             //console.dump(funcs);
375             var ret = [];
376             var _this = this;
377             // let's assume top down...
378             var inherits = [ cname ];
379             inherits.push.apply(inherits, this.getPropertiesFor(cname,'inherits'));
380             funcs.forEach(function(m) {
381                 if (m.params.length && (typeof(m.params[0].type) == 'string') &&
382                     inherits.indexOf(m.params[0].type) > -1) {
383                     ret.push(m);
384                 }
385             });
386             return ret; 
387         }
388       */
389
390                 public override void fillPack(JsRender.Node node,JsRender.Node parent)
391                 {   
392
393                         string inherits = " " + string.joinv(" ", this.getInheritsFor (node.fqn()) + " ";
394                         // parent.fqn() method ( node.fqn()
395                         var methods = this.getPropertiesFor (parent.fqn());
396                         
397                         var map = methods.map_iterator();
398                         while (map.next()) {
399                                 var n = map.get_key();
400                                 var meth = map.get_value();
401                                 if (meth.paramset == null || meth.paramset.params.length() < 1) {
402                                         continue;
403                                 }
404                                 var fp = meth.paramset.params.nth_data(0);
405                                 var type = this.fqtype(fp.type, meth.ns);
406                                 if (!inherits.contains(" " + type + " ")) {
407                                         continue;
408                                 }
409                                 
410                                 
411
412                         }
413
414                         
415                 }
416         
417     }
418 }
419