30bfedde66a3d1d5a02acd4381db613650001f39
[roobuilder] / src / Builder4 / Editor.bjs
1 {
2  "build_module" : "builder",
3  "gen_extended" : false,
4  "items" : [
5   {
6    "# GtkSource.SearchContext searchcontext" : "null",
7    "# JsRender.JsRender? file" : "null",
8    "# JsRender.Node node" : "null",
9    "# JsRender.NodeProp? prop" : "null",
10    "# Xcls_MainWindow window" : "null",
11    "# bool dirty" : false,
12    "# bool pos" : false,
13    "# int last_error_counter" : 0,
14    "# int pos_root_x" : "",
15    "# int pos_root_y" : "",
16    "# string activeEditor" : "\"\"",
17    "$ homogeneous" : false,
18    "$ xns" : "Gtk",
19    "@ void save" : "()",
20    "Gtk.Orientation orientation" : "Gtk.Orientation.VERTICAL",
21    "bool hexpand" : true,
22    "bool vexpand" : true,
23    "int last_search_end" : 0,
24    "items" : [
25     {
26      "$ homogeneous" : false,
27      "$ xns" : "Gtk",
28      "Gtk.Orientation orientation" : "Gtk.Orientation.HORIZONTAL",
29      "bool hexpand" : true,
30      "items" : [
31       {
32        "$ xns" : "Gtk",
33        "id" : "save_button",
34        "label" : "Save",
35        "listeners" : {
36         "clicked" : [
37          " () => { ",
38          "    _this.saveContents();",
39          "}",
40          "  "
41         ]
42        },
43        "xtype" : "Button"
44       },
45       {
46        "$ xns" : "Gtk",
47        "bool hexpand" : true,
48        "xtype" : "Label"
49       },
50       {
51        "$ xns" : "Gtk",
52        "* ctor" : "new Gtk.Scale.with_range (Gtk.Orientation.HORIZONTAL,6, 30, 1)",
53        "* init" : [
54         "{",
55         "\tthis.el.set_range(6,30);",
56         "\tthis.el.set_value(8);",
57         "}",
58         ""
59        ],
60        "bool draw_value" : false,
61        "bool has_origin" : true,
62        "bool sensitive" : true,
63        "int digits" : 0,
64        "int width_request" : 200,
65        "listeners" : {
66         "change_value" : [
67          "(st, val ) => {",
68          "\t ",
69          "\t   ",
70          "\t  _this.view.css.load_from_string(",
71          "\t  \t\t\"#editor-view { font: %dpx monospace; }\".printf((int)val)",
72          "\t   );",
73          "     ",
74          " \treturn false;",
75          "}"
76         ]
77        },
78        "xtype" : "Scale"
79       },
80       {
81        "$ xns" : "Gtk",
82        "id" : "close_btn",
83        "items" : [
84         {
85          "$ xns" : "Gtk",
86          "* prop" : "child",
87          "Gtk.IconSize icon_size" : "Gtk.IconSize.NORMAL",
88          "string icon_name" : "window-close",
89          "xtype" : "Image"
90         }
91        ],
92        "listeners" : {
93         "clicked" : [
94          " () => { ",
95          "    _this.saveContents();",
96          "    _this.window.windowstate.switchState(WindowState.State.PREVIEW);",
97          "}",
98          "  "
99         ]
100        },
101        "string icon_name" : "window-close",
102        "xtype" : "Button"
103       }
104      ],
105      "xtype" : "Box"
106     },
107     {
108      "$ xns" : "Gtk",
109      "Gtk.PolicyType hscrollbar_policy" : "Gtk.PolicyType.AUTOMATIC",
110      "Gtk.PolicyType vscrollbar_policy" : "Gtk.PolicyType.AUTOMATIC",
111      "bool overlay_scrolling" : false,
112      "bool vexpand" : true,
113      "id" : "RightEditor",
114      "items" : [
115       {
116        "# Gtk.CssProvider css" : "null",
117        "$ gboolean auto_indent" : true,
118        "$ xns" : "GtkSource",
119        "* init" : [
120         "",
121         "",
122         "this.css = new Gtk.CssProvider();",
123         "",
124         "this.css.load_from_string(",
125         "\t\"#editor-view { font:  12px monospace;}\"",
126         ");",
127         " ",
128         "Gtk.StyleContext.add_provider_for_display(",
129         "\tthis.el.get_display(),",
130         "\tthis.css,",
131         "\tGtk.STYLE_PROVIDER_PRIORITY_APPLICATION",
132         ");",
133         "\t",
134         " ",
135         " ",
136         "this.el.completion.add_provider(",
137         "\tnew Palete.CompletionProvider(_this)",
138         ");",
139         "  ",
140         "//this.el.completion.unblock_interactive();",
141         "this.el.completion.select_on_show = true; // select",
142         "//this.el.completion.remember_info_visibility\t = true;",
143         "",
144         "",
145         "var attrs = new GtkSource.MarkAttributes();",
146         "",
147         "attrs.set_icon_name ( \"process-stop\");    ",
148         "attrs.query_tooltip_text.connect(( mark) => {",
149         "     GLib.debug(\"tooltip query? %s\", mark.name);",
150         "    return strdup( mark.name);",
151         "});",
152         " attrs.query_tooltip_markup.connect(( mark) => {",
153         "     GLib.debug(\"tooltip query? %s\", mark.name);",
154         "    return strdup( mark.name);",
155         "});",
156         "this.el.set_mark_attributes (\"ERR\", attrs, 1);",
157         "attrs.ref();",
158         "",
159         "",
160         "var wattrs = new GtkSource.MarkAttributes();",
161         "wattrs.set_icon_name ( \"process-stop\");    ",
162         "wattrs.query_tooltip_text.connect(( mark) => {",
163         "     GLib.debug(\"tooltip query? %s\", mark.name);",
164         "    return strdup(mark.name);",
165         "});",
166         "wattrs.query_tooltip_markup.connect(( mark) => {",
167         "     GLib.debug(\"tooltip query? %s\", mark.name);",
168         "    return strdup(mark.name);",
169         "});",
170         "this.el.set_mark_attributes (\"WARN\", wattrs, 1);",
171         "wattrs.ref();",
172         "",
173         " ",
174         "var dattrs = new GtkSource.MarkAttributes();",
175         " ",
176         "dattrs.set_icon_name ( \"process-stop\"); ",
177         "",
178         "dattrs.query_tooltip_text.connect(( mark) => {",
179         "\tGLib.debug(\"tooltip query? %s\", mark.name);",
180         "    return strdup(mark.name);",
181         "});",
182         "//dattrs.query_tooltip_markup.connect(( mark) => {",
183         "//\tGLib.debug(\"tooltip query? %s\", mark.name);",
184         " //   return strdup(mark.name);",
185         "//});",
186         "this.el.set_mark_attributes (\"DEPR\", dattrs, 1);",
187         "dattrs.ref();    ",
188         "",
189         " this.el.get_space_drawer().set_matrix(null);",
190         " this.el.get_space_drawer().set_types_for_locations( ",
191         "\tGtkSource.SpaceLocationFlags.ALL,",
192         "\tGtkSource.SpaceTypeFlags.ALL",
193         ");",
194         "this.el.get_space_drawer().set_enable_matrix(true);",
195         ""
196        ],
197        "* prop" : "child",
198        "bool has_tooltip" : true,
199        "bool hexpand" : true,
200        "bool insert_spaces_instead_of_tabs" : true,
201        "bool vexpand" : true,
202        "boolean show_line_marks" : true,
203        "boolean show_line_numbers" : true,
204        "gboolean highlight_current_line" : true,
205        "id" : "view",
206        "indent_width" : 4,
207        "items" : [
208         {
209          "$ Gee.HashMap<int,string>? xmarks" : "null",
210          "$ xns" : "GtkSource",
211          "$ xtype" : "Buffer",
212          "* init" : [
213           "",
214           "var buf = this.el;",
215           "buf.create_tag (\"bold\", \"weight\", Pango.Weight.BOLD);",
216           "buf.create_tag (\"type\", \"weight\", Pango.Weight.BOLD, \"foreground\", \"#204a87\");",
217           "buf.create_tag (\"keyword\", \"weight\", Pango.Weight.BOLD, \"foreground\", \"#a40000\");",
218           "buf.create_tag (\"text\", \"weight\", Pango.Weight.NORMAL, \"foreground\", \"#729fcf\");",
219           "buf.create_tag (\"number\", \"weight\", Pango.Weight.BOLD, \"foreground\", \"#ad7fa8\");",
220           "buf.create_tag (\"method\", \"weight\", Pango.Weight.BOLD, \"foreground\", \"#729fcf\");",
221           "buf.create_tag (\"property\", \"weight\", Pango.Weight.BOLD, \"foreground\", \"#BC1F51\");",
222           "buf.create_tag (\"variable\", \"weight\", Pango.Weight.BOLD, \"foreground\", \"#A518B5\");",
223           "",
224           "",
225           "buf.create_tag (\"ERR\", \"weight\", Pango.Weight.BOLD, \"background\", \"pink\");",
226           "buf.create_tag (\"WARN\", \"weight\", Pango.Weight.BOLD, \"background\", \"#ABF4EB\");",
227           "buf.create_tag (\"DEPR\", \"weight\", Pango.Weight.BOLD, \"background\", \"#EEA9FF\");",
228           "",
229           "",
230           ""
231          ],
232          "* prop" : "buffer",
233          "bool check_queued" : false,
234          "bool enable_undo" : true,
235          "bool highlight_matching_brackets" : true,
236          "bool highlight_syntax" : true,
237          "id" : "buffer",
238          "int error_line" : "-1",
239          "listeners" : {
240           "changed" : [
241            " () => {",
242            "    // check syntax??",
243            "    // ??needed..??",
244            "    _this.save_button.el.sensitive = true;",
245            "    print(\"EDITOR CHANGED\");",
246            "    this.checkSyntax();",
247            "   ",
248            "    _this.dirty = true;",
249            "",
250            "    // this.get('/LeftPanel.model').changed(  str , false);",
251            "    return ;",
252            "}",
253            ""
254           ]
255          },
256          "| bool OLDhighlightErrorsJson" : [
257           "(string type, Json.Object obj) {",
258           "\tGtk.TextIter start;",
259           "\tGtk.TextIter end;     ",
260           "\tthis.el.get_bounds (out start, out end);",
261           "",
262           "\tthis.el.remove_source_marks (start, end, type);",
263           "\tGLib.debug(\"highlight errors\");\t\t ",
264           "",
265           "\t // we should highlight other types of errors..",
266           "",
267           "\tif (!obj.has_member(type)) {",
268           "\t\tGLib.debug(\"Return has no errors\\n\");",
269           "\t\treturn true;",
270           "\t}",
271           "",
272           "\tif (_this.window.windowstate.state != WindowState.State.CODEONLY ",
273           "\t\t&&",
274           "\t\t_this.window.windowstate.state != WindowState.State.CODE",
275           "\t\t) {",
276           "\t\tGLib.debug(\"windowstate != CODEONLY?\");",
277           "\t\t",
278           "\t\treturn true;",
279           "\t} ",
280           "",
281           "\t//this.marks = new Gee.HashMap<int,string>();",
282           "\tvar err = obj.get_object_member(type);",
283           " ",
284           "\tif (_this.file == null) {",
285           "\t\tGLib.debug(\"file is null?\");",
286           "\t\treturn true;",
287           "",
288           "\t}",
289           "\tvar valafn = _this.file.path;",
290           "",
291           "\tif (_this.file.xtype != \"PlainFile\") {",
292           "",
293           "\t\tvalafn = \"\";",
294           "\t\ttry {             ",
295           "\t\t\tvar  regex = new Regex(\"\\\\.bjs$\");",
296           "\t\t\t// should not happen",
297           "\t      \t\tvalafn = regex.replace(_this.file.path,_this.file.path.length , 0 , \".vala\");",
298           "\t\t} catch (GLib.RegexError e) {",
299           "\t\t\treturn true;",
300           "\t\t}   ",
301           "",
302           "",
303           "",
304           "\t}",
305           "\tif (!err.has_member(valafn)) {",
306           "\t\tGLib.debug(\"File path has no errors\");",
307           "\t\treturn  true;",
308           "\t}",
309           "",
310           "\tvar lines = err.get_object_member(valafn);",
311           "\t",
312           "\tvar offset = 1;",
313           "\tif (obj.has_member(\"line_offset\")) { // ?? why??",
314           "\t\toffset = (int)obj.get_int_member(\"line_offset\") + 1;",
315           "\t}",
316           "",
317           "",
318           "\tvar tlines = this.el.get_line_count () +1;",
319           "\t",
320           "\tif (_this.prop != null) {",
321           "\t",
322           "\t\ttlines = _this.prop.end_line + 1;",
323           "\t\toffset = _this.prop.start_line + 1;",
324           "\t",
325           "\t}",
326           "\t",
327           "",
328           "",
329           "\tlines.foreach_member((obj, line, node) => {",
330           "\t\t",
331           "\t     Gtk.TextIter iter;",
332           "//        print(\"get inter\\n\");",
333           "\t    var eline = int.parse(line) - offset;",
334           "\t    GLib.debug(\"GOT ERROR on line %s -- converted to %d  (offset = %d)\\n\", line,eline, offset);",
335           "\t    ",
336           "\t    ",
337           "\t    if (eline > tlines || eline < 0) {",
338           "\t        return;",
339           "\t    }",
340           "\t   ",
341           "\t    ",
342           "\t    this.el.get_iter_at_line( out iter, eline);",
343           "\t    //print(\"mark line\\n\");",
344           "\t    var msg  = \"\";",
345           "\t    var ar = lines.get_array_member(line);",
346           "\t    for (var i = 0 ; i < ar.get_length(); i++) {",
347           "\t    \tif (ar.get_string_element(i) == \"Success\") {",
348           "\t    \t\tcontinue;",
349           "    \t\t}",
350           "\t\t\tmsg += (msg.length > 0) ? \"\\n\" : \"\";",
351           "\t\t\tmsg += ar.get_string_element(i);",
352           "\t\t}",
353           "\t\tif (msg == \"\") {",
354           "\t\t\treturn;",
355           "\t\t}",
356           "\t\tmsg = \"Line: %d\".printf(eline+1) +  \" \" + msg;",
357           "\t    this.el.create_source_mark(msg, type, iter);",
358           "\t    GLib.debug(\"set line %d to %m\", eline, msg);",
359           "\t   // this.marks.set(eline, msg);",
360           "\t} );",
361           "\treturn false;",
362           "",
363           "",
364           "",
365           "",
366           "",
367           "\t}",
368           ""
369          ],
370          "| bool checkSyntax" : [
371           " () {",
372           " ",
373           "    ",
374           "    var str = this.toString();",
375           "    ",
376           "    // needed???",
377           "    if (this.error_line > 0) {",
378           "         Gtk.TextIter start;",
379           "         Gtk.TextIter end;     ",
380           "        this.el.get_bounds (out start, out end);",
381           "",
382           "        this.el.remove_source_marks (start, end, null);",
383           "    }",
384           "    if (str.length < 1) {",
385           "        print(\"checkSyntax - empty string?\\n\");",
386           "        return true;",
387           "    }",
388           "    ",
389           "    // bit presumptiona",
390           "    if (_this.file.xtype == \"PlainFile\") {",
391           "    ",
392           "        // assume it's gtk...",
393           "         var  oldcode =_this.file.toSource();",
394           "        _this.file.setSource(str);",
395           "\t    BuilderApplication.showSpinner(\"appointment soon\",\"document change pending\");",
396           "    \t_this.file.getLanguageServer().document_change(_this.file);",
397           "",
398           "        _this.file.setSource(oldcode);",
399           "        ",
400           "\t\t ",
401           "        return true;",
402           "    ",
403           "    }",
404           "   if (_this.file == null) {",
405           "       return true;",
406           "   }",
407           " ",
408           "    ",
409           "",
410           "      ",
411           "     ",
412           "    GLib.debug(\"calling validate\");    ",
413           "    // clear the buttons.",
414           " \tif (_this.prop.name == \"xns\" || _this.prop.name == \"xtype\") {",
415           "\t\treturn true ;",
416           "\t}",
417           "\tvar oldcode  = _this.prop.val;",
418           "\t",
419           "\t_this.prop.val = str;",
420           "\t_this.node.updated_count++;",
421           "    _this.file.getLanguageServer().document_change(_this.file);",
422           "    _this.node.updated_count++;",
423           "    _this.prop.val = oldcode;",
424           "    ",
425           "    ",
426           "    //print(\"done mark line\\n\");",
427           "     ",
428           "    return true; // at present allow saving - even if it's invalid..",
429           "}",
430           ""
431          ],
432          "| bool highlightErrors" : [
433           "( Gee.HashMap<int,string> validate_res) {",
434           "         ",
435           "\tthis.error_line = validate_res.size;",
436           "",
437           "\tif (this.error_line < 1) {",
438           "\t\treturn true;",
439           "\t}",
440           "\tvar tlines = this.el.get_line_count ();",
441           "\tGtk.TextIter iter;",
442           "\tvar valiter = validate_res.map_iterator();",
443           "\twhile (valiter.next()) {",
444           "",
445           "\t//        print(\"get inter\\n\");",
446           "\t\tvar eline = valiter.get_key();",
447           "\t\tif (eline > tlines) {",
448           "\t\t\tcontinue;",
449           "\t\t}",
450           "\t\tthis.el.get_iter_at_line( out iter, eline);",
451           "\t\t//print(\"mark line\\n\");",
452           "\t\tthis.el.create_source_mark(valiter.get_value(), \"ERR\", iter);",
453           "\t}   ",
454           "\treturn false;",
455           "}"
456          ],
457          "| string toString" : [
458           "  () {",
459           "    ",
460           "    Gtk.TextIter s;",
461           "    Gtk.TextIter e;",
462           "    this.el.get_start_iter(out s);",
463           "    this.el.get_end_iter(out e);",
464           "    var ret = this.el.get_text(s,e,true);",
465           "    //print(\"TO STRING? \" + ret);",
466           "    return ret;",
467           "}",
468           " "
469          ]
470         },
471         {
472          "$ xns" : "Gtk",
473          "listeners" : {
474           "key_released" : [
475            "(keyval, keycode, state) => {",
476            "",
477            "  ",
478            "    if (keyval == Gdk.Key.s && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {",
479            "        GLib.debug(\"SAVE: ctrl-S  pressed\");",
480            "        _this.saveContents();",
481            "        return;",
482            "    }",
483            "    ",
484            "    if (keyval == Gdk.Key.g && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {",
485            "\t    GLib.debug(\"SAVE: ctrl-g  pressed\");",
486            "\t\t_this.forwardSearch(true);",
487            "\t    return;",
488            "\t}",
489            "\tif (keyval == Gdk.Key.f && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {",
490            "\t    GLib.debug(\"SAVE: ctrl-f  pressed\");",
491            "\t\t_this.search_entry.el.grab_focus();",
492            "\t\t_this.search_entry.el.select_region(0,-1);",
493            "\t    return;",
494            "\t}",
495            "\tif (keyval == Gdk.Key.space && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {",
496            "\t\t_this.view.el.show_completion();",
497            "\t}",
498            "\t",
499            "\tGtk.TextIter iter;",
500            "\t_this.buffer.el.get_iter_at_offset( out iter, _this.buffer.el.cursor_position);  ",
501            "\tvar line  = iter.get_line();",
502            "\tvar offset = iter.get_line_offset();",
503            "\tGLib.debug(\"line  %d  off %d\", line ,offset);",
504            "\tif (_this.prop != null) {",
505            "\t\tline += _this.prop.start_line + 1; // i think..",
506            "\t\toffset += 12; // should probably be 8 without namespaced ",
507            "\t\tGLib.debug(\"guess line  %d  off %d\", line ,offset);",
508            "\t} ",
509            "    //_this.view.el.show_completion();",
510            "   // print(event.key.keyval)",
511            "   ",
512            "   ",
513            "   ",
514            "    ",
515            "    return;",
516            " ",
517            " ",
518            "}",
519            ""
520           ]
521          },
522          "xtype" : "EventControllerKey"
523         }
524        ],
525        "listeners" : {
526         "query_tooltip" : [
527          "(x, y, keyboard_tooltip, tooltip) => {",
528          "\t",
529          "\t//GLib.debug(\"query tooltip\");",
530          "\tGtk.TextIter iter;",
531          "\tint trailing;",
532          "\t",
533          "\tvar yoff = (int) _this.RightEditor.el.vadjustment.value;",
534          "\t",
535          "\t// I think this is problematic - if it's compliing  / updating at same time as query.",
536          "\t",
537          "\t//if (_this.window.statusbar_compile_spinner.el.spinning) {",
538          "\t//\treturn false;",
539          "\t//}",
540          "\t",
541          "\tthis.el.get_iter_at_position (out iter, out trailing,  x,  y + yoff);",
542          "\t ",
543          "\tvar l = iter.get_line();",
544          "",
545          "\t",
546          "\t ",
547          "\t// GLib.debug(\"query tooltip line %d\", (int) l);",
548          "\tif (l < 0) {",
549          "",
550          "\t\treturn false;",
551          "\t}",
552          "\t/*",
553          "\tif (_this.buffer.marks != null && _this.buffer.marks.has_key(l)) {",
554          "\t\tGLib.debug(\"line %d setting tip to %s\", l,  _this.buffer.marks.get(l));",
555          "\t\ttooltip.set_text(_this.buffer.marks.get(l).dup());",
556          "\t\treturn true;",
557          "\t}",
558          " ",
559          "\treturn false;",
560          "\t*/",
561          "\t",
562          "\t  ",
563          "\t// this crashes?? - not sure why.",
564          "\tvar marks = _this.buffer.el.get_source_marks_at_line(l, \"ERR\");",
565          "\tif (marks.is_empty()) {",
566          "\t\tmarks = _this.buffer.el.get_source_marks_at_line(l, \"WARN\");",
567          "\t}",
568          "\tif (marks.is_empty()) {",
569          "\t\tmarks = _this.buffer.el.get_source_marks_at_line(l, \"DEPR\");",
570          "\t}",
571          "\t",
572          "\t// GLib.debug(\"query tooltip line %d marks %d\", (int)l, (int) marks.length());",
573          "\tvar str = \"\";",
574          "\tmarks.@foreach((m) => { ",
575          "\t\t//GLib.debug(\"got mark %s\", m.name);",
576          "\t\tstr += (str.length > 0 ? \"\\n\" : \"\") + m.category + \": \" + m.name;",
577          "\t});",
578          "\t// true if there is a mark..",
579          "\tif (str.length > 0 ) {",
580          "\t\ttooltip.set_text( str );",
581          "\t}",
582          "\treturn str.length > 0 ? true : false;",
583          "\t ",
584          "}",
585          ""
586         ]
587        },
588        "string name" : "editor-view",
589        "uint tab_width" : 4,
590        "xtype" : "View",
591        "| void load" : [
592         " (string str) {",
593         "",
594         "// show the help page for the active node..",
595         "   //this.get('/Help').show();",
596         " ",
597         "  // this.get('/BottomPane').el.set_current_page(0);",
598         "  \tGLib.debug(\"load called - Reset undo buffer\");",
599         "  \t",
600         "    var buf = (GtkSource.Buffer)this.el.get_buffer();",
601         "    buf.begin_irreversible_action();",
602         "    buf.set_text(str, str.length);",
603         "    buf.end_irreversible_action();",
604         "    ",
605         "    var lm = GtkSource.LanguageManager.get_default();",
606         "    var lang = \"vala\";",
607         "    if (_this.file != null) {",
608         "         lang = _this.file.language;",
609         "    }",
610         "    print(\"lang=%s, content_type = %s\\n\", lang, _this.file.content_type);",
611         "    var lg = _this.file.content_type.length > 0  ?",
612         "            lm.guess_language(_this.file.path, _this.file.content_type) :",
613         "            lm.get_language(lang);",
614         "     ",
615         "   ",
616         "    ((GtkSource.Buffer)(this.el.get_buffer())) .set_language(lg); ",
617         "",
618         "    this.el.insert_spaces_instead_of_tabs = true;",
619         "    if (lg != null) {",
620         "\t\tprint(\"sourcelanguage  = %s\\n\", lg.name);",
621         "\t\tif (lg.name == \"Vala\") {",
622         "\t\t    this.el.insert_spaces_instead_of_tabs = false;",
623         "\t\t}",
624         "     }",
625         "    _this.dirty = false;",
626         "    this.el.grab_focus();",
627         "    _this.save_button.el.sensitive = false;",
628         "    _this.last_error_counter = -1;",
629         "}"
630        ]
631       }
632      ],
633      "xtype" : "ScrolledWindow"
634     },
635     {
636      "$ xns" : "Gtk",
637      "* pack" : "append",
638      "Gtk.Orientation orientation" : "Gtk.Orientation.HORIZONTAL",
639      "bool homogeneous" : false,
640      "bool vexpand" : false,
641      "int spacing" : 0,
642      "items" : [
643       {
644        "$ xns" : "Gtk",
645        "Gtk.CssProvider css" : "",
646        "bool hexpand" : true,
647        "id" : "search_entry",
648        "items" : [
649         {
650          "$ xns" : "Gtk",
651          "listeners" : {
652           "key_pressed" : [
653            "(keyval, keycode, state) => {",
654            "",
655            "\tif (keyval == Gdk.Key.g && (state & Gdk.ModifierType.CONTROL_MASK ) > 0 ) {",
656            "\t    GLib.debug(\"SAVE: ctrl-g  pressed\");",
657            "\t\t_this.forwardSearch(true);",
658            "\t    return true;",
659            "\t}",
660            "    ",
661            "  ",
662            " \tif (keyval == Gdk.Key.Return && _this.search_entry.el.text.length > 0) {",
663            "\t\t_this.forwardSearch(true);",
664            "\t\t",
665            "\t\t",
666            "\t    return true;",
667            "",
668            "\t}    ",
669            "   // print(event.key.keyval)",
670            "   ",
671            "    return false;",
672            "}",
673            ""
674           ]
675          },
676          "xtype" : "EventControllerKey"
677         }
678        ],
679        "listeners" : {
680         "search_changed" : [
681          "( ) => {",
682          "",
683          "_this.search(_this.search_entry.el.text);",
684          "\t _this.search_results.updateResults();",
685          "",
686          "\tGLib.Timeout.add_seconds(1,() => {",
687          "\t\t _this.search_results.updateResults();",
688          "\t\t return false;",
689          "\t });",
690          "}",
691          ""
692         ]
693        },
694        "string name" : "editor-search-entry",
695        "string placeholder_text" : "Press enter to search",
696        "uint search_delay" : 3,
697        "xtype" : "SearchEntry",
698        "| void forwardSearch" : [
699         "(bool change_focus) {",
700         "",
701         "",
702         "\t_this.forwardSearch(change_focus);",
703         "",
704         "/*",
705         "",
706         "\tswitch(_this.windowstate.state) {",
707         "\t\tcase WindowState.State.CODEONLY:",
708         "\t\t//case WindowState.State.CODE:",
709         "\t\t\t// search the code being edited..",
710         "\t\t\t_this.windowstate.code_editor_tab.forwardSearch(change_focus);",
711         "\t\t\t ",
712         "\t\t\tbreak;",
713         "\t\tcase WindowState.State.PREVIEW:",
714         "\t\t\tif (_this.windowstate.file.xtype == \"Gtk\") {",
715         "\t\t\t\t_this.windowstate.window_gladeview.forwardSearch(change_focus);",
716         "\t\t\t} else { ",
717         "\t\t\t\t _this.windowstate.window_rooview.forwardSearch(change_focus);",
718         "\t\t\t}",
719         "\t\t",
720         "\t\t\tbreak;",
721         "\t}",
722         "\t*/",
723         "\t",
724         "}",
725         ""
726        ]
727       },
728       {
729        "$ xns" : "Gtk",
730        "id" : "search_results",
731        "int margin_end" : 4,
732        "int margin_start" : 4,
733        "string label" : "No Results",
734        "xtype" : "Label",
735        "| void updateResults" : [
736         "() {",
737         "\tthis.el.visible = true;",
738         "\t",
739         "\tvar res = _this.searchcontext.get_occurrences_count();",
740         "\tif (res < 0) {",
741         "\t\t_this.search_results.el.label = \"??? Matches\";\t\t",
742         "\t\treturn;",
743         "\t}",
744         "",
745         "\t_this.nextBtn.el.sensitive = false;",
746         "\t_this.backBtn.el.sensitive = false;\t",
747         "",
748         "\tif (res > 0) {",
749         "\t\t_this.search_results.el.label = \"%d Matches\".printf(res);",
750         "\t\t_this.nextBtn.el.sensitive = true;",
751         "\t\t_this.backBtn.el.sensitive = true;",
752         "\t\treturn;",
753         "\t} ",
754         "\t_this.search_results.el.label = \"No Matches\";",
755         "\t",
756         "}"
757        ]
758       },
759       {
760        "$ xns" : "Gtk",
761        "bool always_show_image" : true,
762        "bool sensitive" : false,
763        "id" : "nextBtn",
764        "listeners" : {
765         "clicked" : [
766          "(event) => {",
767          "",
768          "\t_this.forwardSearch(true);",
769          "\t",
770          "\t ",
771          "}",
772          ""
773         ]
774        },
775        "string icon_name" : "go-down",
776        "xtype" : "Button"
777       },
778       {
779        "$ xns" : "Gtk",
780        "bool always_show_image" : true,
781        "bool sensitive" : false,
782        "id" : "backBtn",
783        "listeners" : {
784         "clicked" : [
785          "(event) => {",
786          "",
787          "\t_this.backSearch(true);",
788          "\t ",
789          "}",
790          ""
791         ]
792        },
793        "string icon_name" : "go-up",
794        "xtype" : "Button"
795       },
796       {
797        "$ xns" : "Gtk",
798        "bool always_show_arrow" : true,
799        "bool always_show_image" : true,
800        "items" : [
801         {
802          "$ xns" : "Gtk",
803          "* prop" : "popover",
804          "id" : "search_settings",
805          "items" : [
806           {
807            "$ xns" : "Gtk",
808            "* prop" : "child",
809            "Gtk.Orientation orientation" : "Gtk.Orientation.VERTICAL",
810            "int spacing" : 0,
811            "items" : [
812             {
813              "$ xns" : "Gtk",
814              "* init" : [
815               "{",
816               "\tthis.el.show();",
817               "}",
818               ""
819              ],
820              "id" : "case_sensitive",
821              "string label" : "Case Sensitive",
822              "xtype" : "CheckButton"
823             },
824             {
825              "$ xns" : "Gtk",
826              "* init" : [
827               "{",
828               "\tthis.el.show();",
829               "}",
830               ""
831              ],
832              "id" : "regex",
833              "string label" : "Regex",
834              "xtype" : "CheckButton"
835             },
836             {
837              "$ xns" : "Gtk",
838              "id" : "multiline",
839              "string label" : "Multi-line (add \\n)",
840              "xtype" : "CheckButton"
841             }
842            ],
843            "xtype" : "Box"
844           }
845          ],
846          "xtype" : "Popover"
847         }
848        ],
849        "string icon_name" : "emblem-system",
850        "xtype" : "MenuButton"
851       }
852      ],
853      "xtype" : "Box"
854     }
855    ],
856    "xtype" : "Box",
857    "| bool saveContents" : [
858     "  ()  {",
859     "    ",
860     "    ",
861     "    if (_this.file == null) {",
862     "        return true;",
863     "    }",
864     "    ",
865     "     ",
866     "     ",
867     "     var str = _this.buffer.toString();",
868     "     ",
869     "     _this.buffer.checkSyntax();",
870     "     ",
871     "     ",
872     "     ",
873     "     // LeftPanel.model.changed(  str , false);",
874     "     _this.dirty = false;",
875     "     _this.save_button.el.sensitive = false;",
876     "     ",
877     "    // find the text for the node..",
878     "    if (_this.file.xtype != \"PlainFile\") {",
879     "       // in theory these properties have to exist!?!",
880     "    \tthis.prop.val = str;",
881     "        //this.window.windowstate.left_props.reload();",
882     "    } else {",
883     "        _this.file.setSource(  str );",
884     "     }",
885     "    ",
886     "    // call the signal..",
887     "    this.save();",
888     "    ",
889     "    return true;",
890     "",
891     "} "
892    ],
893    "| int search" : [
894     "(string in_txt) {",
895     "",
896     "\tvar s = new GtkSource.SearchSettings();",
897     "\ts.case_sensitive = _this.case_sensitive.el.active;",
898     "\ts.regex_enabled = _this.regex.el.active;\t",
899     "\ts.wrap_around = false;",
900     "\t",
901     "\tthis.searchcontext = new GtkSource.SearchContext(this.buffer.el,s);",
902     "\tthis.searchcontext.set_highlight(true);",
903     "\tvar txt = in_txt;",
904     "\t",
905     "\tif (_this.multiline.el.active) {",
906     "\t\ttxt = in_txt.replace(\"\\\\n\", \"\\n\");",
907     "\t}",
908     "\t",
909     "\ts.set_search_text(txt);",
910     "\tGtk.TextIter beg, st,en;",
911     "\t ",
912     "\tthis.buffer.el.get_start_iter(out beg);",
913     "\tbool has_wrapped_around;",
914     "\tthis.searchcontext.forward(beg, out st, out en, out has_wrapped_around);",
915     "\tthis.last_search_end = 0;",
916     "\t",
917     "\treturn this.searchcontext.get_occurrences_count();",
918     "",
919     " ",
920     "   ",
921     "",
922     "}",
923     ""
924    ],
925    "| string tempFileContents" : [
926     "() {",
927     "   ",
928     "   ",
929     "   if (_this.file == null) {",
930     "       return \"\";",
931     "   }",
932     "\tvar str= this.buffer.toString();",
933     "\tif (_this.file.xtype == \"PlainFile\") {",
934     "    ",
935     "     \treturn str;",
936     "    ",
937     "    }",
938     "  ",
939     "      ",
940     "     ",
941     "    GLib.debug(\"calling validate\");    ",
942     "    // clear the buttons.",
943     " \tif (_this.prop.name == \"xns\" || _this.prop.name == \"xtype\") {",
944     "\t\treturn this.file.toSource(); ;",
945     "\t}",
946     "\t",
947     "\tvar oldcode  = _this.prop.val;",
948     "\t_this.prop.val = str;",
949     "    var ret = _this.file.toSource();",
950     "    _this.prop.val = oldcode;",
951     "    return ret;",
952     "    ",
953     "}"
954    ],
955    "| void backSearch" : [
956     "(bool change_focus) {",
957     "",
958     "\tif (this.searchcontext == null) {",
959     "\t\treturn;",
960     "\t} ",
961     "\t",
962     "\tGtk.TextIter beg, st,en;",
963     "\tbool has_wrapped_around;",
964     "\tthis.buffer.el.get_iter_at_offset(out beg, this.last_search_end -1 );",
965     "\t",
966     "\tif (!this.searchcontext.backward(beg, out st, out en, out has_wrapped_around)) {",
967     "\t\tthis.last_search_end = 0;",
968     "\t} else {",
969     "\t\tthis.last_search_end = en.get_offset();",
970     "\t\tif (change_focus) {",
971     "\t\t\tthis.view.el.grab_focus();",
972     "\t\t}",
973     "\t\tthis.buffer.el.place_cursor(st);",
974     "\t\tthis.view.el.scroll_to_iter(st,  0.1f, true, 0.0f, 0.5f);",
975     "\t}",
976     "",
977     "}",
978     ""
979    ],
980    "| void forwardSearch" : [
981     "(bool change_focus) {",
982     "",
983     "\tif (this.searchcontext == null) {",
984     "\t\treturn;",
985     "\t} ",
986     "",
987     "\tGtk.TextIter beg, st,en;",
988     "\t bool has_wrapped_around;",
989     "\tthis.buffer.el.get_iter_at_offset(out beg, this.last_search_end);",
990     "\tif (!this.searchcontext.forward(beg, out st, out en, out has_wrapped_around)) {",
991     "\t",
992     "\t\tthis.last_search_end = 0; // not sure if this should happen",
993     "\t} else {",
994     "\t\tif (has_wrapped_around) {",
995     "\t\t\treturn;",
996     "\t\t}",
997     "\t",
998     "\t\tthis.last_search_end = en.get_offset();",
999     "\t\tif (change_focus) {",
1000     "\t\t\tthis.view.el.grab_focus();",
1001     "\t\t}",
1002     "\t\tthis.buffer.el.place_cursor(st);",
1003     "\t\tthis.view.el.scroll_to_iter(st,  0.1f, true, 0.0f, 0.5f);",
1004     "\t}",
1005     " ",
1006     "}",
1007     ""
1008    ],
1009    "| void reset" : [
1010     "() {",
1011     "\t this.file = null;    ",
1012     "     ",
1013     "    this.node = null;",
1014     "    this.prop = null;",
1015     "\tthis.searchcontext = null;",
1016     "  ",
1017     "}",
1018     ""
1019    ],
1020    "| void scroll_to_line" : [
1021     "(int line) {",
1022     "",
1023     "\tGLib.Timeout.add(500, () => {",
1024     "   ",
1025     "\t\tvar buf = this.view.el.get_buffer();",
1026     "",
1027     "\t\tvar sbuf = (GtkSource.Buffer) buf;",
1028     "",
1029     "",
1030     "\t\tGtk.TextIter iter;   ",
1031     "\t\tsbuf.get_iter_at_line(out iter,  line);",
1032     "\t\tthis.view.el.scroll_to_iter(iter,  0.1f, true, 0.0f, 0.5f);",
1033     "\t\treturn false;",
1034     "\t});   ",
1035     "}",
1036     ""
1037    ],
1038    "| void show" : [
1039     "(JsRender.JsRender file, JsRender.Node? node, JsRender.NodeProp? prop)",
1040     "{",
1041     "    this.reset();",
1042     "    this.file = file;    ",
1043     "    ",
1044     "    if (file.xtype != \"PlainFile\") {",
1045     "    \tthis.prop = prop;",
1046     "        this.node = node;",
1047     "",
1048     "        // find the text for the node..",
1049     "        this.view.load( prop.val );",
1050     "        this.updateErrorMarks();",
1051     "        ",
1052     "        this.close_btn.el.show();       ",
1053     "    ",
1054     "    } else {",
1055     "        this.view.load(        file.toSource() );",
1056     "         this.updateErrorMarks();",
1057     "        this.close_btn.el.hide();",
1058     "        ",
1059     "    }",
1060     " ",
1061     "}"
1062    ],
1063    "| void updateErrorMarks" : [
1064     "() {",
1065     "\t",
1066     " ",
1067     "",
1068     "\tvar buf = _this.buffer.el;",
1069     "\tGtk.TextIter start;",
1070     "\tGtk.TextIter end;     ",
1071     "\tbuf.get_bounds (out start, out end);",
1072     "",
1073     "\t",
1074     "",
1075     " ",
1076     "\t//GLib.debug(\"highlight errors\");\t\t ",
1077     "",
1078     "\t // we should highlight other types of errors..",
1079     "",
1080     "\tif (_this.window.windowstate.state != WindowState.State.CODEONLY ",
1081     "\t\t&&",
1082     "\t\t_this.window.windowstate.state != WindowState.State.CODE",
1083     "\t\t) {",
1084     "\t\t//GLib.debug(\"windowstate != CODEONLY?\");",
1085     "\t\t",
1086     "\t\treturn;",
1087     "\t} ",
1088     "",
1089     "\t ",
1090     "\tif (_this.file == null) {",
1091     "\t\tGLib.debug(\"file is null?\");",
1092     "\t\treturn;",
1093     "",
1094     "\t}",
1095     "\tvar ar = this.file.getErrors();",
1096     "\tif (ar.size < 1) {",
1097     "\t\tbuf.remove_source_marks (start, end, null);",
1098     "\t\tbuf.remove_tag_by_name (\"ERR\", start, end);",
1099     "\t\tbuf.remove_tag_by_name (\"WARN\", start, end);",
1100     "\t\tbuf.remove_tag_by_name (\"DEPR\", start, end);",
1101     "\t\tthis.last_error_counter = file.error_counter ;",
1102     "\t\t//GLib.debug(\"highlight %s :  %s has no errors\", this.file.relpath, category);",
1103     "\t\treturn;",
1104     "\t}",
1105     "\t",
1106     "",
1107     " // basicaly check if there is no change, then we do not do any update..",
1108     " // we can do this by just using an error counter?",
1109     " // if that's changed then we will do an update, otherwise dont bother.",
1110     "\t  ",
1111     "\t",
1112     "\tvar offset = 0;",
1113     "\tvar hoffset = 0;",
1114     "",
1115     "\tvar tlines = buf.get_line_count () +1;",
1116     "\t",
1117     "\tif (_this.prop != null) {",
1118     "\t\t// this still seems flaky...",
1119     "",
1120     "\t\ttlines = _this.prop.end_line;",
1121     "\t\toffset = _this.prop.start_line;",
1122     "\t\thoffset = _this.node.node_pad.length + 2; //shift it left  by 2 ? ..",
1123     "\t\t",
1124     "\t\t ",
1125     "\t} else {",
1126     "\t\t// no update...",
1127     "\t\tif (this.last_error_counter == file.error_counter) {",
1128     "\t\t",
1129     "\t\t\treturn;",
1130     "\t\t}",
1131     "\t",
1132     "\t}",
1133     "\tbuf.remove_source_marks (start, end, null);",
1134     "\tbuf.remove_tag_by_name (\"ERR\", start, end);",
1135     "\tbuf.remove_tag_by_name (\"WARN\", start, end);",
1136     "\tbuf.remove_tag_by_name (\"DEPR\", start, end);",
1137     "\t",
1138     "\tforeach(var diag in ar) { ",
1139     "\t     Gtk.TextIter iter;",
1140     "//        print(\"get inter\\n\");",
1141     "\t    var eline = (int)diag.range.start.line - offset;",
1142     "\t    var eline_to = (int)diag.range.end.line - offset;",
1143     "\t    //var eline =  diag.range.end_line - offset;",
1144     "\t    //GLib.debug(\"GOT ERROR on line %d -- converted to %d  (offset = %d)\",",
1145     "\t    //\terr.line ,eline, offset);",
1146     "\t    ",
1147     "\t    ",
1148     "\t    if (eline > tlines || eline < 0) {",
1149     "\t        continue;",
1150     "\t    }",
1151     "\t   ",
1152     "\t    ",
1153     "\t    buf.get_iter_at_line( out iter, eline);",
1154     "\t   \tvar msg = \"Line: %d %s : %s\".printf(eline+1, diag.category, diag.message);",
1155     "\t    buf.create_source_mark( msg, diag.category, iter);",
1156     " \t    ",
1157     " \t    buf.get_iter_at_line_offset( out start, ",
1158     " \t    \teline, (int)diag.range.start.character - hoffset); ",
1159     " \t    buf.get_iter_at_line_offset( out end, ",
1160     " \t    \teline_to, (int)diag.range.end.character - hoffset); ",
1161     " \t    \t",
1162     "\t    buf.apply_tag_by_name(diag.category, start, end);",
1163     "\t    ",
1164     "\t   // GLib.debug(\"set line %d to %s\", eline, msg);",
1165     "\t    //this.marks.set(eline, msg);",
1166     "\t}",
1167     "\tthis.last_error_counter = file.error_counter ;",
1168     "",
1169     "",
1170     "",
1171     " ",
1172     "",
1173     "}"
1174    ]
1175   }
1176  ],
1177  "name" : "Editor"
1178 }