diff options
Diffstat (limited to 'calendar/gui/alarm-notify/alarm-queue.c')
-rw-r--r-- | calendar/gui/alarm-notify/alarm-queue.c | 1078 |
1 files changed, 0 insertions, 1078 deletions
diff --git a/calendar/gui/alarm-notify/alarm-queue.c b/calendar/gui/alarm-notify/alarm-queue.c deleted file mode 100644 index 7f829e1bf5..0000000000 --- a/calendar/gui/alarm-notify/alarm-queue.c +++ /dev/null @@ -1,1078 +0,0 @@ -/* Evolution calendar - Alarm queueing engine - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <gtk/gtksignal.h> -#include <cal-util/timeutil.h> -#include "alarm.h" -#include "alarm-notify-dialog.h" -#include "alarm-queue.h" - - - -/* Whether the queueing system has been initialized */ -static gboolean alarm_queue_inited; - -/* Clients we are monitoring for alarms */ -static GHashTable *client_alarms_hash = NULL; - -/* Structure that stores a client we are monitoring */ -typedef struct { - /* Monitored client */ - CalClient *client; - - /* Number of times this client has been registered */ - int refcount; - - /* Hash table of component UID -> CompQueuedAlarms. If an element is - * present here, then it means its cqa->queued_alarms contains at least - * one queued alarm. When all the alarms for a component have been - * dequeued, the CompQueuedAlarms structure is removed from the hash - * table. Thus a CQA exists <=> it has queued alarms. - */ - GHashTable *uid_alarms_hash; -} ClientAlarms; - -/* Pair of a CalComponentAlarms and the mapping from queued alarm IDs to the - * actual alarm instance structures. - */ -typedef struct { - /* The parent client alarms structure */ - ClientAlarms *parent_client; - - /* The actual component and its alarm instances */ - CalComponentAlarms *alarms; - - /* List of QueuedAlarm structures */ - GSList *queued_alarms; -} CompQueuedAlarms; - -/* Pair of a queued alarm ID and the alarm trigger instance it refers to */ -typedef struct { - /* Alarm ID from alarm.h */ - gpointer alarm_id; - - /* Instance from our parent CompQueuedAlarms->alarms->alarms list */ - CalAlarmInstance *instance; -} QueuedAlarm; - -/* Alarm ID for the midnight refresh function */ -static gpointer midnight_refresh_id = NULL; - -static void display_notification (time_t trigger, CalAlarmInstance *instance, - CalComponent *comp, CalComponentAlarm *alarm); - - - -/* Alarm queue engine */ - -static void load_alarms (ClientAlarms *ca); -static void midnight_refresh_cb (gpointer alarm_id, time_t trigger, gpointer data); - -/* Queues an alarm trigger for midnight so that we can load the next day's worth - * of alarms. - */ -static void -queue_midnight_refresh (void) -{ - time_t midnight; - - g_assert (midnight_refresh_id == NULL); - - midnight = time_day_end (time (NULL)); - - midnight_refresh_id = alarm_add (midnight, midnight_refresh_cb, NULL, NULL); - if (!midnight_refresh_id) { - g_message ("queue_midnight_refresh(): Could not set up the midnight refresh alarm!"); - /* FIXME: what to do? */ - } -} - -/* Loads a client's alarms; called from g_hash_table_foreach() */ -static void -add_client_alarms_cb (gpointer key, gpointer value, gpointer data) -{ - ClientAlarms *ca; - - ca = value; - load_alarms (ca); -} - -/* Loads the alarms for the new day every midnight */ -static void -midnight_refresh_cb (gpointer alarm_id, time_t trigger, gpointer data) -{ - /* Re-load the alarms for all clients */ - - g_hash_table_foreach (client_alarms_hash, add_client_alarms_cb, NULL); - - /* Re-schedule the midnight update */ - - midnight_refresh_id = NULL; - queue_midnight_refresh (); -} - -/* Looks up a client in the client alarms hash table */ -static ClientAlarms * -lookup_client (CalClient *client) -{ - return g_hash_table_lookup (client_alarms_hash, client); -} - -/* Callback used when an alarm triggers */ -static void -alarm_trigger_cb (gpointer alarm_id, time_t trigger, gpointer data) -{ - CompQueuedAlarms *cqa; - CalComponent *comp; - GSList *l; - QueuedAlarm *qa; - CalComponentAlarm *alarm; - CalAlarmAction action; - - cqa = data; - comp = cqa->alarms->comp; - - /* Look for the queued alarm so that we can identify its occurrence */ - - qa = NULL; - - for (l = cqa->queued_alarms; l; l = l->next) { - qa = l->data; - if (qa->alarm_id == alarm_id) - break; - } - - g_assert (qa != NULL); - - /* Decide what to do based on the alarm action. We use the trigger that - * is passed to us instead of the one from the instance structure - * because this may be a snoozed alarm instead of an original - * occurrence. - */ - - alarm = cal_component_get_alarm (comp, qa->instance->auid); - g_assert (alarm != NULL); - - cal_component_alarm_get_action (alarm, &action); - - switch (action) { - case CAL_ALARM_AUDIO: - /* FIXME: audio_notification (); */ - break; - - case CAL_ALARM_DISPLAY: - display_notification (trigger, qa->instance, comp, alarm); - break; - - case CAL_ALARM_EMAIL: - /* FIXME: mail_notification (); */ - break; - - case CAL_ALARM_PROCEDURE: - /* FIXME: procedure_notification (); */ - break; - - default: - g_assert_not_reached (); - break; - } - - cal_component_alarm_free (alarm); -} - -/* Callback used when an alarm must be destroyed */ -static void -alarm_destroy_cb (gpointer alarm_id, gpointer data) -{ - CompQueuedAlarms *cqa; - GSList *l; - QueuedAlarm *qa; - const char *uid; - - cqa = data; - - qa = NULL; /* Keep GCC happy */ - - /* Find the alarm in the queued alarms */ - - for (l = cqa->queued_alarms; l; l = l->next) { - qa = l->data; - if (qa->alarm_id == alarm_id) - break; - } - - g_assert (l != NULL); - - /* Remove it and free it */ - - cqa->queued_alarms = g_slist_remove_link (cqa->queued_alarms, l); - g_slist_free_1 (l); - - g_free (qa); - - /* If this was the last queued alarm for this component, remove the - * component itself. - */ - - if (cqa->queued_alarms != NULL) - return; - - cal_component_get_uid (cqa->alarms->comp, &uid); - g_hash_table_remove (cqa->parent_client->uid_alarms_hash, uid); - cqa->parent_client = NULL; - - cal_component_alarms_free (cqa->alarms); - cqa->alarms = NULL; - - g_free (cqa); -} - -/* Adds the alarms in a CalComponentAlarms structure to the alarms queued for a - * particular client. Also puts the triggers in the alarm timer queue. - */ -static void -add_component_alarms (ClientAlarms *ca, CalComponentAlarms *alarms) -{ - const char *uid; - CompQueuedAlarms *cqa; - GSList *l; - - /* No alarms? */ - if (alarms->alarms == NULL) { - cal_component_alarms_free (alarms); - return; - } - - cqa = g_new (CompQueuedAlarms, 1); - cqa->parent_client = ca; - cqa->alarms = alarms; - - cqa->queued_alarms = NULL; - - for (l = alarms->alarms; l; l = l->next) { - CalAlarmInstance *instance; - gpointer alarm_id; - QueuedAlarm *qa; - - instance = l->data; - - alarm_id = alarm_add (instance->trigger, alarm_trigger_cb, cqa, alarm_destroy_cb); - if (!alarm_id) { - g_message ("add_component_alarms(): Could not schedule a trigger for " - "%ld, discarding...", (long) instance->trigger); - continue; - } - - qa = g_new (QueuedAlarm, 1); - qa->alarm_id = alarm_id; - qa->instance = instance; - - cqa->queued_alarms = g_slist_prepend (cqa->queued_alarms, qa); - } - - cal_component_get_uid (alarms->comp, &uid); - - /* If we failed to add all the alarms, then we should get rid of the cqa */ - if (cqa->queued_alarms == NULL) { - g_message ("add_component_alarms(): Could not add any of the alarms " - "for the component `%s'; discarding it...", uid); - - cal_component_alarms_free (cqa->alarms); - cqa->alarms = NULL; - - g_free (cqa); - return; - } - - cqa->queued_alarms = g_slist_reverse (cqa->queued_alarms); - g_hash_table_insert (ca->uid_alarms_hash, (char *) uid, cqa); -} - -/* Loads today's remaining alarms for a client */ -static void -load_alarms (ClientAlarms *ca) -{ - time_t now, day_end; - GSList *comp_alarms; - GSList *l; - - now = time (NULL); - day_end = time_day_end (now); - - comp_alarms = cal_client_get_alarms_in_range (ca->client, now, day_end); - - /* All of the last day's alarms should have already triggered and should - * have been removed, so we should have no pending components. - */ - g_assert (g_hash_table_size (ca->uid_alarms_hash) == 0); - - for (l = comp_alarms; l; l = l->next) { - CalComponentAlarms *alarms; - - alarms = l->data; - add_component_alarms (ca, alarms); - } - - g_slist_free (comp_alarms); -} - -/* Called when a calendar client finished loading; we load its alarms */ -static void -cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data) -{ - ClientAlarms *ca; - - ca = data; - - if (status != CAL_CLIENT_OPEN_SUCCESS) - return; - - load_alarms (ca); -} - -/* Looks up a component's queued alarm structure in a client alarms structure */ -static CompQueuedAlarms * -lookup_comp_queued_alarms (ClientAlarms *ca, const char *uid) -{ - return g_hash_table_lookup (ca->uid_alarms_hash, uid); -} - -/* Removes a component an its alarms */ -static void -remove_comp (ClientAlarms *ca, const char *uid) -{ - CompQueuedAlarms *cqa; - GSList *l; - - cqa = lookup_comp_queued_alarms (ca, uid); - if (!cqa) - return; - - /* If a component is present, then it means we must have alarms queued - * for it. - */ - g_assert (cqa->queued_alarms != NULL); - - for (l = cqa->queued_alarms; l;) { - QueuedAlarm *qa; - - qa = l->data; - - /* Get the next element here because the list element will go - * away. Also, we do not free the qa here because it will be - * freed by the destroy notification function. - */ - l = l->next; - - alarm_remove (qa->alarm_id); - } - - /* The list should be empty now, and thus the queued component alarms - * structure should have been freed and removed from the hash table. - */ - g_assert (lookup_comp_queued_alarms (ca, uid) == NULL); -} - -/* Called when a calendar component changes; we must reload its corresponding - * alarms. - */ -static void -obj_updated_cb (CalClient *client, const char *uid, gpointer data) -{ - ClientAlarms *ca; - time_t now, day_end; - CalComponentAlarms *alarms; - gboolean found; - - ca = data; - - remove_comp (ca, uid); - - now = time (NULL); - day_end = time_day_end (now); - - found = cal_client_get_alarms_for_object (ca->client, uid, now, day_end, &alarms); - - if (!found) - return; - - add_component_alarms (ca, alarms); -} - -/* Called when a calendar component is removed; we must delete its corresponding - * alarms. - */ -static void -obj_removed_cb (CalClient *client, const char *uid, gpointer data) -{ - ClientAlarms *ca; - - ca = data; - - remove_comp (ca, uid); -} - - - -/* Notification functions */ - -/* Callback used from the alarm notify dialog */ -static void -notify_dialog_cb (AlarmNotifyResult result, int snooze_mins, gpointer data) -{ - switch (result) { - case ALARM_NOTIFY_SNOOZE: - /* FIXME */ - break; - - case ALARM_NOTIFY_EDIT: - /* FIXME */ - break; - - case ALARM_NOTIFY_CLOSE: - default: - break; - } -} - -/* Performs notification of a display alarm */ -static void -display_notification (time_t trigger, CalAlarmInstance *instance, - CalComponent *comp, CalComponentAlarm *alarm) -{ - CalComponentVType vtype; - CalComponentText text; - const char *message; - - vtype = cal_component_get_vtype (comp); - - /* Pick a sensible notification message. First we try the DESCRIPTION - * from the alarm, then the SUMMARY of the component. - */ - - cal_component_alarm_get_description (alarm, &text); - if (text.value) - message = text.value; - else { - cal_component_get_summary (comp, &text); - if (text.value) - message = text.value; - else - message = _("No description available."); - } - - if (!alarm_notify_dialog (trigger, - instance->occur_start, instance->occur_end, - vtype, message, - notify_dialog_cb, comp)) - g_message ("display_notification(): Could not create the alarm notify dialog"); -} - - - -/** - * alarm_queue_init: - * - * Initializes the alarm queueing system. This should be called near the - * beginning of the program, after calling alarm_init(). - **/ -void -alarm_queue_init (void) -{ - g_return_if_fail (alarm_queue_inited == FALSE); - - client_alarms_hash = g_hash_table_new (g_direct_hash, g_direct_equal); - queue_midnight_refresh (); - - alarm_queue_inited = TRUE; -} - -/** - * alarm_queue_done: - * - * Shuts down the alarm queueing system. This should be called near the end - * of the program. All the monitored calendar clients should already have been - * unregistered with alarm_queue_remove_client(). - **/ -void -alarm_queue_done (void) -{ - g_return_if_fail (alarm_queue_inited); - - /* All clients must be unregistered by now */ - g_return_if_fail (g_hash_table_size (client_alarms_hash) == 0); - - 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; - - alarm_queue_inited = FALSE; -} - -/** - * alarm_queue_add_client: - * @client: A calendar client. - * - * Adds a calendar client to the alarm queueing system. Alarm trigger - * notifications will be presented at the appropriate times. The client should - * be removed with alarm_queue_remove_client() when receiving notifications - * from it is no longer desired. - * - * A client can be added any number of times to the alarm queueing system, - * but any single alarm trigger will only be presented once for a particular - * client. The client must still be removed the same number of times from the - * queueing system when it is no longer wanted. - **/ -void -alarm_queue_add_client (CalClient *client) -{ - ClientAlarms *ca; - - g_return_if_fail (alarm_queue_inited); - g_return_if_fail (client != NULL); - g_return_if_fail (IS_CAL_CLIENT (client)); - - ca = lookup_client (client); - if (ca) { - ca->refcount++; - return; - } - - ca = g_new (ClientAlarms, 1); - - ca->client = client; - gtk_object_ref (GTK_OBJECT (ca->client)); - - ca->refcount = 1; - g_hash_table_insert (client_alarms_hash, client, ca); - - ca->uid_alarms_hash = g_hash_table_new (g_str_hash, g_str_equal); - - if (cal_client_get_load_state (client) != CAL_CLIENT_LOAD_LOADED) - gtk_signal_connect (GTK_OBJECT (client), "cal_opened", - GTK_SIGNAL_FUNC (cal_opened_cb), ca); - - gtk_signal_connect (GTK_OBJECT (client), "obj_updated", - GTK_SIGNAL_FUNC (obj_updated_cb), ca); - gtk_signal_connect (GTK_OBJECT (client), "obj_removed", - GTK_SIGNAL_FUNC (obj_removed_cb), ca); - - if (cal_client_get_load_state (client) == CAL_CLIENT_LOAD_LOADED) - load_alarms (ca); -} - -/* Called from g_hash_table_foreach(); adds a component UID to a list */ -static void -add_uid_cb (gpointer key, gpointer value, gpointer data) -{ - GSList **uids; - const char *uid; - - uids = data; - uid = key; - - *uids = g_slist_prepend (*uids, (char *) uid); -} - -/* Removes all the alarms queued for a particular calendar client */ -static void -remove_client_alarms (ClientAlarms *ca) -{ - GSList *uids; - GSList *l; - - /* First we build a list of UIDs so that we can remove them one by one */ - - uids = NULL; - g_hash_table_foreach (ca->uid_alarms_hash, add_uid_cb, &uids); - - for (l = uids; l; l = l->next) { - const char *uid; - - uid = l->data; - - remove_comp (ca, uid); - } - - g_slist_free (uids); - - /* The hash table should be empty now */ - - g_assert (g_hash_table_size (ca->uid_alarms_hash) == 0); -} - -/** - * alarm_queue_remove_client: - * @client: A calendar client. - * - * Removes a calendar client from the alarm queueing system. - **/ -void -alarm_queue_remove_client (CalClient *client) -{ - ClientAlarms *ca; - - g_return_if_fail (alarm_queue_inited); - g_return_if_fail (client != NULL); - g_return_if_fail (IS_CAL_CLIENT (client)); - - ca = lookup_client (client); - g_return_if_fail (ca != NULL); - - g_assert (ca->refcount > 0); - ca->refcount--; - - if (ca->refcount > 0) - return; - - remove_client_alarms (ca); - - /* Clean up */ - - gtk_signal_disconnect_by_data (GTK_OBJECT (ca->client), ca); - - gtk_object_unref (GTK_OBJECT (ca->client)); - ca->client = NULL; - - g_hash_table_destroy (ca->uid_alarms_hash); - ca->uid_alarms_hash = NULL; - - g_free (ca); - - g_hash_table_remove (client_alarms_hash, client); -} - - - -#if 0 - -/* Sends a mail notification of an alarm trigger */ -static void -mail_notification (char *mail_address, char *text, time_t app_time) -{ - pid_t pid; - int p [2]; - char *command; - - pipe (p); - pid = fork (); - if (pid == 0){ - int dev_null; - - dev_null = open ("/dev/null", O_RDWR); - dup2 (p [0], 0); - dup2 (dev_null, 1); - dup2 (dev_null, 2); - execl ("/usr/lib/sendmail", "/usr/lib/sendmail", - mail_address, NULL); - _exit (127); - } - command = g_strconcat ("To: ", mail_address, "\n", - "Subject: ", _("Reminder of your appointment at "), - ctime (&app_time), "\n\n", text, "\n", NULL); - write (p [1], command, strlen (command)); - close (p [1]); - close (p [0]); - g_free (command); -} - -static int -max_open_files (void) -{ - static int files; - - if (files) - return files; - - files = sysconf (_SC_OPEN_MAX); - if (files != -1) - return files; -#ifdef OPEN_MAX - return files = OPEN_MAX; -#else - return files = 256; -#endif -} - -/* Executes a program as a notification of an alarm trigger */ -static void -program_notification (char *command, int close_standard) -{ - struct sigaction ignore, save_intr, save_quit; - int status = 0, i; - pid_t pid; - - ignore.sa_handler = SIG_IGN; - sigemptyset (&ignore.sa_mask); - ignore.sa_flags = 0; - - sigaction (SIGINT, &ignore, &save_intr); - sigaction (SIGQUIT, &ignore, &save_quit); - - if ((pid = fork ()) < 0){ - fprintf (stderr, "\n\nfork () = -1\n"); - return; - } - if (pid == 0){ - pid = fork (); - if (pid == 0){ - const int top = max_open_files (); - sigaction (SIGINT, &save_intr, NULL); - sigaction (SIGQUIT, &save_quit, NULL); - - for (i = (close_standard ? 0 : 3); i < top; i++) - close (i); - - /* FIXME: As an excercise to the reader, copy the - * code from mc to setup shell properly instead of - * /bin/sh. Yes, this comment is larger than a cut and paste. - */ - execl ("/bin/sh", "/bin/sh", "-c", command, (char *) 0); - - _exit (127); - } else { - _exit (127); - } - } - wait (&status); - sigaction (SIGINT, &save_intr, NULL); - sigaction (SIGQUIT, &save_quit, NULL); -} - -/* Queues a snooze alarm */ -static void -snooze (GnomeCalendar *gcal, CalComponent *comp, time_t occur, int snooze_mins, gboolean audio) -{ - time_t now, trigger; - struct tm tm; - CalAlarmInstance ai; - - now = time (NULL); - tm = *localtime (&now); - tm.tm_min += snooze_mins; - - trigger = mktime (&tm); - if (trigger == -1) { - g_message ("snooze(): produced invalid time_t; not queueing alarm!"); - return; - } - -#if 0 - cal_component_get_uid (comp, &ai.uid); - ai.type = audio ? ALARM_AUDIO : ALARM_DISPLAY; -#endif - ai.trigger = trigger; - ai.occur = occur; - - setup_alarm (gcal, &ai); -} - -struct alarm_notify_closure { - GnomeCalendar *gcal; - CalComponent *comp; - time_t occur; -}; - -/* Callback used for the result of the alarm notification dialog */ -static void -display_notification_cb (AlarmNotifyResult result, int snooze_mins, gpointer data) -{ - struct alarm_notify_closure *c; - - c = data; - - switch (result) { - case ALARM_NOTIFY_CLOSE: - break; - - case ALARM_NOTIFY_SNOOZE: - snooze (c->gcal, c->comp, c->occur, snooze_mins, FALSE); - break; - - case ALARM_NOTIFY_EDIT: - gnome_calendar_edit_object (c->gcal, c->comp); - break; - - default: - g_assert_not_reached (); - } - - gtk_object_unref (GTK_OBJECT (c->comp)); - g_free (c); -} - -/* Present a display notification of an alarm trigger */ -static void -display_notification (time_t trigger, time_t occur, CalComponent *comp, GnomeCalendar *gcal) -{ - gboolean result; - struct alarm_notify_closure *c; - - gtk_object_ref (GTK_OBJECT (comp)); - - c = g_new (struct alarm_notify_closure, 1); - c->gcal = gcal; - c->comp = comp; - c->occur = occur; - - result = alarm_notify_dialog (trigger, occur, comp, display_notification_cb, c); - if (!result) { - g_message ("display_notification(): could not display the alarm notification dialog"); - g_free (c); - gtk_object_unref (GTK_OBJECT (comp)); - } -} - -/* Present an audible notification of an alarm trigger */ -static void -audio_notification (time_t trigger, time_t occur, CalComponent *comp, GnomeCalendar *gcal) -{ - g_message ("AUDIO NOTIFICATION!"); - /* FIXME */ -} - -/* Callback function used when an alarm is triggered */ -static void -trigger_alarm_cb (gpointer alarm_id, time_t trigger, gpointer data) -{ - struct trigger_alarm_closure *c; - GnomeCalendarPrivate *priv; - CalComponent *comp; - CalClientGetStatus status; - const char *uid; - ObjectAlarms *oa; - GList *l; - - c = data; - priv = c->gcal->priv; - - /* Fetch the object */ - - status = cal_client_get_object (priv->client, c->uid, &comp); - - switch (status) { - case CAL_CLIENT_GET_SUCCESS: - /* Go on */ - break; - case CAL_CLIENT_GET_SYNTAX_ERROR: - case CAL_CLIENT_GET_NOT_FOUND: - g_message ("trigger_alarm_cb(): syntax error in fetched object"); - return; - } - - g_assert (comp != NULL); - - /* Present notification */ - - switch (c->type) { - case CAL_COMPONENT_ALARM_EMAIL: -#if 0 - g_assert (ico->malarm.enabled); - mail_notification (ico->malarm.data, ico->summary, c->occur); -#endif - break; - - case CAL_COMPONENT_ALARM_PROCEDURE: -#if 0 - g_assert (ico->palarm.enabled); - program_notification (ico->palarm.data, FALSE); -#endif - break; - - case CAL_COMPONENT_ALARM_DISPLAY: -#if 0 - g_assert (ico->dalarm.enabled); -#endif - display_notification (trigger, c->occur, comp, c->gcal); - break; - - case CAL_COMPONENT_ALARM_AUDIO: -#if 0 - g_assert (ico->aalarm.enabled); -#endif - audio_notification (trigger, c->occur, comp, c->gcal); - break; - - default: - break; - } - - /* Remove the alarm from the hash table */ - cal_component_get_uid (comp, &uid); - oa = g_hash_table_lookup (priv->alarms, uid); - g_assert (oa != NULL); - - l = g_list_find (oa->alarm_ids, alarm_id); - g_assert (l != NULL); - - oa->alarm_ids = g_list_remove_link (oa->alarm_ids, l); - g_list_free_1 (l); - - if (!oa->alarm_ids) { - g_hash_table_remove (priv->alarms, uid); - g_free (oa->uid); - g_free (oa); - } - - gtk_object_unref (GTK_OBJECT (comp)); -} - -#endif - -#if 0 - -static void -stop_beeping (GtkObject* object, gpointer data) -{ - guint timer_tag, beep_tag; - timer_tag = GPOINTER_TO_INT (gtk_object_get_data (object, "timer_tag")); - beep_tag = GPOINTER_TO_INT (gtk_object_get_data (object, "beep_tag")); - - if (beep_tag > 0) { - gtk_timeout_remove (beep_tag); - gtk_object_set_data (object, "beep_tag", GINT_TO_POINTER (0)); - } - if (timer_tag > 0) { - gtk_timeout_remove (timer_tag); - gtk_object_set_data (object, "timer_tag", GINT_TO_POINTER (0)); - } -} - -static gint -start_beeping (gpointer data) -{ - gdk_beep (); - - return TRUE; -} - -static gint -timeout_beep (gpointer data) -{ - stop_beeping (data, NULL); - return FALSE; -} - -void -calendar_notify (time_t activation_time, CalendarAlarm *which, void *data) -{ - iCalObject *ico = data; - guint beep_tag, timer_tag; - int ret; - gchar* snooze_button = (enable_snooze ? _("Snooze") : NULL); - time_t now, diff; - - if (&ico->aalarm == which){ - time_t app = ico->aalarm.trigger + ico->aalarm.offset; - GtkWidget *w; - char *msg; - - msg = g_strconcat (_("Reminder of your appointment at "), - ctime (&app), "`", - ico->summary, "'", NULL); - - /* Idea: we need Snooze option :-) */ - w = gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO, _("Ok"), snooze_button, NULL); - beep_tag = gtk_timeout_add (1000, start_beeping, NULL); - if (enable_aalarm_timeout) - timer_tag = gtk_timeout_add (audio_alarm_timeout*1000, - timeout_beep, w); - else - timer_tag = 0; - gtk_object_set_data (GTK_OBJECT (w), "timer_tag", - GINT_TO_POINTER (timer_tag)); - gtk_object_set_data (GTK_OBJECT (w), "beep_tag", - GINT_TO_POINTER (beep_tag)); - gtk_widget_ref (w); - gtk_window_set_modal (GTK_WINDOW (w), FALSE); - ret = gnome_dialog_run (GNOME_DIALOG (w)); - switch (ret) { - case 1: - stop_beeping (GTK_OBJECT (w), NULL); - now = time (NULL); - diff = now - which->trigger; - which->trigger = which->trigger + diff + snooze_secs; - which->offset = which->offset - diff - snooze_secs; - alarm_add (which, &calendar_notify, data); - break; - default: - stop_beeping (GTK_OBJECT (w), NULL); - break; - } - - gtk_widget_unref (w); - return; - } - - if (&ico->palarm == which){ - execute (ico->palarm.data, 0); - return; - } - - if (&ico->malarm == which){ - time_t app = ico->malarm.trigger + ico->malarm.offset; - - mail_notify (ico->malarm.data, ico->summary, app); - return; - } - - if (&ico->dalarm == which){ - time_t app = ico->dalarm.trigger + ico->dalarm.offset; - GtkWidget *w; - char *msg; - - if (beep_on_display) - gdk_beep (); - msg = g_strconcat (_("Reminder of your appointment at "), - ctime (&app), "`", - ico->summary, "'", NULL); - w = gnome_message_box_new (msg, GNOME_MESSAGE_BOX_INFO, - _("Ok"), snooze_button, NULL); - gtk_window_set_modal (GTK_WINDOW (w), FALSE); - ret = gnome_dialog_run (GNOME_DIALOG (w)); - switch (ret) { - case 1: - now = time (NULL); - diff = now - which->trigger; - which->trigger = which->trigger + diff + snooze_secs; - which->offset = which->offset - diff - snooze_secs; - alarm_add (which, &calendar_notify, data); - break; - default: - break; - } - - return; - } -} - -#endif |