38b3627da96fc0323b38b7d1c48d24ef1952065c
[app.Builder.js] / Builder / Provider / Palete / Gtk.js
1 //<Script type="text/javascript">
2  
3 Gio = imports.gi.Gio;
4 GIRepository  = imports.gi.GIRepository;
5 xml     = imports.libxml;
6 console = imports.console;
7 XObject = imports.XObject.XObject;
8
9 Base = imports.Builder.Provider.Palete.Base.Base;
10 File = imports.File.File;
11 //----------------------- our roo verison
12
13
14
15
16 Gtk = XObject.define(
17     function(cfg) {
18         
19        
20         // various loader methods..
21           this.map = [];
22         this.load();
23         this.proplist = {};
24         this.comments = { }; 
25         // no parent...
26         
27        
28     },
29     Base,
30     {
31         load: function () {
32                 
33          
34         
35             var data = File.read(__script_path__ +'/../GtkUsage.txt');
36           // print(data);
37             data  = data.split(/\n/g);
38             var state = 0;
39             var cfg = [];
40             var left = [];
41             var right = [];
42             
43             data.forEach( function(d) {
44                 if (!d.length || d.match(/^\s+$/) || d.match(/^\//)) { //empty
45                     return;
46                 }
47                 if (d.match(/^left:/)) { 
48                     state = 1;
49                     if (left.length ){
50                         
51                         cfg.push({
52                             left : left,
53                             right: right
54                         });
55                         }
56                     left = [];
57                     right = [];
58                     return;
59                 }
60                 if (d.match(/^right:/)) { 
61                     state = 2;
62                     return;
63                 }
64                 if (state == 1) {
65                     left.push(d.replace(/\s+/g, ''));
66                     return;
67                 }
68                 right.push(d.replace(/\s+/g, ''));
69                 //Seed.quit();
70                
71             }); 
72             if (left.length ){
73                         
74                 cfg.push({
75                     left : left,
76                     right: right
77                 });
78             }
79             this.map = cfg;
80              
81         },
82         
83         
84         commentLoad : function(ns)
85         {
86              
87             if (typeof(this.comments[ns]) != 'undefined') {
88                 return;
89             }
90
91             console.log("LOAD DOCS: " + ns);
92             var gi = GIRepository.IRepository.get_default();
93             var ver = gi.get_version(ns);
94             if (!ver) {
95                 this.comments[ns] = {};
96                 return;
97             }
98             var ret = { };
99
100             // no idea why this is broken on my build system.
101             function getAttribute(n, name){
102                 var properties = n.properties;
103                 while (properties){
104                     if (properties.name == name)
105                          return properties.children.content;
106                      properties = properties.next
107                 }
108                 return null;
109             }
110                  
111          
112             function walk(element, path) {
113                  
114                  
115                 if (!element) {
116                     return;
117                 }
118                 
119                 var n =  getAttribute(element, 'name') ;
120                 //console.log("WALK" + n);
121                 if (n) {
122                     path += path.length ? '.' : '';
123                     path += n;
124                 }
125                 if (element.name == 'return-value') {
126                     path += '.return-value';
127                 }
128                 
129                 if (element.name == 'signal') {
130                     path += '.signal';
131                 } 
132              
133                 var d =   getAttribute(element,'doc');
134                 if (d) {
135                  //   Seed.print(path + ':' + d);
136                     ret[path] = d;
137                 }
138                 
139                 var child = element.children;
140
141                 while (child){
142                     //console.log(child.tag);
143                     if (child.type == "element"){
144                         walk (child, path);
145                     }
146                     child = child.next;
147                 }
148             }
149             
150             var pth = GIRepository.IRepository.get_search_path ();
151             
152             
153             var gir_path = pth[0].replace(/lib\/girepository-1.0/, 'share\/gir-1.0');
154            
155             
156             //console.log(fn);
157             var  fn = gir_path + '/'+ ns + '-' + ver + '.gir';
158            // console.log(fn);
159             
160             if (!File.exists(fn)) {
161                 console.log('missing docc file ' + fn);
162                 this.comments[ns] = {};
163                 
164                 return;
165             }
166             var doc = xml.parseFile(fn);
167             //console.log("xmldoc?" + doc);
168             walk (doc.root, '');
169             //console.dump(ret);
170             this.comments[ns] = ret;
171
172         },
173        
174         
175         doc : function(what) {
176             var ns = what.split('.').shift();
177             this.commentLoad(ns);
178             return typeof(this.comments[ns][what]) == 'undefined' ?  '' : this.comments[ns][what];
179         },
180   
181         getPropertiesFor: function(ename, type)
182         {
183             print("Loading for " + ename);
184             
185             if (typeof(this.proplist[ename]) != 'undefined') {
186                     return this.proplist[ename][type];
187             }
188             // use introspection to get lists..
189             var gi = GIRepository.IRepository.get_default();
190             var es = ename.split('.');
191             var bi = gi.find_by_name(es[0], es[1]);
192             
193             if (!bi) {
194                 print("COULND NOT FIND BY NAME");
195                 return [];
196             }
197             var etype = GIRepository.base_info_get_type(bi);
198             var meth = etype == GIRepository.IInfoType.INTERFACE ?
199                 [ 
200                     'interface_info_get_n_properties',
201                     'interface_info_get_property',
202                     'interface_info_get_n_signals',
203                     'interface_info_get_signal'
204                 ] : [ 
205                     'object_info_get_n_properties',
206                     'object_info_get_property',
207                     'object_info_get_n_signals',
208                     'object_info_get_signal'
209                 ]; 
210             
211             
212             this.proplist[ename] = {}
213             this.proplist[ename]['props'] = [];
214             this.proplist[ename]['events'] = [];
215             this.proplist[ename]['inherits']= [];
216             var plist = this.proplist[ename]['props'] ;
217             var elist = this.proplist[ename]['events'];
218             var ilist = this.proplist[ename]['inherits'];
219              /*
220              we need...
221              p.name
222             p.type
223             p.desc
224             p.sig */
225            function typeToName (type_info) {
226                var ty = GIRepository.type_tag_to_string( GIRepository.type_info_get_tag(type_info));
227                
228                 if ((ty == 'void') && GIRepository.type_info_is_pointer(type_info)) {
229                     return false;
230                 }
231                 if (ty == 'array') {
232                     return false; // unspported   
233                 }
234                 if (ty != 'interface') {
235                     
236                     return ty;
237                 }
238                 // we can accept enum types here..
239                 var interface_info = GIRepository.type_info_get_interface (type_info);        
240                 var interface_type = GIRepository.base_info_get_type (interface_info);
241                 if (interface_type != GIRepository.IInfoType.ENUM) {
242                     return false;
243                 }
244                 return GIRepository.base_info_get_namespace(interface_info) + '.' +
245                         GIRepository.base_info_get_name(interface_info);
246                 
247             }
248             // properties.. -- and parent ones...!!!
249             for (var i =0;i <  GIRepository[meth[0]](bi); i++) {
250                 var prop = GIRepository[meth[1]](bi, i);  
251                 var n_original =  GIRepository.base_info_get_name(prop);
252                 
253                 var flags =  GIRepository.property_info_get_flags(prop); // check for readonly..
254                 
255                 
256                 var ty = typeToName(GIRepository.property_info_get_type(prop));
257                 print (n_original +":"+ ty);
258                 if (ty === false) {
259                     continue;
260                 }
261                 var add = {
262                      name :  n_original.replace(/\-/g, '_'),
263                      type :  ty,
264                      desc : this.doc(ename + '.' + n_original),
265                      sig : ''
266                 }
267                 plist.push(add)
268             }
269            
270             // signals..
271             
272             for (var i =0;i <  GIRepository[meth[2]](bi); i++) {
273                 var prop = GIRepository[meth[3]](bi, i);  
274                 var n_original =  GIRepository.base_info_get_name(prop);
275                  print ('signal: ' + n_original); 
276                 var add = {
277                     name :  n_original.replace(/\-/g, '_'),
278                     type : 'function', //???
279                     desc : this.doc(ename + '.' + n_original),
280                     sig  : '' // fixme..
281                 }
282                 elist.push(add);
283             }
284             
285             if (etype == GIRepository.IInfoType.INTERFACE ) {
286                   return;
287             }
288             
289             // parent!!?!!?
290             var pi = GIRepository.object_info_get_parent(bi);
291             
292             if (pi) {
293                 
294                    
295                 var pname = GIRepository.base_info_get_namespace(pi) + '.' +
296                     GIRepository.base_info_get_name(pi);
297                 this.getPropertiesFor(pname, 'props');
298             
299                 elist.push.apply(elist,this.proplist[pname]['events']);
300                 plist.push.apply(plist,this.proplist[pname]['props']);
301                 ilist.push.apply(ilist,this.proplist[pname]['inherits']);
302             }
303             
304             // implements needs to be more carefull as it could add dupes..
305             // use the parent implements list to ensure no dupes..
306             for(var i =0; i < GIRepository.object_info_get_n_interfaces(bi); i++) {
307                  
308                 var prop = GIRepository.object_info_get_interface(bi,i);
309                 var iface = GIRepository.base_info_get_namespace(prop) +'.'+ 
310                     GIRepository.base_info_get_name(prop);
311                 if ( ilist.indexOf(iface) > -1) {
312                     continue;
313                 }
314                 this.getPropertiesFor(iface, 'props');
315                 ilist.push(iface);
316                 elist.push.apply(elist,this.proplist[iface]['events']);
317                 plist.push.apply(plist,this.proplist[iface]['props']);
318             }
319             
320             return this.proplist[ename][type];
321             
322         }
323         
324         
325         
326     }
327 );
328