Show polygen results in a clickable text area
[gregoa/zavai.git] / src / app_polygen.vala
1 /*
2  * app_wm - zavai window management functions
3  *
4  * Copyright (C) 2009  Enrico Zini <enrico@enricozini.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 using GLib;
22
23 namespace zavai {
24 namespace ui {
25 namespace polygen {
26
27 protected class PolygenPage : Object
28 {
29     public string name { get; construct; }
30     public Gtk.ListStore model;
31     public Gtk.TreeView list;
32     public Gtk.ScrolledWindow scroll;
33     public signal void selected(string page, string name);
34
35     public PolygenPage(string name)
36     {
37         this.name = name;
38         model = new Gtk.ListStore(2, typeof(string), typeof(string));
39         list = new Gtk.TreeView.with_model(model);
40         list.insert_column_with_attributes (-1, "Name", new Gtk.CellRendererText(), "text", 0);
41         list.insert_column_with_attributes (-1, "Title", new Gtk.CellRendererText(), "text", 1);
42         scroll = new Gtk.ScrolledWindow (null, null);
43         scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
44         scroll.add(list);
45
46         list.row_activated += on_row_activated;
47     }
48
49     private void on_row_activated(Gtk.TreeView tv, Gtk.TreePath path, Gtk.TreeViewColumn column)
50     {
51         Gtk.TreeIter iter;
52         if (!model.get_iter(out iter, path)) return;
53         Value grm_name;
54         model.get_value(iter, 0, out grm_name);
55         selected(name, (string)grm_name);
56     }
57 }
58
59 protected class PolygenRun : Gtk.VBox
60 {
61     public Gtk.ScrolledWindow scroll;
62     protected Gtk.TextBuffer text_buffer;
63     protected Gtk.TextView text;
64
65     private string _grammar;
66     public string grammar {
67         get { return _grammar; }
68         set {
69             _grammar = value;
70             update();
71         }
72     }
73
74     public PolygenRun()
75     {
76         _grammar = "";
77         text_buffer = new Gtk.TextBuffer(null);
78         text = new Gtk.TextView.with_buffer(text_buffer);
79         text.wrap_mode = Gtk.WrapMode.WORD;
80         text.cursor_visible = false;
81         text.editable = false;
82         text.add_events(Gdk.EventMask.BUTTON_PRESS_MASK);
83         text.button_press_event += on_button_press;
84         scroll = new Gtk.ScrolledWindow (null, null);
85         scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
86         scroll.add(text);
87                 pack_start(scroll, true, true, 0);
88     }
89
90     public bool on_button_press(Gdk.EventButton event)
91     {
92         update();
93         return true;
94     }
95
96     public void update()
97     {
98         string[] args = new string[3];
99         args[0] = "/usr/bin/polygen";
100         args[1] = "/usr/share/polygen/" + _grammar + ".grm";
101         args[2] = null;
102         int pipe_out;
103         Process.spawn_async_with_pipes(config.homedir, args, null, 0, null, null, null, out pipe_out, null);
104         IOChannel ch = new IOChannel.unix_new(pipe_out);
105         string result;
106         ch.read_to_end(out result, null);
107         ch.shutdown(false);
108
109         text_buffer.text = result;
110         Gtk.TextIter iter;
111         text_buffer.get_iter_at_offset(out iter, 0);
112         Gtk.TextMark mark = text_buffer.create_mark(null, iter, true);
113         text.scroll_mark_onscreen(mark);
114     }
115 }
116
117 public class Polygen : Applet
118 {
119     protected Gee.ArrayList<PolygenPage> pages;
120     protected Gtk.Notebook notebook;
121     protected PolygenRun result;
122
123     private void add(string page, string name, string title)
124     {
125         PolygenPage pg = null;
126         foreach (PolygenPage p in pages)
127         {
128             if (p.name == page)
129             {
130                 pg = p;
131                 break;
132             }
133         }
134         if (pg == null)
135         {
136             pg = new PolygenPage(page);
137             pg.selected += on_selected;
138             pages.add(pg);
139         }
140
141         Gtk.TreeIter iter;
142         pg.model.append (out iter);
143         pg.model.set(iter, 0, name);
144         pg.model.set(iter, 1, title);
145     }
146
147     protected void on_selected(string page, string name)
148     {
149         result.grammar = page + "/" + name;
150         notebook.set_current_page(notebook.get_n_pages()-1);
151     }
152
153         public Polygen(string label, IOChannel data)
154         {
155                 _label = label;
156         pages = new Gee.ArrayList<PolygenPage>();
157
158         while (true)
159         {
160             string line;
161             var res = data.read_line(out line, null, null);
162             if (res != IOStatus.NORMAL) break;
163             string[] vals = line.split(" ", 2);
164             if (vals == null) break;
165             string[] np = vals[0].split("/", 2);
166             if (np == null) break;
167             add(np[0], np[1], vals[1].strip());
168         }
169
170         notebook = new Gtk.Notebook();
171         foreach (PolygenPage p in pages)
172         {
173             notebook.append_page(p.scroll, new Gtk.Label(p.name));
174         }
175         result = new PolygenRun();
176         notebook.append_page(result, new Gtk.Label("Result"));
177
178                 pack_start(notebook, true, true, 0);
179         }
180 }
181
182 Polygen polygen;
183
184 public void init()
185 {
186     try {
187         var data = new IOChannel.file(zavai.config.homedir + "/polygen-info", "r");
188         polygen = new Polygen("Polygen", data);
189         data.shutdown(false);
190
191         zavai.registry.register_applet("ui.polygen", polygen);
192         zavai.registry.getmenu("menu.main").add_applet("ui.polygen");
193     } catch (FileError e) {
194         polygen = null;
195         zavai.log.error("Skipping polygen plugin: " + e.message);
196     }
197
198     /*
199         window_list = new WindowList("Current apps");
200         zavai.registry.register_applet("wm.list", window_list);
201         zavai.registry.getmenu("menu.main").add_applet("wm.list");
202
203         try {
204                 launcher = new Launcher("Run program");
205         } catch (Error e) {
206                 zavai.log.error("Not running launcher: " + e.message);
207                 launcher = null;
208         }
209
210         if (launcher != null)
211         {
212                 zavai.registry.register_applet("wm.launcher", launcher);
213                 zavai.registry.getmenu("menu.main").add_applet("wm.launcher");
214         }
215     */
216 }
217
218 }
219 }
220 }