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