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