~ubuntu-branches/debian/sid/alarm-clock-applet/sid

« back to all changes in this revision

Viewing changes to src/ui.c

  • Committer: Bazaar Package Importer
  • Author(s): Chow Loong Jin
  • Date: 2009-05-30 23:24:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090530232427-88on1j2ily4ajxdz
Tags: upstream-0.2.6
Import upstream version 0.2.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ui.c - Alarm Clock applet UI routines
 
3
 * 
 
4
 * Copyright (C) 2007-2008 Johannes H. Jensen <joh@pseudoberries.com>
 
5
 * 
 
6
 * This program is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU General Public License
 
8
 * as published by the Free Software Foundation; either version 2
 
9
 * of the License, or (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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
19
 * 
 
20
 * Authors:
 
21
 *              Johannes H. Jensen <joh@pseudoberries.com>
 
22
 */
 
23
 
 
24
#include <time.h>
 
25
#include <string.h>
 
26
#ifdef HAVE_LIBNOTIFY
 
27
#include <libnotify/notify.h>
 
28
#endif
 
29
 
 
30
#include "alarm-applet.h"
 
31
#include "ui.h"
 
32
#include "alarms-list.h"
 
33
 
 
34
enum
 
35
{
 
36
    PIXBUF_COL,
 
37
    TEXT_COL,
 
38
    N_COLUMNS
 
39
};
 
40
 
 
41
void
 
42
display_error_dialog (const gchar *message, const gchar *secondary_text, GtkWindow *parent)
 
43
{
 
44
        GtkWidget *dialog;
 
45
 
 
46
        dialog = gtk_message_dialog_new (parent,
 
47
                                                                        GTK_DIALOG_DESTROY_WITH_PARENT,
 
48
                                                                        GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
 
49
                                                                        message);
 
50
        
 
51
        if (secondary_text != NULL) {
 
52
                gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
 
53
                                                                                                  secondary_text);
 
54
        }
 
55
        
 
56
        gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
 
57
        gtk_dialog_run (GTK_DIALOG (dialog));
 
58
        gtk_widget_destroy (dialog);
 
59
}
 
60
 
 
61
 
 
62
// TODO: Should display any triggered alarms / etc.
 
63
void
 
64
alarm_applet_label_update (AlarmApplet *applet)
 
65
{
 
66
        Alarm *a;
 
67
        struct tm *tm;
 
68
        guint hour, min, sec, now;
 
69
        gchar *tmp;
 
70
        
 
71
        if (!applet->upcoming_alarm) {
 
72
                // No upcoming alarms
 
73
                g_object_set (applet->label, "label", ALARM_DEF_LABEL, NULL);
 
74
                return;
 
75
        }
 
76
        
 
77
        a = applet->upcoming_alarm;
 
78
        
 
79
        if (applet->label_type == LABEL_TYPE_REMAIN) {
 
80
                /* Remaining time */
 
81
                tm = alarm_get_remain (a);
 
82
        } else {
 
83
                /* Alarm time */
 
84
                tm = alarm_get_time (a);
 
85
        }
 
86
        
 
87
        tmp = g_strdup_printf(_("%02d:%02d:%02d"), tm->tm_hour, tm->tm_min, tm->tm_sec);
 
88
        
 
89
        g_object_set(applet->label, "label", tmp, NULL);
 
90
        g_free(tmp);
 
91
}
 
92
 
 
93
// TODO: Refactor for more fancy tooltip with alarm summary.
 
94
void
 
95
alarm_applet_update_tooltip (AlarmApplet *applet)
 
96
{
 
97
        struct tm *time, *remain;
 
98
        GList *l;
 
99
        Alarm *a;
 
100
        GString *tip;
 
101
        guint count = 0;
 
102
 
 
103
        tip = g_string_new ("");
 
104
        
 
105
        // Find all active alarms
 
106
        for (l = applet->alarms; l; l = l->next) {
 
107
                a = ALARM (l->data);
 
108
                
 
109
                if (!a->active) continue;
 
110
                
 
111
                count++;
 
112
                
 
113
                time   = alarm_get_time (a);
 
114
                remain = alarm_get_remain (a);
 
115
                
 
116
                g_string_append_printf (tip, _("\n(%c) <b>%s</b> @%02d:%02d:%02d (-%02d:%02d:%02d)"), (a->type == ALARM_TYPE_TIMER) ? 'T' : 'A', a->message,
 
117
                                                                                                                time->tm_hour, time->tm_min, time->tm_sec, remain->tm_hour, remain->tm_min, remain->tm_sec);
 
118
        }
 
119
        
 
120
        if (count > 0) {
 
121
                tip = g_string_prepend (tip, _("Active alarms:"));
 
122
        } else {
 
123
                tip = g_string_append (tip, _("No active alarms"));
 
124
        }
 
125
        
 
126
        tip = g_string_append (tip, _("\n\nClick to snooze alarms"));
 
127
        tip = g_string_append (tip, _("\nDouble click to edit alarms"));
 
128
        
 
129
        gtk_widget_set_tooltip_markup (GTK_WIDGET (applet->parent), tip->str);
 
130
        
 
131
        g_string_free (tip, TRUE);
 
132
}
 
133
 
 
134
static gboolean
 
135
is_separator (GtkTreeModel *model, GtkTreeIter *iter, gpointer sep_index)
 
136
{
 
137
        GtkTreePath *path;
 
138
        gboolean result;
 
139
 
 
140
        path = gtk_tree_model_get_path (model, iter);
 
141
        result = gtk_tree_path_get_indices (path)[0] == GPOINTER_TO_INT (sep_index);
 
142
        gtk_tree_path_free (path);
 
143
 
 
144
        return result;
 
145
}
 
146
 
 
147
/*
 
148
 * Shamelessly stolen from gnome-da-capplet.c
 
149
 */
 
150
void
 
151
fill_combo_box (GtkComboBox *combo_box, GList *list, const gchar *custom_label)
 
152
{
 
153
        GList *l;
 
154
        GtkTreeModel *model;
 
155
        GtkCellRenderer *renderer;
 
156
        GtkTreeIter iter;
 
157
        GdkPixbuf *pixbuf = NULL;
 
158
        GtkIconTheme *theme;
 
159
        AlarmListEntry *entry;
 
160
        
 
161
        g_debug ("fill_combo_box... %d", g_list_length (list));
 
162
 
 
163
//      if (theme == NULL) {
 
164
        theme = gtk_icon_theme_get_default ();
 
165
//      }
 
166
 
 
167
        gtk_combo_box_set_row_separator_func (combo_box, is_separator,
 
168
                                          GINT_TO_POINTER (g_list_length (list)), NULL);
 
169
 
 
170
        model = GTK_TREE_MODEL (gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_STRING));
 
171
        gtk_combo_box_set_model (combo_box, model);
 
172
        
 
173
        gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo_box));
 
174
 
 
175
        renderer = gtk_cell_renderer_pixbuf_new ();
 
176
 
 
177
        /* not all cells have a pixbuf, this prevents the combo box to shrink */
 
178
        gtk_cell_renderer_set_fixed_size (renderer, -1, 22);
 
179
        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, FALSE);
 
180
        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer,
 
181
                                        "pixbuf", PIXBUF_COL,
 
182
                                        NULL);
 
183
 
 
184
        renderer = gtk_cell_renderer_text_new ();
 
185
        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE);
 
186
        gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer,
 
187
                                        "text", TEXT_COL,
 
188
                                        NULL);
 
189
 
 
190
        for (l = list; l != NULL; l = g_list_next (l)) {
 
191
                entry = (AlarmListEntry *) l->data;
 
192
                
 
193
                pixbuf = gtk_icon_theme_load_icon (theme, entry->icon, 22, 0, NULL);
 
194
                
 
195
                gtk_list_store_append (GTK_LIST_STORE (model), &iter);
 
196
                gtk_list_store_set (GTK_LIST_STORE (model), &iter,
 
197
                                        PIXBUF_COL, pixbuf,
 
198
                                        TEXT_COL, entry->name,
 
199
                                        -1);
 
200
                
 
201
                if (pixbuf)
 
202
                        g_object_unref (pixbuf);
 
203
        }
 
204
 
 
205
        gtk_list_store_append (GTK_LIST_STORE (model), &iter);
 
206
        gtk_list_store_set (GTK_LIST_STORE (model), &iter, -1);
 
207
        gtk_list_store_append (GTK_LIST_STORE (model), &iter);
 
208
        gtk_list_store_set (GTK_LIST_STORE (model), &iter,
 
209
                        PIXBUF_COL, NULL,
 
210
                        TEXT_COL, custom_label,
 
211
                        -1);
 
212
}
 
213
 
 
214
 
 
215
static gboolean
 
216
button_cb (GtkWidget *widget,
 
217
                                                GdkEventButton *event,
 
218
                                                gpointer data)
 
219
{
 
220
        AlarmApplet *applet = (AlarmApplet *)data;
 
221
        
 
222
        g_debug("BUTTON: %d", event->button);
 
223
        
 
224
        /* React only to left mouse button */
 
225
        if (event->button == 2 || event->button == 3) {
 
226
                return FALSE;
 
227
        }
 
228
        
 
229
        if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) {
 
230
                /* Double click: Open list alarms */
 
231
                list_alarms_dialog_display (applet);
 
232
        } else {
 
233
                alarm_applet_snooze_alarms (applet);
 
234
        }
 
235
        
 
236
        /* Show edit alarms dialog */
 
237
        //display_list_alarms_dialog (applet);
 
238
        
 
239
        return TRUE;
 
240
}
 
241
 
 
242
/* Taken from the GeyesApplet */
 
243
static void
 
244
applet_back_change (PanelApplet                 *a,
 
245
                                        PanelAppletBackgroundType       type,
 
246
                                        GdkColor                        *color,
 
247
                                        GdkPixmap                       *pixmap,
 
248
                                        AlarmApplet                     *applet) 
 
249
{
 
250
        /* taken from the TrashApplet */
 
251
        GtkRcStyle *rc_style;
 
252
        GtkStyle *style;
 
253
 
 
254
        /* reset style */
 
255
        gtk_widget_set_style (GTK_WIDGET (applet->parent), NULL);
 
256
        rc_style = gtk_rc_style_new ();
 
257
        gtk_widget_modify_style (GTK_WIDGET (applet->parent), rc_style);
 
258
        gtk_rc_style_unref (rc_style);
 
259
 
 
260
        switch (type) {
 
261
                case PANEL_COLOR_BACKGROUND:
 
262
                        gtk_widget_modify_bg (GTK_WIDGET (applet->parent),
 
263
                                        GTK_STATE_NORMAL, color);
 
264
                        break;
 
265
 
 
266
                case PANEL_PIXMAP_BACKGROUND:
 
267
                        style = gtk_style_copy (GTK_WIDGET (
 
268
                                        applet->parent)->style);
 
269
                        if (style->bg_pixmap[GTK_STATE_NORMAL])
 
270
                                g_object_unref
 
271
                                        (style->bg_pixmap[GTK_STATE_NORMAL]);
 
272
                        style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref
 
273
                                (pixmap);
 
274
                        gtk_widget_set_style (GTK_WIDGET (applet->parent),
 
275
                                        style);
 
276
                        g_object_unref (style);
 
277
                        break;
 
278
 
 
279
                case PANEL_NO_BACKGROUND:
 
280
                default:
 
281
                        break;
 
282
        }
 
283
 
 
284
}
 
285
 
 
286
/* Taken from gnome-panel/button-widget.c */
 
287
void
 
288
alarm_applet_icon_update (AlarmApplet *applet)
 
289
{
 
290
        static const gchar *prev_icon = ALARM_ICON;
 
291
        
 
292
        GtkWidget *w;
 
293
        GdkPixbuf *icon;
 
294
        gint      size, pbsize;
 
295
        const gchar *icon_name = ALARM_ICON;
 
296
        
 
297
        if (applet->upcoming_alarm && applet->upcoming_alarm->type == ALARM_TYPE_TIMER) {
 
298
                icon_name = TIMER_ICON;
 
299
        }
 
300
        
 
301
        w = GTK_WIDGET (applet->parent);
 
302
        
 
303
        if (panel_applet_get_orient (applet->parent) == PANEL_APPLET_ORIENT_UP ||
 
304
                panel_applet_get_orient (applet->parent) == PANEL_APPLET_ORIENT_DOWN)
 
305
                size = w->allocation.height;
 
306
        else
 
307
                size = w->allocation.width;
 
308
        
 
309
        if (size < 22)
 
310
                size = 16;
 
311
        else if (size < 24)
 
312
                size = 22;
 
313
        else if (size < 32)
 
314
                size = 24;
 
315
        else if (size < 48)
 
316
                size = 32;
 
317
        else if (size < 64)
 
318
                size = 48;
 
319
        else
 
320
                size = 64;
 
321
 
 
322
        // Reload icon only if the size is different.}
 
323
        icon = gtk_image_get_pixbuf (GTK_IMAGE (applet->icon));
 
324
        
 
325
        if (icon) {
 
326
                if (IS_HORIZONTAL (applet->parent))
 
327
                        pbsize = gdk_pixbuf_get_height (icon);
 
328
                else
 
329
                        pbsize = gdk_pixbuf_get_width (icon);
 
330
                
 
331
                if (prev_icon == icon_name && pbsize == size) {
 
332
                        // Do nothing
 
333
                        //g_debug ("load_icon: Existing size the same.");
 
334
                        return;
 
335
                }
 
336
        }
 
337
        
 
338
        g_debug ("Resizing icon to %dx%d...", size, size);
 
339
        
 
340
        icon = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
 
341
                                                                         icon_name,
 
342
                                                                         size,
 
343
                                                                         0, NULL);
 
344
        
 
345
        if (icon == NULL) {
 
346
                g_critical ("Icon not found.");
 
347
                return;
 
348
        }
 
349
        
 
350
        g_object_set (applet->icon, "pixbuf", icon, NULL);
 
351
        
 
352
        if (icon)
 
353
                g_object_unref (icon);
 
354
        
 
355
        prev_icon = icon_name;
 
356
}
 
357
 
 
358
static void
 
359
change_size_cb (GtkWidget         *widget,
 
360
                                GtkAllocation *alloc,
 
361
                                AlarmApplet       *applet) 
 
362
{       
 
363
        alarm_applet_icon_update (applet);
 
364
}
 
365
 
 
366
 
 
367
 
 
368
static void
 
369
update_orient (AlarmApplet *applet)
 
370
{
 
371
        const gchar *text;
 
372
        int          min_width;
 
373
        gdouble      new_angle;
 
374
        gdouble      angle;
 
375
        gint             width;
 
376
        GtkWidget       *box;
 
377
        
 
378
        if (IS_HORIZONTAL (applet->parent) && ORIENT_IS_HORIZONTAL (applet->orient)) {
 
379
                // Nothing to do, both old and new orientation is horizontal.
 
380
                return;
 
381
        }
 
382
        
 
383
        /* Do we need to repack? */
 
384
        if (IS_HORIZONTAL (applet->parent) != ORIENT_IS_HORIZONTAL (applet->orient)) {
 
385
                g_debug ("update_orient: REPACK");
 
386
                
 
387
                // Add new
 
388
                if (IS_HORIZONTAL (applet->parent))
 
389
                        box = gtk_hbox_new(FALSE, 6);
 
390
                else
 
391
                        box = gtk_vbox_new(FALSE, 6);
 
392
                
 
393
                /* Keep children */
 
394
                g_object_ref (applet->icon);
 
395
                g_object_ref (applet->label);
 
396
                
 
397
                /* Remove old */
 
398
                gtk_container_remove (GTK_CONTAINER (applet->box), applet->icon);
 
399
                gtk_container_remove (GTK_CONTAINER (applet->box), applet->label);
 
400
                gtk_container_remove (GTK_CONTAINER (applet->parent), applet->box);
 
401
                
 
402
                /* Pack */
 
403
                gtk_box_pack_start_defaults(GTK_BOX (box), applet->icon);
 
404
                gtk_box_pack_start_defaults(GTK_BOX (box), applet->label);
 
405
                
 
406
                applet->box = box;
 
407
                
 
408
                /* Add to container and show */
 
409
                gtk_container_add (GTK_CONTAINER (applet->parent), box);
 
410
                gtk_widget_show_all (GTK_WIDGET (applet->parent));
 
411
        }
 
412
        
 
413
        switch (panel_applet_get_orient (applet->parent)) {
 
414
        case PANEL_APPLET_ORIENT_LEFT:
 
415
                new_angle = 270;
 
416
                break;
 
417
        case PANEL_APPLET_ORIENT_RIGHT:
 
418
                new_angle = 90;
 
419
                break;
 
420
        default:
 
421
                new_angle = 0;
 
422
                break;
 
423
        }
 
424
        
 
425
        
 
426
        angle = gtk_label_get_angle (GTK_LABEL (applet->label));
 
427
        if (angle != new_angle) {
 
428
                //unfix_size (cd);
 
429
                gtk_label_set_angle (GTK_LABEL (applet->label), new_angle);
 
430
        }
 
431
}
 
432
 
 
433
static void
 
434
orient_change_cb (PanelApplet *a,
 
435
                                          PanelAppletOrient orient,
 
436
                                          AlarmApplet *applet)
 
437
{
 
438
        g_debug ("applet_orient_change");
 
439
        
 
440
        update_orient (applet);
 
441
        
 
442
        // Store new orientation
 
443
        applet->orient = panel_applet_get_orient (applet->parent);
 
444
}
 
445
 
 
446
 
 
447
static void
 
448
unrealize_cb (GtkWidget *object, AlarmApplet *applet)
 
449
{
 
450
        alarm_applet_destroy (applet);
 
451
}
 
452
 
 
453
#ifdef HAVE_LIBNOTIFY
 
454
static void
 
455
alarm_applet_notification_action_cb (NotifyNotification *notify,
 
456
                                                                         gchar *action,
 
457
                                                                         gpointer data)
 
458
{
 
459
        Alarm *alarm = ALARM (data);
 
460
        
 
461
        g_debug ("NOTIFY ACTION: %s", action);
 
462
        
 
463
        if (strcmp (action, "clear") == 0) {
 
464
                g_debug ("NOTIFY CLEAR #%d", alarm->id);
 
465
                alarm_clear (alarm);
 
466
        } else {
 
467
                // "snooze"
 
468
                g_debug ("NOTIFY SNOOZE #%d", alarm->id);
 
469
                alarm_snooze (alarm);
 
470
        }
 
471
}
 
472
#endif
 
473
 
 
474
/* Taken from the battery applet */
 
475
gboolean
 
476
alarm_applet_notification_display (AlarmApplet *applet, Alarm *alarm)
 
477
{
 
478
#ifdef HAVE_LIBNOTIFY
 
479
        GError *error = NULL;
 
480
        //GdkPixbuf *icon;
 
481
        gboolean result;
 
482
        const gchar *message;
 
483
        const gchar *icon = (alarm->type == ALARM_TYPE_CLOCK) ? ALARM_ICON : TIMER_ICON;
 
484
        
 
485
        if (!notify_is_initted () && !notify_init (_("Alarm Applet")))
 
486
                return FALSE;
 
487
        
 
488
        message = alarm->message;
 
489
        
 
490
        applet->notify = notify_notification_new (_("Alarm!"), message, icon, GTK_WIDGET (applet->icon));
 
491
        
 
492
        notify_notification_set_timeout (applet->notify, NOTIFY_EXPIRES_NEVER);
 
493
        notify_notification_add_action (applet->notify, "clear", "Clear", alarm_applet_notification_action_cb, alarm, NULL);
 
494
        
 
495
        if (alarm->snooze) {
 
496
                notify_notification_add_action (applet->notify, "snooze", "Snooze", alarm_applet_notification_action_cb, alarm, NULL);
 
497
        }
 
498
 
 
499
        result = notify_notification_show (applet->notify, &error);
 
500
        
 
501
        if (error)
 
502
        {
 
503
           g_warning (error->message);
 
504
           g_error_free (error);
 
505
        }
 
506
 
 
507
        return result;
 
508
#else
 
509
        return FALSE;
 
510
#endif
 
511
}
 
512
 
 
513
gboolean
 
514
alarm_applet_notification_close (AlarmApplet *applet)
 
515
{
 
516
#ifdef HAVE_LIBNOTIFY
 
517
        gboolean result;
 
518
        GError *error = NULL;
 
519
        
 
520
        result = notify_notification_close (applet->notify, &error);
 
521
        
 
522
        if (error)
 
523
        {
 
524
           g_warning (error->message);
 
525
           g_error_free (error);
 
526
        }
 
527
        
 
528
        g_object_unref (applet->notify);
 
529
        applet->notify = NULL;
 
530
#endif
 
531
}
 
532
 
 
533
/*
 
534
 * Updates label etc
 
535
 */
 
536
static gboolean
 
537
alarm_applet_ui_update (AlarmApplet *applet)
 
538
{
 
539
        if (applet->show_label) {
 
540
                alarm_applet_label_update (applet);
 
541
        }
 
542
        
 
543
        alarm_applet_update_tooltip (applet);
 
544
        
 
545
        return TRUE;
 
546
}
 
547
 
 
548
void
 
549
alarm_applet_ui_init (AlarmApplet *applet)
 
550
{
 
551
        GtkWidget *hbox;
 
552
        GdkPixbuf *icon;
 
553
        
 
554
        /* Set up PanelApplet signals */
 
555
        g_signal_connect (G_OBJECT(applet->parent), "button-press-event",
 
556
                                          G_CALLBACK(button_cb), applet);
 
557
        
 
558
        g_signal_connect (G_OBJECT(applet->parent), "unrealize",
 
559
                                          G_CALLBACK(unrealize_cb), applet);
 
560
        
 
561
        g_signal_connect (G_OBJECT(applet->parent), "change-background",
 
562
                                          G_CALLBACK (applet_back_change), applet);
 
563
        
 
564
        g_signal_connect (G_OBJECT(applet->parent), "change-orient",
 
565
                                          G_CALLBACK (orient_change_cb), applet);
 
566
        
 
567
        g_signal_connect (G_OBJECT(applet->parent), "size-allocate",
 
568
                                          G_CALLBACK (change_size_cb), applet);
 
569
        
 
570
        /* Set up container box */
 
571
        if (IS_HORIZONTAL (applet->parent))
 
572
                applet->box = gtk_hbox_new(FALSE, 6);
 
573
        else
 
574
                applet->box = gtk_vbox_new(FALSE, 6);
 
575
        
 
576
        /* Store orientation for future reference */
 
577
        applet->orient = panel_applet_get_orient (applet->parent);
 
578
        
 
579
        /* Set up icon and label */
 
580
        applet->icon = gtk_image_new ();
 
581
        alarm_applet_icon_update (applet);
 
582
        
 
583
        applet->label = g_object_new(GTK_TYPE_LABEL,
 
584
                                                                 "label", ALARM_DEF_LABEL,
 
585
                                                                 "use-markup", TRUE,
 
586
                                                                 "visible", applet->show_label,
 
587
                                                                 "no-show-all", TRUE,                   /* So gtk_widget_show_all() won't set visible to TRUE */
 
588
                                                                 NULL);
 
589
        
 
590
        /* Set up UI updater */
 
591
        alarm_applet_ui_update (applet);
 
592
        applet->timer_id = g_timeout_add_seconds (1, (GSourceFunc)alarm_applet_ui_update, applet);
 
593
        
 
594
        /* Pack */
 
595
        gtk_box_pack_start_defaults(GTK_BOX (applet->box), applet->icon);
 
596
        gtk_box_pack_start_defaults(GTK_BOX (applet->box), applet->label);
 
597
        
 
598
        /* Update orientation */
 
599
        update_orient (applet);
 
600
        
 
601
        /* Add to container and show */
 
602
        gtk_container_add (GTK_CONTAINER (applet->parent), applet->box);
 
603
        gtk_widget_show_all (GTK_WIDGET (applet->parent));
 
604
        
 
605
        alarm_applet_update_tooltip (applet);
 
606
}
 
607
 
 
608
 
 
609
 
 
610
 
 
611
 
 
612
static void
 
613
menu_snooze_alarm_cb (BonoboUIComponent *component,
 
614
                                         AlarmApplet *applet,
 
615
                                         const gchar *cname)
 
616
{
 
617
        g_debug("menu_snooze_alarm");
 
618
        
 
619
        alarm_applet_snooze_alarms (applet);
 
620
}
 
621
 
 
622
static void
 
623
menu_clear_alarm_cb (BonoboUIComponent *component,
 
624
                                         AlarmApplet *applet,
 
625
                                         const gchar *cname)
 
626
{
 
627
        g_debug("menu_clear_alarm");
 
628
        
 
629
        alarm_applet_clear_alarms (applet);
 
630
}
 
631
 
 
632
static void
 
633
menu_list_alarms_cb (BonoboUIComponent *component,
 
634
                                         gpointer data,
 
635
                                         const gchar *cname)
 
636
{
 
637
        AlarmApplet *applet = (AlarmApplet *)data;
 
638
        list_alarms_dialog_display (applet);
 
639
}
 
640
 
 
641
static void
 
642
menu_preferences_cb (BonoboUIComponent *component,
 
643
                                         AlarmApplet *applet,
 
644
                                         const gchar *cname)
 
645
{
 
646
        /* Construct the preferences dialog and show it here */
 
647
        g_debug("preferences_dialog");
 
648
        
 
649
        preferences_dialog_display (applet);
 
650
}
 
651
 
 
652
static void
 
653
menu_about_cb (BonoboUIComponent *component,
 
654
                           AlarmApplet *applet,
 
655
                           const gchar *cname)
 
656
{
 
657
        /* Construct the about dialog and show it here */
 
658
        g_debug("about_dialog");
 
659
        
 
660
        static const gchar *const authors[] = {
 
661
            "Johannes H. Jensen <joh@pseudoberries.com>",
 
662
            NULL
 
663
    };
 
664
    static const gchar *const documenters[] = {
 
665
            "Johannes H. Jensen <joh@pseudoberries.com>",
 
666
            NULL
 
667
    };
 
668
    static const gchar *const artists[] = {
 
669
            "Lasse Gulvåg Sætre <lassegs@gmail.com>",
 
670
            NULL
 
671
    };
 
672
 
 
673
    gtk_show_about_dialog (NULL,
 
674
                                           "program-name",      ALARM_NAME,
 
675
                                           "title",             _("About " ALARM_NAME),
 
676
                           "version",       VERSION,
 
677
                           "copyright",     "\xC2\xA9 2007 Johannes H. Jensen",
 
678
                           "website",           "http://alarm-clock.pseudoberries.com/",
 
679
                           "authors",       authors,
 
680
                           "documenters",   documenters,
 
681
                           "artists",       artists, 
 
682
                           "logo-icon-name",ALARM_ICON,
 
683
                           NULL);
 
684
}
 
685
 
 
686
/*
 
687
 * Set up menu
 
688
 */
 
689
void
 
690
alarm_applet_menu_init (AlarmApplet *applet)
 
691
{
 
692
        GtkIconInfo *info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default(), SNOOZE_ICON, 16, 0);
 
693
        
 
694
        g_debug ("ICON: %s", gtk_icon_info_get_filename (info));
 
695
        
 
696
        static const gchar *menu_xml =
 
697
                "<popup name=\"button3\">\n"
 
698
                "   <menuitem name=\"Snooze Item\" "
 
699
                "                         verb=\"SnoozeAlarm\" "
 
700
                "                       _label=\"_Snooze alarms\" "
 
701
                "                  pixtype=\"filename\" "
 
702
                "                  pixname=\"%s\"/>\n"
 
703
                "   <menuitem name=\"Clear Item\" "
 
704
                "                         verb=\"ClearAlarm\" "
 
705
                "                       _label=\"_Clear alarms\" "
 
706
                "                  pixtype=\"stock\" "
 
707
                "                  pixname=\"gtk-clear\"/>\n"
 
708
                "   <separator/>\n"
 
709
                "   <menuitem name=\"List Alarms\" "
 
710
                "                         verb=\"ListAlarms\" "
 
711
                "                       _label=\"_Edit Alarms\" "
 
712
                "                  pixtype=\"stock\" "
 
713
                "                  pixname=\"gtk-edit\"/>\n"
 
714
                "   <menuitem name=\"Preferences Item\" "
 
715
                "             verb=\"Preferences\" "
 
716
                "           _label=\"_Preferences...\"\n"
 
717
                "          pixtype=\"stock\" "
 
718
                "          pixname=\"gtk-properties\"/>\n"
 
719
                "   <menuitem name=\"About Item\" "
 
720
                "             verb=\"About\" "
 
721
                "           _label=\"_About...\"\n"
 
722
                "          pixtype=\"stock\" "
 
723
                "          pixname=\"gtk-about\"/>\n"
 
724
                "</popup>\n";
 
725
        
 
726
        static const BonoboUIVerb menu_verbs [] = {
 
727
                        BONOBO_UI_VERB ("SnoozeAlarm", menu_snooze_alarm_cb),
 
728
                        BONOBO_UI_VERB ("ClearAlarm", menu_clear_alarm_cb),
 
729
                        BONOBO_UI_VERB ("ListAlarms", menu_list_alarms_cb),
 
730
                        BONOBO_UI_VERB ("Preferences", menu_preferences_cb),
 
731
                        BONOBO_UI_VERB ("About", menu_about_cb),
 
732
                        BONOBO_UI_VERB_END
 
733
        };
 
734
        
 
735
        gchar *xml = g_strdup_printf (menu_xml, gtk_icon_info_get_filename (info));
 
736
        
 
737
        panel_applet_setup_menu (PANEL_APPLET (applet->parent),
 
738
                                 xml,
 
739
                                 menu_verbs,
 
740
                                 applet);
 
741
        
 
742
        g_free (xml);
 
743
        gtk_icon_info_free (info);
 
744
}
 
745
 
 
746
 
 
747
 
 
748
/*
 
749
 * An error callback for MediaPlayers
 
750
 */
 
751
void
 
752
media_player_error_cb (MediaPlayer *player, GError *err, GtkWindow *parent)
 
753
{
 
754
        gchar *uri, *tmp;
 
755
        
 
756
        uri = media_player_get_uri (player);
 
757
        tmp = g_strdup_printf (_("%s: %s"), uri, err->message);
 
758
        
 
759
        g_critical (_("Could not play '%s': %s"), uri, err->message);
 
760
        display_error_dialog (_("Could not play"), tmp, parent);
 
761
        
 
762
        g_free (tmp);
 
763
        g_free (uri);
 
764
}
 
765
 
 
766