src/Builder4/WindowRooView.bjs
[app.Builder.js] / src / Builder4 / WindowRooView.vala
1 static Xcls_WindowRooView  _WindowRooView;
2
3 public class Xcls_WindowRooView : Object
4 {
5     public Gtk.Box el;
6     private Xcls_WindowRooView  _this;
7
8     public static Xcls_WindowRooView singleton()
9     {
10         if (_WindowRooView == null) {
11             _WindowRooView= new Xcls_WindowRooView();
12         }
13         return _WindowRooView;
14     }
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
26         // my vars (def)
27     public Gtk.Widget lastObj;
28     public int width;
29     public int last_search_end;
30     public Gtk.SourceSearchContext searchcontext;
31     public JsRender.JsRender file;
32     public int height;
33     public Xcls_MainWindow main_window;
34
35     // ctor
36     public Xcls_WindowRooView()
37     {
38         _this = this;
39         this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
40
41         // my vars (dec)
42         this.lastObj = null;
43         this.width = 0;
44         this.last_search_end = 0;
45         this.file = null;
46         this.height = 0;
47
48         // set gobject values
49         this.el.hexpand = true;
50         var child_0 = new Xcls_notebook( _this );
51         child_0.ref();
52         this.el.pack_start (  child_0.el , true,true,0 );
53     }
54
55     // user defined functions
56     public void scroll_to_line (int line) {
57        this.notebook.el.page = 1;// code preview...
58        
59        GLib.Timeout.add(500, () => {
60        
61        
62            
63            
64                   var buf = this.sourceview.el.get_buffer();
65          
66                 var sbuf = (Gtk.SourceBuffer) buf;
67     
68     
69                 Gtk.TextIter iter;   
70                 sbuf.get_iter_at_line(out iter,  line);
71                 this.sourceview.el.scroll_to_iter(iter,  0.1f, true, 0.0f, 0.5f);
72                 return false;
73         });   
74     
75        
76     }
77     public void createThumb () {
78         
79         
80         if (this.file == null) {
81             return;
82         }
83         if (this.notebook.el.page > 0 ) {
84             return;
85         }
86         
87         var filename = this.file.getIconFileName(false);
88         
89         var  win = this.el.get_parent_window();
90         var width = win.get_width();
91       //  var height = win.get_height();
92         try { 
93             Gdk.Pixbuf screenshot = Gdk.pixbuf_get_from_window(win, 0, 0, width, this.paned.el.position);
94             screenshot.save(filename,"png");
95         } catch(Error e) {
96             //noop
97         }
98     
99         
100          
101         
102          
103     }
104     public void loadFile (JsRender.JsRender file)
105     {
106         this.file = file;
107         this.view.renderJS(true);
108         this.notebook.el.page = 0;// gtk preview 
109         this.sourceview.loadFile();   
110         
111     }
112     public int search (string txt) {
113         this.notebook.el.page = 1;
114         var s = new Gtk.SourceSearchSettings();
115         var buf = (Gtk.SourceBuffer) this.sourceview.el.get_buffer();
116         this.searchcontext = new Gtk.SourceSearchContext(buf,s);
117         this.searchcontext.set_highlight(true);
118         s.set_search_text(txt);
119         
120         Gtk.TextIter beg, st,en;
121          
122         buf.get_start_iter(out beg);
123         this.searchcontext.forward(beg, out st, out en);
124         this.last_search_end  = 0;
125         return this.searchcontext.get_occurrences_count();
126     
127        
128     }
129     public void requestRedraw () {
130         this.view.renderJS(false);
131         this.sourceview.loadFile();   
132     }
133     public void forwardSearch (bool change_focus) {
134     
135         if (this.searchcontext == null) {
136                 return;
137         }
138         this.notebook.el.page = 1;
139         Gtk.TextIter beg, st,en, stl;
140         
141         var buf = this.sourceview.el.get_buffer();
142         buf.get_iter_at_offset(out beg, this.last_search_end);
143         if (!this.searchcontext.forward(beg, out st, out en)) {
144                 this.last_search_end = 0;
145         } else { 
146                 this.last_search_end = en.get_offset();
147                 if (change_focus) {
148                         this.sourceview.el.grab_focus();
149                 }
150                 buf.place_cursor(st);
151                 var ln = st.get_line();
152                 buf.get_iter_at_line(out stl,ln);
153                  
154                 this.sourceview.el.scroll_to_iter(stl,  0.0f, true, 0.0f, 0.5f);
155         }
156     
157     }
158     public class Xcls_notebook : Object
159     {
160         public Gtk.Notebook el;
161         private Xcls_WindowRooView  _this;
162
163
164             // my vars (def)
165
166         // ctor
167         public Xcls_notebook(Xcls_WindowRooView _owner )
168         {
169             _this = _owner;
170             _this.notebook = this;
171             this.el = new Gtk.Notebook();
172
173             // my vars (dec)
174
175             // set gobject values
176             var child_0 = new Xcls_label_preview( _this );
177             child_0.ref();
178             var child_1 = new Xcls_label_code( _this );
179             child_1.ref();
180             var child_2 = new Xcls_paned( _this );
181             child_2.ref();
182             this.el.add (  child_2.el  );
183             var child_3 = new Xcls_ScrolledWindow14( _this );
184             child_3.ref();
185             this.el.append_page (  child_3.el , _this.label_code.el );
186         }
187
188         // user defined functions
189     }
190     public class Xcls_label_preview : Object
191     {
192         public Gtk.Label el;
193         private Xcls_WindowRooView  _this;
194
195
196             // my vars (def)
197
198         // ctor
199         public Xcls_label_preview(Xcls_WindowRooView _owner )
200         {
201             _this = _owner;
202             _this.label_preview = this;
203             this.el = new Gtk.Label( "Preview" );
204
205             // my vars (dec)
206
207             // set gobject values
208         }
209
210         // user defined functions
211     }
212
213     public class Xcls_label_code : Object
214     {
215         public Gtk.Label el;
216         private Xcls_WindowRooView  _this;
217
218
219             // my vars (def)
220
221         // ctor
222         public Xcls_label_code(Xcls_WindowRooView _owner )
223         {
224             _this = _owner;
225             _this.label_code = this;
226             this.el = new Gtk.Label( "Preview Generated Code" );
227
228             // my vars (dec)
229
230             // set gobject values
231         }
232
233         // user defined functions
234     }
235
236     public class Xcls_paned : Object
237     {
238         public Gtk.Paned el;
239         private Xcls_WindowRooView  _this;
240
241
242             // my vars (def)
243
244         // ctor
245         public Xcls_paned(Xcls_WindowRooView _owner )
246         {
247             _this = _owner;
248             _this.paned = this;
249             this.el = new Gtk.Paned( Gtk.Orientation.VERTICAL );
250
251             // my vars (dec)
252
253             // set gobject values
254             var child_0 = new Xcls_viewbox( _this );
255             child_0.ref();
256             this.el.pack1 (  child_0.el , true,true );
257             var child_1 = new Xcls_inspectorcontainer( _this );
258             child_1.ref();
259             this.el.pack2 (  child_1.el , true,true );
260         }
261
262         // user defined functions
263     }
264     public class Xcls_viewbox : Object
265     {
266         public Gtk.Box el;
267         private Xcls_WindowRooView  _this;
268
269
270             // my vars (def)
271
272         // ctor
273         public Xcls_viewbox(Xcls_WindowRooView _owner )
274         {
275             _this = _owner;
276             _this.viewbox = this;
277             this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
278
279             // my vars (dec)
280
281             // set gobject values
282             this.el.homogeneous = false;
283             var child_0 = new Xcls_Box7( _this );
284             child_0.ref();
285             this.el.pack_start (  child_0.el , false,true,0 );
286             var child_1 = new Xcls_viewcontainer( _this );
287             child_1.ref();
288             this.el.pack_end (  child_1.el , true,true,0 );
289         }
290
291         // user defined functions
292     }
293     public class Xcls_Box7 : Object
294     {
295         public Gtk.Box el;
296         private Xcls_WindowRooView  _this;
297
298
299             // my vars (def)
300
301         // ctor
302         public Xcls_Box7(Xcls_WindowRooView _owner )
303         {
304             _this = _owner;
305             this.el = new Gtk.Box( Gtk.Orientation.HORIZONTAL, 0 );
306
307             // my vars (dec)
308
309             // set gobject values
310             this.el.homogeneous = true;
311             this.el.height_request = 20;
312             this.el.vexpand = false;
313             var child_0 = new Xcls_Button8( _this );
314             child_0.ref();
315             this.el.pack_start (  child_0.el , false,false,0 );
316             var child_1 = new Xcls_AutoRedraw( _this );
317             child_1.ref();
318             this.el.pack_start (  child_1.el , false,false,0 );
319             var child_2 = new Xcls_Button10( _this );
320             child_2.ref();
321             this.el.pack_start (  child_2.el , false,false,0 );
322         }
323
324         // user defined functions
325     }
326     public class Xcls_Button8 : Object
327     {
328         public Gtk.Button el;
329         private Xcls_WindowRooView  _this;
330
331
332             // my vars (def)
333
334         // ctor
335         public Xcls_Button8(Xcls_WindowRooView _owner )
336         {
337             _this = _owner;
338             this.el = new Gtk.Button();
339
340             // my vars (dec)
341
342             // set gobject values
343             this.el.label = "Redraw";
344
345             //listeners
346             this.el.clicked.connect( ( ) => {
347                 _this.view.renderJS(  true);
348             });
349         }
350
351         // user defined functions
352     }
353
354     public class Xcls_AutoRedraw : Object
355     {
356         public Gtk.CheckButton el;
357         private Xcls_WindowRooView  _this;
358
359
360             // my vars (def)
361
362         // ctor
363         public Xcls_AutoRedraw(Xcls_WindowRooView _owner )
364         {
365             _this = _owner;
366             _this.AutoRedraw = this;
367             this.el = new Gtk.CheckButton();
368
369             // my vars (dec)
370
371             // set gobject values
372             this.el.active = true;
373             this.el.label = "Auto Redraw On";
374
375             //listeners
376             this.el.toggled.connect( (state) => {
377                 this.el.set_label(this.el.active  ? "Auto Redraw On" : "Auto Redraw Off");
378             });
379         }
380
381         // user defined functions
382     }
383
384     public class Xcls_Button10 : Object
385     {
386         public Gtk.Button el;
387         private Xcls_WindowRooView  _this;
388
389
390             // my vars (def)
391
392         // ctor
393         public Xcls_Button10(Xcls_WindowRooView _owner )
394         {
395             _this = _owner;
396             this.el = new Gtk.Button();
397
398             // my vars (dec)
399
400             // set gobject values
401             this.el.label = "Full Redraw";
402
403             //listeners
404             this.el.clicked.connect( () => {
405               _this.view.redraws = 99;
406                 _this.view.el.web_context.clear_cache();  
407               //_this.view.renderJS(true);
408               FakeServerCache.clear();
409               _this.view.reInit();
410             
411             });
412         }
413
414         // user defined functions
415     }
416
417
418     public class Xcls_viewcontainer : Object
419     {
420         public Gtk.ScrolledWindow el;
421         private Xcls_WindowRooView  _this;
422
423
424             // my vars (def)
425
426         // ctor
427         public Xcls_viewcontainer(Xcls_WindowRooView _owner )
428         {
429             _this = _owner;
430             _this.viewcontainer = this;
431             this.el = new Gtk.ScrolledWindow( null, null );
432
433             // my vars (dec)
434
435             // set gobject values
436             this.el.shadow_type = Gtk.ShadowType.IN;
437             var child_0 = new Xcls_view( _this );
438             child_0.ref();
439             this.el.add (  child_0.el  );
440
441             // init method
442
443             this.el.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
444         }
445
446         // user defined functions
447     }
448     public class Xcls_view : Object
449     {
450         public WebKit.WebView el;
451         private Xcls_WindowRooView  _this;
452
453
454             // my vars (def)
455         public string renderedData;
456         public bool refreshRequired;
457         public WebKit.WebInspector inspector;
458         public string runjs;
459         public int redraws;
460         public GLib.DateTime lastRedraw;
461         public string runhtml;
462         public bool pendingRedraw;
463
464         // ctor
465         public Xcls_view(Xcls_WindowRooView _owner )
466         {
467             _this = _owner;
468             _this.view = this;
469             this.el = new WebKit.WebView();
470
471             // my vars (dec)
472             this.renderedData = "";
473             this.refreshRequired = false;
474             this.runjs = "";
475             this.redraws = 0;
476             this.lastRedraw = null;
477             this.runhtml = "";
478             this.pendingRedraw = false;
479
480             // set gobject values
481
482             // init method
483
484             {
485                 // this may not work!?
486                 var settings =  this.el.get_settings();
487                 settings.enable_developer_extras = true;
488                 
489                 
490                 var fs= new FakeServer(this.el);
491                 fs.ref();
492                 // this was an attempt to change the url perms.. did not work..
493                 // settings.enable_file_access_from_file_uris = true;
494                 // settings.enable_offline_web_application_cache - true;
495                 // settings.enable_universal_access_from_file_uris = true;
496                
497                  
498                 
499                 
500                 
501             
502                  // FIXME - base url of script..
503                  // we need it so some of the database features work.
504                 this.el.load_html( "Render not ready" , 
505                         //fixme - should be a config option!
506                         // or should we catch stuff and fix it up..
507                         "http://localhost/app.Builder/"
508                 );
509                     
510                     
511                //this.el.open('file:///' + __script_path__ + '/../builder.html');
512                 /*
513                 Gtk.drag_dest_set
514                 (
515                         this.el,              //
516                         Gtk.DestDefaults.MOTION  | Gtk.DestDefaults.HIGHLIGHT,
517                         null,            // list of targets
518                         Gdk.DragAction.COPY         // what to do with data after dropped 
519                 );
520                                         
521                // print("RB: TARGETS : " + LeftTree.atoms["STRING"]);
522                 Gtk.drag_dest_set_target_list(this.el, this.get('/Window').targetList);
523                 */
524                 GLib.Timeout.add_seconds(1,  ()  =>{
525                      //print("run refresh?");
526                      if (this.el == null) {
527                         return false;
528                      }
529                      this.runRefresh(); 
530                      return true;
531                  });
532                 
533                 
534             }
535
536             //listeners
537             this.el.script_dialog.connect( (dialog) => {
538                 if (this.el == null) {
539                     return true;
540                 }
541                 
542                  var msg = dialog.get_message();
543                  if (msg.length < 4) {
544                     return false;
545                  }
546                  if (msg.substring(0,4) != "IPC:") {
547                      return false;
548                  }
549                  var ar = msg.split(":", 3);
550                 if (ar.length < 3) {
551                     return false;
552                 }
553                 switch(ar[1]) {
554                     case "SAVEHTML":
555                         _this.file.saveHTML(ar[2]);
556                         return true;
557                     default:
558                         return false;
559                 }
560                 
561             });
562             this.el.show.connect( ( ) => {
563                 this.initInspector();;
564             });
565             this.el.drag_drop.connect( ( ctx, x, y,time, ud) => {
566                 return false;
567                 /*
568                 print("TARGET: drag-drop");
569                     var is_valid_drop_site = true;
570                     
571                      
572                     Gtk.drag_get_data
573                     (
574                             w,         // will receive 'drag-data-received' signal 
575                             ctx,        /* represents the current state of the DnD 
576                             this.get('/Window').atoms["STRING"],    /* the target type we want 
577                             time            /* time stamp 
578                     );
579                                     
580                                     
581                                     /* No target offered by source => error 
582                                    
583             
584                 return  is_valid_drop_site;
585                 */
586             });
587             this.el.load_changed.connect( (le) => {
588                 if (le != WebKit.LoadEvent.FINISHED) {
589                     return;
590                 }
591                 if (this.runjs.length < 1) {
592                     return;
593                 }
594               //  this.el.run_javascript(this.runjs, null);
595                  FakeServerCache.remove(    this.runjs);
596                 this.runjs = "";
597             });
598         }
599
600         // user defined functions
601         public void reInit () {
602            print("reInit?");
603                  // if this happens destroy the webkit..
604                  // recreate it..
605              this.el.stop_loading();
606                  
607              if (_this.viewbox.el.get_parent() == null) {
608                 return;
609              }
610                  
611                  
612             _this.viewbox.el.remove(_this.viewcontainer.el);
613             _this.paned.el.remove(_this.inspectorcontainer.el);        
614                  
615                  // destory seems to cause problems.
616                  //this.el.destroy();
617                 //_this.viewcontainer.el.destroy();
618                  //_this.inspectorcontainer.el.destroy();
619              var  inv =new Xcls_inspectorcontainer(_this);
620               inv.ref();
621               _this.paned.el.pack2(inv.el,true,true);
622               
623               
624              this.el = null;         
625              var nv =new Xcls_viewcontainer(_this);
626              nv.ref();
627              _this.viewbox.el.pack_end(nv.el,true,true,0);
628                  
629                  
630              inv.el.show_all();
631              nv.el.show_all();
632                  //while(Gtk.events_pending ()) Gtk.main_iteration ();
633                  //_this.view.renderJS(true); 
634              _this.view.refreshRequired  = true;
635         }
636         public void runRefresh () 
637         {
638             // this is run every 2 seconds from the init..
639         
640           
641             
642             if (!this.refreshRequired) {
643                // print("no refresh required");
644                 return;
645             }
646         
647             if (this.lastRedraw != null) {
648                // do not redraw if last redraw was less that 5 seconds ago.
649                if ((int64)(new DateTime.now_local()).difference(this.lastRedraw) < 5000 ) {
650                     return;
651                 }
652             }
653             
654             if (_this.file == null) {
655                 return;
656             }
657             
658             
659              this.refreshRequired = false;
660            //  print("HTML RENDERING");
661              
662              
663              //this.get('/BottomPane').el.show();
664              //this.get('/BottomPane').el.set_current_page(2);// webkit inspector
665             _this.file.webkit_page_id  = this.el.get_page_id();
666             
667             var js = _this.file.toSourcePreview();
668         
669             if (js.length < 1) {
670                 print("no data");
671                 return;
672             }
673         //    var  data = js[0];
674             this.redraws++;
675           
676             var project = _this.file.project;  
677         
678              //print (project.fn);
679              // set it to non-empty.
680              
681         //     runhtml = runhtml.length ?  runhtml : '<script type="text/javascript"></script>'; 
682         
683         
684         //   this.runhtml  = this.runhtml || '';
685          
686          
687             // then we need to reload the browser using
688             // load_html_string..
689         
690             // then trigger a redraw once it's loaded..
691             this.pendingRedraw = true;
692         
693             var runhtml = "<script type=\"text/javascript\">\n" ;
694             string builderhtml;
695             
696             try {
697                 GLib.FileUtils.get_contents(BuilderApplication.configDirectory() + "/resources/roo.builder.js", out builderhtml);
698             } catch (Error e) {
699                 builderhtml = "";
700             }
701         
702             runhtml += builderhtml + "\n";
703             runhtml += "</script>\n" ;
704         
705             // fix to make sure they are the same..
706             this.runhtml = project.runhtml;
707             // need to modify paths
708         
709             string inhtml;
710             var base_template = _this.file.project.base_template;
711             
712             if (base_template.length > 0 && !FileUtils.test(
713                 BuilderApplication.configDirectory() + "/resources/" +  base_template, FileTest.EXISTS)  
714                 ) {
715                    print("invalid base_template name - using default:  %s\n", base_template);
716                    base_template = "";
717             
718             }
719             try {
720                 GLib.FileUtils.get_contents(
721                     BuilderApplication.configDirectory() + "/resources/" + 
722                         (base_template.length > 0 ? base_template :  "roo.builder.html")
723                         , out inhtml);
724             
725             } catch (Error e) {
726                 inhtml = "";
727             }    
728             this.renderedData = js;
729         
730         
731             string js_src = js + "\n" +
732                 "Roo.onReady(function() {\n" +
733                 "if (" + _this.file.name +".show) " +  _this.file.name +".show({});\n" +
734                 "Roo.XComponent.build();\n" +
735                 "});\n";
736                 
737            // print("render js: " + js);
738             //if (!this.ready) {
739           //      console.log('not loaded yet');
740             //}
741             this.lastRedraw = new DateTime.now_local();
742         
743         
744             //this.runjs = js_src;
745             var fc =    FakeServerCache.factory_with_data(js_src);
746             this.runjs = fc.fname;
747             
748                 var html = inhtml.replace("</head>", runhtml + this.runhtml + 
749                     "<script type=\"text/javascript\" src=\"xhttp://localhost" + fc.fname + "\"></script>" +   
750                       //  "<script type=\"text/javascript\">\n" +
751                       //  js_src + "\n" + 
752                       //  "</script>" + 
753                                 
754                 "</head>");
755                 //print("LOAD HTML " + html);
756                 
757                  var rootURL = _this.file.project.rootURL;
758            
759                 
760                 
761                 this.el.load_html( html , 
762                     //fixme - should be a config option!
763                     (rootURL.length > 0 ? rootURL : "xhttp://localhost/app.Builder.js/")
764                 );
765                 
766             // force the inspector...        
767                //   this.initInspector();
768                 
769                 // - no need for this, the builder javascript will call it when build is complete
770                 //GLib.Timeout.add_seconds(1, () => {
771                 //    this.el.run_javascript("Builder.saveHTML()",null);
772                 //    return false;
773                 //});
774         //     print( "before render" +    this.lastRedraw);
775         //    print( "after render" +    (new Date()));
776             
777         }
778         public void initInspector () {
779             
780            /* if (this.inspector == this.el.get_inspector()) {
781                 this.inspector.show();
782                 this.inspector.open_window();        
783                 print("init inspecter called, and inspector is the same as existing\n");
784                 return;
785             }
786             print("new inspector?\n");
787         */
788             this.inspector = this.el.get_inspector();
789             this.inspector.ref();
790             
791             // got a new inspector...
792                 
793             this.inspector.open_window.connect(() => {
794                  this.inspector = this.el.get_inspector();
795                 print("inspector attach\n");
796                 var wv = this.inspector.get_web_view();
797                 if (wv != null) {
798                     print("got inspector web view\n");
799                     
800                     var cn = _this.inspectorcontainer.el.get_child();
801                     if (cn != null) {
802                          _this.inspectorcontainer.el.remove(cn);
803                      }
804                     
805                     _this.inspectorcontainer.el.add(wv);
806                     wv.show();
807                 } else {
808                     //this.inspector.close();
809                     
810                     //this.inspector = null;
811                    
812          
813                 }
814                 return true;
815                
816             });
817             /*
818             this.inspector.closed.connect(() => {
819                  print("inspector closed?!?");
820                  // if this happens destroy the webkit..
821                  // recreate it..
822                  this.el.stop_loading();
823                  
824                  if (_this.viewbox.el.get_parent() == null) {
825                     return;
826                  }
827                  
828                  
829                 _this.viewbox.el.remove(_this.viewcontainer.el);
830                 _this.el.remove(_this.inspectorcontainer.el);        
831                  
832                  // destory seems to cause problems.
833                  //this.el.destroy();
834                 //_this.viewcontainer.el.destroy();
835                  //_this.inspectorcontainer.el.destroy();
836         
837                  this.el = null;         
838                  var nv =new Xcls_viewcontainer(_this);
839                  nv.ref();
840                  _this.viewbox.el.pack_end(nv.el,true,true,0);
841                  
842                   var  inv =new Xcls_inspectorcontainer(_this);
843                   inv.ref();
844                   _this.el.pack2(inv.el,true,true);
845                  
846                  inv.el.show_all();
847                  nv.el.show_all();
848                  //while(Gtk.events_pending ()) Gtk.main_iteration ();
849                  //_this.view.renderJS(true); 
850                  _this.view.refreshRequired  = true;
851                
852             }); 
853             */
854             
855             this.inspector.show();
856         }
857         public void renderJS (bool force) {
858         
859             // this is the public redraw call..
860             // we refresh in a loop privately..
861             var autodraw = _this.AutoRedraw.el.active;
862             if (!autodraw && !force) {
863                 print("Skipping redraw - no force, and autodraw off");
864                 return;
865             }
866              
867             this.refreshRequired  = true;
868         }
869     }
870
871
872
873     public class Xcls_inspectorcontainer : Object
874     {
875         public Gtk.ScrolledWindow el;
876         private Xcls_WindowRooView  _this;
877
878
879             // my vars (def)
880
881         // ctor
882         public Xcls_inspectorcontainer(Xcls_WindowRooView _owner )
883         {
884             _this = _owner;
885             _this.inspectorcontainer = this;
886             this.el = new Gtk.ScrolledWindow( null, null );
887
888             // my vars (dec)
889
890             // set gobject values
891             this.el.shadow_type = Gtk.ShadowType.IN;
892
893             // init method
894
895             this.el.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
896         }
897
898         // user defined functions
899     }
900
901
902     public class Xcls_ScrolledWindow14 : Object
903     {
904         public Gtk.ScrolledWindow el;
905         private Xcls_WindowRooView  _this;
906
907
908             // my vars (def)
909
910         // ctor
911         public Xcls_ScrolledWindow14(Xcls_WindowRooView _owner )
912         {
913             _this = _owner;
914             this.el = new Gtk.ScrolledWindow( null, null );
915
916             // my vars (dec)
917
918             // set gobject values
919             var child_0 = new Xcls_sourceview( _this );
920             child_0.ref();
921             this.el.add (  child_0.el  );
922         }
923
924         // user defined functions
925     }
926     public class Xcls_sourceview : Object
927     {
928         public Gtk.SourceView el;
929         private Xcls_WindowRooView  _this;
930
931
932             // my vars (def)
933         public bool loading;
934         public bool allow_node_scroll;
935         public string propSelected;
936
937         // ctor
938         public Xcls_sourceview(Xcls_WindowRooView _owner )
939         {
940             _this = _owner;
941             _this.sourceview = this;
942             this.el = new Gtk.SourceView();
943
944             // my vars (dec)
945             this.loading = true;
946             this.allow_node_scroll = true;
947             this.propSelected = "";
948
949             // set gobject values
950             this.el.editable = false;
951             this.el.show_line_marks = true;
952             this.el.show_line_numbers = true;
953
954             // init method
955
956             {
957                
958                 var description =   Pango.FontDescription.from_string("monospace");
959                 description.set_size(8000);
960                 this.el.override_font(description);
961             
962                 this.loading = true;
963                 //var buf = this.el.get_buffer();
964                 //buf.notify.connect(this.onCursorChanged);
965               
966               
967               
968                 var attrs = new Gtk.SourceMarkAttributes();
969                 var  pink =   Gdk.RGBA();
970                 pink.parse ( "pink");
971                 attrs.set_background ( pink);
972                 attrs.set_icon_name ( "process-stop");    
973                 attrs.query_tooltip_text.connect(( mark) => {
974                     //print("tooltip query? %s\n", mark.name);
975                     return mark.name;
976                 });
977                 
978                 this.el.set_mark_attributes ("ERR", attrs, 1);
979                 
980                  var wattrs = new Gtk.SourceMarkAttributes();
981                 var  blue =   Gdk.RGBA();
982                 blue.parse ( "#ABF4EB");
983                 wattrs.set_background ( blue);
984                 wattrs.set_icon_name ( "process-stop");    
985                 wattrs.query_tooltip_text.connect(( mark) => {
986                     //print("tooltip query? %s\n", mark.name);
987                     return mark.name;
988                 });
989                 
990                 this.el.set_mark_attributes ("WARN", wattrs, 1);
991                 
992              
993                 
994                  var dattrs = new Gtk.SourceMarkAttributes();
995                 var  purple =   Gdk.RGBA();
996                 purple.parse ( "#EEA9FF");
997                 dattrs.set_background ( purple);
998                 dattrs.set_icon_name ( "process-stop");    
999                 dattrs.query_tooltip_text.connect(( mark) => {
1000                     //print("tooltip query? %s\n", mark.name);
1001                     return mark.name;
1002                 });
1003                 
1004                 this.el.set_mark_attributes ("DEPR", dattrs, 1);
1005                 
1006                 
1007                 var gattrs = new Gtk.SourceMarkAttributes();
1008                 var  grey =   Gdk.RGBA();
1009                 grey.parse ( "#ccc");
1010                 gattrs.set_background ( grey);
1011              
1012                 
1013                 this.el.set_mark_attributes ("grey", gattrs, 1);
1014                 
1015                 
1016                 
1017                 
1018                 
1019                 
1020             }
1021
1022             //listeners
1023             this.el.button_release_event.connect( () => {
1024                 this.onCursorChanged();
1025             
1026                 return false;
1027             });
1028         }
1029
1030         // user defined functions
1031         public void onCursorChanged (/*ParamSpec ps*/) {
1032                   if (this.loading) {
1033                     return;
1034                 }
1035                // if (ps.name != "cursor-position") {
1036                //     return;
1037                // }
1038         
1039                 var buf = this.el.get_buffer();
1040                 print("cursor changed : %d\n", buf.cursor_position);
1041                 Gtk.TextIter cpos;
1042                 buf.get_iter_at_offset(out cpos, buf.cursor_position);
1043                 
1044                 var ln = cpos.get_line();
1045                         print("cursor changed line : %d\n", ln);
1046                 var node = _this.file.lineToNode(ln+1);
1047          
1048                 if (node == null) {
1049                     print("can not find node\n");
1050                     return;
1051                 }
1052                 var prop = node.lineToProp(ln+1);
1053                 print("prop : %s", prop == null ? "???" : prop);
1054                 
1055                 
1056                 
1057                 
1058                 
1059                 
1060                 var ltree = _this.main_window.windowstate.left_tree;
1061                 var tp = ltree.model.treePathFromNode(node);
1062                 print("got tree path %s\n", tp);
1063                 if (tp != "") {
1064                        this.allow_node_scroll = false; /// block node scrolling..
1065                        
1066                        
1067                         //print("changing cursor on tree..\n");
1068                        
1069          
1070                     
1071                     // let's try allowing editing on the methods.
1072                     // a little klunky at present..
1073                     this.propSelected = "";
1074                     if (prop != null) {
1075                                 //see if we can find it..
1076                                 var kv = prop.split(":");
1077                                 if (kv[0] == "p") {
1078                                 
1079                                         //var k = prop.get_key(kv[1]);
1080                                         // fixme -- need to determine if it's an editable property...
1081                                         this.propSelected = prop;
1082                                         
1083                                 } else if (kv[0] == "l") {
1084                                          this.propSelected = prop;
1085                                         
1086                                 }
1087                     }
1088                     ltree.view.setCursor(tp, "editor");
1089                    // ltree.view.el.set_cursor(new Gtk.TreePath.from_string(tp), null, false); 
1090                    this.nodeSelected(node,false);
1091                     
1092                     // scrolling is disabled... as node selection calls scroll 10ms after it changes.
1093                     GLib.Timeout.add_full(GLib.Priority.DEFAULT,100 , () => {
1094                             this.allow_node_scroll = true;
1095                             return false;
1096                     });
1097                 }
1098                 
1099                 // highlight the node..
1100         }
1101         public void nodeSelected (JsRender.Node? sel, bool scroll ) {
1102           
1103             
1104           
1105             // this is connected in widnowstate
1106             print("node selected\n");
1107             var buf = this.el.get_buffer();
1108          
1109             var sbuf = (Gtk.SourceBuffer) buf;
1110         
1111            
1112             while(Gtk.events_pending()) {
1113                 Gtk.main_iteration();
1114             }
1115             
1116            
1117             // clear all the marks..
1118             Gtk.TextIter start;
1119             Gtk.TextIter end;     
1120                 
1121             sbuf.get_bounds (out start, out end);
1122             sbuf.remove_source_marks (start, end, "grey");
1123             
1124             
1125              if (sel == null) {
1126                      print("no selected node\n");
1127                 // no highlighting..
1128                 return;
1129             }
1130             
1131             print("highlight region %d to %d\n", sel.line_start,sel.line_end);
1132             Gtk.TextIter iter;   
1133             sbuf.get_iter_at_line(out iter,  sel.line_start);
1134             
1135             
1136             Gtk.TextIter cur_iter;
1137             sbuf.get_iter_at_offset(out cur_iter, sbuf.cursor_position);
1138             
1139             //var cur_line = cur_iter.get_line();
1140             //if (cur_line > sel.line_start && cur_line < sel.line_end) {
1141             
1142             //} else {
1143             if (scroll) {
1144                          
1145                 this.el.scroll_to_iter(iter,  0.1f, true, 0.0f, 0.5f);
1146                 }
1147             
1148             var start_line = sel.line_start;
1149             var end_line = sel.line_end;
1150             
1151             
1152             this.el.editable = false;
1153             // now if we have selected a property...
1154             if (this.propSelected.length> 0 ) {
1155         
1156                         int nstart, nend;
1157                         if (sel.getPropertyRange(this.propSelected, out nstart, out nend) && nend > nstart) {
1158                                 start_line = nstart;
1159                                 end_line = nend;
1160                                 this.el.editable = true;
1161                         }
1162                         print("propSelected = %s range  %d -> %d\n", this.propSelected, nstart, nend);          
1163                         
1164                         
1165             }
1166             
1167             // check selection - if it's out of 'bounds'
1168             if (this.el.editable && sbuf.get_has_selection()) {
1169                         Gtk.TextIter sel_start_iter, sel_end_iter;
1170                         sbuf.get_selection_bounds(out sel_start_iter, out sel_end_iter);
1171                         
1172                         if (sel_start_iter.get_line() < start_line || sel_end_iter.get_line() > end_line ||
1173                                 sel_start_iter.get_line() > end_line   || sel_end_iter.get_line() < start_line                  ) {
1174                                 // save?
1175                                 this.el.editable = false;
1176                         }
1177             
1178             }
1179             
1180             
1181             
1182             
1183             for (var i = 0; i < buf.get_line_count();i++) {
1184                 if (i < (start_line -1) || i > (end_line -1)) {
1185                    
1186                     sbuf.get_iter_at_line(out iter, i);
1187                     sbuf.create_source_mark(null, "grey", iter);
1188                     
1189                 }
1190             
1191             }
1192             
1193         
1194         }
1195         public string toString () {
1196            Gtk.TextIter s;
1197             Gtk.TextIter e;
1198             this.el.get_buffer().get_start_iter(out s);
1199             this.el.get_buffer().get_end_iter(out e);
1200             var ret = this.el.get_buffer().get_text(s,e,true);
1201             //print("TO STRING? " + ret);
1202             return ret;
1203         }
1204         public void loadFile ( ) {
1205             this.loading = true;
1206             
1207             
1208             // get the cursor and scroll position....
1209             var buf = this.el.get_buffer();
1210                 var cpos = buf.cursor_position;
1211             
1212         
1213            
1214             var vadj = this.el.get_vadjustment();
1215            
1216             
1217             var buf = this.el.get_buffer();
1218             buf.set_text("",0);
1219             var sbuf = (Gtk.SourceBuffer) buf;
1220         
1221             
1222         
1223             if (_this.file == null || _this.file.xtype != "Roo") {
1224                 print("xtype != Roo");
1225                 this.loading = false;
1226                 return;
1227             }
1228             
1229             // get the string from the rendered tree...
1230              
1231              var str = _this.file.toSource();
1232              
1233         //    print("setting str %d\n", str.length);
1234             buf.set_text(str, str.length);
1235             var lm = Gtk.SourceLanguageManager.get_default();
1236              
1237             //?? is javascript going to work as js?
1238             
1239             ((Gtk.SourceBuffer)(buf)) .set_language(lm.get_language(_this.file.language));
1240           
1241             
1242             Gtk.TextIter start;
1243             Gtk.TextIter end;     
1244                 
1245             sbuf.get_bounds (out start, out end);
1246             sbuf.remove_source_marks (start, end, null); // remove all marks..
1247             
1248             Gtk.TextIter cpos_iter;
1249             buf.get_iter_at_offset(out cpos_iter, cpos);
1250             buf.place_cursor(cpos_iter); 
1251             
1252             this.el.set_vadjustment(vadj);
1253             
1254             
1255             
1256             this.loading = false; 
1257         }
1258         public void highlightErrorsJson (string type, Json.Object obj) {
1259               Gtk.TextIter start;
1260              Gtk.TextIter end;   
1261              
1262              var buf =  this.el.get_buffer();
1263                var sbuf = (Gtk.SourceBuffer)buf;
1264                 buf.get_bounds (out start, out end);
1265                 
1266                 sbuf.remove_source_marks (start, end, type);
1267                          
1268              
1269              // we should highlight other types of errors..
1270             
1271             if (!obj.has_member(type)) {
1272                 print("Return has no errors\n");
1273                 return  ;
1274             }
1275             var err = obj.get_object_member(type);
1276             
1277             if (_this.file == null) { 
1278                 return; // just in case the file has not loaded yet?
1279             }
1280          
1281         
1282             var valafn = "";
1283               try {             
1284                    var  regex = new Regex("\\.bjs$");
1285                 
1286                  
1287                     valafn = regex.replace(_this.file.path,_this.file.path.length , 0 , ".vala");
1288                  } catch (GLib.RegexError e) {
1289                     return;
1290                 }   
1291         
1292            if (!err.has_member(valafn)) {
1293                 print("File path has no errors\n");
1294                 return  ;
1295             }
1296             var lines = err.get_object_member(valafn);
1297             
1298            
1299             
1300             var tlines = buf.get_line_count () +1;
1301             
1302             lines.foreach_member((obj, line, node) => {
1303                 
1304                      Gtk.TextIter iter;
1305             //        print("get inter\n");
1306                     var eline = int.parse(line) -1  ;
1307                     print("GOT ERROR on line %s -- converted to %d\n", line,eline);
1308                     
1309                     
1310                     if (eline > tlines || eline < 0) {
1311                         return;
1312                     }
1313                     sbuf.get_iter_at_line( out iter, eline);
1314                     //print("mark line\n");
1315                     var msg  = type + " on line: %d - %s".printf(eline+1, valafn);
1316                     var ar = lines.get_array_member(line);
1317                     for (var i = 0 ; i < ar.get_length(); i++) {
1318                             msg += (msg.length > 0) ? "\n" : "";
1319                             msg += ar.get_string_element(i);
1320                     }
1321                     
1322                     
1323                     sbuf.create_source_mark(msg, type, iter);
1324                 } );
1325                 return  ;
1326             
1327          
1328         
1329         
1330         }
1331     }
1332
1333
1334
1335 }