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;
30 public int last_search_end;
31 public Gtk.SourceSearchContext searchcontext;
32 public JsRender.JsRender file;
34 public Xcls_MainWindow main_window;
37 public Xcls_WindowRooView()
40 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
45 this.last_search_end = 0;
50 this.el.hexpand = true;
51 var child_0 = new Xcls_notebook( _this );
53 this.el.pack_start ( child_0.el , true,true,0 );
56 // user defined functions
57 public void scroll_to_line (int line) {
58 this.notebook.el.page = 1;// code preview...
60 GLib.Timeout.add(500, () => {
65 var buf = this.sourceview.el.get_buffer();
67 var sbuf = (Gtk.SourceBuffer) buf;
71 sbuf.get_iter_at_line(out iter, line);
72 this.sourceview.el.scroll_to_iter(iter, 0.1f, true, 0.0f, 0.5f);
78 public void createThumb () {
81 if (this.file == null) {
84 if (this.notebook.el.page > 0 ) {
88 var filename = this.file.getIconFileName(false);
90 var win = this.el.get_parent_window();
91 var width = win.get_width();
92 // var height = win.get_height();
94 Gdk.Pixbuf screenshot = Gdk.pixbuf_get_from_window(win, 0, 0, width, this.paned.el.position);
95 screenshot.save(filename,"png");
105 public void loadFile (JsRender.JsRender file)
108 this.view.renderJS(true);
109 this.notebook.el.page = 0;// gtk preview
110 this.sourceview.loadFile();
113 public int search (string txt) {
114 this.notebook.el.page = 1;
115 var s = new Gtk.SourceSearchSettings();
116 var buf = (Gtk.SourceBuffer) this.sourceview.el.get_buffer();
117 this.searchcontext = new Gtk.SourceSearchContext(buf,s);
118 this.searchcontext.set_highlight(true);
119 s.set_search_text(txt);
121 Gtk.TextIter beg, st,en;
123 buf.get_start_iter(out beg);
124 this.searchcontext.forward(beg, out st, out en);
125 this.last_search_end = 0;
126 return this.searchcontext.get_occurrences_count();
130 public void requestRedraw () {
131 this.view.renderJS(false);
132 this.sourceview.loadFile();
134 public void forwardSearch (bool change_focus) {
136 if (this.searchcontext == null) {
139 this.notebook.el.page = 1;
140 Gtk.TextIter beg, st,en, stl;
142 var buf = this.sourceview.el.get_buffer();
143 buf.get_iter_at_offset(out beg, this.last_search_end);
144 if (!this.searchcontext.forward(beg, out st, out en)) {
145 this.last_search_end = 0;
148 this.last_search_end = en.get_offset();
150 this.sourceview.el.grab_focus();
152 buf.place_cursor(st);
153 var ln = st.get_line();
154 buf.get_iter_at_line(out stl,ln);
156 this.sourceview.el.scroll_to_iter(stl, 0.0f, true, 0.0f, 0.5f);
161 var node = _this.file.lineToNode(ln+1);
164 //print("can not find node\n");
167 var prop = node.lineToProp(ln+1);
168 print("prop : %s", prop == null ? "???" : prop);
171 // ---------- this selects the tree's node...
173 var ltree = _this.main_window.windowstate.left_tree;
174 var tp = ltree.model.treePathFromNode(node);
175 print("got tree path %s\n", tp);
179 //_this.sourceview.allow_node_scroll = false; /// block node scrolling..
182 //print("changing cursor on tree..\n");
186 // let's try allowing editing on the methods.
187 // a little klunky at present..
188 _this.sourceview.prop_selected = "";
190 //see if we can find it..
191 var kv = prop.split(":");
194 //var k = prop.get_key(kv[1]);
195 // fixme -- need to determine if it's an editable property...
196 _this.sourceview.prop_selected = prop;
198 } else if (kv[0] == "l") {
199 _this.sourceview.prop_selected = prop;
203 ltree.view.setCursor(tp, "editor");
204 // ltree.view.el.set_cursor(new Gtk.TreePath.from_string(tp), null, false);
205 _this.sourceview.nodeSelected(node,false);
207 // scrolling is disabled... as node selection calls scroll 10ms after it changes.
208 // GLib.Timeout.add_full(GLib.Priority.DEFAULT,100 , () => {
209 // this.allow_node_scroll = true;
225 public class Xcls_notebook : Object
227 public Gtk.Notebook el;
228 private Xcls_WindowRooView _this;
234 public Xcls_notebook(Xcls_WindowRooView _owner )
237 _this.notebook = this;
238 this.el = new Gtk.Notebook();
242 // set gobject values
243 var child_0 = new Xcls_label_preview( _this );
245 var child_1 = new Xcls_label_code( _this );
247 var child_2 = new Xcls_paned( _this );
249 this.el.append_page ( child_2.el , _this.label_preview.el );
250 var child_3 = new Xcls_ScrolledWindow14( _this );
252 this.el.append_page ( child_3.el , _this.label_code.el );
255 // user defined functions
257 public class Xcls_label_preview : Object
260 private Xcls_WindowRooView _this;
266 public Xcls_label_preview(Xcls_WindowRooView _owner )
269 _this.label_preview = this;
270 this.el = new Gtk.Label( "Preview" );
274 // set gobject values
277 // user defined functions
280 public class Xcls_label_code : Object
283 private Xcls_WindowRooView _this;
289 public Xcls_label_code(Xcls_WindowRooView _owner )
292 _this.label_code = this;
293 this.el = new Gtk.Label( "Preview Generated Code" );
297 // set gobject values
300 // user defined functions
303 public class Xcls_paned : Object
306 private Xcls_WindowRooView _this;
312 public Xcls_paned(Xcls_WindowRooView _owner )
316 this.el = new Gtk.Paned( Gtk.Orientation.VERTICAL );
320 // set gobject values
321 var child_0 = new Xcls_viewbox( _this );
323 this.el.pack1 ( child_0.el , true,true );
324 var child_1 = new Xcls_inspectorcontainer( _this );
326 this.el.pack2 ( child_1.el , true,true );
329 // user defined functions
331 public class Xcls_viewbox : Object
334 private Xcls_WindowRooView _this;
340 public Xcls_viewbox(Xcls_WindowRooView _owner )
343 _this.viewbox = this;
344 this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
348 // set gobject values
349 this.el.homogeneous = false;
350 var child_0 = new Xcls_Box7( _this );
352 this.el.pack_start ( child_0.el , false,true,0 );
353 var child_1 = new Xcls_viewcontainer( _this );
355 this.el.pack_end ( child_1.el , true,true,0 );
358 // user defined functions
360 public class Xcls_Box7 : Object
363 private Xcls_WindowRooView _this;
369 public Xcls_Box7(Xcls_WindowRooView _owner )
372 this.el = new Gtk.Box( Gtk.Orientation.HORIZONTAL, 0 );
376 // set gobject values
377 this.el.homogeneous = true;
378 this.el.height_request = 20;
379 this.el.vexpand = false;
380 var child_0 = new Xcls_Button8( _this );
382 this.el.pack_start ( child_0.el , false,false,0 );
383 var child_1 = new Xcls_AutoRedraw( _this );
385 this.el.pack_start ( child_1.el , false,false,0 );
386 var child_2 = new Xcls_Button10( _this );
388 this.el.pack_start ( child_2.el , false,false,0 );
391 // user defined functions
393 public class Xcls_Button8 : Object
395 public Gtk.Button el;
396 private Xcls_WindowRooView _this;
402 public Xcls_Button8(Xcls_WindowRooView _owner )
405 this.el = new Gtk.Button();
409 // set gobject values
410 this.el.label = "Redraw";
413 this.el.clicked.connect( ( ) => {
414 _this.view.renderJS( true);
418 // user defined functions
421 public class Xcls_AutoRedraw : Object
423 public Gtk.CheckButton el;
424 private Xcls_WindowRooView _this;
430 public Xcls_AutoRedraw(Xcls_WindowRooView _owner )
433 _this.AutoRedraw = this;
434 this.el = new Gtk.CheckButton();
438 // set gobject values
439 this.el.active = true;
440 this.el.label = "Auto Redraw On";
443 this.el.toggled.connect( (state) => {
444 this.el.set_label(this.el.active ? "Auto Redraw On" : "Auto Redraw Off");
448 // user defined functions
451 public class Xcls_Button10 : Object
453 public Gtk.Button el;
454 private Xcls_WindowRooView _this;
460 public Xcls_Button10(Xcls_WindowRooView _owner )
463 this.el = new Gtk.Button();
467 // set gobject values
468 this.el.label = "Full Redraw";
471 this.el.clicked.connect( () => {
472 _this.view.redraws = 99;
473 _this.view.el.web_context.clear_cache();
474 //_this.view.renderJS(true);
475 FakeServerCache.clear();
481 // user defined functions
485 public class Xcls_viewcontainer : Object
487 public Gtk.ScrolledWindow el;
488 private Xcls_WindowRooView _this;
494 public Xcls_viewcontainer(Xcls_WindowRooView _owner )
497 _this.viewcontainer = this;
498 this.el = new Gtk.ScrolledWindow( null, null );
502 // set gobject values
503 this.el.shadow_type = Gtk.ShadowType.IN;
504 var child_0 = new Xcls_view( _this );
506 this.el.add ( child_0.el );
510 this.el.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
513 // user defined functions
515 public class Xcls_view : Object
517 public WebKit.WebView el;
518 private Xcls_WindowRooView _this;
522 public string renderedData;
523 public bool refreshRequired;
524 public WebKit.WebInspector inspector;
527 public GLib.DateTime lastRedraw;
528 public string runhtml;
529 public bool pendingRedraw;
532 public Xcls_view(Xcls_WindowRooView _owner )
536 this.el = new WebKit.WebView();
539 this.renderedData = "";
540 this.refreshRequired = false;
543 this.lastRedraw = null;
545 this.pendingRedraw = false;
547 // set gobject values
552 // this may not work!?
553 var settings = this.el.get_settings();
554 settings.enable_developer_extras = true;
557 var fs= new FakeServer(this.el);
559 // this was an attempt to change the url perms.. did not work..
560 // settings.enable_file_access_from_file_uris = true;
561 // settings.enable_offline_web_application_cache - true;
562 // settings.enable_universal_access_from_file_uris = true;
569 // FIXME - base url of script..
570 // we need it so some of the database features work.
571 this.el.load_html( "Render not ready" ,
572 //fixme - should be a config option!
573 // or should we catch stuff and fix it up..
574 "http://localhost/app.Builder/"
578 //this.el.open('file:///' + __script_path__ + '/../builder.html');
583 Gtk.DestDefaults.MOTION | Gtk.DestDefaults.HIGHLIGHT,
584 null, // list of targets
585 Gdk.DragAction.COPY // what to do with data after dropped
588 // print("RB: TARGETS : " + LeftTree.atoms["STRING"]);
589 Gtk.drag_dest_set_target_list(this.el, this.get('/Window').targetList);
591 GLib.Timeout.add_seconds(1, () =>{
592 //print("run refresh?");
593 if (this.el == null) {
604 this.el.script_dialog.connect( (dialog) => {
605 if (this.el == null) {
609 var msg = dialog.get_message();
610 if (msg.length < 4) {
613 if (msg.substring(0,4) != "IPC:") {
616 var ar = msg.split(":", 3);
622 _this.file.saveHTML(ar[2]);
629 this.el.show.connect( ( ) => {
630 this.initInspector();;
632 this.el.drag_drop.connect( ( ctx, x, y,time, ud) => {
635 print("TARGET: drag-drop");
636 var is_valid_drop_site = true;
641 w, // will receive 'drag-data-received' signal
642 ctx, /* represents the current state of the DnD
643 this.get('/Window').atoms["STRING"], /* the target type we want
648 /* No target offered by source => error
651 return is_valid_drop_site;
654 this.el.load_changed.connect( (le) => {
655 if (le != WebKit.LoadEvent.FINISHED) {
658 if (this.runjs.length < 1) {
661 // this.el.run_javascript(this.runjs, null);
662 FakeServerCache.remove( this.runjs);
667 // user defined functions
668 public void reInit () {
670 // if this happens destroy the webkit..
672 this.el.stop_loading();
674 if (_this.viewbox.el.get_parent() == null) {
679 _this.viewbox.el.remove(_this.viewcontainer.el);
680 _this.paned.el.remove(_this.inspectorcontainer.el);
682 // destory seems to cause problems.
684 //_this.viewcontainer.el.destroy();
685 //_this.inspectorcontainer.el.destroy();
686 var inv =new Xcls_inspectorcontainer(_this);
688 _this.paned.el.pack2(inv.el,true,true);
692 var nv =new Xcls_viewcontainer(_this);
694 _this.viewbox.el.pack_end(nv.el,true,true,0);
699 //while(Gtk.events_pending ()) Gtk.main_iteration ();
700 //_this.view.renderJS(true);
701 _this.view.refreshRequired = true;
703 public void runRefresh ()
705 // this is run every 2 seconds from the init..
709 if (!this.refreshRequired) {
710 // print("no refresh required");
714 if (this.lastRedraw != null) {
715 // do not redraw if last redraw was less that 5 seconds ago.
716 if ((int64)(new DateTime.now_local()).difference(this.lastRedraw) < 5000 ) {
721 if (_this.file == null) {
726 this.refreshRequired = false;
727 // print("HTML RENDERING");
730 //this.get('/BottomPane').el.show();
731 //this.get('/BottomPane').el.set_current_page(2);// webkit inspector
732 _this.file.webkit_page_id = this.el.get_page_id();
734 var js = _this.file.toSourcePreview();
743 var project = _this.file.project;
745 //print (project.fn);
746 // set it to non-empty.
748 // runhtml = runhtml.length ? runhtml : '<script type="text/javascript"></script>';
751 // this.runhtml = this.runhtml || '';
754 // then we need to reload the browser using
755 // load_html_string..
757 // then trigger a redraw once it's loaded..
758 this.pendingRedraw = true;
760 var runhtml = "<script type=\"text/javascript\">\n" ;
764 GLib.FileUtils.get_contents(BuilderApplication.configDirectory() + "/resources/roo.builder.js", out builderhtml);
769 runhtml += builderhtml + "\n";
770 runhtml += "</script>\n" ;
772 // fix to make sure they are the same..
773 this.runhtml = project.runhtml;
774 // need to modify paths
777 var base_template = _this.file.project.base_template;
779 if (base_template.length > 0 && !FileUtils.test(
780 BuilderApplication.configDirectory() + "/resources/" + base_template, FileTest.EXISTS)
782 print("invalid base_template name - using default: %s\n", base_template);
787 GLib.FileUtils.get_contents(
788 BuilderApplication.configDirectory() + "/resources/" +
789 (base_template.length > 0 ? base_template : "roo.builder.html")
795 this.renderedData = js;
798 string js_src = js + "\n" +
799 "Roo.onReady(function() {\n" +
800 "if (" + _this.file.name +".show) " + _this.file.name +".show({});\n" +
801 "Roo.XComponent.build();\n" +
804 // print("render js: " + js);
806 // console.log('not loaded yet');
808 this.lastRedraw = new DateTime.now_local();
811 //this.runjs = js_src;
812 var fc = FakeServerCache.factory_with_data(js_src);
813 this.runjs = fc.fname;
815 var html = inhtml.replace("</head>", runhtml + this.runhtml +
816 "<script type=\"text/javascript\" src=\"xhttp://localhost" + fc.fname + "\"></script>" +
817 // "<script type=\"text/javascript\">\n" +
822 //print("LOAD HTML " + html);
824 var rootURL = _this.file.project.rootURL;
828 this.el.load_html( html ,
829 //fixme - should be a config option!
830 (rootURL.length > 0 ? rootURL : "xhttp://localhost/app.Builder.js/")
833 // force the inspector...
834 // this.initInspector();
836 // - no need for this, the builder javascript will call it when build is complete
837 //GLib.Timeout.add_seconds(1, () => {
838 // this.el.run_javascript("Builder.saveHTML()",null);
841 // print( "before render" + this.lastRedraw);
842 // print( "after render" + (new Date()));
845 public void initInspector () {
847 /* if (this.inspector == this.el.get_inspector()) {
848 this.inspector.show();
849 this.inspector.open_window();
850 print("init inspecter called, and inspector is the same as existing\n");
853 print("new inspector?\n");
855 this.inspector = this.el.get_inspector();
856 this.inspector.ref();
858 // got a new inspector...
860 this.inspector.open_window.connect(() => {
861 this.inspector = this.el.get_inspector();
862 print("inspector attach\n");
863 var wv = this.inspector.get_web_view();
865 print("got inspector web view\n");
867 var cn = _this.inspectorcontainer.el.get_child();
869 _this.inspectorcontainer.el.remove(cn);
872 _this.inspectorcontainer.el.add(wv);
875 //this.inspector.close();
877 //this.inspector = null;
885 this.inspector.closed.connect(() => {
886 print("inspector closed?!?");
887 // if this happens destroy the webkit..
889 this.el.stop_loading();
891 if (_this.viewbox.el.get_parent() == null) {
896 _this.viewbox.el.remove(_this.viewcontainer.el);
897 _this.el.remove(_this.inspectorcontainer.el);
899 // destory seems to cause problems.
901 //_this.viewcontainer.el.destroy();
902 //_this.inspectorcontainer.el.destroy();
905 var nv =new Xcls_viewcontainer(_this);
907 _this.viewbox.el.pack_end(nv.el,true,true,0);
909 var inv =new Xcls_inspectorcontainer(_this);
911 _this.el.pack2(inv.el,true,true);
915 //while(Gtk.events_pending ()) Gtk.main_iteration ();
916 //_this.view.renderJS(true);
917 _this.view.refreshRequired = true;
922 this.inspector.show();
924 public void renderJS (bool force) {
926 // this is the public redraw call..
927 // we refresh in a loop privately..
928 var autodraw = _this.AutoRedraw.el.active;
929 if (!autodraw && !force) {
930 print("Skipping redraw - no force, and autodraw off");
934 this.refreshRequired = true;
940 public class Xcls_inspectorcontainer : Object
942 public Gtk.ScrolledWindow el;
943 private Xcls_WindowRooView _this;
949 public Xcls_inspectorcontainer(Xcls_WindowRooView _owner )
952 _this.inspectorcontainer = this;
953 this.el = new Gtk.ScrolledWindow( null, null );
957 // set gobject values
958 this.el.shadow_type = Gtk.ShadowType.IN;
962 this.el.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
965 // user defined functions
969 public class Xcls_ScrolledWindow14 : Object
971 public Gtk.ScrolledWindow el;
972 private Xcls_WindowRooView _this;
978 public Xcls_ScrolledWindow14(Xcls_WindowRooView _owner )
981 this.el = new Gtk.ScrolledWindow( null, null );
985 // set gobject values
986 var child_0 = new Xcls_sourceview( _this );
988 this.el.add ( child_0.el );
991 // user defined functions
993 public class Xcls_sourceview : Object
995 public Gtk.SourceView el;
996 private Xcls_WindowRooView _this;
1000 public bool loading;
1001 public bool button_is_pressed;
1002 public string prop_selected;
1003 public bool key_is_pressed;
1004 public JsRender.Node? node_selected;
1005 public int editable_start_pos;
1008 public Xcls_sourceview(Xcls_WindowRooView _owner )
1011 _this.sourceview = this;
1012 this.el = new Gtk.SourceView();
1015 this.loading = true;
1016 this.button_is_pressed = false;
1017 this.prop_selected = "";
1018 this.key_is_pressed = false;
1019 this.node_selected = null;
1020 this.editable_start_pos = 0;
1022 // set gobject values
1023 this.el.editable = false;
1024 this.el.show_line_marks = true;
1025 this.el.show_line_numbers = true;
1026 var child_0 = new Xcls_buffer( _this );
1028 this.el.set_buffer ( child_0.el );
1034 var description = Pango.FontDescription.from_string("monospace");
1035 description.set_size(8000);
1036 this.el.override_font(description);
1038 this.loading = true;
1039 //var buf = this.el.get_buffer();
1040 //buf.notify.connect(this.onCursorChanged);
1044 var attrs = new Gtk.SourceMarkAttributes();
1045 var pink = Gdk.RGBA();
1046 pink.parse ( "pink");
1047 attrs.set_background ( pink);
1048 attrs.set_icon_name ( "process-stop");
1049 attrs.query_tooltip_text.connect(( mark) => {
1050 //print("tooltip query? %s\n", mark.name);
1054 this.el.set_mark_attributes ("ERR", attrs, 1);
1056 var wattrs = new Gtk.SourceMarkAttributes();
1057 var blue = Gdk.RGBA();
1058 blue.parse ( "#ABF4EB");
1059 wattrs.set_background ( blue);
1060 wattrs.set_icon_name ( "process-stop");
1061 wattrs.query_tooltip_text.connect(( mark) => {
1062 //print("tooltip query? %s\n", mark.name);
1066 this.el.set_mark_attributes ("WARN", wattrs, 1);
1070 var dattrs = new Gtk.SourceMarkAttributes();
1071 var purple = Gdk.RGBA();
1072 purple.parse ( "#EEA9FF");
1073 dattrs.set_background ( purple);
1074 dattrs.set_icon_name ( "process-stop");
1075 dattrs.query_tooltip_text.connect(( mark) => {
1076 //print("tooltip query? %s\n", mark.name);
1080 this.el.set_mark_attributes ("DEPR", dattrs, 1);
1083 var gattrs = new Gtk.SourceMarkAttributes();
1084 var grey = Gdk.RGBA();
1085 grey.parse ( "#ccc");
1086 gattrs.set_background ( grey);
1089 this.el.set_mark_attributes ("grey", gattrs, 1);
1099 this.el.button_release_event.connect( () => {
1101 print("BUTTON RELEASE EVENT\n");
1102 this.onCursorChanged();
1103 this.button_is_pressed = false;
1106 this.el.button_press_event.connect( () => {
1109 // if cursor postion is 'at start' of editing range,
1110 // and backspace is pressed...
1113 var buf = this.el.get_buffer();
1114 //print("cursor changed : %d\n", buf.cursor_position);
1116 buf.get_iter_at_offset(out cpos, buf.cursor_position);
1120 this.button_is_pressed = true;
1123 this.el.key_press_event.connect( (src, key) => {
1124 this.key_is_pressed = true;
1125 // is it ctrl-G -- find next?
1126 // which will will still ignore..
1128 if (key.str == "g" && key.state == Gdk.ModifierType.CONTROL_MASK) {
1129 this.key_is_pressed = false;
1131 print("KEY PRESS EVENT \n");
1132 this.onCursorChanged();
1135 this.el.key_release_event.connect( () => {
1136 this.key_is_pressed = false;
1141 // user defined functions
1142 public void onCursorChanged (/*ParamSpec ps*/) {
1144 if (!this.key_is_pressed && !this.button_is_pressed) {
1151 // if (ps.name != "cursor-position") {
1155 var buf = this.el.get_buffer();
1156 //print("cursor changed : %d\n", buf.cursor_position);
1158 buf.get_iter_at_offset(out cpos, buf.cursor_position);
1160 var ln = cpos.get_line();
1163 // --- select node at line....
1165 var node = _this.file.lineToNode(ln+1);
1168 print("can not find node\n");
1171 var prop = node.lineToProp(ln+1);
1172 print("prop : %s", prop == null ? "???" : prop);
1175 // ---------- this selects the tree's node...
1177 var ltree = _this.main_window.windowstate.left_tree;
1178 var tp = ltree.model.treePathFromNode(node);
1179 print("got tree path %s\n", tp);
1183 //print("changing cursor on tree..\n");
1187 // let's try allowing editing on the methods.
1188 // a little klunky at present..
1189 this.prop_selected = "";
1191 //see if we can find it..
1192 var kv = prop.split(":");
1195 //var k = prop.get_key(kv[1]);
1196 // fixme -- need to determine if it's an editable property...
1197 this.prop_selected = prop;
1199 } else if (kv[0] == "l") {
1200 this.prop_selected = prop;
1204 ltree.view.setCursor(tp, "editor");
1205 // ltree.view.el.set_cursor(new Gtk.TreePath.from_string(tp), null, false);
1206 this.nodeSelected(node,false);
1208 // scrolling is disabled... as node selection calls scroll 10ms after it changes.
1212 // highlight the node..
1214 public void clearGreySelection () {
1215 // clear all the marks..
1216 var sbuf = (Gtk.SourceBuffer)this.el.buffer;
1221 sbuf.get_bounds (out start, out end);
1222 sbuf.remove_source_marks (start, end, "grey");
1226 public void nodeSelected (JsRender.Node? sel, bool scroll ) {
1230 // this is connected in widnowstate
1234 while(Gtk.events_pending()) {
1235 Gtk.main_iteration();
1238 this.node_selected = sel;
1240 this.updateGreySelection(scroll);
1245 public string toString () {
1248 this.el.get_buffer().get_start_iter(out s);
1249 this.el.get_buffer().get_end_iter(out e);
1250 var ret = this.el.get_buffer().get_text(s,e,true);
1251 //print("TO STRING? " + ret);
1254 public void loadFile ( ) {
1255 this.loading = true;
1258 // get the cursor and scroll position....
1259 var buf = this.el.get_buffer();
1260 var cpos = buf.cursor_position;
1262 print("BEFORE LOAD cursor = %d\n", cpos);
1264 var vadj_pos = this.el.get_vadjustment().get_value();
1269 var sbuf = (Gtk.SourceBuffer) buf;
1273 if (_this.file == null || _this.file.xtype != "Roo") {
1274 print("xtype != Roo");
1275 this.loading = false;
1279 // get the string from the rendered tree...
1281 var str = _this.file.toSource();
1283 // print("setting str %d\n", str.length);
1284 buf.set_text(str, str.length);
1285 var lm = Gtk.SourceLanguageManager.get_default();
1287 //?? is javascript going to work as js?
1289 ((Gtk.SourceBuffer)(buf)) .set_language(lm.get_language(_this.file.language));
1295 sbuf.get_bounds (out start, out end);
1296 sbuf.remove_source_marks (start, end, null); // remove all marks..
1298 GLib.Timeout.add(500, () => {
1300 print("RESORTING cursor to = %d\n", cpos);
1301 Gtk.TextIter cpos_iter;
1302 buf.get_iter_at_offset(out cpos_iter, cpos);
1303 buf.place_cursor(cpos_iter);
1305 this.el.get_vadjustment().set_value(vadj_pos);;
1308 this.onCursorChanged();
1311 _this.buffer.checkSyntax();
1315 this.loading = false;
1316 _this.buffer.dirty = false;
1318 public void updateGreySelection (bool scroll) {
1319 var sel = this.node_selected;
1320 print("node selected\n");
1321 var buf = this.el.get_buffer();
1322 var sbuf = (Gtk.SourceBuffer) buf;
1325 this.clearGreySelection();
1330 print("no selected node\n");
1331 // no highlighting..
1335 print("highlight region %d to %d\n", sel.line_start,sel.line_end);
1337 sbuf.get_iter_at_line(out iter, sel.line_start);
1340 Gtk.TextIter cur_iter;
1341 sbuf.get_iter_at_offset(out cur_iter, sbuf.cursor_position);
1343 var cursor_at_line = cur_iter.get_line();
1346 //var cur_line = cur_iter.get_line();
1347 //if (cur_line > sel.line_start && cur_line < sel.line_end) {
1351 print("scrolling to node -- should occur on node picking.\n");
1352 this.el.scroll_to_iter(iter, 0.1f, true, 0.0f, 0.5f);
1355 var start_line = sel.line_start;
1356 var end_line = sel.line_end;
1359 this.el.editable = false;
1363 // now if we have selected a property...
1364 if (this.prop_selected.length> 0 ) {
1367 if (sel.getPropertyRange(this.prop_selected, out nstart, out nend) && nend > nstart) {
1368 start_line = nstart;
1370 this.el.editable = true;
1371 print("start line = %d, end line = %d\n", start_line, end_line);
1373 // see if we are 'right of ':'
1374 // get an iter for the start of the line.
1375 Gtk.TextIter start_line_iter,end_line_iter;
1376 this.el.buffer.get_iter_at_line(out start_line_iter, start_line -1);
1377 this.el.buffer.get_iter_at_line(out end_line_iter, start_line -1);
1382 if (end_line_iter.forward_to_line_end()) {
1383 var first_line = this.el.buffer.get_text(start_line_iter, end_line_iter, false);
1384 print("first line = %s\n", first_line);
1385 if (first_line.contains(":")) {
1386 colon_pos = start_line_iter.get_offset() + first_line.index_of(":") + 1;
1388 print("colon_pos = %d\n", colon_pos);
1389 Gtk.TextIter colon_iter;
1390 sbuf.get_iter_at_offset (out colon_iter, colon_pos);
1391 sbuf.create_source_mark(null, "active_text", colon_iter);
1394 print("is cursor at line? %d ?= %d\n", start_line -1 , cursor_at_line);
1395 if (start_line - 1 == cursor_at_line) {
1396 print("cursor is on current line.\n");
1397 var before_cursor_string = this.el.buffer.get_text(start_line_iter, cur_iter, false);
1398 print("before cursor string = %s\n", before_cursor_string);
1399 if (!before_cursor_string.contains(":")) {
1400 this.el.editable = false;
1407 print("propSelected = %s range %d -> %d\n", this.prop_selected, start_line, end_line);
1412 print("checking selection\n");
1415 // check selection - if it's out of 'bounds'
1416 if (this.el.editable && sbuf.get_has_selection()) {
1417 Gtk.TextIter sel_start_iter, sel_end_iter;
1418 sbuf.get_selection_bounds(out sel_start_iter, out sel_end_iter);
1420 if (sel_start_iter.get_line() < start_line || sel_end_iter.get_line() > end_line ||
1421 sel_start_iter.get_line() > end_line || sel_end_iter.get_line() < start_line ) {
1423 this.el.editable = false;
1425 if (colon_pos > 0 &&
1426 (sel_start_iter.get_offset() < colon_pos || sel_end_iter.get_offset() < colon_pos)
1429 this.el.editable = false;
1439 for (var i = 0; i < buf.get_line_count();i++) {
1440 if (i < (start_line -1) || i > (end_line -1)) {
1442 sbuf.get_iter_at_line(out iter, i);
1443 sbuf.create_source_mark(null, "grey", iter);
1448 if (scroll && (cursor_at_line > end_line || cursor_at_line < start_line)) {
1449 Gtk.TextIter cpos_iter;
1450 buf.get_iter_at_line(out cpos_iter, start_line);
1452 buf.place_cursor(cpos_iter);
1457 public void highlightErrorsJson (string type, Json.Object obj) {
1458 // this is a hook for the vala code - it has no value in javascript
1459 // as we only have one error ususally....
1467 public class Xcls_buffer : Object
1469 public Gtk.SourceBuffer el;
1470 private Xcls_WindowRooView _this;
1475 public int error_line;
1478 public Xcls_buffer(Xcls_WindowRooView _owner )
1481 _this.buffer = this;
1482 this.el = new Gtk.SourceBuffer( null );
1486 this.error_line = -1;
1488 // set gobject values
1491 this.el.changed.connect( () => {
1496 // _this.save_button.el.sensitive = true;
1497 ///?? has changed occured during loading?
1499 // only trigger this if
1504 if (_this.sourceview.loading) {
1508 print("- PREVIEW EDITOR CHANGED--");
1511 if (!this.checkSyntax()) {
1515 // what are we editing??
1516 if (null == _this.sourceview.node_selected || _this.sourceview.prop_selected.length < 1) {
1520 // find the colon on the first line...
1528 // user defined functions
1529 public bool highlightErrors ( Gee.HashMap<int,string> validate_res) {
1531 this.error_line = validate_res.size;
1533 if (this.error_line < 1) {
1536 var tlines = this.el.get_line_count ();
1538 var valiter = validate_res.map_iterator();
1539 while (valiter.next()) {
1541 // print("get inter\n");
1542 var eline = valiter.get_key();
1543 if (eline > tlines) {
1546 this.el.get_iter_at_line( out iter, eline);
1547 //print("mark line\n");
1548 this.el.create_source_mark(valiter.get_value(), "ERR", iter);
1552 public string toString () {
1556 this.el.get_start_iter(out s);
1557 this.el.get_end_iter(out e);
1558 var ret = this.el.get_text(s,e,true);
1559 //print("TO STRING? " + ret);
1562 public bool checkSyntax () {
1565 var str = this.toString();
1568 if (this.error_line > 0) {
1571 this.el.get_bounds (out start, out end);
1573 this.el.remove_source_marks (start, end, "WARN");
1574 this.el.remove_source_marks (start, end, "ERR");
1578 if (str.length < 1) {
1579 print("checkSyntax - empty string?\n");
1583 if (_this.file == null) {
1586 var p = Palete.factory(_this.file.xtype); // returns Roo | Gtk | PlainFile
1589 if (_this.file.language != "js") {
1590 return false; // fake syntax error.
1593 //Gee.HashMap<int,string> ret_x;
1595 return p.javascriptHasErrors(
1596 _this.main_window.windowstate,
1599 "file", //_this.ptype,