Attribute changed old-javascript
[app.Builder.js] / old-javascript / Palete / Gtk.js
1 //<Script type="text/javascript">
2  
3 Gio = imports.gi.Gio;
4 GIRepository  = imports.gi.GIRepository;
5 GObject= imports.gi.GObject;
6 xml     = imports.libxml;
7 console = imports.console;
8 XObject = imports.XObject.XObject;
9
10 Base = imports.Palete.Base.Base;
11 File = imports.File.File;
12 //----------------------- our roo verison
13
14
15
16
17 Gtk = XObject.define(
18     function(cfg) {
19         
20        
21         // various loader methods..
22           this.map = [];
23         this.load();
24         this.proplist = {};
25         this.comments = { }; 
26         // no parent...
27         
28        
29     },
30     Base,
31     {
32         name : 'Gtk',
33         
34         load: function () {
35                 
36          
37         
38             var data = File.read(__script_path__ +'/GtkUsage.txt');
39           // print(data);
40             data  = data.split(/\n/g);
41             var state = 0;
42             var cfg = [];
43             var left = [];
44             var right = [];
45             
46             data.forEach( function(d) {
47                 if (!d.length || d.match(/^\s+$/) || d.match(/^\s*\//)) { //empty
48                     return;
49                 }
50                 if (d.match(/^left:/)) { 
51                     state = 1;
52                     if (left.length ){
53                         
54                         cfg.push({
55                             left : left,
56                             right: right
57                         });
58                         }
59                     left = [];
60                     right = [];
61                     return;
62                 }
63                 if (d.match(/^right:/)) { 
64                     state = 2;
65                     return;
66                 }
67                 if (state == 1) {
68                     left.push(d.replace(/\s+/g, ''));
69                     return;
70                 }
71                 right.push(d.replace(/\s+/g, ''));
72                 //Seed.quit();
73                
74             }); 
75             if (left.length ){
76                         
77                 cfg.push({
78                     left : left,
79                     right: right
80                 });
81             }
82             this.map = cfg;
83              
84         },
85         
86         
87         commentLoad : function(ns)
88         {
89              
90             if (typeof(this.comments[ns]) != 'undefined') {
91                 return;
92             }
93
94             console.log("LOAD DOCS: " + ns);
95             var gi = GIRepository.Repository.get_default();
96             var ver = gi.get_version(ns);
97             if (!ver) {
98                 this.comments[ns] = {};
99                 return;
100             }
101             var ret = { };
102
103             // no idea why this is broken on my build system.
104             function getAttribute(n, name){
105                 var properties = n.properties;
106                 while (properties){
107                     if (properties.name == name)
108                          return properties.children.content;
109                      properties = properties.next
110                 }
111                 return null;
112             }
113                  
114          
115             function walk(element, path) {
116                  
117                  
118                 if (!element) {
119                     return;
120                 }
121                 
122                 var n =  getAttribute(element, 'name') ;
123                 //console.log("WALK" + n);
124                 if (element.name == 'signal') {
125                     path += '.signal';
126                 } 
127                 if (n) {
128                     path += path.length ? '.' : '';
129                     path += n;
130                 }
131                 if (element.name == 'return-value') {
132                     path += '.return-value';
133                 }
134                 
135                 
136              
137                 var d =   getAttribute(element,'doc');
138                 if (d) {
139                  //   Seed.print(path + ':' + d);
140                     ret[path] = d;
141                 }
142                 
143                 var child = element.children;
144
145                 while (child){
146                     //console.log(child.tag);
147                     if (child.type == "element"){
148                         walk (child, path);
149                     }
150                     child = child.next;
151                 }
152             }
153             
154             var pth = GIRepository.Repository.get_search_path ();
155             
156             
157             var gir_path = pth[0].replace(/lib\/girepository-1.0/, 'share\/gir-1.0');
158            
159             
160             //console.log(fn);
161             var  fn = gir_path + '/'+ ns + '-' + ver + '.gir';
162            // console.log(fn);
163             
164             if (!File.exists(fn)) {
165                 console.log('missing docc file ' + fn);
166                 this.comments[ns] = {};
167                 
168                 return;
169             }
170             var doc = xml.parseFile(fn);
171             //console.log("xmldoc?" + doc);
172             walk (doc.root, '');
173             //console.dump(ret);
174             this.comments[ns] = ret;
175             //console.dump(ret);
176
177         },
178        
179         
180         doc : function(what) {
181             var ns = what.split('.').shift();
182             this.commentLoad(ns);
183             return typeof(this.comments[ns][what]) == 'undefined' ?  '' : this.comments[ns][what];
184         },
185   
186         getPropertiesFor: function(ename, type)
187         {
188             //print("Loading for " + ename);
189             
190             if (typeof(this.proplist[ename]) != 'undefined') {
191                 //print("using cache");
192                 return this.proplist[ename][type];
193             }
194             // use introspection to get lists..
195             var gi = GIRepository.Repository.get_default();
196             var es = ename.split('.');
197             
198             var giname = es[0];
199             giname = giname == 'Glade' ? 'Gladeui' : giname;
200             
201             imports.gi[giname ];
202             var bi = gi.find_by_name(giname , es[1]);
203             
204             if (!bi) {
205                 print("COULND NOT FIND BY NAME");
206                 return [];
207             }
208             var etype = bi.get_type();;
209             var meth = etype == GIRepository.InfoType.INTERFACE ?
210                 [ 
211                     'interface_info_get_n_properties',
212                     'interface_info_get_property',
213                     'interface_info_get_n_signals',
214                     'interface_info_get_signal',
215                     'interface_info_get_n_methods',
216                     'interface_info_get_method'
217                 ] : [ 
218                     'object_info_get_n_properties',
219                     'object_info_get_property',
220                     'object_info_get_n_signals',
221                     'object_info_get_signal',
222                     'object_info_get_n_methods',
223                     'object_info_get_method'
224                 ]; 
225             
226             
227             this.proplist[ename] = {}
228             this.proplist[ename]['props'] = [];
229             this.proplist[ename]['events'] = [];
230             this.proplist[ename]['methods'] = [];
231             this.proplist[ename]['inherits']= [];
232             
233             var plist = this.proplist[ename]['props'] ;
234             var elist = this.proplist[ename]['events'];
235             var mlist = this.proplist[ename]['methods'];
236             var ilist = this.proplist[ename]['inherits'];
237              /*
238              we need...
239              p.name
240             p.type
241             p.desc
242             p.sig */
243             
244             // properties.. -- and parent ones...!!!
245             for (var i =0;i <  GIRepository[meth[0]](bi); i++) {
246                 var prop = GIRepository[meth[1]](bi,i);  
247                 var n_original =  prop.get_name();
248                 
249                 var flags =  GIRepository.property_info_get_flags(prop); // check for readonly..
250                 
251                 
252                 var ty = this.typeToName(GIRepository.property_info_get_type(prop));
253                 var flags = GIRepository.property_info_get_flags(prop);
254                 print (n_original +":"+ ty);
255                 if (ty === false) {
256                     continue;
257                 }
258                 var add = {
259                      name :  n_original.replace(/\-/g, '_'),
260                      type :  ty,
261                      desc : this.doc(ename + '.' + n_original),
262                      sig : '',
263                      ctor_only : (flags  & GObject.ParamFlags.CONSTRUCT_ONLY) > 0
264                 }
265                 plist.push(add)
266             }
267            
268            
269            
270            
271            
272             // signals..
273             
274             for (var i =0;i <  GIRepository[meth[2]](bi); i++) {
275                 var prop =GIRepository[meth[3]](bi,i);  
276                 var n_original =  prop.get_name();
277                 // print ('signal: ' + n_original); 
278                 var add = {
279                     name :  n_original.replace(/\-/g, '_'),
280                     type : 'function', //???
281                     desc : this.doc(ename + '.signal.' + n_original),
282                     sig  : this.genSkel(prop) // fixme..
283                 }
284                 elist.push(add);
285             }
286             // methods
287             
288             for (var i =0;i <  GIRepository[meth[4]](bi); i++) {
289                 var prop = GIRepository[meth[5]](bi,i);  
290                 var n_original =  prop.get_name();
291                 print(ename +": ADD method: " + n_original );
292                 //var flags = GIRepository.property_info_get_flags(prop);
293                 
294                 if (n_original.match(/^new/)) {
295                     var add = {
296                         name :  n_original.replace(/\-/g, '_'),
297                         type : 'ctor', //???
298                         desc : '',
299                         //desc : this.doc(ename + "."+ n_original)
300                     };
301                     this.genParams(prop,add);
302                     mlist.push(add);
303                     continue;
304                 }
305                 continue;
306                 // not sure why we need all the other ones...
307                 //if (!(flags & GIRepository.FunctionInfoFlags.IS_METHOD)) {
308                 //    continue;
309                 //}
310                 // print ('signal: ' + n_original); 
311                 var add = {
312                     name :  n_original.replace(/\-/g, '_'),
313                     type : 'function', //???
314                     desc : '', //this.doc(ename + '.' + n_original)
315                 };
316                 this.genParams(prop,add);
317                 mlist.push(add);
318             }
319             
320             
321             
322             
323             
324             
325             if (etype == GIRepository.InfoType.INTERFACE ) {
326                // print("SKIPPING PARENT - it's an interface?!?!");
327                   return;
328             }
329             
330             // parent!!?!!?
331             var pi = GIRepository.object_info_get_parent(bi);
332             
333             if (pi) {
334                 
335                    
336                 var pname = pi.get_namespace() + '.' + pi.get_name();
337                 this.getPropertiesFor(pname, 'props');
338                 
339                 
340                 elist.push.apply(elist,this.proplist[pname]['events']);
341                 plist.push.apply(plist,this.proplist[pname]['props']);
342                 ilist.push(pname);
343                 ilist.push.apply(ilist,this.proplist[pname]['inherits']);
344                 
345                 this.overrides(mlist, this.proplist[pname]['methods']);
346                 
347                 
348             } else {
349                 print("NO PARENT FOUND?");
350             }
351             
352             // implements needs to be more carefull as it could add dupes..
353             // use the parent implements list to ensure no dupes..
354             for(var i =0; i < GIRepository.object_info_get_n_interfaces(bi); i++) {
355                  
356                 var prop = GIRepository.object_info_get_interface(bi,i);
357                 var iface = prop.get_namespace() +'.'+ prop.get_name();
358                 if ( ilist.indexOf(iface) > -1) {
359                     continue;
360                 }
361                 this.getPropertiesFor(iface, 'props'); // just load one of them..
362                 ilist.push(iface);
363                 
364                 elist.push.apply(elist,this.proplist[iface]['events']);
365                 plist.push.apply(plist,this.proplist[iface]['props']);
366                 this.overrides(mlist, this.proplist[pname]['methods']);
367             }
368             function sfunc(a,b) {
369                 if (a.name == b.name) return 0;
370                 return a.name > b.name ? 1 : -1
371             }
372             plist.sort(sfunc);
373             elist.sort(sfunc);
374             mlist.sort(sfunc);
375             
376             return this.proplist[ename][type];
377             
378         },
379         genParams: function(sig, meth)
380         {
381             var args = ['self'];
382             var ret = "\n";
383             meth.ret_type = this.typeToName(GIRepository.callable_info_get_return_type(sig));
384             // might be a numbeR??
385             meth.params = [];
386             for(var a_i  =0; a_i   < GIRepository.callable_info_get_n_args(sig); a_i++) {
387                 var arg = GIRepository.callable_info_get_arg(sig, a_i);
388                 print(arg.get_name());
389                 print(arg.get_type());
390                 meth.params.push({
391                     name  : arg.get_name(),
392                     type : this.typeToName(arg.get_type(), true)
393                 });
394             }
395             
396                 
397             
398             
399         },
400         genSkel: function(sig) // should really use genParams...
401         {
402             var args = ['self'];
403             var ret = "\n";
404             var ret_type = this.typeToName(GIRepository.callable_info_get_return_type(sig));
405             // might be a numbeR??
406             if (ret_type == 'boolean') {
407                 ret = "    return false;\n";
408             }
409             for(var a_i  =0; a_i   < GIRepository.callable_info_get_n_args(sig); a_i++) {
410                 var arg = GIRepository.callable_info_get_arg(sig, a_i);
411                 
412                 args.push(arg.get_name());
413             }
414             return 'function (' + args.join(', ') + ") {\n" + ret + "}"; 
415                 
416             
417             
418         },
419         typeToName  : function (type_info, allow_iface) // find type for properties or arguments.
420         {
421             print(type_info);
422             if (type_info == 17) {
423                 return 'integer';
424             }
425              
426             var x = GIRepository.type_info_get_tag(type_info);
427             print(x);
428             var ty = GIRepository.type_tag_to_string( GIRepository.type_info_get_tag(type_info));
429             print(ty);
430            
431             if ((ty == 'void') && GIRepository.type_info_is_pointer(type_info)) {
432                 return false;
433             }
434             if (ty == 'array') {
435                 return false; // unspported   
436             }
437             if (ty != 'interface') {
438                 return ty;
439             }
440             // we can accept enum types here..
441             var interface_info = GIRepository.type_info_get_interface(type_info);
442             var interface_type = interface_info.get_type();
443             
444             if (!allow_iface && interface_type != GIRepository.InfoType.ENUM) {
445                 return false;
446             }
447             return interface_info.get_namespace() + '.' + interface_info.get_name();
448             
449         },
450         /**
451          * merge two proprety arrays' ignoring what's overrriden.
452          * 
453          */
454         
455         
456         overrides : function (top, bottom)
457         {
458             function inTop(b)
459             {
460                 return !top.every(function(t) {
461                     if (t.name == b.name) {
462                         return false;
463                     }
464                     return true;
465                 });
466             }
467             bottom.forEach(function(e) {
468                 if (!inTop(e)) {
469                     top.push(e);
470                 }
471             });
472             
473         },
474         
475         /**
476          * guess type..
477          * 
478          */
479         findType : function (data, prop, value)
480         {
481             // specials??
482             if ((prop == '|xns') || (prop == 'xtype'))  {
483                 return 'string';
484             }
485             
486             var qname = this.guessName(data);
487             if (prop[0] == '|') {
488                 prop= prop.substring(1);
489             }
490             
491             var prs = this.getPropertiesFor(qname, 'props');
492             var ret = false;
493             prs.forEach(function(e) {
494                 if (ret !== false) {
495                     return; // got it.
496                 }
497                 if (e.name == prop) {
498                     ret = e;
499                 }
500                 
501             });
502             if (!ret) {
503                 return Base.prototype.findType(data, prop,value);
504             }
505              
506             // got the type
507             return ret.type;
508         },
509         
510         findOptions : function(ename)
511         {
512             
513             var es = ename.split('.');
514             if (es.length !=2) {
515                 return Base.prototype.findOptions(ename);
516             }
517             var gi = GIRepository.Repository.get_default();
518             var bi = gi.find_by_name(es[0], es[1]);
519             var etype 
520             try {
521                 etype = GIRepository.object_info_get_type(bi);    
522             } catch(e) {
523                 return false;
524             }
525             
526             if (etype != GIRepository.InfoType.ENUM) {
527                 console.log("Options not handled yet!!!");
528                 return false;
529             }
530             var ret = [];
531             // got an enum.. let's return the values..
532             for(var i =0; i < bi.get_n_values(); i++) {
533                  
534                   var prop = bi.get_value(i);
535                    
536                 
537                   ret.push( ename + '.' + prop.get_name().toUpperCase() ) 
538             }
539             return ret;
540         },
541         /**
542          * determine the packing types..
543          */
544         getDefaultPack: function(pname, cname) {
545             var list = this.getPackingList(pname,cname);
546            // console.dump(list);
547             
548             
549             if (!list.every(function(e) { return e.name != 'add'; })) {
550                 return 'add'; // add is in our list..?? what about args..?!?
551             }
552             function toRet(e) {
553                 var ret = [e.name];
554                 e.params.forEach(function(p,i) {
555                     if (ret === false) { return; } // skip broken..
556                     if (i==0) { return; } // skip first..
557                     if (p.type == 'boolean') {
558                         ret.push('false');
559                         return;
560                     }
561                     if (p.type == 'number') {
562                         ret.push('0');
563                         return;
564                     }
565                     if (p.type == 'uint') {
566                         ret.push('0');
567                         return;
568                     }
569                     ret = false; // invalid!
570                 });
571                 return ret === false ? false : ret.join(',');
572             };
573             var packret = false;
574             list.every(function(e) {
575                 
576                 packret = toRet(e);
577                 //print("DEFAULT PACK TEST : " + e.name + " : " +packret);
578                 if (packret !== false) {
579                     return false;
580                 }
581                 return true; // continue
582             });
583             //print("DEFAULT PACK: " + packret);
584             // should we do best match..?
585             return packret;
586         },
587         /**
588          * get packing list..
589          */
590         getPackingList :function (pname, cname)
591         {
592             var funcs = this.getPropertiesFor(pname,'methods');
593             //print("getPackingList : ALL FUNCS");
594             //console.dump(funcs);
595             var ret = [];
596             var _this = this;
597             // let's assume top down...
598             var inherits = [ cname ];
599             inherits.push.apply(inherits, this.getPropertiesFor(cname,'inherits'));
600             funcs.forEach(function(m) {
601                 if (m.params.length && (typeof(m.params[0].type) == 'string') &&
602                     inherits.indexOf(m.params[0].type) > -1) {
603                     ret.push(m);
604                 }
605             });
606             return ret; 
607         }
608         
609         
610     }
611 );
612