e03db08c5a97505466f1398ebd1989f7555e0792
[roobuilder] / src / Builder4 / Editor.vala
1     static Editor  _Editor;
2
3     public class Editor : Object
4     {
5         public Gtk.Box el;
6         private Editor  _this;
7
8         public static Editor singleton()
9         {
10             if (_Editor == null) {
11                 _Editor= new Editor();
12             }
13             return _Editor;
14         }
15         public Xcls_save_button save_button;
16         public Xcls_close_btn close_btn;
17         public Xcls_RightEditor RightEditor;
18         public Xcls_view view;
19         public Xcls_buffer buffer;
20         public Xcls_search_entry search_entry;
21         public Xcls_search_results search_results;
22         public Xcls_nextBtn nextBtn;
23         public Xcls_backBtn backBtn;
24         public Xcls_search_settings search_settings;
25         public Xcls_case_sensitive case_sensitive;
26         public Xcls_regex regex;
27         public Xcls_multiline multiline;
28
29             // my vars (def)
30         public int pos_root_x;
31         public Xcls_MainWindow window;
32         public bool dirty;
33         public int pos_root_y;
34         public bool pos;
35         public GtkSource.SearchContext searchcontext;
36         public int last_search_end;
37         public signal void save ();
38         public JsRender.JsRender? file;
39         public JsRender.Node node;
40         public JsRender.NodeProp? prop;
41         public string activeEditor;
42
43         // ctor
44         public Editor()
45         {
46             _this = this;
47             this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
48
49             // my vars (dec)
50             this.window = null;
51             this.dirty = false;
52             this.pos = false;
53             this.searchcontext = null;
54             this.last_search_end = 0;
55             this.file = null;
56             this.node = null;
57             this.prop = null;
58             this.activeEditor = "";
59
60             // set gobject values
61             this.el.homogeneous = false;
62             this.el.hexpand = true;
63             this.el.vexpand = true;
64             var child_1 = new Xcls_Box2( _this );
65             child_1.ref();
66             this.el.append( child_1.el );
67             new Xcls_RightEditor( _this );
68             this.el.append( _this.RightEditor.el );
69             var child_3 = new Xcls_Box12( _this );
70             child_3.ref();
71             this.el.append ( child_3.el  );
72         }
73
74         // user defined functions
75         public bool saveContents ()  {
76             
77             
78             if (_this.file == null) {
79                 return true;
80             }
81             
82              
83              
84              var str = _this.buffer.toString();
85              
86              _this.buffer.checkSyntax();
87              
88              
89              
90              // LeftPanel.model.changed(  str , false);
91              _this.dirty = false;
92              _this.save_button.el.sensitive = false;
93              
94             // find the text for the node..
95             if (_this.file.xtype != "PlainFile") {
96                // in theory these properties have to exist!?!
97                 this.prop.val = str;
98                 //this.window.windowstate.left_props.reload();
99             } else {
100                 _this.file.setSource(  str );
101              }
102             
103             // call the signal..
104             this.save();
105             
106             return true;
107         
108         }
109         public void forwardSearch (bool change_focus) {
110         
111                 if (this.searchcontext == null) {
112                         return;
113                 } 
114                 
115                 Gtk.TextIter beg, st,en;
116                  bool has_wrapped_around;
117                 this.buffer.el.get_iter_at_offset(out beg, this.last_search_end);
118                 if (!this.searchcontext.forward(beg, out st, out en, out has_wrapped_around)) {
119                 
120                         this.last_search_end = 0; // not sure if this should happen
121                 } else {
122                         if (has_wrapped_around) {
123                                 return;
124                         }
125                 
126                         this.last_search_end = en.get_offset();
127                         if (change_focus) {
128                                 this.view.el.grab_focus();
129                         }
130                         this.buffer.el.place_cursor(st);
131                         this.view.el.scroll_to_iter(st,  0.1f, true, 0.0f, 0.5f);
132                 }
133          
134         }
135         public void show (JsRender.JsRender file, JsRender.Node? node, JsRender.NodeProp? prop)
136         {
137             this.reset();
138             this.file = file;    
139             
140             if (file.xtype != "PlainFile") {
141                 this.prop = prop;
142                 this.node = node;
143         
144                 // find the text for the node..
145                 this.view.load( prop.val );
146                 
147                 
148                 this.close_btn.el.show();       
149             
150             } else {
151                 this.view.load(        file.toSource() );
152                 this.close_btn.el.hide();
153             }
154          
155         }
156         public void backSearch (bool change_focus) {
157         
158                 if (this.searchcontext == null) {
159                         return;
160                 } 
161                 
162                 Gtk.TextIter beg, st,en;
163                 bool has_wrapped_around;
164                 this.buffer.el.get_iter_at_offset(out beg, this.last_search_end -1 );
165                 
166                 if (!this.searchcontext.backward(beg, out st, out en, out has_wrapped_around)) {
167                         this.last_search_end = 0;
168                 } else {
169                         this.last_search_end = en.get_offset();
170                         if (change_focus) {
171                                 this.view.el.grab_focus();
172                         }
173                         this.buffer.el.place_cursor(st);
174                         this.view.el.scroll_to_iter(st,  0.1f, true, 0.0f, 0.5f);
175                 }
176         
177         }
178         public void reset () {
179                  this.file = null;    
180              
181             this.node = null;
182             this.prop = null;
183                 this.searchcontext = null;
184           
185         }
186         public int search (string in_txt) {
187         
188                 var s = new GtkSource.SearchSettings();
189                 s.case_sensitive = _this.case_sensitive.el.active;
190                 s.regex_enabled = _this.regex.el.active;        
191                 s.wrap_around = false;
192                 
193                 this.searchcontext = new GtkSource.SearchContext(this.buffer.el,s);
194                 this.searchcontext.set_highlight(true);
195                 var txt = in_txt;
196                 
197                 if (_this.multiline.el.active) {
198                         txt = in_txt.replace("\\n", "\n");
199                 }
200                 
201                 s.set_search_text(txt);
202                 Gtk.TextIter beg, st,en;
203                  
204                 this.buffer.el.get_start_iter(out beg);
205                 bool has_wrapped_around;
206                 this.searchcontext.forward(beg, out st, out en, out has_wrapped_around);
207                 this.last_search_end = 0;
208                 
209                 return this.searchcontext.get_occurrences_count();
210         
211          
212            
213         
214         }
215         public void updateErrorMarks (GLib.ListStore?  ar) {
216                 
217          
218                 
219                  var buf = _this.buffer.el;
220                 Gtk.TextIter start;
221                 Gtk.TextIter end;     
222                 buf.get_bounds (out start, out end);
223         
224                 buf.remove_source_marks (start, end, "ERR");
225                 buf.remove_source_marks (start, end, "WARN");
226                 buf.remove_source_marks (start, end, "DEPR");
227                 GLib.debug("highlight errors");          
228         
229                  // we should highlight other types of errors..
230         
231                 if (ar == null || ar.get_n_items() < 1) {
232                         GLib.debug("Return has no errors\n");
233                         return;
234                 }
235         
236                 if (_this.window.windowstate.state != WindowState.State.CODEONLY 
237                         &&
238                         _this.window.windowstate.state != WindowState.State.CODE
239                         ) {
240                         GLib.debug("windowstate != CODEONLY?");
241                         
242                         return;
243                 } 
244         
245                  
246                 if (_this.file == null) {
247                         GLib.debug("file is null?");
248                         return;
249         
250                 }
251          
252         
253          
254                 
255                 var offset = 1;
256                  
257         
258                 var tlines = buf.get_line_count () +1;
259                 
260                 if (_this.prop != null) {
261                 
262                         tlines = _this.prop.end_line + 1;
263                         offset = _this.prop.start_line + 1;
264                 
265                 }
266                  
267                 for (var i = 0; i < ar.get_n_items();i++) {
268                         var err = (Palete.CompileError) ar.get_item(i);
269                         
270                      Gtk.TextIter iter;
271         //        print("get inter\n");
272                     var eline = err.line - offset;
273                     GLib.debug("GOT ERROR on line %d -- converted to %d  (offset = %d)",
274                         err.line ,eline, offset);
275                     
276                     
277                     if (eline > tlines || eline < 0) {
278                         return;
279                     }
280                    
281                     
282                     buf.get_iter_at_line( out iter, eline);
283                    
284                    
285                         var msg = "Line: %d %s : %s".printf(eline+1, err.category, err.msg);
286                     buf.create_source_mark( msg, err.category, iter);
287                     GLib.debug("set line %d to %m", eline, msg);
288                    // this.marks.set(eline, msg);
289                 }
290                 return ;
291         
292         
293         
294          
295         
296         }
297         public void scroll_to_line (int line) {
298         
299                 GLib.Timeout.add(500, () => {
300            
301                         var buf = this.view.el.get_buffer();
302         
303                         var sbuf = (GtkSource.Buffer) buf;
304         
305         
306                         Gtk.TextIter iter;   
307                         sbuf.get_iter_at_line(out iter,  line);
308                         this.view.el.scroll_to_iter(iter,  0.1f, true, 0.0f, 0.5f);
309                         return false;
310                 });   
311         }
312         public class Xcls_Box2 : Object
313         {
314             public Gtk.Box el;
315             private Editor  _this;
316
317
318                 // my vars (def)
319
320             // ctor
321             public Xcls_Box2(Editor _owner )
322             {
323                 _this = _owner;
324                 this.el = new Gtk.Box( Gtk.Orientation.HORIZONTAL, 0 );
325
326                 // my vars (dec)
327
328                 // set gobject values
329                 this.el.homogeneous = false;
330                 this.el.hexpand = true;
331                 new Xcls_save_button( _this );
332                 this.el.append( _this.save_button.el );
333                 var child_2 = new Xcls_Label4( _this );
334                 child_2.ref();
335                 this.el.append( child_2.el );
336                 var child_3 = new Xcls_Scale5( _this );
337                 child_3.ref();
338                 this.el.append( child_3.el );
339                 new Xcls_close_btn( _this );
340                 this.el.append( _this.close_btn.el );
341             }
342
343             // user defined functions
344         }
345         public class Xcls_save_button : Object
346         {
347             public Gtk.Button el;
348             private Editor  _this;
349
350
351                 // my vars (def)
352
353             // ctor
354             public Xcls_save_button(Editor _owner )
355             {
356                 _this = _owner;
357                 _this.save_button = this;
358                 this.el = new Gtk.Button();
359
360                 // my vars (dec)
361
362                 // set gobject values
363                 this.el.label = "Save";
364
365                 //listeners
366                 this.el.clicked.connect( () => { 
367                     _this.saveContents();
368                 });
369             }
370
371             // user defined functions
372         }
373
374         public class Xcls_Label4 : Object
375         {
376             public Gtk.Label el;
377             private Editor  _this;
378
379
380                 // my vars (def)
381
382             // ctor
383             public Xcls_Label4(Editor _owner )
384             {
385                 _this = _owner;
386                 this.el = new Gtk.Label( null );
387
388                 // my vars (dec)
389
390                 // set gobject values
391                 this.el.hexpand = true;
392             }
393
394             // user defined functions
395         }
396
397         public class Xcls_Scale5 : Object
398         {
399             public Gtk.Scale el;
400             private Editor  _this;
401
402
403                 // my vars (def)
404
405             // ctor
406             public Xcls_Scale5(Editor _owner )
407             {
408                 _this = _owner;
409                 this.el = new Gtk.Scale.with_range (Gtk.Orientation.HORIZONTAL,6, 30, 1);
410
411                 // my vars (dec)
412
413                 // set gobject values
414                 this.el.width_request = 200;
415                 this.el.has_origin = true;
416                 this.el.draw_value = false;
417                 this.el.digits = 0;
418                 this.el.sensitive = true;
419
420                 // init method
421
422                 {
423                         this.el.set_range(6,30);
424                         this.el.set_value(8);
425                 }
426
427                 //listeners
428                 this.el.change_value.connect( (st, val ) => {
429                          
430                            
431                           _this.view.css.load_from_string(
432                                         "#editor-view { font: %dpx monospace; }".printf((int)val)
433                            );
434                      
435                         return false;
436                 });
437             }
438
439             // user defined functions
440         }
441
442         public class Xcls_close_btn : Object
443         {
444             public Gtk.Button el;
445             private Editor  _this;
446
447
448                 // my vars (def)
449
450             // ctor
451             public Xcls_close_btn(Editor _owner )
452             {
453                 _this = _owner;
454                 _this.close_btn = this;
455                 this.el = new Gtk.Button();
456
457                 // my vars (dec)
458
459                 // set gobject values
460                 this.el.icon_name = "window-close";
461                 var child_1 = new Xcls_Image7( _this );
462                 this.el.child = child_1.el;
463
464                 //listeners
465                 this.el.clicked.connect( () => { 
466                     _this.saveContents();
467                     _this.window.windowstate.switchState(WindowState.State.PREVIEW);
468                 });
469             }
470
471             // user defined functions
472         }
473         public class Xcls_Image7 : Object
474         {
475             public Gtk.Image el;
476             private Editor  _this;
477
478
479                 // my vars (def)
480
481             // ctor
482             public Xcls_Image7(Editor _owner )
483             {
484                 _this = _owner;
485                 this.el = new Gtk.Image();
486
487                 // my vars (dec)
488
489                 // set gobject values
490                 this.el.icon_name = "window-close";
491                 this.el.icon_size = Gtk.IconSize.NORMAL;
492             }
493
494             // user defined functions
495         }
496
497
498
499         public class Xcls_RightEditor : Object
500         {
501             public Gtk.ScrolledWindow el;
502             private Editor  _this;
503
504
505                 // my vars (def)
506
507             // ctor
508             public Xcls_RightEditor(Editor _owner )
509             {
510                 _this = _owner;
511                 _this.RightEditor = this;
512                 this.el = new Gtk.ScrolledWindow();
513
514                 // my vars (dec)
515
516                 // set gobject values
517                 this.el.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
518                 this.el.vexpand = true;
519                 this.el.overlay_scrolling = false;
520                 this.el.hscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
521                 new Xcls_view( _this );
522                 this.el.child = _this.view.el;
523             }
524
525             // user defined functions
526         }
527         public class Xcls_view : Object
528         {
529             public GtkSource.View el;
530             private Editor  _this;
531
532
533                 // my vars (def)
534             public Gtk.CssProvider css;
535
536             // ctor
537             public Xcls_view(Editor _owner )
538             {
539                 _this = _owner;
540                 _this.view = this;
541                 this.el = new GtkSource.View();
542
543                 // my vars (dec)
544                 this.css = null;
545
546                 // set gobject values
547                 this.el.auto_indent = true;
548                 this.el.indent_width = 4;
549                 this.el.name = "editor-view";
550                 this.el.show_line_marks = true;
551                 this.el.insert_spaces_instead_of_tabs = true;
552                 this.el.show_line_numbers = true;
553                 this.el.hexpand = true;
554                 this.el.vexpand = true;
555                 this.el.has_tooltip = true;
556                 this.el.tab_width = 4;
557                 this.el.highlight_current_line = true;
558                 new Xcls_buffer( _this );
559                 this.el.buffer = _this.buffer.el;
560                 var child_2 = new Xcls_EventControllerKey11( _this );
561                 child_2.ref();
562                 this.el.add_controller(  child_2.el );
563
564                 // init method
565
566                 this.css = new Gtk.CssProvider();
567                 
568                 this.css.load_from_string(
569                         "#editor-view { font:  12px monospace;}"
570                 );
571                  
572                 Gtk.StyleContext.add_provider_for_display(
573                         this.el.get_display(),
574                         this.css,
575                         Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
576                 );
577                         
578                  
579                          
580                 
581                        
582                 this.el.completion.add_provider(new Palete.CompletionProvider(_this));
583                  
584                 
585                 this.el.completion.unblock_interactive();
586                 this.el.completion.select_on_show = true; // select
587                 
588                 this.el.completion.remember_info_visibility      = true;
589                 
590                 
591                 var attrs = new GtkSource.MarkAttributes();
592                 var  pink =   Gdk.RGBA();
593                 pink.parse ( "pink");
594                 attrs.set_background ( pink);
595                 attrs.set_icon_name ( "process-stop");    
596                 attrs.query_tooltip_text.connect(( mark) => {
597                      GLib.debug("tooltip query? %s", mark.name);
598                     return strdup( mark.name);
599                 });
600                  attrs.query_tooltip_markup.connect(( mark) => {
601                      GLib.debug("tooltip query? %s", mark.name);
602                     return strdup( mark.name);
603                 });
604                 this.el.set_mark_attributes ("ERR", attrs, 1);
605                 attrs.ref();
606                  var wattrs = new GtkSource.MarkAttributes();
607                 var  blue =   Gdk.RGBA();
608                 blue.parse ( "#ABF4EB");
609                 wattrs.set_background ( blue);
610                 wattrs.set_icon_name ( "process-stop");    
611                 wattrs.query_tooltip_text.connect(( mark) => {
612                      GLib.debug("tooltip query? %s", mark.name);
613                     return strdup(mark.name);
614                 });
615                 wattrs.query_tooltip_markup.connect(( mark) => {
616                      GLib.debug("tooltip query? %s", mark.name);
617                     return strdup(mark.name);
618                 });
619                 this.el.set_mark_attributes ("WARN", wattrs, 1);
620                 wattrs.ref();
621                 
622                 
623                  var dattrs = new GtkSource.MarkAttributes();
624                 var  purple =   Gdk.RGBA();
625                 purple.parse ( "#EEA9FF");
626                 dattrs.set_background ( purple);
627                 dattrs.set_icon_name ( "process-stop");    
628                 dattrs.query_tooltip_text.connect(( mark) => {
629                         GLib.debug("tooltip query? %s", mark.name);
630                     return strdup(mark.name);
631                 });
632                 dattrs.query_tooltip_markup.connect(( mark) => {
633                         GLib.debug("tooltip query? %s", mark.name);
634                     return strdup(mark.name);
635                 });
636                 this.el.set_mark_attributes ("DEPR", dattrs, 1);
637                 dattrs.ref();    
638                 
639                  this.el.get_space_drawer().set_matrix(null);
640                  this.el.get_space_drawer().set_types_for_locations( 
641                         GtkSource.SpaceLocationFlags.ALL,
642                         GtkSource.SpaceTypeFlags.ALL
643                 );
644                 this.el.get_space_drawer().set_enable_matrix(true);
645                 /*
646                 Gtk.SourceDrawSpacesFlags.LEADING + 
647                 Gtk.SourceDrawSpacesFlags.TRAILING + 
648                 Gtk.SourceDrawSpacesFlags.TAB + 
649                 Gtk.SourceDrawSpacesFlags.SPACE
650                 */
651
652                 //listeners
653                 this.el.query_tooltip.connect( (x, y, keyboard_tooltip, tooltip) => {
654                         
655                         //GLib.debug("query tooltip");
656                         Gtk.TextIter iter;
657                         int trailing;
658                         
659                         var yoff = (int) _this.RightEditor.el.vadjustment.value;
660                         
661                         // I think this is problematic - if it's compliing  / updating at same time as query.
662                         
663                         //if (_this.window.statusbar_compile_spinner.el.spinning) {
664                         //      return false;
665                         //}
666                         
667                         this.el.get_iter_at_position (out iter, out trailing,  x,  y + yoff);
668                          
669                         var l = iter.get_line();
670                 
671                         
672                          
673                         // GLib.debug("query tooltip line %d", (int) l);
674                         if (l < 0) {
675                 
676                                 return false;
677                         }
678                         /*
679                         if (_this.buffer.marks != null && _this.buffer.marks.has_key(l)) {
680                                 GLib.debug("line %d setting tip to %s", l,  _this.buffer.marks.get(l));
681                                 tooltip.set_text(_this.buffer.marks.get(l).dup());
682                                 return true;
683                         }
684                  
685                         return false;
686                         */
687                         
688                           
689                         // this crashes?? - not sure why.
690                         var marks = _this.buffer.el.get_source_marks_at_line(l, "ERR");
691                         if (marks.is_empty()) {
692                                 marks = _this.buffer.el.get_source_marks_at_line(l, "WARN");
693                         }
694                         if (marks.is_empty()) {
695                                 marks = _this.buffer.el.get_source_marks_at_line(l, "DEPR");
696                         }
697                         
698                         // GLib.debug("query tooltip line %d marks %d", (int)l, (int) marks.length());
699                         var str = "";
700                         marks.@foreach((m) => { 
701                                 //GLib.debug("got mark %s", m.name);
702                                 str += (str.length > 0 ? "\n" : "") + m.category + ": " + m.name;
703                         });
704                         // true if there is a mark..
705                         if (str.length > 0 ) {
706                                 tooltip.set_text( str );
707                         }
708                         return str.length > 0 ? true : false;
709                          
710                 });
711             }
712
713             // user defined functions
714             public void load (string str) {
715             
716             // show the help page for the active node..
717                //this.get('/Help').show();
718              
719               // this.get('/BottomPane').el.set_current_page(0);
720                 GLib.debug("load called - Reset undo buffer");
721                 
722                 var buf = (GtkSource.Buffer)this.el.get_buffer();
723                 buf.begin_irreversible_action();
724                 buf.set_text(str, str.length);
725                 buf.end_irreversible_action();
726                 
727                 var lm = GtkSource.LanguageManager.get_default();
728                 var lang = "vala";
729                 if (_this.file != null) {
730                      lang = _this.file.language;
731                 }
732                 print("lang=%s, content_type = %s\n", lang, _this.file.content_type);
733                 var lg = _this.file.content_type.length > 0  ?
734                         lm.guess_language(_this.file.path, _this.file.content_type) :
735                         lm.get_language(lang);
736                  
737                
738                 ((GtkSource.Buffer)(this.el.get_buffer())) .set_language(lg); 
739             
740                 this.el.insert_spaces_instead_of_tabs = true;
741                 if (lg != null) {
742                         print("sourcelanguage  = %s\n", lg.name);
743                         if (lg.name == "Vala") {
744                             this.el.insert_spaces_instead_of_tabs = false;
745                         }
746                  }
747                 _this.dirty = false;
748                 this.el.grab_focus();
749                 _this.save_button.el.sensitive = false;
750             }
751         }
752         public class Xcls_buffer : Object
753         {
754             public GtkSource.Buffer el;
755             private Editor  _this;
756
757
758                 // my vars (def)
759             public int error_line;
760             public Gee.HashMap<int,string>? xmarks;
761             public bool check_queued;
762
763             // ctor
764             public Xcls_buffer(Editor _owner )
765             {
766                 _this = _owner;
767                 _this.buffer = this;
768                 this.el = new GtkSource.Buffer( null );
769
770                 // my vars (dec)
771                 this.error_line = -1;
772                 this.xmarks = null;
773                 this.check_queued = false;
774
775                 // set gobject values
776                 this.el.enable_undo = true;
777
778                 //listeners
779                 this.el.changed.connect( () => {
780                     // check syntax??
781                     // ??needed..??
782                     _this.save_button.el.sensitive = true;
783                     print("EDITOR CHANGED");
784                     this.checkSyntax();
785                    
786                     _this.dirty = true;
787                 
788                     // this.get('/LeftPanel.model').changed(  str , false);
789                     return ;
790                 });
791             }
792
793             // user defined functions
794             public bool checkSyntax () {
795              
796                 
797                 var str = this.toString();
798                 
799                 // needed???
800                 if (this.error_line > 0) {
801                      Gtk.TextIter start;
802                      Gtk.TextIter end;     
803                     this.el.get_bounds (out start, out end);
804             
805                     this.el.remove_source_marks (start, end, null);
806                 }
807                 if (str.length < 1) {
808                     print("checkSyntax - empty string?\n");
809                     return true;
810                 }
811                 
812                 // bit presumptiona
813                 if (_this.file.xtype == "PlainFile" && _this.file.project.xtype == "Gtk") {
814                 
815                     // assume it's gtk...
816                        
817                         BuilderApplication.valacompilequeue.addFile( 
818                                 Palete.ValaCompileRequestType.FILE_CHANGE, 
819                                 _this.file , str, false) ;
820               
821             
822                     return true;
823                 
824                 }
825                if (_this.file == null) {
826                    return true;
827                }
828              
829                 
830             
831                   
832                  
833                 GLib.debug("calling validate");    
834                 // clear the buttons.
835              
836                 BuilderApplication.valacompilequeue.addProp( 
837                                 Palete.ValaCompileRequestType.PROP_CHANGE,
838                                 _this.file,
839                                 _this.node,
840                                 _this.prop,
841                                 str); 
842                  
843                 
844                 
845                 //print("done mark line\n");
846                  
847                 return true; // at present allow saving - even if it's invalid..
848             }
849             public bool highlightErrorsJson (string type, Json.Object obj) {
850                 Gtk.TextIter start;
851                 Gtk.TextIter end;     
852                 this.el.get_bounds (out start, out end);
853             
854                 this.el.remove_source_marks (start, end, type);
855                 GLib.debug("highlight errors");          
856             
857                  // we should highlight other types of errors..
858             
859                 if (!obj.has_member(type)) {
860                         GLib.debug("Return has no errors\n");
861                         return true;
862                 }
863             
864                 if (_this.window.windowstate.state != WindowState.State.CODEONLY 
865                         &&
866                         _this.window.windowstate.state != WindowState.State.CODE
867                         ) {
868                         GLib.debug("windowstate != CODEONLY?");
869                         
870                         return true;
871                 } 
872             
873                 //this.marks = new Gee.HashMap<int,string>();
874                 var err = obj.get_object_member(type);
875              
876                 if (_this.file == null) {
877                         GLib.debug("file is null?");
878                         return true;
879             
880                 }
881                 var valafn = _this.file.path;
882             
883                 if (_this.file.xtype != "PlainFile") {
884             
885                         valafn = "";
886                         try {             
887                                 var  regex = new Regex("\\.bjs$");
888                                 // should not happen
889                                 valafn = regex.replace(_this.file.path,_this.file.path.length , 0 , ".vala");
890                         } catch (GLib.RegexError e) {
891                                 return true;
892                         }   
893             
894             
895             
896                 }
897                 if (!err.has_member(valafn)) {
898                         GLib.debug("File path has no errors");
899                         return  true;
900                 }
901             
902                 var lines = err.get_object_member(valafn);
903                 
904                 var offset = 1;
905                 if (obj.has_member("line_offset")) { // ?? why??
906                         offset = (int)obj.get_int_member("line_offset") + 1;
907                 }
908             
909             
910                 var tlines = this.el.get_line_count () +1;
911                 
912                 if (_this.prop != null) {
913                 
914                         tlines = _this.prop.end_line + 1;
915                         offset = _this.prop.start_line + 1;
916                 
917                 }
918                 
919             
920             
921                 lines.foreach_member((obj, line, node) => {
922                         
923                      Gtk.TextIter iter;
924             //        print("get inter\n");
925                     var eline = int.parse(line) - offset;
926                     GLib.debug("GOT ERROR on line %s -- converted to %d  (offset = %d)\n", line,eline, offset);
927                     
928                     
929                     if (eline > tlines || eline < 0) {
930                         return;
931                     }
932                    
933                     
934                     this.el.get_iter_at_line( out iter, eline);
935                     //print("mark line\n");
936                     var msg  = "";
937                     var ar = lines.get_array_member(line);
938                     for (var i = 0 ; i < ar.get_length(); i++) {
939                         if (ar.get_string_element(i) == "Success") {
940                                 continue;
941                                 }
942                                 msg += (msg.length > 0) ? "\n" : "";
943                                 msg += ar.get_string_element(i);
944                         }
945                         if (msg == "") {
946                                 return;
947                         }
948                         msg = "Line: %d".printf(eline+1) +  " " + msg;
949                     this.el.create_source_mark(msg, type, iter);
950                     GLib.debug("set line %d to %m", eline, msg);
951                    // this.marks.set(eline, msg);
952                 } );
953                 return false;
954             
955             
956             
957             
958             
959                 }
960             public bool highlightErrors ( Gee.HashMap<int,string> validate_res) {
961                      
962                 this.error_line = validate_res.size;
963             
964                 if (this.error_line < 1) {
965                         return true;
966                 }
967                 var tlines = this.el.get_line_count ();
968                 Gtk.TextIter iter;
969                 var valiter = validate_res.map_iterator();
970                 while (valiter.next()) {
971             
972                 //        print("get inter\n");
973                         var eline = valiter.get_key();
974                         if (eline > tlines) {
975                                 continue;
976                         }
977                         this.el.get_iter_at_line( out iter, eline);
978                         //print("mark line\n");
979                         this.el.create_source_mark(valiter.get_value(), "ERR", iter);
980                 }   
981                 return false;
982             }
983             public string toString () {
984                 
985                 Gtk.TextIter s;
986                 Gtk.TextIter e;
987                 this.el.get_start_iter(out s);
988                 this.el.get_end_iter(out e);
989                 var ret = this.el.get_text(s,e,true);
990                 //print("TO STRING? " + ret);
991                 return ret;
992             }
993         }
994
995         public class Xcls_EventControllerKey11 : Object
996         {
997             public Gtk.EventControllerKey el;
998             private Editor  _this;
999
1000
1001                 // my vars (def)
1002
1003             // ctor
1004             public Xcls_EventControllerKey11(Editor _owner )
1005             {
1006                 _this = _owner;
1007                 this.el = new Gtk.EventControllerKey();
1008
1009                 // my vars (dec)
1010
1011                 // set gobject values
1012
1013                 //listeners
1014                 this.el.key_released.connect( (keyval, keycode, state) => {
1015                 
1016                   
1017                     if (keyval == Gdk.Key.s && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {
1018                         GLib.debug("SAVE: ctrl-S  pressed");
1019                         _this.saveContents();
1020                         return;
1021                     }
1022                     
1023                     if (keyval == Gdk.Key.g && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {
1024                             GLib.debug("SAVE: ctrl-g  pressed");
1025                                 _this.forwardSearch(true);
1026                             return;
1027                         }
1028                         if (keyval == Gdk.Key.f && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {
1029                             GLib.debug("SAVE: ctrl-f  pressed");
1030                                 _this.search_entry.el.grab_focus();
1031                             return;
1032                         }
1033                     
1034                    // print(event.key.keyval)
1035                     
1036                     return;
1037                  
1038                  
1039                 });
1040             }
1041
1042             // user defined functions
1043         }
1044
1045
1046
1047         public class Xcls_Box12 : Object
1048         {
1049             public Gtk.Box el;
1050             private Editor  _this;
1051
1052
1053                 // my vars (def)
1054
1055             // ctor
1056             public Xcls_Box12(Editor _owner )
1057             {
1058                 _this = _owner;
1059                 this.el = new Gtk.Box( Gtk.Orientation.HORIZONTAL, 0 );
1060
1061                 // my vars (dec)
1062
1063                 // set gobject values
1064                 this.el.homogeneous = false;
1065                 this.el.vexpand = false;
1066                 new Xcls_search_entry( _this );
1067                 this.el.append( _this.search_entry.el );
1068                 new Xcls_search_results( _this );
1069                 this.el.append( _this.search_results.el );
1070                 new Xcls_nextBtn( _this );
1071                 this.el.append( _this.nextBtn.el );
1072                 new Xcls_backBtn( _this );
1073                 this.el.append( _this.backBtn.el );
1074                 var child_5 = new Xcls_MenuButton18( _this );
1075                 child_5.ref();
1076                 this.el.append( child_5.el );
1077             }
1078
1079             // user defined functions
1080         }
1081         public class Xcls_search_entry : Object
1082         {
1083             public Gtk.SearchEntry el;
1084             private Editor  _this;
1085
1086
1087                 // my vars (def)
1088             public Gtk.CssProvider css;
1089
1090             // ctor
1091             public Xcls_search_entry(Editor _owner )
1092             {
1093                 _this = _owner;
1094                 _this.search_entry = this;
1095                 this.el = new Gtk.SearchEntry();
1096
1097                 // my vars (dec)
1098
1099                 // set gobject values
1100                 this.el.name = "editor-search-entry";
1101                 this.el.hexpand = true;
1102                 this.el.placeholder_text = "Press enter to search";
1103                 this.el.search_delay = 3;
1104                 var child_1 = new Xcls_EventControllerKey14( _this );
1105                 child_1.ref();
1106                 this.el.add_controller(  child_1.el );
1107
1108                 //listeners
1109                 this.el.search_changed.connect( ( ) => {
1110                 
1111                 _this.search(_this.search_entry.el.text);
1112                          _this.search_results.updateResults();
1113                 
1114                         GLib.Timeout.add_seconds(1,() => {
1115                                  _this.search_results.updateResults();
1116                                  return false;
1117                          });
1118                 });
1119             }
1120
1121             // user defined functions
1122             public void forwardSearch (bool change_focus) {
1123             
1124             
1125                 _this.forwardSearch(change_focus);
1126             
1127             /*
1128             
1129                 switch(_this.windowstate.state) {
1130                         case WindowState.State.CODEONLY:
1131                         //case WindowState.State.CODE:
1132                                 // search the code being edited..
1133                                 _this.windowstate.code_editor_tab.forwardSearch(change_focus);
1134                                  
1135                                 break;
1136                         case WindowState.State.PREVIEW:
1137                                 if (_this.windowstate.file.xtype == "Gtk") {
1138                                         _this.windowstate.window_gladeview.forwardSearch(change_focus);
1139                                 } else { 
1140                                          _this.windowstate.window_rooview.forwardSearch(change_focus);
1141                                 }
1142                         
1143                                 break;
1144                 }
1145                 */
1146                 
1147             }
1148         }
1149         public class Xcls_EventControllerKey14 : Object
1150         {
1151             public Gtk.EventControllerKey el;
1152             private Editor  _this;
1153
1154
1155                 // my vars (def)
1156
1157             // ctor
1158             public Xcls_EventControllerKey14(Editor _owner )
1159             {
1160                 _this = _owner;
1161                 this.el = new Gtk.EventControllerKey();
1162
1163                 // my vars (dec)
1164
1165                 // set gobject values
1166
1167                 //listeners
1168                 this.el.key_pressed.connect( (keyval, keycode, state) => {
1169                 
1170                         if (keyval == Gdk.Key.g && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {
1171                             GLib.debug("SAVE: ctrl-g  pressed");
1172                                 _this.forwardSearch(true);
1173                             return true;
1174                         }
1175                     
1176                   
1177                         if (keyval == Gdk.Key.Return && _this.search_entry.el.text.length > 0) {
1178                                 _this.forwardSearch(true);
1179                                 
1180                                 
1181                             return true;
1182                 
1183                         }    
1184                    // print(event.key.keyval)
1185                    
1186                     return false;
1187                 });
1188             }
1189
1190             // user defined functions
1191         }
1192
1193
1194         public class Xcls_search_results : Object
1195         {
1196             public Gtk.Label el;
1197             private Editor  _this;
1198
1199
1200                 // my vars (def)
1201
1202             // ctor
1203             public Xcls_search_results(Editor _owner )
1204             {
1205                 _this = _owner;
1206                 _this.search_results = this;
1207                 this.el = new Gtk.Label( "No Results" );
1208
1209                 // my vars (dec)
1210
1211                 // set gobject values
1212                 this.el.margin_end = 4;
1213                 this.el.margin_start = 4;
1214             }
1215
1216             // user defined functions
1217             public void updateResults () {
1218                 this.el.visible = true;
1219                 
1220                 var res = _this.searchcontext.get_occurrences_count();
1221                 if (res < 0) {
1222                         _this.search_results.el.label = "??? Matches";          
1223                         return;
1224                 }
1225             
1226                 _this.nextBtn.el.sensitive = false;
1227                 _this.backBtn.el.sensitive = false;     
1228             
1229                 if (res > 0) {
1230                         _this.search_results.el.label = "%d Matches".printf(res);
1231                         _this.nextBtn.el.sensitive = true;
1232                         _this.backBtn.el.sensitive = true;
1233                         return;
1234                 } 
1235                 _this.search_results.el.label = "No Matches";
1236                 
1237             }
1238         }
1239
1240         public class Xcls_nextBtn : Object
1241         {
1242             public Gtk.Button el;
1243             private Editor  _this;
1244
1245
1246                 // my vars (def)
1247             public bool always_show_image;
1248
1249             // ctor
1250             public Xcls_nextBtn(Editor _owner )
1251             {
1252                 _this = _owner;
1253                 _this.nextBtn = this;
1254                 this.el = new Gtk.Button();
1255
1256                 // my vars (dec)
1257                 this.always_show_image = true;
1258
1259                 // set gobject values
1260                 this.el.icon_name = "go-down";
1261                 this.el.sensitive = false;
1262
1263                 //listeners
1264                 this.el.clicked.connect( (event) => {
1265                 
1266                         _this.forwardSearch(true);
1267                         
1268                          
1269                 });
1270             }
1271
1272             // user defined functions
1273         }
1274
1275         public class Xcls_backBtn : Object
1276         {
1277             public Gtk.Button el;
1278             private Editor  _this;
1279
1280
1281                 // my vars (def)
1282             public bool always_show_image;
1283
1284             // ctor
1285             public Xcls_backBtn(Editor _owner )
1286             {
1287                 _this = _owner;
1288                 _this.backBtn = this;
1289                 this.el = new Gtk.Button();
1290
1291                 // my vars (dec)
1292                 this.always_show_image = true;
1293
1294                 // set gobject values
1295                 this.el.icon_name = "go-up";
1296                 this.el.sensitive = false;
1297
1298                 //listeners
1299                 this.el.clicked.connect( (event) => {
1300                 
1301                         _this.backSearch(true);
1302                          
1303                 });
1304             }
1305
1306             // user defined functions
1307         }
1308
1309         public class Xcls_MenuButton18 : Object
1310         {
1311             public Gtk.MenuButton el;
1312             private Editor  _this;
1313
1314
1315                 // my vars (def)
1316             public bool always_show_image;
1317
1318             // ctor
1319             public Xcls_MenuButton18(Editor _owner )
1320             {
1321                 _this = _owner;
1322                 this.el = new Gtk.MenuButton();
1323
1324                 // my vars (dec)
1325                 this.always_show_image = true;
1326
1327                 // set gobject values
1328                 this.el.icon_name = "emblem-system";
1329                 this.el.always_show_arrow = true;
1330                 new Xcls_search_settings( _this );
1331                 this.el.popover = _this.search_settings.el;
1332             }
1333
1334             // user defined functions
1335         }
1336         public class Xcls_search_settings : Object
1337         {
1338             public Gtk.Popover el;
1339             private Editor  _this;
1340
1341
1342                 // my vars (def)
1343
1344             // ctor
1345             public Xcls_search_settings(Editor _owner )
1346             {
1347                 _this = _owner;
1348                 _this.search_settings = this;
1349                 this.el = new Gtk.Popover();
1350
1351                 // my vars (dec)
1352
1353                 // set gobject values
1354                 var child_1 = new Xcls_Box20( _this );
1355                 this.el.child = child_1.el;
1356             }
1357
1358             // user defined functions
1359         }
1360         public class Xcls_Box20 : Object
1361         {
1362             public Gtk.Box el;
1363             private Editor  _this;
1364
1365
1366                 // my vars (def)
1367
1368             // ctor
1369             public Xcls_Box20(Editor _owner )
1370             {
1371                 _this = _owner;
1372                 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
1373
1374                 // my vars (dec)
1375
1376                 // set gobject values
1377                 new Xcls_case_sensitive( _this );
1378                 this.el.append( _this.case_sensitive.el );
1379                 new Xcls_regex( _this );
1380                 this.el.append( _this.regex.el );
1381                 new Xcls_multiline( _this );
1382                 this.el.append( _this.multiline.el );
1383             }
1384
1385             // user defined functions
1386         }
1387         public class Xcls_case_sensitive : Object
1388         {
1389             public Gtk.CheckButton el;
1390             private Editor  _this;
1391
1392
1393                 // my vars (def)
1394
1395             // ctor
1396             public Xcls_case_sensitive(Editor _owner )
1397             {
1398                 _this = _owner;
1399                 _this.case_sensitive = this;
1400                 this.el = new Gtk.CheckButton();
1401
1402                 // my vars (dec)
1403
1404                 // set gobject values
1405                 this.el.label = "Case Sensitive";
1406
1407                 // init method
1408
1409                 {
1410                         this.el.show();
1411                 }
1412             }
1413
1414             // user defined functions
1415         }
1416
1417         public class Xcls_regex : Object
1418         {
1419             public Gtk.CheckButton el;
1420             private Editor  _this;
1421
1422
1423                 // my vars (def)
1424
1425             // ctor
1426             public Xcls_regex(Editor _owner )
1427             {
1428                 _this = _owner;
1429                 _this.regex = this;
1430                 this.el = new Gtk.CheckButton();
1431
1432                 // my vars (dec)
1433
1434                 // set gobject values
1435                 this.el.label = "Regex";
1436
1437                 // init method
1438
1439                 {
1440                         this.el.show();
1441                 }
1442             }
1443
1444             // user defined functions
1445         }
1446
1447         public class Xcls_multiline : Object
1448         {
1449             public Gtk.CheckButton el;
1450             private Editor  _this;
1451
1452
1453                 // my vars (def)
1454
1455             // ctor
1456             public Xcls_multiline(Editor _owner )
1457             {
1458                 _this = _owner;
1459                 _this.multiline = this;
1460                 this.el = new Gtk.CheckButton();
1461
1462                 // my vars (dec)
1463
1464                 // set gobject values
1465                 this.el.label = "Multi-line (add \\n)";
1466             }
1467
1468             // user defined functions
1469         }
1470
1471
1472
1473
1474
1475     }