Renamed zapolygen in zavai-polygen
[gregoa/zavai.git] / polygen / zavai-polygen.vala
1 /*
2  * zapolygen - 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 /*
24 protected class PolygenPage : Object
25 {
26         public string name { get; construct; }
27         public Gtk.ListStore model;
28         public Gtk.TreeView list;
29         public Gtk.ScrolledWindow scroll;
30         public signal void selected(string page, string name, string type);
31
32         public PolygenPage(string name)
33         {
34                 Object(name: name);
35                 model = new Gtk.ListStore(3, typeof(string), typeof(string), typeof(string));
36                 list = new Gtk.TreeView.with_model(model);
37                 list.insert_column_with_attributes (-1, "Name", new Gtk.CellRendererText(), "text", 0);
38                 list.insert_column_with_attributes (-1, "Title", new Gtk.CellRendererText(), "text", 1);
39                 scroll = new Gtk.ScrolledWindow (null, null);
40                 scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
41                 scroll.add(list);
42
43                 list.row_activated += on_row_activated;
44         }
45
46         public void select()
47         {
48                 // Get currently selected/focused
49                 Gtk.TreePath path;
50                 Gtk.TreeViewColumn col;
51                 list.get_cursor(out path, out col);
52
53                 // Activate it
54                 list.row_activated(path, col);
55         }
56
57         private void on_row_activated(Gtk.TreeView tv, Gtk.TreePath path, Gtk.TreeViewColumn column)
58         {
59                 Gtk.TreeIter iter;
60                 if (!model.get_iter(out iter, path)) return;
61                 Value grm_name, grm_type;
62                 model.get_value(iter, 0, out grm_name);
63                 model.get_value(iter, 2, out grm_type);
64                 selected(name, (string)grm_name, (string)grm_type);
65         }
66 }
67 */
68
69 protected class PolygenRun : Gtk.VBox
70 {
71         public Gtk.ScrolledWindow scroll;
72         protected Gtk.TextBuffer text_buffer;
73         protected Gtk.TextView text;
74         protected Regex unhtml;
75         protected Regex seplines;
76
77         public string grm_name { get; set; }
78         public string grm_type { get; set; }
79
80         public PolygenRun() throws RegexError
81         {
82                 grm_name = "";
83                 grm_type = "";
84                 unhtml = new Regex("[ ]*<[^>]+>[ ]*", 0, 0);
85                 seplines = new Regex("\n");
86                 text_buffer = new Gtk.TextBuffer(null);
87                 text = new Gtk.TextView.with_buffer(text_buffer);
88                 text.wrap_mode = Gtk.WrapMode.WORD;
89                 text.cursor_visible = false;
90                 text.editable = false;
91                 text.add_events(Gdk.EventMask.BUTTON_PRESS_MASK);
92                 text.button_press_event += on_button_press;
93                 scroll = new Gtk.ScrolledWindow (null, null);
94                 scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
95                 scroll.add(text);
96                 pack_start(scroll, true, true, 0);
97         }
98
99         public bool on_button_press(Gdk.EventButton event)
100         {
101                 update();
102                 return true;
103         }
104
105         public void update()
106         {
107                 if (grm_name == "") return;
108                 string[] args = new string[5];
109                 args[0] = "/usr/bin/polygen";
110                 args[1] = "/usr/share/polygen/" + grm_name + ".grm";
111                 if (grm_type == "line/text" || grm_type == "line/html")
112                 {
113                         args[2] = "-X";
114                         args[3] = "10";
115                         args[4] = null;
116                 }
117                 else
118                         args[2] = null;
119                 int pipe_out;
120                 string result;
121                 try {
122                         Process.spawn_async_with_pipes(homedir, args, null, 0, null, null, null, out pipe_out, null);
123                         IOChannel ch = new IOChannel.unix_new(pipe_out);
124                         size_t res_len;
125                         ch.read_to_end(out result, out res_len);
126                         ch.shutdown(false);
127
128                         if (grm_type == "line/html" || grm_type == "block/html")
129                         {
130                                 result = unhtml.replace(result, (long)res_len, 0, " ", 0);
131                         } else if (grm_type == "line/text") {
132                                 result = seplines.replace(result, (long)res_len, 0, "\n\n", 0);
133                         }
134
135
136                 } catch (Error e) {
137                         result = "Error: " + e.message;
138                 }
139                 text_buffer.text = result;
140                 Gtk.TextIter iter;
141                 text_buffer.get_iter_at_offset(out iter, 0);
142                 Gtk.TextMark mark = text_buffer.create_mark(null, iter, true);
143                 text.scroll_mark_onscreen(mark);
144         }
145 }
146
147 public class Polygen : Gtk.Window
148 {
149         //protected Gee.ArrayList<PolygenPage> pages;
150         protected Gtk.Notebook notebook;
151         protected PolygenRun result;
152         protected Gtk.ListStore grammars;
153         protected FisheyeListView grammarlist;
154
155         private void add_grammar(string page, string name, string type, string title)
156         {
157 /*
158                 PolygenPage pg = null;
159                 foreach (PolygenPage p in pages)
160                 {
161                         if (p.name == page)
162                         {
163                                 pg = p;
164                                 break;
165                         }
166                 }
167                 if (pg == null)
168                 {
169                         pg = new PolygenPage(page);
170                         pg.selected += on_selected;
171                         pages.add(pg);
172                 }
173
174                 Gtk.TreeIter iter;
175                 pg.model.append (out iter);
176                 pg.model.set(iter, 0, name);
177                 pg.model.set(iter, 1, title);
178                 pg.model.set(iter, 2, type);
179         */
180                 Gtk.TreeIter iter;
181                 grammars.append (out iter);
182                 grammars.set(iter, 0, "%s/%s - %s".printf(page, name, title));
183                 grammars.set(iter, 1, "%s/%s".printf(page, name));
184                 grammars.set(iter, 2, type);
185         }
186
187         /*
188         protected void on_selected(string page, string name, string type)
189         {
190                 result.grm_name = page + "/" + name;
191                 result.grm_type = type;
192                 result.update();
193                 notebook.set_current_page(notebook.get_n_pages()-1);
194         }
195         */
196
197         public Polygen(string label, IOChannel data) throws ConvertError, IOChannelError, RegexError
198         {
199                 title = label;
200                 destroy += Gtk.main_quit;
201
202                 grammars = new Gtk.ListStore(3, typeof(string), typeof(string), typeof(string));
203
204                 var vbox = new Gtk.VBox(false, 0);
205                 add(vbox);
206
207                 //pages = new Gee.ArrayList<PolygenPage>();
208
209                 while (true)
210                 {
211                         string line;
212                         var res = data.read_line(out line, null, null);
213                         if (res != IOStatus.NORMAL) break;
214                         string[] vals = line.split(" ", 3);
215                         if (vals == null) break;
216                         string[] np = vals[0].split("/", 2);
217                         if (np == null) break;
218                         add_grammar(np[0], np[1], vals[1], vals[2].strip());
219                 }
220
221                 grammarlist = new FisheyeListView();
222                 grammarlist.set_model(grammars);
223                 grammarlist.row_activated += on_row_activated;
224
225                 notebook = new Gtk.Notebook();
226                 notebook.append_page(grammarlist, new Gtk.Label("Grammars"));
227                 /*
228                 foreach (PolygenPage p in pages)
229                 {
230                         notebook.append_page(p.scroll, new Gtk.Label(p.name));
231                 }
232                 */
233                 result = new PolygenRun();
234                 notebook.append_page(result, new Gtk.Label("Result"));
235
236                 vbox.pack_start(notebook, true, true, 0);
237
238                 //Gtk.Button select = new Gtk.Button.with_label("Select");
239                 //button_box.pack_start(select, true, true, 0);
240                 //select.clicked += on_click;
241         }
242
243         public void on_row_activated(Gtk.TreePath path)
244         {
245                 Gtk.TreeIter iter;
246                 grammars.get_iter(out iter, path);
247                 string grm;
248                 string type;
249                 grammars.get(iter, 1, out grm, 2, out type, -1);
250                 stdout.printf("Clicked on %s %s\n", type, grm);
251
252                 result.grm_name = grm;
253                 result.grm_type = type;
254                 result.update();
255                 notebook.set_current_page(notebook.get_n_pages()-1);
256         }
257
258         /*
259         private void on_click(Gtk.Button b)
260         {
261                 stderr.printf("ZA\n");
262                 if (notebook.page >= pages.size)
263                         result.update(); // If we are in the result page, just update
264                 else
265                 {
266                         PolygenPage page = pages[notebook.page];
267                         page.select();
268                 }
269         }
270                         */
271 }
272
273 string homedir;
274
275 static int main (string[] args) {
276         Gtk.init (ref args);
277
278         homedir = GLib.Environment.get_home_dir() + "/.zavai";
279         Polygen polygen;
280         try {
281                 var data = new IOChannel.file(homedir + "/polygen-info", "r");
282                 polygen = new Polygen("Polygen", data);
283                 polygen.set_size_request(300, 500);
284                 polygen.show_all();
285                 data.shutdown(false);
286
287                 //zavai.registry.register_applet("ui.polygen", polygen);
288                 //zavai.registry.getmenu("menu.misc").add_applet("ui.polygen");
289         } catch (Error e) {
290                 stderr.printf("%s", e.message);
291         }
292
293         Gtk.main();
294         return 0;
295 }