~ubuntu-branches/ubuntu/saucy/alarm-clock-applet/saucy

« back to all changes in this revision

Viewing changes to src/alarm-list-window.c

  • Committer: Bazaar Package Importer
  • Author(s): Chow Loong Jin
  • Date: 2010-03-17 09:02:44 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100317090244-ni0ye04mva2hxe10
Tags: 0.3.0-1
* New upstream release
* debian/control:
  + No change bump of Standards-Version to 3.8.4
  + Update build-deps:
    - Drop libglade, libpanel-applet, libgnomevfs2, libgnome{2,ui}
    - Add libxml2-dev and libunique-dev, intltool
* debian/patches/01_update-alarms-eta,patch:
  + Dropped, applied upstream
* debian/(alarm-clock-applet.1, alarm-clock-applet.manpages):
  + Add manpage for alarm-clock-applet, now that the binary is moved to
    /usr/bin.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * alarms-list.d -- Alarm list window
 
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
 
 
26
#include "alarm-list-window.h"
 
27
#include "alarm-settings.h"
 
28
#include "alarm-actions.h"
 
29
 
 
30
static void
 
31
alarm_list_window_selection_changed (GtkTreeSelection *, gpointer);
 
32
 
 
33
static gboolean
 
34
alarm_list_window_update_timer (gpointer);
 
35
 
 
36
static gint
 
37
alarm_list_window_sort_iter_compare (GtkTreeModel *model, 
 
38
                                     GtkTreeIter *a, GtkTreeIter *b,
 
39
                                     gpointer data);
 
40
 
 
41
void
 
42
alarm_list_window_rows_reordered (GtkTreeModel *model,
 
43
                                  GtkTreePath  *path,
 
44
                                  GtkTreeIter  *iter,
 
45
                                  gpointer      arg3,
 
46
                                  gpointer      data);
 
47
 
 
48
void
 
49
alarm_list_window_enable_toggled (GtkCellRendererToggle *cell_renderer,
 
50
                                  gchar *path,
 
51
                                  gpointer data);
 
52
 
 
53
void
 
54
alarm_list_window_snooze_menu_activated (GtkMenuItem *item, gpointer data);
 
55
 
 
56
void
 
57
alarm_list_window_snooze_menu_custom_activated (GtkMenuItem *menuitem, gpointer data);
 
58
 
 
59
void
 
60
alarm_list_window_snooze_menu_update (AlarmListWindow *list_window);
 
61
 
 
62
static void
 
63
alarm_list_window_update_row (AlarmListWindow *list_window, GtkTreeIter *iter);
 
64
 
 
65
/**
 
66
 * Create a new Alarm List Window
 
67
 */
 
68
AlarmListWindow *
 
69
alarm_list_window_new (AlarmApplet *applet)
 
70
{
 
71
        AlarmListWindow *list_window;
 
72
    GtkBuilder *builder = applet->ui;
 
73
    GtkTreeSelection *selection;
 
74
    GtkTreeSortable *sortable;
 
75
        
 
76
    // Initialize struct
 
77
        list_window = g_new0 (AlarmListWindow, 1);
 
78
 
 
79
        list_window->applet = applet;
 
80
 
 
81
    // Widgets
 
82
        list_window->window = GTK_WINDOW (gtk_builder_get_object (builder, "alarm-list-window"));
 
83
        list_window->model = GTK_LIST_STORE (gtk_builder_get_object (builder, "alarms-liststore"));
 
84
        list_window->tree_view = GTK_TREE_VIEW (gtk_builder_get_object (builder, "alarm-list-view"));
 
85
 
 
86
    list_window->new_button = GTK_WIDGET (gtk_builder_get_object (builder, "new-button"));
 
87
    list_window->edit_button = GTK_WIDGET (gtk_builder_get_object (builder, "edit-button"));
 
88
    list_window->delete_button = GTK_WIDGET (gtk_builder_get_object (builder, "delete-button"));
 
89
    list_window->enable_button = GTK_WIDGET (gtk_builder_get_object (builder, "enable-button"));
 
90
    list_window->stop_button = GTK_WIDGET (gtk_builder_get_object (builder, "stop-button"));
 
91
    list_window->snooze_button = GTK_WIDGET (gtk_builder_get_object (builder, "snooze-button"));
 
92
    list_window->snooze_menu = GTK_WIDGET (gtk_builder_get_object (builder, "snooze-menu"));
 
93
    
 
94
    // Set up window accelerator group
 
95
    list_window->accel_group = gtk_accel_group_new ();
 
96
    gtk_window_add_accel_group (list_window->window, list_window->accel_group);
 
97
    
 
98
    // Connect some signals
 
99
    selection = gtk_tree_view_get_selection (list_window->tree_view);
 
100
    g_signal_connect (selection, "changed", 
 
101
                      G_CALLBACK (alarm_list_window_selection_changed), applet);
 
102
 
 
103
    // Update view every second for pretty countdowns
 
104
    g_timeout_add (500, (GSourceFunc) alarm_list_window_update_timer, applet);
 
105
 
 
106
    // Set up sorting
 
107
    sortable = GTK_TREE_SORTABLE (list_window->model);
 
108
    
 
109
    gtk_tree_sortable_set_sort_func (sortable, SORTID_TIME_REMAINING,
 
110
        alarm_list_window_sort_iter_compare, GINT_TO_POINTER (SORTID_TIME_REMAINING),
 
111
        NULL);
 
112
 
 
113
    // Set initial sort order
 
114
    gtk_tree_sortable_set_sort_column_id (sortable, SORTID_TIME_REMAINING, GTK_SORT_ASCENDING);
 
115
 
 
116
    // Populate with alarms
 
117
    alarm_list_window_alarms_add (list_window, applet->alarms);
 
118
    
 
119
    // Update snooze menu
 
120
    alarm_list_window_snooze_menu_update (list_window);
 
121
 
 
122
        return list_window;
 
123
}
 
124
 
 
125
/**
 
126
 * Show and present list window
 
127
 */
 
128
void
 
129
alarm_list_window_show (AlarmListWindow *list_window)
 
130
{
 
131
        gtk_window_present_with_time (list_window->window, gtk_get_current_event_time());
 
132
}
 
133
 
 
134
/**
 
135
 * Hide list window
 
136
 */
 
137
void
 
138
alarm_list_window_hide (AlarmListWindow *list_window)
 
139
{
 
140
        gtk_widget_hide (GTK_WIDGET (list_window->window));
 
141
}
 
142
 
 
143
/**
 
144
 * Toggle visibility of list window
 
145
 */
 
146
void
 
147
alarm_list_window_toggle (AlarmListWindow *list_window)
 
148
{
 
149
        if (GTK_WIDGET_VISIBLE (list_window->window)) {
 
150
                alarm_list_window_hide (list_window);
 
151
        } else {
 
152
                alarm_list_window_show (list_window);
 
153
        }
 
154
}
 
155
 
 
156
 
 
157
 
 
158
//
 
159
// ALARM LIST MODEL:
 
160
//
 
161
 
 
162
/**
 
163
 * Find alarm in the model
 
164
 *
 
165
 * Returns TRUE if found and sets iter to the location
 
166
 * Returns FALSE otherwise
 
167
 */
 
168
gboolean
 
169
alarm_list_window_find_alarm (GtkTreeModel *model,
 
170
                              Alarm *alarm,
 
171
                              GtkTreeIter *iter)
 
172
{
 
173
    GtkTreeIter it;
 
174
    Alarm *a;
 
175
    gboolean valid;
 
176
 
 
177
    valid = gtk_tree_model_get_iter_first (model, &it);
 
178
 
 
179
    while (valid) {
 
180
        gtk_tree_model_get (model, &it, COLUMN_ALARM, &a, -1);
 
181
        
 
182
        if (a == alarm) {
 
183
            if (iter) {
 
184
                *iter = it;
 
185
            }
 
186
            return TRUE;
 
187
        }
 
188
        
 
189
        valid = gtk_tree_model_iter_next(model, &it);
 
190
    }
 
191
 
 
192
    return FALSE;
 
193
}
 
194
 
 
195
/**
 
196
 * Check whether the list window contains an alarm
 
197
 */
 
198
gboolean
 
199
alarm_list_window_contains (AlarmListWindow *list_window, Alarm *alarm)
 
200
{
 
201
    return alarm_list_window_find_alarm (GTK_TREE_MODEL (list_window->model), alarm, NULL);
 
202
}
 
203
 
 
204
/**
 
205
 * Update the row in the list at the position specified by iter
 
206
 */
 
207
static void
 
208
alarm_list_window_update_row (AlarmListWindow *list_window, GtkTreeIter *iter)
 
209
{
 
210
    GtkTreeModel *model = GTK_TREE_MODEL (list_window->model);
 
211
    Alarm *a;
 
212
 
 
213
    gchar tmp[200];
 
214
    gchar *tmp2;
 
215
    struct tm *tm;
 
216
    
 
217
    const gchar *type_col;
 
218
    const gchar *time_format;    
 
219
    GString *time_col;
 
220
    gchar *label_col;
 
221
 
 
222
    // Get the alarm at iter
 
223
    gtk_tree_model_get (GTK_TREE_MODEL (model), iter,
 
224
                        COLUMN_ALARM, &a,
 
225
                        -1);
 
226
    
 
227
    // If alarm is running (active), show remaining time
 
228
    if (a->active) {
 
229
        tm = alarm_get_remain (a);
 
230
    } else {
 
231
        tm = alarm_get_time (a);
 
232
    }
 
233
    
 
234
    if (a->type == ALARM_TYPE_CLOCK) {
 
235
        type_col = ALARM_ICON;
 
236
        time_format = TIME_COL_CLOCK_FORMAT;
 
237
    } else {
 
238
        type_col = TIMER_ICON;
 
239
        time_format = TIME_COL_TIMER_FORMAT;
 
240
    }
 
241
 
 
242
    // Create time column
 
243
    strftime(tmp, sizeof(tmp), time_format, tm);
 
244
 
 
245
    time_col = g_string_new (tmp);
 
246
    if (a->type == ALARM_TYPE_CLOCK && a->repeat != ALARM_REPEAT_NONE) {
 
247
        tmp2 = alarm_repeat_to_pretty (a->repeat);
 
248
        g_string_append_printf (time_col, TIME_COL_REPEAT_FORMAT, tmp2);
 
249
        g_free (tmp2);
 
250
    }
 
251
    
 
252
    // Create label column
 
253
    tmp2 = g_markup_escape_text (a->message, -1);
 
254
    if (a->triggered) {
 
255
        label_col = g_strdup_printf (LABEL_COL_TRIGGERED_FORMAT, tmp2);
 
256
    } else {
 
257
        label_col = g_strdup_printf (LABEL_COL_FORMAT, tmp2);
 
258
    }
 
259
    g_free (tmp2);
 
260
    
 
261
        gtk_list_store_set (GTK_LIST_STORE (model), iter,
 
262
                        COLUMN_TYPE, type_col,
 
263
                        COLUMN_TIME, time_col->str,
 
264
                        COLUMN_LABEL, label_col,
 
265
                        COLUMN_ACTIVE, a->active,
 
266
                        COLUMN_TRIGGERED, a->triggered,
 
267
                        -1);
 
268
 
 
269
    // Restore icon visibility when an alarm is cleared / snoozed
 
270
    if (!a->triggered) {
 
271
        gtk_list_store_set (GTK_LIST_STORE (model), iter, COLUMN_SHOW_ICON, TRUE, -1);
 
272
    }
 
273
 
 
274
    
 
275
    g_string_free (time_col, TRUE);
 
276
    g_free (label_col);
 
277
}
 
278
 
 
279
/**
 
280
 * Add alarm to the list window
 
281
 */
 
282
void
 
283
alarm_list_window_alarm_add (AlarmListWindow *list_window, Alarm *alarm)
 
284
{
 
285
    GtkListStore *store = list_window->model;
 
286
    GtkTreeIter iter;
 
287
 
 
288
    gtk_list_store_append (store, &iter);
 
289
    gtk_list_store_set (store, &iter, COLUMN_ALARM, alarm, -1);
 
290
    
 
291
    alarm_list_window_update_row (list_window, &iter);
 
292
}
 
293
 
 
294
/**
 
295
 * Update alarm in the list window
 
296
 */
 
297
void
 
298
alarm_list_window_alarm_update (AlarmListWindow *list_window, Alarm *alarm)
 
299
{
 
300
    GtkTreeIter iter;
 
301
 
 
302
    g_debug ("AlarmListWindow alarm_update: %p (%s)", alarm, alarm->message);
 
303
 
 
304
    if (alarm_list_window_find_alarm (GTK_TREE_MODEL (list_window->model), alarm, &iter)) {
 
305
        alarm_list_window_update_row (list_window, &iter);
 
306
    } else {
 
307
        g_warning ("AlarmListWindow alarm_update: Could not find alarm %p", alarm);
 
308
    }
 
309
}
 
310
 
 
311
/**
 
312
 * Remove alarm from the list window
 
313
 */
 
314
void
 
315
alarm_list_window_alarm_remove (AlarmListWindow *list_window, Alarm *alarm)
 
316
{
 
317
    GtkTreeIter iter;
 
318
 
 
319
    if (alarm_list_window_find_alarm (GTK_TREE_MODEL (list_window->model), alarm, &iter)) {
 
320
        gtk_list_store_remove (list_window->model, &iter);
 
321
    } else {
 
322
        g_warning ("AlarmListWindow alarm_remove: Could not find alarm %p", alarm);
 
323
    }
 
324
}
 
325
 
 
326
/**
 
327
 * Add several alarms to the list window
 
328
 */
 
329
void
 
330
alarm_list_window_alarms_add (AlarmListWindow *list_window, GList *alarms)
 
331
{
 
332
    AlarmApplet *applet = list_window->applet;
 
333
    
 
334
    GList *l = NULL;
 
335
    Alarm *a;
 
336
 
 
337
    for (l = applet->alarms; l; l = l->next) {
 
338
                a = ALARM (l->data);
 
339
 
 
340
        alarm_list_window_alarm_add (list_window, a);
 
341
    }
 
342
}
 
343
 
 
344
/**
 
345
 * Update the alarm view every second
 
346
 */
 
347
static gboolean
 
348
alarm_list_window_update_timer (gpointer data)
 
349
{
 
350
    AlarmApplet *applet = (AlarmApplet *)data;
 
351
    GtkTreeModel *model = GTK_TREE_MODEL (applet->list_window->model);
 
352
    GtkTreeIter iter;
 
353
    Alarm *a;
 
354
    gboolean show_icon;
 
355
    gboolean valid;
 
356
 
 
357
    valid = gtk_tree_model_get_iter_first (model, &iter);
 
358
 
 
359
    while (valid) {
 
360
        alarm_list_window_update_row (applet->list_window, &iter);
 
361
        
 
362
        gtk_tree_model_get (model, &iter, 
 
363
                            COLUMN_ALARM, &a,
 
364
                            COLUMN_SHOW_ICON, &show_icon, -1);
 
365
 
 
366
        // Blink icon on triggered alarms
 
367
        if (a->triggered) {
 
368
            gtk_list_store_set (GTK_LIST_STORE (model), &iter, COLUMN_SHOW_ICON, !show_icon, -1);
 
369
        }
 
370
        
 
371
        valid = gtk_tree_model_iter_next(model, &iter);
 
372
    }
 
373
    
 
374
    // Keep updating
 
375
    return TRUE;
 
376
}
 
377
 
 
378
/**
 
379
 * Sort compare function
 
380
 */
 
381
static gint
 
382
alarm_list_window_sort_iter_compare (GtkTreeModel *model, 
 
383
                                     GtkTreeIter *i1, GtkTreeIter *i2,
 
384
                                     gpointer data)
 
385
{
 
386
    gint sortcol = GPOINTER_TO_INT (data);
 
387
    Alarm *a1, *a2;
 
388
    gint ret = 0;
 
389
 
 
390
    // Fetch ze alarms
 
391
    gtk_tree_model_get (model, i1, COLUMN_ALARM, &a1, -1);
 
392
    gtk_tree_model_get (model, i2, COLUMN_ALARM, &a2, -1);
 
393
 
 
394
    switch (sortcol) {
 
395
        case SORTID_TIME_REMAINING:
 
396
        {
 
397
            // Sort by remaining time
 
398
            time_t t1, t2;
 
399
 
 
400
            // Show active alarms first
 
401
            if (a1->active && a2->active) {
 
402
                t1 = alarm_get_remain_seconds (a1);
 
403
                t2 = alarm_get_remain_seconds (a2);
 
404
                
 
405
            } else if (a1->active && !a2->active) {
 
406
                t1 = 0;
 
407
                t2 = 1;
 
408
            } else if (!a1->active && a2->active) {
 
409
                t1 = 1;
 
410
                t2 = 0;
 
411
            } else {
 
412
                // Both inactive, sort by time
 
413
                t1 = a1->time;
 
414
                t2 = a2->time;
 
415
            }
 
416
 
 
417
            ret = t1 - t2;
 
418
        }
 
419
            break;
 
420
        default:
 
421
            g_return_val_if_reached (0);
 
422
    }
 
423
 
 
424
    return ret;
 
425
}
 
426
 
 
427
 
 
428
//
 
429
// TREE VIEW:
 
430
//
 
431
 
 
432
/**
 
433
 * Get the selected alarm
 
434
 */
 
435
Alarm *
 
436
alarm_list_window_get_selected_alarm (AlarmListWindow *list_window)
 
437
{
 
438
    GtkTreeModel *model;
 
439
        GtkTreeSelection *selection;
 
440
        GtkTreeIter iter;
 
441
        Alarm *a;
 
442
 
 
443
    g_assert (list_window);
 
444
        
 
445
        // Fetch selection
 
446
        selection = gtk_tree_view_get_selection (list_window->tree_view);
 
447
 
 
448
        if (!gtk_tree_selection_get_selected(selection, &model, &iter)) {
 
449
                // No alarms selected
 
450
                //g_debug ("get_selected_alarm: No alarms selected!");
 
451
                return NULL;
 
452
        }
 
453
    
 
454
        gtk_tree_model_get (model, &iter, COLUMN_ALARM, &a, -1);
 
455
        
 
456
        // gtk_tree_model_get () will increase the reference count 
 
457
        // of the alarms each time it's called. We dereference it
 
458
        // here so they can be properly freed later with g_object_unref()
 
459
    // Ugh, we use gtk_tree_model_get a lot, is there no other way?
 
460
        //g_object_unref (a);
 
461
        
 
462
        return a;
 
463
}
 
464
 
 
465
/**
 
466
 * Set the selected alarm
 
467
 */
 
468
static void
 
469
alarm_list_window_select_alarm (AlarmListWindow *list_window, Alarm *alarm)
 
470
{
 
471
    GtkTreeModel *model = GTK_TREE_MODEL (list_window->model);
 
472
    GtkTreeSelection *selection;
 
473
    GtkTreeIter iter;
 
474
 
 
475
    if (!alarm_list_window_find_alarm (model, alarm, &iter)) {
 
476
        g_warning ("AlarmListWindow select_alarm: Alarm %p not found!", alarm);
 
477
        return;
 
478
    }
 
479
    
 
480
    selection = gtk_tree_view_get_selection (list_window->tree_view);
 
481
 
 
482
    gtk_tree_selection_select_iter (selection, &iter);
 
483
}
 
484
 
 
485
 
 
486
/**
 
487
 * Selection changed in tree view
 
488
 *
 
489
 * Here we update the associated actions
 
490
 */
 
491
void
 
492
alarm_list_window_selection_changed (GtkTreeSelection *selection, gpointer data)
 
493
{
 
494
    AlarmApplet *applet = (AlarmApplet *)data;
 
495
    AlarmListWindow *list_window = applet->list_window;
 
496
    Alarm *a = list_window->selected_alarm;
 
497
 
 
498
    // If rows have just been reordered, retain the selected row
 
499
    // But only if the reordering was triggered by a click on the toggle cell
 
500
    if (list_window->reordered && list_window->toggled) {
 
501
        list_window->reordered = FALSE;
 
502
        list_window->toggled = FALSE;
 
503
 
 
504
        alarm_list_window_select_alarm (list_window, list_window->selected_alarm);
 
505
        return;
 
506
    }
 
507
 
 
508
    // Reset reordered and toggled flags
 
509
    list_window->reordered = FALSE;
 
510
    list_window->toggled = FALSE;
 
511
    
 
512
    // Update actions
 
513
    alarm_applet_actions_update_sensitive (applet);
 
514
    alarm_action_update_enabled (applet);
 
515
    
 
516
    // Update selected alarm (might be NULL)
 
517
    list_window->selected_alarm = alarm_list_window_get_selected_alarm (list_window);
 
518
 
 
519
    if (list_window->selected_alarm) {
 
520
        // Update snooze button menu
 
521
        if (list_window->selected_alarm->type == ALARM_TYPE_CLOCK) {
 
522
            // We always snooze for 9 mins on alarm clocks
 
523
            gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (list_window->snooze_button), NULL);
 
524
        } else {
 
525
            // Allow custom snooze mins
 
526
            gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (list_window->snooze_button), list_window->snooze_menu);
 
527
        }
 
528
    }
 
529
    
 
530
    
 
531
    g_debug ("AlarmListWindow: selection-changed from %s (%p) to %s (%p)",
 
532
        (a) ? a->message : "<none>", a,
 
533
        (list_window->selected_alarm) ? list_window->selected_alarm->message : "<none>",
 
534
        list_window->selected_alarm);
 
535
}
 
536
 
 
537
/**
 
538
 * Toggle cell changed
 
539
 */
 
540
void
 
541
alarm_list_window_enable_toggled (GtkCellRendererToggle *cell_renderer,
 
542
                                  gchar *path,
 
543
                                  gpointer data)
 
544
{
 
545
    AlarmApplet *applet = (AlarmApplet *)data;
 
546
    AlarmListWindow *list_window = applet->list_window;
 
547
    GtkTreeModel *model = GTK_TREE_MODEL (list_window->model);
 
548
    GtkTreeIter iter;
 
549
    Alarm *a;
 
550
    
 
551
    if (gtk_tree_model_get_iter_from_string (model, &iter, path)) {
 
552
        gtk_tree_model_get (model, &iter, COLUMN_ALARM, &a, -1);
 
553
 
 
554
        g_debug ("AlarmListWindow enable toggled on %p", a);
 
555
        
 
556
        // Reset reordered flag
 
557
        list_window->reordered = FALSE;
 
558
        
 
559
        // Select the toggled alarm
 
560
        alarm_list_window_select_alarm (list_window, a);
 
561
 
 
562
        // Let selection_changed know an alarm was just toggled so
 
563
        // this alarm is re-selected if the rows are reordered
 
564
        list_window->toggled = TRUE;
 
565
        
 
566
        // Activate the enabled action
 
567
        gtk_action_activate (GTK_ACTION (applet->action_enabled));
 
568
    }
 
569
}
 
570
 
 
571
/**
 
572
 * Rows reordered callback
 
573
 */
 
574
void
 
575
alarm_list_window_rows_reordered (GtkTreeModel *model,
 
576
                                  GtkTreePath  *path,
 
577
                                  GtkTreeIter  *iter,
 
578
                                  gpointer      arg3,
 
579
                                  gpointer      data)
 
580
{
 
581
    AlarmApplet *applet = (AlarmApplet *)data;
 
582
    AlarmListWindow *list_window = applet->list_window;
 
583
    Alarm *a;
 
584
 
 
585
    // Return if list_window is not set. This happens during initialization.
 
586
    if (!list_window)
 
587
        return;
 
588
    
 
589
    // Retain selected alarm
 
590
    a = alarm_list_window_get_selected_alarm (list_window);
 
591
    
 
592
    // Signal to selection_changed that the rows have been reordered.
 
593
    list_window->reordered = TRUE;
 
594
}
 
595
 
 
596
 
 
597
//
 
598
// TOOLBAR:
 
599
//
 
600
 
 
601
/**
 
602
 * Snooze menu item activated
 
603
 */
 
604
void
 
605
alarm_list_window_snooze_menu_activated (GtkMenuItem *menuitem,
 
606
                                         gpointer          data)
 
607
{
 
608
    AlarmApplet *applet = (AlarmApplet *)data;
 
609
    gchar **parts;
 
610
    guint i;
 
611
    guint mins;
 
612
 
 
613
//    g_debug ("AlarmListWindow: snooze-menu activated %s to %d", 
 
614
//        gtk_menu_item_get_label (menuitem), gtk_check_menu_item_get_active (menuitem));
 
615
 
 
616
    if (gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menuitem))) {
 
617
        // Determine #mins from the name of the menu item (hackish)
 
618
        // Assumes name follows the format {foo}-{mins}
 
619
        parts = g_strsplit (gtk_widget_get_name (GTK_WIDGET (menuitem)), "-", 0);
 
620
        for (i = 0; parts[i] != NULL; i++)
 
621
            // Loop to the last element
 
622
            ;
 
623
        
 
624
        mins = g_strtod (parts[i-1], NULL);
 
625
        
 
626
        g_debug ("AlarmListWindow: snooze-menu activated: Snooze for %d mins!", mins);
 
627
 
 
628
        applet->snooze_mins = mins;
 
629
 
 
630
        gtk_action_activate (applet->action_snooze);
 
631
    }
 
632
}
 
633
 
 
634
/**
 
635
 * Snooze menu custom item activated
 
636
 */
 
637
void
 
638
alarm_list_window_snooze_menu_custom_activated (GtkMenuItem *menuitem,
 
639
                                                gpointer          data)
 
640
{
 
641
    AlarmApplet *applet = (AlarmApplet *)data;
 
642
    AlarmListWindow *list_window = applet->list_window;
 
643
    GtkWidget *dialog, *spin;
 
644
    gint response;
 
645
    Alarm *a;
 
646
    guint mins;
 
647
 
 
648
    g_debug ("AlarmListWindow: snooze-menu custom activated");
 
649
    
 
650
    dialog = GTK_WIDGET (gtk_builder_get_object (applet->ui, "snooze-dialog"));
 
651
    spin = GTK_WIDGET (gtk_builder_get_object (applet->ui, "snooze-spin"));
 
652
 
 
653
    // Run dialog, hide for later use
 
654
        response = gtk_dialog_run (GTK_DIALOG (dialog));
 
655
        gtk_widget_hide (GTK_WIDGET (dialog));
 
656
 
 
657
        if (response == GTK_RESPONSE_OK) {
 
658
        mins = (gint) gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin));
 
659
        if ((a = alarm_list_window_get_selected_alarm (list_window))) {
 
660
            g_debug ("AlarmListWindow: Snooze Custom: %s for %d mins", a->message, mins);
 
661
            alarm_snooze (a, mins * 60);
 
662
        }
 
663
    }
 
664
}
 
665
 
 
666
/**
 
667
 * Update the snooze menu according to the applet's snooze_mins property
 
668
 */
 
669
void
 
670
alarm_list_window_snooze_menu_update (AlarmListWindow *list_window)
 
671
{
 
672
    AlarmApplet *applet = (AlarmApplet *)list_window->applet;
 
673
    GtkMenuShell *menu = GTK_MENU_SHELL(list_window->snooze_menu);
 
674
    gchar *target_name = g_strdup_printf ("snooze-menu-%d", applet->snooze_mins);
 
675
 
 
676
    const gchar *name;
 
677
    GtkMenuItem *item;
 
678
    GList *l = NULL;
 
679
 
 
680
    g_debug ("AlarmListWindow: menu_update to %d", applet->snooze_mins);
 
681
 
 
682
    block_list (menu->children, alarm_list_window_snooze_menu_activated);
 
683
    
 
684
    for (l = menu->children; l != NULL; l = l->next) {
 
685
        item = GTK_MENU_ITEM (l->data);
 
686
        name = gtk_widget_get_name (GTK_WIDGET (item));
 
687
        if (g_strcmp0 (name, target_name) == 0) {
 
688
            g_object_set (item, "active", TRUE, NULL);
 
689
            
 
690
            g_debug ("AlarmListWindow: menu_update to %s", name);
 
691
        }
 
692
    }
 
693
 
 
694
    unblock_list (menu->children, alarm_list_window_snooze_menu_activated);
 
695
    
 
696
    g_free (target_name);
 
697
}