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