From d21e6e4dc143f1b077da4d9c9375947e63321d7a Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Thu, 18 Oct 2001 19:50:29 +0000 Subject: Adds session management for the alarm daemon. Also makes it store a list 2001-10-18 Federico Mena Quintero Adds session management for the alarm daemon. Also makes it store a list of calendars to be monitored. Those calendars will all be loaded when the alarm daemon starts up. * idl/evolution-calendar.idl (AlarmNotify): Removed the ::die() method. The alarm daemon now handles termination via the session manager's commands. * gui/alarm-notify/notify-main.c (set_session_parameters): New function, sets some parameters so that the session manager can restart the daemon via the evolution-alarm-client program. Also, sets up the "die" signal so that the daemon can terminate when the session ends. (load_calendars): New function to load the calendars on startup. (main): Set the session parameters. Load the calendars on startup. * gui/alarm-notify/alarm-notify.c (alarm_notify_add_calendar): New function, moved over from the impl_ function. Added a load_afterwards argument to indicate whether the calendar should just be loaded or if it should also be added to the list of calendars to load on startup. (AlarmNotify_addCalendar): Use alarm_notify_add_calendar(). (AlarmNotify_removeCalendar): Remove the calendar from the list of calendars to load on startup. * gui/alarm-notify/save.c (save_calendars_to_load): New function, saves a sequence of the URIs to load. (get_calendars_to_load): New function, loads a sequence of calendars to load. * gui/alarm-notify/alarm.h: Removed stale prototype for alarm_init(). * gui/component-factory.c (remove_folder): Ask the alarm daemon to stop monitoring alarms for the folder that is being deleted. svn path=/trunk/; revision=13763 --- calendar/ChangeLog | 37 +++++ calendar/gui/alarm-notify/Makefile.am | 11 +- calendar/gui/alarm-notify/alarm-notify.c | 237 +++++++++++++++++++++++-------- calendar/gui/alarm-notify/alarm-notify.h | 3 + calendar/gui/alarm-notify/alarm-queue.c | 2 +- calendar/gui/alarm-notify/alarm.h | 1 - calendar/gui/alarm-notify/client-main.c | 178 ----------------------- calendar/gui/alarm-notify/notify-main.c | 110 +++++++++++++- calendar/gui/alarm-notify/save.c | 144 ++++++++++++++++++- calendar/gui/alarm-notify/save.h | 4 +- calendar/gui/calendar-component.c | 58 ++++++++ calendar/gui/component-factory.c | 58 ++++++++ calendar/idl/evolution-calendar.idl | 13 +- 13 files changed, 595 insertions(+), 261 deletions(-) delete mode 100644 calendar/gui/alarm-notify/client-main.c (limited to 'calendar') diff --git a/calendar/ChangeLog b/calendar/ChangeLog index eab413bef6..154edf2a84 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,40 @@ +2001-10-18 Federico Mena Quintero + + Adds session management for the alarm daemon. Also makes it store + a list of calendars to be monitored. Those calendars will all be + loaded when the alarm daemon starts up. + + * idl/evolution-calendar.idl (AlarmNotify): Removed the ::die() + method. The alarm daemon now handles termination via the session + manager's commands. + + * gui/alarm-notify/notify-main.c (set_session_parameters): New + function, sets some parameters so that the session manager can + restart the daemon via the evolution-alarm-client program. Also, + sets up the "die" signal so that the daemon can terminate when the + session ends. + (load_calendars): New function to load the calendars on startup. + (main): Set the session parameters. Load the calendars on startup. + + * gui/alarm-notify/alarm-notify.c (alarm_notify_add_calendar): New + function, moved over from the impl_ function. Added a + load_afterwards argument to indicate whether the calendar should + just be loaded or if it should also be added to the list of + calendars to load on startup. + (AlarmNotify_addCalendar): Use alarm_notify_add_calendar(). + (AlarmNotify_removeCalendar): Remove the calendar from the list of + calendars to load on startup. + + * gui/alarm-notify/save.c (save_calendars_to_load): New function, + saves a sequence of the URIs to load. + (get_calendars_to_load): New function, loads a sequence of + calendars to load. + + * gui/alarm-notify/alarm.h: Removed stale prototype for alarm_init(). + + * gui/component-factory.c (remove_folder): Ask the alarm daemon to + stop monitoring alarms for the folder that is being deleted. + 2001-10-18 JP Rosevear * gui/e-meeting-time-sel.c diff --git a/calendar/gui/alarm-notify/Makefile.am b/calendar/gui/alarm-notify/Makefile.am index 4c323c3b55..8cf9b749fc 100644 --- a/calendar/gui/alarm-notify/Makefile.am +++ b/calendar/gui/alarm-notify/Makefile.am @@ -11,7 +11,7 @@ idl_flags = `$(GNOME_CONFIG) --cflags idl` -I $(datadir)/idl $(CORBA_GENERATED): $(idls) $(ORBIT_IDL) $(idl_flags) $(top_srcdir)/calendar/idl/evolution-calendar.idl -bin_PROGRAMS = evolution-alarm-notify # evolution-alarm-client +bin_PROGRAMS = evolution-alarm-notify noinst_LIBRARIES = libalarm.a @@ -63,15 +63,6 @@ evolution_alarm_notify_LDADD = \ $(EXTRA_GNOME_LIBS) \ $(INTLLIBS) -# evolution_alarm_client_SOURCES = \ -# client-main.c \ -# $(CORBA_GENERATED) -# -# evolution_alarm_client_LDADD = \ -# $(BONOBO_VFS_GNOME_LIBS) \ -# $(EXTRA_GNOME_LIBS) \ -# $(INTLLIBS) - oafdir = $(datadir)/oaf oaf_in_files = \ GNOME_Evolution_Calendar_AlarmNotify.oaf.in diff --git a/calendar/gui/alarm-notify/alarm-notify.c b/calendar/gui/alarm-notify/alarm-notify.c index 88d25dafbc..61b8e8ecc5 100644 --- a/calendar/gui/alarm-notify/alarm-notify.c +++ b/calendar/gui/alarm-notify/alarm-notify.c @@ -27,6 +27,7 @@ #include #include "alarm-notify.h" #include "alarm-queue.h" +#include "save.h" @@ -64,8 +65,6 @@ static void AlarmNotify_addCalendar (PortableServer_Servant servant, static void AlarmNotify_removeCalendar (PortableServer_Servant servant, const CORBA_char *str_uri, CORBA_Environment *ev); -static void AlarmNotify_die (PortableServer_Servant servant, - CORBA_Environment *ev); static BonoboXObjectClass *parent_class; @@ -89,7 +88,6 @@ alarm_notify_class_init (AlarmNotifyClass *class) class->epv.addCalendar = AlarmNotify_addCalendar; class->epv.removeCalendar = AlarmNotify_removeCalendar; - class->epv.die = AlarmNotify_die; object_class->destroy = alarm_notify_destroy; } @@ -148,63 +146,124 @@ alarm_notify_destroy (GtkObject *object) /* CORBA servant implementation */ -/* AlarmNotify::addCalendar method */ +/* Looks for a canonicalized URI inside an array of URIs; returns the index + * within the array or -1 if not found. + */ +static int +find_uri_index (GPtrArray *uris, const char *str_uri) +{ + int i; + + for (i = 0; i < uris->len; i++) { + char *uri; + + uri = uris->pdata[i]; + if (strcmp (uri, str_uri) == 0) + break; + } + + if (i == uris->len) + return -1; + else + return i; +} + +/* Frees an array of URIs and the URIs within it. */ static void -AlarmNotify_addCalendar (PortableServer_Servant servant, - const CORBA_char *str_uri, - CORBA_Environment *ev) +free_uris (GPtrArray *uris) { - AlarmNotify *an; - AlarmNotifyPrivate *priv; - GnomeVFSURI *uri; - CalClient *client; - LoadedClient *lc; + int i; - an = ALARM_NOTIFY (bonobo_object_from_servant (servant)); - priv = an->priv; + for (i = 0; i < uris->len; i++) { + char *uri; - uri = gnome_vfs_uri_new (str_uri); - if (!uri) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI, - NULL); - return; + uri = uris->pdata[i]; + g_free (uri); } - lc = g_hash_table_lookup (priv->uri_client_hash, uri); + g_ptr_array_free (uris, TRUE); +} - if (lc) { - gnome_vfs_uri_unref (uri); - g_assert (lc->refcount > 0); - lc->refcount++; +/* Adds an URI to the list of calendars to load on startup */ +static void +add_uri_to_load (GnomeVFSURI *uri) +{ + char *str_uri; + GPtrArray *loaded_uris; + int i; + + /* Canonicalize the URI */ + str_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + g_assert (str_uri != NULL); + + loaded_uris = get_calendars_to_load (); + g_assert (loaded_uris != NULL); + + /* Look for the URI in the list of calendars to load */ + + i = find_uri_index (loaded_uris, str_uri); + + /* We only need to add the URI if we didn't find it among the list of + * calendars. + */ + if (i != -1) { + g_free (str_uri); + free_uris (loaded_uris); return; } - client = cal_client_new (); + g_ptr_array_add (loaded_uris, str_uri); + save_calendars_to_load (loaded_uris); - if (client) { - if (cal_client_open_calendar (client, str_uri, FALSE)) { - lc = g_new (LoadedClient, 1); - lc->client = client; - lc->uri = uri; - lc->refcount = 1; - g_hash_table_insert (priv->uri_client_hash, uri, lc); + free_uris (loaded_uris); +} - alarm_queue_add_client (client); - } else { - gtk_object_unref (GTK_OBJECT (client)); - client = NULL; - } - } +/* Removes an URI from the list of calendars to load on startup */ +static void +remove_uri_to_load (GnomeVFSURI *uri) +{ + char *str_uri; + GPtrArray *loaded_uris; + char *loaded_uri; + int i; - if (!client) { - gnome_vfs_uri_unref (uri); + /* Canonicalize the URI */ + str_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + g_assert (str_uri != NULL); - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_AlarmNotify_BackendContactError, - NULL); + loaded_uris = get_calendars_to_load (); + g_assert (loaded_uris != NULL); + + /* Look for the URI in the list of calendars to load */ + + i = find_uri_index (loaded_uris, str_uri); + g_free (str_uri); + + /* If we didn't find it, there is no need to remove it */ + if (i == -1) { + free_uris (loaded_uris); return; } + + loaded_uri = loaded_uris->pdata[i]; + g_free (loaded_uri); + + g_ptr_array_remove_index (loaded_uris, i); + save_calendars_to_load (loaded_uris); + + free_uris (loaded_uris); +} + +/* AlarmNotify::addCalendar method */ +static void +AlarmNotify_addCalendar (PortableServer_Servant servant, + const CORBA_char *str_uri, + CORBA_Environment *ev) +{ + AlarmNotify *an; + + an = ALARM_NOTIFY (bonobo_object_from_servant (servant)); + alarm_notify_add_calendar (an, str_uri, TRUE, ev); } /* AlarmNotify::removeCalendar method */ @@ -229,6 +288,8 @@ AlarmNotify_removeCalendar (PortableServer_Servant servant, return; } + remove_uri_to_load (uri); + lc = g_hash_table_lookup (priv->uri_client_hash, uri); gnome_vfs_uri_unref (uri); @@ -252,19 +313,6 @@ AlarmNotify_removeCalendar (PortableServer_Servant servant, g_free (lc); } -static void -AlarmNotify_die (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - AlarmNotify *an; - AlarmNotifyPrivate *priv; - - an = ALARM_NOTIFY (bonobo_object_from_servant (servant)); - priv = an->priv; - - /* FIXME */ -} - /** @@ -283,3 +331,78 @@ alarm_notify_new (void) an = gtk_type_new (TYPE_ALARM_NOTIFY); return an; } + +/** + * alarm_notify_add_calendar: + * @an: An alarm notification service. + * @uri: URI of the calendar to load. + * @load_afterwards: Whether this calendar should be loaded in the future + * when the alarm daemon starts up. + * @ev: CORBA environment for exceptions. + * + * Tells the alarm notification service to load a calendar and start monitoring + * its alarms. It can optionally be made to save the URI of this calendar so + * that it can be loaded in the future when the alarm daemon starts up. + **/ +void +alarm_notify_add_calendar (AlarmNotify *an, const char *str_uri, gboolean load_afterwards, + CORBA_Environment *ev) +{ + AlarmNotifyPrivate *priv; + GnomeVFSURI *uri; + CalClient *client; + LoadedClient *lc; + + g_return_if_fail (an != NULL); + g_return_if_fail (IS_ALARM_NOTIFY (an)); + g_return_if_fail (str_uri != NULL); + g_return_if_fail (ev != NULL); + + priv = an->priv; + + uri = gnome_vfs_uri_new (str_uri); + if (!uri) { + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI, + NULL); + return; + } + + if (load_afterwards) + add_uri_to_load (uri); + + lc = g_hash_table_lookup (priv->uri_client_hash, uri); + + if (lc) { + gnome_vfs_uri_unref (uri); + g_assert (lc->refcount > 0); + lc->refcount++; + return; + } + + client = cal_client_new (); + + if (client) { + if (cal_client_open_calendar (client, str_uri, FALSE)) { + lc = g_new (LoadedClient, 1); + lc->client = client; + lc->uri = uri; + lc->refcount = 1; + g_hash_table_insert (priv->uri_client_hash, uri, lc); + + alarm_queue_add_client (client); + } else { + gtk_object_unref (GTK_OBJECT (client)); + client = NULL; + } + } + + if (!client) { + gnome_vfs_uri_unref (uri); + + CORBA_exception_set (ev, CORBA_USER_EXCEPTION, + ex_GNOME_Evolution_Calendar_AlarmNotify_BackendContactError, + NULL); + return; + } +} diff --git a/calendar/gui/alarm-notify/alarm-notify.h b/calendar/gui/alarm-notify/alarm-notify.h index 4122b269fa..39aef31c74 100644 --- a/calendar/gui/alarm-notify/alarm-notify.h +++ b/calendar/gui/alarm-notify/alarm-notify.h @@ -57,6 +57,9 @@ GtkType alarm_notify_get_type (void); AlarmNotify *alarm_notify_new (void); +void alarm_notify_add_calendar (AlarmNotify *an, const char *str_uri, gboolean load_afterwards, + CORBA_Environment *ev); + diff --git a/calendar/gui/alarm-notify/alarm-queue.c b/calendar/gui/alarm-notify/alarm-queue.c index 342a07e420..b0a6aa8dda 100644 --- a/calendar/gui/alarm-notify/alarm-queue.c +++ b/calendar/gui/alarm-notify/alarm-queue.c @@ -802,7 +802,7 @@ procedure_notification (time_t trigger, CompQueuedAlarms *cqa, gpointer alarm_id * alarm_queue_init: * * Initializes the alarm queueing system. This should be called near the - * beginning of the program, after calling alarm_init(). + * beginning of the program. **/ void alarm_queue_init (void) diff --git a/calendar/gui/alarm-notify/alarm.h b/calendar/gui/alarm-notify/alarm.h index b5d57cbe49..592fcdfca2 100644 --- a/calendar/gui/alarm-notify/alarm.h +++ b/calendar/gui/alarm-notify/alarm.h @@ -32,7 +32,6 @@ typedef void (* AlarmFunction) (gpointer alarm_id, time_t trigger, gpointer data); typedef void (* AlarmDestroyNotify) (gpointer alarm_id, gpointer data); -void alarm_init (void); void alarm_done (void); gpointer alarm_add (time_t trigger, AlarmFunction alarm_fn, gpointer data, diff --git a/calendar/gui/alarm-notify/client-main.c b/calendar/gui/alarm-notify/client-main.c deleted file mode 100644 index 5b0fb669d2..0000000000 --- a/calendar/gui/alarm-notify/client-main.c +++ /dev/null @@ -1,178 +0,0 @@ -/* Evolution calendar - Command-line client for the alarm notification service - * - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Federico Mena-Quintero - * - * 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 -#include "evolution-calendar.h" - - - -/* Requests that a calendar be added to the alarm notification service */ -static void -add_calendar (GNOME_Evolution_Calendar_AlarmNotify an, const char *uri) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_AlarmNotify_addCalendar (an, uri, &ev); - - if (ev._major == CORBA_USER_EXCEPTION) { - char *ex_id; - - ex_id = CORBA_exception_id (&ev); - if (strcmp (ex_id, ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI) == 0) { - g_message ("add_calendar(): Invalid URI reported from the " - "alarm notification service"); - goto out; - } else if (strcmp (ex_id, - ex_GNOME_Evolution_Calendar_AlarmNotify_BackendContactError) - == 0) { - g_message ("add_calendar(): The alarm notification service could " - "not contact the backend"); - goto out; - } - } - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("add_calendar(): Could not issue the addCalendar request"); - - out: - CORBA_exception_free (&ev); -} - -/* Loads the calendars that the user has configured to be loaded */ -static void -load_calendars (void) -{ - CORBA_Environment ev; - GNOME_Evolution_Calendar_AlarmNotify an; - char *base_uri; - char *uri; - - CORBA_exception_init (&ev); - an = oaf_activate_from_id ("OAFID:GNOME_Evolution_Calendar_AlarmNotify", 0, NULL, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("load_calendars(): Could not activate the alarm notification service"); - CORBA_exception_free (&ev); - exit (EXIT_FAILURE); - } - CORBA_exception_free (&ev); - - /* FIXME: this should be obtained from the configuration in the Wombat */ - - base_uri = g_concat_dir_and_file (g_get_home_dir (), "evolution"); - - uri = g_concat_dir_and_file (base_uri, "local/Calendar/calendar.ics"); - add_calendar (an, uri); - g_free (uri); - - uri = g_concat_dir_and_file (base_uri, "local/Tasks/tasks.ics"); - add_calendar (an, uri); - g_free (uri); - - g_free (base_uri); - - CORBA_exception_init (&ev); - Bonobo_Unknown_unref (an, &ev); - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("load_calendars(): Could not unref the alarm notification service"); - - CORBA_exception_free (&ev); - - CORBA_exception_init (&ev); - CORBA_Object_release (an, &ev); - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("load_calendars(): Could not release the alarm notification service"); - - CORBA_exception_free (&ev); -} - -/* FIXME: handle the --die option */ - -int -main (int argc, char **argv) -{ - GnomeClient *client; - int flags; - gboolean launch_service; - - bindtextdomain (PACKAGE, EVOLUTION_LOCALEDIR); - textdomain (PACKAGE); - - if (gnome_init_with_popt_table ("evolution-alarm-client", VERSION, - argc, argv, oaf_popt_options, 0, NULL) != 0) { - g_message ("main(): Could not initialize GNOME"); - exit (EXIT_FAILURE); - } - - oaf_init (argc, argv); - - if (!bonobo_init (CORBA_OBJECT_NIL, CORBA_OBJECT_NIL, CORBA_OBJECT_NIL)) { - g_message ("main(): Could not initialize Bonobo"); - exit (EXIT_FAILURE); - } - - /* Ask the session manager to restart us */ - - client = gnome_master_client (); - flags = gnome_client_get_flags (client); - - if (flags & GNOME_CLIENT_IS_CONNECTED) { - char *client_id; - - client_id = gnome_client_get_id (client); - g_assert (client_id != NULL); - - launch_service = gnome_startup_acquire_token ("EVOLUTION_ALARM_NOTIFY", - client_id); - - if (launch_service) { - char *args[3]; - - args[0] = argv[0]; - args[2] = NULL; - - gnome_client_set_restart_style (client, GNOME_RESTART_ANYWAY); - gnome_client_set_restart_command (client, 2, args); - - args[0] = argv[0]; - args[1] = "--die"; - args[2] = NULL; - - gnome_client_set_shutdown_command (client, 2, args); - } else - gnome_client_set_restart_style (client, GNOME_RESTART_NEVER); - - gnome_client_flush (client); - } else - launch_service = TRUE; - - if (!launch_service) - return EXIT_SUCCESS; - - load_calendars (); - - return EXIT_SUCCESS; -} diff --git a/calendar/gui/alarm-notify/notify-main.c b/calendar/gui/alarm-notify/notify-main.c index 5134aae0b7..f2e2444201 100644 --- a/calendar/gui/alarm-notify/notify-main.c +++ b/calendar/gui/alarm-notify/notify-main.c @@ -36,30 +36,121 @@ #include "alarm.h" #include "alarm-queue.h" #include "alarm-notify.h" +#include "save.h" +static GnomeClient *master_client = NULL; + static BonoboGenericFactory *factory; static AlarmNotify *alarm_notify_service; +/* Callback for the master client's "die" signal. We must terminate the daemon + * since the session is ending. + */ +static void +client_die_cb (GnomeClient *client) +{ + gtk_main_quit (); +} + +/* Sees if a session manager is present. If so, it tells the SM how to restart + * the daemon when the session starts. It also sets the die callback so that + * the daemon can terminate properly when the session ends. + */ +static void +set_session_parameters (char **argv) +{ + int flags; + char *args[2]; + + master_client = gnome_master_client (); + flags = gnome_client_get_flags (master_client); + + if (!(flags & GNOME_CLIENT_IS_CONNECTED)) + return; + + /* The daemon should always be started up by the session manager when + * the session starts. The daemon will take care of loading whatever + * calendars it was told to load. + */ + gnome_client_set_restart_style (master_client, GNOME_RESTART_ANYWAY); + + args[0] = argv[0]; + args[1] = NULL; + + gnome_client_set_restart_command (master_client, 1, args); + + gtk_signal_connect (GTK_OBJECT (master_client), "die", + GTK_SIGNAL_FUNC (client_die_cb), NULL); +} + +/* Creates the singleton alarm notify service object */ +static gboolean +init_alarm_notify_service (void) +{ + g_assert (alarm_notify_service == NULL); + + alarm_notify_service = alarm_notify_new (); + return (alarm_notify_service != NULL); +} + /* Factory function for the alarm notify service; just creates and references a * singleton service object. */ static BonoboObject * alarm_notify_factory_fn (BonoboGenericFactory *factory, void *data) { - if (!alarm_notify_service) { - alarm_notify_service = alarm_notify_new (); - if (!alarm_notify_service) - return NULL; - } + g_assert (alarm_notify_service != NULL); bonobo_object_ref (BONOBO_OBJECT (alarm_notify_service)); return BONOBO_OBJECT (alarm_notify_service); } +/* Loads the calendars that the alarm daemon has been told to load in the past */ +static void +load_calendars (void) +{ + GPtrArray *uris; + int i; + + uris = get_calendars_to_load (); + g_assert (uris != NULL); + + for (i = 0; i < uris->len; i++) { + char *uri; + CORBA_Environment ev; + + uri = uris->pdata[i]; + + CORBA_exception_init (&ev); + alarm_notify_add_calendar (alarm_notify_service, uri, FALSE, &ev); + + if (ev._major == CORBA_USER_EXCEPTION) { + char *ex_id; + + ex_id = CORBA_exception_id (&ev); + if (strcmp (ex_id, ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI) == 0) + g_message ("load_calendars(): Invalid URI `%s'; will not load " + "that calendar.", uri); + else if (strcmp (ex_id, + ex_GNOME_Evolution_Calendar_AlarmNotify_BackendContactError) + == 0) + g_message ("load_calendars(): Could not contact the backend " + "while trying to load `%s'", uri); + } else if (ev._major != CORBA_NO_EXCEPTION) + g_message ("load_calendars(): Exception while loading calendar `%s'", uri); + + CORBA_exception_free (&ev); + + g_free (uri); + } + + g_ptr_array_free (uris, TRUE); +} + int main (int argc, char **argv) { @@ -84,16 +175,25 @@ main (int argc, char **argv) alarm_queue_init (); + if (!init_alarm_notify_service ()) + g_error (_("Could not create the alarm notify service")); + factory = bonobo_generic_factory_new ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify_Factory", alarm_notify_factory_fn, NULL); if (!factory) g_error (_("Could not create the alarm notify service factory")); + set_session_parameters (argv); + + load_calendars (); + bonobo_main (); bonobo_object_unref (BONOBO_OBJECT (factory)); factory = NULL; + /* FIXME: free the alarm_notify_service */ + alarm_queue_done (); alarm_done (); diff --git a/calendar/gui/alarm-notify/save.c b/calendar/gui/alarm-notify/save.c index 3fb8dde818..b4a788e71e 100644 --- a/calendar/gui/alarm-notify/save.c +++ b/calendar/gui/alarm-notify/save.c @@ -23,13 +23,22 @@ #include #endif +#include #include #include #include +#include "evolution-calendar.h" #include "save.h" +/* Key names for the configuration values */ + +#define KEY_LAST_NOTIFICATION_TIME "/Calendar/AlarmNotify/LastNotificationTime" +#define KEY_CALENDARS_TO_LOAD "/Calendar/AlarmNotify/CalendarsToLoad" + + + /* Tries to get the config database object; returns CORBA_OBJECT_NIL on failure. */ static Bonobo_ConfigDatabase get_config_db (void) @@ -94,7 +103,7 @@ save_notification_time (time_t t) CORBA_exception_init (&ev); - bonobo_config_set_long (db, "/Calendar/AlarmNotify/LastNotificationTime", (long) t, &ev); + bonobo_config_set_long (db, KEY_LAST_NOTIFICATION_TIME, (long) t, &ev); if (BONOBO_EX (&ev)) g_message ("save_notification_time(): Could not save the value"); @@ -120,10 +129,139 @@ get_saved_notification_time (void) if (db == CORBA_OBJECT_NIL) return -1; - t = bonobo_config_get_long_with_default (db, "/Calendar/AlarmNotify/LastNotificationTime", - -1, NULL); + t = bonobo_config_get_long_with_default (db, KEY_LAST_NOTIFICATION_TIME, -1, NULL); discard_config_db (db); return (time_t) t; } + +/** + * save_calendars_to_load: + * @uris: A list of URIs of calendars. + * + * Saves the list of calendars that should be loaded the next time the alarm + * daemon starts up. + **/ +void +save_calendars_to_load (GPtrArray *uris) +{ + Bonobo_ConfigDatabase db; + int len, i; + GNOME_Evolution_Calendar_StringSeq *seq; + CORBA_Environment ev; + CORBA_any *any; + + g_return_if_fail (uris != NULL); + + db = get_config_db (); + if (db == CORBA_OBJECT_NIL) + return; + + /* Build the sequence of URIs */ + + len = uris->len; + + seq = GNOME_Evolution_Calendar_StringSeq__alloc (); + seq->_length = len; + seq->_buffer = CORBA_sequence_CORBA_string_allocbuf (len); + CORBA_sequence_set_release (seq, TRUE); + + for (i = 0; i < len; i++) { + char *uri; + + uri = uris->pdata[i]; + seq->_buffer[i] = CORBA_string_dup (uri); + } + + /* Save it */ + + any = bonobo_arg_new (TC_GNOME_Evolution_Calendar_StringSeq); +#if 0 + *((GNOME_Evolution_Calendar_StringSeq **) any->_value) = seq; +#else + any->_value = seq; +#endif + CORBA_exception_init (&ev); + + bonobo_config_set_value (db, KEY_CALENDARS_TO_LOAD, any, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("save_calendars_to_load(): Could not save the list of calendars"); + + CORBA_exception_free (&ev); + + discard_config_db (db); + bonobo_arg_release (any); /* this releases the sequence */ +} + +/** + * get_calendars_to_load: + * + * Gets the list of calendars that should be loaded when the alarm daemon starts + * up. + * + * Return value: A list of URIs, or NULL if the value could not be retrieved. + **/ +GPtrArray * +get_calendars_to_load (void) +{ + Bonobo_ConfigDatabase db; + GNOME_Evolution_Calendar_StringSeq *seq; + CORBA_Environment ev; + CORBA_any *any; + int len, i; + GPtrArray *uris; + + db = get_config_db (); + if (db == CORBA_OBJECT_NIL) + return NULL; + + /* Get the value */ + + CORBA_exception_init (&ev); + + any = bonobo_config_get_value (db, KEY_CALENDARS_TO_LOAD, + TC_GNOME_Evolution_Calendar_StringSeq, + &ev); + discard_config_db (db); + + if (ev._major == CORBA_USER_EXCEPTION) { + char *ex_id; + + ex_id = CORBA_exception_id (&ev); + + if (strcmp (ex_id, ex_Bonobo_ConfigDatabase_NotFound) == 0) { + CORBA_exception_free (&ev); + uris = g_ptr_array_new (); + g_ptr_array_set_size (uris, 0); + return uris; + } + } + + if (ev._major != CORBA_NO_EXCEPTION) { + g_message ("get_calendars_to_load(): Could not get the list of calendars"); + CORBA_exception_free (&ev); + return NULL; + } + + CORBA_exception_free (&ev); + + /* Decode the value */ +#if 0 + seq = *((GNOME_Evolution_Calendar_StringSeq **) any->_value); +#else + seq = any->_value; +#endif + len = seq->_length; + + uris = g_ptr_array_new (); + g_ptr_array_set_size (uris, len); + + for (i = 0; i < len; i++) + uris->pdata[i] = g_strdup (seq->_buffer[i]); + + bonobo_arg_release (any); + + return uris; +} diff --git a/calendar/gui/alarm-notify/save.h b/calendar/gui/alarm-notify/save.h index 550fc972ea..41fee52836 100644 --- a/calendar/gui/alarm-notify/save.h +++ b/calendar/gui/alarm-notify/save.h @@ -25,7 +25,9 @@ #include void save_notification_time (time_t t); - time_t get_saved_notification_time (void); +void save_calendars_to_load (GPtrArray *uris); +GPtrArray *get_calendars_to_load (void); + #endif diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c index e13a3f8a50..5aa8913f73 100644 --- a/calendar/gui/calendar-component.c +++ b/calendar/gui/calendar-component.c @@ -142,6 +142,60 @@ create_folder (EvolutionShellComponent *shell_component, CORBA_exception_free (&ev); } +/* Asks the alarm daemon to stop monitoring the specified URI */ +static void +stop_alarms (GnomeVFSURI *uri) +{ + char *str_uri; + CORBA_Environment ev; + GNOME_Evolution_Calendar_AlarmNotify an; + + /* Activate the alarm notification service */ + + CORBA_exception_init (&ev); + an = oaf_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify", 0, NULL, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + g_message ("stop_alarms(): Could not activate the alarm notification service"); + CORBA_exception_free (&ev); + return; + } + CORBA_exception_free (&ev); + + /* Ask the service to remove the URI from its list of calendars */ + + str_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + g_assert (str_uri != NULL); + + CORBA_exception_init (&ev); + GNOME_Evolution_Calendar_AlarmNotify_removeCalendar (an, str_uri, &ev); + g_free (str_uri); + + if (ev._major == CORBA_USER_EXCEPTION) { + char *ex_id; + + ex_id = CORBA_exception_id (&ev); + if (strcmp (ex_id, ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI) == 0) + g_message ("stop_alarms(): Invalid URI reported from the " + "alarm notification service"); + else if (strcmp (ex_id, ex_GNOME_Evolution_Calendar_AlarmNotify_NotFound) == 0) { + /* This is OK; the service may not have loaded that calendar */ + } + } else if (ev._major != CORBA_NO_EXCEPTION) + g_message ("stop_alarms(): Could not issue the removeCalendar request"); + + CORBA_exception_free (&ev); + + /* Get rid of the service */ + + CORBA_exception_init (&ev); + bonobo_object_release_unref (an, &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("stop_alarms(): Could not unref the alarm notification service"); + + CORBA_exception_free (&ev); +} + static void remove_folder (EvolutionShellComponent *shell_component, const char *physical_uri, @@ -217,6 +271,10 @@ remove_folder (EvolutionShellComponent *shell_component, goto out; } + /* Ask the alarm daemon to stop monitoring this URI */ + + stop_alarms (data_uri); + /* Delete the data and backup files; the shell will take care of the rest */ data_result = gnome_vfs_unlink_from_uri (data_uri); diff --git a/calendar/gui/component-factory.c b/calendar/gui/component-factory.c index e13a3f8a50..5aa8913f73 100644 --- a/calendar/gui/component-factory.c +++ b/calendar/gui/component-factory.c @@ -142,6 +142,60 @@ create_folder (EvolutionShellComponent *shell_component, CORBA_exception_free (&ev); } +/* Asks the alarm daemon to stop monitoring the specified URI */ +static void +stop_alarms (GnomeVFSURI *uri) +{ + char *str_uri; + CORBA_Environment ev; + GNOME_Evolution_Calendar_AlarmNotify an; + + /* Activate the alarm notification service */ + + CORBA_exception_init (&ev); + an = oaf_activate_from_id ("OAFIID:GNOME_Evolution_Calendar_AlarmNotify", 0, NULL, &ev); + + if (ev._major != CORBA_NO_EXCEPTION) { + g_message ("stop_alarms(): Could not activate the alarm notification service"); + CORBA_exception_free (&ev); + return; + } + CORBA_exception_free (&ev); + + /* Ask the service to remove the URI from its list of calendars */ + + str_uri = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); + g_assert (str_uri != NULL); + + CORBA_exception_init (&ev); + GNOME_Evolution_Calendar_AlarmNotify_removeCalendar (an, str_uri, &ev); + g_free (str_uri); + + if (ev._major == CORBA_USER_EXCEPTION) { + char *ex_id; + + ex_id = CORBA_exception_id (&ev); + if (strcmp (ex_id, ex_GNOME_Evolution_Calendar_AlarmNotify_InvalidURI) == 0) + g_message ("stop_alarms(): Invalid URI reported from the " + "alarm notification service"); + else if (strcmp (ex_id, ex_GNOME_Evolution_Calendar_AlarmNotify_NotFound) == 0) { + /* This is OK; the service may not have loaded that calendar */ + } + } else if (ev._major != CORBA_NO_EXCEPTION) + g_message ("stop_alarms(): Could not issue the removeCalendar request"); + + CORBA_exception_free (&ev); + + /* Get rid of the service */ + + CORBA_exception_init (&ev); + bonobo_object_release_unref (an, &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_message ("stop_alarms(): Could not unref the alarm notification service"); + + CORBA_exception_free (&ev); +} + static void remove_folder (EvolutionShellComponent *shell_component, const char *physical_uri, @@ -217,6 +271,10 @@ remove_folder (EvolutionShellComponent *shell_component, goto out; } + /* Ask the alarm daemon to stop monitoring this URI */ + + stop_alarms (data_uri); + /* Delete the data and backup files; the shell will take care of the rest */ data_result = gnome_vfs_unlink_from_uri (data_uri); diff --git a/calendar/idl/evolution-calendar.idl b/calendar/idl/evolution-calendar.idl index cde16eba15..ca63d3c52c 100644 --- a/calendar/idl/evolution-calendar.idl +++ b/calendar/idl/evolution-calendar.idl @@ -301,16 +301,19 @@ module Calendar { exception BackendContactError {}; exception NotFound {}; - /* Adds a calendar to the alarm notification system */ + /* Adds a calendar to the alarm notification system so that + * alarms will be triggered for it. The calendar will be loaded + * automatically whenever the alarm daemon starts up. + */ void addCalendar (in string uri) raises (InvalidURI, BackendContactError); - /* Removes a calendar from the alarm notification system */ + /* Removes a calendar from the alarm notification system and + * alarms will no longer be triggered for it. The calendar will + * no longer be loaded when the alarm daemon starts up. + */ void removeCalendar (in string uri) raises (InvalidURI, NotFound); - - /* Makes the alarm notification daemon unconditionally exit */ - void die (); }; /* Factory to centralize calendar component editor dialogs */ -- cgit v1.2.3