From a45b33e0dbc03ee82cf15513a7e014cc79b596c8 Mon Sep 17 00:00:00 2001 From: Rodrigo Moya Date: Fri, 4 Mar 2005 14:39:13 +0000 Subject: Fixes #72835 2005-03-04 Rodrigo Moya Fixes #72835 * gui/alarm-notify/alarm-notify-dialog.[ch] (alarm_notify_dialog): changed to return the dialog we create, and to run in the background. (dialog_response_cb): response callback for the dialog. * gui/alarm-notify/alarm-queue.c (alarm_queue_done): don't g_assert, just check for midnight_refresh pointer, and clear it up if not NULL. Also, traverse all clients with g_hash_table_foreach_remove. (free_client_alarms_cb, alarm_queue_remove_client, load_alarms): added missing cleanup code. (queue_midnight_refresh): don't g_assert, just check for midnigh_refresh pointer and clear it up if not NULL. (open_alarm_dialog): store the dialog returned by alarm_notify_dialog(). (tray_icon_destroyed_cb): destroy the dialog if still around. svn path=/trunk/; revision=28956 --- calendar/ChangeLog | 18 ++++++ calendar/gui/alarm-notify/alarm-notify-dialog.c | 73 +++++++++++++--------- calendar/gui/alarm-notify/alarm-notify-dialog.h | 9 +-- calendar/gui/alarm-notify/alarm-queue.c | 81 ++++++++++++++++++------- 4 files changed, 127 insertions(+), 54 deletions(-) diff --git a/calendar/ChangeLog b/calendar/ChangeLog index e3211fe153..29ef032209 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,21 @@ +2005-03-04 Rodrigo Moya + + Fixes #72835 + + * gui/alarm-notify/alarm-notify-dialog.[ch] (alarm_notify_dialog): + changed to return the dialog we create, and to run in the background. + (dialog_response_cb): response callback for the dialog. + + * gui/alarm-notify/alarm-queue.c (alarm_queue_done): don't g_assert, + just check for midnight_refresh pointer, and clear it up if not NULL. + Also, traverse all clients with g_hash_table_foreach_remove. + (free_client_alarms_cb, alarm_queue_remove_client, load_alarms): added + missing cleanup code. + (queue_midnight_refresh): don't g_assert, just check for midnigh_refresh + pointer and clear it up if not NULL. + (open_alarm_dialog): store the dialog returned by alarm_notify_dialog(). + (tray_icon_destroyed_cb): destroy the dialog if still around. + 2005-02-28 Harish Krishnaswamy Fixes #69556 diff --git a/calendar/gui/alarm-notify/alarm-notify-dialog.c b/calendar/gui/alarm-notify/alarm-notify-dialog.c index 8d60fb7c70..ee625c96f9 100644 --- a/calendar/gui/alarm-notify/alarm-notify-dialog.c +++ b/calendar/gui/alarm-notify/alarm-notify-dialog.c @@ -81,6 +81,36 @@ an_update_minutes_label (GtkSpinButton *sb, gpointer data) g_free (new_label); } +static void +dialog_response_cb (GtkDialog *dialog, guint response_id, gpointer user_data) +{ + int snooze_timeout; + AlarmNotify *an = user_data; + + switch (response_id) { + case AN_RESPONSE_EDIT: + (* an->func) (ALARM_NOTIFY_EDIT, -1, an->func_data); + break; + case AN_RESPONSE_SNOOZE: + snooze_timeout = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (an->snooze_time)); + (* an->func) (ALARM_NOTIFY_SNOOZE, snooze_timeout, an->func_data); + break; + case GTK_RESPONSE_CLOSE: + case GTK_RESPONSE_DELETE_EVENT: + (* an->func) (ALARM_NOTIFY_CLOSE, -1, an->func_data); + break; + } +} + +static void +dialog_destroyed_cb (GtkWidget *dialog, gpointer user_data) +{ + AlarmNotify *an = user_data; + + g_object_unref (an->xml); + g_free (an); +} + /** * alarm_notify_dialog: * @trigger: Trigger time for the alarm. @@ -96,9 +126,9 @@ an_update_minutes_label (GtkSpinButton *sb, gpointer data) * Runs the alarm notification dialog. The specified @func will be used to * notify the client about result of the actions in the dialog. * - * Return value: a pointer to the dialog structure if successful or NULL if an error occurs. + * Return value: a pointer to the dialog widget created or NULL if there is an error. **/ -void +GtkWidget * alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end, ECalComponentVType vtype, const char *summary, const char *description, const char *location, @@ -111,17 +141,15 @@ alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end, char *start, *end; char *icon_path; GList *icon_list; - int snooze_timeout; - g_return_if_fail (trigger != -1); + g_return_val_if_fail (trigger != -1, NULL); /* Only VEVENTs or VTODOs can have alarms */ - g_return_if_fail (vtype == E_CAL_COMPONENT_EVENT - || vtype == E_CAL_COMPONENT_TODO); - g_return_if_fail (summary != NULL); - g_return_if_fail (description != NULL); - g_return_if_fail (location != NULL); - g_return_if_fail (func != NULL); + g_return_val_if_fail (vtype == E_CAL_COMPONENT_EVENT || vtype == E_CAL_COMPONENT_TODO, NULL); + g_return_val_if_fail (summary != NULL, NULL); + g_return_val_if_fail (description != NULL, NULL); + g_return_val_if_fail (location != NULL, NULL); + g_return_val_if_fail (func != NULL, NULL); an = g_new0 (AlarmNotify, 1); @@ -132,7 +160,7 @@ alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end, if (!an->xml) { g_message ("alarm_notify_dialog(): Could not load the Glade XML file!"); g_free (an); - return; + return NULL; } an->dialog = glade_xml_get_widget (an->xml, "alarm-notify"); @@ -149,7 +177,7 @@ alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end, g_message ("alarm_notify_dialog(): Could not find all widgets in Glade file!"); g_object_unref (an->xml); g_free (an); - return; + return NULL; } gtk_widget_realize (an->dialog); @@ -199,20 +227,9 @@ alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end, g_list_free (icon_list); } - switch (gtk_dialog_run (GTK_DIALOG (an->dialog))) { - case AN_RESPONSE_EDIT: - (* an->func) (ALARM_NOTIFY_EDIT, -1, an->func_data); - break; - case AN_RESPONSE_SNOOZE: - snooze_timeout = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (an->snooze_time)); - (* an->func) (ALARM_NOTIFY_SNOOZE, snooze_timeout, an->func_data); - break; - case GTK_RESPONSE_CLOSE: - case GTK_RESPONSE_DELETE_EVENT: - break; - } - gtk_widget_destroy (an->dialog); - - g_object_unref (an->xml); - g_free (an); + g_signal_connect (G_OBJECT (an->dialog), "response", G_CALLBACK (dialog_response_cb), an); + g_signal_connect (G_OBJECT (an->dialog), "destroy", G_CALLBACK (dialog_destroyed_cb), an); + gtk_widget_show (an->dialog); + + return an->dialog; } diff --git a/calendar/gui/alarm-notify/alarm-notify-dialog.h b/calendar/gui/alarm-notify/alarm-notify-dialog.h index 91861aaa99..cf01f76af9 100644 --- a/calendar/gui/alarm-notify/alarm-notify-dialog.h +++ b/calendar/gui/alarm-notify/alarm-notify-dialog.h @@ -24,6 +24,7 @@ #include #include #include +#include @@ -35,10 +36,10 @@ typedef enum { typedef void (* AlarmNotifyFunc) (AlarmNotifyResult result, int snooze_mins, gpointer data); -void alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end, - ECalComponentVType vtype, const char *summary, - const char *description, const char *location, - AlarmNotifyFunc func, gpointer func_data); +GtkWidget *alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end, + ECalComponentVType vtype, const char *summary, + const char *description, const char *location, + AlarmNotifyFunc func, gpointer func_data); #endif diff --git a/calendar/gui/alarm-notify/alarm-queue.c b/calendar/gui/alarm-notify/alarm-queue.c index 9e1519d1a6..da3028d37e 100644 --- a/calendar/gui/alarm-notify/alarm-queue.c +++ b/calendar/gui/alarm-notify/alarm-queue.c @@ -147,7 +147,10 @@ queue_midnight_refresh (void) time_t midnight; icaltimezone *zone; - g_assert (midnight_refresh_id == NULL); + if (midnight_refresh_id != NULL) { + alarm_remove (midnight_refresh_id); + midnight_refresh_id = NULL; + } zone = config_data_get_timezone (); @@ -180,7 +183,11 @@ midnight_refresh_cb (gpointer alarm_id, time_t trigger, gpointer data) /* Re-schedule the midnight update */ - midnight_refresh_id = NULL; + if (midnight_refresh_id != NULL) { + alarm_remove (midnight_refresh_id); + midnight_refresh_id = NULL; + } + queue_midnight_refresh (); } @@ -408,6 +415,7 @@ load_alarms (ClientAlarms *ca, time_t start, time_t end) /* create the live query */ if (ca->query) { + g_signal_handlers_disconnect_matched (ca->query, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, ca); g_object_unref (ca->query); ca->query = NULL; } @@ -781,6 +789,11 @@ tray_icon_destroyed_cb (GtkWidget *tray, gpointer user_data) if (tray_data->cqa != NULL) remove_queued_alarm (tray_data->cqa, tray_data->alarm_id, TRUE, TRUE); + if (tray_data->alarm_dialog != NULL) { + gtk_widget_destroy (tray_data->alarm_dialog); + tray_data->alarm_dialog = NULL; + } + if (tray_data->summary != NULL) { g_free (tray_data->summary); tray_data->summary = NULL; @@ -818,14 +831,14 @@ open_alarm_dialog (TrayIconData *tray_data) qa = lookup_queued_alarm (tray_data->cqa, tray_data->alarm_id); if (qa) { gtk_widget_hide (tray_data->tray_icon); - alarm_notify_dialog (tray_data->trigger, - qa->instance->occur_start, - qa->instance->occur_end, - e_cal_component_get_vtype (tray_data->comp), - tray_data->summary, - tray_data->description, - tray_data->location, - notify_dialog_cb, tray_data); + tray_data->alarm_dialog = alarm_notify_dialog (tray_data->trigger, + qa->instance->occur_start, + qa->instance->occur_end, + e_cal_component_get_vtype (tray_data->comp), + tray_data->summary, + tray_data->description, + tray_data->location, + notify_dialog_cb, tray_data); } return TRUE; @@ -1227,15 +1240,32 @@ alarm_queue_init (void) alarm_queue_inited = TRUE; } -static void +static gboolean free_client_alarms_cb (gpointer key, gpointer value, gpointer user_data) { ClientAlarms *ca = value; if (ca) { - g_object_unref (ca->client); + remove_client_alarms (ca); + if (ca->client) { + g_signal_handlers_disconnect_matched (ca->client, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, ca); + g_object_unref (ca->client); + } + + if (ca->query) { + g_signal_handlers_disconnect_matched (ca->query, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, ca); + g_object_unref (ca->query); + } + + g_hash_table_destroy (ca->uid_alarms_hash); + g_free (ca); + return TRUE; } + + return FALSE; } /** @@ -1253,13 +1283,14 @@ alarm_queue_done (void) /* All clients must be unregistered by now */ g_return_if_fail (g_hash_table_size (client_alarms_hash) == 0); - g_hash_table_foreach (client_alarms_hash, (GHFunc) free_client_alarms_cb, NULL); + g_hash_table_foreach_remove (client_alarms_hash, (GHRFunc) free_client_alarms_cb, NULL); g_hash_table_destroy (client_alarms_hash); client_alarms_hash = NULL; - g_assert (midnight_refresh_id != NULL); - alarm_remove (midnight_refresh_id); - midnight_refresh_id = NULL; + if (midnight_refresh_id != NULL) { + alarm_remove (midnight_refresh_id); + midnight_refresh_id = NULL; + } alarm_queue_inited = FALSE; } @@ -1373,13 +1404,19 @@ alarm_queue_remove_client (ECal *client) /* Clean up */ - g_signal_handlers_disconnect_matched (ca->client, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, ca); + if (ca->client) { + g_signal_handlers_disconnect_matched (ca->client, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, ca); + g_object_unref (ca->client); + ca->client = NULL; + } - g_object_unref (ca->query); - ca->query = NULL; - g_object_unref (ca->client); - ca->client = NULL; + if (ca->query) { + g_signal_handlers_disconnect_matched (ca->query, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, ca); + g_object_unref (ca->query); + ca->query = NULL; + } g_hash_table_destroy (ca->uid_alarms_hash); ca->uid_alarms_hash = NULL; -- cgit