608d9926f80de48b375c85f821c5802aabe644ca
[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              
130                 var d =   getAttribute(element,'doc');
131                 if (d) {
132                  //   Seed.print(path + ':' + d);
133                     ret[path] = d;
134                 }
135                 
136                 var child = element.children;
137
138                 while (child){
139                     //console.log(child.tag);
140                     if (child.type == "element"){
141                         walk (child, path);
142                     }
143                     child = child.next;
144                 }
145             }
146             
147             var pth = GIRepository.IRepository.get_search_path ();
148             
149             
150             var gir_path = pth[0].replace(/lib\/girepository-1.0/, 'share\/gir-1.0');
151            
152             
153             //console.log(fn);
154             var  fn = gir_path + '/'+ ns + '-' + ver + '.gir';
155            // console.log(fn);
156             
157             if (!File.exists(fn)) {
158                 console.log('missing docc file ' + fn);
159                 this.comments[ns] = {};
160                 
161                 return;
162             }
163             var doc = xml.parseFile(fn);
164             //console.log("xmldoc?" + doc);
165             walk (doc.root, '');
166             //console.dump(ret);
167             this.comments[ns] = ret;
168
169         },
170        
171         
172         doc : function(what) {
173             var ns = what.split('.').shift();
174             this.commentLoad(ns);
175             return typeof(this.comments[ns][what]) == 'undefined' ?  '' : this.comments[ns][what];
176         },
177   
178         getPropertiesFor: function(ename, type)
179         {
180             print("Loading for " + ename);
181             
182             if (typeof(this.proplist[ename]) != 'undefined') {
183                     return this.proplist[ename][type];
184             }
185             // use introspection to get lists..
186             var gi = GIRepository.IRepository.get_default();
187             var es = ename.split('.');
188             var bi = gi.find_by_name(es[0], es[1]);
189             
190             if (!bi) {
191                 print("COULND NOT FIND BY NAME");
192                 return [];
193             }
194             var etype = GIRepository.base_info_get_type(bi);
195             var meth = etype == GIRepository.IInfoType.INTERFACE ?
196                 [ 
197                     'interface_info_get_n_properties',
198                     'interface_info_get_property',
199                     'interface_info_get_n_signals',
200                     'interface_info_get_signal'
201                 ] : [ 
202                     'object_info_get_n_properties',
203                     'object_info_get_property',
204                     'object_info_get_n_signals',
205                     'object_info_get_signal'
206                 ]; 
207             
208             
209             this.proplist[ename] = {}
210             this.proplist[ename]['props'] = [];
211             this.proplist[ename]['events'] = [];
212             this.proplist[ename]['inherits']= [];
213             var plist = this.proplist[ename]['props'] ;
214             var elist = this.proplist[ename]['events'];
215             var ilist = this.proplist[ename]['inherits'];
216              /*
217              we need...
218              p.name
219             p.type
220             p.desc
221             p.sig */
222            function typeToName (type_info) {
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                     
233                     return ty;
234                 }
235                 // we can accept enum types here..
236                 var interface_info = GIRepository.type_info_get_interface (type_info);        
237                 var interface_type = GIRepository.base_info_get_type (interface_info);
238                 if (interface_type != GIRepository.IInfoType.ENUM) {
239                     return false;
240                 }
241                 return GIRepository.base_info_get_namespace(interface_info) + '.' +
242                         GIRepository.base_info_get_name(interface_info);
243                 
244             }
245             // properties.. -- and parent ones...!!!
246             for (var i =0;i <  GIRepository[meth[0]](bi); i++) {
247                 var prop = GIRepository[meth[1]](bi, i);  
248                 var n_original =  GIRepository.base_info_get_name(prop);
249                 
250                 var flags =  GIRepository.property_info_get_flags(prop); // check for readonly..
251                 
252                 
253                 var ty = typeToName(GIRepository.property_info_get_type(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                 }
264                 plist.push(add)
265             }
266            
267             // signals..
268             
269             for (var i =0;i <  GIRepository[meth[2]](bi); i++) {
270                 var prop = GIRepository[meth[3]](bi, i);  
271                 var n_original =  GIRepository.base_info_get_name(prop);
272                  print ('signal: ' + n_original); 
273                 var add = {
274                     name :  n_original.replace(/\-/g, '_'),
275                     type : 'function', //???
276                     desc : this.doc(ename + '.' + n_original),
277                     sig  : '' // fixme..
278                 }
279                 elist.push(add);
280             }
281             
282             if (etype == GIRepository.IInfoType.INTERFACE ) {
283                   return;
284             }
285             
286             // parent!!?!!?
287             var pi = GIRepository.object_info_get_parent(bi);
288             
289             if (pi) {
290                 
291                    
292                 var pname = GIRepository.base_info_get_namespace(pi) + '.' +
293                     GIRepository.base_info_get_name(pi);
294                 this.getPropertiesFor(pname, 'props');
295             
296                 elist.push.apply(elist,this.proplist[pname]['events']);
297                 plist.push.apply(plist,this.proplist[pname]['props']);
298                 ilist.push.apply(ilist,this.proplist[pname]['inherits']);
299             }
300             
301             // implements needs to be more carefull as it could add dupes..
302             // use the parent implements list to ensure no dupes..
303             for(var i =0; i < GIRepository.object_info_get_n_interfaces(bi); i++) {
304                  
305                 var prop = GIRepository.object_info_get_interface(bi,i);
306                 var iface = GIRepository.base_info_get_namespace(prop) +'.'+ 
307                     GIRepository.base_info_get_name(prop);
308                 if ( ilist.indexOf(iface) > -1) {
309                     continue;
310                 }
311                 this.getPropertiesFor(iface, 'props');
312                 ilist.push(iface);
313                 elist.push.apply(elist,this.proplist[iface]['events']);
314                 plist.push.apply(plist,this.proplist[iface]['props']);
315             }
316             
317             return this.proplist[ename][type];
318             
319         }
320         
321         
322         
323     }
324 );
325