Added log viewer
[gregoa/zavai.git] / src / app_main.vala
1 /*
2  * app_main - zavai main status display
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 main {
26
27 /*
28 public class StatusBar : Gtk.HBox
29 {
30     void StatusBar()
31     {
32     }
33 }
34 */
35
36 public class Clock : Gtk.VBox
37 {
38     protected Gtk.Label l_date;
39     protected Gtk.Button l_date_button;
40     protected Gtk.Label l_time;
41     protected Gtk.Label l_deadline;
42     protected time_t last_time;
43     protected zavai.clock.SourceType last_time_type;
44     protected time_t last_deadline;
45     protected string last_deadline_label;
46     protected Log log;
47
48     construct
49     {
50         last_time = time_t();
51         last_time_type = zavai.clock.SourceType.SYSTEM;
52         last_deadline = 0;
53         last_deadline_label = "";
54
55         l_date = new Gtk.Label("--");
56         l_date.modify_font(Pango.FontDescription.from_string("Sans 40"));
57         l_date_button = new Gtk.Button();
58         l_date_button.set_image(l_date);
59         l_date_button.relief = Gtk.ReliefStyle.NONE;
60         l_date_button.clicked += on_date_clicked;
61         pack_start(l_date_button, false, false, 0);
62         l_time = new Gtk.Label("--:--");
63         l_time.modify_font(Pango.FontDescription.from_string("Sans 60"));
64         pack_start(l_time, false, false, 0);
65         l_deadline = new Gtk.Label("");
66         l_deadline.modify_font(Pango.FontDescription.from_string("Sans 30"));
67         l_deadline.set_justify(Gtk.Justification.CENTER);
68         pack_start(l_deadline, false, false, 0);
69
70         log = new Log();
71         pack_start(log, false, false, 0);
72
73         zavai.clock.clock.minute_changed += on_minute_changed;
74         zavai.clock.clock.schedule_changed += on_schedule_changed;
75         on_schedule_changed(zavai.clock.clock.next_alarm());
76
77         zavai.clock.clock.request("ui.main.clock");
78     }
79
80     private void on_date_clicked(Gtk.Button b)
81     {
82         zavai.app.push_applet(zavai.ui.calendar.calendar);
83     }
84
85     private void on_schedule_changed(zavai.clock.Alarm? next)
86     {
87         if (next == null)
88         {
89             last_deadline = 0;
90             last_deadline_label = "";
91         } else {
92             last_deadline = next.ev.deadline;
93             last_deadline_label = next.label;
94         }
95         on_minute_changed((long)last_time, last_time_type);
96     }
97
98     private void on_minute_changed(long ts, zavai.clock.SourceType type)
99     {
100         last_time = (time_t)ts;
101         last_time_type = type;
102
103         string typetag = "unknown";
104         switch (type)
105         {
106             case zavai.clock.SourceType.GPS:
107                 typetag = "gps";
108                 break;
109             case zavai.clock.SourceType.SYSTEM:
110                 typetag = "sys";
111                 break;
112         }
113
114         var t = Time.local((time_t)ts);
115         l_date.set_text(t.format("%a %d %b"));
116         l_time.set_text("%2d:%02d (%s)".printf(t.hour, t.minute, typetag));
117
118         if (last_deadline == 0)
119             l_deadline.set_text("");
120         else
121         {
122             int remaining = (int)(last_deadline - last_time);
123             int hours = remaining / 3600;
124             int minutes = (remaining % 3600) / 60;
125             if (hours == 0 && minutes == 0)
126                 l_deadline.set_text(last_deadline_label + "\nanytime now");
127             else
128                 l_deadline.set_text("%s\nin %02dh %02dm".printf(last_deadline_label, hours, minutes));
129         }
130     }
131 }
132
133 public class Status : Applet
134 {
135     public Gtk.HBox status_icons;
136     public Clock clock;
137     public Gtk.Label gsm_status;
138     public Gtk.Label gsm_info;
139     public AppletPushLink menu;
140
141     public Status(string label)
142     {
143         _label = label;
144         status_icons = new Gtk.HBox(false, 0);
145         clock = new Clock();
146         gsm_status = new Gtk.Label("");
147         gsm_info = new Gtk.Label("");
148         menu = new AppletPushLink(zavai.menu_main);
149
150         pack_start(status_icons, false, false, 0);
151         pack_start(clock, false, false, 0);
152         pack_start(gsm_status, false, false, 0);
153         pack_start(gsm_info, false, false, 0);
154         // pack_start(music.player, false, false, 0);
155         pack_end(menu, false, false, 0);
156
157         zavai.gsm.gsm.status_changed += (msg) => { gsm_status.set_text(msg); };
158         zavai.gsm.gsm.info_changed += () => {
159 stderr.printf("NEW INFO %s %s %d\n", zavai.gsm.gsm.info_provider, zavai.gsm.gsm.info_registration, zavai.gsm.gsm.info_signal_strength);
160             string text = "%s (%s)".printf(zavai.gsm.gsm.info_provider, zavai.gsm.gsm.info_registration);
161             if (zavai.gsm.gsm.info_signal_strength != -1)
162                 text = "%s %d%%".printf(text, zavai.gsm.gsm.info_signal_strength);
163             gsm_info.set_text(text);
164         };
165     }
166 }
167
168 public class IncDec : Gtk.HBox
169 {
170     protected Gtk.Button b_decmore;
171     protected Gtk.Button b_dec;
172     protected Gtk.Button b_inc;
173     protected Gtk.Button b_incmore;
174     static const int BH = 50;
175     static const int BW = 50;
176
177     public signal void tweaked(IncDec id, int amount);
178
179     public IncDec()
180     {
181         homogeneous = true;
182         b_decmore = new Gtk.Button.with_label("«");
183         b_decmore.set_size_request(BW, BH);
184         b_dec = new Gtk.Button.with_label("<");
185         b_dec.set_size_request(BW, BH);
186         b_inc = new Gtk.Button.with_label(">");
187         b_inc.set_size_request(BW, BH);
188         b_incmore = new Gtk.Button.with_label("»");
189         b_incmore.set_size_request(BW, BH);
190         pack_start(b_decmore, false, true, 0);
191         pack_start(b_dec, false, true, 0);
192         pack_start(b_inc, false, true, 0);
193         pack_start(b_incmore, false, true, 0);
194         b_decmore.clicked += on_clicked;
195         b_dec.clicked += on_clicked;
196         b_inc.clicked += on_clicked;
197         b_incmore.clicked += on_clicked;
198     }
199
200     protected void on_clicked(Gtk.Button b)
201     {
202         if (b == b_decmore)
203             tweaked(this, -10);
204         else if (b == b_dec)
205             tweaked(this, -1);
206         else if (b == b_inc)
207             tweaked(this, 1);
208         else if (b == b_incmore)
209             tweaked(this, 10);
210     }
211 }
212
213 public abstract class AddDeadline : Applet
214 {
215     protected Gtk.ComboBoxEntry dl_label;
216     protected Gtk.Button dl_submit;
217
218     public AddDeadline()
219     {
220         dl_label = new Gtk.ComboBoxEntry.text();
221         dl_label.append_text("Pasta");
222         dl_label.append_text("Talk");
223         dl_label.append_text("Leave");
224         dl_label.changed += on_label_changed;
225
226         var hbox = new Gtk.HBox(false, 0);
227         hbox.pack_start(new Gtk.Label("Label: "), false, false, 0);
228         hbox.pack_start(dl_label, true, true, 0);
229         pack_start(hbox, false, false, 0);
230
231         dl_submit = new Gtk.Button.with_label("Activate");
232         dl_submit.set_sensitive(false);
233         dl_submit.clicked += on_submit;
234         button_box.pack_start(dl_submit, true, true, 0);
235     }
236
237     public override void start()
238     {
239         ((Gtk.Entry)dl_label.get_child()).set_text("");
240         update();
241     }
242
243     protected virtual void update()
244     {
245         dl_submit.set_sensitive(((Gtk.Entry)dl_label.get_child()).get_text() == "" ? false : true);
246     }
247
248     protected abstract time_t get_deadline();
249
250     protected void on_label_changed(Gtk.ComboBox e)
251     {
252         update();
253     }
254
255     protected void on_submit(Gtk.Button b)
256     {
257         string label = ((Gtk.Entry)dl_label.get_child()).get_text();
258         time_t deadlinets = get_deadline();
259         Time deadline = Time.local(deadlinets);
260         string timespec = deadline.format("%H:%M %m/%d/%Y");
261         zavai.log.info("Scheduling deadline " + label + " at " + timespec);
262         zavai.clock.clock.schedule(timespec, label);
263         back();
264     }
265 }
266
267 public class AddAbsoluteDeadline : AddDeadline
268 {
269     protected Gtk.Label dl_day;
270     protected IncDec dl_day_tweak;
271     protected Gtk.Label dl_hour;
272     protected IncDec dl_hour_tweak;
273     protected Gtk.Label dl_min;
274     protected IncDec dl_min_tweak;
275     protected time_t dl_time;
276
277     public AddAbsoluteDeadline()
278     {
279         _label = "Add absolute deadline";
280         dl_time = 0;
281
282         dl_day = new Gtk.Label("");
283         dl_day.set_justify(Gtk.Justification.RIGHT);
284         dl_day_tweak = new IncDec();
285         dl_day_tweak.tweaked += on_tweak;
286         var hbox = new Gtk.HBox(false, 0);
287         hbox.pack_start(new Gtk.Label("Day: "), false, false, 0);
288         hbox.pack_start(dl_day, true, true, 0);
289         hbox.pack_start(dl_day_tweak, false, false, 0);
290         pack_start(hbox, false, false, 0);
291
292         dl_hour = new Gtk.Label("");
293         dl_hour.set_justify(Gtk.Justification.RIGHT);
294         dl_hour_tweak = new IncDec();
295         dl_hour_tweak.tweaked += on_tweak;
296         hbox = new Gtk.HBox(false, 0);
297         hbox.pack_start(new Gtk.Label("Hour: "), false, false, 0);
298         hbox.pack_start(dl_hour, true, true, 0);
299         hbox.pack_start(dl_hour_tweak, false, false, 0);
300         pack_start(hbox, false, false, 0);
301
302         dl_min = new Gtk.Label("");
303         dl_min.set_justify(Gtk.Justification.RIGHT);
304         dl_min_tweak = new IncDec();
305         dl_min_tweak.tweaked += on_tweak;
306         hbox = new Gtk.HBox(false, 0);
307         hbox.pack_start(new Gtk.Label("Minute: "), false, false, 0);
308         hbox.pack_start(dl_min, true, true, 0);
309         hbox.pack_start(dl_min_tweak, false, false, 0);
310         pack_start(hbox, false, false, 0);
311     }
312
313     public override void start()
314     {
315         dl_time = time_t();
316         base.start();
317     }
318
319     protected override void update()
320     {
321         Time t = Time.local(dl_time);
322         dl_day.set_text(t.format("%a %d %b"));
323         dl_hour.set_text(t.format("%H"));
324         dl_min.set_text(t.format("%M"));
325         base.update();
326     }
327
328     protected override time_t get_deadline()
329     {
330         return dl_time;
331     }
332
333     protected void on_tweak(IncDec id, int amount)
334     {
335         time_t old = dl_time;
336         if (id == dl_day_tweak)
337             dl_time += amount * 3600 * 24;
338         else if (id == dl_hour_tweak)
339             dl_time += amount * 3600;
340         else if (id == dl_min_tweak)
341             dl_time += amount * 60;
342         time_t now = time_t();
343         if (dl_time < now)
344             dl_time = old;
345         update();
346     }
347 }
348
349 public class AddRelativeDeadline : AddDeadline
350 {
351     protected Gtk.Label dl_hour;
352     protected IncDec dl_hour_tweak;
353     protected Gtk.Label dl_min;
354     protected IncDec dl_min_tweak;
355     protected int dl_time;
356
357     public AddRelativeDeadline()
358     {
359         _label = "Add relative deadline";
360         dl_time = 0;
361
362         dl_hour = new Gtk.Label("");
363         dl_hour.set_justify(Gtk.Justification.RIGHT);
364         dl_hour_tweak = new IncDec();
365         dl_hour_tweak.tweaked += on_tweak;
366         var hbox = new Gtk.HBox(false, 0);
367         hbox.pack_start(new Gtk.Label("Hour: "), false, false, 0);
368         hbox.pack_start(dl_hour, true, true, 0);
369         hbox.pack_start(dl_hour_tweak, false, false, 0);
370         pack_start(hbox, false, false, 0);
371
372         dl_min = new Gtk.Label("");
373         dl_min.set_justify(Gtk.Justification.RIGHT);
374         dl_min_tweak = new IncDec();
375         dl_min_tweak.tweaked += on_tweak;
376         hbox = new Gtk.HBox(false, 0);
377         hbox.pack_start(new Gtk.Label("Minute: "), false, false, 0);
378         hbox.pack_start(dl_min, true, true, 0);
379         hbox.pack_start(dl_min_tweak, false, false, 0);
380         pack_start(hbox, false, false, 0);
381     }
382
383     public override void start()
384     {
385         dl_time = 0;
386         base.start();
387     }
388
389     protected override void update()
390     {
391         dl_hour.set_text("%2d".printf(dl_time/60));
392         dl_min.set_text("%2d".printf(dl_time%60));
393         base.update();
394     }
395
396     protected void on_tweak(IncDec id, int amount)
397     {
398         int old = dl_time;
399         if (id == dl_hour_tweak)
400             dl_time += amount * 60;
401         else if (id == dl_min_tweak)
402             dl_time += amount;
403         if (dl_time < 0)
404             dl_time = old;
405         update();
406     }
407
408     protected override time_t get_deadline()
409     {
410         return time_t() + dl_time * 60;
411     }
412 }
413
414 public class Log : Gtk.VBox
415 {
416     protected Gtk.Label l_info;
417     protected Gtk.Button l_info_button;
418
419     construct
420     {
421         l_info = new Gtk.Label("");
422         // l_info.modify_font(Pango.FontDescription.from_string("Sans 60"));
423         pack_start(l_info, false, false, 0);
424
425         l_info_button = new Gtk.Button();
426         l_info_button.set_image(l_info);
427         l_info_button.relief = Gtk.ReliefStyle.NONE;
428         l_info_button.clicked += (b) => {
429             zavai.app.push_applet(zavai.ui.logview.log);
430         };
431         pack_start(l_info_button, false, false, 0);
432
433         zavai.log.log.entries_changed += refresh;
434
435         refresh();
436     }
437
438     public void refresh()
439     {
440         int count = 0;
441         zavai.log.log.list_entries((d, f) => {
442             ++count;
443             return true;
444         });
445         l_info.set_text("%d log entries".printf(count));
446         l_info_button.set_sensitive(count != 0);
447         //zavai.log.Log l = zavai.log.log.load(args[2]);
448     }
449 }
450
451 /*
452 public class AddDailyDeadline : Applet
453 {
454     public AddDailyDeadline()
455     {
456         _label = "Add daily deadline";
457     }
458 }
459 */
460
461 public Status status;
462 public AddAbsoluteDeadline aad;
463 public AddRelativeDeadline ard;
464 //AddDailyDeadline add;
465
466 public void init()
467 {
468     status = new Status("Zavai");
469     aad = new AddAbsoluteDeadline();
470     ard = new AddRelativeDeadline();
471     /*
472     add = new AddDailyDeadline();
473     zavai.registry.register_applet("clock.adddaily", add);
474     */
475
476     zavai.menu_misc.add_applet(aad);
477     zavai.menu_misc.add_applet(ard);
478     //menu_misc.add_applet("clock.adddaily");
479 }
480
481 }
482 }
483 }