diff options
author | nobody <nobody@localhost> | 2002-12-28 12:49:29 +0800 |
---|---|---|
committer | nobody <nobody@localhost> | 2002-12-28 12:49:29 +0800 |
commit | ab7d6ef097bf18a3ebb97c4d73947fe8d2f059c9 (patch) | |
tree | 1e12040caec266ee2e16460c80583d4af3687d10 /calendar/pcs | |
parent | 79d8fd91171f81a97c319616dcca32002269af55 (diff) | |
download | gsoc2013-evolution-ab7d6ef097bf18a3ebb97c4d73947fe8d2f059c9.tar gsoc2013-evolution-ab7d6ef097bf18a3ebb97c4d73947fe8d2f059c9.tar.gz gsoc2013-evolution-ab7d6ef097bf18a3ebb97c4d73947fe8d2f059c9.tar.bz2 gsoc2013-evolution-ab7d6ef097bf18a3ebb97c4d73947fe8d2f059c9.tar.lz gsoc2013-evolution-ab7d6ef097bf18a3ebb97c4d73947fe8d2f059c9.tar.xz gsoc2013-evolution-ab7d6ef097bf18a3ebb97c4d73947fe8d2f059c9.tar.zst gsoc2013-evolution-ab7d6ef097bf18a3ebb97c4d73947fe8d2f059c9.zip |
This commit was manufactured by cvs2svn to create tag 'GHEX_2_0_0'.GHEX_2_0_0
svn path=/tags/GHEX_2_0_0/; revision=19188
Diffstat (limited to 'calendar/pcs')
-rw-r--r-- | calendar/pcs/.cvsignore | 11 | ||||
-rw-r--r-- | calendar/pcs/Makefile.am | 67 | ||||
-rw-r--r-- | calendar/pcs/cal-backend-file.c | 2039 | ||||
-rw-r--r-- | calendar/pcs/cal-backend-file.h | 61 | ||||
-rw-r--r-- | calendar/pcs/cal-backend-util.c | 117 | ||||
-rw-r--r-- | calendar/pcs/cal-backend-util.h | 51 | ||||
-rw-r--r-- | calendar/pcs/cal-backend.c | 904 | ||||
-rw-r--r-- | calendar/pcs/cal-backend.h | 220 | ||||
-rw-r--r-- | calendar/pcs/cal-common.h | 41 | ||||
-rw-r--r-- | calendar/pcs/cal-factory.c | 836 | ||||
-rw-r--r-- | calendar/pcs/cal-factory.h | 72 | ||||
-rw-r--r-- | calendar/pcs/cal.c | 1017 | ||||
-rw-r--r-- | calendar/pcs/cal.h | 79 | ||||
-rw-r--r-- | calendar/pcs/job.c | 98 | ||||
-rw-r--r-- | calendar/pcs/job.h | 35 | ||||
-rw-r--r-- | calendar/pcs/query-backend.c | 365 | ||||
-rw-r--r-- | calendar/pcs/query-backend.h | 55 | ||||
-rw-r--r-- | calendar/pcs/query.c | 1733 | ||||
-rw-r--r-- | calendar/pcs/query.h | 68 |
19 files changed, 0 insertions, 7869 deletions
diff --git a/calendar/pcs/.cvsignore b/calendar/pcs/.cvsignore deleted file mode 100644 index ac51a554db..0000000000 --- a/calendar/pcs/.cvsignore +++ /dev/null @@ -1,11 +0,0 @@ -Makefile -Makefile.in -.deps -.libs -.pure -*.la -*.lo -evolution-calendar-stubs.c -evolution-calendar-skels.c -evolution-calendar-common.c -evolution-calendar.h diff --git a/calendar/pcs/Makefile.am b/calendar/pcs/Makefile.am deleted file mode 100644 index 3432837685..0000000000 --- a/calendar/pcs/Makefile.am +++ /dev/null @@ -1,67 +0,0 @@ -INCLUDES = \ - -DG_LOG_DOMAIN=\"wombat-pcs\" \ - -I$(top_srcdir) \ - -I$(top_srcdir)/calendar \ - -I$(top_builddir)/calendar \ - -I$(top_srcdir)/libical/src/libical \ - -I$(top_builddir)/libical/src/libical \ - -I$(top_srcdir)/libwombat \ - -I$(top_builddir)/libwombat \ - -DGNOMELOCALEDIR=\""$(localedir)"\" \ - $(EVOLUTION_CALENDAR_CFLAGS) - -CORBA_GENERATED_H = \ - evolution-calendar.h - -CORBA_GENERATED_C = \ - evolution-calendar-common.c \ - evolution-calendar-skels.c \ - evolution-calendar-stubs.c - -CORBA_GENERATED = $(CORBA_GENERATED_H) $(CORBA_GENERATED_C) - -idls = \ - $(srcdir)/../idl/evolution-calendar.idl - -idl_flags = -I $(srcdir) $(IDL_INCLUDES) - -$(CORBA_GENERATED): $(idls) - $(ORBIT_IDL) $(idl_flags) $(srcdir)/../idl/evolution-calendar.idl - -pcsincludedir = $(includedir)/evolution/pcs - -privlib_LIBRARIES = libpcs.a -noinst_LIBRARIES = libpcsfile.a - -pcsinclude_HEADERS = \ - $(CORBA_GENERATED_H) \ - cal.h \ - cal-backend.h \ - cal-backend-util.h \ - cal-common.h \ - cal-factory.h \ - job.h \ - query-backend.h \ - query.h - -libpcs_a_SOURCES = \ - $(pcsinclude_HEADERS) \ - $(CORBA_GENERATED_C) \ - cal.c \ - cal-backend.c \ - cal-backend-util.c \ - cal-factory.c \ - job.c \ - query-backend.c \ - query.c - -libpcsfile_a_SOURCES = \ - cal-backend-file.c \ - cal-backend-file.h - -BUILT_SOURCES = $(CORBA_GENERATED) -CLEANFILES = $(BUILT_SOURCES) - -dist-hook: - cd $(distdir); rm -f $(BUILT_SOURCES) - diff --git a/calendar/pcs/cal-backend-file.c b/calendar/pcs/cal-backend-file.c deleted file mode 100644 index 595626f043..0000000000 --- a/calendar/pcs/cal-backend-file.c +++ /dev/null @@ -1,2039 +0,0 @@ -/* Evolution calendar - iCalendar file backend - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#include <config.h> -#include <string.h> -#include <bonobo/bonobo-exception.h> -#include <bonobo/bonobo-moniker-util.h> -#include <libgnomevfs/gnome-vfs.h> -#include "e-util/e-dbhash.h" -#include "cal-util/cal-recur.h" -#include "cal-util/cal-util.h" -#include "cal-backend-file.h" -#include "cal-backend-util.h" - - - -/* A category that exists in some of the objects of the calendar */ -typedef struct { - /* Category name, also used as the key in the categories hash table */ - char *name; - - /* Number of objects that have this category */ - int refcount; -} Category; - -/* Private part of the CalBackendFile structure */ -struct _CalBackendFilePrivate { - /* URI where the calendar data is stored */ - char *uri; - - /* List of Cal objects with their listeners */ - GList *clients; - - /* Toplevel VCALENDAR component */ - icalcomponent *icalcomp; - - /* All the CalComponent objects in the calendar, hashed by UID. The - * hash key *is* the uid returned by cal_component_get_uid(); it is not - * copied, so don't free it when you remove an object from the hash - * table. - */ - GHashTable *comp_uid_hash; - - /* All event, to-do, and journal components in the calendar; they are - * here just for easy access (i.e. so that you don't have to iterate - * over the comp_uid_hash). If you need *all* the components in the - * calendar, iterate over the hash instead. - */ - GList *events; - GList *todos; - GList *journals; - - /* Hash table of live categories, and a temporary hash of removed categories */ - GHashTable *categories; - GHashTable *removed_categories; - - /* Config database handle for free/busy organizer information */ - EConfigListener *config_listener; - - /* Idle handler for saving the calendar when it is dirty */ - guint idle_id; - - /* The calendar's default timezone, used for resolving DATE and - floating DATE-TIME values. */ - icaltimezone *default_zone; -}; - - - -static void cal_backend_file_class_init (CalBackendFileClass *class); -static void cal_backend_file_init (CalBackendFile *cbfile, CalBackendFileClass *class); -static void cal_backend_file_dispose (GObject *object); -static void cal_backend_file_finalize (GObject *object); - -static const char *cal_backend_file_get_uri (CalBackend *backend); -static gboolean cal_backend_file_is_read_only (CalBackend *backend); -static const char *cal_backend_file_get_email_address (CalBackend *backend); -static CalBackendOpenStatus cal_backend_file_open (CalBackend *backend, - const char *uristr, - gboolean only_if_exists); -static gboolean cal_backend_file_is_loaded (CalBackend *backend); -static Query *cal_backend_file_get_query (CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp); - -static CalMode cal_backend_file_get_mode (CalBackend *backend); -static void cal_backend_file_set_mode (CalBackend *backend, CalMode mode); - -static int cal_backend_file_get_n_objects (CalBackend *backend, CalObjType type); -static char *cal_backend_file_get_object (CalBackend *backend, const char *uid); -static CalComponent *cal_backend_file_get_object_component (CalBackend *backend, const char *uid); -static char *cal_backend_file_get_timezone_object (CalBackend *backend, const char *tzid); -static GList *cal_backend_file_get_uids (CalBackend *backend, CalObjType type); -static GList *cal_backend_file_get_objects_in_range (CalBackend *backend, CalObjType type, - time_t start, time_t end); -static GList *cal_backend_file_get_free_busy (CalBackend *backend, GList *users, time_t start, time_t end); -static GNOME_Evolution_Calendar_CalObjChangeSeq *cal_backend_file_get_changes ( - CalBackend *backend, CalObjType type, const char *change_id); - -static GNOME_Evolution_Calendar_CalComponentAlarmsSeq *cal_backend_file_get_alarms_in_range ( - CalBackend *backend, time_t start, time_t end); - -static GNOME_Evolution_Calendar_CalComponentAlarms *cal_backend_file_get_alarms_for_object ( - CalBackend *backend, const char *uid, - time_t start, time_t end, gboolean *object_found); - -static CalBackendResult cal_backend_file_update_objects (CalBackend *backend, - const char *calobj); -static CalBackendResult cal_backend_file_remove_object (CalBackend *backend, const char *uid); - -static CalBackendSendResult cal_backend_file_send_object (CalBackend *backend, - const char *calobj, gchar **new_calobj, - GNOME_Evolution_Calendar_UserList **user_list, - char error_msg[256]); - -static icaltimezone* cal_backend_file_get_timezone (CalBackend *backend, const char *tzid); -static icaltimezone* cal_backend_file_get_default_timezone (CalBackend *backend); -static gboolean cal_backend_file_set_default_timezone (CalBackend *backend, - const char *tzid); - -static void notify_categories_changed (CalBackendFile *cbfile); -static void notify_error (CalBackendFile *cbfile, const char *message); - -static CalBackendClass *parent_class; - - - -/** - * cal_backend_file_get_type: - * @void: - * - * Registers the #CalBackendFile class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #CalBackendFile class. - **/ -GType -cal_backend_file_get_type (void) -{ - static GType cal_backend_file_type = 0; - - if (!cal_backend_file_type) { - static GTypeInfo info = { - sizeof (CalBackendFileClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) cal_backend_file_class_init, - NULL, NULL, - sizeof (CalBackendFile), - 0, - (GInstanceInitFunc) cal_backend_file_init - }; - cal_backend_file_type = g_type_register_static (CAL_BACKEND_TYPE, - "CalBackendFile", &info, 0); - } - - return cal_backend_file_type; -} - -/* Class initialization function for the file backend */ -static void -cal_backend_file_class_init (CalBackendFileClass *class) -{ - GObjectClass *object_class; - CalBackendClass *backend_class; - - object_class = (GObjectClass *) class; - backend_class = (CalBackendClass *) class; - - parent_class = (CalBackendClass *) g_type_class_peek_parent (class); - - object_class->dispose = cal_backend_file_dispose; - object_class->finalize = cal_backend_file_finalize; - - backend_class->get_uri = cal_backend_file_get_uri; - backend_class->is_read_only = cal_backend_file_is_read_only; - backend_class->get_email_address = cal_backend_file_get_email_address; - backend_class->open = cal_backend_file_open; - backend_class->is_loaded = cal_backend_file_is_loaded; - backend_class->get_query = cal_backend_file_get_query; - backend_class->get_mode = cal_backend_file_get_mode; - backend_class->set_mode = cal_backend_file_set_mode; - backend_class->get_n_objects = cal_backend_file_get_n_objects; - backend_class->get_object = cal_backend_file_get_object; - backend_class->get_object_component = cal_backend_file_get_object_component; - backend_class->get_timezone_object = cal_backend_file_get_timezone_object; - backend_class->get_uids = cal_backend_file_get_uids; - backend_class->get_objects_in_range = cal_backend_file_get_objects_in_range; - backend_class->get_free_busy = cal_backend_file_get_free_busy; - backend_class->get_changes = cal_backend_file_get_changes; - backend_class->get_alarms_in_range = cal_backend_file_get_alarms_in_range; - backend_class->get_alarms_for_object = cal_backend_file_get_alarms_for_object; - backend_class->update_objects = cal_backend_file_update_objects; - backend_class->remove_object = cal_backend_file_remove_object; - backend_class->send_object = cal_backend_file_send_object; - - backend_class->get_timezone = cal_backend_file_get_timezone; - backend_class->get_default_timezone = cal_backend_file_get_default_timezone; - backend_class->set_default_timezone = cal_backend_file_set_default_timezone; -} - -static void -cal_added_cb (CalBackend *backend, gpointer user_data) -{ - notify_categories_changed (CAL_BACKEND_FILE (backend)); -} - -/* Object initialization function for the file backend */ -static void -cal_backend_file_init (CalBackendFile *cbfile, CalBackendFileClass *class) -{ - CalBackendFilePrivate *priv; - - priv = g_new0 (CalBackendFilePrivate, 1); - cbfile->priv = priv; - - priv->uri = NULL; - priv->icalcomp = NULL; - priv->comp_uid_hash = NULL; - priv->events = NULL; - priv->todos = NULL; - priv->journals = NULL; - - priv->categories = g_hash_table_new (g_str_hash, g_str_equal); - priv->removed_categories = g_hash_table_new (g_str_hash, g_str_equal); - - /* The timezone defaults to UTC. */ - priv->default_zone = icaltimezone_get_utc_timezone (); - - priv->config_listener = e_config_listener_new (); - - g_signal_connect (G_OBJECT (cbfile), "cal_added", - G_CALLBACK (cal_added_cb), NULL); -} - -/* g_hash_table_foreach() callback to destroy a CalComponent */ -static void -free_cal_component (gpointer key, gpointer value, gpointer data) -{ - CalComponent *comp; - - comp = CAL_COMPONENT (value); - g_object_unref (comp); -} - -/* Saves the calendar data */ -static void -save (CalBackendFile *cbfile) -{ - CalBackendFilePrivate *priv; - GnomeVFSURI *uri, *backup_uri; - GnomeVFSHandle *handle = NULL; - GnomeVFSResult result; - GnomeVFSFileSize out; - gchar *tmp, *backup_uristr; - char *buf; - - priv = cbfile->priv; - g_assert (priv->uri != NULL); - g_assert (priv->icalcomp != NULL); - - uri = gnome_vfs_uri_new (priv->uri); - if (!uri) - goto error; - - /* save calendar to backup file */ - tmp = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE); - if (!tmp) { - gnome_vfs_uri_unref (uri); - goto error; - } - - backup_uristr = g_strconcat (tmp, "~", NULL); - backup_uri = gnome_vfs_uri_new (backup_uristr); - - g_free (tmp); - g_free (backup_uristr); - - if (!backup_uri) { - gnome_vfs_uri_unref (uri); - goto error; - } - - result = gnome_vfs_create_uri (&handle, backup_uri, - GNOME_VFS_OPEN_WRITE, - FALSE, 0666); - if (result != GNOME_VFS_OK) { - gnome_vfs_uri_unref (uri); - gnome_vfs_uri_unref (backup_uri); - goto error; - } - - buf = icalcomponent_as_ical_string (priv->icalcomp); - result = gnome_vfs_write (handle, buf, strlen (buf) * sizeof (char), &out); - gnome_vfs_close (handle); - if (result != GNOME_VFS_OK) { - gnome_vfs_uri_unref (uri); - gnome_vfs_uri_unref (backup_uri); - goto error; - } - - /* now copy the temporary file to the real file */ - result = gnome_vfs_move_uri (backup_uri, uri, TRUE); - - gnome_vfs_uri_unref (uri); - gnome_vfs_uri_unref (backup_uri); - if (result != GNOME_VFS_OK) - goto error; - - return; - - error: - notify_error (cbfile, gnome_vfs_result_to_string (result)); - return; -} - -/* Used from g_hash_table_foreach(), frees a Category structure */ -static void -free_category_cb (gpointer key, gpointer value, gpointer data) -{ - Category *c; - - c = value; - g_free (c->name); - g_free (c); -} - -/* Dispose handler for the file backend */ -static void -cal_backend_file_dispose (GObject *object) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - cbfile = CAL_BACKEND_FILE (object); - priv = cbfile->priv; - - /* Save if necessary */ - - if (priv->idle_id != 0) { - save (cbfile); - g_source_remove (priv->idle_id); - priv->idle_id = 0; - } - - if (priv->comp_uid_hash) { - g_hash_table_foreach (priv->comp_uid_hash, - free_cal_component, NULL); - g_hash_table_destroy (priv->comp_uid_hash); - priv->comp_uid_hash = NULL; - } - - g_list_free (priv->events); - g_list_free (priv->todos); - g_list_free (priv->journals); - priv->events = NULL; - priv->todos = NULL; - priv->journals = NULL; - - if (priv->icalcomp) { - icalcomponent_free (priv->icalcomp); - priv->icalcomp = NULL; - } - - if (priv->config_listener) { - g_object_unref (priv->config_listener); - priv->config_listener = NULL; - } - - if (G_OBJECT_CLASS (parent_class)->dispose) - (* G_OBJECT_CLASS (parent_class)->dispose) (object); -} - -/* Finalize handler for the file backend */ -static void -cal_backend_file_finalize (GObject *object) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - GList *clients; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CAL_BACKEND_FILE (object)); - - cbfile = CAL_BACKEND_FILE (object); - priv = cbfile->priv; - - clients = CAL_BACKEND (cbfile)->clients; - g_assert (clients == NULL); - - /* Clean up */ - - if (priv->uri) { - g_free (priv->uri); - priv->uri = NULL; - } - - g_hash_table_foreach (priv->categories, free_category_cb, NULL); - g_hash_table_destroy (priv->categories); - priv->categories = NULL; - - g_hash_table_foreach (priv->removed_categories, free_category_cb, NULL); - g_hash_table_destroy (priv->removed_categories); - priv->removed_categories = NULL; - - g_free (priv); - cbfile->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - - - -/* Looks up a component by its UID on the backend's component hash table */ -static CalComponent * -lookup_component (CalBackendFile *cbfile, const char *uid) -{ - CalBackendFilePrivate *priv; - CalComponent *comp; - - priv = cbfile->priv; - - comp = g_hash_table_lookup (priv->comp_uid_hash, uid); - - return comp; -} - - - -/* Calendar backend methods */ - -/* Get_uri handler for the file backend */ -static const char * -cal_backend_file_get_uri (CalBackend *backend) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - g_assert (priv->uri != NULL); - - return (const char *) priv->uri; -} - -/* Is_read_only handler for the file backend */ -static gboolean -cal_backend_file_is_read_only (CalBackend *backend) -{ - /* we just return FALSE, since all calendars are read-write */ - return FALSE; -} - -/* Get_email_address handler for the file backend */ -static const char * -cal_backend_file_get_email_address (CalBackend *backend) -{ - /* A file backend has no particular email address associated - * with it (although that would be a useful feature some day). - */ - return NULL; -} - -/* Used from g_hash_table_foreach(), adds a category name to the sequence */ -static void -add_category_cb (gpointer key, gpointer value, gpointer data) -{ - Category *c; - GNOME_Evolution_Calendar_StringSeq *seq; - - c = value; - seq = data; - - seq->_buffer[seq->_length] = CORBA_string_dup (c->name); - seq->_length++; -} - -/* Notifies the clients with the current list of categories */ -static void -notify_categories_changed (CalBackendFile *cbfile) -{ - CalBackendFilePrivate *priv; - GNOME_Evolution_Calendar_StringSeq *seq; - GList *l; - - priv = cbfile->priv; - - /* Build the sequence of category names */ - - seq = GNOME_Evolution_Calendar_StringSeq__alloc (); - seq->_length = 0; - seq->_maximum = g_hash_table_size (priv->categories); - seq->_buffer = CORBA_sequence_CORBA_string_allocbuf (seq->_maximum); - CORBA_sequence_set_release (seq, TRUE); - - g_hash_table_foreach (priv->categories, add_category_cb, seq); - g_assert (seq->_length == seq->_maximum); - - /* Notify the clients */ - - for (l = CAL_BACKEND (cbfile)->clients; l; l = l->next) { - Cal *cal; - - cal = CAL (l->data); - cal_notify_categories_changed (cal, seq); - } - - CORBA_free (seq); -} - -/* Idle handler; we save the calendar since it is dirty */ -static gboolean -save_idle (gpointer data) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - cbfile = CAL_BACKEND_FILE (data); - priv = cbfile->priv; - - g_assert (priv->icalcomp != NULL); - - save (cbfile); - - priv->idle_id = 0; - return FALSE; -} - -/* Marks the file backend as dirty and queues a save operation */ -static void -mark_dirty (CalBackendFile *cbfile) -{ - CalBackendFilePrivate *priv; - - priv = cbfile->priv; - - if (priv->idle_id != 0) - return; - - priv->idle_id = g_idle_add (save_idle, cbfile); -} - -/* Checks if the specified component has a duplicated UID and if so changes it */ -static void -check_dup_uid (CalBackendFile *cbfile, CalComponent *comp) -{ - CalBackendFilePrivate *priv; - CalComponent *old_comp; - const char *uid; - char *new_uid; - - priv = cbfile->priv; - - cal_component_get_uid (comp, &uid); - - old_comp = g_hash_table_lookup (priv->comp_uid_hash, uid); - if (!old_comp) - return; /* Everything is fine */ - - g_message ("check_dup_uid(): Got object with duplicated UID `%s', changing it...", uid); - - new_uid = cal_component_gen_uid (); - cal_component_set_uid (comp, new_uid); - g_free (new_uid); - - /* FIXME: I think we need to reset the SEQUENCE property and reset the - * CREATED/DTSTAMP/LAST-MODIFIED. - */ - - mark_dirty (cbfile); -} - -/* Updates the hash table of categories by adding or removing those in the - * component. - */ -static void -update_categories_from_comp (CalBackendFile *cbfile, CalComponent *comp, gboolean add) -{ - CalBackendFilePrivate *priv; - GSList *categories, *l; - - priv = cbfile->priv; - - cal_component_get_categories_list (comp, &categories); - - for (l = categories; l; l = l->next) { - const char *name; - Category *c; - - name = l->data; - c = g_hash_table_lookup (priv->categories, name); - - if (add) { - /* Add the category to the set */ - if (c) - c->refcount++; - else { - /* See if it was in the removed categories */ - - c = g_hash_table_lookup (priv->removed_categories, name); - if (c) { - /* Move it to the set of live categories */ - g_assert (c->refcount == 0); - g_hash_table_remove (priv->removed_categories, c->name); - - c->refcount = 1; - g_hash_table_insert (priv->categories, c->name, c); - } else { - /* Create a new category */ - c = g_new (Category, 1); - c->name = g_strdup (name); - c->refcount = 1; - - g_hash_table_insert (priv->categories, c->name, c); - } - } - } else { - /* Remove the category from the set --- it *must* have existed */ - - g_assert (c != NULL); - g_assert (c->refcount > 0); - - c->refcount--; - - if (c->refcount == 0) { - g_hash_table_remove (priv->categories, c->name); - g_hash_table_insert (priv->removed_categories, c->name, c); - } - } - } - - cal_component_free_categories_list (categories); -} - -/* Tries to add an icalcomponent to the file backend. We only store the objects - * of the types we support; all others just remain in the toplevel component so - * that we don't lose them. - */ -static void -add_component (CalBackendFile *cbfile, CalComponent *comp, gboolean add_to_toplevel) -{ - CalBackendFilePrivate *priv; - GList **list; - const char *uid; - - priv = cbfile->priv; - - switch (cal_component_get_vtype (comp)) { - case CAL_COMPONENT_EVENT: - list = &priv->events; - break; - - case CAL_COMPONENT_TODO: - list = &priv->todos; - break; - - case CAL_COMPONENT_JOURNAL: - list = &priv->journals; - break; - - default: - g_assert_not_reached (); - return; - } - - /* Ensure that the UID is unique; some broken implementations spit - * components with duplicated UIDs. - */ - check_dup_uid (cbfile, comp); - cal_component_get_uid (comp, &uid); - g_hash_table_insert (priv->comp_uid_hash, (char *)uid, comp); - - *list = g_list_prepend (*list, comp); - - /* Put the object in the toplevel component if required */ - - if (add_to_toplevel) { - icalcomponent *icalcomp; - - icalcomp = cal_component_get_icalcomponent (comp); - g_assert (icalcomp != NULL); - - icalcomponent_add_component (priv->icalcomp, icalcomp); - } - - /* Update the set of categories */ - - update_categories_from_comp (cbfile, comp, TRUE); -} - -/* Removes a component from the backend's hash and lists. Does not perform - * notification on the clients. Also removes the component from the toplevel - * icalcomponent. - */ -static void -remove_component (CalBackendFile *cbfile, CalComponent *comp) -{ - CalBackendFilePrivate *priv; - icalcomponent *icalcomp; - const char *uid; - GList **list, *l; - - priv = cbfile->priv; - - /* Remove the icalcomp from the toplevel */ - - icalcomp = cal_component_get_icalcomponent (comp); - g_assert (icalcomp != NULL); - - icalcomponent_remove_component (priv->icalcomp, icalcomp); - - /* Remove it from our mapping */ - - cal_component_get_uid (comp, &uid); - g_hash_table_remove (priv->comp_uid_hash, uid); - - switch (cal_component_get_vtype (comp)) { - case CAL_COMPONENT_EVENT: - list = &priv->events; - break; - - case CAL_COMPONENT_TODO: - list = &priv->todos; - break; - - case CAL_COMPONENT_JOURNAL: - list = &priv->journals; - break; - - default: - /* Make the compiler shut up. */ - list = NULL; - g_assert_not_reached (); - } - - l = g_list_find (*list, comp); - g_assert (l != NULL); - - *list = g_list_remove_link (*list, l); - g_list_free_1 (l); - - /* Update the set of categories */ - - update_categories_from_comp (cbfile, comp, FALSE); - - g_object_unref (comp); -} - -/* Scans the toplevel VCALENDAR component and stores the objects it finds */ -static void -scan_vcalendar (CalBackendFile *cbfile) -{ - CalBackendFilePrivate *priv; - icalcompiter iter; - - priv = cbfile->priv; - g_assert (priv->icalcomp != NULL); - g_assert (priv->comp_uid_hash != NULL); - - for (iter = icalcomponent_begin_component (priv->icalcomp, ICAL_ANY_COMPONENT); - icalcompiter_deref (&iter) != NULL; - icalcompiter_next (&iter)) { - icalcomponent *icalcomp; - icalcomponent_kind kind; - CalComponent *comp; - - icalcomp = icalcompiter_deref (&iter); - - kind = icalcomponent_isa (icalcomp); - - if (!(kind == ICAL_VEVENT_COMPONENT - || kind == ICAL_VTODO_COMPONENT - || kind == ICAL_VJOURNAL_COMPONENT)) - continue; - - comp = cal_component_new (); - - if (!cal_component_set_icalcomponent (comp, icalcomp)) - continue; - - add_component (cbfile, comp, FALSE); - } -} - -/* Callback used from icalparser_parse() */ -static char * -get_line_fn (char *s, size_t size, void *data) -{ - FILE *file; - - file = data; - return fgets (s, size, file); -} - -/* Parses an open iCalendar file and returns a toplevel component with the contents */ -static icalcomponent * -parse_file (FILE *file) -{ - icalparser *parser; - icalcomponent *icalcomp; - - parser = icalparser_new (); - icalparser_set_gen_data (parser, file); - - icalcomp = icalparser_parse (parser, get_line_fn); - icalparser_free (parser); - - return icalcomp; -} - -/* Parses an open iCalendar file and loads it into the backend */ -static CalBackendOpenStatus -open_cal (CalBackendFile *cbfile, const char *uristr, FILE *file) -{ - CalBackendFilePrivate *priv; - icalcomponent *icalcomp; - - priv = cbfile->priv; - - icalcomp = parse_file (file); - - if (fclose (file) != 0) { - if (icalcomp) - icalcomponent_free (icalcomp); - - return CAL_BACKEND_OPEN_ERROR; - } - - if (!icalcomp) - return CAL_BACKEND_OPEN_ERROR; - - /* FIXME: should we try to demangle XROOT components and - * individual components as well? - */ - - if (icalcomponent_isa (icalcomp) != ICAL_VCALENDAR_COMPONENT) { - icalcomponent_free (icalcomp); - return CAL_BACKEND_OPEN_ERROR; - } - - priv->icalcomp = icalcomp; - - priv->comp_uid_hash = g_hash_table_new (g_str_hash, g_str_equal); - scan_vcalendar (cbfile); - - priv->uri = g_strdup (uristr); - - return CAL_BACKEND_OPEN_SUCCESS; -} - -static CalBackendOpenStatus -create_cal (CalBackendFile *cbfile, const char *uristr) -{ - CalBackendFilePrivate *priv; - - priv = cbfile->priv; - - /* Create the new calendar information */ - priv->icalcomp = cal_util_new_top_level (); - - /* Create our internal data */ - priv->comp_uid_hash = g_hash_table_new (g_str_hash, g_str_equal); - - priv->uri = g_strdup (uristr); - - mark_dirty (cbfile); - - return CAL_BACKEND_OPEN_SUCCESS; -} - -/* Open handler for the file backend */ -static CalBackendOpenStatus -cal_backend_file_open (CalBackend *backend, const char *uristr, gboolean only_if_exists) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - FILE *file; - char *str_uri; - GnomeVFSURI *uri; - CalBackendOpenStatus status; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp == NULL, CAL_BACKEND_OPEN_ERROR); - g_return_val_if_fail (uristr != NULL, CAL_BACKEND_OPEN_ERROR); - - g_assert (priv->uri == NULL); - g_assert (priv->comp_uid_hash == NULL); - - uri = gnome_vfs_uri_new (uristr); - if (!uri) - return CAL_BACKEND_OPEN_ERROR; - - if (!gnome_vfs_uri_is_local (uri)) { - gnome_vfs_uri_unref (uri); - return CAL_BACKEND_OPEN_ERROR; - } - - str_uri = gnome_vfs_uri_to_string (uri, - (GNOME_VFS_URI_HIDE_USER_NAME - | GNOME_VFS_URI_HIDE_PASSWORD - | GNOME_VFS_URI_HIDE_HOST_NAME - | GNOME_VFS_URI_HIDE_HOST_PORT - | GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD)); - if (!str_uri || !strlen (str_uri)) { - g_free (str_uri); - gnome_vfs_uri_unref (uri); - return CAL_BACKEND_OPEN_ERROR; - } - - /* Load! */ - file = fopen (str_uri, "r"); - - if (file) - status = open_cal (cbfile, str_uri, file); - else { - if (only_if_exists) - status = CAL_BACKEND_OPEN_NOT_FOUND; - else - status = create_cal (cbfile, str_uri); - } - - g_free (str_uri); - gnome_vfs_uri_unref (uri); - - return status; -} - -/* is_loaded handler for the file backend */ -static gboolean -cal_backend_file_is_loaded (CalBackend *backend) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - return (priv->icalcomp != NULL); -} - -/* get_query handler for the file backend */ -static Query * -cal_backend_file_get_query (CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp) -{ - CalBackendFile *cbfile; - - cbfile = CAL_BACKEND_FILE (backend); - - return query_new (backend, ql, sexp); -} - -/* is_remote handler for the file backend */ -static CalMode -cal_backend_file_get_mode (CalBackend *backend) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - return CAL_MODE_LOCAL; -} - -static void -notify_mode (CalBackendFile *cbfile, - GNOME_Evolution_Calendar_Listener_SetModeStatus status, - GNOME_Evolution_Calendar_CalMode mode) -{ - CalBackendFilePrivate *priv; - GList *l; - - priv = cbfile->priv; - - for (l = CAL_BACKEND (cbfile)->clients; l; l = l->next) { - Cal *cal; - - cal = CAL (l->data); - cal_notify_mode (cal, status, mode); - } -} - -/* Set_mode handler for the file backend */ -static void -cal_backend_file_set_mode (CalBackend *backend, CalMode mode) -{ - notify_mode (CAL_BACKEND_FILE (backend), - GNOME_Evolution_Calendar_Listener_MODE_NOT_SUPPORTED, - GNOME_Evolution_Calendar_MODE_LOCAL); - -} - -/* Get_n_objects handler for the file backend */ -static int -cal_backend_file_get_n_objects (CalBackend *backend, CalObjType type) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - int n; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, -1); - - n = 0; - - if (type & CALOBJ_TYPE_EVENT) - n += g_list_length (priv->events); - - if (type & CALOBJ_TYPE_TODO) - n += g_list_length (priv->todos); - - if (type & CALOBJ_TYPE_JOURNAL) - n += g_list_length (priv->journals); - - return n; -} - -/* Get_object handler for the file backend */ -static char * -cal_backend_file_get_object (CalBackend *backend, const char *uid) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - CalComponent *comp; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (uid != NULL, NULL); - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - g_assert (priv->comp_uid_hash != NULL); - - comp = lookup_component (cbfile, uid); - - if (!comp) - return NULL; - - return cal_component_get_as_string (comp); -} - -/* Get_object handler for the file backend */ -static CalComponent * -cal_backend_file_get_object_component (CalBackend *backend, const char *uid) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (uid != NULL, NULL); - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - g_assert (priv->comp_uid_hash != NULL); - - return lookup_component (cbfile, uid); -} - -/* Get_object handler for the file backend */ -static char * -cal_backend_file_get_timezone_object (CalBackend *backend, const char *tzid) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - icaltimezone *zone; - icalcomponent *icalcomp; - char *ical_string; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (tzid != NULL, NULL); - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - g_assert (priv->comp_uid_hash != NULL); - - zone = icalcomponent_get_timezone (priv->icalcomp, tzid); - if (!zone) { - zone = icaltimezone_get_builtin_timezone_from_tzid (tzid); - if (!zone) - return NULL; - } - - icalcomp = icaltimezone_get_component (zone); - if (!icalcomp) - return NULL; - - ical_string = icalcomponent_as_ical_string (icalcomp); - /* We dup the string; libical owns that memory. */ - if (ical_string) - return g_strdup (ical_string); - else - return NULL; -} - -/* Builds a list of UIDs from a list of CalComponent objects */ -static void -build_uids_list (GList **list, GList *components) -{ - GList *l; - - for (l = components; l; l = l->next) { - CalComponent *comp; - const char *uid; - - comp = CAL_COMPONENT (l->data); - cal_component_get_uid (comp, &uid); - *list = g_list_prepend (*list, g_strdup (uid)); - } -} - -/* Get_uids handler for the file backend */ -static GList * -cal_backend_file_get_uids (CalBackend *backend, CalObjType type) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - GList *list; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - list = NULL; - - if (type & CALOBJ_TYPE_EVENT) - build_uids_list (&list, priv->events); - - if (type & CALOBJ_TYPE_TODO) - build_uids_list (&list, priv->todos); - - if (type & CALOBJ_TYPE_JOURNAL) - build_uids_list (&list, priv->journals); - - return list; -} - -/* function to resolve timezones */ -static icaltimezone * -resolve_tzid (const char *tzid, gpointer user_data) -{ - icalcomponent *vcalendar_comp = user_data; - - if (!tzid || !tzid[0]) - return NULL; - else if (!strcmp (tzid, "UTC")) - return icaltimezone_get_utc_timezone (); - - return icalcomponent_get_timezone (vcalendar_comp, tzid); -} - -/* Callback used from cal_recur_generate_instances(); adds the component's UID - * to our hash table. - */ -static gboolean -add_instance (CalComponent *comp, time_t start, time_t end, gpointer data) -{ - GHashTable *uid_hash; - const char *uid; - const char *old_uid; - - uid_hash = data; - - /* We only care that the component's UID is listed in the hash table; - * that's why we only allow generation of one instance (i.e. return - * FALSE every time). - */ - - cal_component_get_uid (comp, &uid); - - old_uid = g_hash_table_lookup (uid_hash, uid); - if (old_uid) - return FALSE; - - g_hash_table_insert (uid_hash, (char *) uid, NULL); - return FALSE; -} - -/* Populates a hash table with the UIDs of the components that occur or recur - * within a specific time range. - */ -static void -get_instances_in_range (GHashTable *uid_hash, GList *components, time_t start, time_t end, icaltimezone *default_zone) -{ - GList *l; - - for (l = components; l; l = l->next) { - CalComponent *comp; - icalcomponent *icalcomp, *vcalendar_comp; - - comp = CAL_COMPONENT (l->data); - - /* Get the parent VCALENDAR component, so we can resolve - TZIDs. */ - icalcomp = cal_component_get_icalcomponent (comp); - vcalendar_comp = icalcomponent_get_parent (icalcomp); - g_assert (vcalendar_comp != NULL); - - cal_recur_generate_instances (comp, start, end, add_instance, uid_hash, resolve_tzid, vcalendar_comp, default_zone); - } -} - -/* Used from g_hash_table_foreach(), adds a UID from the hash table to our list */ -static void -add_uid_to_list (gpointer key, gpointer value, gpointer data) -{ - GList **list; - const char *uid; - char *uid_copy; - - list = data; - - uid = key; - uid_copy = g_strdup (uid); - - *list = g_list_prepend (*list, uid_copy); -} - -/* Get_objects_in_range handler for the file backend */ -static GList * -cal_backend_file_get_objects_in_range (CalBackend *backend, CalObjType type, - time_t start, time_t end) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - GList *event_list; - GHashTable *uid_hash; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - g_return_val_if_fail (start != -1 && end != -1, NULL); - g_return_val_if_fail (start <= end, NULL); - - uid_hash = g_hash_table_new (g_str_hash, g_str_equal); - - if (type & CALOBJ_TYPE_EVENT) - get_instances_in_range (uid_hash, priv->events, start, end, - priv->default_zone); - - if (type & CALOBJ_TYPE_TODO) - get_instances_in_range (uid_hash, priv->todos, start, end, - priv->default_zone); - - if (type & CALOBJ_TYPE_JOURNAL) - get_instances_in_range (uid_hash, priv->journals, start, end, - priv->default_zone); - - event_list = NULL; - g_hash_table_foreach (uid_hash, add_uid_to_list, &event_list); - g_hash_table_destroy (uid_hash); - - return event_list; -} - -static gboolean -free_busy_instance (CalComponent *comp, - time_t instance_start, - time_t instance_end, - gpointer data) -{ - icalcomponent *vfb = data; - icalproperty *prop; - icalparameter *param; - struct icalperiodtype ipt; - icaltimezone *utc_zone; - - utc_zone = icaltimezone_get_utc_timezone (); - - ipt.start = icaltime_from_timet_with_zone (instance_start, FALSE, utc_zone); - ipt.end = icaltime_from_timet_with_zone (instance_end, FALSE, utc_zone); - ipt.duration = icaldurationtype_null_duration (); - - /* add busy information to the vfb component */ - prop = icalproperty_new (ICAL_FREEBUSY_PROPERTY); - icalproperty_set_freebusy (prop, ipt); - - param = icalparameter_new_fbtype (ICAL_FBTYPE_BUSY); - icalproperty_add_parameter (prop, param); - - icalcomponent_add_property (vfb, prop); - - return TRUE; -} - -static icalcomponent * -create_user_free_busy (CalBackendFile *cbfile, const char *address, const char *cn, - time_t start, time_t end) -{ - CalBackendFilePrivate *priv; - GList *uids; - GList *l; - icalcomponent *vfb; - icaltimezone *utc_zone; - - priv = cbfile->priv; - - /* create the (unique) VFREEBUSY object that we'll return */ - vfb = icalcomponent_new_vfreebusy (); - if (address != NULL) { - icalproperty *prop; - icalparameter *param; - - prop = icalproperty_new_organizer (address); - if (prop != NULL && cn != NULL) { - param = icalparameter_new_cn (cn); - icalproperty_add_parameter (prop, param); - } - if (prop != NULL) - icalcomponent_add_property (vfb, prop); - } - utc_zone = icaltimezone_get_utc_timezone (); - icalcomponent_set_dtstart (vfb, icaltime_from_timet_with_zone (start, FALSE, utc_zone)); - icalcomponent_set_dtend (vfb, icaltime_from_timet_with_zone (end, FALSE, utc_zone)); - - /* add all objects in the given interval */ - - uids = cal_backend_get_objects_in_range (CAL_BACKEND (cbfile), - CALOBJ_TYPE_ANY, start, end); - for (l = uids; l != NULL; l = l->next) { - CalComponent *comp; - icalcomponent *icalcomp, *vcalendar_comp; - icalproperty *prop; - char *uid = (char *) l->data; - - /* get the component from our internal list */ - comp = lookup_component (cbfile, uid); - if (!comp) - continue; - - icalcomp = cal_component_get_icalcomponent (comp); - if (!icalcomp) - continue; - - /* If the event is TRANSPARENT, skip it. */ - prop = icalcomponent_get_first_property (icalcomp, - ICAL_TRANSP_PROPERTY); - if (prop) { - const char *transp_val = icalproperty_get_transp (prop); - if (transp_val - && !strcasecmp (transp_val, "TRANSPARENT")) - continue; - } - - vcalendar_comp = icalcomponent_get_parent (icalcomp); - cal_recur_generate_instances (comp, start, end, - free_busy_instance, - vfb, - resolve_tzid, - vcalendar_comp, - priv->default_zone); - - } - cal_obj_uid_list_free (uids); - - return vfb; -} - -/* Get_free_busy handler for the file backend */ -static GList * -cal_backend_file_get_free_busy (CalBackend *backend, GList *users, time_t start, time_t end) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - gchar *address, *name; - icalcomponent *vfb; - char *calobj; - GList *obj_list = NULL; - GList *l; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - g_return_val_if_fail (start != -1 && end != -1, NULL); - g_return_val_if_fail (start <= end, NULL); - - if (users == NULL) { - if (cal_backend_mail_account_get_default (priv->config_listener, &address, &name)) { - vfb = create_user_free_busy (cbfile, address, name, start, end); - calobj = icalcomponent_as_ical_string (vfb); - obj_list = g_list_append (obj_list, g_strdup (calobj)); - icalcomponent_free (vfb); - g_free (address); - g_free (name); - } - } else { - for (l = users; l != NULL; l = l->next ) { - address = l->data; - if (cal_backend_mail_account_is_valid (priv->config_listener, address, &name)) { - vfb = create_user_free_busy (cbfile, address, name, start, end); - calobj = icalcomponent_as_ical_string (vfb); - obj_list = g_list_append (obj_list, g_strdup (calobj)); - icalcomponent_free (vfb); - g_free (name); - } - } - } - - return obj_list; -} - -typedef struct -{ - CalBackend *backend; - CalObjType type; - GList *changes; - GList *change_ids; -} CalBackendFileComputeChangesData; - -static void -cal_backend_file_compute_changes_foreach_key (const char *key, gpointer data) -{ - CalBackendFileComputeChangesData *be_data = data; - char *calobj = cal_backend_get_object (be_data->backend, key); - - if (calobj == NULL) { - CalComponent *comp; - GNOME_Evolution_Calendar_CalObjChange *coc; - char *calobj; - - comp = cal_component_new (); - if (be_data->type == GNOME_Evolution_Calendar_TYPE_TODO) - cal_component_set_new_vtype (comp, CAL_COMPONENT_TODO); - else - cal_component_set_new_vtype (comp, CAL_COMPONENT_EVENT); - - cal_component_set_uid (comp, key); - calobj = cal_component_get_as_string (comp); - - coc = GNOME_Evolution_Calendar_CalObjChange__alloc (); - coc->calobj = CORBA_string_dup (calobj); - coc->type = GNOME_Evolution_Calendar_DELETED; - be_data->changes = g_list_prepend (be_data->changes, coc); - be_data->change_ids = g_list_prepend (be_data->change_ids, g_strdup (key)); - - g_free (calobj); - g_object_unref (comp); - } -} - -static GNOME_Evolution_Calendar_CalObjChangeSeq * -cal_backend_file_compute_changes (CalBackend *backend, CalObjType type, const char *change_id) -{ - char *filename; - EDbHash *ehash; - CalBackendFileComputeChangesData be_data; - GNOME_Evolution_Calendar_CalObjChangeSeq *seq; - GList *uids, *changes = NULL, *change_ids = NULL; - GList *i, *j; - int n; - - /* Find the changed ids - FIX ME, path should not be hard coded */ - if (type == GNOME_Evolution_Calendar_TYPE_TODO) - filename = g_strdup_printf ("%s/evolution/local/Tasks/%s.db", g_get_home_dir (), change_id); - else - filename = g_strdup_printf ("%s/evolution/local/Calendar/%s.db", g_get_home_dir (), change_id); - ehash = e_dbhash_new (filename); - g_free (filename); - - uids = cal_backend_get_uids (backend, type); - - /* Calculate adds and modifies */ - for (i = uids; i != NULL; i = i->next) { - GNOME_Evolution_Calendar_CalObjChange *coc; - char *uid = i->data; - char *calobj = cal_backend_get_object (backend, uid); - - g_assert (calobj != NULL); - - /* check what type of change has occurred, if any */ - switch (e_dbhash_compare (ehash, uid, calobj)) { - case E_DBHASH_STATUS_SAME: - break; - case E_DBHASH_STATUS_NOT_FOUND: - coc = GNOME_Evolution_Calendar_CalObjChange__alloc (); - coc->calobj = CORBA_string_dup (calobj); - coc->type = GNOME_Evolution_Calendar_ADDED; - changes = g_list_prepend (changes, coc); - change_ids = g_list_prepend (change_ids, g_strdup (uid)); - break; - case E_DBHASH_STATUS_DIFFERENT: - coc = GNOME_Evolution_Calendar_CalObjChange__alloc (); - coc->calobj = CORBA_string_dup (calobj); - coc->type = GNOME_Evolution_Calendar_MODIFIED; - changes = g_list_prepend (changes, coc); - change_ids = g_list_prepend (change_ids, g_strdup (uid)); - break; - } - } - - /* Calculate deletions */ - be_data.backend = backend; - be_data.type = type; - be_data.changes = changes; - be_data.change_ids = change_ids; - e_dbhash_foreach_key (ehash, (EDbHashFunc)cal_backend_file_compute_changes_foreach_key, &be_data); - changes = be_data.changes; - change_ids = be_data.change_ids; - - /* Build the sequence and update the hash */ - n = g_list_length (changes); - - seq = GNOME_Evolution_Calendar_CalObjChangeSeq__alloc (); - seq->_length = n; - seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalObjChange_allocbuf (n); - CORBA_sequence_set_release (seq, TRUE); - - for (i = changes, j = change_ids, n = 0; i != NULL; i = i->next, j = j->next, n++) { - GNOME_Evolution_Calendar_CalObjChange *coc = i->data; - GNOME_Evolution_Calendar_CalObjChange *seq_coc; - char *uid = j->data; - - /* sequence building */ - seq_coc = &seq->_buffer[n]; - seq_coc->calobj = CORBA_string_dup (coc->calobj); - seq_coc->type = coc->type; - - /* hash updating */ - if (coc->type == GNOME_Evolution_Calendar_ADDED - || coc->type == GNOME_Evolution_Calendar_MODIFIED) { - e_dbhash_add (ehash, uid, coc->calobj); - } else { - e_dbhash_remove (ehash, uid); - } - - CORBA_free (coc); - g_free (uid); - } - e_dbhash_write (ehash); - e_dbhash_destroy (ehash); - - cal_obj_uid_list_free (uids); - g_list_free (change_ids); - g_list_free (changes); - - return seq; -} - -/* Get_changes handler for the file backend */ -static GNOME_Evolution_Calendar_CalObjChangeSeq * -cal_backend_file_get_changes (CalBackend *backend, CalObjType type, const char *change_id) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - return cal_backend_file_compute_changes (backend, type, change_id); -} - -/* Get_alarms_in_range handler for the file backend */ -static GNOME_Evolution_Calendar_CalComponentAlarmsSeq * -cal_backend_file_get_alarms_in_range (CalBackend *backend, - time_t start, time_t end) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - int n_comp_alarms; - GSList *comp_alarms; - GSList *l; - int i; - GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - g_return_val_if_fail (start != -1 && end != -1, NULL); - g_return_val_if_fail (start <= end, NULL); - - /* Per RFC 2445, only VEVENTs and VTODOs can have alarms */ - - n_comp_alarms = 0; - comp_alarms = NULL; - - n_comp_alarms += cal_util_generate_alarms_for_list (priv->events, start, end, - &comp_alarms, resolve_tzid, - priv->icalcomp, - priv->default_zone); - n_comp_alarms += cal_util_generate_alarms_for_list (priv->todos, start, end, - &comp_alarms, resolve_tzid, - priv->icalcomp, - priv->default_zone); - - seq = GNOME_Evolution_Calendar_CalComponentAlarmsSeq__alloc (); - CORBA_sequence_set_release (seq, TRUE); - seq->_length = n_comp_alarms; - seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalComponentAlarms_allocbuf ( - n_comp_alarms); - - for (l = comp_alarms, i = 0; l; l = l->next, i++) { - CalComponentAlarms *alarms; - char *comp_str; - - alarms = l->data; - - comp_str = cal_component_get_as_string (alarms->comp); - seq->_buffer[i].calobj = CORBA_string_dup (comp_str); - g_free (comp_str); - - cal_backend_util_fill_alarm_instances_seq (&seq->_buffer[i].alarms, alarms->alarms); - - cal_component_alarms_free (alarms); - } - - g_slist_free (comp_alarms); - - return seq; -} - -/* Get_alarms_for_object handler for the file backend */ -static GNOME_Evolution_Calendar_CalComponentAlarms * -cal_backend_file_get_alarms_for_object (CalBackend *backend, const char *uid, - time_t start, time_t end, - gboolean *object_found) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - CalComponent *comp; - char *comp_str; - GNOME_Evolution_Calendar_CalComponentAlarms *corba_alarms; - CalComponentAlarms *alarms; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - g_return_val_if_fail (uid != NULL, NULL); - g_return_val_if_fail (start != -1 && end != -1, NULL); - g_return_val_if_fail (start <= end, NULL); - g_return_val_if_fail (object_found != NULL, NULL); - - comp = lookup_component (cbfile, uid); - if (!comp) { - *object_found = FALSE; - return NULL; - } - - *object_found = TRUE; - - comp_str = cal_component_get_as_string (comp); - corba_alarms = GNOME_Evolution_Calendar_CalComponentAlarms__alloc (); - - corba_alarms->calobj = CORBA_string_dup (comp_str); - g_free (comp_str); - - alarms = cal_util_generate_alarms_for_comp (comp, start, end, resolve_tzid, priv->icalcomp, priv->default_zone); - if (alarms) { - cal_backend_util_fill_alarm_instances_seq (&corba_alarms->alarms, alarms->alarms); - cal_component_alarms_free (alarms); - } else - cal_backend_util_fill_alarm_instances_seq (&corba_alarms->alarms, NULL); - - return corba_alarms; -} - -/* Notifies a backend's clients that an object was updated */ -static void -notify_update (CalBackendFile *cbfile, const char *uid) -{ - CalBackendFilePrivate *priv; - GList *l; - - priv = cbfile->priv; - - cal_backend_obj_updated (CAL_BACKEND (cbfile), uid); - - for (l = CAL_BACKEND (cbfile)->clients; l; l = l->next) { - Cal *cal; - - cal = CAL (l->data); - cal_notify_update (cal, uid); - } -} - -/* Notifies a backend's clients that an object was removed */ -static void -notify_remove (CalBackendFile *cbfile, const char *uid) -{ - CalBackendFilePrivate *priv; - GList *l; - - priv = cbfile->priv; - - cal_backend_obj_removed (CAL_BACKEND (cbfile), uid); - - for (l = CAL_BACKEND (cbfile)->clients; l; l = l->next) { - Cal *cal; - - cal = CAL (l->data); - cal_notify_remove (cal, uid); - } -} - -/* Notifies a backend's clients that an error has occurred */ -static void -notify_error (CalBackendFile *cbfile, const char *message) -{ - CalBackendFilePrivate *priv; - GList *l; - - priv = cbfile->priv; - - for (l = CAL_BACKEND (cbfile)->clients; l; l = l->next) { - Cal *cal; - - cal = CAL (l->data); - cal_notify_error (cal, message); - } -} - -/* Used from g_hash_table_foreach_remove(); removes and frees a category */ -static gboolean -remove_category_cb (gpointer key, gpointer value, gpointer data) -{ - Category *c; - - c = value; - g_free (c->name); - g_free (c); - - return TRUE; -} - -/* Clears the table of removed categories */ -static void -clean_removed_categories (CalBackendFile *cbfile) -{ - CalBackendFilePrivate *priv; - - priv = cbfile->priv; - - g_hash_table_foreach_remove (priv->removed_categories, - remove_category_cb, - NULL); -} - - -/* Creates a CalComponent for the given icalcomponent and adds it to our - cache. Note that the icalcomponent is not added to the toplevel - icalcomponent here. That needs to be done elsewhere. It returns the uid - of the added component, or NULL if it failed. */ -static const char* -cal_backend_file_update_object (CalBackendFile *cbfile, - icalcomponent *icalcomp) -{ - CalComponent *old_comp; - CalComponent *comp; - const char *comp_uid; - struct icaltimetype last_modified; - - /* Create a CalComponent wrapper for the icalcomponent. */ - comp = cal_component_new (); - if (!cal_component_set_icalcomponent (comp, icalcomp)) { - g_object_unref (comp); - return NULL; - } - - /* Get the UID, and check it isn't empty. */ - cal_component_get_uid (comp, &comp_uid); - if (!comp_uid || !comp_uid[0]) { - g_object_unref (comp); - return NULL; - } - - /* Set the LAST-MODIFIED time on the component */ - last_modified = icaltime_from_timet (time (NULL), 0); - cal_component_set_last_modified (comp, &last_modified); - - /* Remove any old version of the component. */ - old_comp = lookup_component (cbfile, comp_uid); - if (old_comp) - remove_component (cbfile, old_comp); - - /* Now add the component to our local cache, but we pass FALSE as - the last argument, since the libical component is assumed to have - been added already. */ - add_component (cbfile, comp, FALSE); - - return comp_uid; -} - - - -/* Update_objects handler for the file backend. */ -static CalBackendResult -cal_backend_file_update_objects (CalBackend *backend, const char *calobj) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - icalcomponent *toplevel_comp, *icalcomp = NULL; - icalcomponent_kind kind; - int old_n_categories, new_n_categories; - icalcomponent *subcomp; - CalBackendResult retval = CAL_BACKEND_RESULT_SUCCESS; - GList *comp_uid_list = NULL, *elem; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, CAL_BACKEND_RESULT_INVALID_OBJECT); - - g_return_val_if_fail (calobj != NULL, CAL_BACKEND_RESULT_INVALID_OBJECT); - - /* Pull the component from the string and ensure that it is sane */ - - toplevel_comp = icalparser_parse_string ((char *) calobj); - - if (!toplevel_comp) - return CAL_BACKEND_RESULT_INVALID_OBJECT; - - kind = icalcomponent_isa (toplevel_comp); - - if (kind == ICAL_VEVENT_COMPONENT - || kind == ICAL_VTODO_COMPONENT - || kind == ICAL_VJOURNAL_COMPONENT) { - /* Create a temporary toplevel component and put the VEVENT - or VTODO in it, to simplify the code below. */ - icalcomp = toplevel_comp; - toplevel_comp = cal_util_new_top_level (); - icalcomponent_add_component (toplevel_comp, icalcomp); - } else if (kind != ICAL_VCALENDAR_COMPONENT) { - /* We don't support this type of component */ - icalcomponent_free (toplevel_comp); - return CAL_BACKEND_RESULT_INVALID_OBJECT; - } - - /* The list of removed categories must be empty because we are about to - * start a new scanning process. - */ - g_assert (g_hash_table_size (priv->removed_categories) == 0); - - old_n_categories = g_hash_table_size (priv->categories); - - /* Step throught the VEVENT/VTODOs being added, create CalComponents - for them, and add them to our cache. */ - subcomp = icalcomponent_get_first_component (toplevel_comp, - ICAL_ANY_COMPONENT); - while (subcomp) { - /* We ignore anything except VEVENT, VTODO and VJOURNAL - components. */ - icalcomponent_kind child_kind = icalcomponent_isa (subcomp); - if (child_kind == ICAL_VEVENT_COMPONENT - || child_kind == ICAL_VTODO_COMPONENT - || child_kind == ICAL_VJOURNAL_COMPONENT) { - const char *comp_uid; - - comp_uid = cal_backend_file_update_object (cbfile, - subcomp); - if (comp_uid) { - /* We add a copy of the UID to a list, so we - can emit notification signals later. We do - a g_strdup() in case any of the components - get removed while we are emitting - notification signals. */ - comp_uid_list = g_list_prepend (comp_uid_list, - g_strdup (comp_uid)); - } else { - retval = CAL_BACKEND_RESULT_INVALID_OBJECT; - } - } - subcomp = icalcomponent_get_next_component (toplevel_comp, - ICAL_ANY_COMPONENT); - } - - /* Merge the iCalendar components with our existing VCALENDAR, - resolving any conflicting TZIDs. */ - icalcomponent_merge_component (priv->icalcomp, toplevel_comp); - - new_n_categories = g_hash_table_size (priv->categories); - - mark_dirty (cbfile); - - /* Now emit notification signals for all of the added components. - We do this after adding them all to make sure the calendar is in a - stable state before emitting signals. */ - for (elem = comp_uid_list; elem; elem = elem->next) { - char *comp_uid = elem->data; - notify_update (cbfile, comp_uid); - g_free (comp_uid); - } - g_list_free (comp_uid_list); - - if (old_n_categories != new_n_categories || - g_hash_table_size (priv->removed_categories) != 0) { - clean_removed_categories (cbfile); - notify_categories_changed (cbfile); - } - - return retval; -} - - -/* Remove_object handler for the file backend */ -static CalBackendResult -cal_backend_file_remove_object (CalBackend *backend, const char *uid) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - CalComponent *comp; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, CAL_BACKEND_RESULT_INVALID_OBJECT); - - g_return_val_if_fail (uid != NULL, CAL_BACKEND_RESULT_NOT_FOUND); - - comp = lookup_component (cbfile, uid); - if (!comp) - return CAL_BACKEND_RESULT_NOT_FOUND; - - /* The list of removed categories must be empty because we are about to - * start a new scanning process. - */ - g_assert (g_hash_table_size (priv->removed_categories) == 0); - - remove_component (cbfile, comp); - - mark_dirty (cbfile); - - notify_remove (cbfile, uid); - - if (g_hash_table_size (priv->removed_categories) != 0) { - clean_removed_categories (cbfile); - notify_categories_changed (cbfile); - } - - return CAL_BACKEND_RESULT_SUCCESS; -} - -static CalBackendSendResult -cal_backend_file_send_object (CalBackend *backend, const char *calobj, char **new_calobj, - GNOME_Evolution_Calendar_UserList **user_list, char error_msg[256]) -{ - *new_calobj = g_strdup (calobj); - - *user_list = GNOME_Evolution_Calendar_UserList__alloc (); - (*user_list)->_length = 0; - - return CAL_BACKEND_SEND_SUCCESS; -} - -static icaltimezone* -cal_backend_file_get_timezone (CalBackend *backend, const char *tzid) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - icaltimezone *zone; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - if (!strcmp (tzid, "UTC")) - zone = icaltimezone_get_utc_timezone (); - else { - zone = icalcomponent_get_timezone (priv->icalcomp, tzid); - if (!zone) - zone = icaltimezone_get_builtin_timezone_from_tzid (tzid); - } - - return zone; -} - - -static icaltimezone* -cal_backend_file_get_default_timezone (CalBackend *backend) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, NULL); - - return priv->default_zone; -} - - -static gboolean -cal_backend_file_set_default_timezone (CalBackend *backend, - const char *tzid) -{ - CalBackendFile *cbfile; - CalBackendFilePrivate *priv; - icaltimezone *zone; - - cbfile = CAL_BACKEND_FILE (backend); - priv = cbfile->priv; - - g_return_val_if_fail (priv->icalcomp != NULL, FALSE); - - /* Look up the VTIMEZONE in our icalcomponent. */ - zone = icalcomponent_get_timezone (priv->icalcomp, tzid); - if (!zone) - return FALSE; - - /* Set the default timezone to it. */ - priv->default_zone = zone; - - return TRUE; -} - diff --git a/calendar/pcs/cal-backend-file.h b/calendar/pcs/cal-backend-file.h deleted file mode 100644 index 4f79da66de..0000000000 --- a/calendar/pcs/cal-backend-file.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Evolution calendar - iCalendar file backend - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#ifndef CAL_BACKEND_FILE_H -#define CAL_BACKEND_FILE_H - -#include "pcs/cal-backend.h" - -G_BEGIN_DECLS - - - -#define CAL_BACKEND_FILE_TYPE (cal_backend_file_get_type ()) -#define CAL_BACKEND_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CAL_BACKEND_FILE_TYPE, \ - CalBackendFile)) -#define CAL_BACKEND_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CAL_BACKEND_FILE_TYPE, \ - CalBackendFileClass)) -#define IS_CAL_BACKEND_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CAL_BACKEND_FILE_TYPE)) -#define IS_CAL_BACKEND_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CAL_BACKEND_FILE_TYPE)) - -typedef struct _CalBackendFile CalBackendFile; -typedef struct _CalBackendFileClass CalBackendFileClass; - -typedef struct _CalBackendFilePrivate CalBackendFilePrivate; - -struct _CalBackendFile { - CalBackend backend; - - /* Private data */ - CalBackendFilePrivate *priv; -}; - -struct _CalBackendFileClass { - CalBackendClass parent_class; -}; - -GType cal_backend_file_get_type (void); - - - -G_END_DECLS - -#endif diff --git a/calendar/pcs/cal-backend-util.c b/calendar/pcs/cal-backend-util.c deleted file mode 100644 index a5b6d1adc8..0000000000 --- a/calendar/pcs/cal-backend-util.c +++ /dev/null @@ -1,117 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - generic backend class - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#include <string.h> -#include "cal-backend-util.h" - -void -cal_backend_util_fill_alarm_instances_seq (GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq, - GSList *alarms) -{ - int n_alarms; - GSList *l; - int i; - - g_return_if_fail (seq != NULL); - - n_alarms = g_slist_length (alarms); - - CORBA_sequence_set_release (seq, TRUE); - seq->_length = n_alarms; - seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalAlarmInstance_allocbuf (n_alarms); - - for (l = alarms, i = 0; l; l = l->next, i++) { - CalAlarmInstance *instance; - GNOME_Evolution_Calendar_CalAlarmInstance *corba_instance; - - instance = l->data; - corba_instance = seq->_buffer + i; - - corba_instance->auid = CORBA_string_dup (instance->auid); - corba_instance->trigger = (long) instance->trigger; - corba_instance->occur_start = (long) instance->occur_start; - corba_instance->occur_end = (long) instance->occur_end; - } -} - -void -cal_backend_mail_account_get (EConfigListener *db, - gint def, - char **address, - char **name) -{ - gchar *path; - - *address = NULL; - *name = NULL; - - /* get the identity info */ - path = g_strdup_printf ("/apps/Evolution/Mail/Accounts/identity_name_%d", def); - *name = e_config_listener_get_string_with_default (db, path, NULL, NULL); - g_free (path); - - path = g_strdup_printf ("/apps/Evolution/Mail/Accounts/identity_address_%d", def); - *address = e_config_listener_get_string_with_default (db, path, NULL, NULL); - g_free (path); -} - -gboolean -cal_backend_mail_account_get_default (EConfigListener *db, - char **address, - char **name) -{ - glong def, len; - - *address = NULL; - *name = NULL; - - len = e_config_listener_get_long_with_default (db, "/apps/Evolution/Mail/Accounts/num", 0, NULL); - def = e_config_listener_get_long_with_default (db, "/apps/Evolution/Mail/Accounts/default_account", 0, NULL); - - if (def < len) - cal_backend_mail_account_get (db, def, address, name); - else - return FALSE; - - return TRUE; -} - -gboolean -cal_backend_mail_account_is_valid (EConfigListener *db, char *user, char **name) -{ - gchar *address; - glong len, i; - - len = e_config_listener_get_long_with_default (db, "/apps/Evolution/Mail/Accounts/num", 0, NULL); - - for (i = 0; i < len; i++) { - cal_backend_mail_account_get (db, i, &address, name); - if (address != NULL && !strcmp (address, user)) { - g_free (address); - return TRUE; - } - g_free (address); - g_free (*name); - } - - return FALSE; -} diff --git a/calendar/pcs/cal-backend-util.h b/calendar/pcs/cal-backend-util.h deleted file mode 100644 index 20c07f0799..0000000000 --- a/calendar/pcs/cal-backend-util.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - generic backend class - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2001 Ximian, Inc. - * - * Authors: Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#ifndef CAL_BACKEND_UTIL_H -#define CAL_BACKEND_UTIL_H - -#include <e-util/e-config-listener.h> -#include <pcs/cal-backend.h> - -G_BEGIN_DECLS - -/* - * CORBA utility functions - */ - -void cal_backend_util_fill_alarm_instances_seq ( - GNOME_Evolution_Calendar_CalAlarmInstanceSeq *seq, GSList *alarms); - -/* - * Functions for accessing mail configuration - */ - -void cal_backend_mail_account_get (EConfigListener *db, gint def, - char **address, char **name); -gboolean cal_backend_mail_account_get_default (EConfigListener *db, - char **address, char **name); -gboolean cal_backend_mail_account_is_valid (EConfigListener *db, - char *user, char **name); - -G_END_DECLS - -#endif diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c deleted file mode 100644 index 876ef0d5ec..0000000000 --- a/calendar/pcs/cal-backend.c +++ /dev/null @@ -1,904 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - generic backend class - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * JP Rosevear <jpr@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#include <config.h> -#include <libxml/parser.h> -#include <libxml/parserInternals.h> -#include <libxml/xmlmemory.h> - -#include "cal-backend.h" -#include "libversit/vcc.h" - - - -/* Signal IDs */ -enum { - LAST_CLIENT_GONE, - CAL_ADDED, - OPENED, - OBJ_UPDATED, - OBJ_REMOVED, - LAST_SIGNAL -}; - -static void cal_backend_class_init (CalBackendClass *class); - -static guint cal_backend_signals[LAST_SIGNAL]; - -#define CLASS(backend) (CAL_BACKEND_CLASS (G_OBJECT_GET_CLASS (backend))) - - - -/** - * cal_backend_get_type: - * @void: - * - * Registers the #CalBackend class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #CalBackend class. - **/ -GType -cal_backend_get_type (void) -{ - static GType cal_backend_type = 0; - - if (!cal_backend_type) { - static GTypeInfo info = { - sizeof (CalBackendClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) cal_backend_class_init, - NULL, NULL, - sizeof (CalBackend), - 0, - (GInstanceInitFunc) NULL - }; - cal_backend_type = g_type_register_static (G_TYPE_OBJECT, "CalBackend", &info, 0); - } - - return cal_backend_type; -} - -/* Class initialization function for the calendar backend */ -static void -cal_backend_class_init (CalBackendClass *class) -{ - GObjectClass *object_class; - - object_class = (GObjectClass *) class; - - cal_backend_signals[LAST_CLIENT_GONE] = - g_signal_new ("last_client_gone", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (CalBackendClass, last_client_gone), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - cal_backend_signals[CAL_ADDED] = - g_signal_new ("cal_added", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (CalBackendClass, cal_added), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, - G_TYPE_POINTER); - cal_backend_signals[OPENED] = - g_signal_new ("opened", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (CalBackendClass, opened), - NULL, NULL, - g_cclosure_marshal_VOID__ENUM, - G_TYPE_NONE, 1, - G_TYPE_ENUM); - cal_backend_signals[OBJ_UPDATED] = - g_signal_new ("obj_updated", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (CalBackendClass, obj_updated), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); - cal_backend_signals[OBJ_REMOVED] = - g_signal_new ("obj_removed", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (CalBackendClass, obj_removed), - NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, - G_TYPE_STRING); - - class->last_client_gone = NULL; - class->opened = NULL; - class->obj_updated = NULL; - class->obj_removed = NULL; - - class->get_uri = NULL; - class->get_email_address = NULL; - class->open = NULL; - class->is_loaded = NULL; - class->is_read_only = NULL; - class->get_query = NULL; - class->get_mode = NULL; - class->set_mode = NULL; - class->get_n_objects = NULL; - class->get_object = NULL; - class->get_object_component = NULL; - class->get_timezone_object = NULL; - class->get_uids = NULL; - class->get_objects_in_range = NULL; - class->get_free_busy = NULL; - class->get_changes = NULL; - class->get_alarms_in_range = NULL; - class->get_alarms_for_object = NULL; - class->update_objects = NULL; - class->remove_object = NULL; - class->send_object = NULL; -} - - - -/** - * cal_backend_get_uri: - * @backend: A calendar backend. - * - * Queries the URI of a calendar backend, which must already have an open - * calendar. - * - * Return value: The URI where the calendar is stored. - **/ -const char * -cal_backend_get_uri (CalBackend *backend) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - g_assert (CLASS (backend)->get_uri != NULL); - return (* CLASS (backend)->get_uri) (backend); -} - -/** - * cal_backend_get_email_address: - * @backend: A calendar backend. - * - * Queries the email address associated with a calendar backend, which - * must already have an open calendar. - * - * Return value: The email address associated with the calendar. - **/ -const char * -cal_backend_get_email_address (CalBackend *backend) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - g_assert (CLASS (backend)->get_email_address != NULL); - return (* CLASS (backend)->get_email_address) (backend); -} - -/* Callback used when a Cal is destroyed */ -static void -cal_destroy_cb (GObject *object, gpointer data) -{ - Cal *cal; - Cal *lcal; - CalBackend *backend; - GList *l; - - cal = CAL (object); - - backend = CAL_BACKEND (data); - - /* Find the cal in the list of clients */ - - for (l = backend->clients; l; l = l->next) { - lcal = CAL (l->data); - - if (lcal == cal) - break; - } - - g_assert (l != NULL); - - /* Disconnect */ - - backend->clients = g_list_remove_link (backend->clients, l); - g_list_free_1 (l); - - /* When all clients go away, notify the parent factory about it so that - * it may decide whether to kill the backend or not. - */ - if (!backend->clients) - cal_backend_last_client_gone (backend); -} - -/** - * cal_backend_add_cal: - * @backend: A calendar backend. - * @cal: A calendar client interface object. - * - * Adds a calendar client interface object to a calendar @backend. - * The calendar backend must already have an open calendar. - **/ -void -cal_backend_add_cal (CalBackend *backend, Cal *cal) -{ - g_return_if_fail (backend != NULL); - g_return_if_fail (IS_CAL_BACKEND (backend)); - g_return_if_fail (IS_CAL (cal)); - - /* we do not keep a reference to the Cal since the Calendar - * user agent owns it */ - g_signal_connect (G_OBJECT (cal), "destroy", - G_CALLBACK (cal_destroy_cb), - backend); - - backend->clients = g_list_prepend (backend->clients, cal); - - /* notify backend that a new Cal has been added */ - g_signal_emit (G_OBJECT (backend), - cal_backend_signals[CAL_ADDED], - 0, cal); -} - -/** - * cal_backend_open: - * @backend: A calendar backend. - * @uristr: URI that contains the calendar data. - * @only_if_exists: Whether the calendar should be opened only if it already - * exists. If FALSE, a new calendar will be created when the specified @uri - * does not exist. - * - * Opens a calendar backend with data from a calendar stored at the specified - * URI. - * - * Return value: An operation status code. - **/ -CalBackendOpenStatus -cal_backend_open (CalBackend *backend, const char *uristr, gboolean only_if_exists) -{ - CalBackendOpenStatus result; - - g_return_val_if_fail (backend != NULL, CAL_BACKEND_OPEN_ERROR); - g_return_val_if_fail (IS_CAL_BACKEND (backend), CAL_BACKEND_OPEN_ERROR); - g_return_val_if_fail (uristr != NULL, CAL_BACKEND_OPEN_ERROR); - - g_assert (CLASS (backend)->open != NULL); - result = (* CLASS (backend)->open) (backend, uristr, only_if_exists); - - return result; -} - -/** - * cal_backend_is_loaded: - * @backend: A calendar backend. - * - * Queries whether a calendar backend has been loaded yet. - * - * Return value: TRUE if the backend has been loaded with data, FALSE - * otherwise. - **/ -gboolean -cal_backend_is_loaded (CalBackend *backend) -{ - gboolean result; - - g_return_val_if_fail (backend != NULL, FALSE); - g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - - g_assert (CLASS (backend)->is_loaded != NULL); - result = (* CLASS (backend)->is_loaded) (backend); - - return result; -} - -/** - * cal_backend_is_read_only - * @backend: A calendar backend. - * - * Queries whether a calendar backend is read only or not. - * - * Return value: TRUE if the calendar is read only, FALSE otherwise. - */ -gboolean -cal_backend_is_read_only (CalBackend *backend) -{ - gboolean result; - - g_return_val_if_fail (backend != NULL, FALSE); - g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - - g_assert (CLASS (backend)->is_read_only != NULL); - result = (* CLASS (backend)->is_read_only) (backend); - - return result; -} - -/** - * cal_backend_get_query: - * @backend: A calendar backend. - * @ql: The query listener. - * @sexp: Search expression. - * - * Create a query object for this backend. - */ -Query * -cal_backend_get_query (CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp) -{ - Query *result; - - g_return_val_if_fail (backend != NULL, FALSE); - g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - - if (CLASS (backend)->get_query != NULL) - result = (* CLASS (backend)->get_query) (backend, ql, sexp); - else - result = query_new (backend, ql, sexp); - - return result; -} - -/** - * cal_backend_get_mode: - * @backend: A calendar backend. - * - * Queries whether a calendar backend is connected remotely. - * - * Return value: The current mode the calendar is in - **/ -CalMode -cal_backend_get_mode (CalBackend *backend) -{ - CalMode result; - - g_return_val_if_fail (backend != NULL, FALSE); - g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - - g_assert (CLASS (backend)->get_mode != NULL); - result = (* CLASS (backend)->get_mode) (backend); - - return result; -} - - -/** - * cal_backend_set_mode: - * @backend: A calendar backend - * @mode: Mode to change to - * - * Sets the mode of the calendar - * - **/ -void -cal_backend_set_mode (CalBackend *backend, CalMode mode) -{ - g_return_if_fail (backend != NULL); - g_return_if_fail (IS_CAL_BACKEND (backend)); - - g_assert (CLASS (backend)->set_mode != NULL); - (* CLASS (backend)->set_mode) (backend, mode); -} - -/** - * cal_backend_get_n_objects: - * @backend: A calendar backend. - * @type: Types of objects that will be included in the count. - * - * Queries the number of calendar objects of a particular type. - * - * Return value: Number of objects of the specified @type. - **/ -int -cal_backend_get_n_objects (CalBackend *backend, CalObjType type) -{ - g_return_val_if_fail (backend != NULL, -1); - g_return_val_if_fail (IS_CAL_BACKEND (backend), -1); - - g_assert (CLASS (backend)->get_n_objects != NULL); - return (* CLASS (backend)->get_n_objects) (backend, type); -} - -/** - * cal_backend_get_object: - * @backend: A calendar backend. - * @uid: Unique identifier for a calendar object. - * - * Queries a calendar backend for a calendar object based on its unique - * identifier. - * - * Return value: The string representation of a complete calendar wrapping the - * the sought object, or NULL if no object had the specified UID. - **/ -char * -cal_backend_get_object (CalBackend *backend, const char *uid) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (uid != NULL, NULL); - - g_assert (CLASS (backend)->get_object != NULL); - return (* CLASS (backend)->get_object) (backend, uid); -} - -/** - * cal_backend_get_object_component: - * @backend: A calendar backend. - * @uid: Unique identifier for a calendar object. - * - * Queries a calendar backend for a calendar object based on its unique - * identifier. It returns the CalComponent rather than the string - * representation. - * - * Return value: The CalComponent of the sought object, or NULL if no object - * had the specified UID. - **/ -CalComponent * -cal_backend_get_object_component (CalBackend *backend, const char *uid) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (uid != NULL, NULL); - - g_assert (CLASS (backend)->get_object_component != NULL); - return (* CLASS (backend)->get_object_component) (backend, uid); -} - -/** - * cal_backend_get_timezone_object: - * @backend: A calendar backend. - * @tzid: Unique identifier for a calendar VTIMEZONE object. - * - * Queries a calendar backend for a VTIMEZONE calendar object based on its - * unique TZID identifier. - * - * Return value: The string representation of a VTIMEZONE component, or NULL - * if no VTIMEZONE object had the specified TZID. - **/ -char * -cal_backend_get_timezone_object (CalBackend *backend, const char *tzid) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (tzid != NULL, NULL); - - g_assert (CLASS (backend)->get_timezone_object != NULL); - return (* CLASS (backend)->get_timezone_object) (backend, tzid); -} - -/** - * cal_backend_get_type_by_uid - * @backend: A calendar backend. - * @uid: Unique identifier for a Calendar object. - * - * Returns the type of the object identified by the @uid argument - */ -CalObjType -cal_backend_get_type_by_uid (CalBackend *backend, const char *uid) -{ - icalcomponent *icalcomp; - char *comp_str; - CalObjType type = CAL_COMPONENT_NO_TYPE; - - g_return_val_if_fail (IS_CAL_BACKEND (backend), CAL_COMPONENT_NO_TYPE); - g_return_val_if_fail (uid != NULL, CAL_COMPONENT_NO_TYPE); - - comp_str = cal_backend_get_object (backend, uid); - if (!comp_str) - return CAL_COMPONENT_NO_TYPE; - - icalcomp = icalparser_parse_string (comp_str); - if (icalcomp) { - switch (icalcomponent_isa (icalcomp)) { - case ICAL_VEVENT_COMPONENT : - type = CALOBJ_TYPE_EVENT; - break; - case ICAL_VTODO_COMPONENT : - type = CALOBJ_TYPE_TODO; - break; - case ICAL_VJOURNAL_COMPONENT : - type = CALOBJ_TYPE_JOURNAL; - break; - default : - type = CAL_COMPONENT_NO_TYPE; - } - - icalcomponent_free (icalcomp); - } - - g_free (comp_str); - - return type; -} - -/** - * cal_backend_get_uids: - * @backend: A calendar backend. - * @type: Bitmask with types of objects to return. - * - * Builds a list of unique identifiers corresponding to calendar objects whose - * type matches one of the types specified in the @type flags. - * - * Return value: A list of strings that are the sought UIDs. The list should be - * freed using the cal_obj_uid_list_free() function. - **/ -GList * -cal_backend_get_uids (CalBackend *backend, CalObjType type) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - g_assert (CLASS (backend)->get_uids != NULL); - return (* CLASS (backend)->get_uids) (backend, type); -} - - -/** - * cal_backend_get_objects_in_range: - * @backend: A calendar backend. - * @type: Bitmask with types of objects to return. - * @start: Start time for query. - * @end: End time for query. - * - * Builds a list of unique identifiers corresponding to calendar objects of the - * specified type that occur or recur within the specified time range. - * - * Return value: A list of UID strings. The list should be freed using the - * cal_obj_uid_list_free() function. - **/ -GList * -cal_backend_get_objects_in_range (CalBackend *backend, CalObjType type, - time_t start, time_t end) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (start != -1 && end != -1, NULL); - g_return_val_if_fail (start <= end, NULL); - - g_assert (CLASS (backend)->get_objects_in_range != NULL); - return (* CLASS (backend)->get_objects_in_range) (backend, type, start, end); -} - -/** - * cal_backend_get_free_busy: - * @backend: A calendar backend. - * @users: List of users to get free/busy information for. - * @start: Start time for query. - * @end: End time for query. - * - * Gets a free/busy object for the given time interval - * - * Return value: a list of CalObj's - **/ -GList * -cal_backend_get_free_busy (CalBackend *backend, GList *users, time_t start, time_t end) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (start != -1 && end != -1, NULL); - g_return_val_if_fail (start <= end, NULL); - - g_assert (CLASS (backend)->get_free_busy != NULL); - return (* CLASS (backend)->get_free_busy) (backend, users, start, end); -} - -/** - * cal_backend_get_changes: - * @backend: A calendar backend - * @type: Bitmask with types of objects to return. - * @change_id: A unique uid for the callers change list - * - * Builds a sequence of objects and the type of change that occurred on them since - * the last time the give change_id was seen - * - * Return value: A list of the objects that changed and the type of change - **/ -GNOME_Evolution_Calendar_CalObjChangeSeq * -cal_backend_get_changes (CalBackend *backend, CalObjType type, const char *change_id) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (change_id != NULL, NULL); - - g_assert (CLASS (backend)->get_changes != NULL); - return (* CLASS (backend)->get_changes) (backend, type, change_id); -} - -/** - * cal_backend_get_alarms_in_range: - * @backend: A calendar backend. - * @start: Start time for query. - * @end: End time for query. - * @valid_range: Return value that says whether the range is valid or not. - * - * Builds a sorted list of the alarms that trigger in the specified time range. - * - * Return value: A sequence of component alarm instances structures, or NULL - * if @valid_range returns FALSE. - **/ -GNOME_Evolution_Calendar_CalComponentAlarmsSeq * -cal_backend_get_alarms_in_range (CalBackend *backend, time_t start, time_t end, - gboolean *valid_range) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (valid_range != NULL, NULL); - - g_assert (CLASS (backend)->get_alarms_in_range != NULL); - - if (!(start != -1 && end != -1 && start <= end)) { - *valid_range = FALSE; - return NULL; - } else { - *valid_range = TRUE; - return (* CLASS (backend)->get_alarms_in_range) (backend, start, end); - } -} - -/** - * cal_backend_get_alarms_for_object: - * @backend: A calendar backend. - * @uid: Unique identifier for a calendar object. - * @start: Start time for query. - * @end: End time for query. - * @result: Return value for the result code for the operation. - * - * Builds a sorted list of the alarms of the specified event that trigger in a - * particular time range. - * - * Return value: A structure of the component's alarm instances, or NULL if @result - * returns something other than #CAL_BACKEND_GET_ALARMS_SUCCESS. - **/ -GNOME_Evolution_Calendar_CalComponentAlarms * -cal_backend_get_alarms_for_object (CalBackend *backend, const char *uid, - time_t start, time_t end, - CalBackendGetAlarmsForObjectResult *result) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (uid != NULL, NULL); - g_return_val_if_fail (result != NULL, NULL); - - g_assert (CLASS (backend)->get_alarms_for_object != NULL); - - if (!(start != -1 && end != -1 && start <= end)) { - *result = CAL_BACKEND_GET_ALARMS_INVALID_RANGE; - return NULL; - } else { - gboolean object_found; - GNOME_Evolution_Calendar_CalComponentAlarms *alarms; - - alarms = (* CLASS (backend)->get_alarms_for_object) (backend, uid, start, end, - &object_found); - - if (object_found) - *result = CAL_BACKEND_GET_ALARMS_SUCCESS; - else - *result = CAL_BACKEND_GET_ALARMS_NOT_FOUND; - - return alarms; - } -} - -/** - * cal_backend_update_objects: - * @backend: A calendar backend. - * @calobj: String representation of the new calendar object(s). - * - * Updates an object in a calendar backend. It will replace any existing - * object that has the same UID as the specified one. The backend will in - * turn notify all of its clients about the change. - * - * Return value: a #CalBackendResult value, which indicates the - * result of the operation. - **/ -CalBackendResult -cal_backend_update_objects (CalBackend *backend, const char *calobj) -{ - g_return_val_if_fail (backend != NULL, FALSE); - g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - g_return_val_if_fail (calobj != NULL, FALSE); - - g_assert (CLASS (backend)->update_objects != NULL); - return (* CLASS (backend)->update_objects) (backend, calobj); -} - -/** - * cal_backend_remove_object: - * @backend: A calendar backend. - * @uid: Unique identifier of the object to remove. - * - * Removes an object in a calendar backend. The backend will notify all of its - * clients about the change. - * - * Return value: a #CalBackendResult value, which indicates the - * result of the operation. - **/ -CalBackendResult -cal_backend_remove_object (CalBackend *backend, const char *uid) -{ - g_return_val_if_fail (backend != NULL, FALSE); - g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - g_return_val_if_fail (uid != NULL, FALSE); - - g_assert (CLASS (backend)->remove_object != NULL); - return (* CLASS (backend)->remove_object) (backend, uid); -} - -CalBackendSendResult -cal_backend_send_object (CalBackend *backend, const char *calobj, char **new_calobj, - GNOME_Evolution_Calendar_UserList **user_list, char error_msg[256]) -{ - g_return_val_if_fail (backend != NULL, CAL_BACKEND_SEND_INVALID_OBJECT); - g_return_val_if_fail (IS_CAL_BACKEND (backend), CAL_BACKEND_SEND_INVALID_OBJECT); - g_return_val_if_fail (calobj != NULL, CAL_BACKEND_SEND_INVALID_OBJECT); - - g_assert (CLASS (backend)->send_object != NULL); - return (* CLASS (backend)->send_object) (backend, calobj, new_calobj, user_list, error_msg); -} - -/** - * cal_backend_last_client_gone: - * @backend: A calendar backend. - * - * Emits the "last_client_gone" signal of a calendar backend. This function is - * to be used only by backend implementations. - **/ -void -cal_backend_last_client_gone (CalBackend *backend) -{ - g_return_if_fail (backend != NULL); - g_return_if_fail (IS_CAL_BACKEND (backend)); - - g_signal_emit (G_OBJECT (backend), cal_backend_signals[LAST_CLIENT_GONE], 0); -} - -/** - * cal_backend_opened: - * @backend: A calendar backend. - * @status: Open status code. - * - * Emits the "opened" signal of a calendar backend. This function is to be used - * only by backend implementations. - **/ -void -cal_backend_opened (CalBackend *backend, CalBackendOpenStatus status) -{ - g_return_if_fail (backend != NULL); - g_return_if_fail (IS_CAL_BACKEND (backend)); - - g_signal_emit (G_OBJECT (backend), cal_backend_signals[OPENED], - 0, status); -} - -/** - * cal_backend_obj_updated: - * @backend: A calendar backend. - * @uid: Unique identifier of the component that was updated. - * - * Emits the "obj_updated" signal of a calendar backend. This function is to be - * used only by backend implementations. - **/ -void -cal_backend_obj_updated (CalBackend *backend, const char *uid) -{ - g_return_if_fail (backend != NULL); - g_return_if_fail (IS_CAL_BACKEND (backend)); - g_return_if_fail (uid != NULL); - - g_signal_emit (G_OBJECT (backend), cal_backend_signals[OBJ_UPDATED], - 0, uid); -} - -/** - * cal_backend_obj_removed: - * @backend: A calendar backend. - * @uid: Unique identifier of the component that was removed. - * - * Emits the "obj_removed" signal of a calendar backend. This function is to be - * used only by backend implementations. - **/ -void -cal_backend_obj_removed (CalBackend *backend, const char *uid) -{ - g_return_if_fail (backend != NULL); - g_return_if_fail (IS_CAL_BACKEND (backend)); - g_return_if_fail (uid != NULL); - - g_signal_emit (G_OBJECT (backend), cal_backend_signals[OBJ_REMOVED], - 0, uid); -} - - -/** - * cal_backend_get_timezone: - * @backend: A calendar backend. - * @tzid: Unique identifier of a VTIMEZONE object. Note that this must not be - * NULL. - * - * Returns the icaltimezone* corresponding to the TZID, or NULL if the TZID - * can't be found. - * - * Returns: The icaltimezone* corresponding to the given TZID, or NULL. - **/ -icaltimezone* -cal_backend_get_timezone (CalBackend *backend, const char *tzid) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (tzid != NULL, NULL); - - g_assert (CLASS (backend)->get_timezone != NULL); - return (* CLASS (backend)->get_timezone) (backend, tzid); -} - - -/** - * cal_backend_get_default_timezone: - * @backend: A calendar backend. - * - * Returns the default timezone for the calendar, which is used to resolve - * DATE and floating DATE-TIME values. - * - * Returns: The default icaltimezone* for the calendar. - **/ -icaltimezone* -cal_backend_get_default_timezone (CalBackend *backend) -{ - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - g_assert (CLASS (backend)->get_default_timezone != NULL); - return (* CLASS (backend)->get_default_timezone) (backend); -} - - -/** - * cal_backend_set_default_timezone: - * @backend: A calendar backend. - * @tzid: The TZID identifying the timezone. - * - * Sets the default timezone for the calendar, which is used to resolve - * DATE and floating DATE-TIME values. - * - * Returns: TRUE if the VTIMEZONE data for the timezone was found, or FALSE if - * not. - **/ -gboolean -cal_backend_set_default_timezone (CalBackend *backend, const char *tzid) -{ - g_return_val_if_fail (backend != NULL, FALSE); - g_return_val_if_fail (IS_CAL_BACKEND (backend), FALSE); - g_return_val_if_fail (tzid != NULL, FALSE); - - g_assert (CLASS (backend)->set_default_timezone != NULL); - return (* CLASS (backend)->set_default_timezone) (backend, tzid); -} - diff --git a/calendar/pcs/cal-backend.h b/calendar/pcs/cal-backend.h deleted file mode 100644 index b0790e8e73..0000000000 --- a/calendar/pcs/cal-backend.h +++ /dev/null @@ -1,220 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* Evolution calendar - generic backend class - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#ifndef CAL_BACKEND_H -#define CAL_BACKEND_H - -#include <cal-util/cal-util.h> -#include <cal-util/cal-component.h> -#include "pcs/evolution-calendar.h" -#include "pcs/cal-common.h" -#include "pcs/cal.h" -#include "pcs/query.h" - -G_BEGIN_DECLS - - - -#define CAL_BACKEND_TYPE (cal_backend_get_type ()) -#define CAL_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CAL_BACKEND_TYPE, CalBackend)) -#define CAL_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CAL_BACKEND_TYPE, \ - CalBackendClass)) -#define IS_CAL_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CAL_BACKEND_TYPE)) -#define IS_CAL_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CAL_BACKEND_TYPE)) - -/* Open status values */ -typedef enum { - CAL_BACKEND_OPEN_SUCCESS, /* Loading OK */ - CAL_BACKEND_OPEN_ERROR, /* We need better error reporting in libversit */ - CAL_BACKEND_OPEN_NOT_FOUND, - CAL_BACKEND_OPEN_PERMISSION_DENIED -} CalBackendOpenStatus; - -/* Update and Remove result values */ -typedef enum { - CAL_BACKEND_RESULT_SUCCESS, - CAL_BACKEND_RESULT_INVALID_OBJECT, - CAL_BACKEND_RESULT_NOT_FOUND, - CAL_BACKEND_RESULT_PERMISSION_DENIED -} CalBackendResult; - -/* Send result values */ -typedef enum { - CAL_BACKEND_SEND_SUCCESS, - CAL_BACKEND_SEND_INVALID_OBJECT, - CAL_BACKEND_SEND_BUSY, - CAL_BACKEND_SEND_PERMISSION_DENIED, -} CalBackendSendResult; - -/* Result codes for ::get_alarms_in_range() */ -typedef enum { - CAL_BACKEND_GET_ALARMS_SUCCESS, - CAL_BACKEND_GET_ALARMS_NOT_FOUND, - CAL_BACKEND_GET_ALARMS_INVALID_RANGE -} CalBackendGetAlarmsForObjectResult; - -struct _CalBackend { - GObject object; - GList *clients; -}; - -struct _CalBackendClass { - GObjectClass parent_class; - - /* Notification signals */ - void (* last_client_gone) (CalBackend *backend); - void (* cal_added) (CalBackend *backend, Cal *cal); - - void (* opened) (CalBackend *backend, CalBackendOpenStatus status); - void (* obj_updated) (CalBackend *backend, const char *uid); - void (* obj_removed) (CalBackend *backend, const char *uid); - - /* Virtual methods */ - const char *(* get_uri) (CalBackend *backend); - - const char *(* get_email_address) (CalBackend *backend); - - CalBackendOpenStatus (* open) (CalBackend *backend, const char *uristr, - gboolean only_if_exists); - - gboolean (* is_loaded) (CalBackend *backend); - gboolean (* is_read_only) (CalBackend *backend); - - Query *(* get_query) (CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp); - - /* Mode relate virtual methods */ - CalMode (* get_mode) (CalBackend *backend); - void (* set_mode) (CalBackend *backend, CalMode mode); - - /* General object acquirement and information related virtual methods */ - int (* get_n_objects) (CalBackend *backend, CalObjType type); - char *(* get_object) (CalBackend *backend, const char *uid); - CalComponent *(* get_object_component) (CalBackend *backend, const char *uid); - char *(* get_timezone_object) (CalBackend *backend, const char *tzid); - GList *(* get_uids) (CalBackend *backend, CalObjType type); - - GList *(* get_objects_in_range) (CalBackend *backend, CalObjType type, - time_t start, time_t end); - GList *(* get_free_busy) (CalBackend *backend, GList *users, time_t start, time_t end); - - /* Change related virtual methods */ - GNOME_Evolution_Calendar_CalObjChangeSeq * (* get_changes) ( - CalBackend *backend, CalObjType type, const char *change_id); - - /* Alarm related virtual methods */ - GNOME_Evolution_Calendar_CalComponentAlarmsSeq *(* get_alarms_in_range) ( - CalBackend *backend, time_t start, time_t end); - GNOME_Evolution_Calendar_CalComponentAlarms *(* get_alarms_for_object) ( - CalBackend *backend, const char *uid, - time_t start, time_t end, gboolean *object_found); - - /* Object manipulation virtual methods */ - CalBackendResult (* update_objects) (CalBackend *backend, const char *calobj); - CalBackendResult (* remove_object) (CalBackend *backend, const char *uid); - - CalBackendSendResult (* send_object) (CalBackend *backend, const char *calobj, char **new_calobj, - GNOME_Evolution_Calendar_UserList **user_list, - char error_msg[256]); - - /* Timezone related virtual methods */ - icaltimezone *(* get_timezone) (CalBackend *backend, const char *tzid); - icaltimezone *(* get_default_timezone) (CalBackend *backend); - gboolean (* set_default_timezone) (CalBackend *backend, const char *tzid); -}; - -GType cal_backend_get_type (void); - -const char *cal_backend_get_uri (CalBackend *backend); - -const char *cal_backend_get_email_address (CalBackend *backend); - -void cal_backend_add_cal (CalBackend *backend, Cal *cal); - -CalBackendOpenStatus cal_backend_open (CalBackend *backend, const char *uristr, - gboolean only_if_exists); - -gboolean cal_backend_is_loaded (CalBackend *backend); - -gboolean cal_backend_is_read_only (CalBackend *backend); - -Query *cal_backend_get_query (CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp); - -CalMode cal_backend_get_mode (CalBackend *backend); -void cal_backend_set_mode (CalBackend *backend, CalMode mode); - -int cal_backend_get_n_objects (CalBackend *backend, CalObjType type); - -char *cal_backend_get_object (CalBackend *backend, const char *uid); - -CalComponent *cal_backend_get_object_component (CalBackend *backend, const char *uid); - -gboolean cal_backend_set_default_timezone (CalBackend *backend, const char *tzid); - -char *cal_backend_get_timezone_object (CalBackend *backend, const char *tzid); - -CalObjType cal_backend_get_type_by_uid (CalBackend *backend, const char *uid); - -GList *cal_backend_get_uids (CalBackend *backend, CalObjType type); - -GList *cal_backend_get_objects_in_range (CalBackend *backend, CalObjType type, - time_t start, time_t end); - -GList *cal_backend_get_free_busy (CalBackend *backend, GList *users, time_t start, time_t end); - -GNOME_Evolution_Calendar_CalObjChangeSeq * cal_backend_get_changes ( - CalBackend *backend, CalObjType type, const char *change_id); - -GNOME_Evolution_Calendar_CalComponentAlarmsSeq *cal_backend_get_alarms_in_range ( - CalBackend *backend, time_t start, time_t end, gboolean *valid_range); - -GNOME_Evolution_Calendar_CalComponentAlarms *cal_backend_get_alarms_for_object ( - CalBackend *backend, const char *uid, - time_t start, time_t end, - CalBackendGetAlarmsForObjectResult *result); - - -CalBackendResult cal_backend_update_objects (CalBackend *backend, const char *calobj); - -CalBackendResult cal_backend_remove_object (CalBackend *backend, const char *uid); - -CalBackendSendResult cal_backend_send_object (CalBackend *backend, const char *calobj, char **new_calobj, - GNOME_Evolution_Calendar_UserList **user_list, - char error_msg[256]); - -icaltimezone* cal_backend_get_timezone (CalBackend *backend, const char *tzid); -icaltimezone* cal_backend_get_default_timezone (CalBackend *backend); - -void cal_backend_last_client_gone (CalBackend *backend); -void cal_backend_opened (CalBackend *backend, CalBackendOpenStatus status); -void cal_backend_obj_updated (CalBackend *backend, const char *uid); -void cal_backend_obj_removed (CalBackend *backend, const char *uid); - - - -G_END_DECLS - -#endif diff --git a/calendar/pcs/cal-common.h b/calendar/pcs/cal-common.h deleted file mode 100644 index 3bf229ee8f..0000000000 --- a/calendar/pcs/cal-common.h +++ /dev/null @@ -1,41 +0,0 @@ -/* Evolution calendar server - common declarations - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#ifndef CAL_COMMON_H -#define CAL_COMMON_H - -#include <glib/gmacros.h> - -G_BEGIN_DECLS - - - -typedef struct _CalBackend CalBackend; -typedef struct _CalBackendClass CalBackendClass; - -typedef struct _Cal Cal; -typedef struct _CalClass CalClass; - - - -G_END_DECLS - -#endif diff --git a/calendar/pcs/cal-factory.c b/calendar/pcs/cal-factory.c deleted file mode 100644 index d9f0f5ad27..0000000000 --- a/calendar/pcs/cal-factory.c +++ /dev/null @@ -1,836 +0,0 @@ -/* Evolution calendar factory - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#include <config.h> -#include <ctype.h> -#include <stdio.h> -#include <bonobo-activation/bonobo-activation.h> -#include "e-util/e-url.h" -#include "evolution-calendar.h" -#include "cal.h" -#include "cal-backend.h" -#include "cal-factory.h" -#include "job.h" - -#define PARENT_TYPE BONOBO_TYPE_OBJECT -#define DEFAULT_CAL_FACTORY_OAF_ID "OAFIID:GNOME_Evolution_Wombat_CalendarFactory" - -static BonoboObjectClass *parent_class; - -/* Private part of the CalFactory structure */ -struct _CalFactoryPrivate { - /* Hash table from URI method strings to GType * for backend class types */ - GHashTable *methods; - - /* Hash table from GnomeVFSURI structures to CalBackend objects */ - GHashTable *backends; - - /* OAFIID of the factory */ - char *iid; - - /* Whether we have been registered with OAF yet */ - guint registered : 1; -}; - -typedef struct -{ - CalFactory *factory; - GNOME_Evolution_Calendar_CalMode mode; - GNOME_Evolution_Calendar_StringSeq *list; -} CalFactoryUriData; - -/* Signal IDs */ -enum SIGNALS { - LAST_CALENDAR_GONE, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -/* Frees a method/GType * pair from the methods hash table */ -static void -free_method (gpointer key, gpointer value, gpointer data) -{ - char *method; - GType *type; - - method = key; - type = value; - - g_free (method); - g_free (type); -} - -/* Frees a uri/backend pair from the backends hash table */ -static void -free_backend (gpointer key, gpointer value, gpointer data) -{ - char *uri; - CalBackend *backend; - - uri = key; - backend = value; - - g_free (uri); - g_object_unref (backend); -} - -/* Opening calendars */ - -/* Looks up a calendar backend in a factory's hash table of uri->cal. If - * *non-NULL, orig_uri_return will be set to point to the original key in the - * *hash table. - */ -static CalBackend * -lookup_backend (CalFactory *factory, const char *uristr, char **orig_uri_return) -{ - CalFactoryPrivate *priv; - EUri *uri; - char *tmp; - gboolean found; - gpointer orig_key; - gpointer data; - - priv = factory->priv; - - uri = e_uri_new (uristr); - if (!uri) { - if (orig_uri_return) - *orig_uri_return = NULL; - - return NULL; - } - - tmp = e_uri_to_string (uri, FALSE); - found = g_hash_table_lookup_extended (priv->backends, tmp, &orig_key, &data); - g_free (tmp); - e_uri_free (uri); - - if (found) { - if (orig_uri_return) - *orig_uri_return = orig_key; - - return CAL_BACKEND (data); - } else { - if (orig_uri_return) - *orig_uri_return = NULL; - - return NULL; - } -} - -/* Callback used when a backend loses its last connected client */ -static void -backend_last_client_gone_cb (CalBackend *backend, gpointer data) -{ - CalFactory *factory; - CalFactoryPrivate *priv; - CalBackend *ret_backend; - const char *uristr; - char *orig_uristr; - - fprintf (stderr, "backend_last_client_gone_cb() called!\n"); - - factory = CAL_FACTORY (data); - priv = factory->priv; - - /* Remove the backend from the hash table */ - - uristr = cal_backend_get_uri (backend); - g_assert (uristr != NULL); - - ret_backend = lookup_backend (factory, uristr, &orig_uristr); - g_assert (ret_backend != NULL); - g_assert (ret_backend == backend); - - g_hash_table_remove (priv->backends, orig_uristr); - g_free (orig_uristr); - - g_object_unref (backend); - - /* Notify upstream if there are no more backends */ - - if (g_hash_table_size (priv->backends) == 0) - g_signal_emit (G_OBJECT (factory), signals[LAST_CALENDAR_GONE], 0); -} - -/* Adds a backend to the calendar factory's hash table */ -static void -add_backend (CalFactory *factory, const char *uristr, CalBackend *backend) -{ - CalFactoryPrivate *priv; - EUri *uri; - char *tmp; - - priv = factory->priv; - - uri = e_uri_new (uristr); - if (!uri) - return; - - tmp = e_uri_to_string (uri, FALSE); - g_hash_table_insert (priv->backends, tmp, backend); - e_uri_free (uri); - - g_signal_connect (G_OBJECT (backend), "last_client_gone", - G_CALLBACK (backend_last_client_gone_cb), - factory); -} - -/* Tries to launch a backend for the method of the specified URI. If there is - * no such method registered in the factory, it sends the listener the - * MethodNotSupported error code. - */ -static CalBackend * -launch_backend_for_uri (CalFactory *factory, - const char *uristr, - GNOME_Evolution_Calendar_Listener listener) -{ - CalFactoryPrivate *priv; - const char *method; - GType *type; - CalBackend *backend; - EUri *uri; - - priv = factory->priv; - - uri = e_uri_new (uristr); - if (!uri) - return NULL; - - method = uri->protocol; - type = g_hash_table_lookup (priv->methods, method); - e_uri_free (uri); - - if (!type) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalOpened ( - listener, - GNOME_Evolution_Calendar_Listener_METHOD_NOT_SUPPORTED, - CORBA_OBJECT_NIL, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("launch_backend_for_uri(): could not notify the listener"); - - CORBA_exception_free (&ev); - return NULL; - } - - backend = g_object_new (*type, NULL); - if (!backend) - g_message ("launch_backend_for_uri(): could not launch the backend"); - - return backend; -} - -/* Opens a calendar backend and puts it in the factory's backend hash table */ -static CalBackend * -open_backend (CalFactory *factory, const char *uristr, gboolean only_if_exists, - GNOME_Evolution_Calendar_Listener listener) -{ - CalFactoryPrivate *priv; - CalBackend *backend; - CalBackendOpenStatus status; - CORBA_Environment ev; - - priv = factory->priv; - - backend = launch_backend_for_uri (factory, uristr, listener); - if (!backend) - return NULL; - - status = cal_backend_open (backend, uristr, only_if_exists); - - switch (status) { - case CAL_BACKEND_OPEN_SUCCESS: - add_backend (factory, uristr, backend); - return backend; - - case CAL_BACKEND_OPEN_ERROR: - g_object_unref (backend); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalOpened ( - listener, - GNOME_Evolution_Calendar_Listener_ERROR, - CORBA_OBJECT_NIL, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("open_backend(): could not notify the listener"); - - CORBA_exception_free (&ev); - return NULL; - - case CAL_BACKEND_OPEN_NOT_FOUND: - g_object_unref (backend); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalOpened ( - listener, - GNOME_Evolution_Calendar_Listener_NOT_FOUND, - CORBA_OBJECT_NIL, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("open_backend(): could not notify the listener"); - - CORBA_exception_free (&ev); - return NULL; - - case CAL_BACKEND_OPEN_PERMISSION_DENIED : - g_object_unref (backend); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalOpened ( - listener, - GNOME_Evolution_Calendar_Listener_PERMISSION_DENIED, - CORBA_OBJECT_NIL, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("open_backend(): could not notify the listener"); - - CORBA_exception_free (&ev); - return NULL; - - default: - g_assert_not_reached (); - return NULL; - } -} - -/* Adds a listener to a calendar backend by creating a calendar client interface - * object. - */ -static void -add_calendar_client (CalFactory *factory, - CalBackend *backend, - GNOME_Evolution_Calendar_Listener listener) -{ - Cal *cal; - CORBA_Environment ev; - - cal = cal_new (backend, listener); - if (!cal) { - g_message ("add_calendar_client(): could not create the calendar client interface"); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalOpened ( - listener, - GNOME_Evolution_Calendar_Listener_ERROR, - CORBA_OBJECT_NIL, - &ev); - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("add_calendar_client(): could not notify the listener"); - - CORBA_exception_free (&ev); - return; - } - - cal_backend_add_cal (backend, cal); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalOpened ( - listener, - GNOME_Evolution_Calendar_Listener_SUCCESS, - BONOBO_OBJREF (cal), - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_message ("add_calendar_client(): could not notify the listener"); - bonobo_object_unref (BONOBO_OBJECT (cal)); - } - - CORBA_exception_free (&ev); -} - -/* Add a uri to a string list */ -static void -add_uri (gpointer key, gpointer value, gpointer data) -{ - CalFactoryUriData *cfud = data; - CalFactory *factory = cfud->factory; - GNOME_Evolution_Calendar_StringSeq *list = cfud->list; - GNOME_Evolution_Calendar_CalMode mode = cfud->mode; - char *uri_string = key; - CalBackend *backend; - - switch (mode) { - case GNOME_Evolution_Calendar_MODE_LOCAL: - backend = lookup_backend (factory, uri_string, NULL); - if (backend == NULL || cal_backend_get_mode (backend) != CAL_MODE_LOCAL) - return; - break; - case GNOME_Evolution_Calendar_MODE_REMOTE: - backend = lookup_backend (factory, uri_string, NULL); - if (backend == NULL || cal_backend_get_mode (backend) != CAL_MODE_REMOTE) - return; - break; - case GNOME_Evolution_Calendar_MODE_ANY: - break; - } - - list->_buffer[list->_length] = CORBA_string_dup (uri_string); - list->_length++; -} - -/* Job data */ -typedef struct { - CalFactory *factory; - char *uri; - gboolean only_if_exists; - GNOME_Evolution_Calendar_Listener listener; -} OpenJobData; - -/* Job handler for the open calendar command */ -static void -open_fn (gpointer data) -{ - OpenJobData *jd; - CalFactory *factory; - gboolean only_if_exists; - GNOME_Evolution_Calendar_Listener listener; - CalBackend *backend; - CORBA_Environment ev; - char *uri_string; - - jd = data; - g_assert (jd->uri != NULL); - - /* Check the URI */ - uri_string = g_strdup (jd->uri); - g_free (jd->uri); - - only_if_exists = jd->only_if_exists; - factory = jd->factory; - listener = jd->listener; - g_free (jd); - - if (!uri_string) { - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalOpened ( - listener, - GNOME_Evolution_Calendar_Listener_ERROR, - CORBA_OBJECT_NIL, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("open_fn(): Could not notify the listener!"); - - CORBA_exception_free (&ev); - goto out; - } - - /* Look up the backend and create it if needed */ - - backend = lookup_backend (factory, uri_string, NULL); - - if (!backend) - backend = open_backend (factory, uri_string, only_if_exists, listener); - - g_free (uri_string); - - if (backend) - add_calendar_client (factory, backend, listener); - - out: - - CORBA_exception_init (&ev); - CORBA_Object_release (listener, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - g_message ("open_fn(): could not release the listener"); - - CORBA_exception_free (&ev); -} - - - -static void -impl_CalFactory_open (PortableServer_Servant servant, - const CORBA_char *str_uri, - CORBA_boolean only_if_exists, - GNOME_Evolution_Calendar_Listener listener, - CORBA_Environment *ev) -{ - CalFactory *factory; - CalFactoryPrivate *priv; - CORBA_Environment ev2; - gboolean result; - OpenJobData *jd; - GNOME_Evolution_Calendar_Listener listener_copy; - GType *type; - EUri *uri; - - factory = CAL_FACTORY (bonobo_object_from_servant (servant)); - priv = factory->priv; - - /* check URI to see if we support it */ - - uri = e_uri_new (str_uri); - if (!uri) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_CalFactory_InvalidURI, - NULL); - return; - } - - type = g_hash_table_lookup (priv->methods, uri->protocol); - - e_uri_free (uri); - if (!type) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_CalFactory_UnsupportedMethod, - NULL); - return; - } - - /* duplicate the listener object */ - CORBA_exception_init (&ev2); - result = CORBA_Object_is_nil (listener, &ev2); - - if (ev2._major != CORBA_NO_EXCEPTION || result) { - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_CalFactory_NilListener, - NULL); - - CORBA_exception_free (&ev2); - return; - } - CORBA_exception_free (&ev2); - - CORBA_exception_init (&ev2); - listener_copy = CORBA_Object_duplicate (listener, &ev2); - - if (ev2._major != CORBA_NO_EXCEPTION) { - g_message ("CalFactory_open(): could not duplicate the listener"); - CORBA_exception_free (&ev2); - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, - ex_GNOME_Evolution_Calendar_CalFactory_NilListener, - NULL); - return; - } - - CORBA_exception_free (&ev2); - - /* add new asynchronous job */ - jd = g_new (OpenJobData, 1); - jd->factory = factory; - jd->uri = g_strdup (str_uri); - jd->only_if_exists = only_if_exists; - jd->listener = listener_copy; - - job_add (open_fn, jd); -} - -static GNOME_Evolution_Calendar_StringSeq * -impl_CalFactory_uriList (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalMode mode, - CORBA_Environment *ev) -{ - CalFactory *factory; - CalFactoryPrivate *priv; - CalFactoryUriData cfud; - GNOME_Evolution_Calendar_StringSeq *list; - - factory = CAL_FACTORY (bonobo_object_from_servant (servant)); - priv = factory->priv; - - list = GNOME_Evolution_Calendar_StringSeq__alloc (); - list->_length = 0; - list->_maximum = g_hash_table_size (priv->backends); - list->_buffer = CORBA_sequence_CORBA_string_allocbuf (list->_maximum); - - cfud.factory = factory; - cfud.mode = mode; - cfud.list = list; - g_hash_table_foreach (priv->backends, add_uri, &cfud); - - return list; - -} - - - -/** - * cal_factory_new: - * @void: - * - * Creates a new #CalFactory object. - * - * Return value: A newly-created #CalFactory, or NULL if its corresponding CORBA - * object could not be created. - **/ -CalFactory * -cal_factory_new (void) -{ - CalFactory *factory; - - factory = g_object_new (CAL_FACTORY_TYPE, NULL); - - return factory; -} - -/* Destroy handler for the calendar */ -static void -cal_factory_finalize (GObject *object) -{ - CalFactory *factory; - CalFactoryPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CAL_FACTORY (object)); - - factory = CAL_FACTORY (object); - priv = factory->priv; - - g_hash_table_foreach (priv->methods, free_method, NULL); - g_hash_table_destroy (priv->methods); - priv->methods = NULL; - - /* Should we assert that there are no more backends? */ - - g_hash_table_foreach (priv->backends, free_backend, NULL); - g_hash_table_destroy (priv->backends); - priv->backends = NULL; - - if (priv->registered) { - bonobo_activation_active_server_unregister (priv->iid, BONOBO_OBJREF (factory)); - priv->registered = FALSE; - } - g_free (priv->iid); - - g_free (priv); - factory->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - -/* Class initialization function for the calendar factory */ -static void -cal_factory_class_init (CalFactoryClass *klass) -{ - GObjectClass *object_class = (GObjectClass *) klass; - POA_GNOME_Evolution_Calendar_CalFactory__epv *epv = &klass->epv; - - parent_class = g_type_class_peek_parent (klass); - - signals[LAST_CALENDAR_GONE] = - g_signal_new ("last_calendar_gone", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (CalFactoryClass, last_calendar_gone), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - /* Class method overrides */ - object_class->finalize = cal_factory_finalize; - - /* Epv methods */ - epv->open = impl_CalFactory_open; - epv->uriList = impl_CalFactory_uriList; -} - -/* Object initialization function for the calendar factory */ -static void -cal_factory_init (CalFactory *factory, CalFactoryClass *klass) -{ - CalFactoryPrivate *priv; - - priv = g_new0 (CalFactoryPrivate, 1); - factory->priv = priv; - - priv->methods = g_hash_table_new (g_str_hash, g_str_equal); - priv->backends = g_hash_table_new (g_str_hash, g_str_equal); - priv->registered = FALSE; -} - -BONOBO_TYPE_FUNC_FULL (CalFactory, - GNOME_Evolution_Calendar_CalFactory, - PARENT_TYPE, - cal_factory); - -/* Returns the lowercase version of a string */ -static char * -str_tolower (const char *s) -{ - char *str; - unsigned char *p; - - str = g_strdup (s); - for (p = str; *p; p++) - if (isalpha (*p)) - *p = tolower (*p); - - return str; -} - -/** - * cal_factory_oaf_register: - * @factory: A calendar factory. - * @iid: OAFIID for the factory to be registered. - * - * Registers a calendar factory with the OAF object activation daemon. This - * function must be called before any clients can activate the factory. - * - * Return value: TRUE on success, FALSE otherwise. - **/ -gboolean -cal_factory_oaf_register (CalFactory *factory, const char *iid) -{ - CalFactoryPrivate *priv; - Bonobo_RegistrationResult result; - char *tmp_iid; - - g_return_val_if_fail (factory != NULL, FALSE); - g_return_val_if_fail (IS_CAL_FACTORY (factory), FALSE); - - priv = factory->priv; - - g_return_val_if_fail (!priv->registered, FALSE); - - /* if iid is NULL, use the default factory OAFIID */ - if (iid) - tmp_iid = g_strdup (iid); - else - tmp_iid = g_strdup (DEFAULT_CAL_FACTORY_OAF_ID); - - result = bonobo_activation_active_server_register (tmp_iid, BONOBO_OBJREF (factory)); - - switch (result) { - case Bonobo_ACTIVATION_REG_SUCCESS: - priv->registered = TRUE; - priv->iid = tmp_iid; - return TRUE; - - case Bonobo_ACTIVATION_REG_NOT_LISTED: - g_message ("cal_factory_oaf_register(): Cannot register the calendar factory: " - "not listed"); - break; - - case Bonobo_ACTIVATION_REG_ALREADY_ACTIVE: - g_message ("cal_factory_oaf_register(): Cannot register the calendar factory: " - "already active"); - break; - - case Bonobo_ACTIVATION_REG_ERROR: - default: - g_message ("cal_factory_oaf_register(): Cannot register the calendar factory: " - "generic error"); - break; - } - - g_free (tmp_iid); - - return FALSE; -} - -/** - * cal_factory_register_method: - * @factory: A calendar factory. - * @method: Method for the URI, i.e. "http", "file", etc. - * @backend_type: Class type of the backend to create for this @method. - * - * Registers the type of a #CalBackend subclass that will be used to handle URIs - * with a particular method. When the factory is asked to open a particular - * URI, it will look in its list of registered methods and create a backend of - * the appropriate type. - **/ -void -cal_factory_register_method (CalFactory *factory, const char *method, GType backend_type) -{ - CalFactoryPrivate *priv; - GType *type; - char *method_str; - - g_return_if_fail (factory != NULL); - g_return_if_fail (IS_CAL_FACTORY (factory)); - g_return_if_fail (method != NULL); - g_return_if_fail (backend_type != 0); - g_return_if_fail (g_type_is_a (backend_type, CAL_BACKEND_TYPE)); - - priv = factory->priv; - - method_str = str_tolower (method); - - type = g_hash_table_lookup (priv->methods, method_str); - if (type) { - g_message ("cal_factory_register_method(): Method `%s' already registered!", - method_str); - g_free (method_str); - return; - } - - type = g_new (GType, 1); - *type = backend_type; - - g_hash_table_insert (priv->methods, method_str, type); -} - -/** - * cal_factory_get_n_backends: - * @factory: A calendar factory. - * - * Queries the number of running calendar backends in a calendar factory. - * - * Return value: Number of running backends. - **/ -int -cal_factory_get_n_backends (CalFactory *factory) -{ - CalFactoryPrivate *priv; - - g_return_val_if_fail (factory != NULL, -1); - g_return_val_if_fail (IS_CAL_FACTORY (factory), -1); - - priv = factory->priv; - return g_hash_table_size (priv->backends); -} - -/* Frees a uri/backend pair from the backends hash table */ -static void -dump_backend (gpointer key, gpointer value, gpointer data) -{ - char *uri; - CalBackend *backend; - - uri = key; - backend = value; - - g_message (" %s: %p", uri, backend); -} - -void -cal_factory_dump_active_backends (CalFactory *factory) -{ - CalFactoryPrivate *priv; - - g_message ("Active PCS backends"); - - priv = factory->priv; - g_hash_table_foreach (priv->backends, dump_backend, NULL); -} diff --git a/calendar/pcs/cal-factory.h b/calendar/pcs/cal-factory.h deleted file mode 100644 index b7c370066b..0000000000 --- a/calendar/pcs/cal-factory.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Evolution calendar factory - * - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#ifndef CAL_FACTORY_H -#define CAL_FACTORY_H - -#include <bonobo/bonobo-object.h> - -#include "pcs/evolution-calendar.h" - -G_BEGIN_DECLS - - - -#define CAL_FACTORY_TYPE (cal_factory_get_type ()) -#define CAL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CAL_FACTORY_TYPE, CalFactory)) -#define CAL_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CAL_FACTORY_TYPE, \ - CalFactoryClass)) -#define IS_CAL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CAL_FACTORY_TYPE)) -#define IS_CAL_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CAL_FACTORY_TYPE)) - -typedef struct _CalFactory CalFactory; -typedef struct _CalFactoryClass CalFactoryClass; - -typedef struct _CalFactoryPrivate CalFactoryPrivate; - -struct _CalFactory { - BonoboObject object; - - /* Private data */ - CalFactoryPrivate *priv; -}; - -struct _CalFactoryClass { - BonoboObjectClass parent_class; - - POA_GNOME_Evolution_Calendar_CalFactory__epv epv; - - /* Notification signals */ - void (* last_calendar_gone) (CalFactory *factory); -}; - -GType cal_factory_get_type (void); -CalFactory *cal_factory_new (void); - -gboolean cal_factory_oaf_register (CalFactory *factory, const char *iid); -void cal_factory_register_method (CalFactory *factory, - const char *method, - GType backend_type); -int cal_factory_get_n_backends (CalFactory *factory); -void cal_factory_dump_active_backends (CalFactory *factory); - -G_END_DECLS - -#endif diff --git a/calendar/pcs/cal.c b/calendar/pcs/cal.c deleted file mode 100644 index 0d089b5096..0000000000 --- a/calendar/pcs/cal.c +++ /dev/null @@ -1,1017 +0,0 @@ -/* Evolution calendar client interface object - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#include <config.h> -#include <ical.h> -#include <bonobo/bonobo-exception.h> -#include "cal.h" -#include "cal-backend.h" -#include "query.h" -#include "Evolution-Wombat.h" - -#define PARENT_TYPE BONOBO_TYPE_OBJECT - -static BonoboObjectClass *parent_class; - -/* Private part of the Cal structure */ -struct _CalPrivate { - /* Our backend */ - CalBackend *backend; - - /* Listener on the client we notify */ - GNOME_Evolution_Calendar_Listener listener; - - /* A reference to the WombatClient interface */ - GNOME_Evolution_WombatClient wombat_client; -}; - - -/* Cal::get_uri method */ -static CORBA_char * -impl_Cal_get_uri (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - const char *str_uri; - CORBA_char *str_uri_copy; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - str_uri = cal_backend_get_uri (priv->backend); - str_uri_copy = CORBA_string_dup (str_uri); - - return str_uri_copy; -} - -/* Cal::isReadOnly method */ -static CORBA_boolean -impl_Cal_isReadOnly (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - return cal_backend_is_read_only (priv->backend); -} - -/* Cal::getEmailAddress method */ -static CORBA_char * -impl_Cal_getEmailAddress (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - const char *str_email_address; - CORBA_char *str_email_address_copy; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - str_email_address = cal_backend_get_email_address (priv->backend); - if (str_email_address == NULL) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - return CORBA_OBJECT_NIL; - } - - str_email_address_copy = CORBA_string_dup (str_email_address); - - return str_email_address_copy; -} - -/* Converts a calendar object type from its CORBA representation to our own - * representation. - */ -static CalObjType -uncorba_obj_type (GNOME_Evolution_Calendar_CalObjType type) -{ - return (((type & GNOME_Evolution_Calendar_TYPE_EVENT) ? CALOBJ_TYPE_EVENT : 0) - | ((type & GNOME_Evolution_Calendar_TYPE_TODO) ? CALOBJ_TYPE_TODO : 0) - | ((type & GNOME_Evolution_Calendar_TYPE_JOURNAL) ? CALOBJ_TYPE_JOURNAL : 0)); -} - -/* Cal::setMode method */ -static void -impl_Cal_setMode (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalMode mode, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - cal_backend_set_mode (priv->backend, mode); -} - -/* Cal::countObjects method */ -static CORBA_long -impl_Cal_countObjects (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjType type, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - int t; - int n; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - t = uncorba_obj_type (type); - n = cal_backend_get_n_objects (priv->backend, t); - return n; -} - -/* Cal::getObject method */ -static GNOME_Evolution_Calendar_CalObj -impl_Cal_getObject (PortableServer_Servant servant, - const CORBA_char *uid, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - char *calobj; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - calobj = cal_backend_get_object (priv->backend, uid); - - if (calobj) { - CORBA_char *calobj_copy; - - calobj_copy = CORBA_string_dup (calobj); - g_free (calobj); - return calobj_copy; - } else { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - - return NULL; - } -} - -static GNOME_Evolution_Calendar_CalObjUIDSeq * -build_uid_seq (GList *uids) -{ - GNOME_Evolution_Calendar_CalObjUIDSeq *seq; - GList *l; - int n, i; - - n = g_list_length (uids); - - seq = GNOME_Evolution_Calendar_CalObjUIDSeq__alloc (); - CORBA_sequence_set_release (seq, TRUE); - seq->_length = n; - seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalObjUID_allocbuf (n); - - /* Fill the sequence */ - - for (i = 0, l = uids; l; i++, l = l->next) { - char *uid; - - uid = l->data; - seq->_buffer[i] = CORBA_string_dup (uid); - } - - return seq; -} - -/* Cal::getUIDs method */ -static GNOME_Evolution_Calendar_CalObjUIDSeq * -impl_Cal_getUIDs (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjType type, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - GList *uids; - GNOME_Evolution_Calendar_CalObjUIDSeq *seq; - int t; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - t = uncorba_obj_type (type); - - uids = cal_backend_get_uids (priv->backend, t); - seq = build_uid_seq (uids); - - cal_obj_uid_list_free (uids); - - return seq; -} - -/* Cal::getChanges method */ -static GNOME_Evolution_Calendar_CalObjChangeSeq * -impl_Cal_getChanges (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjType type, - const CORBA_char *change_id, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - int t; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - t = uncorba_obj_type (type); - - return cal_backend_get_changes (priv->backend, t, change_id); -} - -/* Cal::getObjectsInRange method */ -static GNOME_Evolution_Calendar_CalObjUIDSeq * -impl_Cal_getObjectsInRange (PortableServer_Servant servant, - GNOME_Evolution_Calendar_CalObjType type, - GNOME_Evolution_Calendar_Time_t start, - GNOME_Evolution_Calendar_Time_t end, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - int t; - time_t t_start, t_end; - GNOME_Evolution_Calendar_CalObjUIDSeq *seq; - GList *uids; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - t = uncorba_obj_type (type); - t_start = (time_t) start; - t_end = (time_t) end; - - if (t_start > t_end || t_start == -1 || t_end == -1) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidRange); - return NULL; - } - - uids = cal_backend_get_objects_in_range (priv->backend, t, t_start, t_end); - seq = build_uid_seq (uids); - - cal_obj_uid_list_free (uids); - - return seq; -} - -static GNOME_Evolution_Calendar_CalObjSeq * -build_fb_seq (GList *obj_list) -{ - GNOME_Evolution_Calendar_CalObjSeq *seq; - GList *l; - int n, i; - - n = g_list_length (obj_list); - - seq = GNOME_Evolution_Calendar_CalObjSeq__alloc (); - CORBA_sequence_set_release (seq, TRUE); - seq->_length = n; - seq->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalObj_allocbuf (n); - - /* Fill the sequence */ - - for (i = 0, l = obj_list; l; i++, l = l->next) { - char *calobj; - - calobj = l->data; - seq->_buffer[i] = CORBA_string_dup (calobj); - } - - return seq; -} - -/* Cal::getFreeBusy method */ -static GNOME_Evolution_Calendar_CalObjSeq * -impl_Cal_getFreeBusy (PortableServer_Servant servant, - const GNOME_Evolution_Calendar_UserList *user_list, - const GNOME_Evolution_Calendar_Time_t start, - const GNOME_Evolution_Calendar_Time_t end, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - time_t t_start, t_end; - GList *users = NULL; - GList *obj_list; - GNOME_Evolution_Calendar_CalObjSeq *seq; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - t_start = (time_t) start; - t_end = (time_t) end; - - if (t_start > t_end || t_start == -1 || t_end == -1) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidRange); - return build_fb_seq (NULL); - } - - /* convert the CORBA user list to a GList */ - if (user_list) { - int i; - - for (i = 0; i < user_list->_length; i++) - users = g_list_append (users, user_list->_buffer[i]); - } - - /* call the backend's get_free_busy method */ - obj_list = cal_backend_get_free_busy (priv->backend, users, t_start, t_end); - seq = build_fb_seq (obj_list); - g_list_free (users); - - if (obj_list == NULL) - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - - return seq; -} - -/* Cal::getAlarmsInRange method */ -static GNOME_Evolution_Calendar_CalComponentAlarmsSeq * -impl_Cal_getAlarmsInRange (PortableServer_Servant servant, - GNOME_Evolution_Calendar_Time_t start, - GNOME_Evolution_Calendar_Time_t end, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - time_t t_start, t_end; - gboolean valid_range; - GNOME_Evolution_Calendar_CalComponentAlarmsSeq *seq; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - t_start = (time_t) start; - t_end = (time_t) end; - - seq = cal_backend_get_alarms_in_range (priv->backend, t_start, t_end, &valid_range); - if (!valid_range) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidRange); - return NULL; - } - - if (!seq) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - return NULL; - } - - return seq; -} - -/* Cal::getAlarmsForObject method */ -static GNOME_Evolution_Calendar_CalComponentAlarms * -impl_Cal_getAlarmsForObject (PortableServer_Servant servant, - const CORBA_char *uid, - GNOME_Evolution_Calendar_Time_t start, - GNOME_Evolution_Calendar_Time_t end, - CORBA_Environment * ev) -{ - Cal *cal; - CalPrivate *priv; - time_t t_start, t_end; - GNOME_Evolution_Calendar_CalComponentAlarms *alarms; - CalBackendGetAlarmsForObjectResult result; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - t_start = (time_t) start; - t_end = (time_t) end; - - alarms = cal_backend_get_alarms_for_object (priv->backend, uid, t_start, t_end, &result); - - switch (result) { - case CAL_BACKEND_GET_ALARMS_SUCCESS: - return alarms; - - case CAL_BACKEND_GET_ALARMS_NOT_FOUND: - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - return NULL; - - case CAL_BACKEND_GET_ALARMS_INVALID_RANGE: - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidRange); - return NULL; - - default: - g_assert_not_reached (); - return NULL; - } -} - -/* Cal::updateObjects method */ -static void -impl_Cal_updateObjects (PortableServer_Servant servant, - const CORBA_char *calobj, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - CalBackendResult result; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - result = cal_backend_update_objects (priv->backend, calobj); - switch (result) { - case CAL_BACKEND_RESULT_INVALID_OBJECT : - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject); - break; - case CAL_BACKEND_RESULT_NOT_FOUND : - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - break; - case CAL_BACKEND_RESULT_PERMISSION_DENIED : - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied); - break; - default : - break; - } -} - -/* Cal::removeObject method */ -static void -impl_Cal_removeObject (PortableServer_Servant servant, - const CORBA_char *uid, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - CalBackendResult result; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - result = cal_backend_remove_object (priv->backend, uid); - switch (result) { - case CAL_BACKEND_RESULT_INVALID_OBJECT : - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject); - break; - case CAL_BACKEND_RESULT_NOT_FOUND : - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - break; - case CAL_BACKEND_RESULT_PERMISSION_DENIED : - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied); - break; - default : - break; - } -} - -/* Cal::sendObject method */ -static GNOME_Evolution_Calendar_CalObj -impl_Cal_sendObject (PortableServer_Servant servant, - const CORBA_char *calobj, - GNOME_Evolution_Calendar_UserList **user_list, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - CORBA_char *calobj_copy; - char *new_calobj; - GNOME_Evolution_Calendar_Cal_Busy *err; - CalBackendSendResult result; - char error_msg[256]; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - result = cal_backend_send_object (priv->backend, calobj, &new_calobj, user_list, error_msg); - switch (result) { - case CAL_BACKEND_SEND_SUCCESS: - calobj_copy = CORBA_string_dup (new_calobj); - g_free (new_calobj); - - return calobj_copy; - - case CAL_BACKEND_SEND_INVALID_OBJECT: - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_InvalidObject); - break; - - case CAL_BACKEND_SEND_BUSY: - err = GNOME_Evolution_Calendar_Cal_Busy__alloc (); - err->errorMsg = CORBA_string_dup (error_msg); - CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Calendar_Cal_Busy, err); - break; - - case CAL_BACKEND_SEND_PERMISSION_DENIED: - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_PermissionDenied); - break; - - default : - g_assert_not_reached (); - } - - return NULL; -} - -/* Cal::getQuery implementation */ -static GNOME_Evolution_Calendar_Query -impl_Cal_getQuery (PortableServer_Servant servant, - const CORBA_char *sexp, - GNOME_Evolution_Calendar_QueryListener ql, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - Query *query; - CORBA_Environment ev2; - GNOME_Evolution_Calendar_Query query_copy; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - query = cal_backend_get_query (priv->backend, ql, sexp); - if (!query) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_CouldNotCreate); - return CORBA_OBJECT_NIL; - } - - CORBA_exception_init (&ev2); - query_copy = CORBA_Object_duplicate (BONOBO_OBJREF (query), &ev2); - if (BONOBO_EX (&ev2)) { - bonobo_object_unref (query); - CORBA_exception_free (&ev2); - g_message ("Cal_get_query(): Could not duplicate the query reference"); - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_CouldNotCreate); - return CORBA_OBJECT_NIL; - } - - CORBA_exception_free (&ev2); - - return query_copy; -} - -/* Cal::setDefaultTimezone method */ -static void -impl_Cal_setDefaultTimezone (PortableServer_Servant servant, - const CORBA_char *tzid, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - gboolean zone_set; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - zone_set = cal_backend_set_default_timezone (priv->backend, tzid); - - if (!zone_set) { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - } -} - -/* Cal::getTimezoneObject method */ -static GNOME_Evolution_Calendar_CalObj -impl_Cal_getTimezoneObject (PortableServer_Servant servant, - const CORBA_char *tzid, - CORBA_Environment *ev) -{ - Cal *cal; - CalPrivate *priv; - char *calobj; - - cal = CAL (bonobo_object_from_servant (servant)); - priv = cal->priv; - - calobj = cal_backend_get_timezone_object (priv->backend, tzid); - - if (calobj) { - CORBA_char *calobj_copy; - - calobj_copy = CORBA_string_dup (calobj); - g_free (calobj); - return calobj_copy; - } else { - bonobo_exception_set (ev, ex_GNOME_Evolution_Calendar_Cal_NotFound); - return NULL; - } -} - -/** - * cal_construct: - * @cal: A calendar client interface. - * @corba_cal: CORBA object for the calendar. - * @backend: Calendar backend that this @cal presents an interface to. - * @listener: Calendar listener for notification. - * - * Constructs a calendar client interface object by binding the corresponding - * CORBA object to it. The calendar interface is bound to the specified - * @backend, and will notify the @listener about changes to the calendar. - * - * Return value: The same object as the @cal argument. - **/ -Cal * -cal_construct (Cal *cal, - CalBackend *backend, - GNOME_Evolution_Calendar_Listener listener) -{ - CalPrivate *priv; - CORBA_Environment ev; - - g_return_val_if_fail (cal != NULL, NULL); - g_return_val_if_fail (IS_CAL (cal), NULL); - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - priv = cal->priv; - - CORBA_exception_init (&ev); - priv->listener = CORBA_Object_duplicate (listener, &ev); - if (BONOBO_EX (&ev)) { - g_message ("cal_construct: could not duplicate the listener"); - priv->listener = CORBA_OBJECT_NIL; - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - - /* obtain the WombatClient interface */ - CORBA_exception_init (&ev); - priv->wombat_client = Bonobo_Unknown_queryInterface ( - priv->listener, - "IDL:GNOME/Evolution/WombatClient:1.0", - &ev); - if (BONOBO_EX (&ev)) { - g_message ("cal_construct: could not get the WombatClient interface"); - priv->wombat_client = CORBA_OBJECT_NIL; - } - - CORBA_exception_free (&ev); - - priv->backend = backend; - - return cal; -} - -/** - * cal_new: - * @backend: A calendar backend. - * @listener: A calendar listener. - * - * Creates a new calendar client interface object and binds it to the specified - * @backend and @listener objects. - * - * Return value: A newly-created #Cal calendar client interface object, or NULL - * if its corresponding CORBA object could not be created. - **/ -Cal * -cal_new (CalBackend *backend, GNOME_Evolution_Calendar_Listener listener) -{ - Cal *cal, *retval; - - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - cal = CAL (g_object_new (CAL_TYPE, NULL)); - - retval = cal_construct (cal, backend, listener); - if (!retval) { - g_message ("cal_new(): could not construct the calendar client interface"); - bonobo_object_unref (BONOBO_OBJECT (cal)); - return NULL; - } - - return retval; -} - -/* Destroy handler for the calendar */ -static void -cal_finalize (GObject *object) -{ - Cal *cal; - CalPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_CAL (object)); - - cal = CAL (object); - priv = cal->priv; - - priv->backend = NULL; - - CORBA_exception_init (&ev); - bonobo_object_release_unref (priv->listener, &ev); - if (BONOBO_EX (&ev)) - g_message ("cal_destroy(): could not release the listener"); - - priv->listener = NULL; - CORBA_exception_free (&ev); - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - - - -/* Class initialization function for the calendar */ -static void -cal_class_init (CalClass *klass) -{ - GObjectClass *object_class = (GObjectClass *) klass; - POA_GNOME_Evolution_Calendar_Cal__epv *epv = &klass->epv; - - parent_class = g_type_class_peek_parent (klass); - - /* Class method overrides */ - object_class->finalize = cal_finalize; - - /* Epv methods */ - epv->_get_uri = impl_Cal_get_uri; - epv->isReadOnly = impl_Cal_isReadOnly; - epv->getEmailAddress = impl_Cal_getEmailAddress; - epv->setMode = impl_Cal_setMode; - epv->countObjects = impl_Cal_countObjects; - epv->getObject = impl_Cal_getObject; - epv->setDefaultTimezone = impl_Cal_setDefaultTimezone; - epv->getTimezoneObject = impl_Cal_getTimezoneObject; - epv->getUIDs = impl_Cal_getUIDs; - epv->getChanges = impl_Cal_getChanges; - epv->getObjectsInRange = impl_Cal_getObjectsInRange; - epv->getFreeBusy = impl_Cal_getFreeBusy; - epv->getAlarmsInRange = impl_Cal_getAlarmsInRange; - epv->getAlarmsForObject = impl_Cal_getAlarmsForObject; - epv->updateObjects = impl_Cal_updateObjects; - epv->removeObject = impl_Cal_removeObject; - epv->sendObject = impl_Cal_sendObject; - epv->getQuery = impl_Cal_getQuery; -} - - -/* Object initialization function for the calendar */ -static void -cal_init (Cal *cal, CalClass *klass) -{ - CalPrivate *priv; - - priv = g_new0 (CalPrivate, 1); - cal->priv = priv; - - priv->listener = CORBA_OBJECT_NIL; -} - -BONOBO_TYPE_FUNC_FULL (Cal, GNOME_Evolution_Calendar_Cal, PARENT_TYPE, cal); - -/** - * cal_notify_mode: - * @cal: A calendar client interface. - * @status: Status of the mode set. - * @mode: The current mode. - * - * Notifys the listener of the results of a setMode call. - **/ -void -cal_notify_mode (Cal *cal, - GNOME_Evolution_Calendar_Listener_SetModeStatus status, - GNOME_Evolution_Calendar_CalMode mode) -{ - CalPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); - - priv = cal->priv; - g_return_if_fail (priv->listener != CORBA_OBJECT_NIL); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCalSetMode (priv->listener, status, mode, &ev); - - if (BONOBO_EX (&ev)) - g_message ("cal_notify_mode(): could not notify the listener " - "about a mode change"); - - CORBA_exception_free (&ev); -} - -/** - * cal_notify_update: - * @cal: A calendar client interface. - * @uid: UID of object that was updated. - * - * Notifies a listener attached to a calendar client interface object about an - * update to a calendar object. - **/ -void -cal_notify_update (Cal *cal, const char *uid) -{ - CalPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); - g_return_if_fail (uid != NULL); - - priv = cal->priv; - g_return_if_fail (priv->listener != CORBA_OBJECT_NIL); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyObjUpdated (priv->listener, (char *) uid, &ev); - - if (BONOBO_EX (&ev)) - g_message ("cal_notify_update(): could not notify the listener " - "about an updated object"); - - CORBA_exception_free (&ev); -} - -/** - * cal_notify_remove: - * @cal: A calendar client interface. - * @uid: UID of object that was removed. - * - * Notifies a listener attached to a calendar client interface object about a - * calendar object that was removed. - **/ -void -cal_notify_remove (Cal *cal, const char *uid) -{ - CalPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); - g_return_if_fail (uid != NULL); - - priv = cal->priv; - g_return_if_fail (priv->listener != CORBA_OBJECT_NIL); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyObjRemoved (priv->listener, (char *) uid, &ev); - - if (BONOBO_EX (&ev)) - g_message ("cal_notify_remove(): could not notify the listener " - "about a removed object"); - - CORBA_exception_free (&ev); -} - -/** - * cal_notify_error - * @cal: A calendar client interface. - * @message: Error message. - * - * Notify a calendar client of an error occurred in the backend. - */ -void -cal_notify_error (Cal *cal, const char *message) -{ - CalPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); - g_return_if_fail (message != NULL); - - priv = cal->priv; - g_return_if_fail (priv->listener != CORBA_OBJECT_NIL); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyErrorOccurred (priv->listener, (char *) message, &ev); - - if (BONOBO_EX (&ev)) - g_message ("cal_notify_remove(): could not notify the listener " - "about a removed object"); - - CORBA_exception_free (&ev); -} - -/** - * cal_notify_categories_changed: - * @cal: A calendar client interface. - * @categories: List of categories. - * - * Notifies a listener attached to a calendar client interface object about the - * current set of categories in a calendar backend. - **/ -void -cal_notify_categories_changed (Cal *cal, GNOME_Evolution_Calendar_StringSeq *categories) -{ - CalPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); - g_return_if_fail (categories != NULL); - - priv = cal->priv; - g_return_if_fail (priv->listener != CORBA_OBJECT_NIL); - - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_Listener_notifyCategoriesChanged (priv->listener, categories, &ev); - - if (BONOBO_EX (&ev)) - g_message ("cal_notify_categories_changed(): Could not notify the listener " - "about the current set of categories"); - - CORBA_exception_free (&ev); -} - -/** - * cal_get_password: - * @cal: A calendar client interface. - * @prompt: The message to show to the user when asking for the password. - * @key: A key associated with the password being asked. - * - * Gets a password from the calendar client this Cal knows about. It does - * so by using the WombatClient interface being used by the corresponding - * CalClient. - * - * Returns: a password entered by the user. - */ -char * -cal_get_password (Cal *cal, const char *prompt, const char *key) -{ - CalPrivate *priv; - CORBA_Environment ev; - CORBA_char *pwd; - - g_return_val_if_fail (cal != NULL, NULL); - g_return_val_if_fail (IS_CAL (cal), NULL); - - priv = cal->priv; - g_return_val_if_fail (priv->wombat_client != CORBA_OBJECT_NIL, NULL); - - CORBA_exception_init (&ev); - pwd = GNOME_Evolution_WombatClient_getPassword ( - priv->wombat_client, - (const CORBA_char *) prompt, - (const CORBA_char *) key, - &ev); - if (BONOBO_EX (&ev)) { - g_message ("cal_get_password: could not get password from associated WombatClient"); - CORBA_exception_free (&ev); - return NULL; - } - - CORBA_exception_free (&ev); - - return pwd; -} - -/** - * cal_forget_password: - * @cal: A calendar client interface. - * @key: A key associated with the password to be forgotten. - * - * Notifies the associated calendar client that it should forget - * about the password identified by @key, so that next time the backend - * asks the client about it, the client would ask again the user for it. - * This is done in cases where the password supplied the first time - * was not a valid password and the backend needs the user to enter - * a new one. - */ -void -cal_forget_password (Cal *cal, const char *key) -{ - CalPrivate *priv; - CORBA_Environment ev; - - g_return_if_fail (cal != NULL); - g_return_if_fail (IS_CAL (cal)); - - priv = cal->priv; - g_return_if_fail (priv->wombat_client != CORBA_OBJECT_NIL); - - CORBA_exception_init (&ev); - GNOME_Evolution_WombatClient_forgetPassword ( - priv->wombat_client, - (const CORBA_char *) key, - &ev); - - if (BONOBO_EX (&ev)) { - g_message ("cal_forget_password: could not notify WombatClient about " - "password to be forgotten"); - } - - CORBA_exception_free (&ev); -} diff --git a/calendar/pcs/cal.h b/calendar/pcs/cal.h deleted file mode 100644 index 61db51abf6..0000000000 --- a/calendar/pcs/cal.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Evolution calendar client interface object - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Authors: Federico Mena-Quintero <federico@ximian.com> - * Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#ifndef CAL_H -#define CAL_H - -#include <bonobo/bonobo-object.h> -#include "pcs/evolution-calendar.h" -#include "pcs/cal-common.h" - -G_BEGIN_DECLS - - - -#define CAL_TYPE (cal_get_type ()) -#define CAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CAL_TYPE, Cal)) -#define CAL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CAL_TYPE, CalClass)) -#define IS_CAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CAL_TYPE)) -#define IS_CAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CAL_TYPE)) - -typedef struct _CalPrivate CalPrivate; - -struct _Cal { - BonoboObject object; - - /* Private data */ - CalPrivate *priv; -}; - -struct _CalClass { - BonoboObjectClass parent_class; - - POA_GNOME_Evolution_Calendar_Cal__epv epv; -}; - -GType cal_get_type (void); - -Cal *cal_construct (Cal *cal, - CalBackend *backend, - GNOME_Evolution_Calendar_Listener listener); - -Cal *cal_new (CalBackend *backend, GNOME_Evolution_Calendar_Listener listener); - -void cal_notify_mode (Cal *cal, - GNOME_Evolution_Calendar_Listener_SetModeStatus status, - GNOME_Evolution_Calendar_CalMode mode); -void cal_notify_update (Cal *cal, const char *uid); -void cal_notify_remove (Cal *cal, const char *uid); -void cal_notify_error (Cal *cal, const char *message); - -void cal_notify_categories_changed (Cal *cal, GNOME_Evolution_Calendar_StringSeq *categories); - -char *cal_get_password (Cal *cal, const char *prompt, const char *key); -void cal_forget_password (Cal *cal, const char *key); - - - -G_END_DECLS - -#endif diff --git a/calendar/pcs/job.c b/calendar/pcs/job.c deleted file mode 100644 index 584f1a6f38..0000000000 --- a/calendar/pcs/job.c +++ /dev/null @@ -1,98 +0,0 @@ -/* GNOME personal calendar server - job manager - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#include <config.h> -#include "job.h" - - - -/* The job list */ - -typedef struct { - JobFunc func; - gpointer data; -} Job; - -static GSList *jobs_head; -static GSList *jobs_tail; - -static guint jobs_idle_id; - - - -/* Runs a job and dequeues it */ -static gboolean -run_job (gpointer data) -{ - Job *job; - GSList *l; - - g_assert (jobs_head != NULL); - - job = jobs_head->data; - (* job->func) (job->data); - g_free (job); - - l = jobs_head; - jobs_head = g_slist_remove_link (jobs_head, jobs_head); - g_slist_free_1 (l); - - if (!jobs_head) { - jobs_tail = NULL; - jobs_idle_id = 0; - return FALSE; - } else - return TRUE; -} - -/** - * job_add: - * @func: Function to run the job. - * @data: Data to pass to @function. - * - * Adds a job to the queue. The job will automatically be run asynchronously. - **/ -void -job_add (JobFunc func, gpointer data) -{ - Job *job; - - g_return_if_fail (func != NULL); - - job = g_new (Job, 1); - job->func = func; - job->data = data; - - if (!jobs_head) { - g_assert (jobs_tail == NULL); - g_assert (jobs_idle_id == 0); - - jobs_head = g_slist_append (NULL, job); - jobs_tail = jobs_head; - - jobs_idle_id = g_idle_add (run_job, NULL); - } else { - g_assert (jobs_tail != NULL); - g_assert (jobs_idle_id != 0); - - jobs_tail = g_slist_append (jobs_tail, job)->next; - } -} diff --git a/calendar/pcs/job.h b/calendar/pcs/job.h deleted file mode 100644 index 07e3371f89..0000000000 --- a/calendar/pcs/job.h +++ /dev/null @@ -1,35 +0,0 @@ -/* GNOME personal calendar server - job manager - * - * Copyright (C) 2000 Ximian, Inc. - * Copyright (C) 2000 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#ifndef JOB_H -#define JOB_H - -#include <glib.h> - - - -typedef void (* JobFunc) (gpointer data); - -void job_add (JobFunc func, gpointer data); - - - -#endif diff --git a/calendar/pcs/query-backend.c b/calendar/pcs/query-backend.c deleted file mode 100644 index 8bace1023d..0000000000 --- a/calendar/pcs/query-backend.c +++ /dev/null @@ -1,365 +0,0 @@ -/* Evolution calendar - Backend cache for calendar queries. - * - * Copyright (C) 2001 Ximian, Inc. - * - * Author: Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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-i18n.h> -#include <cal-util/cal-component.h> -#include "query.h" -#include "query-backend.h" - -static void query_backend_class_init (QueryBackendClass *klass); -static void query_backend_init (QueryBackend *qb, QueryBackendClass *klass); -static void query_backend_finalize (GObject *object); - -typedef struct { - CalComponent *comp; -} QueryBackendComponent; - -/* Private part of the QueryBackend structure */ -struct _QueryBackendPrivate { - char *uri; - CalBackend *backend; - GHashTable *components; - GList *queries; -}; - -static GHashTable *loaded_backends = NULL; -static GObjectClass *parent_class = NULL; - -/* Class initialization function for the backend cache */ -static void -query_backend_class_init (QueryBackendClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - parent_class = g_type_class_peek_parent (klass); - - object_class->finalize = query_backend_finalize; -} - -/* Object initialization function for the backend cache */ -static void -query_backend_init (QueryBackend *qb, QueryBackendClass *klass) -{ - QueryBackendPrivate *priv; - - priv = g_new0 (QueryBackendPrivate, 1); - qb->priv = priv; - - priv->uri = NULL; - priv->backend = NULL; - priv->components = g_hash_table_new (g_str_hash, g_str_equal); - priv->queries = NULL; -} - -static void -free_hash_comp_cb (gpointer key, gpointer value, gpointer user_data) -{ - g_free (key); - g_object_unref (value); -} - -/* Finalize handler for the backend cache */ -static void -query_backend_finalize (GObject *object) -{ - QueryBackend *qb = (QueryBackend *) object; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_QUERY_BACKEND (qb)); - - /* remove the QueryBackend from the internal hash table */ - g_hash_table_remove (loaded_backends, qb->priv->uri); - if (g_hash_table_size (loaded_backends) == 0) { - g_hash_table_destroy (loaded_backends); - loaded_backends = NULL; - } - - /* free memory */ - qb->priv->backend = NULL; - - g_free (qb->priv->uri); - qb->priv->uri = NULL; - - g_hash_table_foreach (qb->priv->components, (GHFunc) free_hash_comp_cb, NULL); - g_hash_table_destroy (qb->priv->components); - qb->priv->components = NULL; - - g_list_free (qb->priv->queries); - qb->priv->queries = NULL; - - g_free (qb->priv); - qb->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - -/** - * query_backend_get_type: - * @void: - * - * Registers the #QueryBackend class if necessary, and returns the type ID - * associated to it. - * - * Return value: The type ID of the #QueryBackend class. - **/ -GType -query_backend_get_type (void) -{ - static GType type = 0; - - if (!type) { - static GTypeInfo info = { - sizeof (QueryBackendClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) query_backend_class_init, - NULL, NULL, - sizeof (QueryBackend), - 0, - (GInstanceInitFunc) query_backend_init - }; - type = g_type_register_static (G_TYPE_OBJECT, "QueryBackend", &info, 0); - } - - return type; -} - -static void -backend_destroyed_cb (GObject *object, gpointer user_data) -{ - CalBackend *backend = (CalBackend *) object; - QueryBackend *qb = (QueryBackend *) user_data; - - g_return_if_fail (IS_CAL_BACKEND (backend)); - g_return_if_fail (IS_QUERY_BACKEND (qb)); - - g_object_unref (qb); -} - -static void -object_updated_cb (CalBackend *backend, const char *uid, gpointer user_data) -{ - gpointer orig_key, orig_value; - const char *tmp_uid; - CalComponent *comp; - icalcomponent *icalcomp; - char *comp_str; - QueryBackend *qb = (QueryBackend *) user_data; - - g_return_if_fail (IS_QUERY_BACKEND (qb)); - - if (g_hash_table_lookup_extended (qb->priv->components, uid, &orig_key, &orig_value)) { - g_hash_table_remove (qb->priv->components, uid); - g_free (orig_key); - g_object_unref (orig_value); - } - - comp_str = cal_backend_get_object (qb->priv->backend, uid); - if (!comp_str) - return; - - icalcomp = icalparser_parse_string (comp_str); - g_free (comp_str); - if (icalcomp) { - comp = cal_component_new (); - if (!cal_component_set_icalcomponent (comp, icalcomp)) { - icalcomponent_free (icalcomp); - g_object_unref (comp); - return; - } - - cal_component_get_uid (comp, &tmp_uid); - if (!uid || !*uid) { - g_object_unref (comp); - } else - g_hash_table_insert (qb->priv->components, g_strdup (tmp_uid), comp); - } -} - -static void -object_removed_cb (CalBackend *backend, const char *uid, gpointer user_data) -{ - gpointer orig_key, orig_value; - QueryBackend *qb = (QueryBackend *) user_data; - - g_return_if_fail (IS_QUERY_BACKEND (qb)); - - if (g_hash_table_lookup_extended (qb->priv->components, uid, &orig_key, &orig_value)) { - g_hash_table_remove (qb->priv->components, uid); - g_free (orig_key); - g_object_unref (orig_value); - } -} - -static void -query_destroyed_cb (GObject *object, gpointer user_data) -{ - Query *query = (Query *) object; - QueryBackend *qb = (QueryBackend *) user_data; - - g_return_if_fail (IS_QUERY (query)); - g_return_if_fail (IS_QUERY_BACKEND (qb)); - - qb->priv->queries = g_list_remove (qb->priv->queries, query); -} - -static void -foreach_uid_cb (gpointer data, gpointer user_data) -{ - QueryBackend *qb = (QueryBackend *) user_data; - - g_return_if_fail (data != NULL); - g_return_if_fail (IS_QUERY_BACKEND (qb)); - - object_updated_cb (qb->priv->backend, (const char *) data, qb); -} - -/** - * query_backend_new - * @query: The #Query object that issues the query. - * @backend: A #CalBackend object. - * - * Create a new #QueryBackend instance, which is a class to - * have a cache of objects for the calendar queries, so that - * we don't have to ask the calendar backend to get the objects - * everytime. - * - * Returns: the newly-created object. - */ -QueryBackend * -query_backend_new (Query *query, CalBackend *backend) -{ - QueryBackend *qb = NULL; - - g_return_val_if_fail (IS_QUERY (query), NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - - if (!loaded_backends) - loaded_backends = g_hash_table_new (g_str_hash, g_str_equal); - - /* see if we already have the backend loaded */ - qb = g_hash_table_lookup (loaded_backends, - cal_backend_get_uri (backend)); - if (!qb) { - GList *uidlist; - - qb = g_object_new (QUERY_BACKEND_TYPE, NULL); - - qb->priv->uri = g_strdup (cal_backend_get_uri (backend)); - qb->priv->backend = backend; - - /* load all UIDs */ - uidlist = cal_backend_get_uids (backend, CALOBJ_TYPE_ANY); - g_list_foreach (uidlist, foreach_uid_cb, qb); - cal_obj_uid_list_free (uidlist); - - g_signal_connect (G_OBJECT (backend), "destroy", - G_CALLBACK (backend_destroyed_cb), qb); - g_signal_connect (G_OBJECT (backend), "obj_updated", - G_CALLBACK (object_updated_cb), qb); - g_signal_connect (G_OBJECT (backend), "obj_removed", - G_CALLBACK (object_removed_cb), qb); - - g_hash_table_insert (loaded_backends, qb->priv->uri, qb); - } - - qb->priv->queries = g_list_append (qb->priv->queries, query); - g_signal_connect (G_OBJECT (query), "destroy", - G_CALLBACK (query_destroyed_cb), qb); - - return qb; -} - -typedef struct { - GList *uidlist; - CalObjType type; -} GetUidsData; - -static void -uid_hash_cb (gpointer key, gpointer value, gpointer user_data) -{ - CalComponentVType vtype; - char *uid = (char *) key; - CalComponent *comp = (CalComponent *) value; - GetUidsData *uids_data = (GetUidsData *) user_data; - - g_return_if_fail (uid != NULL); - g_return_if_fail (IS_CAL_COMPONENT (comp)); - g_return_if_fail (uids_data != NULL); - - vtype = cal_component_get_vtype (comp); - if (vtype == CAL_COMPONENT_EVENT && uids_data->type == CALOBJ_TYPE_EVENT) - uids_data->uidlist = g_list_append (uids_data->uidlist, g_strdup (uid)); - else if (vtype == CAL_COMPONENT_TODO && uids_data->type == CALOBJ_TYPE_TODO) - uids_data->uidlist = g_list_append (uids_data->uidlist, g_strdup (uid)); - else if (vtype == CAL_COMPONENT_JOURNAL && uids_data->type == CALOBJ_TYPE_JOURNAL) - uids_data->uidlist = g_list_append (uids_data->uidlist, g_strdup (uid)); - else if (uids_data->type == CALOBJ_TYPE_ANY) - uids_data->uidlist = g_list_append (uids_data->uidlist, g_strdup (uid)); -} - -/** - * query_backend_get_uids - * @qb: A #QueryBackend type. - * @type: Type of objects to get the UIDs for. - * - * Get a list of all UIDs for objects of the given type out from - * the specified #QueryBackend object. - * - * Returns: a GList of UIDs, which should be freed, when no longer needed, - * via a call to cal_obj_uid_list_free. - */ -GList * -query_backend_get_uids (QueryBackend *qb, CalObjType type) -{ - GetUidsData uids_data; - - g_return_val_if_fail (IS_QUERY_BACKEND (qb), NULL); - - uids_data.uidlist = NULL; - uids_data.type = type; - g_hash_table_foreach (qb->priv->components, (GHFunc) uid_hash_cb, &uids_data); - - return uids_data.uidlist; -} - -/** - * query_backend_get_object_component - * @qb: A #QueryBackend object. - * @uid: UID of the object to retrieve. - * - * Get a #CalComponent from the given #QueryBackend. - * - * Returns: the component if found, NULL otherwise. - */ -CalComponent * -query_backend_get_object_component (QueryBackend *qb, const char *uid) -{ - g_return_val_if_fail (IS_QUERY_BACKEND (qb), NULL); - g_return_val_if_fail (uid != NULL, NULL); - - return g_hash_table_lookup (qb->priv->components, uid); -} diff --git a/calendar/pcs/query-backend.h b/calendar/pcs/query-backend.h deleted file mode 100644 index a6d9b5d8aa..0000000000 --- a/calendar/pcs/query-backend.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Evolution calendar - Backend cache for calendar queries. - * - * Copyright (C) 2001 Ximian, Inc. - * - * Author: Rodrigo Moya <rodrigo@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#ifndef QUERY_BACKEND_H -#define QUERY_BACKEND_H - -#include "cal-backend.h" -#include "query.h" - -G_BEGIN_DECLS - -#define QUERY_BACKEND_TYPE (query_backend_get_type ()) -#define QUERY_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), QUERY_BACKEND_TYPE, QueryBackend)) -#define QUERY_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), QUERY_BACKEND_TYPE, QueryBackendClass)) -#define IS_QUERY_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), QUERY_BACKEND_TYPE)) -#define IS_QUERY_BACKEND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), QUERY_BACKEND_TYPE)) - -typedef struct _QueryBackendPrivate QueryBackendPrivate; - -typedef struct { - GObject object; - - /* Private data */ - QueryBackendPrivate *priv; -} QueryBackend; - -typedef struct { - GObjectClass parent; -} QueryBackendClass; - -GType query_backend_get_type (void); -QueryBackend *query_backend_new (Query *query, CalBackend *backend); -GList *query_backend_get_uids (QueryBackend *qb, CalObjType type); -CalComponent *query_backend_get_object_component (QueryBackend *qb, const char *uid); - -G_END_DECLS - -#endif diff --git a/calendar/pcs/query.c b/calendar/pcs/query.c deleted file mode 100644 index 4e077245ce..0000000000 --- a/calendar/pcs/query.c +++ /dev/null @@ -1,1733 +0,0 @@ -/* Evolution calendar - Live search query implementation - * - * Copyright (C) 2001 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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 <string.h> -#include <glib.h> -#include <gtk/gtkmain.h> -#include <libgnome/gnome-i18n.h> -#include <bonobo/bonobo-exception.h> -#include <gal/widgets/e-unicode.h> -#include <e-util/e-component-listener.h> -#include <e-util/e-sexp.h> -#include <cal-util/cal-recur.h> -#include <cal-util/timeutil.h> -#include "cal-backend.h" -#include "query.h" -#include "query-backend.h" - - - -typedef struct { - Query *query; - GNOME_Evolution_Calendar_QueryListener ql; - guint tid; -} StartCachedQueryInfo; - -/* States of a query */ -typedef enum { - QUERY_WAIT_FOR_BACKEND, /* the query is not populated and the backend is not loaded */ - QUERY_START_PENDING, /* the query is not populated yet, but the backend is loaded */ - QUERY_IN_PROGRESS, /* the query is populated; components are still being processed */ - QUERY_DONE, /* the query is done, but still accepts object changes */ - QUERY_PARSE_ERROR /* a parse error occurred when initially creating the ESexp */ -} QueryState; - -/* Private part of the Query structure */ -struct _QueryPrivate { - /* The backend we are monitoring */ - CalBackend *backend; - - /* The cache backend */ - QueryBackend *qb; - - /* The default timezone for the calendar. */ - icaltimezone *default_zone; - - /* Listeners to which we report changes in the live query */ - GList *listeners; - GList *component_listeners; - - /* Sexp that defines the query */ - char *sexp; - ESExp *esexp; - - /* Timeout handler ID for asynchronous queries and current state of the query */ - guint timeout_id; - QueryState state; - - GList *cached_timeouts; - - /* List of UIDs that we still have to process */ - GList *pending_uids; - int n_pending; - int pending_total; - - /* Table of the UIDs we know do match the query */ - GHashTable *uids; - - /* The next component that will be handled in e_sexp_eval(); put here - * just because the query object itself is the esexp context. - */ - CalComponent *next_comp; -}; - - - -static void query_class_init (QueryClass *class); -static void query_init (Query *query, QueryClass *class); -static void query_finalize (GObject *object); - -static BonoboObjectClass *parent_class; -static GList *cached_queries = NULL; - - - -BONOBO_TYPE_FUNC_FULL (Query, - GNOME_Evolution_Calendar_Query, - BONOBO_TYPE_OBJECT, - query); - -/* Class initialization function for the live search query */ -static void -query_class_init (QueryClass *class) -{ - GObjectClass *object_class; - - object_class = (GObjectClass *) class; - - parent_class = g_type_class_peek_parent (class); - - object_class->finalize = query_finalize; - - /* The Query interface (ha ha! query interface!) has no methods, so we - * don't need to fiddle with the epv. - */ -} - -/* Object initialization function for the live search query */ -static void -query_init (Query *query, QueryClass *class) -{ - QueryPrivate *priv; - - priv = g_new0 (QueryPrivate, 1); - query->priv = priv; - - priv->backend = NULL; - priv->qb = NULL; - priv->default_zone = NULL; - priv->listeners = NULL; - priv->component_listeners = NULL; - priv->sexp = NULL; - - priv->timeout_id = 0; - priv->state = QUERY_WAIT_FOR_BACKEND; - - priv->cached_timeouts = NULL; - - priv->pending_uids = NULL; - priv->uids = g_hash_table_new (g_str_hash, g_str_equal); - - priv->next_comp = NULL; -} - -/* Used from g_hash_table_foreach(); frees a UID */ -static void -free_uid_cb (gpointer key, gpointer value, gpointer data) -{ - char *uid; - - uid = key; - g_free (uid); -} - -/* Finalize handler for the live search query */ -static void -query_finalize (GObject *object) -{ - Query *query; - QueryPrivate *priv; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_QUERY (object)); - - query = QUERY (object); - priv = query->priv; - - if (priv->backend) { - /* If we are waiting for the backend to be opened, we'll be - * connected to its "opened" signal. If we are in the middle of - * a query or if we are just waiting for object update - * notifications, we'll have the "obj_removed" and "obj_updated" - * connections. Otherwise, we are either in a parse error state - * or waiting for the query to be populated, and in both cases - * we have no signal connections. - */ - if (priv->state == QUERY_WAIT_FOR_BACKEND - || priv->state == QUERY_IN_PROGRESS || priv->state == QUERY_DONE) - g_signal_handlers_disconnect_matched (G_OBJECT (priv->backend), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, query); - - g_object_unref (priv->backend); - priv->backend = NULL; - } - - priv->qb = NULL; - - if (priv->listeners != NULL) { - CORBA_Environment ev; - GList *l; - - CORBA_exception_init (&ev); - for (l = priv->listeners; l != NULL; l = l->next) { - bonobo_object_release_unref (l->data, &ev); - - if (BONOBO_EX (&ev)) - g_message ("query_destroy(): Could not unref the listener\n"); - } - - CORBA_exception_free (&ev); - - g_list_free (priv->listeners); - priv->listeners = NULL; - } - - if (priv->component_listeners != NULL) { - g_list_foreach (priv->component_listeners, (GFunc) g_object_unref, NULL); - g_list_free (priv->component_listeners); - priv->component_listeners = NULL; - } - - if (priv->sexp) { - g_free (priv->sexp); - priv->sexp = NULL; - } - - if (priv->esexp) { - e_sexp_unref (priv->esexp); - priv->esexp = NULL; - } - - if (priv->timeout_id) { - g_source_remove (priv->timeout_id); - priv->timeout_id = 0; - } - - if (priv->cached_timeouts) { - GList *l; - - for (l = priv->cached_timeouts; l != NULL; l = l->next) - g_source_remove (GPOINTER_TO_INT (l->data)); - - g_list_free (priv->cached_timeouts); - priv->cached_timeouts = NULL; - } - - if (priv->pending_uids) { - GList *l; - - for (l = priv->pending_uids; l; l = l->next) { - char *uid; - - uid = l->data; - g_assert (uid != NULL); - g_free (uid); - } - - g_list_free (priv->pending_uids); - priv->pending_uids = NULL; - priv->n_pending = 0; - } - - g_hash_table_foreach (priv->uids, free_uid_cb, NULL); - g_hash_table_destroy (priv->uids); - priv->uids = NULL; - - g_free (priv); - query->priv = NULL; - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); -} - - - -/* E-Sexp functions */ - -/* (time-now) - * - * Returns a time_t of time (NULL). - */ -static ESExpResult * -func_time_now (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - ESExpResult *result; - - if (argc != 0) { - e_sexp_fatal_error (esexp, _("time-now expects 0 arguments")); - return NULL; - } - - result = e_sexp_result_new (esexp, ESEXP_RES_TIME); - result->value.time = time (NULL); - - return result; -} - -/* (make-time ISODATE) - * - * ISODATE - string, ISO 8601 date/time representation - * - * Constructs a time_t value for the specified date. - */ -static ESExpResult * -func_make_time (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - const char *str; - time_t t; - ESExpResult *result; - - if (argc != 1) { - e_sexp_fatal_error (esexp, _("make-time expects 1 argument")); - return NULL; - } - - if (argv[0]->type != ESEXP_RES_STRING) { - e_sexp_fatal_error (esexp, _("make-time expects argument 1 " - "to be a string")); - return NULL; - } - str = argv[0]->value.string; - - t = time_from_isodate (str); - if (t == -1) { - e_sexp_fatal_error (esexp, _("make-time argument 1 must be an " - "ISO 8601 date/time string")); - return NULL; - } - - result = e_sexp_result_new (esexp, ESEXP_RES_TIME); - result->value.time = t; - - return result; -} - -/* (time-add-day TIME N) - * - * TIME - time_t, base time - * N - int, number of days to add - * - * Adds the specified number of days to a time value. - * - * FIXME: TIMEZONES - need to use a timezone or daylight saving changes will - * make the result incorrect. - */ -static ESExpResult * -func_time_add_day (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - ESExpResult *result; - time_t t; - int n; - - if (argc != 2) { - e_sexp_fatal_error (esexp, _("time-add-day expects 2 arguments")); - return NULL; - } - - if (argv[0]->type != ESEXP_RES_TIME) { - e_sexp_fatal_error (esexp, _("time-add-day expects argument 1 " - "to be a time_t")); - return NULL; - } - t = argv[0]->value.time; - - if (argv[1]->type != ESEXP_RES_INT) { - e_sexp_fatal_error (esexp, _("time-add-day expects argument 2 " - "to be an integer")); - return NULL; - } - n = argv[1]->value.number; - - result = e_sexp_result_new (esexp, ESEXP_RES_TIME); - result->value.time = time_add_day (t, n); - - return result; -} - -/* (time-day-begin TIME) - * - * TIME - time_t, base time - * - * Returns the start of the day, according to the local time. - * - * FIXME: TIMEZONES - this uses the current Unix timezone. - */ -static ESExpResult * -func_time_day_begin (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - time_t t; - ESExpResult *result; - - if (argc != 1) { - e_sexp_fatal_error (esexp, _("time-day-begin expects 1 argument")); - return NULL; - } - - if (argv[0]->type != ESEXP_RES_TIME) { - e_sexp_fatal_error (esexp, _("time-day-begin expects argument 1 " - "to be a time_t")); - return NULL; - } - t = argv[0]->value.time; - - result = e_sexp_result_new (esexp, ESEXP_RES_TIME); - result->value.time = time_day_begin (t); - - return result; -} - -/* (time-day-end TIME) - * - * TIME - time_t, base time - * - * Returns the end of the day, according to the local time. - * - * FIXME: TIMEZONES - this uses the current Unix timezone. - */ -static ESExpResult * -func_time_day_end (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - time_t t; - ESExpResult *result; - - if (argc != 1) { - e_sexp_fatal_error (esexp, _("time-day-end expects 1 argument")); - return NULL; - } - - if (argv[0]->type != ESEXP_RES_TIME) { - e_sexp_fatal_error (esexp, _("time-day-end expects argument 1 " - "to be a time_t")); - return NULL; - } - t = argv[0]->value.time; - - result = e_sexp_result_new (esexp, ESEXP_RES_TIME); - result->value.time = time_day_end (t); - - return result; -} - -/* (get-vtype) - * - * Returns a string indicating the type of component (VEVENT, VTODO, VJOURNAL, - * VFREEBUSY, VTIMEZONE, UNKNOWN). - */ -static ESExpResult * -func_get_vtype (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - Query *query; - QueryPrivate *priv; - CalComponent *comp; - CalComponentVType vtype; - char *str; - ESExpResult *result; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->next_comp != NULL); - comp = priv->next_comp; - - /* Check argument types */ - - if (argc != 0) { - e_sexp_fatal_error (esexp, _("get-vtype expects 0 arguments")); - return NULL; - } - - /* Get the type */ - - vtype = cal_component_get_vtype (comp); - - switch (vtype) { - case CAL_COMPONENT_EVENT: - str = g_strdup ("VEVENT"); - break; - - case CAL_COMPONENT_TODO: - str = g_strdup ("VTODO"); - break; - - case CAL_COMPONENT_JOURNAL: - str = g_strdup ("VJOURNAL"); - break; - - case CAL_COMPONENT_FREEBUSY: - str = g_strdup ("VFREEBUSY"); - break; - - case CAL_COMPONENT_TIMEZONE: - str = g_strdup ("VTIMEZONE"); - break; - - default: - str = g_strdup ("UNKNOWN"); - break; - } - - result = e_sexp_result_new (esexp, ESEXP_RES_STRING); - result->value.string = str; - - return result; -} - -/* Sets a boolean value in the data to TRUE; called from - * cal_recur_generate_instances() to indicate that at least one instance occurs - * in the sought time range. We always return FALSE because we want the - * recurrence engine to finish as soon as possible. - */ -static gboolean -instance_occur_cb (CalComponent *comp, time_t start, time_t end, gpointer data) -{ - gboolean *occurs; - - occurs = data; - *occurs = TRUE; - - return FALSE; -} - -/* Call the backend function to get a timezone from a TZID. */ -static icaltimezone* -resolve_tzid (const char *tzid, gpointer data) -{ - Query *query = data; - - if (!tzid || !tzid[0]) - return NULL; - else - return cal_backend_get_timezone (query->priv->backend, tzid); -} - - -/* (occur-in-time-range? START END) - * - * START - time_t, start of the time range - * END - time_t, end of the time range - * - * Returns a boolean indicating whether the component has any occurrences in the - * specified time range. - */ -static ESExpResult * -func_occur_in_time_range (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - Query *query; - QueryPrivate *priv; - CalComponent *comp; - time_t start, end; - gboolean occurs; - ESExpResult *result; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->next_comp != NULL); - comp = priv->next_comp; - - /* Check argument types */ - - if (argc != 2) { - e_sexp_fatal_error (esexp, _("occur-in-time-range? expects 2 arguments")); - return NULL; - } - - if (argv[0]->type != ESEXP_RES_TIME) { - e_sexp_fatal_error (esexp, _("occur-in-time-range? expects argument 1 " - "to be a time_t")); - return NULL; - } - start = argv[0]->value.time; - - if (argv[1]->type != ESEXP_RES_TIME) { - e_sexp_fatal_error (esexp, _("occur-in-time-range? expects argument 2 " - "to be a time_t")); - return NULL; - } - end = argv[1]->value.time; - - /* See if there is at least one instance in that range */ - - occurs = FALSE; - - cal_recur_generate_instances (comp, start, end, - instance_occur_cb, &occurs, - resolve_tzid, query, priv->default_zone); - - result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); - result->value.bool = occurs; - - return result; -} - -/* Returns whether a list of CalComponentText items matches the specified string */ -static gboolean -matches_text_list (GSList *text_list, const char *str) -{ - GSList *l; - gboolean matches; - - matches = FALSE; - - for (l = text_list; l; l = l->next) { - CalComponentText *text; - - text = l->data; - g_assert (text->value != NULL); - - if (e_utf8_strstrcasedecomp (text->value, str) != NULL) { - matches = TRUE; - break; - } - } - - return matches; -} - -/* Returns whether the comments in a component matches the specified string */ -static gboolean -matches_comment (CalComponent *comp, const char *str) -{ - GSList *list; - gboolean matches; - - cal_component_get_comment_list (comp, &list); - matches = matches_text_list (list, str); - cal_component_free_text_list (list); - - return matches; -} - -/* Returns whether the description in a component matches the specified string */ -static gboolean -matches_description (CalComponent *comp, const char *str) -{ - GSList *list; - gboolean matches; - - cal_component_get_description_list (comp, &list); - matches = matches_text_list (list, str); - cal_component_free_text_list (list); - - return matches; -} - -/* Returns whether the summary in a component matches the specified string */ -static gboolean -matches_summary (CalComponent *comp, const char *str) -{ - CalComponentText text; - - cal_component_get_summary (comp, &text); - - if (!text.value) - return FALSE; - - return e_utf8_strstrcasedecomp (text.value, str) != NULL; -} - -/* Returns whether any text field in a component matches the specified string */ -static gboolean -matches_any (CalComponent *comp, const char *str) -{ - /* As an optimization, and to make life easier for the individual - * predicate functions, see if we are looking for the empty string right - * away. - */ - if (strlen (str) == 0) - return TRUE; - - return (matches_comment (comp, str) - || matches_description (comp, str) - || matches_summary (comp, str)); -} - -/* (contains? FIELD STR) - * - * FIELD - string, name of field to match (any, comment, description, summary) - * STR - string, match string - * - * Returns a boolean indicating whether the specified field contains the - * specified string. - */ -static ESExpResult * -func_contains (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - Query *query; - QueryPrivate *priv; - CalComponent *comp; - const char *field; - const char *str; - gboolean matches; - ESExpResult *result; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->next_comp != NULL); - comp = priv->next_comp; - - /* Check argument types */ - - if (argc != 2) { - e_sexp_fatal_error (esexp, _("contains? expects 2 arguments")); - return NULL; - } - - if (argv[0]->type != ESEXP_RES_STRING) { - e_sexp_fatal_error (esexp, _("contains? expects argument 1 " - "to be a string")); - return NULL; - } - field = argv[0]->value.string; - - if (argv[1]->type != ESEXP_RES_STRING) { - e_sexp_fatal_error (esexp, _("contains? expects argument 2 " - "to be a string")); - return NULL; - } - str = argv[1]->value.string; - - /* See if it matches */ - - if (strcmp (field, "any") == 0) - matches = matches_any (comp, str); - else if (strcmp (field, "comment") == 0) - matches = matches_comment (comp, str); - else if (strcmp (field, "description") == 0) - matches = matches_description (comp, str); - else if (strcmp (field, "summary") == 0) - matches = matches_summary (comp, str); - else { - e_sexp_fatal_error (esexp, _("contains? expects argument 1 to " - "be one of \"any\", \"summary\", \"description\"")); - return NULL; - } - - result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); - result->value.bool = matches; - - return result; -} - -/* (has-categories? STR+) - * (has-categories? #f) - * - * STR - At least one string specifying a category - * Or you can specify a single #f (boolean false) value for components - * that have no categories assigned to them ("unfiled"). - * - * Returns a boolean indicating whether the component has all the specified - * categories. - */ -static ESExpResult * -func_has_categories (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - Query *query; - QueryPrivate *priv; - CalComponent *comp; - gboolean unfiled; - int i; - GSList *categories; - gboolean matches; - ESExpResult *result; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->next_comp != NULL); - comp = priv->next_comp; - - /* Check argument types */ - - if (argc < 1) { - e_sexp_fatal_error (esexp, _("has-categories? expects at least 1 argument")); - return NULL; - } - - if (argc == 1 && argv[0]->type == ESEXP_RES_BOOL) - unfiled = TRUE; - else - unfiled = FALSE; - - if (!unfiled) - for (i = 0; i < argc; i++) - if (argv[i]->type != ESEXP_RES_STRING) { - e_sexp_fatal_error (esexp, _("has-categories? expects all arguments " - "to be strings or one and only one " - "argument to be a boolean false (#f)")); - return NULL; - } - - /* Search categories. First, if there are no categories we return - * whether unfiled components are supposed to match. - */ - - cal_component_get_categories_list (comp, &categories); - if (!categories) { - result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); - result->value.bool = unfiled; - - return result; - } - - /* Otherwise, we *do* have categories but unfiled components were - * requested, so this component does not match. - */ - if (unfiled) { - result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); - result->value.bool = FALSE; - - return result; - } - - matches = TRUE; - - for (i = 0; i < argc; i++) { - const char *sought; - GSList *l; - gboolean has_category; - - sought = argv[i]->value.string; - - has_category = FALSE; - - for (l = categories; l; l = l->next) { - const char *category; - - category = l->data; - - if (strcmp (category, sought) == 0) { - has_category = TRUE; - break; - } - } - - if (!has_category) { - matches = FALSE; - break; - } - } - - cal_component_free_categories_list (categories); - - result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); - result->value.bool = matches; - - return result; -} - -/* (is-completed?) - * - * Returns a boolean indicating whether the component is completed (i.e. has - * a COMPLETED property. This is really only useful for TODO components. - */ -static ESExpResult * -func_is_completed (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - Query *query; - QueryPrivate *priv; - CalComponent *comp; - ESExpResult *result; - struct icaltimetype *t; - gboolean complete = FALSE; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->next_comp != NULL); - comp = priv->next_comp; - - /* Check argument types */ - - if (argc != 0) { - e_sexp_fatal_error (esexp, _("is-completed? expects 0 arguments")); - return NULL; - } - - cal_component_get_completed (comp, &t); - if (t) { - complete = TRUE; - cal_component_free_icaltimetype (t); - } - - result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); - result->value.bool = complete; - - return result; -} - -/* (completed-before? TIME) - * - * TIME - time_t - * - * Returns a boolean indicating whether the component was completed on or - * before the given time (i.e. it checks the COMPLETED property). - * This is really only useful for TODO components. - */ -static ESExpResult * -func_completed_before (ESExp *esexp, int argc, ESExpResult **argv, void *data) -{ - Query *query; - QueryPrivate *priv; - CalComponent *comp; - ESExpResult *result; - struct icaltimetype *tt; - icaltimezone *zone; - gboolean retval = FALSE; - time_t before_time, completed_time; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->next_comp != NULL); - comp = priv->next_comp; - - /* Check argument types */ - - if (argc != 1) { - e_sexp_fatal_error (esexp, _("completed-before? expects 1 argument")); - return NULL; - } - - if (argv[0]->type != ESEXP_RES_TIME) { - e_sexp_fatal_error (esexp, _("completed-before? expects argument 1 " - "to be a time_t")); - return NULL; - } - before_time = argv[0]->value.time; - - cal_component_get_completed (comp, &tt); - if (tt) { - /* COMPLETED must be in UTC. */ - zone = icaltimezone_get_utc_timezone (); - completed_time = icaltime_as_timet_with_zone (*tt, zone); - -#if 0 - g_print ("Query Time : %s", ctime (&before_time)); - g_print ("Completed Time: %s", ctime (&completed_time)); -#endif - - /* We want to return TRUE if before_time is after - completed_time. */ - if (difftime (before_time, completed_time) > 0) { -#if 0 - g_print (" Returning TRUE\n"); -#endif - retval = TRUE; - } - - cal_component_free_icaltimetype (tt); - } - - result = e_sexp_result_new (esexp, ESEXP_RES_BOOL); - result->value.bool = retval; - - return result; -} - - - -/* Adds a component to our the UIDs hash table and notifies the client */ -static void -add_component (Query *query, const char *uid, gboolean query_in_progress, int n_scanned, int total) -{ - QueryPrivate *priv; - char *old_uid; - CORBA_Environment ev; - GList *l; - - if (query_in_progress) - g_assert (n_scanned > 0 || n_scanned <= total); - - priv = query->priv; - - if (g_hash_table_lookup_extended (priv->uids, uid, (gpointer *) &old_uid, NULL)) { - g_hash_table_remove (priv->uids, old_uid); - g_free (old_uid); - } - - g_hash_table_insert (priv->uids, g_strdup (uid), NULL); - - CORBA_exception_init (&ev); - for (l = priv->listeners; l != NULL; l = l->next) { - GNOME_Evolution_Calendar_CalObjUIDSeq *corba_uids; - - corba_uids = GNOME_Evolution_Calendar_CalObjUIDSeq__alloc (); - CORBA_sequence_set_release (corba_uids, TRUE); - corba_uids->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalObjUID_allocbuf (1); - corba_uids->_length = 1; - corba_uids->_buffer[0] = CORBA_string_dup (uid); - - GNOME_Evolution_Calendar_QueryListener_notifyObjUpdated ( - l->data, - corba_uids, - query_in_progress, - n_scanned, - total, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("add_component(): Could not notify the listener of an " - "updated component"); - - CORBA_free (corba_uids); - } - - CORBA_exception_free (&ev); -} - -/* Removes a component from our the UIDs hash table and notifies the client */ -static void -remove_component (Query *query, const char *uid) -{ - QueryPrivate *priv; - char *old_uid; - CORBA_Environment ev; - GList *l; - - priv = query->priv; - - if (!g_hash_table_lookup_extended (priv->uids, uid, (gpointer *) &old_uid, NULL)) - return; - - /* The component did match the query before but it no longer does, so we - * have to notify the client. - */ - - g_hash_table_remove (priv->uids, old_uid); - g_free (old_uid); - - CORBA_exception_init (&ev); - for (l = priv->listeners; l != NULL; l = l->next) { - GNOME_Evolution_Calendar_QueryListener_notifyObjRemoved ( - l->data, - (char *) uid, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("remove_component(): Could not notify the listener of a " - "removed component"); - } - - CORBA_exception_free (&ev); -} - -/* Removes a component from the list of pending UIDs */ -static void -remove_from_pending (Query *query, const char *remove_uid) -{ - QueryPrivate *priv; - GList *l; - - priv = query->priv; - - for (l = priv->pending_uids; l; l = l->next) { - char *uid; - - g_assert (priv->n_pending > 0); - - uid = l->data; - if (strcmp (remove_uid, uid)) - continue; - - g_free (uid); - - priv->pending_uids = g_list_remove_link (priv->pending_uids, l); - g_list_free_1 (l); - priv->n_pending--; - - g_assert ((priv->pending_uids && priv->n_pending != 0) - || (!priv->pending_uids && priv->n_pending == 0)); - - break; - } -} - -static struct { - char *name; - ESExpFunc *func; -} functions[] = { - /* Time-related functions */ - { "time-now", func_time_now }, - { "make-time", func_make_time }, - { "time-add-day", func_time_add_day }, - { "time-day-begin", func_time_day_begin }, - { "time-day-end", func_time_day_end }, - - /* Component-related functions */ - { "get-vtype", func_get_vtype }, - { "occur-in-time-range?", func_occur_in_time_range }, - { "contains?", func_contains }, - { "has-categories?", func_has_categories }, - { "is-completed?", func_is_completed }, - { "completed-before?", func_completed_before } -}; - -/* Initializes a sexp by interning our own symbols */ -static ESExp * -create_sexp (Query *query) -{ - ESExp *esexp; - int i; - - esexp = e_sexp_new (); - - for (i = 0; i < (sizeof (functions) / sizeof (functions[0])); i++) - e_sexp_add_function (esexp, 0, functions[i].name, functions[i].func, query); - - return esexp; -} - -/* Creates the ESexp and parses the esexp. If a parse error occurs, it sets the - * query state to QUERY_PARSE_ERROR and returns FALSE. - */ -static gboolean -parse_sexp (Query *query) -{ - QueryPrivate *priv; - - priv = query->priv; - - /* Compile the query string */ - - priv->esexp = create_sexp (query); - - g_assert (priv->sexp != NULL); - e_sexp_input_text (priv->esexp, priv->sexp, strlen (priv->sexp)); - - if (e_sexp_parse (priv->esexp) == -1) { - const char *error_str; - CORBA_Environment ev; - GList *l; - - priv->state = QUERY_PARSE_ERROR; - - /* Report the error to the listeners */ - - error_str = e_sexp_error (priv->esexp); - g_assert (error_str != NULL); - - CORBA_exception_init (&ev); - for (l = priv->listeners; l != NULL; l = l->next) { - GNOME_Evolution_Calendar_QueryListener_notifyQueryDone ( - l->data, - GNOME_Evolution_Calendar_QueryListener_PARSE_ERROR, - error_str, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("parse_sexp(): Could not notify the listener of " - "a parse error"); - } - - CORBA_exception_free (&ev); - - e_sexp_unref (priv->esexp); - priv->esexp = NULL; - - /* remove the query from the list of cached queries */ - cached_queries = g_list_remove (cached_queries, query); - bonobo_object_unref (BONOBO_OBJECT (query)); - - return FALSE; - } - - return TRUE; -} - -/* Evaluates the query sexp on the specified component and notifies the listener - * as appropriate. - */ -static void -match_component (Query *query, const char *uid, - gboolean query_in_progress, int n_scanned, int total) -{ - QueryPrivate *priv; - CalComponent *comp; - ESExpResult *result; - - priv = query->priv; - - g_assert (priv->state == QUERY_IN_PROGRESS || priv->state == QUERY_DONE); - g_assert (priv->esexp != NULL); - - comp = query_backend_get_object_component (priv->qb, uid); - if (!comp) - return; - - /* Eval the sexp */ - - g_assert (priv->next_comp == NULL); - - priv->next_comp = comp; - result = e_sexp_eval (priv->esexp); - priv->next_comp = NULL; - - if (!result) { - const char *error_str; - CORBA_Environment ev; - GList *l; - - error_str = e_sexp_error (priv->esexp); - g_assert (error_str != NULL); - - CORBA_exception_init (&ev); - for (l = priv->listeners; l != NULL; l = l->next) { - GNOME_Evolution_Calendar_QueryListener_notifyEvalError ( - l->data, - error_str, - &ev); - - if (BONOBO_EX (&ev)) - g_message ("match_component(): Could not notify the listener of " - "an evaluation error"); - } - - CORBA_exception_free (&ev); - return; - } else if (result->type != ESEXP_RES_BOOL) { - CORBA_Environment ev; - GList *l; - - CORBA_exception_init (&ev); - for (l = priv->listeners; l != NULL; l = l->next) { - GNOME_Evolution_Calendar_QueryListener_notifyEvalError ( - l->data, - _("Evaluation of the search expression did not yield a boolean value"), - &ev); - - if (BONOBO_EX (&ev)) - g_message ("match_component(): Could not notify the listener of " - "an unexpected result value type when evaluating the " - "search expression"); - } - - CORBA_exception_free (&ev); - } else { - /* Success; process the component accordingly */ - - if (result->value.bool) - add_component (query, uid, query_in_progress, n_scanned, total); - else - remove_component (query, uid); - } - - e_sexp_result_free (priv->esexp, result); -} - -/* Processes all components that are queued in the list */ -static gboolean -process_components_cb (gpointer data) -{ - Query *query; - QueryPrivate *priv; - char *uid; - GList *l; - CORBA_Environment ev; - - query = QUERY (data); - priv = query->priv; - - g_source_remove (priv->timeout_id); - priv->timeout_id = 0; - - bonobo_object_ref (BONOBO_OBJECT (query)); - - while (priv->pending_uids) { - g_assert (priv->n_pending > 0); - - /* Fetch the component */ - - l = priv->pending_uids; - priv->pending_uids = g_list_remove_link (priv->pending_uids, l); - priv->n_pending--; - - g_assert ((priv->pending_uids && priv->n_pending != 0) - || (!priv->pending_uids && priv->n_pending == 0)); - - uid = l->data; - g_assert (uid != NULL); - - g_list_free_1 (l); - - match_component (query, uid, - TRUE, - priv->pending_total - priv->n_pending, - priv->pending_total); - - g_free (uid); - - /* run the main loop, for not blocking */ - if (gtk_events_pending ()) - gtk_main_iteration (); - } - - bonobo_object_unref (BONOBO_OBJECT (query)); - if (!priv || !priv->listeners) - return FALSE; - - /* notify listeners that the query ended */ - priv->state = QUERY_DONE; - - CORBA_exception_init (&ev); - for (l = priv->listeners; l != NULL; l = l->next) { - GNOME_Evolution_Calendar_QueryListener_notifyQueryDone ( - l->data, - GNOME_Evolution_Calendar_QueryListener_SUCCESS, - "", - &ev); - - if (BONOBO_EX (&ev)) - g_message ("start_query(): Could not notify the listener of " - "a finished query"); - } - - CORBA_exception_free (&ev); - - return FALSE; -} - -/* Callback used when a component changes in the backend */ -static void -backend_obj_updated_cb (CalBackend *backend, const char *uid, gpointer data) -{ - Query *query; - QueryPrivate *priv; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->state == QUERY_IN_PROGRESS || priv->state == QUERY_DONE); - - bonobo_object_ref (BONOBO_OBJECT (query)); - - match_component (query, uid, FALSE, 0, 0); - remove_from_pending (query, uid); - - bonobo_object_unref (BONOBO_OBJECT (query)); -} - -/* Callback used when a component is removed from the backend */ -static void -backend_obj_removed_cb (CalBackend *backend, const char *uid, gpointer data) -{ - Query *query; - QueryPrivate *priv; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->state == QUERY_IN_PROGRESS || priv->state == QUERY_DONE); - - bonobo_object_ref (BONOBO_OBJECT (query)); - - remove_component (query, uid); - remove_from_pending (query, uid); - - bonobo_object_unref (BONOBO_OBJECT (query)); -} - -/* Actually starts the query */ -static void -start_query (Query *query) -{ - QueryPrivate *priv; - - priv = query->priv; - - if (!parse_sexp (query)) - return; - - /* Populate the query with UIDs so that we can process them asynchronously */ - - priv->state = QUERY_IN_PROGRESS; - priv->pending_uids = query_backend_get_uids (priv->qb, CALOBJ_TYPE_ANY); - priv->pending_total = g_list_length (priv->pending_uids); - priv->n_pending = priv->pending_total; - - g_signal_connect (G_OBJECT (priv->backend), "obj_updated", - G_CALLBACK (backend_obj_updated_cb), - query); - g_signal_connect (G_OBJECT (priv->backend), "obj_removed", - G_CALLBACK (backend_obj_removed_cb), - query); - - priv->timeout_id = g_timeout_add (100, (GSourceFunc) process_components_cb, query); -} - -/* Idle handler for starting a query */ -static gboolean -start_query_cb (gpointer data) -{ - Query *query; - QueryPrivate *priv; - - query = QUERY (data); - priv = query->priv; - - g_source_remove (priv->timeout_id); - priv->timeout_id = 0; - - if (priv->state == QUERY_START_PENDING) { - priv->state = QUERY_IN_PROGRESS; - start_query (query); - } - - return FALSE; -} - -static void -listener_died_cb (EComponentListener *cl, gpointer data) -{ - QueryPrivate *priv; - Query *query = QUERY (data); - GNOME_Evolution_Calendar_QueryListener ql; - CORBA_Environment ev; - - priv = query->priv; - - ql = e_component_listener_get_component (cl); - priv->listeners = g_list_remove (priv->listeners, ql); - - priv->component_listeners = g_list_remove (priv->component_listeners, cl); - g_object_unref (cl); - - CORBA_exception_init (&ev); - bonobo_object_release_unref (ql, &ev); - - if (BONOBO_EX (&ev)) - g_message ("query_destroy(): Could not unref the listener\n"); - - CORBA_exception_free (&ev); -} - -static void -add_uid_cb (gpointer key, gpointer value, gpointer data) -{ - char *uid = (char *) key; - GList **uidlist = (GList **) data; - - *uidlist = g_list_append (*uidlist, uid); -} - -/* Idle handler for starting a cached query */ -static gboolean -start_cached_query_cb (gpointer data) -{ - CORBA_Environment ev; - QueryPrivate *priv; - EComponentListener *cl; - StartCachedQueryInfo *info = (StartCachedQueryInfo *) data; - - priv = info->query->priv; - - g_source_remove (info->tid); - priv->cached_timeouts = g_list_remove (priv->cached_timeouts, - GINT_TO_POINTER (info->tid)); - - /* if the query hasn't started yet, we add the listener */ - if (priv->state == QUERY_START_PENDING || - priv->state == QUERY_WAIT_FOR_BACKEND) { - priv->listeners = g_list_append (priv->listeners, info->ql); - - cl = e_component_listener_new (info->ql, 0); - priv->component_listeners = g_list_append (priv->component_listeners, cl); - g_signal_connect (G_OBJECT (cl), "component_died", - G_CALLBACK (listener_died_cb), info->query); - } else if (priv->state == QUERY_IN_PROGRESS) { - /* if it's in progress, we re-add the timeout */ - info->tid = g_timeout_add (100, (GSourceFunc) start_cached_query_cb, info); - priv->cached_timeouts = g_list_append (priv->cached_timeouts, - GINT_TO_POINTER (info->tid)); - - return FALSE; - } else if (priv->state == QUERY_PARSE_ERROR) { - /* notify listener of error */ - CORBA_exception_init (&ev); - GNOME_Evolution_Calendar_QueryListener_notifyQueryDone ( - info->ql, - GNOME_Evolution_Calendar_QueryListener_PARSE_ERROR, - _("Parse error"), - &ev); - - if (BONOBO_EX (&ev)) - g_message ("start_cached_query_cb(): Could not notify the listener of " - "a parse error"); - - CORBA_exception_free (&ev); - - /* remove all traces of this query */ - cached_queries = g_list_remove (cached_queries, info->query); - bonobo_object_unref (BONOBO_OBJECT (info->query)); - } else if (priv->state == QUERY_DONE) { - int len; - GList *uid_list = NULL, *l; - - CORBA_exception_init (&ev); - - /* if the query is done, then we just notify the listener of all the - * UIDS we've got so far, all at once */ - g_hash_table_foreach (priv->uids, (GHFunc) add_uid_cb, &uid_list); - - len = g_list_length (uid_list); - if (len > 0) { - int n; - GNOME_Evolution_Calendar_CalObjUIDSeq *corba_uids; - - corba_uids = GNOME_Evolution_Calendar_CalObjUIDSeq__alloc (); - corba_uids->_length = len; - corba_uids->_maximum = len; - corba_uids->_buffer = CORBA_sequence_GNOME_Evolution_Calendar_CalObjUID_allocbuf (len); - CORBA_sequence_set_release (corba_uids, TRUE); - - for (l = uid_list, n = 0; l != NULL; l = l->next, n++) - corba_uids->_buffer[n] = CORBA_string_dup ((CORBA_char *) l->data); - - GNOME_Evolution_Calendar_QueryListener_notifyObjUpdated ( - info->ql, - corba_uids, - TRUE, - len, - len, &ev); - - if (BONOBO_EX (&ev)) - g_message ("start_cached_query_cb(): Could not notify the listener of all " - "cached components"); - - CORBA_free (corba_uids); - g_list_free (uid_list); - } - - /* setup private data and notify listener that the query ended */ - priv->listeners = g_list_append (priv->listeners, info->ql); - - cl = e_component_listener_new (info->ql, 0); - priv->component_listeners = g_list_append (priv->component_listeners, cl); - g_signal_connect (G_OBJECT (cl), "component_died", - G_CALLBACK (listener_died_cb), info->query); - - GNOME_Evolution_Calendar_QueryListener_notifyQueryDone ( - info->ql, - GNOME_Evolution_Calendar_QueryListener_SUCCESS, - "", - &ev); - if (BONOBO_EX (&ev)) - g_message ("start_cached_query_cb(): Could not notify the listener of " - "a finished query"); - - CORBA_exception_free (&ev); - } - - g_free (info); - - return FALSE; -} - -/* Callback used when the backend gets loaded; we just queue the query to be - * started later. - */ -static void -backend_opened_cb (CalBackend *backend, CalBackendOpenStatus status, gpointer data) -{ - Query *query; - QueryPrivate *priv; - - query = QUERY (data); - priv = query->priv; - - g_assert (priv->state == QUERY_WAIT_FOR_BACKEND); - - g_signal_handlers_disconnect_matched (G_OBJECT (priv->backend), - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, query); - priv->state = QUERY_START_PENDING; - - if (status == CAL_BACKEND_OPEN_SUCCESS) { - g_assert (cal_backend_is_loaded (backend)); - - priv->timeout_id = g_timeout_add (100, (GSourceFunc) start_query_cb, query); - } -} - -/* Callback used when the backend for a cached query is destroyed */ -static void -backend_destroyed_cb (GObject *object, gpointer data) -{ - Query *query; - - query = QUERY (data); - - cached_queries = g_list_remove (cached_queries, query); - bonobo_object_unref (BONOBO_OBJECT (query)); -} - -/** - * query_construct: - * @query: A live search query. - * @backend: Calendar backend that the query object will monitor. - * @ql: Listener for query results. - * @sexp: Sexp that defines the query. - * - * Constructs a #Query object by binding it to a calendar backend and a query - * listener. The @query object will start to populate itself asynchronously and - * call the listener as appropriate. - * - * Return value: The same value as @query, or NULL if the query could not - * be constructed. - **/ -Query * -query_construct (Query *query, - CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp) -{ - QueryPrivate *priv; - CORBA_Environment ev; - EComponentListener *cl; - - g_return_val_if_fail (query != NULL, NULL); - g_return_val_if_fail (IS_QUERY (query), NULL); - g_return_val_if_fail (backend != NULL, NULL); - g_return_val_if_fail (IS_CAL_BACKEND (backend), NULL); - g_return_val_if_fail (ql != CORBA_OBJECT_NIL, NULL); - g_return_val_if_fail (sexp != NULL, NULL); - - priv = query->priv; - - CORBA_exception_init (&ev); - priv->listeners = g_list_append (NULL, CORBA_Object_duplicate (ql, &ev)); - if (BONOBO_EX (&ev)) { - g_message ("query_construct(): Could not duplicate the listener"); - priv->listeners = NULL; - CORBA_exception_free (&ev); - return NULL; - } - CORBA_exception_free (&ev); - - cl = e_component_listener_new (ql, 0); - priv->component_listeners = g_list_append (priv->component_listeners, cl); - g_signal_connect (G_OBJECT (cl), "component_died", - G_CALLBACK (listener_died_cb), query); - - priv->backend = backend; - g_object_ref (priv->backend); - - priv->qb = query_backend_new (query, backend); - priv->default_zone = cal_backend_get_default_timezone (backend); - - priv->sexp = g_strdup (sexp); - - /* Queue the query to be started asynchronously */ - - if (cal_backend_is_loaded (priv->backend)) { - priv->state = QUERY_START_PENDING; - - priv->timeout_id = g_timeout_add (100, (GSourceFunc) start_query_cb, query); - } else - g_signal_connect (G_OBJECT (priv->backend), "opened", - G_CALLBACK (backend_opened_cb), - query); - - return query; -} - -/** - * query_new: - * @backend: Calendar backend that the query object will monitor. - * @ql: Listener for query results. - * @sexp: Sexp that defines the query. - * - * Creates a new query engine object that monitors a calendar backend. - * - * Return value: A newly-created query object, or NULL on failure. - **/ -Query * -query_new (CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp) -{ - Query *query; - GList *l; - - /* first, see if we've got this query in our cache */ - for (l = cached_queries; l != NULL; l = l->next) { - query = QUERY (l->data); - - g_assert (query != NULL); - - if (query->priv->backend == backend && - !strcmp (query->priv->sexp, sexp)) { - StartCachedQueryInfo *info; - CORBA_Environment ev; - - info = g_new0 (StartCachedQueryInfo, 1); - info->query = query; - - CORBA_exception_init (&ev); - info->ql = CORBA_Object_duplicate (ql, &ev); - if (BONOBO_EX (&ev)) { - g_message ("query_new(): Could not duplicate listener object"); - g_free (info); - - return NULL; - } - CORBA_exception_free (&ev); - - info->tid = g_timeout_add (100, (GSourceFunc) start_cached_query_cb, info); - query->priv->cached_timeouts = g_list_append (query->priv->cached_timeouts, - GINT_TO_POINTER (info->tid)); - - bonobo_object_ref (BONOBO_OBJECT (query)); - return query; - } - } - - /* not found, so create a new one */ - query = QUERY (g_object_new (QUERY_TYPE, NULL)); - if (!query_construct (query, backend, ql, sexp)) { - bonobo_object_unref (BONOBO_OBJECT (query)); - return NULL; - } - - /* add the new query to our cache */ - g_signal_connect (G_OBJECT (query->priv->backend), "destroy", - G_CALLBACK (backend_destroyed_cb), query); - - bonobo_object_ref (BONOBO_OBJECT (query)); - cached_queries = g_list_append (cached_queries, query); - - return query; -} diff --git a/calendar/pcs/query.h b/calendar/pcs/query.h deleted file mode 100644 index 752c29eb40..0000000000 --- a/calendar/pcs/query.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Evolution calendar - Live search query implementation - * - * Copyright (C) 2001 Ximian, Inc. - * - * Author: Federico Mena-Quintero <federico@ximian.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 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. - */ - -#ifndef QUERY_H -#define QUERY_H - -#include <bonobo/bonobo-object.h> -#include "pcs/cal-common.h" -#include "pcs/evolution-calendar.h" - -G_BEGIN_DECLS - - - -#define QUERY_TYPE (query_get_type ()) -#define QUERY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), QUERY_TYPE, Query)) -#define QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), QUERY_TYPE, QueryClass)) -#define IS_QUERY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), QUERY_TYPE)) -#define IS_QUERY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), QUERY_TYPE)) - -typedef struct _QueryPrivate QueryPrivate; - -typedef struct { - BonoboObject xobject; - - /* Private data */ - QueryPrivate *priv; -} Query; - -typedef struct { - BonoboObjectClass parent_class; - - POA_GNOME_Evolution_Calendar_Query__epv epv; -} QueryClass; - -GType query_get_type (void); - -Query *query_construct (Query *query, - CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp); - -Query *query_new (CalBackend *backend, - GNOME_Evolution_Calendar_QueryListener ql, - const char *sexp); - - - -G_END_DECLS - -#endif |