/* $Id$ */ /* Copyright (c) 2013-2020 Pierre Pronchery */ /* This file is part of DeforaOS Desktop Accessories */ /* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include "clock.h" #define _(string) gettext(string) /* Clock */ /* private */ /* types */ struct _Clock { /* internal */ guint source; /* widgets */ GtkWidget * window; /* alarms */ GtkListStore * al_store; GtkWidget * al_view; /* clock */ GtkWidget * cl_toggle; GtkWidget * cl_day; GtkWidget * cl_month; GtkWidget * cl_year; GtkWidget * cl_hour; GtkWidget * cl_minute; GtkWidget * cl_second; /* timers */ GtkListStore * ti_store; GtkWidget * ti_view; /* actions */ GtkWidget * apply; }; typedef enum _ClockAlarmColumn { CAC_ACTIVE = 0, CAC_TITLE, CAC_TIME } ClockAlarmColumn; #define CAC_LAST CAC_TIME #define CAC_COUNT (CAC_LAST + 1) typedef enum _ClockTimerColumn { CTC_ACTIVE = 0, CTC_TITLE, CTC_TIME } ClockTimerColumn; #define CTC_LAST CTC_TIME #define CTC_COUNT (CTC_LAST + 1) /* prototypes */ /* useful */ static int _clock_error(Clock * clock, char const * message, int ret); /* callbacks */ static void _clock_on_apply(gpointer data); static void _clock_on_close(gpointer data); static gboolean _clock_on_timeout(gpointer data); static void _clock_on_toggled(gpointer data); static gboolean _clock_on_window_closex(gpointer data); /* alarm */ static void _clock_on_alarm_delete(gpointer data); static void _clock_on_alarm_toggled(GtkCellRendererToggle * renderer, char * path, gpointer data); /* timer */ static void _clock_on_timer_delete(gpointer data); static void _clock_on_timer_toggled(GtkCellRendererToggle * renderer, char * path, gpointer data); /* public */ /* functions */ /* clock_new */ static void _new_alarms(Clock * clock, GtkWidget * notebook); static void _new_alarms_on_new(gpointer data); static void _new_alarms_on_title_edited(GtkCellRendererText * renderer, gchar * path, gchar * text, gpointer data); static void _new_date(Clock * clock, GtkWidget * notebook); static void _new_timers(Clock * clock, GtkWidget * notebook); static void _new_timers_on_new(gpointer data); static void _new_timers_on_title_edited(GtkCellRendererText * renderer, gchar * path, gchar * text, gpointer data); Clock * clock_new(void) { Clock * clock; GtkWidget * vbox; GtkWidget * hbox; GtkWidget * widget; if((clock = object_new(sizeof(*clock))) == NULL) return NULL; clock->window = gtk_dialog_new(); gtk_window_set_default_size(GTK_WINDOW(clock->window), 200, 300); #if GTK_CHECK_VERSION(2, 6, 0) gtk_window_set_icon_name(GTK_WINDOW(clock->window), "appointment-soon"); #endif gtk_window_set_position(GTK_WINDOW(clock->window), GTK_WIN_POS_CENTER); gtk_window_set_title(GTK_WINDOW(clock->window), _("Date and time settings")); g_signal_connect_swapped(clock->window, "delete-event", G_CALLBACK( _clock_on_window_closex), clock); #if GTK_CHECK_VERSION(2, 14, 0) vbox = gtk_dialog_get_content_area(GTK_DIALOG(clock->window)); #else vbox = GTK_DIALOG(clock->window)->vbox; #endif /* notebook */ widget = gtk_notebook_new(); _new_date(clock, widget); _new_alarms(clock, widget); _new_timers(clock, widget); gtk_box_pack_start(GTK_BOX(vbox), widget, TRUE, TRUE, 0); /* button box */ #if GTK_CHECK_VERSION(2, 14, 0) hbox = gtk_dialog_get_action_area(GTK_DIALOG(clock->window)); #else hbox = GTK_DIALOG(clock->window)->action_area; #endif clock->apply = gtk_button_new_from_stock(GTK_STOCK_APPLY); gtk_widget_set_sensitive(clock->apply, FALSE); g_signal_connect_swapped(clock->apply, "clicked", G_CALLBACK( _clock_on_apply), clock); gtk_container_add(GTK_CONTAINER(hbox), clock->apply); widget = gtk_button_new_from_stock(GTK_STOCK_CLOSE); g_signal_connect_swapped(widget, "clicked", G_CALLBACK(_clock_on_close), clock); gtk_container_add(GTK_CONTAINER(hbox), widget); clock->source = g_timeout_add(1000, _clock_on_timeout, clock); _clock_on_timeout(clock); gtk_widget_show_all(clock->window); return clock; } static void _new_alarms(Clock * clock, GtkWidget * notebook) { GtkWidget * vbox; GtkWidget * widget; GtkToolItem * toolitem; GtkCellRenderer * renderer; GtkTreeViewColumn * column; #if GTK_CHECK_VERSION(3, 0, 0) vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); #else vbox = gtk_vbox_new(FALSE, 0); #endif /* toolbar */ widget = gtk_toolbar_new(); toolitem = gtk_tool_button_new(NULL, _("New alarm")); gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "gtk-new"); g_signal_connect_swapped(toolitem, "clicked", G_CALLBACK( _new_alarms_on_new), clock); gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); toolitem = gtk_separator_tool_item_new(); gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); toolitem = gtk_tool_button_new(NULL, _("Copy")); gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "gtk-copy"); gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); toolitem = gtk_tool_button_new(NULL, _("Paste")); gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "gtk-paste"); gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); toolitem = gtk_separator_tool_item_new(); gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); toolitem = gtk_tool_button_new(NULL, _("Delete")); gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "gtk-delete"); g_signal_connect_swapped(toolitem, "clicked", G_CALLBACK( _clock_on_alarm_delete), clock); gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, TRUE, 0); /* view */ widget = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); clock->al_store = gtk_list_store_new(CAC_COUNT, G_TYPE_BOOLEAN, /* CAC_ACTIVE */ G_TYPE_STRING, /* CAC_TITLE */ G_TYPE_STRING); /* CAC_TIME */ clock->al_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL( clock->al_store)); /* active */ renderer = gtk_cell_renderer_toggle_new(); g_signal_connect(renderer, "toggled", G_CALLBACK( _clock_on_alarm_toggled), clock); column = gtk_tree_view_column_new_with_attributes(NULL, renderer, "active", CAC_ACTIVE, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(clock->al_view), column); /* title */ renderer = gtk_cell_renderer_text_new(); g_object_set(G_OBJECT(renderer), "editable", TRUE, NULL); g_signal_connect(renderer, "edited", G_CALLBACK( _new_alarms_on_title_edited), clock); column = gtk_tree_view_column_new_with_attributes(_("Title"), renderer, "text", CAC_TITLE, NULL); gtk_tree_view_column_set_expand(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(clock->al_view), column); /* time */ renderer = gtk_cell_renderer_text_new(); /* FIXME popup when editing */ column = gtk_tree_view_column_new_with_attributes(_("Time"), renderer, "text", CAC_TIME, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(clock->al_view), column); gtk_container_add(GTK_CONTAINER(widget), clock->al_view); gtk_box_pack_start(GTK_BOX(vbox), widget, TRUE, TRUE, 0); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, gtk_label_new(_("Alarms"))); } static void _new_alarms_on_new(gpointer data) { Clock * clock = data; GtkTreeIter iter; gtk_list_store_append(clock->al_store, &iter); gtk_list_store_set(clock->al_store, &iter, CAC_ACTIVE, FALSE, CAC_TITLE, _("Alarm"), -1); } static void _new_alarms_on_title_edited(GtkCellRendererText * renderer, gchar * path, gchar * text, gpointer data) { Clock * clock = data; GtkTreeModel * model = GTK_TREE_MODEL(clock->al_store); GtkTreeIter iter; (void) renderer; if(gtk_tree_model_get_iter_from_string(model, &iter, path) != TRUE) return; gtk_list_store_set(clock->al_store, &iter, CAC_TITLE, text, -1); } static void _new_date(Clock * clock, GtkWidget * notebook) { GtkWidget * vbox; GtkWidget * hbox; GtkWidget * widget; char const * p; #if GTK_CHECK_VERSION(3, 0, 0) vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4); #else vbox = gtk_vbox_new(FALSE, 4); #endif /* toggle */ clock->cl_toggle = gtk_check_button_new_with_mnemonic( _("_Set the time and date:")); g_signal_connect_swapped(clock->cl_toggle, "toggled", G_CALLBACK( _clock_on_toggled), clock); gtk_box_pack_start(GTK_BOX(vbox), clock->cl_toggle, FALSE, TRUE, 0); /* date */ #if GTK_CHECK_VERSION(3, 0, 0) hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); #else hbox = gtk_hbox_new(FALSE, 4); #endif widget = gtk_label_new(_("Date: ")); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0); /* day */ clock->cl_day = gtk_spin_button_new_with_range(1.0, 31.0, 1.0); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(clock->cl_day), 0); gtk_widget_set_sensitive(clock->cl_day, FALSE); gtk_box_pack_start(GTK_BOX(hbox), clock->cl_day, TRUE, TRUE, 0); /* month */ clock->cl_month = gtk_spin_button_new_with_range(1.0, 12.0, 1.0); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(clock->cl_month), 0); gtk_widget_set_sensitive(clock->cl_month, FALSE); gtk_box_pack_start(GTK_BOX(hbox), clock->cl_month, TRUE, TRUE, 0); /* year */ clock->cl_year = gtk_spin_button_new_with_range(1970.0, 2038.0, 1.0); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(clock->cl_year), 0); gtk_widget_set_sensitive(clock->cl_year, FALSE); gtk_box_pack_start(GTK_BOX(hbox), clock->cl_year, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); /* time */ #if GTK_CHECK_VERSION(3, 0, 0) hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4); #else hbox = gtk_hbox_new(FALSE, 4); #endif widget = gtk_label_new(_("Time: ")); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0); /* hour */ clock->cl_hour = gtk_spin_button_new_with_range(0.0, 23.0, 1.0); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(clock->cl_hour), 0); gtk_widget_set_sensitive(clock->cl_hour, FALSE); gtk_box_pack_start(GTK_BOX(hbox), clock->cl_hour, TRUE, TRUE, 0); /* minutes */ clock->cl_minute = gtk_spin_button_new_with_range(0.0, 59.0, 1.0); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(clock->cl_minute), 0); gtk_widget_set_sensitive(clock->cl_minute, FALSE); gtk_box_pack_start(GTK_BOX(hbox), clock->cl_minute, TRUE, TRUE, 0); /* seconds */ clock->cl_second = gtk_spin_button_new_with_range(0.0, 61.0, 1.0); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(clock->cl_second), 0); gtk_widget_set_sensitive(clock->cl_second, FALSE); gtk_box_pack_start(GTK_BOX(hbox), clock->cl_second, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); /* timezone */ if((p = getenv("TZ")) != NULL) { #if GTK_CHECK_VERSION(3, 0, 0) hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); #else hbox = gtk_hbox_new(FALSE, 0); #endif widget = gtk_label_new(_("Timezone: ")); gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0); /* FIXME make it an editable combo box (with drop-down list) */ widget = gtk_label_new(p); #if GTK_CHECK_VERSION(3, 0, 0) g_object_set(widget, "halign", GTK_ALIGN_START, NULL); #else gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5); #endif gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); } /* automatic update */ /* FIXME add a button to start ntpdate? */ gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, gtk_label_new(_("Clock"))); } static void _new_timers(Clock * clock, GtkWidget * notebook) { GtkWidget * vbox; GtkWidget * widget; GtkToolItem * toolitem; GtkCellRenderer * renderer; GtkTreeViewColumn * column; #if GTK_CHECK_VERSION(3, 0, 0) vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); #else vbox = gtk_vbox_new(FALSE, 0); #endif /* toolbar */ widget = gtk_toolbar_new(); toolitem = gtk_tool_button_new(NULL, _("New timer")); gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "gtk-new"); g_signal_connect_swapped(toolitem, "clicked", G_CALLBACK( _new_timers_on_new), clock); gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); toolitem = gtk_separator_tool_item_new(); gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); toolitem = gtk_tool_button_new(NULL, _("Copy")); gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "gtk-copy"); gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); toolitem = gtk_tool_button_new(NULL, _("Paste")); gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "gtk-paste"); gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); toolitem = gtk_separator_tool_item_new(); gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); toolitem = gtk_tool_button_new(NULL, _("Delete")); gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "gtk-delete"); g_signal_connect_swapped(toolitem, "clicked", G_CALLBACK( _clock_on_timer_delete), clock); gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, TRUE, 0); /* view */ widget = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); clock->ti_store = gtk_list_store_new(CTC_COUNT, G_TYPE_BOOLEAN, /* CTC_ACTIVE */ G_TYPE_STRING, /* CTC_TITLE */ G_TYPE_STRING); /* CTC_TIME */ clock->ti_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL( clock->ti_store)); /* active */ renderer = gtk_cell_renderer_toggle_new(); g_signal_connect(renderer, "toggled", G_CALLBACK( _clock_on_timer_toggled), clock); column = gtk_tree_view_column_new_with_attributes(NULL, renderer, "active", CTC_ACTIVE, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(clock->ti_view), column); /* title */ renderer = gtk_cell_renderer_text_new(); g_object_set(G_OBJECT(renderer), "editable", TRUE, NULL); g_signal_connect(renderer, "edited", G_CALLBACK( _new_timers_on_title_edited), clock); column = gtk_tree_view_column_new_with_attributes(_("Title"), renderer, "text", CTC_TITLE, NULL); gtk_tree_view_column_set_expand(column, TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(clock->ti_view), column); /* duration */ renderer = gtk_cell_renderer_text_new(); /* FIXME popup when editing */ column = gtk_tree_view_column_new_with_attributes(_("Duration"), renderer, "text", CTC_TIME, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(clock->ti_view), column); gtk_container_add(GTK_CONTAINER(widget), clock->ti_view); gtk_box_pack_start(GTK_BOX(vbox), widget, TRUE, TRUE, 0); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), vbox, gtk_label_new(_("Timers"))); } static void _new_timers_on_new(gpointer data) { Clock * clock = data; GtkTreeIter iter; gtk_list_store_append(clock->ti_store, &iter); gtk_list_store_set(clock->ti_store, &iter, CTC_ACTIVE, FALSE, CTC_TITLE, _("Timer"), -1); } static void _new_timers_on_title_edited(GtkCellRendererText * renderer, gchar * path, gchar * text, gpointer data) { Clock * clock = data; GtkTreeModel * model = GTK_TREE_MODEL(clock->ti_store); GtkTreeIter iter; (void) renderer; if(gtk_tree_model_get_iter_from_string(model, &iter, path) != TRUE) return; gtk_list_store_set(clock->ti_store, &iter, CTC_TITLE, text, -1); } /* clock_delete */ void clock_delete(Clock * clock) { if(clock->source != 0) g_source_remove(clock->source); gtk_widget_destroy(clock->window); object_delete(clock); } /* private */ /* functions */ /* useful */ /* clock_error */ static int _clock_error(Clock * clock, char const * message, int ret) { GtkWidget * dialog; dialog = gtk_message_dialog_new(GTK_WINDOW(clock->window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, #if GTK_CHECK_VERSION(2, 6, 0) "%s", _("Error")); gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), #endif "%s", message); gtk_window_set_title(GTK_WINDOW(dialog), _("Error")); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return ret; } /* callbacks */ /* clock_on_apply */ static void _clock_on_apply(gpointer data) { Clock * clock = data; struct tm t; struct timeval tv; memset(&t, 0, sizeof(t)); t.tm_mday = gtk_spin_button_get_value(GTK_SPIN_BUTTON(clock->cl_day)); t.tm_mon = gtk_spin_button_get_value(GTK_SPIN_BUTTON(clock->cl_month)) - 1; t.tm_year = gtk_spin_button_get_value(GTK_SPIN_BUTTON(clock->cl_year)) - 1900; t.tm_hour = gtk_spin_button_get_value(GTK_SPIN_BUTTON(clock->cl_hour)); t.tm_min = gtk_spin_button_get_value(GTK_SPIN_BUTTON(clock->cl_minute)); t.tm_sec = gtk_spin_button_get_value(GTK_SPIN_BUTTON(clock->cl_second)); tv.tv_sec = mktime(&t); tv.tv_usec = 0; if(settimeofday(&tv, NULL) != 0) _clock_error(clock, strerror(errno), 1); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(clock->cl_toggle), FALSE); } /* clock_on_close */ static void _clock_on_close(gpointer data) { Clock * clock = data; gtk_widget_hide(clock->window); gtk_main_quit(); } /* clock_on_timeout */ static gboolean _clock_on_timeout(gpointer data) { Clock * clock = data; struct timeval tv; struct tm t; /* do not update if the time is being set */ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(clock->cl_toggle))) return TRUE; if(gettimeofday(&tv, NULL) != 0 || localtime_r(&tv.tv_sec, &t) == NULL) /* XXX report error */ return TRUE; /* date */ gtk_spin_button_set_value(GTK_SPIN_BUTTON(clock->cl_day), t.tm_mday); gtk_spin_button_set_value(GTK_SPIN_BUTTON(clock->cl_month), t.tm_mon + 1); gtk_spin_button_set_value(GTK_SPIN_BUTTON(clock->cl_year), t.tm_year + 1900); /* time */ gtk_spin_button_set_value(GTK_SPIN_BUTTON(clock->cl_hour), t.tm_hour); gtk_spin_button_set_value(GTK_SPIN_BUTTON(clock->cl_minute), t.tm_min); gtk_spin_button_set_value(GTK_SPIN_BUTTON(clock->cl_second), t.tm_sec); return TRUE; } /* clock_on_toggled */ static void _clock_on_toggled(gpointer data) { Clock * clock = data; gboolean sensitive; sensitive = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( clock->cl_toggle)); gtk_widget_set_sensitive(clock->cl_day, sensitive); gtk_widget_set_sensitive(clock->cl_month, sensitive); gtk_widget_set_sensitive(clock->cl_year, sensitive); gtk_widget_set_sensitive(clock->cl_hour, sensitive); gtk_widget_set_sensitive(clock->cl_minute, sensitive); gtk_widget_set_sensitive(clock->cl_second, sensitive); gtk_widget_set_sensitive(clock->apply, sensitive); if(sensitive == FALSE) _clock_on_timeout(clock); } /* clock_on_window_closex */ static gboolean _clock_on_window_closex(gpointer data) { Clock * clock = data; gtk_widget_hide(clock->window); gtk_main_quit(); return TRUE; } /* alarm */ /* clock_on_alarm_delete */ static void _clock_on_alarm_delete(gpointer data) { Clock * clock = data; GtkTreeSelection * treesel; GList * rows; GList * s; GtkTreeModel * model; GtkTreePath * path; GtkTreeIter iter; treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(clock->al_view)); if((rows = gtk_tree_selection_get_selected_rows(treesel, &model)) == NULL) return; for(s = rows; s != NULL; s = s->next) { if((path = s->data) == NULL) continue; s->data = gtk_tree_row_reference_new(model, path); gtk_tree_path_free(path); } for(s = rows; s != NULL; s = s->next) { if(s->data == NULL) continue; if((path = gtk_tree_row_reference_get_path(s->data)) == NULL) continue; gtk_tree_model_get_iter(model, &iter, path); gtk_tree_path_free(path); /* FIXME really implement */ gtk_list_store_remove(GTK_LIST_STORE(model), &iter); } g_list_foreach(rows, (GFunc)gtk_tree_row_reference_free, NULL); g_list_free(rows); } /* clock_on_alarm_toggled */ static void _clock_on_alarm_toggled(GtkCellRendererToggle * renderer, char * path, gpointer data) { Clock * clock = data; GtkTreeIter iter; gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(clock->al_store), &iter, path); gtk_list_store_set(clock->al_store, &iter, CAC_ACTIVE, !gtk_cell_renderer_toggle_get_active(renderer), -1); /* FIXME really implement */ } /* timer */ /* clock_on_timer_delete */ static void _clock_on_timer_delete(gpointer data) { Clock * clock = data; GtkTreeSelection * treesel; GList * rows; GList * s; GtkTreeModel * model; GtkTreePath * path; GtkTreeIter iter; treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW(clock->ti_view)); if((rows = gtk_tree_selection_get_selected_rows(treesel, &model)) == NULL) return; for(s = rows; s != NULL; s = s->next) { if((path = s->data) == NULL) continue; s->data = gtk_tree_row_reference_new(model, path); gtk_tree_path_free(path); } for(s = rows; s != NULL; s = s->next) { if(s->data == NULL) continue; if((path = gtk_tree_row_reference_get_path(s->data)) == NULL) continue; gtk_tree_model_get_iter(model, &iter, path); gtk_tree_path_free(path); /* FIXME really implement */ gtk_list_store_remove(GTK_LIST_STORE(model), &iter); } g_list_foreach(rows, (GFunc)gtk_tree_row_reference_free, NULL); g_list_free(rows); } /* clock_on_timer_toggled */ static void _clock_on_timer_toggled(GtkCellRendererToggle * renderer, char * path, gpointer data) { Clock * clock = data; GtkTreeIter iter; gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(clock->ti_store), &iter, path); gtk_list_store_set(clock->ti_store, &iter, CTC_ACTIVE, !gtk_cell_renderer_toggle_get_active(renderer), -1); /* FIXME really implement */ }