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