diff options
Diffstat (limited to 'calendar/pcs/cal-backend.c')
-rw-r--r-- | calendar/pcs/cal-backend.c | 501 |
1 files changed, 101 insertions, 400 deletions
diff --git a/calendar/pcs/cal-backend.c b/calendar/pcs/cal-backend.c index 765d873f79..e074f09bc2 100644 --- a/calendar/pcs/cal-backend.c +++ b/calendar/pcs/cal-backend.c @@ -23,38 +23,17 @@ */ #include <config.h> -#include <libxml/parser.h> -#include <libxml/parserInternals.h> -#include <libxml/xmlmemory.h> +#include <gtk/gtkobject.h> +#include <gtk/gtksignal.h> +#include <gnome-xml/parser.h> +#include <gnome-xml/parserInternals.h> +#include <gnome-xml/xmlmemory.h> #include "cal-backend.h" #include "libversit/vcc.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; -} CalBackendCategory; - -/* Private part of the CalBackend structure */ -struct _CalBackendPrivate { - /* List of Cal objects with their listeners */ - GList *clients; - - /* Hash table of live categories, temporary hash of - * added/removed categories, and idle handler for sending - * category_changed. - */ - GHashTable *categories; - GHashTable *changed_categories; - guint category_idle_id; -}; - /* Signal IDs */ enum { LAST_CLIENT_GONE, @@ -64,19 +43,12 @@ enum { OBJ_REMOVED, LAST_SIGNAL }; -static guint cal_backend_signals[LAST_SIGNAL]; static void cal_backend_class_init (CalBackendClass *class); -static void cal_backend_init (CalBackend *backend); -static void cal_backend_finalize (GObject *object); - -static char *get_object (CalBackend *backend, const char *uid); - -static void notify_categories_changed (CalBackend *backend); -#define CLASS(backend) (CAL_BACKEND_CLASS (G_OBJECT_GET_CLASS (backend))) +static guint cal_backend_signals[LAST_SIGNAL]; -static GObjectClass *parent_class; +#define CLASS(backend) (CAL_BACKEND_CLASS (GTK_OBJECT (backend)->klass)) @@ -89,23 +61,25 @@ static GObjectClass *parent_class; * * Return value: The type ID of the #CalBackend class. **/ -GType +GtkType cal_backend_get_type (void) { - static GType cal_backend_type = 0; + static GtkType 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) cal_backend_init, - }; - cal_backend_type = g_type_register_static (G_TYPE_OBJECT, "CalBackend", &info, 0); + static const GtkTypeInfo cal_backend_info = { + "CalBackend", + sizeof (CalBackend), + sizeof (CalBackendClass), + (GtkClassInitFunc) cal_backend_class_init, + (GtkObjectInitFunc) NULL, + NULL, /* reserved_1 */ + NULL, /* reserved_2 */ + (GtkClassInitFunc) NULL + }; + + cal_backend_type = + gtk_type_unique (GTK_TYPE_OBJECT, &cal_backend_info); } return cal_backend_type; @@ -115,58 +89,51 @@ cal_backend_get_type (void) static void cal_backend_class_init (CalBackendClass *class) { - GObjectClass *object_class; - - parent_class = (GObjectClass *) g_type_class_peek_parent (class); + GtkObjectClass *object_class; - object_class = (GObjectClass *) class; + object_class = (GtkObjectClass *) 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); + gtk_signal_new ("last_client_gone", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (CalBackendClass, last_client_gone), + gtk_marshal_NONE__NONE, + GTK_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); + gtk_signal_new ("cal_added", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (CalBackendClass, cal_added), + gtk_marshal_NONE__POINTER, + GTK_TYPE_NONE, 1, + GTK_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); + gtk_signal_new ("opened", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (CalBackendClass, opened), + gtk_marshal_NONE__ENUM, + GTK_TYPE_NONE, 1, + GTK_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); + gtk_signal_new ("obj_updated", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (CalBackendClass, obj_updated), + gtk_marshal_NONE__STRING, + GTK_TYPE_NONE, 1, + GTK_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); + gtk_signal_new ("obj_removed", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (CalBackendClass, obj_removed), + gtk_marshal_NONE__STRING, + GTK_TYPE_NONE, 1, + GTK_TYPE_STRING); - object_class->finalize = cal_backend_finalize; + gtk_object_class_add_signals (object_class, cal_backend_signals, LAST_SIGNAL); class->last_client_gone = NULL; class->opened = NULL; @@ -184,7 +151,7 @@ cal_backend_class_init (CalBackendClass *class) class->get_mode = NULL; class->set_mode = NULL; class->get_n_objects = NULL; - class->get_object = get_object; + class->get_object = NULL; class->get_object_component = NULL; class->get_timezone_object = NULL; class->get_uids = NULL; @@ -198,51 +165,6 @@ cal_backend_class_init (CalBackendClass *class) class->send_object = NULL; } -/* Object initialization func for the calendar backend */ -void -cal_backend_init (CalBackend *backend) -{ - CalBackendPrivate *priv; - - priv = g_new0 (CalBackendPrivate, 1); - backend->priv = priv; - - priv->categories = g_hash_table_new (g_str_hash, g_str_equal); - priv->changed_categories = g_hash_table_new (g_str_hash, g_str_equal); -} - -/* Used from g_hash_table_foreach(), frees a CalBackendCategory structure */ -static void -free_category_cb (gpointer key, gpointer value, gpointer data) -{ - CalBackendCategory *c = value; - - g_free (c->name); - g_free (c); -} - -void -cal_backend_finalize (GObject *object) -{ - CalBackend *backend = (CalBackend *)object; - CalBackendPrivate *priv; - - priv = backend->priv; - - g_assert (priv->clients == NULL); - - g_hash_table_foreach (priv->categories, free_category_cb, NULL); - g_hash_table_destroy (priv->categories); - - g_hash_table_foreach (priv->changed_categories, free_category_cb, NULL); - g_hash_table_destroy (priv->changed_categories); - - if (priv->category_idle_id) - g_source_remove (priv->category_idle_id); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - /** @@ -315,17 +237,37 @@ cal_backend_get_static_capabilities (CalBackend *backend) /* Callback used when a Cal is destroyed */ static void -cal_destroy_cb (gpointer data, GObject *where_cal_was) +cal_destroy_cb (GtkObject *object, gpointer data) { - CalBackend *backend = CAL_BACKEND (data); - CalBackendPrivate *priv = backend->priv; + Cal *cal; + Cal *lcal; + CalBackend *backend; + GList *l; + + cal = CAL (object); + + backend = CAL_BACKEND (data); + + /* Find the cal in the list of clients */ - priv->clients = g_list_remove (priv->clients, where_cal_was); + 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 (!priv->clients) + if (!backend->clients) cal_backend_last_client_gone (backend); } @@ -340,25 +282,22 @@ cal_destroy_cb (gpointer data, GObject *where_cal_was) void cal_backend_add_cal (CalBackend *backend, Cal *cal) { - CalBackendPrivate *priv = backend->priv; - 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 (strong) reference to the Cal since the - * Calendar user agent owns it */ - g_object_weak_ref (G_OBJECT (cal), cal_destroy_cb, backend); + /* we do not keep a reference to the Cal since the Calendar + * user agent owns it */ + gtk_signal_connect (GTK_OBJECT (cal), "destroy", + GTK_SIGNAL_FUNC (cal_destroy_cb), + backend); - priv->clients = g_list_prepend (priv->clients, cal); - - /* Tell the new client about the list of categories. - * (Ends up telling all the other clients too, but *shrug*.) - */ - notify_categories_changed (backend); + backend->clients = g_list_prepend (backend->clients, cal); /* notify backend that a new Cal has been added */ - g_signal_emit (backend, cal_backend_signals[CAL_ADDED], 0, cal); + gtk_signal_emit (GTK_OBJECT (backend), + cal_backend_signals[CAL_ADDED], + cal); } /** @@ -520,19 +459,6 @@ cal_backend_get_n_objects (CalBackend *backend, CalObjType type) return (* CLASS (backend)->get_n_objects) (backend, type); } -/* Default cal_backend_get_object implementation */ -static char * -get_object (CalBackend *backend, const char *uid) -{ - CalComponent *comp; - - comp = cal_backend_get_object_component (backend, uid); - if (!comp) - return NULL; - - return cal_component_get_as_string (comp); -} - char * cal_backend_get_default_object (CalBackend *backend, CalObjType type) { @@ -894,7 +820,7 @@ 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); + gtk_signal_emit (GTK_OBJECT (backend), cal_backend_signals[LAST_CLIENT_GONE]); } /** @@ -911,8 +837,8 @@ 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); + gtk_signal_emit (GTK_OBJECT (backend), cal_backend_signals[OPENED], + status); } /** @@ -930,8 +856,8 @@ cal_backend_obj_updated (CalBackend *backend, const char *uid) 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); + gtk_signal_emit (GTK_OBJECT (backend), cal_backend_signals[OBJ_UPDATED], + uid); } /** @@ -949,8 +875,8 @@ cal_backend_obj_removed (CalBackend *backend, const char *uid) 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); + gtk_signal_emit (GTK_OBJECT (backend), cal_backend_signals[OBJ_REMOVED], + uid); } @@ -1019,228 +945,3 @@ cal_backend_set_default_timezone (CalBackend *backend, const char *tzid) return (* CLASS (backend)->set_default_timezone) (backend, tzid); } - -/** - * cal_backend_notify_mode: - * @backend: A calendar backend. - * @status: Status of the mode set - * @mode: the current mode - * - * Notifies each of the backend's listeners about the results of a - * setMode call. - **/ -void -cal_backend_notify_mode (CalBackend *backend, - GNOME_Evolution_Calendar_Listener_SetModeStatus status, - GNOME_Evolution_Calendar_CalMode mode) -{ - CalBackendPrivate *priv = backend->priv; - GList *l; - - for (l = priv->clients; l; l = l->next) - cal_notify_mode (l->data, status, mode); -} - -/** - * cal_backend_notify_update: - * @backend: A calendar backend. - * @uid: UID of object that was updated. - * - * Notifies each of the backend's listeners about an update to a - * calendar object. - **/ -void -cal_backend_notify_update (CalBackend *backend, const char *uid) -{ - CalBackendPrivate *priv = backend->priv; - GList *l; - - cal_backend_obj_updated (backend, uid); - for (l = priv->clients; l; l = l->next) - cal_notify_update (l->data, uid); -} - -/** - * cal_backend_notify_remove: - * @backend: A calendar backend. - * @uid: UID of object that was removed. - * - * Notifies each of the backend's listeners about a calendar object - * that was removed. - **/ -void -cal_backend_notify_remove (CalBackend *backend, const char *uid) -{ - CalBackendPrivate *priv = backend->priv; - GList *l; - - cal_backend_obj_removed (backend, uid); - for (l = priv->clients; l; l = l->next) - cal_notify_remove (l->data, uid); -} - -/** - * cal_backend_notify_error: - * @backend: A calendar backend. - * @message: Error message - * - * Notifies each of the backend's listeners about an error - **/ -void -cal_backend_notify_error (CalBackend *backend, const char *message) -{ - CalBackendPrivate *priv = backend->priv; - GList *l; - - for (l = priv->clients; l; l = l->next) - cal_notify_error (l->data, message); -} - -static void -add_category_cb (gpointer name, gpointer category, gpointer data) -{ - GNOME_Evolution_Calendar_StringSeq *seq = data; - - seq->_buffer[seq->_length++] = CORBA_string_dup (name); -} - -static void -notify_categories_changed (CalBackend *backend) -{ - CalBackendPrivate *priv = backend->priv; - GNOME_Evolution_Calendar_StringSeq *seq; - GList *l; - - /* 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); - - /* Notify the clients */ - for (l = priv->clients; l; l = l->next) - cal_notify_categories_changed (l->data, seq); - - CORBA_free (seq); -} - -static gboolean -prune_changed_categories (gpointer key, gpointer value, gpointer data) -{ - CalBackendCategory *category = value; - - if (!category->refcount) { - g_free (category->name); - g_free (category); - } - return TRUE; -} - -static gboolean -idle_notify_categories_changed (gpointer data) -{ - CalBackend *backend = CAL_BACKEND (data); - CalBackendPrivate *priv = backend->priv; - - if (g_hash_table_size (priv->changed_categories)) { - notify_categories_changed (backend); - g_hash_table_foreach_remove (priv->changed_categories, prune_changed_categories, NULL); - } - return FALSE; -} - -/** - * cal_backend_ref_categories: - * @backend: A calendar backend - * @categories: a list of categories - * - * Adds 1 to the refcount of each of the named categories. If any of - * the categories are new, clients will be notified of the updated - * category list at idle time. - **/ -void -cal_backend_ref_categories (CalBackend *backend, GSList *categories) -{ - CalBackendPrivate *priv; - CalBackendCategory *c; - const char *name; - - priv = backend->priv; - - while (categories) { - name = categories->data; - c = g_hash_table_lookup (priv->categories, name); - - if (c) - c->refcount++; - else { - /* See if it was recently removed */ - - c = g_hash_table_lookup (priv->changed_categories, name); - if (c && c->refcount == 0) { - /* Move it back to the set of live categories */ - g_hash_table_remove (priv->changed_categories, c->name); - - c->refcount = 1; - g_hash_table_insert (priv->categories, c->name, c); - } else { - /* Create a new category */ - c = g_new (CalBackendCategory, 1); - c->name = g_strdup (name); - c->refcount = 1; - g_hash_table_insert (priv->changed_categories, c->name, c); - } - } - - categories = categories->next; - } - - if (g_hash_table_size (priv->changed_categories) && - !priv->category_idle_id) - priv->category_idle_id = g_idle_add (idle_notify_categories_changed, backend); -} - -/** - * cal_backend_unref_categories: - * @backend: A calendar backend - * @categories: a list of categories - * - * Subtracts 1 from the refcount of each of the named categories. If - * any of the refcounts go down to 0, clients will be notified of the - * updated category list at idle time. - **/ -void -cal_backend_unref_categories (CalBackend *backend, GSList *categories) -{ - CalBackendPrivate *priv; - CalBackendCategory *c; - const char *name; - - priv = backend->priv; - - while (categories) { - name = categories->data; - c = g_hash_table_lookup (priv->categories, name); - - if (c) { - 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->changed_categories, c->name, c); - } - } - - categories = categories->next; - } - - if (g_hash_table_size (priv->changed_categories) && - !priv->category_idle_id) - priv->category_idle_id = g_idle_add (idle_notify_categories_changed, backend); -} |