Merge branch 'master' of http://git.roojs.com/roobuilder
[roobuilder] / src / Builder4 / GladeuiView.vala
1 static Xcls_GladeuiView  _GladeuiView;
2
3 public class Xcls_GladeuiView : Object
4 {
5     public Gtk.Box el;
6     private Xcls_GladeuiView  _this;
7
8     public static Xcls_GladeuiView singleton()
9     {
10         if (_GladeuiView == null) {
11             _GladeuiView= new Xcls_GladeuiView();
12         }
13         return _GladeuiView;
14     }
15     public Xcls_notebook notebook;
16     public Xcls_label_preview label_preview;
17     public Xcls_label_code label_code;
18     public Xcls_designview designview;
19     public Xcls_sourceview sourceview;
20
21         // my vars (def)
22     public Gtk.Widget lastObj;
23     public Xcls_MainWindow main_window;
24     public int last_search_end;
25     public Gtk.SourceSearchContext searchcontext;
26     public int width;
27     public JsRender.JsRender file;
28     public int height;
29
30     // ctor
31     public Xcls_GladeuiView()
32     {
33         _this = this;
34         this.el = new Gtk.Box( Gtk.Orientation.VERTICAL, 0 );
35
36         // my vars (dec)
37         this.lastObj = null;
38         this.last_search_end = 0;
39         this.width = 0;
40         this.file = null;
41         this.height = 0;
42
43         // set gobject values
44         this.el.hexpand = true;
45         this.el.vexpand = true;
46         var child_0 = new Xcls_Button2( _this );
47         child_0.ref();
48         this.el.append(  child_0.el );
49         var child_1 = new Xcls_GestureClick5( _this );
50         child_1.ref();
51         this.el.add_controller (  child_1.el  );
52         var child_2 = new Xcls_ColumnView6( _this );
53         child_2.ref();
54         this.el.append(  child_2.el );
55         var child_3 = new Xcls_notebook( _this );
56         child_3.ref();
57         this.el.pack_start (  child_3.el , true,true,0 );
58
59         //listeners
60         this.el.size_allocate.connect( (aloc) => {
61          
62             this.width = aloc.width;
63             this.height =aloc.height;
64         });
65     }
66
67     // user defined functions
68     public void loadFile (JsRender.JsRender file)
69     {
70         
71     
72         this.file = file;
73         
74     
75             // clear existing elements from project?
76             
77             var  p = this.designview.el.get_project();
78             var    li = p.get_objects().copy();
79             // should remove all..
80             for (var i =0;    i < li.length(); i++) {   
81                 p.remove_object(li.nth_data(i)); 
82             }
83     
84             if (file.tree == null) {
85                 return;
86             }
87     
88     //        print("%s\n",tf.tree.toJsonString());
89         var x =  new JsRender.NodeToGlade((Project.Gtk) file.project, file.tree,  null);
90         Glade.App.set_window(_this.main_window.el); // see if setting it again forces it to go to the irght locations.
91          
92     FileIOStream iostream;
93         var  f = File.new_tmp ("tpl-XXXXXX.glade", out iostream);
94         var ostream = iostream.output_stream;
95         var dostream = new DataOutputStream (ostream);
96         dostream.put_string (x.munge());
97         this.el.show();
98          print("LOADING %s\n",f.get_path ());
99           //p.load_from_file(f.get_path ());
100             
101          p.load_from_file("/tmp/glade.xml");
102     
103     }
104     public void initGlade () {
105          _this.designview =  new Xcls_designview( _this );
106          
107          var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL,0);
108          
109          _this.notebook.el.append_page(box, _this.label_preview.el);
110              Glade.App.set_window(this.main_window.el);
111         // var  pal = new Glade.Palette();
112         //var ins = new Glade.Inspector();
113     
114          box.pack_start(_this.designview.el);
115         // box.pack_start(pal);
116          //box.pack_start(ins);
117           // pal.show();
118        // ins.show();
119         _this.designview.el.show();
120          box.show_all();         
121          
122     }
123     public void forwardSearch (bool change_focus) {
124     
125         if (this.searchcontext == null) {
126                 return;
127         }
128         this.notebook.el.page = 1;
129         Gtk.TextIter beg, st,en, stl;
130         
131         var buf = this.sourceview.el.get_buffer();
132         buf.get_iter_at_offset(out beg, this.last_search_end);
133         if (!this.searchcontext.forward(beg, out st, out en)) {
134                 this.last_search_end = 0;
135         } else { 
136                 this.last_search_end = en.get_offset();
137                 if (change_focus) {
138                         this.sourceview.el.grab_focus();        
139                 }
140                 buf.place_cursor(st);
141                 var ln = st.get_line();
142                 buf.get_iter_at_line(out stl,ln);
143                  
144                 this.sourceview.el.scroll_to_iter(stl,  0.0f, true, 0.0f, 0.5f);
145         }
146     
147     }
148     public int search (string txt) {
149         this.notebook.el.page = 1;
150         var s = new Gtk.SourceSearchSettings();
151         var buf = (Gtk.SourceBuffer) this.sourceview.el.get_buffer();
152         this.searchcontext = new Gtk.SourceSearchContext(buf,s);
153         this.searchcontext.set_highlight(true);
154         s.set_search_text(txt);
155         
156         Gtk.TextIter beg, st,en;
157          
158         buf.get_start_iter(out beg);
159         this.searchcontext.forward(beg, out st, out en);
160         this.last_search_end  = 0;
161         return this.searchcontext.get_occurrences_count();
162     
163        
164     }
165     public void createThumb () {
166         
167         
168         if (this.file == null) {
169             return;
170         }
171         // only screenshot the gtk preview..
172         if (this.notebook.el.page > 0 ) {
173             return;
174         }
175         
176         
177         var filename = this.file.getIconFileName(false);
178         
179         var  win = this.designview.el.get_parent_window();
180         var width = win.get_width();
181         var height = win.get_height();
182         try {
183              Gdk.Pixbuf screenshot = Gdk.pixbuf_get_from_window(win, 0, 0, width, height); // this.el.position?
184              screenshot.save(filename,"png");
185         } catch (Error e) {
186             
187         }
188     
189         
190         
191         
192     
193     
194         
195          
196     }
197     public void scroll_to_line (int line) {
198        this.notebook.el.page = 1;// code preview...
199        
200        GLib.Timeout.add(500, () => {
201        
202        
203            
204            
205                   var buf = this.sourceview.el.get_buffer();
206          
207                 var sbuf = (Gtk.SourceBuffer) buf;
208     
209     
210                 Gtk.TextIter iter;   
211                 sbuf.get_iter_at_line(out iter,  line);
212                 this.sourceview.el.scroll_to_iter(iter,  0.1f, true, 0.0f, 0.5f);
213                 return false;
214         });   
215     
216        
217     }
218     public class Xcls_Button2 : Object
219     {
220         public Gtk.Button el;
221         private Xcls_GladeuiView  _this;
222
223
224             // my vars (def)
225
226         // ctor
227         public Xcls_Button2(Xcls_GladeuiView _owner )
228         {
229             _this = _owner;
230             this.el = new Gtk.Button();
231
232             // my vars (dec)
233
234             // set gobject values
235             var child_0 = new Xcls_Box3( _this );
236             child_0.ref();
237             this.el.child = child_0.el;
238             var child_1 = new Xcls_GestureClick4( _this );
239             child_1.ref();
240             this.el.add_controller(  child_1.el );
241         }
242
243         // user defined functions
244     }
245     public class Xcls_Box3 : Object
246     {
247         public Gtk.Box el;
248         private Xcls_GladeuiView  _this;
249
250
251             // my vars (def)
252
253         // ctor
254         public Xcls_Box3(Xcls_GladeuiView _owner )
255         {
256             _this = _owner;
257             this.el = new Gtk.Box( null, 0 );
258
259             // my vars (dec)
260
261             // set gobject values
262         }
263
264         // user defined functions
265     }
266
267     public class Xcls_GestureClick4 : Object
268     {
269         public Gtk.GestureClick el;
270         private Xcls_GladeuiView  _this;
271
272
273             // my vars (def)
274
275         // ctor
276         public Xcls_GestureClick4(Xcls_GladeuiView _owner )
277         {
278             _this = _owner;
279             this.el = new Gtk.GestureClick();
280
281             // my vars (dec)
282
283             // set gobject values
284
285             //listeners
286             this.el.pressed.connect( (n_press, x, y) => {
287             
288             
289             });
290         }
291
292         // user defined functions
293     }
294
295
296     public class Xcls_GestureClick5 : Object
297     {
298         public Gtk.GestureClick el;
299         private Xcls_GladeuiView  _this;
300
301
302             // my vars (def)
303
304         // ctor
305         public Xcls_GestureClick5(Xcls_GladeuiView _owner )
306         {
307             _this = _owner;
308             this.el = new Gtk.GestureClick();
309
310             // my vars (dec)
311
312             // set gobject values
313         }
314
315         // user defined functions
316     }
317
318     public class Xcls_ColumnView6 : Object
319     {
320         public Gtk.ColumnView el;
321         private Xcls_GladeuiView  _this;
322
323
324             // my vars (def)
325
326         // ctor
327         public Xcls_ColumnView6(Xcls_GladeuiView _owner )
328         {
329             _this = _owner;
330             this.el = new Gtk.ColumnView( null );
331
332             // my vars (dec)
333
334             // set gobject values
335             var child_0 = new Xcls_SingleSelection7( _this );
336             child_0.ref();
337             this.el.model = child_0.el;
338             var child_1 = new Xcls_ColumnViewColumn9( _this );
339             child_1.ref();
340             this.el.append(  child_1.el );
341         }
342
343         // user defined functions
344     }
345     public class Xcls_SingleSelection7 : Object
346     {
347         public Gtk.SingleSelection el;
348         private Xcls_GladeuiView  _this;
349
350
351             // my vars (def)
352
353         // ctor
354         public Xcls_SingleSelection7(Xcls_GladeuiView _owner )
355         {
356             _this = _owner;
357             this.el = new Gtk.SingleSelection( null );
358
359             // my vars (dec)
360
361             // set gobject values
362             var child_0 = new Xcls_TreeListModel8( _this );
363             child_0.ref();
364             this.el.model = child_0.el;
365         }
366
367         // user defined functions
368     }
369     public class Xcls_TreeListModel8 : Object
370     {
371         public Gtk.TreeListModel el;
372         private Xcls_GladeuiView  _this;
373
374
375             // my vars (def)
376
377         // ctor
378         public Xcls_TreeListModel8(Xcls_GladeuiView _owner )
379         {
380             _this = _owner;
381             this.el = new Gtk.TreeListModel( null, true, true, () => { } );
382
383             // my vars (dec)
384
385             // set gobject values
386         }
387
388         // user defined functions
389     }
390
391
392     public class Xcls_ColumnViewColumn9 : Object
393     {
394         public Gtk.ColumnViewColumn el;
395         private Xcls_GladeuiView  _this;
396
397
398             // my vars (def)
399
400         // ctor
401         public Xcls_ColumnViewColumn9(Xcls_GladeuiView _owner )
402         {
403             _this = _owner;
404             this.el = new Gtk.ColumnViewColumn( "", null );
405
406             // my vars (dec)
407
408             // set gobject values
409         }
410
411         // user defined functions
412     }
413
414
415     public class Xcls_notebook : Object
416     {
417         public Gtk.Notebook el;
418         private Xcls_GladeuiView  _this;
419
420
421             // my vars (def)
422
423         // ctor
424         public Xcls_notebook(Xcls_GladeuiView _owner )
425         {
426             _this = _owner;
427             _this.notebook = this;
428             this.el = new Gtk.Notebook();
429
430             // my vars (dec)
431
432             // set gobject values
433             var child_0 = new Xcls_label_preview( _this );
434             child_0.ref();
435             var child_1 = new Xcls_label_code( _this );
436             child_1.ref();
437             var child_2 = new Xcls_designview( _this );
438             child_2.ref();
439             var child_3 = new Xcls_sourceview( _this );
440             child_3.ref();
441             this.el.append_page (  child_3.el , _this.label_code.el );
442         }
443
444         // user defined functions
445     }
446     public class Xcls_label_preview : Object
447     {
448         public Gtk.Label el;
449         private Xcls_GladeuiView  _this;
450
451
452             // my vars (def)
453
454         // ctor
455         public Xcls_label_preview(Xcls_GladeuiView _owner )
456         {
457             _this = _owner;
458             _this.label_preview = this;
459             this.el = new Gtk.Label( "Preview" );
460
461             // my vars (dec)
462
463             // set gobject values
464         }
465
466         // user defined functions
467     }
468
469     public class Xcls_label_code : Object
470     {
471         public Gtk.Label el;
472         private Xcls_GladeuiView  _this;
473
474
475             // my vars (def)
476
477         // ctor
478         public Xcls_label_code(Xcls_GladeuiView _owner )
479         {
480             _this = _owner;
481             _this.label_code = this;
482             this.el = new Gtk.Label( "Preview Generated Code" );
483
484             // my vars (dec)
485
486             // set gobject values
487         }
488
489         // user defined functions
490     }
491
492     public class Xcls_designview : Object
493     {
494         public Glade.DesignView el;
495         private Xcls_GladeuiView  _this;
496
497
498             // my vars (def)
499         public JsRender.JsRender file;
500
501         // ctor
502         public Xcls_designview(Xcls_GladeuiView _owner )
503         {
504             _this = _owner;
505             _this.designview = this;
506             this.el = _this.main_window == null ? null : new Glade.DesignView(_this.main_window.gladeproject);
507
508             // my vars (dec)
509             this.file = null;
510
511             // init method
512
513             this.el.show();
514         }
515
516         // user defined functions
517         public void test () {
518         
519         }
520         public void createThumb () {
521             
522             
523             if (this.file == null) {
524                 return;
525             }
526             var filename = this.file.getIconFileName(false);
527             
528             var  win = this.el.get_parent_window();
529             var width = win.get_width();
530             var height = win.get_height();
531         
532             Gdk.Pixbuf screenshot = Gdk.pixbuf_get_from_window(win, 0, 0, width, height); // this.el.position?
533         
534             screenshot.save(filename,"png");
535             return;
536             
537             
538              
539         }
540     }
541
542     public class Xcls_sourceview : Object
543     {
544         public Gtk.SourceView el;
545         private Xcls_GladeuiView  _this;
546
547
548             // my vars (def)
549         public bool loading;
550         public gboolean show_line_numbers;
551         public bool allow_node_scroll;
552         public gboolean show_line_marks;
553         public gboolean editable;
554
555         // ctor
556         public Xcls_sourceview(Xcls_GladeuiView _owner )
557         {
558             _this = _owner;
559             _this.sourceview = this;
560             this.el = new Gtk.SourceView();
561
562             // my vars (dec)
563             this.loading = true;
564             this.show_line_numbers = true;
565             this.allow_node_scroll = true;
566             this.show_line_marks = true;
567             this.editable = false;
568
569             // init method
570
571             {
572                
573                 var description =   Pango.FontDescription.from_string("monospace");
574                 description.set_size(8000);
575                 this.el.override_font(description);
576             
577                 this.loading = true;
578                 var buf = this.el.get_buffer();
579                 buf.notify.connect((ps) => {
580                     if (this.loading) {
581                         return;
582                     }
583                     if (ps.name != "cursor-position") {
584                         return;
585                     }
586                     print("cursor changed : %d\n", buf.cursor_position);
587                     Gtk.TextIter cpos;
588                     buf.get_iter_at_offset(out cpos, buf.cursor_position);
589                     
590                     var ln = cpos.get_line();
591              
592                     var node = _this.file.lineToNode(ln);
593              
594                     if (node == null) {
595                         print("can not find node\n");
596                         return;
597                     }
598                     var ltree = _this.main_window.windowstate.left_tree;
599                     var tp = ltree.model.treePathFromNode(node);
600                     print("got tree path %s\n", tp);
601                     if (tp != "") {
602                        this.allow_node_scroll = false;        
603                        print("changing cursor on tree..\n");
604                         ltree.view.el.set_cursor(new Gtk.TreePath.from_string(tp), null, false);
605                         // scrolling is disabled... as node selection calls scroll 10ms after it changes.
606                         GLib.Timeout.add_full(GLib.Priority.DEFAULT,100 , () => {
607                             this.allow_node_scroll = true;
608                             return false;
609                         });
610                     }
611                     
612                     // highlight the node..
613                     
614                 });
615               
616               
617               
618                 var attrs = new Gtk.SourceMarkAttributes();
619                 var  pink =   Gdk.RGBA();
620                 pink.parse ( "pink");
621                 attrs.set_background ( pink);
622                 attrs.set_icon_name ( "process-stop");    
623                 attrs.query_tooltip_text.connect(( mark) => {
624                     //print("tooltip query? %s\n", mark.name);
625                     return mark.name;
626                 });
627                 
628                 this.el.set_mark_attributes ("ERR", attrs, 1);
629                 
630                  var wattrs = new Gtk.SourceMarkAttributes();
631                 var  blue =   Gdk.RGBA();
632                 blue.parse ( "#ABF4EB");
633                 wattrs.set_background ( blue);
634                 wattrs.set_icon_name ( "process-stop");    
635                 wattrs.query_tooltip_text.connect(( mark) => {
636                     //print("tooltip query? %s\n", mark.name);
637                     return mark.name;
638                 });
639                 
640                 this.el.set_mark_attributes ("WARN", wattrs, 1);
641                 
642              
643                 
644                  var dattrs = new Gtk.SourceMarkAttributes();
645                 var  purple =   Gdk.RGBA();
646                 purple.parse ( "#EEA9FF");
647                 dattrs.set_background ( purple);
648                 dattrs.set_icon_name ( "process-stop");    
649                 dattrs.query_tooltip_text.connect(( mark) => {
650                     //print("tooltip query? %s\n", mark.name);
651                     return mark.name;
652                 });
653                 
654                 this.el.set_mark_attributes ("DEPR", dattrs, 1);
655                 
656                 
657                 var gattrs = new Gtk.SourceMarkAttributes();
658                 var  grey =   Gdk.RGBA();
659                 grey.parse ( "#ccc");
660                 gattrs.set_background ( grey);
661              
662                 
663                 this.el.set_mark_attributes ("grey", gattrs, 1);
664                 
665                 
666                 
667                 
668                 
669                 
670             }
671         }
672
673         // user defined functions
674         public void loadFile ( ) {
675         
676             
677             this.loading = true;
678             var buf = this.el.get_buffer();
679             buf.set_text("",0);
680             var sbuf = (Gtk.SourceBuffer) buf;
681         
682             
683         
684             if (_this.file == null || _this.file.xtype != "Gtk") {
685                 print("xtype != Gtk");
686                 this.loading = false;
687                 return;
688             }
689             
690             var valafn = "";
691               try {             
692                    var  regex = new Regex("\\.bjs$");
693                 
694                  
695                     valafn = regex.replace(_this.file.path,_this.file.path.length , 0 , ".vala");
696                  } catch (GLib.RegexError e) {
697                      this.loading = false;
698                     return;
699                 }   
700             
701         
702            if (!FileUtils.test(valafn,FileTest.IS_REGULAR) ) {
703                 print("File path has no errors\n");
704                 this.loading = false;
705                 return  ;
706             }
707             
708             string str;
709             try {
710             
711                 GLib.FileUtils.get_contents (valafn, out str);
712             } catch (Error e) {
713                 this.loading = false;
714                 return  ;
715             }
716         
717         //    print("setting str %d\n", str.length);
718             buf.set_text(str, str.length);
719             var lm = Gtk.SourceLanguageManager.get_default();
720              
721             //?? is javascript going to work as js?
722             
723             ((Gtk.SourceBuffer)(buf)) .set_language(lm.get_language(_this.file.language));
724           
725             
726             Gtk.TextIter start;
727             Gtk.TextIter end;     
728                 
729             sbuf.get_bounds (out start, out end);
730             sbuf.remove_source_marks (start, end, null); // remove all marks..
731             
732             
733             if (_this.main_window.windowstate.last_compile_result != null) {
734                 var obj = _this.main_window.windowstate.last_compile_result;
735                 this.highlightErrorsJson("ERR", obj);
736                 this.highlightErrorsJson("WARN", obj);
737                 this.highlightErrorsJson("DEPR", obj);                  
738             }
739             //while (Gtk.events_pending()) {
740              //   Gtk.main_iteration();
741            // }
742             
743             this.loading = false; 
744         }
745         public void nodeSelected (JsRender.Node? sel) {
746           
747             
748           
749             // this is connected in widnowstate
750             print("Roo-view - node selected\n");
751             var buf = this.el.get_buffer();
752          
753             var sbuf = (Gtk.SourceBuffer) buf;
754         
755            
756             while(Gtk.events_pending()) {
757                 Gtk.main_iteration();
758             }
759             
760            
761             // clear all the marks..
762              Gtk.TextIter start;
763             Gtk.TextIter end;     
764                 
765             sbuf.get_bounds (out start, out end);
766             sbuf.remove_source_marks (start, end, "grey");
767             
768             
769              if (sel == null) {
770                 // no highlighting..
771                 return;
772             }
773             Gtk.TextIter iter;   
774             sbuf.get_iter_at_line(out iter,  sel.line_start);
775             
776             
777             Gtk.TextIter cur_iter;
778             sbuf.get_iter_at_offset(out cur_iter, sbuf.cursor_position);
779             
780             //var cur_line = cur_iter.get_line();
781             //if (cur_line > sel.line_start && cur_line < sel.line_end) {
782             
783             //} else {
784             if (this.allow_node_scroll) {
785                          
786                 this.el.scroll_to_iter(iter,  0.1f, true, 0.0f, 0.5f);
787                 }
788             
789              
790             
791             for (var i = 0; i < buf.get_line_count();i++) {
792                 if (i < sel.line_start || i > sel.line_end) {
793                    
794                     sbuf.get_iter_at_line(out iter, i);
795                     sbuf.create_source_mark(null, "grey", iter);
796                     
797                 }
798             
799             }
800             
801         
802         }
803         public void highlightErrorsJson (string type, Json.Object obj) {
804               Gtk.TextIter start;
805              Gtk.TextIter end;   
806              
807              var buf =  this.el.get_buffer();
808                var sbuf = (Gtk.SourceBuffer)buf;
809                 buf.get_bounds (out start, out end);
810                 
811                 sbuf.remove_source_marks (start, end, type);
812                          
813              
814              // we should highlight other types of errors..
815             
816             if (!obj.has_member(type)) {
817                 print("Return has no errors\n");
818                 return  ;
819             }
820             var err = obj.get_object_member(type);
821             
822             if (_this.file == null) { 
823                 return; // just in case the file has not loaded yet?
824             }
825          
826         
827             var valafn = "";
828               try {             
829                    var  regex = new Regex("\\.bjs$");
830                 
831                  
832                     valafn = regex.replace(_this.file.path,_this.file.path.length , 0 , ".vala");
833                  } catch (GLib.RegexError e) {
834                     return;
835                 }   
836         
837            if (!err.has_member(valafn)) {
838                 print("File path has no errors\n");
839                 return  ;
840             }
841             var lines = err.get_object_member(valafn);
842             
843            
844             
845             var tlines = buf.get_line_count () +1;
846             
847             lines.foreach_member((obj, line, node) => {
848                 
849                      Gtk.TextIter iter;
850             //        print("get inter\n");
851                     var eline = int.parse(line) -1  ;
852                     print("GOT ERROR on line %s -- converted to %d\n", line,eline);
853                     
854                     
855                     if (eline > tlines || eline < 0) {
856                         return;
857                     }
858                     sbuf.get_iter_at_line( out iter, eline);
859                     //print("mark line\n");
860                     var msg  = type + " on line: %d - %s".printf(eline+1, valafn);
861                     var ar = lines.get_array_member(line);
862                     for (var i = 0 ; i < ar.get_length(); i++) {
863                             msg += (msg.length > 0) ? "\n" : "";
864                             msg += ar.get_string_element(i);
865                     }
866                     
867                     
868                     sbuf.create_source_mark(msg, type, iter);
869                 } );
870                 return  ;
871             
872          
873         
874         
875         }
876         public string toString () {
877            Gtk.TextIter s;
878             Gtk.TextIter e;
879             this.el.get_buffer().get_start_iter(out s);
880             this.el.get_buffer().get_end_iter(out e);
881             var ret = this.el.get_buffer().get_text(s,e,true);
882             //print("TO STRING? " + ret);
883             return ret;
884         }
885     }
886
887
888 }