1 static Xcls_WindowRooView _WindowRooView;
3 public class Xcls_WindowRooView : Object
6 private Xcls_WindowRooView _this;
8 public static Xcls_WindowRooView singleton()
10 if (_WindowRooView == null) {
11 _WindowRooView= new Xcls_WindowRooView();
13 return _WindowRooView;
15 public Xcls_notebook notebook;
16 public Xcls_label_preview label_preview;
17 public Xcls_label_code label_code;
18 public Xcls_paned paned;
19 public Xcls_viewbox viewbox;
20 public Xcls_AutoRedraw AutoRedraw;
21 public Xcls_viewcontainer viewcontainer;
22 public Xcls_view view;
23 public Xcls_inspectorcontainer inspectorcontainer;
24 public Xcls_sourceview sourceview;
25 public Xcls_buffer buffer;
28 public Gtk.Widget lastObj;
29 public int last_search_end;
30 public Gtk.SourceSearchContext searchcontext;
31 public JsRender.JsRender file;
32 public Xcls_MainWindow main_window;
35 public Xcls_WindowRooView()
38 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
42 this.last_search_end = 0;
46 this.el.hexpand = true;
47 this.el.vexpand = true;
48 var child_0 = new Xcls_notebook( _this );
50 this.el.pack_start ( child_0.el , true,true,0 );
53 // user defined functions
54 public void scroll_to_line (int line) {
55 this.notebook.el.page = 1;// code preview...
57 GLib.Timeout.add(500, () => {
62 var buf = this.sourceview.el.get_buffer();
64 var sbuf = (Gtk.SourceBuffer) buf;
68 sbuf.get_iter_at_line(out iter, line);
69 this.sourceview.el.scroll_to_iter(iter, 0.1f, true, 0.0f, 0.5f);
75 public int search (string txt) {
76 this.notebook.el.page = 1;
77 var s = new Gtk.SourceSearchSettings();
78 var buf = (Gtk.SourceBuffer) this.sourceview.el.get_buffer();
79 this.searchcontext = new Gtk.SourceSearchContext(buf,s);
80 this.searchcontext.set_highlight(true);
81 s.set_search_text(txt);
83 Gtk.TextIter beg, st,en;
85 buf.get_start_iter(out beg);
86 this.searchcontext.forward(beg, out st, out en);
87 this.last_search_end = 0;
88 return this.searchcontext.get_occurrences_count();
92 public void createThumb () {
95 if (this.file == null) {
98 if (this.notebook.el.page > 0 ) {
102 var filename = this.file.getIconFileName(false);
104 var win = this.el.get_parent_window();
105 var width = win.get_width();
106 // var height = win.get_height();
108 Gdk.Pixbuf screenshot = Gdk.pixbuf_get_from_window(win, 0, 0, width, this.paned.el.position);
109 screenshot.save(filename,"png");
119 public void loadFile (JsRender.JsRender file)
122 this.view.renderJS(true);
123 this.notebook.el.page = 0;// gtk preview
124 this.sourceview.loadFile();
127 public void requestRedraw () {
128 this.view.renderJS(false);
129 this.sourceview.loadFile();
131 public void forwardSearch (bool change_focus) {
133 if (this.searchcontext == null) {
136 this.notebook.el.page = 1;
137 Gtk.TextIter beg, st,en, stl;
139 var buf = this.sourceview.el.get_buffer();
140 buf.get_iter_at_offset(out beg, this.last_search_end);
141 if (!this.searchcontext.forward(beg, out st, out en)) {
142 this.last_search_end = 0;
145 this.last_search_end = en.get_offset();
147 this.sourceview.el.grab_focus();
149 buf.place_cursor(st);
150 var ln = st.get_line();
151 buf.get_iter_at_line(out stl,ln);
153 this.sourceview.el.scroll_to_iter(stl, 0.0f, true, 0.0f, 0.5f);
158 var node = _this.file.lineToNode(ln+1);
161 //print("can not find node\n");
164 var prop = node.lineToProp(ln+1);
165 print("prop : %s", prop == null ? "???" : prop);
168 // ---------- this selects the tree's node...
170 var ltree = _this.main_window.windowstate.left_tree;
171 var tp = ltree.model.treePathFromNode(node);
172 print("got tree path %s\n", tp);
176 //_this.sourceview.allow_node_scroll = false; /// block node scrolling..
179 //print("changing cursor on tree..\n");
183 // let's try allowing editing on the methods.
184 // a little klunky at present..
185 _this.sourceview.prop_selected = "";
187 //see if we can find it..
188 var kv = prop.split(":");
191 //var k = prop.get_key(kv[1]);
192 // fixme -- need to determine if it's an editable property...
193 _this.sourceview.prop_selected = prop;
195 } else if (kv[0] == "l") {
196 _this.sourceview.prop_selected = prop;
200 ltree.view.setCursor(tp, "editor");
201 // ltree.view.el.set_cursor(new Gtk.TreePath.from_string(tp), null, false);
202 _this.sourceview.nodeSelected(node,false);
204 // scrolling is disabled... as node selection calls scroll 10ms after it changes.
205 // GLib.Timeout.add_full(GLib.Priority.DEFAULT,100 , () => {
206 // this.allow_node_scroll = true;
222 public class Xcls_notebook : Object
224 public Gtk.Notebook el;
225 private Xcls_WindowRooView _this;
231 public Xcls_notebook(Xcls_WindowRooView _owner )
234 _this.notebook = this;
235 this.el = new Gtk.Notebook();
239 // set gobject values
240 var child_0 = new Xcls_label_preview( _this );
242 var child_1 = new Xcls_label_code( _this );
244 var child_2 = new Xcls_paned( _this );
246 this.el.append_page ( child_2.el , _this.label_preview.el );
247 var child_3 = new Xcls_ScrolledWindow14( _this );
249 this.el.append_page ( child_3.el , _this.label_code.el );
252 // user defined functions
254 public class Xcls_label_preview : Object
257 private Xcls_WindowRooView _this;
263 public Xcls_label_preview(Xcls_WindowRooView _owner )
266 _this.label_preview = this;
267 this.el = new Gtk.Label( "Preview" );
271 // set gobject values
274 // user defined functions
277 public class Xcls_label_code : Object
280 private Xcls_WindowRooView _this;
286 public Xcls_label_code(Xcls_WindowRooView _owner )
289 _this.label_code = this;
290 this.el = new Gtk.Label( "Preview Generated Code" );
294 // set gobject values
297 // user defined functions
300 public class Xcls_paned : Object
303 private Xcls_WindowRooView _this;
309 public Xcls_paned(Xcls_WindowRooView _owner )
313 this.el = new Gtk.Paned( Gtk.Orientation.VERTICAL );
317 // set gobject values
318 var child_0 = new Xcls_viewbox( _this );
320 this.el.pack1 ( child_0.el , true,true );
321 var child_1 = new Xcls_inspectorcontainer( _this );
323 this.el.pack2 ( child_1.el , true,true );
326 // user defined functions
328 public class Xcls_viewbox : Object
331 private Xcls_WindowRooView _this;
337 public Xcls_viewbox(Xcls_WindowRooView _owner )
340 _this.viewbox = this;
341 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
345 // set gobject values
346 this.el.homogeneous = false;
347 var child_0 = new Xcls_Box7( _this );
349 this.el.pack_start ( child_0.el , false,true,0 );
350 var child_1 = new Xcls_viewcontainer( _this );
352 this.el.pack_end ( child_1.el , true,true,0 );
355 // user defined functions
357 public class Xcls_Box7 : Object
360 private Xcls_WindowRooView _this;
366 public Xcls_Box7(Xcls_WindowRooView _owner )
369 this.el = new Gtk.Box( Gtk.Orientation.HORIZONTAL, 0 );
373 // set gobject values
374 this.el.homogeneous = true;
375 this.el.height_request = 20;
376 this.el.vexpand = false;
377 var child_0 = new Xcls_Button8( _this );
379 this.el.pack_start ( child_0.el , false,false,0 );
380 var child_1 = new Xcls_AutoRedraw( _this );
382 this.el.pack_start ( child_1.el , false,false,0 );
383 var child_2 = new Xcls_Button10( _this );
385 this.el.pack_start ( child_2.el , false,false,0 );
388 // user defined functions
390 public class Xcls_Button8 : Object
392 public Gtk.Button el;
393 private Xcls_WindowRooView _this;
399 public Xcls_Button8(Xcls_WindowRooView _owner )
402 this.el = new Gtk.Button();
406 // set gobject values
407 this.el.label = "Redraw";
410 this.el.clicked.connect( ( ) => {
411 _this.view.renderJS( true);
415 // user defined functions
418 public class Xcls_AutoRedraw : Object
420 public Gtk.CheckButton el;
421 private Xcls_WindowRooView _this;
427 public Xcls_AutoRedraw(Xcls_WindowRooView _owner )
430 _this.AutoRedraw = this;
431 this.el = new Gtk.CheckButton();
435 // set gobject values
436 this.el.active = true;
437 this.el.label = "Auto Redraw On";
440 this.el.toggled.connect( (state) => {
441 this.el.set_label(this.el.active ? "Auto Redraw On" : "Auto Redraw Off");
445 // user defined functions
448 public class Xcls_Button10 : Object
450 public Gtk.Button el;
451 private Xcls_WindowRooView _this;
457 public Xcls_Button10(Xcls_WindowRooView _owner )
460 this.el = new Gtk.Button();
464 // set gobject values
465 this.el.label = "Full Redraw";
468 this.el.clicked.connect( () => {
469 _this.view.redraws = 99;
470 _this.view.el.web_context.clear_cache();
471 //_this.view.renderJS(true);
472 FakeServerCache.clear();
478 // user defined functions
482 public class Xcls_viewcontainer : Object
484 public Gtk.ScrolledWindow el;
485 private Xcls_WindowRooView _this;
491 public Xcls_viewcontainer(Xcls_WindowRooView _owner )
494 _this.viewcontainer = this;
495 this.el = new Gtk.ScrolledWindow( null, null );
499 // set gobject values
500 this.el.shadow_type = Gtk.ShadowType.IN;
501 var child_0 = new Xcls_view( _this );
503 this.el.add ( child_0.el );
507 this.el.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
510 // user defined functions
512 public class Xcls_view : Object
514 public WebKit.WebView el;
515 private Xcls_WindowRooView _this;
519 public string renderedData;
520 public bool refreshRequired;
521 public WebKit.WebInspector inspector;
524 public GLib.DateTime lastRedraw;
525 public string runhtml;
526 public bool pendingRedraw;
529 public Xcls_view(Xcls_WindowRooView _owner )
533 this.el = new WebKit.WebView();
536 this.renderedData = "";
537 this.refreshRequired = false;
540 this.lastRedraw = null;
542 this.pendingRedraw = false;
544 // set gobject values
549 // this may not work!?
550 var settings = this.el.get_settings();
551 settings.enable_developer_extras = true;
554 var fs= new FakeServer(this.el);
556 // this was an attempt to change the url perms.. did not work..
557 // settings.enable_file_access_from_file_uris = true;
558 // settings.enable_offline_web_application_cache - true;
559 // settings.enable_universal_access_from_file_uris = true;
566 // FIXME - base url of script..
567 // we need it so some of the database features work.
568 this.el.load_html( "Render not ready" ,
569 //fixme - should be a config option!
570 // or should we catch stuff and fix it up..
571 "http://localhost/app.Builder/"
575 //this.el.open('file:///' + __script_path__ + '/../builder.html');
580 Gtk.DestDefaults.MOTION | Gtk.DestDefaults.HIGHLIGHT,
581 null, // list of targets
582 Gdk.DragAction.COPY // what to do with data after dropped
585 // print("RB: TARGETS : " + LeftTree.atoms["STRING"]);
586 Gtk.drag_dest_set_target_list(this.el, this.get('/Window').targetList);
588 GLib.Timeout.add_seconds(1, () =>{
589 //print("run refresh?");
590 if (this.el == null) {
601 this.el.script_dialog.connect( (dialog) => {
604 if (this.el == null) {
608 var msg = dialog.get_message();
609 if (msg.length < 4) {
612 if (msg.substring(0,4) != "IPC:") {
615 var ar = msg.split(":", 3);
622 print("GOT saveHTML %d?\n", ar[2].length);
623 _this.file.saveHTML(ar[2]);
630 this.el.show.connect( ( ) => {
631 this.initInspector();;
633 this.el.drag_drop.connect( ( ctx, x, y,time, ud) => {
636 print("TARGET: drag-drop");
637 var is_valid_drop_site = true;
642 w, // will receive 'drag-data-received' signal
643 ctx, /* represents the current state of the DnD
644 this.get('/Window').atoms["STRING"], /* the target type we want
649 /* No target offered by source => error
652 return is_valid_drop_site;
655 this.el.load_changed.connect( (le) => {
656 if (le != WebKit.LoadEvent.FINISHED) {
659 if (this.runjs.length < 1) {
662 // this.el.run_javascript(this.runjs, null);
663 FakeServerCache.remove( this.runjs);
668 // user defined functions
669 public void reInit () {
671 // if this happens destroy the webkit..
673 this.el.stop_loading();
675 if (_this.viewbox.el.get_parent() == null) {
680 _this.viewbox.el.remove(_this.viewcontainer.el);
681 _this.paned.el.remove(_this.inspectorcontainer.el);
683 // destory seems to cause problems.
685 //_this.viewcontainer.el.destroy();
686 //_this.inspectorcontainer.el.destroy();
687 var inv =new Xcls_inspectorcontainer(_this);
689 _this.paned.el.pack2(inv.el,true,true);
693 var nv =new Xcls_viewcontainer(_this);
695 _this.viewbox.el.pack_end(nv.el,true,true,0);
700 //while(Gtk.events_pending ()) Gtk.main_iteration ();
701 //_this.view.renderJS(true);
702 _this.view.refreshRequired = true;
704 public void runRefresh ()
706 // this is run every 2 seconds from the init..
710 if (!this.refreshRequired) {
711 // print("no refresh required");
715 if (this.lastRedraw != null) {
716 // do not redraw if last redraw was less that 5 seconds ago.
717 if ((int64)(new DateTime.now_local()).difference(this.lastRedraw) < 5000 ) {
722 if (_this.file == null) {
727 this.refreshRequired = false;
728 // print("HTML RENDERING");
731 //this.get('/BottomPane').el.show();
732 //this.get('/BottomPane').el.set_current_page(2);// webkit inspector
733 _this.file.webkit_page_id = this.el.get_page_id();
735 var js = _this.file.toSourcePreview();
744 var project = _this.file.project;
746 //print (project.fn);
747 // set it to non-empty.
749 // runhtml = runhtml.length ? runhtml : '<script type="text/javascript"></script>';
752 // this.runhtml = this.runhtml || '';
755 // then we need to reload the browser using
756 // load_html_string..
758 // then trigger a redraw once it's loaded..
759 this.pendingRedraw = true;
761 var runhtml = "<script type=\"text/javascript\">\n" ;
765 GLib.FileUtils.get_contents(BuilderApplication.configDirectory() + "/resources/roo.builder.js", out builderhtml);
770 runhtml += builderhtml + "\n";
771 runhtml += "</script>\n" ;
773 // fix to make sure they are the same..
774 this.runhtml = project.runhtml;
775 // need to modify paths
778 var base_template = _this.file.project.base_template;
780 if (base_template.length > 0 && !FileUtils.test(
781 BuilderApplication.configDirectory() + "/resources/" + base_template, FileTest.EXISTS)
783 print("invalid base_template name - using default: %s\n", base_template);
788 GLib.FileUtils.get_contents(
789 BuilderApplication.configDirectory() + "/resources/" +
790 (base_template.length > 0 ? base_template : "roo.builder.html")
796 this.renderedData = js;
799 string js_src = js + "\n" +
800 "Roo.onReady(function() {\n" +
801 "if (" + _this.file.name +".show) " + _this.file.name +".show({});\n" +
802 "Roo.XComponent.build();\n" +
805 // print("render js: " + js);
807 // console.log('not loaded yet');
809 this.lastRedraw = new DateTime.now_local();
812 //this.runjs = js_src;
813 var fc = FakeServerCache.factory_with_data(js_src);
814 this.runjs = fc.fname;
816 var html = inhtml.replace("</head>", runhtml + this.runhtml +
817 "<script type=\"text/javascript\" src=\"xhttp://localhost" + fc.fname + "\"></script>" +
818 // "<script type=\"text/javascript\">\n" +
823 //print("LOAD HTML " + html);
825 var rootURL = _this.file.project.rootURL;
829 this.el.load_html( html ,
830 //fixme - should be a config option!
831 (rootURL.length > 0 ? rootURL : "xhttp://localhost/roobuilder/")
834 // force the inspector...
835 // this.initInspector();
837 // - no need for this, the builder javascript will call it when build is complete
838 //GLib.Timeout.add_seconds(1, () => {
839 // this.el.run_javascript("Builder.saveHTML()",null);
842 // print( "before render" + this.lastRedraw);
843 // print( "after render" + (new Date()));
846 public void initInspector () {
848 /* if (this.inspector == this.el.get_inspector()) {
849 this.inspector.show();
850 this.inspector.open_window();
851 print("init inspecter called, and inspector is the same as existing\n");
854 print("new inspector?\n");
856 this.inspector = this.el.get_inspector();
857 this.inspector.ref();
859 // got a new inspector...
861 this.inspector.open_window.connect(() => {
862 this.inspector = this.el.get_inspector();
863 print("inspector attach\n");
864 var wv = this.inspector.get_web_view();
866 print("got inspector web view\n");
868 var cn = _this.inspectorcontainer.el.get_child();
870 _this.inspectorcontainer.el.remove(cn);
873 _this.inspectorcontainer.el.add(wv);
876 //this.inspector.close();
878 //this.inspector = null;
886 this.inspector.closed.connect(() => {
887 print("inspector closed?!?");
888 // if this happens destroy the webkit..
890 this.el.stop_loading();
892 if (_this.viewbox.el.get_parent() == null) {
897 _this.viewbox.el.remove(_this.viewcontainer.el);
898 _this.el.remove(_this.inspectorcontainer.el);
900 // destory seems to cause problems.
902 //_this.viewcontainer.el.destroy();
903 //_this.inspectorcontainer.el.destroy();
906 var nv =new Xcls_viewcontainer(_this);
908 _this.viewbox.el.pack_end(nv.el,true,true,0);
910 var inv =new Xcls_inspectorcontainer(_this);
912 _this.el.pack2(inv.el,true,true);
916 //while(Gtk.events_pending ()) Gtk.main_iteration ();
917 //_this.view.renderJS(true);
918 _this.view.refreshRequired = true;
923 this.inspector.show();
925 public void renderJS (bool force) {
927 // this is the public redraw call..
928 // we refresh in a loop privately..
929 var autodraw = _this.AutoRedraw.el.active;
930 if (!autodraw && !force) {
931 print("Skipping redraw - no force, and autodraw off");
935 this.refreshRequired = true;
941 public class Xcls_inspectorcontainer : Object
943 public Gtk.ScrolledWindow el;
944 private Xcls_WindowRooView _this;
950 public Xcls_inspectorcontainer(Xcls_WindowRooView _owner )
953 _this.inspectorcontainer = this;
954 this.el = new Gtk.ScrolledWindow( null, null );
958 // set gobject values
959 this.el.shadow_type = Gtk.ShadowType.IN;
963 this.el.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
966 // user defined functions
970 public class Xcls_ScrolledWindow14 : Object
972 public Gtk.ScrolledWindow el;
973 private Xcls_WindowRooView _this;
979 public Xcls_ScrolledWindow14(Xcls_WindowRooView _owner )
982 this.el = new Gtk.ScrolledWindow( null, null );
986 // set gobject values
987 var child_0 = new Xcls_sourceview( _this );
989 this.el.add ( child_0.el );
992 // user defined functions
994 public class Xcls_sourceview : Object
996 public Gtk.SourceView el;
997 private Xcls_WindowRooView _this;
1001 public bool button_is_pressed;
1002 public JsRender.Node? node_selected;
1003 public bool loading;
1004 public int editable_start_pos;
1005 public string prop_selected;
1006 public bool key_is_pressed;
1009 public Xcls_sourceview(Xcls_WindowRooView _owner )
1012 _this.sourceview = this;
1013 this.el = new Gtk.SourceView();
1016 this.button_is_pressed = false;
1017 this.node_selected = null;
1018 this.loading = true;
1019 this.editable_start_pos = -1;
1020 this.prop_selected = "";
1021 this.key_is_pressed = false;
1023 // set gobject values
1024 this.el.editable = false;
1025 this.el.show_line_marks = true;
1026 this.el.show_line_numbers = true;
1027 var child_0 = new Xcls_buffer( _this );
1029 this.el.set_buffer ( child_0.el );
1036 var description = Pango.FontDescription.from_string("monospace");
1037 description.set_size(8000);
1038 this.el.override_font(description);
1040 this.loading = true;
1041 //var buf = this.el.get_buffer();
1042 //buf.notify.connect(this.onCursorChanged);
1045 var attrs = new Gtk.SourceMarkAttributes();
1046 var pink = Gdk.RGBA();
1047 pink.parse ( "pink");
1048 attrs.set_background ( pink);
1049 attrs.set_icon_name ( "process-stop");
1050 attrs.query_tooltip_text.connect(( mark) => {
1051 //print("tooltip query? %s\n", mark.name);
1055 this.el.set_mark_attributes ("ERR", attrs, 1);
1057 var wattrs = new Gtk.SourceMarkAttributes();
1058 var blue = Gdk.RGBA();
1059 blue.parse ( "#ABF4EB");
1060 wattrs.set_background ( blue);
1061 wattrs.set_icon_name ( "process-stop");
1062 wattrs.query_tooltip_text.connect(( mark) => {
1063 //print("tooltip query? %s\n", mark.name);
1067 this.el.set_mark_attributes ("WARN", wattrs, 1);
1071 var dattrs = new Gtk.SourceMarkAttributes();
1072 var purple = Gdk.RGBA();
1073 purple.parse ( "#EEA9FF");
1074 dattrs.set_background ( purple);
1075 dattrs.set_icon_name ( "process-stop");
1076 dattrs.query_tooltip_text.connect(( mark) => {
1077 //print("tooltip query? %s\n", mark.name);
1081 this.el.set_mark_attributes ("DEPR", dattrs, 1);
1084 var gattrs = new Gtk.SourceMarkAttributes();
1085 var grey = Gdk.RGBA();
1086 grey.parse ( "#ccc");
1087 gattrs.set_background ( grey);
1090 this.el.set_mark_attributes ("grey", gattrs, 1);
1100 this.el.button_release_event.connect( () => {
1102 print("BUTTON RELEASE EVENT\n");
1103 this.onCursorChanged();
1104 this.button_is_pressed = false;
1107 this.el.button_press_event.connect( () => {
1110 this.button_is_pressed = true;
1113 this.el.key_press_event.connect( (src, key) => {
1114 this.key_is_pressed = true;
1115 // is it ctrl-G -- find next?
1116 // which will will still ignore..
1118 if (key.str == "g" && key.state == Gdk.ModifierType.CONTROL_MASK) {
1119 this.key_is_pressed = false;
1122 // if cursor postion is 'at start' of editing range,
1123 // and backspace is pressed...
1126 var buf = this.el.get_buffer();
1127 //print("cursor changed : %d\n", buf.cursor_position);
1129 if (buf.cursor_position <= this.editable_start_pos && key.keyval == Gdk.Key.BackSpace) {
1130 return true; // block...
1132 // what about 'last line of 'grey...'
1133 // get the buffer - find the line, find the next line ?? see if it's grey?
1136 print("KEY PRESS EVENT \n");
1137 this.onCursorChanged();
1140 this.el.key_release_event.connect( () => {
1141 this.key_is_pressed = false;
1146 // user defined functions
1147 public void clearGreySelection () {
1148 // clear all the marks..
1149 var sbuf = (Gtk.SourceBuffer)this.el.buffer;
1154 sbuf.get_bounds (out start, out end);
1155 sbuf.remove_source_marks (start, end, "grey");
1159 public void onCursorChanged (/*ParamSpec ps*/) {
1161 if (!this.key_is_pressed && !this.button_is_pressed) {
1168 // if (ps.name != "cursor-position") {
1172 var buf = this.el.get_buffer();
1173 //print("cursor changed : %d\n", buf.cursor_position);
1175 buf.get_iter_at_offset(out cpos, buf.cursor_position);
1177 var ln = cpos.get_line();
1180 // --- select node at line....
1182 var node = _this.file.lineToNode(ln+1);
1185 print("can not find node\n");
1188 var prop = node.lineToProp(ln+1);
1189 print("prop : %s", prop == null ? "???" : prop);
1192 // ---------- this selects the tree's node...
1194 var ltree = _this.main_window.windowstate.left_tree;
1195 var tp = ltree.model.treePathFromNode(node);
1196 print("got tree path %s\n", tp);
1200 //print("changing cursor on tree..\n");
1204 // let's try allowing editing on the methods.
1205 // a little klunky at present..
1206 this.prop_selected = "";
1208 //see if we can find it..
1209 var kv = prop.split(":");
1212 //var k = prop.get_key(kv[1]);
1213 // fixme -- need to determine if it's an editable property...
1214 this.prop_selected = prop;
1216 } else if (kv[0] == "l") {
1217 this.prop_selected = prop;
1221 ltree.view.setCursor(tp, "editor");
1222 // ltree.view.el.set_cursor(new Gtk.TreePath.from_string(tp), null, false);
1223 this.nodeSelected(node,false);
1225 // scrolling is disabled... as node selection calls scroll 10ms after it changes.
1229 // highlight the node..
1231 public string toString () {
1234 this.el.get_buffer().get_start_iter(out s);
1235 this.el.get_buffer().get_end_iter(out e);
1236 var ret = this.el.get_buffer().get_text(s,e,true);
1237 //print("TO STRING? " + ret);
1240 public void nodeSelected (JsRender.Node? sel, bool scroll ) {
1244 // this is connected in widnowstate
1248 while(Gtk.events_pending()) {
1249 Gtk.main_iteration();
1252 this.node_selected = sel;
1254 this.updateGreySelection(scroll);
1259 public void loadFile ( ) {
1260 this.loading = true;
1263 // get the cursor and scroll position....
1264 var buf = this.el.get_buffer();
1265 var cpos = buf.cursor_position;
1267 print("BEFORE LOAD cursor = %d\n", cpos);
1269 var vadj_pos = this.el.get_vadjustment().get_value();
1274 var sbuf = (Gtk.SourceBuffer) buf;
1278 if (_this.file == null || _this.file.xtype != "Roo") {
1279 print("xtype != Roo");
1280 this.loading = false;
1284 // get the string from the rendered tree...
1286 var str = _this.file.toSource();
1288 // print("setting str %d\n", str.length);
1289 buf.set_text(str, str.length);
1290 var lm = Gtk.SourceLanguageManager.get_default();
1292 //?? is javascript going to work as js?
1294 ((Gtk.SourceBuffer)(buf)) .set_language(lm.get_language(_this.file.language));
1300 sbuf.get_bounds (out start, out end);
1301 sbuf.remove_source_marks (start, end, null); // remove all marks..
1303 GLib.Timeout.add(500, () => {
1305 print("RESORTING cursor to = %d\n", cpos);
1306 Gtk.TextIter cpos_iter;
1307 buf.get_iter_at_offset(out cpos_iter, cpos);
1308 buf.place_cursor(cpos_iter);
1310 this.el.get_vadjustment().set_value(vadj_pos);;
1313 this.onCursorChanged();
1316 _this.buffer.checkSyntax();
1320 this.loading = false;
1321 _this.buffer.dirty = false;
1323 public void updateGreySelection (bool scroll) {
1324 var sel = this.node_selected;
1325 print("node selected\n");
1326 var buf = this.el.get_buffer();
1327 var sbuf = (Gtk.SourceBuffer) buf;
1330 this.clearGreySelection();
1335 print("no selected node\n");
1336 // no highlighting..
1340 print("highlight region %d to %d\n", sel.line_start,sel.line_end);
1342 sbuf.get_iter_at_line(out iter, sel.line_start);
1345 Gtk.TextIter cur_iter;
1346 sbuf.get_iter_at_offset(out cur_iter, sbuf.cursor_position);
1348 var cursor_at_line = cur_iter.get_line();
1351 //var cur_line = cur_iter.get_line();
1352 //if (cur_line > sel.line_start && cur_line < sel.line_end) {
1356 print("scrolling to node -- should occur on node picking.\n");
1357 this.el.scroll_to_iter(iter, 0.1f, true, 0.0f, 0.5f);
1360 var start_line = sel.line_start;
1361 var end_line = sel.line_end;
1364 this.el.editable = false;
1366 //var colon_pos = 0;
1368 this.editable_start_pos = -1;
1370 // now if we have selected a property...
1371 if (this.prop_selected.length> 0 ) {
1374 if (sel.getPropertyRange(this.prop_selected, out nstart, out nend) && nend > nstart) {
1375 start_line = nstart;
1377 this.el.editable = true;
1378 print("start line = %d, end line = %d\n", start_line, end_line);
1380 // see if we are 'right of ':'
1381 // get an iter for the start of the line.
1382 Gtk.TextIter start_first_line_iter,end_first_line_iter;
1383 this.el.buffer.get_iter_at_line(out start_first_line_iter, start_line -1);
1384 this.el.buffer.get_iter_at_line(out end_first_line_iter, start_line -1);
1389 if (end_first_line_iter.forward_to_line_end()) {
1390 var first_line = this.el.buffer.get_text(start_first_line_iter, end_first_line_iter, false);
1392 print("first line = %s\n", first_line);
1393 if (first_line.contains(":")) {
1394 this.editable_start_pos = start_first_line_iter.get_offset() + first_line.index_of(":") + 1;
1395 print("colon_pos = %d\n", this.editable_start_pos);
1399 //Gtk.TextIter colon_iter;
1400 //sbuf.get_iter_at_offset (out colon_iter, colon_pos);
1401 //sbuf.create_source_mark(null, "active_text", colon_iter);
1406 //print("is cursor at line? %d ?= %d\n", start_line -1 , cursor_at_line);
1407 //if (start_line - 1 == cursor_at_line) {
1408 // should be ok - current_posssion can not be less than '-1'...
1409 if (sbuf.cursor_position < this.editable_start_pos) {
1411 print("cursor is before start pos.. - turn off editable...\n");
1412 //var before_cursor_string = this.el.buffer.get_text(start_line_iter, cur_iter, false);
1413 //print("before cursor string = %s\n", before_cursor_string);
1414 //if (!before_cursor_string.contains(":")) {
1415 this.el.editable = false;
1424 print("propSelected = %s range %d -> %d\n", this.prop_selected, start_line, end_line);
1429 print("checking selection\n");
1432 // check selection - if it's out of 'bounds'
1433 if (this.el.editable && sbuf.get_has_selection()) {
1434 Gtk.TextIter sel_start_iter, sel_end_iter;
1435 sbuf.get_selection_bounds(out sel_start_iter, out sel_end_iter);
1437 if (sel_start_iter.get_line() < start_line || sel_end_iter.get_line() > end_line ||
1438 sel_start_iter.get_line() > end_line || sel_end_iter.get_line() < start_line ) {
1440 this.el.editable = false;
1442 if (this.editable_start_pos > 0 &&
1443 (sel_start_iter.get_offset() < this.editable_start_pos || sel_end_iter.get_offset() < this.editable_start_pos)
1446 this.el.editable = false;
1456 for (var i = 0; i < buf.get_line_count();i++) {
1457 if (i < (start_line -1) || i > (end_line -1)) {
1459 sbuf.get_iter_at_line(out iter, i);
1460 sbuf.create_source_mark(null, "grey", iter);
1465 if (scroll && (cursor_at_line > end_line || cursor_at_line < start_line)) {
1466 Gtk.TextIter cpos_iter;
1467 buf.get_iter_at_line(out cpos_iter, start_line);
1469 buf.place_cursor(cpos_iter);
1474 public void highlightErrorsJson (string type, Json.Object obj) {
1475 // this is a hook for the vala code - it has no value in javascript
1476 // as we only have one error ususally....
1484 public class Xcls_buffer : Object
1486 public Gtk.SourceBuffer el;
1487 private Xcls_WindowRooView _this;
1492 public int error_line;
1495 public Xcls_buffer(Xcls_WindowRooView _owner )
1498 _this.buffer = this;
1499 this.el = new Gtk.SourceBuffer( null );
1503 this.error_line = -1;
1505 // set gobject values
1508 this.el.changed.connect( () => {
1513 // _this.save_button.el.sensitive = true;
1514 ///?? has changed occured during loading?
1516 // only trigger this if
1521 if (_this.sourceview.loading) {
1527 print("- PREVIEW EDITOR CHANGED--");
1530 this.checkSyntax(); // this calls backs and highlights errors.. in theory...
1534 if (!_this.sourceview.button_is_pressed && !_this.sourceview.key_is_pressed) {
1535 print("button or key not pressed to generate change?!\n");
1540 // what are we editing??
1541 if (null == _this.sourceview.node_selected || _this.sourceview.prop_selected.length < 1) {
1545 // find the colon on the first line...
1547 if (_this.sourceview.editable_start_pos > -1) {
1549 var buf = (Gtk.SourceBuffer)_this.sourceview.el.get_buffer();
1551 //print("cursor changed : %d\n", buf.cursor_position);
1552 Gtk.TextIter spos,epos;
1553 buf.get_iter_at_offset(out spos, _this.sourceview.editable_start_pos);
1554 buf.get_iter_at_offset(out epos, _this.sourceview.editable_start_pos); // initialize epos..
1557 var line = spos.get_line();
1558 var endline = buf.get_line_count();
1559 while (line < endline) {
1561 buf.get_iter_at_line(out epos, line);
1562 if (buf.get_source_marks_at_line(line, "grey").length() > 0) {
1563 buf.get_iter_at_line(out epos, line);
1570 print("End Offset = %d/%d\n", epos.get_line(), epos.get_offset());
1572 // in theory the last char will be '}' or '},' .. or ','
1573 // we should chop the ',' of the end...
1574 var str = buf.get_text(spos, epos, false);
1575 print("got string\n%s\n", str);
1583 // user defined functions
1584 public bool highlightErrors ( Gee.HashMap<int,string> validate_res) {
1586 this.error_line = validate_res.size;
1588 if (this.error_line < 1) {
1591 var tlines = this.el.get_line_count ();
1593 var valiter = validate_res.map_iterator();
1594 while (valiter.next()) {
1596 // print("get inter\n");
1597 var eline = valiter.get_key();
1598 if (eline > tlines) {
1601 this.el.get_iter_at_line( out iter, eline);
1602 //print("mark line\n");
1603 this.el.create_source_mark(valiter.get_value(), "ERR", iter);
1607 public bool checkSyntax () {
1610 var str = this.toString();
1613 if (this.error_line > 0) {
1616 this.el.get_bounds (out start, out end);
1618 this.el.remove_source_marks (start, end, "WARN");
1619 this.el.remove_source_marks (start, end, "ERR");
1623 if (str.length < 1) {
1624 print("checkSyntax - empty string?\n");
1628 if (_this.file == null) {
1631 var p = _this.file.project.palete;
1634 if (_this.file.language != "js") {
1635 return false; // fake syntax error.
1638 //Gee.HashMap<int,string> ret_x;
1640 return p.javascriptHasErrors(
1641 _this.main_window.windowstate,
1644 "file", //_this.ptype,
1650 public string toString () {
1654 this.el.get_start_iter(out s);
1655 this.el.get_end_iter(out e);
1656 var ret = this.el.get_text(s,e,true);
1657 //print("TO STRING? " + ret);