Fix #8089 - phase 1 - code ast navigation
[roobuilder] / src / JsRender / NodeToVala.vala
1 /**
2  * 
3  * Code to convert node tree to Vala...
4  * 
5  * usage : x = (new JsRender.NodeToVala(node)).munge();
6  * 
7  * Fixmes?
8  *
9  *  pack - can we come up with a replacement?
10      - parent.child == child_widget -- actually uses getters and effectively does 'add'?
11        (works on most)?
12     
13      
14  * args  -- vala constructor args (should really only be used at top level - we did use it for clutter originally(
15  * ctor  -- different ctor argument
16  
17  * 
18  
19  * 
20  * 
21 */
22
23  
24 public abstract class JsRender.NodeToVala : NodeWriter {
25
26         protected string this_el = "??";
27          
28         int child_count = 1; // used to number the children.
29         public string cls;  // node fqn()
30         public string xcls;
31         
32
33         Gee.ArrayList<string> ignoreWrappedList; 
34         Gee.ArrayList<string> myvars;
35
36
37          
38         int pane_number = 0;// ?? used when generating Gtk.Pane tabs
39         
40         
41         static construct {
42                 NodeWriter.globalIgnore("pack");
43                 NodeWriter.globalIgnore("init");
44                 NodeWriter.globalIgnore("xns");
45                 NodeWriter.globalIgnore("xtype");
46                 NodeWriter.globalIgnore("id");
47         
48         }
49         /* 
50          * ctor - just initializes things
51          * - wraps a render node 
52          */
53         protected NodeToVala( JsRender file,  Node node,  int depth, NodeToVala? parent) 
54         {
55
56                 base (file, node, depth, parent);
57          
58                 this.initPadding('\t', 1);
59                 
60                 this.cls = node.xvala_cls;
61                 this.xcls = node.xvala_xcls;
62                 if (depth == 0 && this.xcls.contains(".")) {
63                         var ar = this.xcls.split(".");
64                         this.xcls = ar[ar.length-1];
65                 }
66                 
67
68                 this.ignoreWrappedList  = new Gee.ArrayList<string>();
69                 this.myvars = new Gee.ArrayList<string>();
70                 this.child_count = 1;
71                  
72         }
73  
74         public void initCls()
75         {
76                 this.cls = this.file.tree.xvala_cls;
77                 this.xcls = this.file.tree.xvala_xcls;
78         }
79         public abstract  string mungeChild(  Node cnode);
80         
81          
82         public void namespaceHeader()
83         {
84                 if (this.depth > 0 || this.file.file_namespace == "") {
85                         return;
86                 } 
87                 this.addLine("namespace " + this.file.file_namespace);
88                 this.addLine("{");
89         
90         }
91         public void namespaceFooter()
92         {
93                 if (this.depth > 0 || this.file.file_namespace == "") {
94                         return;
95                 }
96                 this.addLine("}");
97         
98         }
99         
100
101         protected abstract void classHeader();
102          
103
104                         
105         /**
106          * when ID is used... on an element, it registeres a property on the top level...
107          * so that _this.ID always works..
108          * 
109          */
110         protected void addTopProperties()
111         {
112                 if (this.depth > 0) {
113                         return;
114                 }
115                 // properties - global..??
116                 foreach(var n in this.top_level_items) { 
117
118                         if (!n.props.has_key("id") || n.xvala_id.length < 0) {
119                                 continue;
120                                 
121                         }
122                         if (n.xvala_id[0] == '*' || n.xvala_id[0] == '+') {
123                                 continue;
124                         }
125                          
126                         this.addLine(this.pad + "public " + n.xvala_xcls + " " + n.xvala_id + ";");
127                         
128                 }
129                                 
130         }
131         /**
132          * create properties that are not 'part of the wrapped element.
133          * 
134          * 
135          */
136  
137         protected void addMyVars()
138         {
139                 GLib.debug("calling  addMyVars");
140                 
141                 this.addLine();
142                 this.addLine(this.ipad + "// my vars (def)");
143                         
144
145  
146                 var cls = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn());
147                    
148                 if (cls == null) {
149                         GLib.debug("Gir factory failed to find class %s", this.node.fqn());
150                         
151                         //return;
152                 }
153           
154                 
155                         // Key = TYPE:name
156                 foreach(var prop in this.node.props.values) {
157                    
158                         if (this.shouldIgnore(prop.name)) {
159                                 continue;
160                         }
161
162                         // user defined method
163                         if (prop.ptype == NodePropType.METHOD) {
164                                 continue;
165                         }
166                         if (prop.ptype == NodePropType.SPECIAL) {
167                                 continue;
168                         }
169                                 
170                         if (prop.ptype == NodePropType.SIGNAL) {
171                                 this.node.setLine(this.cur_line, "p", prop.name);
172                                 this.addLine(this.pad + "public signal " + prop.rtype + " " + prop.name  + " "  + prop.val + ";");
173                                 
174                                 this.ignore(prop.name);
175                                 continue;
176                         }
177                         
178                         GLib.debug("Got myvars: %s", prop.name.strip());
179                         
180                         if (prop.rtype.strip().length < 1) {
181                                 continue;
182                         }
183                         
184                         var isUser = prop.ptype == NodePropType.USER;
185                         if (this.node.fqn() == "Gtk.NotebookPage") {
186                                 isUser= true;
187                         }
188                         // is it a class property...
189                         if (cls != null && cls.props.has_key(prop.name) && !isUser) {
190                                 continue;
191                         }
192                         
193                         this.myvars.add(prop.name);
194                         prop.start_line = this.cur_line;
195                         
196                         this.node.setLine(this.cur_line, "p", prop.name);
197                         
198                         this.addLine(this.pad + "public " + prop.rtype + " " + prop.name + ";"); // definer - does not include value.
199
200
201                         prop.end_line = this.cur_line;                          
202                         this.ignore(prop.name);
203                         
204                                 
205                 }
206         }
207         
208         // if id of child is '+' then it's a property of this..
209         protected void addPlusProperties()
210         {
211                 if (this.node.readItems().size < 1) {
212                         return;
213                 }
214                 var iter = this.node.readItems().list_iterator();
215                 while (iter.next()) {
216                         var ci = iter.get();
217                                 
218                         if (ci.xvala_id[0] != '+') {
219                                 continue; // skip generation of children?
220                                 
221                         }
222                          
223                         this.addLine(this.pad + "public " + ci.xvala_xcls + " " + ci.xvala_id.substring(1) + ";");
224                                            
225                         
226                 }
227         }
228         /**
229          * add the constructor definition..
230          */
231         protected abstract void addValaCtor();
232         /**
233          *  make sure _this is defined..
234          */
235         protected void addUnderThis() 
236         {
237                 // public static?
238                 if (depth < 1) {
239                         this.addLine( this.ipad + "_this = this;");
240                         return;
241                 }
242                 // for non top level = _this point to owner, and _this.ID is set
243                 
244                 this.addLine( this.ipad + "_this = _owner;");
245
246                 if (this.node.props.has_key("id")
247                         &&
248                         this.node.xvala_id != "" 
249                         && 
250                         this.node.xvala_id[0] != '*' 
251                         && 
252                         this.node.xvala_id[0] != '+' 
253                         ) {
254                                 this.addLine( this.ipad + "_this." + node.xvala_id  + " = this;");
255                    
256                 }
257                          
258         }
259          
260         
261          
262         protected void addInitMyVars()
263         {
264                         //var meths = this.palete.getPropertiesFor(item['|xns'] + '.' + item.xtype, 'methods');
265                         //print(JSON.stringify(meths,null,4));Seed.quit();
266                         
267                         
268                         
269                         // initialize.. my vars..
270                 this.addLine();
271                 this.addLine( this.ipad + "// my vars (dec)");
272                 
273                 var iter = this.myvars.list_iterator();
274                 while(iter.next()) {
275                         
276                         var k = iter.get();
277                         
278                          
279                         var prop = this.node.props.get(k);
280                         
281                         var v = prop.val.strip();                       
282                         
283                         if (v.length < 1) {
284                                 continue; 
285                         }
286                         // at this point start using 
287
288                         if (v == "FALSE" || v == "TRUE") {
289                                 v= v.down();
290                         }
291                         //FIXME -- check for raw string.. "string XXXX"
292                         var is_raw = prop.ptype == NodePropType.RAW;
293                         
294                         // what's the type.. - if it's a string.. then we quote it..
295                         if (prop.rtype == "string" && !is_raw) {
296                                  v = "\"" +  v.escape("") + "\"";
297                         }
298                         // if it's a string...
299                         
300                         prop.start_line = this.cur_line;
301                         this.addLine(this.ipad + "this." + prop.name + " = " +   v +";");
302                         prop.end_line = this.cur_line;
303                 }
304         }
305
306         
307
308
309         
310         protected  void addWrappedProperties()
311         {
312                 var cls = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn());
313                 if (cls == null) {
314                         GLib.debug("Skipping wrapped properties - could not find class  %s" , this.node.fqn());
315                         return;
316                 }
317                 
318                 if (this.node.fqn() == "Gtk.NotebookPage") {
319                         return;
320                 }
321                         // what are the properties of this class???
322                 this.addLine();
323                 this.addLine(this.ipad + "// set gobject values");
324                 
325                 foreach(var p in cls.props.keys) { 
326                         var val = cls.props.get(p);
327                         //print("Check Write %s\n", p);
328                         if (!this.node.has(p)) {
329                                 continue;
330                         }
331                         if (this.shouldIgnoreWrapped(p)) {
332                                 continue;
333                         }
334                         
335                         this.ignore(p);
336
337
338                         var prop = this.node.get_prop(p);
339                         var v = prop.val;
340                         
341                         // user defined properties.
342                         if (prop.ptype == NodePropType.USER) {
343                                 continue;
344                         }
345                                 
346
347                         
348                         var is_raw = prop.ptype == NodePropType.RAW;
349                         
350                         // what's the type.. - if it's a string.. then we quote it..
351                         if (val.type == "string" && !is_raw) {
352                                  v = "\"" +  v.escape("") + "\"";
353                         }
354                         if (v == "TRUE" || v == "FALSE") {
355                                 v = v.down();
356                         }
357                         if (val.type == "float" && v[v.length-1] != 'f') {
358                                 v += "f";
359                         }
360                         
361                         prop.start_line = this.cur_line;
362                         this.addLine("%s%s%s = %s;".printf(ipad,this.this_el,p,v)); // // %s,  iter.get_value().type);
363
364                         
365                         
366                         prop.end_line = this.cur_line;          
367                            // got a property..
368                            
369
370                 }
371         } 
372         /**
373          *  pack the children into the parent.
374          * 
375          * if the child's id starts with '*' then it is not packed...
376          * - this allows you to define children and add them manually..
377          */
378
379         protected  void addChildren()
380         {
381                                 //code
382                 GLib.debug("addChildren %s, %d", this.node.fqn(), (int)this.node.readItems().size);
383                 if (this.node.readItems().size < 1) {
384                         return;
385                 }
386                 this.pane_number = 0;
387                 var cols = this.node.has("* columns") ? int.max(1, int.parse(this.node.get_prop("* columns").val)) : 1;
388                 var colpos = 0;
389                 
390                 var nb_child = "";
391                 var nb_tab = "";
392                 var nb_menu = "";
393                         
394                  
395                 foreach(var child in this.node.readItems()) {
396                         
397                         
398                          
399
400                         if (child.xvala_id[0] == '*') {
401                                 continue; // skip generation of children?
402                         }
403
404                         // probably added in ctor..                             
405                         if (child.has("* prop") && this.shouldIgnoreWrapped(child.get_prop("* prop").val)) {
406                                 continue;
407                         }
408                         // create the element..
409                           
410                         
411                         // this is only needed if it does not have an ID???
412                         var childname = this.addPropSet(child, child.has("id") ? child.get_prop("id").val : "") ; 
413                         if (!child.has("id") && this.this_el == "this.el.") {
414                                 this.addLine(this.ipad +  childname +".ref();"); 
415                         }
416                         if (child.has("* prop")) {
417                                 if (this.node.fqn() == "Gtk.NotebookPage") {
418                                         switch (child.get_prop("* prop").val) {
419                                                 case "child":
420                                                         nb_child = childname + (this.this_el == "this.el." ? ".el" : "");
421                                                         break;
422                                                         
423                                                 case "tab":
424                                                         nb_tab = childname + (this.this_el == "this.el." ? ".el" : "");
425                                                         break;
426                                                         
427                                                 case "menu":
428                                                         nb_menu = childname + (this.this_el == "this.el." ? ".el" : ""); 
429                                                         break;
430                                         }
431                                         continue;
432                                 }
433                         
434                                 // fixme special packing!??!?!
435                                 if (child.get_prop("* prop").val.contains("[]")) {
436                                         // currently this is not used?
437                                         // and it will not add ref..
438                                          
439                                         this.packChild(child, childname, 0, 0, child.get_prop("* prop").val);  /// fixme - this is a bit speciall...
440                                         continue;
441                                 }
442                                 
443         
444                                 
445                                 this.ignoreWrapped(child.get_prop("* prop").val);
446                                 var el_name = this.this_el == "this.el." ? ".el" : "";
447                                 
448                                 
449                                 this.addLine(ipad + this.this_el  + child.get_prop("* prop").val + " = " + childname + el_name +";");
450                                 
451                                 continue;
452                         } 
453                          
454                         this.packChild(child, childname, cols, colpos);
455                         
456                         if (child.has("colspan")) {
457                                 colpos += int.parse(child.get_prop("colspan").val);
458                         } else {
459                                 colpos += 1;
460                         }
461                                           
462                         
463                         // this.{id - without the '+'} = the element...
464                          
465                                   
466                 }
467                 
468                 GLib.debug("got node %s with nb_child= %s", this.node.fqn() , nb_child);
469                 if (this.node.fqn() == "Gtk.NotebookPage" && nb_child != "") {
470                         var nb = (this.this_el == "this.el." ? "notebook.el" : "notebook");
471                         
472                         if (nb_tab == "" && this.node.has("tab_label")) {
473                                 nb_tab = "new Gtk.Label(this.tab_label)";
474                         }
475                  
476                         if (nb_menu == "" && nb_tab == "") {
477                                 this.addLine(@"$(ipad)$(nb).append_page( $(nb_child)  );");
478                                 return;
479                         }
480                         if (nb_menu == "") {
481                                 this.addLine(@"$(ipad)$(nb).append_page( $(nb_child) , $(nb_tab) );");
482                                 return;
483                         }
484                         this.addLine(@"$(ipad)$(nb).append_page_menu( $(nb_child) , $(nb_tab), $(nb_menu) );");
485                 
486                 }
487                 
488         }
489         /**
490                 var childname = new Xcls_.... (....)
491                 
492         
493         */
494         protected string addPropSet(Node child, string child_name) 
495         {       
496          
497                 
498                 var xargs = "";
499                 if (child.has("* args")) {
500                         
501                         var ar = child.get_prop("* args").val.split(",");
502                         for (var ari = 0 ; ari < ar.length; ari++ ) {
503                                 var arg = ar[ari].split(" ");
504                                 xargs += "," + arg[arg.length -1];
505                         }
506                 }
507                 
508                 var childname = "child_" + "%d".printf(this.child_count++);     
509                 var prefix = "";
510                 if (child_name == "") {
511                         prefix = "var " + childname + " = ";
512                 }
513                 var cls =  child.xvala_xcls;
514                 /*
515                 if (this.this_el == "this.") {
516                         var clsdata = Palete.Gir.factoryFqn((Project.Gtk) this.file.project, this.node.fqn());
517                         //if (clsdata.is_sealed) {
518                                 cls = this.node.fqn(); // need ctor data...
519                                 this.addLine(this.ipad + @"$(prefix)new $cls( _this $xargs);" );
520                                 return child_name == "" ? childname : ("_this." + child_name);  
521                         }
522                 }
523                 */
524                 if (child.fqn() == "Gtk.NotebookPage") {
525                         xargs +=" , this";
526                 }
527                 
528                 this.addLine(this.ipad + @"$(prefix)new $cls( _this $xargs);" );
529                  
530                 // add a ref... (if 'id' is not set... to a '+' ?? what does that mean? - fake ids?
531                 // remove '+' support as I cant remember what it does!!!
532                 //if (child.xvala_id.length < 1 ) {
533                 //      this.addLine(this.ipad + childname +".ref();"); // we need to reference increase unnamed children...
534                 //}                     
535             //if (child.xvala_id[0] == '+') {
536                 //      this.addLine(this.ipad + "this." + child.xvala_id.substring(1) + " = " + childname+  ";");
537                                         
538                 //}
539                 
540
541                 return child_name == "" ? childname : ("_this." + child_name);  
542         }               
543                         
544         
545
546         
547         protected void packChild(Node child, string childname, int cols, int colpos, string propname= "")
548         {
549                 
550                 GLib.debug("packChild %s=>%s", this.node.fqn(), child.fqn());
551                 // forcing no packing? - true or false? -should we just accept false?
552                 if (child.has("* pack") && child.get("* pack").down() == "false") {
553                         return; // force no packing
554                 }
555                 if (child.has("* pack") && child.get("* pack").down() == "true") {
556                         return; // force no packing
557                 }
558                 var el_name = this.this_el == "this.el." ? ".el" : "";
559                 var this_el = this.this_el;
560                 // BC really - don't want to support this anymore.
561                 if (child.has("* pack")) {
562                         
563                         string[]  packing =  { "add" };
564                         if (child.has("* pack")) {
565                                 packing = child.get("* pack").split(",");
566                         }
567                         
568                         var pack = packing[0];
569                         this.addLine(this.ipad + this.this_el + pack.strip() + " ( " + childname + el_name + " " +
570                                    (packing.length > 1 ? 
571                                                 (", " + string.joinv(",", packing).substring(pack.length+1))
572                                         : "" ) + " );");
573                         return;  
574                 }
575                 var childcls =  this.file.project.palete.getClass(child.fqn()); // very trusting..
576                 if (childcls == null) {
577                   return;
578                 }
579                 // GTK4
580                 var is_event = childcls.inherits.contains("Gtk.EventController") || childcls.implements.contains("Gtk.EventController");
581                 if (is_event) {
582                     this.addLine(this.ipad + this.this_el + "add_controller(  %s.el );".printf(childname) );
583                     return;
584                 }
585                 
586                 
587                 switch (this.node.fqn()) {
588                          
589                                 
590                 
591                         case "Gtk.Fixed":
592                         case "Gtk.Layout":
593                                 var x = child.has("x") ?  child.get_prop("x").val  : "0";
594                                 var y = child.has("y") ?  child.get_prop("y").val  : "0";
595                                 this.addLine(@"$(ipad)$(this_el)put( $(childname)$(el_name), $(x), $(y) );");
596                                 return;
597                                 
598                         
599
600                         case "Gtk.Stack":
601                                 var named = child.has("stack_name") ?  child.get_prop("stack_name").val.escape() : "";
602                                 var title = child.has("stack_title") ?  child.get_prop("stack_title").val.escape()  : "";
603                                 if (title.length > 0) {
604                                         this.addLine(@"$(ipad)$(this_el)add_titled( $(childname)$(el_name), \"$(named)\", \"$(title)\" );");
605                                         return;
606                                 } 
607                                 this.addLine(@"$(ipad)$(this_el)add_named( $(childname)$(el_name), \"$(named)\");");
608                                 return;
609                                 
610                         case "Gtk.Notebook": // use label
611                                 if (child.fqn() == "Gtk.NotebookPage") {
612                                         return;
613                                 }
614                                 var label = child.has("notebook_label") ?  child.get_prop("notebook_label").val.escape() : "";
615                                 this.addLine(@"$(ipad)$(this_el)append_page( $(childname)$(el_name), new Gtk.Label(\"$(label)\");");
616                                 
617                                 return;
618                                 
619                          
620                         case "Gtk.TreeView": // adding TreeViewColumns
621                                 this.addLine(this.ipad + "this.el.append_column( " + childname + ".el );");
622                                 return;
623                         
624                         case "Gtk.TreeViewColumn": //adding Renderers - I think these are all proprerties of the renderer used...
625                                 if (child.has("markup_column") && int.parse(child.get_prop("markup_column").val) > -1) {
626                                         var val = child.get_prop("markup_column").val;
627                                         this.addLine(@"$(ipad)$(this_el)add_attribute( $(childname)$(el_name), \"markup\", $(val) );");
628  
629                                 }
630                                 if (child.has("text_column") && int.parse(child.get_prop("text_column").val) > -1) {
631                                         var val = child.get_prop("text_column").val;
632                                         this.addLine(@"$(ipad)$(this_el)add_attribute( $(childname)$(el_name), \"text\", $(val) );");
633                                 }
634                                 if (child.has("pixbuf_column") && int.parse(child.get_prop("pixbuf_column").val) > -1) {
635                                         var val = child.get_prop("pixbuf_column").val;
636                                         this.addLine(@"$(ipad)$(this_el).add_attribute( $(childname)$(el_name), \"pixbuf\", $(val) );");
637                                 }
638                                 if (child.has("pixbuf_column") && int.parse(child.get_prop("active_column").val) > -1) {
639                                         var val = child.get_prop("active_column").val;
640                                         this.addLine(@"$(ipad)$(this_el).add_attribute( $(childname)$(el_name), \"active\", $(val) );");
641                                 }
642                                 if (child.has("background_column") && int.parse(child.get_prop("background_column").val) > -1) {
643                                 var val = child.get_prop("background_column").val;
644                                         this.addLine(@"$(ipad)$(this_el).add_attribute( $(childname)$(el_name), \"background-rgba\", $(val) );");
645                                 }
646                                 this.addLine(this.ipad + "this.el.add( " + childname + ".el );");
647                                 // any more!?
648                                 return;
649                 
650                         case "Gtk.Dialog":
651                                 if (propname == "buttons[]") {
652                                         var resp_id = int.parse(childname.replace("child_", ""));
653                                         if (child.has("* response_id")) { 
654                                                 resp_id = int.parse(child.get_prop("* response_id").val);
655                                         }
656                                         this.addLine(@"$(ipad)$(this_el).add_action_widget( $(childname)$(el_name), $(resp_id) );");
657
658                                         return;
659                                 }
660                         
661                                 this.addLine(@"$(ipad)$$(this_el)get_content_area().add( $(childname)$(el_name) );");
662                                 return;
663
664                 
665                                 
666                         
667         
668         
669         // known working with GTK4 !
670                         case "Gtk.HeaderBar": // it could be end... - not sure how to hanle that other than overriding                                  this.addLine(this.ipad + "this.el.add_action_widget( %s.el, %d);".printf(childname,resp_id) ); the pack method?
671                                 this.addLine(@"$(ipad)$(this_el)pack_start( $(childname)$(el_name) );");
672                                 return;
673                         
674                         case "GLib.Menu":
675                                 this.addLine(@"$(ipad)$(this_el)append_item( $(childname)$(el_name) );");
676                                 return; 
677                         
678                         case "Gtk.Paned":
679                                 this.pane_number++;
680                                 switch(this.pane_number) {
681                                         case 1:
682                                                 this.addLine(@"$(ipad)$(this_el)pack_start( $(childname)$(el_name) );");
683                                                 return;
684                                         case 2: 
685                                                 this.addLine(@"$(ipad)$(this_el)pack_end( $(childname)$(el_name) );");
686                                                 return;
687                                         default:
688                                                 // do nothing
689                                                 break;
690                                 }
691                                 return;
692                         
693                         case "Gtk.ColumnView":
694                                 this.addLine(@"$(ipad)$(this_el)append_column( $(childname)$(el_name) );");
695                                 return;
696                         
697                         case "Gtk.Grid":
698                                 var x = "%d".printf(colpos % cols);
699                                 var y = "%d".printf(( colpos - (colpos % cols) ) / cols);
700                                 var w = child.has("colspan") ? child.get_prop("colspan").val : "1";
701                                 var h = "1";
702                                 this.addLine(@"$(ipad)$(this_el)attach( $(childname)$(el_name), $x, $y, $w, $h );");
703                                 return;
704                         
705                         default:
706                                 this.addLine(@"$(ipad)$(this_el)append( $(childname)$(el_name) );");
707                             // gtk4 uses append!!!! - gtk3 - uses add..
708                                 return;
709                 
710                 
711                 }
712                 
713                 
714         }
715         
716         // fixme GtkDialog?!? buttons[]
717         
718         // fixme ... add case "Gtk.RadioButton":  // group_id ??
719
720                         
721
722         protected void addInit()
723         {
724
725                 
726                 if (!this.node.has("* init")) {
727                                 return;
728                 }
729                 this.addLine();
730                 this.addLine(ipad + "// init method");
731                 this.addLine();
732                 this.node.setLine(this.cur_line, "p", "init");
733                 
734                 var init =  this.node.get_prop("* init");
735                 init.start_line = this.cur_line;
736                 this.addMultiLine(ipad + this.padMultiline(ipad, init.val) );
737                 init.end_line = this.cur_line;
738          }
739          protected void addListeners()
740          {
741                 if (this.node.listeners.size < 1) {
742                         return;
743                 }
744                                 
745                 this.addLine();
746                 this.addLine(ipad + "//listeners");
747                         
748                          
749
750                 var iter = this.node.listeners.map_iterator();
751                 while (iter.next()) {
752                         var k = iter.get_key();
753                         var prop = iter.get_value();
754                         var v = prop.val;
755                         
756                         prop.start_line = this.cur_line;
757                         this.node.setLine(this.cur_line, "l", k);
758                         this.addMultiLine(this.ipad + this.this_el + k + ".connect( " + 
759                                         this.padMultiline(this.ipad,v) +");"); 
760                         prop.end_line = this.cur_line;
761                 }
762         }    
763         protected void addEndCtor()
764         {
765                          
766                         // end ctor..
767                         this.addLine(this.pad + "}");
768         }
769
770
771         /*
772  * Standardize this crap...
773  * 
774  * standard properties (use to set)
775  *          If they are long values show the dialog..
776  *
777  * someprop : ....
778  * bool is_xxx  :: can show a pulldown.. (true/false)
779  * string html  
780  * $ string html  = string with value interpolated eg. baseURL + ".." 
781  *  Clutter.ActorAlign x_align  (typed)  -- shows pulldowns if type is ENUM? 
782  * $ untypedvalue = javascript untyped value...  
783  * _ string html ... = translatable..
784
785  * 
786  * object properties (not part of the GOjbect being wrapped?
787  * # Gee.ArrayList<Xcls_fileitem> fileitems
788  * 
789  * signals
790  * @ void open 
791  * 
792  * methods -- always text editor..
793  * | void clearFiles
794  * | someJSmethod
795  * 
796  * specials
797  * * prop -- string
798  * * args  -- string
799  * * ctor -- string
800  * * init -- big string?
801  * 
802  * event handlers (listeners)
803  *   just shown 
804  * 
805  * -----------------
806  * special ID values
807  *  +XXXX -- indicates it's a instance property / not glob...
808  *  *XXXX -- skip writing glob property (used as classes that can be created...)
809  * 
810  * 
811  */
812          
813         protected void addUserMethods()
814         {
815                 this.addLine();
816                 this.addLine(this.pad + "// user defined functions");
817                         
818                         // user defined functions...
819                 var iter = this.node.props.map_iterator();
820                 while(iter.next()) {
821                         var prop = iter.get_value();
822                         if (this.shouldIgnore(prop.name)) {
823                                 continue;
824                         }
825                         // HOW TO DETERIME if its a method?            
826                         if (prop.ptype != NodePropType.METHOD) {
827                                         //strbuilder("\n" + pad + "// skip " + k + " - not pipe \n"); 
828                                         continue;
829                         }
830                         
831                         // function in the format of {type} (args) { .... }
832
833
834
835                         prop.start_line = this.cur_line;
836                         this.node.setLine(this.cur_line, "p", prop.name);
837                         this.addMultiLine(this.pad + "public " + prop.rtype + " " +  prop.name + " " + this.padMultiline(this.pad, prop.val));;
838                         prop.end_line = this.cur_line;
839                                 
840                 }
841         }
842
843         protected void iterChildren()
844         {
845                 this.node.line_end = this.cur_line;
846                 this.node.sortLines();
847                 
848                         
849                 if (this.depth > 0) {
850                         this.addLine(this.inpad + "}");
851                 }
852                 
853                 var iter = this.node.readItems().list_iterator();
854                  
855                 while (iter.next()) {
856                         this.addMultiLine(this.mungeChild(iter.get()));
857                 }
858                          
859                 if (this.depth < 1) {
860                         this.addLine(this.inpad + "}");
861                 }
862                         
863         }
864  
865
866         
867         protected void ignoreWrapped(string i) {
868                 this.ignoreWrappedList.add(i);
869                 
870         }
871         
872         protected  bool shouldIgnoreWrapped(string i)
873         {
874                 return ignoreWrappedList.contains(i);
875         }
876         
877 }
878         
879          
880         
881