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