fix line numbering issues with vala generator - hopefully fixes completion in node...
[roobuilder] / src / JsRender / NodeProp.vala
1 /**
2
3 This is a replacement for our key/value 
4 events and properties
5
6  
7 */ 
8 public enum JsRender.NodePropType 
9 {
10         
11         NONE, // fake value - used in popoveraddprop.
12         CTOR, // not used exetp getProperties for?
13         
14         
15         // these are all stored as properties, and should not overlap.
16         PROP,
17         
18         RAW,
19         METHOD,
20         SIGNAL,
21                 
22         // in theory we could have user defined properties that overlap - but probably not a good idea.
23         USER,
24
25
26         
27         // specials - these should be in a seperate list?
28         SPECIAL,
29
30
31         
32         // listerens can definatly overlap as they are stored in a seperate list. << no need to use this for listeners?
33         LISTENER;
34         
35
36         
37         public static string to_abbr(NodePropType intype)
38         {
39                 switch(intype) {
40                         case PROP: return  "";
41                         case RAW: return "$";
42                         case METHOD : return  "|";      
43                         case SIGNAL : return  "@"; // vala signal
44                         case USER : return  "#"; // user defined.
45                         case SPECIAL : return  "*"; // * prop| args | ctor | init
46                         case LISTENER : return  "";  // always raw...
47                         // not used
48                         case NONE:
49                         case CTOR:
50                                  return "";
51                         
52                 }
53                 return "??";
54         }
55         
56         // only usefull for reall values.
57         public static NodePropType from_string(string str)
58         {
59                 switch(str) {
60                         //case "" : return PROP;
61                         case "$": return  RAW;
62                         case "|": return METHOD;
63                         case "@": return  SIGNAL;
64                         case "#": return USER;
65                         case "*": return SPECIAL;
66                         //case "": return case LISTENER : return  ""  // always raw...
67                 }
68                 return PROP;
69         
70         }
71         public string to_name()
72         {
73                 switch (this) {
74                         case RAW:               return "Raw Property (not quoted or escaped)";
75                         case METHOD :   return "User Defined Method";   
76                         case SIGNAL :   return  "Vala Signal"; // vala signal
77                         case USER :     return  "User Defined Property"; // user defined.
78                         case SPECIAL : return  "Special Property (eg. prop / arg / ctor / init)"; // * prop| args | ctor | init
79                         case LISTENER : return  "Listener / Signal Handler";  // always raw...
80                         // not used
81                         case NONE:  return "None??";
82                         case CTOR:  return "Constructor?";
83                         case PROP:  return "Gtk/Roo Property";
84                         default: return "oops";
85                 
86                 }
87         }
88         
89         
90 }
91
92
93
94 public class JsRender.NodeProp : Object {
95
96
97         private string _name = "";
98         public string name { 
99                 get {
100                         return this._name;  
101                 }
102                 set {
103                         if (this._name == value) {
104                                 return;
105                         }
106                         this._name = value;
107
108                         if (this.parent != null) {
109                                 // causes props/ listeners array to get updated.
110                                 this.parent.updated_count++;
111                         }
112                 }
113          }  // can not be updated... ?? you have to remove / replace?
114         private NodePropType  _ptype;
115          
116         public NodePropType  ptype {            
117                 get {
118                         return this._ptype;  
119                 }
120                 set {
121                         if (this._ptype == value) {
122                                 return;
123                         }
124                         this._ptype = value;
125                         if (this.parent != null) {
126                                 // causes props/ listeners array to get updated.
127                                 this.parent.updated_count++;
128                         }
129                 }
130         }
131         private string _rtype = "";
132         public string rtype { 
133                 get { 
134                         return this._rtype; 
135                 }
136                 set { 
137                         if (this._rtype == value) {
138                                 return;
139                         }
140                         this._rtype = value; 
141                         if (this.parent != null) {
142                                 this.parent.updated_count++;
143                         }
144                         this.to_display_name_prop = "";
145                         this.to_tooltip_name_prop = "";
146                         this.updated_count++;
147                 }
148          } // return or type
149         
150         private string _val = "";
151         public string val { 
152                 get {
153                         return this._val;
154                 }
155                 set {
156                         if (this._val == value) {
157                                 return;
158                         }
159                         this._val = value;
160                         
161                         if (this.parent != null) {
162                                 this.parent.updated_count++;
163                         }
164                         this.val_short = "";
165                         this.val_tooltip = "";                  
166                         this.updated_count++;
167                         
168                 }
169         }
170
171
172         private int _updated_count = 0;
173         public int updated_count { 
174                 get {
175                         return this._updated_count; 
176                 }
177                 set  {
178  
179                         // set things that are used to display values.
180                         this.to_display_name_prop = "";
181                         this.to_tooltip_name_prop = "";
182                         this. _updated_count = value;
183                 }
184  
185         } // changes to this trigger updates on the tree..
186         
187         public string sort_name {
188                 owned get {
189                         if (this.add_node == null) {
190                                 return this.name;
191                         }
192                         return this.name + " " + this.add_node.fqn();
193                 }
194                 set {}
195         
196         }
197         
198         
199         public Node? parent; // the parent node.
200
201         
202         public int start_line = 0;
203         public int end_line = 0;
204         
205         // used by display list..
206         public GLib.ListStore  childstore; // WILL BE USED FOR properties with mutliple types 
207         public Node? add_node = null; // used when we list potentional nodes for properties in add list.
208
209         public string propertyof { get;   set; }
210         
211         
212         public NodeProp(string name, NodePropType ptype, string rtype, string val) {
213                 this.name = name;
214                 this.ptype = ptype;
215                 this.rtype = rtype;
216                 this.val = val;
217                 this.childstore = new GLib.ListStore( typeof(NodeProp));
218         }
219         
220         
221         public bool equals(NodeProp p) 
222         {
223                 return this.name == p.name 
224                                 && 
225                                 this.ptype == p.ptype 
226                                 && 
227                                 this.rtype == p.rtype 
228                                 && 
229                                 this.val == p.val;
230         }
231         
232         public NodeProp dupe()
233         {
234                 return new NodeProp(this.name, this.ptype, this.rtype,  this.val);
235         }
236         
237         
238         public NodeProp.from_json(string key, string inval)
239         {
240                 this.val = inval;
241                 var kkv = key.strip().split(" ");
242                 string[] kk = {};
243                 for (var i = 0; i < kkv.length; i++) {
244                         if (kkv[i].length > 0 ) {
245                                 kk += kkv[i];
246                         }
247                 }
248                 
249                 switch(kk.length) {
250                         case 1: 
251                                 this.name = kk[0];
252                                 this.ptype = NodePropType.PROP;
253                                 this.rtype = "";                
254                                 return;
255                         case 2: 
256                                 this.name = kk[1];
257                                 if (kk[0].length > 1) {
258                                         // void fred (no type)
259                                         this.rtype = kk[0];
260                                         this.ptype = NodePropType.PROP;
261                                 } else {
262                                         // has a ptype.
263                                         
264                                         this.rtype = ""; // no return type, only a ptype indicator.
265                                         this.ptype = NodePropType.from_string(kk[0]);
266                                 }
267                                 return;
268                         default: // 3 or more... (ignores spaces..)
269                         case 3:
270                                 this.name =  kk[2];
271                                 this.ptype = NodePropType.from_string(kk[0]);
272                                 this.rtype = kk[1];
273                                 return;
274                         
275                 }
276                 
277         }
278         public string  to_json_key()
279         {
280                 
281                 if (this.rtype == null) { // not sure why this happens.!?
282                         this.rtype = "";
283                 }
284                 var ortype = this.rtype +  (this.rtype.length > 0 ? " " : "");
285                 var oabbr = NodePropType.to_abbr(this.ptype);
286                 if (oabbr.length > 0) {
287                         oabbr += " ";
288                 }
289                 switch(this.ptype) {
290                         
291
292                         case NodePropType.LISTENER : 
293                                 return this.name; 
294                                 
295                         case NodePropType.PROP:
296                                 return ortype + this.name;                      
297                         
298                         case NodePropType.RAW:
299                         case NodePropType.METHOD:
300                         case NodePropType.SIGNAL:                       
301                         case NodePropType.USER :                        
302                                 return oabbr + ortype + this.name;                      
303                                 
304
305
306                         case NodePropType.SPECIAL:                      
307                                 return oabbr +   this.name;
308                         case NodePropType.NONE: // not used
309                         case NodePropType.CTOR:
310                                  return "";
311                          
312                 }
313                 return this.name;
314         }
315          
316         
317         public string  to_index_key()
318         {
319                 switch(this.ptype) {
320                         case NodePropType.PROP:
321                         case NodePropType.RAW:
322                         case NodePropType.METHOD :
323                         case NodePropType.SIGNAL :
324                         case NodePropType.USER : 
325                                 return this.name;
326                         
327                         case NodePropType.SPECIAL : 
328                                 return "* " + this.name;
329                                 
330                         // in seperate list..
331                         case NodePropType.LISTENER : 
332                                 return  this.name;
333                                 
334                         case NodePropType.NONE: // not used
335                         case NodePropType.CTOR:
336                                  return "";
337
338                                 
339                 }
340                 return this.name;
341         
342         }
343         // how it appears on the property list. -
344         
345         
346  
347         public string val_short { 
348                 set {
349                         // NOOp ??? should 
350                 }
351                 owned get {
352                         
353                          if (this._val.index_of("\n") < 0) {
354                                 return this._val;
355                          }
356                          var vals = this._val.split("\n");
357                          return vals[0]  + (vals.length > 1 ? " ..." : "");
358                 } 
359         }
360  
361     public string val_tooltip { 
362         set {
363                         // NOOp ??? should 
364                 }
365                 owned get {
366                         
367                                 return "<tt>" + GLib.Markup.escape_text(this.val) + "</tt>";
368                 } 
369     
370     
371     }
372     
373     public string to_display_name_prop { 
374                 set {
375                         // NOOp ??? should 
376                 }
377                 owned get {
378                          return  this.to_display_name();
379                 } 
380         }
381         
382         
383     
384         public string to_display_name()
385         {
386                 
387                 //return (this.rtype.length > 0 ? this.rtype + " " : "") +  this.name;
388                 // before we showed "@" for signals
389                 switch(this.ptype) {
390                         case NodePropType.PROP:
391                                 return   GLib.Markup.escape_text(this.name);
392                                 
393                         case NodePropType.RAW:
394                                 return "<span style=\"italic\">" + GLib.Markup.escape_text(this.name) + "</span>";
395                                 
396                         case NodePropType.METHOD :
397                                 return "<i>" + GLib.Markup.escape_text(this.rtype)  + "</i> <span color=\"#008000\" font_weight=\"bold\">" + GLib.Markup.escape_text( this.name) + "</span>";
398                                 
399                         case NodePropType.SIGNAL : // purpley
400                                 return "<span   color=\"#ea00d6\" font_weight=\"bold\">" + GLib.Markup.escape_text(this.name)+ "</span>";
401                                 
402                         case NodePropType.USER : 
403                                 return  "<i>" + GLib.Markup.escape_text(this.rtype)  + "</i> <span  font_weight=\"bold\">" + GLib.Markup.escape_text(this.name) + "</span>";
404                         
405                         case NodePropType.SPECIAL : 
406                                 return "<span   color=\"#0000CC\" font_weight=\"bold\">" + GLib.Markup.escape_text(this.name) + "</span>";       
407                                 
408                         // in seperate list..
409                         case NodePropType.LISTENER : 
410                                 return  "<b>" + this.name + "</b>";
411                                 
412                         case NodePropType.NONE: // not used
413                         case NodePropType.CTOR:
414                                  return "";
415                 
416                                 
417                 }
418                 return this.name;
419         }
420         
421         public string to_tooltip_name_prop { 
422                 set {
423                         // NOOp ??? should 
424                 }
425                 owned get {
426                          return  this.to_tooltip_name();
427                 } 
428         }
429         
430         public string to_tooltip_name()
431         {
432                 
433                 //return (this.rtype.length > 0 ? this.rtype + " " : "") +  this.name;
434                 // before we showed "@" for signals
435                 switch(this.ptype) {
436                         case NodePropType.PROP:
437                         case NodePropType.SIGNAL:
438                         case NodePropType.RAW:
439                         case NodePropType.SPECIAL : 
440                         case NodePropType.LISTENER :
441                                 return GLib.Markup.escape_text(this.name) ;
442                                 
443                         case NodePropType.METHOD :
444                         case NodePropType.USER :                        
445                                 return  GLib.Markup.escape_text(this.rtype)  + " " + GLib.Markup.escape_text( this.name) ;
446                                 
447                         
448                                 
449                         case NodePropType.NONE: // not used
450                         case NodePropType.CTOR:
451                                  return "";
452                 
453                                 
454                 }
455                 return this.name;
456         }
457         // used ot sort the dispaly list of properties.
458         public string to_sort_key()
459         {
460                 var n = this.name;
461                  
462                 //return (this.rtype.length > 0 ? this.rtype + " " : "") +  this.name;
463                 // before we showed "@" for signals
464                 switch(this.ptype) {
465                         case NodePropType.PROP:
466                                 return "5" +  n;
467                                 
468                         case NodePropType.RAW:
469                                 return "5" +  n;
470                                 
471                         case NodePropType.METHOD :
472                                 return "2" +  n;
473                                 
474                         case NodePropType.SIGNAL :
475                                 return "3" +  n;
476                                 
477                         case NodePropType.USER : 
478                                 return "4" +  n;
479                         
480                         case NodePropType.SPECIAL : 
481                                 return "1" +  n;
482                                 
483                         // in seperate list..
484                         case NodePropType.LISTENER : 
485                                 return  "0" + this.name;
486                         
487                         case NodePropType.NONE: // not used
488                         case NodePropType.CTOR:
489                                  return "";
490                                 
491                 }
492                 return this.name;
493         }
494         // this is really only used for stuct ctors at present  
495         // which are only props (although RAW might be valid)
496         public string value_to_code()
497         {
498                 switch (this.ptype) {
499                         case NodePropType.PROP:
500                                 break;
501                                 
502                         case NodePropType.METHOD :                       
503                         case NodePropType.RAW:
504                         case NodePropType.SIGNAL :                      
505                         case NodePropType.USER : 
506                         case NodePropType.SPECIAL : 
507                         case NodePropType.LISTENER : 
508                         case NodePropType.NONE: // not used
509                         case NodePropType.CTOR:                 
510                                 return this.val;
511                 }
512                 if (this.rtype.contains(".")) {
513                         // probalby an enum
514                         return this.val;
515                 }
516                 
517                 
518                 switch (this.rtype) {
519                         case "string":
520                                 return "\"" + this.rtype.escape() + "\"";
521                         case "bool":
522                                 return this.val.down();
523                         case "float":
524                         case "double":
525                         default:
526                                 break;
527                                 
528                         
529                 
530                 }
531                 return this.val;
532         }
533         
534         
535         
536         public string to_tooltip()
537         {
538                  
539                 switch(this.ptype) {
540                         case NodePropType.PROP:
541                                 return this.rtype + " " + this.name + " = \"" + this.val + "\"";
542                         case NodePropType.LISTENER : 
543                                 // thsi might look a bit odd on javascript?
544                                 return "on " + this.name + " " + this.val;
545                                 
546                         case NodePropType.RAW:
547                                 return  this.rtype + " " + this.name + " = " + this.val;
548                         case NodePropType.METHOD :
549                                 // functions - js    FRED  function () { }  <<< could probably be cleaner..
550                                 // functions - vala    FRED () { }
551                                 return  this.rtype + " " + this.name  + " "  + this.val;
552                         case NodePropType.SIGNAL :
553                                 return  "signal: "  + this.rtype + " " + this.name  +  " " + this.val;
554                         case NodePropType.USER : 
555                                 return  "user defined: "  + this.rtype + " " + this.name  + " = "  + this.val;
556                         
557                         case NodePropType.SPECIAL:                      
558                                 return  "special property: "  + this.rtype + " " + this.name  + " = " +   this.val;                     
559
560                         case NodePropType.NONE: // not used
561                         case NodePropType.CTOR:
562                                  return "";
563                 }
564                 return this.name;
565                  
566         }
567         
568          
569         public string to_property_option_markup(bool isbold)
570         {
571                 return isbold ?  "<b>" + this.name + "</b>" : this.name;
572         }
573         
574         public string to_property_option_tooltip()
575         {
576                 return this.to_property_option_markup( false ); // fixme will probaly want help info (possibly by havinga  reference to the GirObject that its created from
577         }
578         
579         
580         public bool is(NodeProp comp) {
581                 if (comp.ptype == NodePropType.LISTENER || this.ptype == NodePropType.LISTENER ) { 
582                         return comp.ptype == this.ptype && comp.name == this.name;
583                 }
584                 return comp.to_index_key() == this.to_index_key();
585         
586         }
587         
588         
589         /*
590         public NodeProp.listenerfromjson(string str, string inval)
591         {
592                 this.val = inval;
593                 this.name = str;
594                 this.ptype = NodePropType.LISTENER;
595                 this.rtype = "";
596                 
597         }
598         */
599         // regular addition - should work for properties  
600         public NodeProp.prop(string name, string rtype = "", string val = "")
601         {
602                 this(name, NodePropType.PROP, rtype, val);
603         }
604         public NodeProp.raw(string name, string rtype = "", string val = "")
605         {
606                 this(name, NodePropType.RAW, rtype, val);
607         }
608         
609         public NodeProp.valamethod(string name, string rtype = "void", string val = "() {\n\n}")
610         {
611                 this(name, NodePropType.METHOD, rtype, val);
612         }
613         public NodeProp.jsmethod(string name,  string val = "function() {\n\n}")
614         {
615                 this(name, NodePropType.METHOD, "", val);
616         }
617         
618         // vala (and js) specials.. props etc.. - they only have name/value (not type) - type is in xns/xtype
619         public NodeProp.special(string name, string val = "")
620         {
621                 this(name, NodePropType.SPECIAL, "", val);
622         }
623          
624         public NodeProp.listener(string name,   string val = "")
625         {
626                 this(name, NodePropType.LISTENER, "", val);
627         }
628          
629         public NodeProp.user(string name, string rtype = "", string val = "")
630         {
631                 this(name, NodePropType.USER, rtype, val);
632         }
633         public NodeProp.sig(string name, string rtype = "void", string val = "()")
634         {
635                 this(name, NodePropType.SIGNAL, rtype, val);
636         }
637         public void appendChild(NodeProp child)
638         {
639                 this.childstore.append(child);
640
641         }
642         
643         /**
644         could use enums.. but basically.
645         0 - > inline text editor
646         1  -> pulldown
647         2  -> full editor
648         */
649         public bool useTextArea()
650         {
651         
652                 var use_textarea = false;
653
654                 //------------ things that require the text editor...
655                 
656                 if (this.ptype == NodePropType.LISTENER) {
657                     use_textarea = true;
658                 }
659                 if (this.ptype == NodePropType.METHOD) { 
660                     use_textarea = true;
661                 }
662                     
663                 if ( this.name == "init" && this.ptype == NodePropType.SPECIAL) {
664                     use_textarea = true;
665                 }
666                 if (this.val.length > 40 || this.val.index_of("\n") > -1) { // long value...
667                     use_textarea = true;
668                 }
669                 
670                 return use_textarea;
671         
672         }
673         
674         
675         
676         
677 }
678         
679