Use ousaged only for suspending
[gregoa/zavai.git] / src / app_polygen.vala
1 /*
2  * app_polygen - zavai polygen applet
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, string type);
34
35     public PolygenPage(string name)
36     {
37         this.name = name;
38         model = new Gtk.ListStore(3, typeof(string), 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     public void select()
50     {
51         // Get currently selected/focused
52         Gtk.TreePath path;
53         Gtk.TreeViewColumn col;
54         list.get_cursor(out path, out col);
55
56         // Activate it
57         list.row_activated(path, col);
58     }
59
60     private void on_row_activated(Gtk.TreeView tv, Gtk.TreePath path, Gtk.TreeViewColumn column)
61     {
62         Gtk.TreeIter iter;
63         if (!model.get_iter(out iter, path)) return;
64         Value grm_name, grm_type;
65         model.get_value(iter, 0, out grm_name);
66         model.get_value(iter, 2, out grm_type);
67         selected(name, (string)grm_name, (string)grm_type);
68     }
69 }
70
71 protected class PolygenRun : Gtk.VBox
72 {
73     public Gtk.ScrolledWindow scroll;
74     protected Gtk.TextBuffer text_buffer;
75     protected Gtk.TextView text;
76     protected Regex unhtml;
77     protected Regex seplines;
78
79     public string grm_name { get; set; }
80     public string grm_type { get; set; }
81
82     public PolygenRun()
83     {
84         grm_name = "";
85         grm_type = "";
86         unhtml = new Regex("[ ]*<[^>]+>[ ]*", 0, 0);
87         seplines = new Regex("\n");
88         text_buffer = new Gtk.TextBuffer(null);
89         text = new Gtk.TextView.with_buffer(text_buffer);
90         text.wrap_mode = Gtk.WrapMode.WORD;
91         text.cursor_visible = false;
92         text.editable = false;
93         text.add_events(Gdk.EventMask.BUTTON_PRESS_MASK);
94         text.button_press_event += on_button_press;
95         scroll = new Gtk.ScrolledWindow (null, null);
96         scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
97         scroll.add(text);
98                 pack_start(scroll, true, true, 0);
99     }
100
101     public bool on_button_press(Gdk.EventButton event)
102     {
103         update();
104         return true;
105     }
106
107     public void update()
108     {
109         if (grm_name == "") return;
110         string[] args = new string[5];
111         args[0] = "/usr/bin/polygen";
112         args[1] = "/usr/share/polygen/" + grm_name + ".grm";
113         if (grm_type == "line/text" || grm_type == "line/html")
114         {
115             args[2] = "-X";
116             args[3] = "10";
117             args[4] = null;
118         }
119         else
120             args[2] = null;
121         int pipe_out;
122         string result;
123         try {
124             Process.spawn_async_with_pipes(config.homedir, args, null, 0, null, null, null, out pipe_out, null);
125             IOChannel ch = new IOChannel.unix_new(pipe_out);
126             size_t res_len;
127             ch.read_to_end(out result, out res_len);
128             ch.shutdown(false);
129
130             if (grm_type == "line/html" || grm_type == "block/html")
131             {
132                 result = unhtml.replace(result, (long)res_len, 0, " ", 0);
133             } else if (grm_type == "line/text") {
134                 result = seplines.replace(result, (long)res_len, 0, "\n\n", 0);
135             }
136             
137
138         } catch (Error e) {
139             result = "Error: " + e.message;
140         }
141         text_buffer.text = result;
142         Gtk.TextIter iter;
143         text_buffer.get_iter_at_offset(out iter, 0);
144         Gtk.TextMark mark = text_buffer.create_mark(null, iter, true);
145         text.scroll_mark_onscreen(mark);
146     }
147 }
148
149 public class Polygen : Applet
150 {
151     protected Gee.ArrayList<PolygenPage> pages;
152     protected Gtk.Notebook notebook;
153     protected PolygenRun result;
154
155     private void add_grammar(string page, string name, string type, string title)
156     {
157         PolygenPage pg = null;
158         foreach (PolygenPage p in pages)
159         {
160             if (p.name == page)
161             {
162                 pg = p;
163                 break;
164             }
165         }
166         if (pg == null)
167         {
168             pg = new PolygenPage(page);
169             pg.selected += on_selected;
170             pages.add(pg);
171         }
172
173         Gtk.TreeIter iter;
174         pg.model.append (out iter);
175         pg.model.set(iter, 0, name);
176         pg.model.set(iter, 1, title);
177         pg.model.set(iter, 2, type);
178     }
179
180     protected void on_selected(string page, string name, string type)
181     {
182         result.grm_name = page + "/" + name;
183         result.grm_type = type;
184         result.update();
185         notebook.set_current_page(notebook.get_n_pages()-1);
186     }
187
188         public Polygen(string label, IOChannel data)
189         {
190                 _label = label;
191         pages = new Gee.ArrayList<PolygenPage>();
192
193         while (true)
194         {
195             string line;
196             var res = data.read_line(out line, null, null);
197             if (res != IOStatus.NORMAL) break;
198             string[] vals = line.split(" ", 3);
199             if (vals == null) break;
200             string[] np = vals[0].split("/", 2);
201             if (np == null) break;
202             add_grammar(np[0], np[1], vals[1], vals[2].strip());
203         }
204
205         notebook = new Gtk.Notebook();
206         foreach (PolygenPage p in pages)
207         {
208             notebook.append_page(p.scroll, new Gtk.Label(p.name));
209         }
210         result = new PolygenRun();
211         notebook.append_page(result, new Gtk.Label("Result"));
212
213                 pack_start(notebook, true, true, 0);
214
215         Gtk.Button select = new Gtk.Button.with_label("Select");
216         button_box.pack_start(select, true, true, 0);
217         select.clicked += on_click;
218         }
219
220     private void on_click(Gtk.Button b)
221     {
222         stderr.printf("ZA\n");
223         if (notebook.page >= pages.size)
224             result.update(); // If we are in the result page, just update
225         else
226         {
227             PolygenPage page = pages[notebook.page];
228             page.select();
229         }
230     }
231 }
232
233 Polygen polygen;
234
235 public void init()
236 {
237     try {
238         var data = new IOChannel.file(zavai.config.homedir + "/polygen-info", "r");
239         polygen = new Polygen("Polygen", data);
240         data.shutdown(false);
241
242         zavai.registry.register_applet("ui.polygen", polygen);
243         zavai.registry.getmenu("menu.misc").add_applet("ui.polygen");
244     } catch (Error e) {
245         polygen = null;
246         zavai.log.error("Skipping polygen plugin: " + e.message);
247     }
248 }
249
250 }
251 }
252 }