diff options
Diffstat (limited to 'calendar/gui/e-meeting-store.c')
-rw-r--r-- | calendar/gui/e-meeting-store.c | 1295 |
1 files changed, 0 insertions, 1295 deletions
diff --git a/calendar/gui/e-meeting-store.c b/calendar/gui/e-meeting-store.c deleted file mode 100644 index 01ac267fe1..0000000000 --- a/calendar/gui/e-meeting-store.c +++ /dev/null @@ -1,1295 +0,0 @@ -/* - * e-meeting-store.c - * - * Copyright (C) 2001-2003 Ximian, Inc. - * - * Authors: JP Rosevear <jpr@ximian.com> - * Mike Kestner <mkestner@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 <libgnome/gnome-util.h> -#include <libgnomevfs/gnome-vfs.h> -#include <libebook/e-book.h> -#include <libecal/e-cal-component.h> -#include <libecal/e-cal-util.h> -#include <libecal/e-cal-time-util.h> -#include "calendar-config.h" -#include "itip-utils.h" -#include "e-meeting-utils.h" -#include "e-meeting-attendee.h" -#include "e-meeting-store.h" - -#define ROW_VALID(store, row) (row >= 0 && row < store->priv->attendees->len) - -struct _EMeetingStorePrivate { - GPtrArray *attendees; - gint stamp; - - ECal *client; - icaltimezone *zone; - - EBook *ebook; - - GPtrArray *refresh_queue; - GHashTable *refresh_data; - guint refresh_idle_id; -}; - -#define BUF_SIZE 1024 - -typedef struct _EMeetingStoreQueueData EMeetingStoreQueueData; -struct _EMeetingStoreQueueData { - EMeetingStore *store; - EMeetingAttendee *attendee; - - gboolean refreshing; - - EMeetingTime start; - EMeetingTime end; - - char buffer[BUF_SIZE]; - GString *string; - - GPtrArray *call_backs; - GPtrArray *data; -}; - - -static GObjectClass *parent_class = NULL; - -static void -start_addressbook_server (EMeetingStore *store) -{ - store->priv->ebook = e_book_new (); - e_book_load_local_addressbook (store->priv->ebook, NULL); -} - -static icalparameter_cutype -text_to_type (const char *type) -{ - if (!g_strcasecmp (type, _("Individual"))) - return ICAL_CUTYPE_INDIVIDUAL; - else if (!g_strcasecmp (type, _("Group"))) - return ICAL_CUTYPE_GROUP; - else if (!g_strcasecmp (type, _("Resource"))) - return ICAL_CUTYPE_RESOURCE; - else if (!g_strcasecmp (type, _("Room"))) - return ICAL_CUTYPE_ROOM; - else - return ICAL_CUTYPE_NONE; -} - -static char * -type_to_text (icalparameter_cutype type) -{ - switch (type) { - case ICAL_CUTYPE_INDIVIDUAL: - return _("Individual"); - case ICAL_CUTYPE_GROUP: - return _("Group"); - case ICAL_CUTYPE_RESOURCE: - return _("Resource"); - case ICAL_CUTYPE_ROOM: - return _("Room"); - default: - return _("Unknown"); - } - - return NULL; - -} - -static icalparameter_role -text_to_role (const char *role) -{ - if (!g_strcasecmp (role, _("Chair"))) - return ICAL_ROLE_CHAIR; - else if (!g_strcasecmp (role, _("Required Participant"))) - return ICAL_ROLE_REQPARTICIPANT; - else if (!g_strcasecmp (role, _("Optional Participant"))) - return ICAL_ROLE_OPTPARTICIPANT; - else if (!g_strcasecmp (role, _("Non-Participant"))) - return ICAL_ROLE_NONPARTICIPANT; - else - return ICAL_ROLE_NONE; -} - -static char * -role_to_text (icalparameter_role role) -{ - switch (role) { - case ICAL_ROLE_CHAIR: - return _("Chair"); - case ICAL_ROLE_REQPARTICIPANT: - return _("Required Participant"); - case ICAL_ROLE_OPTPARTICIPANT: - return _("Optional Participant"); - case ICAL_ROLE_NONPARTICIPANT: - return _("Non-Participant"); - default: - return _("Unknown"); - } - - return NULL; -} - -static gboolean -text_to_boolean (const char *role) -{ - if (!g_strcasecmp (role, _("Yes"))) - return TRUE; - else - return FALSE; -} - -static char * -boolean_to_text (gboolean b) -{ - if (b) - return _("Yes"); - else - return _("No"); -} - -static icalparameter_partstat -text_to_partstat (const char *partstat) -{ - if (!g_strcasecmp (partstat, _("Needs Action"))) - return ICAL_PARTSTAT_NEEDSACTION; - else if (!g_strcasecmp (partstat, _("Accepted"))) - return ICAL_PARTSTAT_ACCEPTED; - else if (!g_strcasecmp (partstat, _("Declined"))) - return ICAL_PARTSTAT_DECLINED; - else if (!g_strcasecmp (partstat, _("Tentative"))) - return ICAL_PARTSTAT_TENTATIVE; - else if (!g_strcasecmp (partstat, _("Delegated"))) - return ICAL_PARTSTAT_DELEGATED; - else if (!g_strcasecmp (partstat, _("Completed"))) - return ICAL_PARTSTAT_COMPLETED; - else if (!g_strcasecmp (partstat, _("In Process"))) - return ICAL_PARTSTAT_INPROCESS; - else - return ICAL_PARTSTAT_NONE; -} - -static char * -partstat_to_text (icalparameter_partstat partstat) -{ - switch (partstat) { - case ICAL_PARTSTAT_NEEDSACTION: - return _("Needs Action"); - case ICAL_PARTSTAT_ACCEPTED: - return _("Accepted"); - case ICAL_PARTSTAT_DECLINED: - return _("Declined"); - case ICAL_PARTSTAT_TENTATIVE: - return _("Tentative"); - case ICAL_PARTSTAT_DELEGATED: - return _("Delegated"); - case ICAL_PARTSTAT_COMPLETED: - return _("Completed"); - case ICAL_PARTSTAT_INPROCESS: - return _("In Process"); - case ICAL_PARTSTAT_NONE: - default: - return _("Unknown"); - } - - return NULL; -} - -static GtkTreeModelFlags -get_flags (GtkTreeModel *model) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (model), 0); - - return GTK_TREE_MODEL_ITERS_PERSIST | GTK_TREE_MODEL_LIST_ONLY; -} - -static int -get_n_columns (GtkTreeModel *model) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (model), 0); - - return E_MEETING_STORE_COLUMN_COUNT; -} - -static GType -get_column_type (GtkTreeModel *model, int col) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (model), G_TYPE_INVALID); - - switch (col) { - case E_MEETING_STORE_ADDRESS_COL: - case E_MEETING_STORE_MEMBER_COL: - case E_MEETING_STORE_TYPE_COL: - case E_MEETING_STORE_ROLE_COL: - case E_MEETING_STORE_RSVP_COL: - case E_MEETING_STORE_DELTO_COL: - case E_MEETING_STORE_DELFROM_COL: - case E_MEETING_STORE_STATUS_COL: - case E_MEETING_STORE_CN_COL: - case E_MEETING_STORE_LANGUAGE_COL: - case E_MEETING_STORE_ATTENDEE_COL: - return G_TYPE_STRING; - case E_MEETING_STORE_ATTENDEE_UNDERLINE_COL: - return PANGO_TYPE_UNDERLINE; - default: - return G_TYPE_INVALID; - } -} - -static gboolean -get_iter (GtkTreeModel *model, GtkTreeIter *iter, GtkTreePath *path) -{ - int row; - - g_return_val_if_fail (E_IS_MEETING_STORE (model), FALSE); - g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE); - - row = gtk_tree_path_get_indices (path) [0]; - - if (!ROW_VALID (E_MEETING_STORE (model), row)) - return FALSE; - - iter->stamp = E_MEETING_STORE (model)->priv->stamp; - iter->user_data = GINT_TO_POINTER (row); - - return TRUE; -} - -static GtkTreePath * -get_path (GtkTreeModel *model, GtkTreeIter *iter) -{ - int row; - GtkTreePath *result; - - g_return_val_if_fail (E_IS_MEETING_STORE (model), NULL); - g_return_val_if_fail (iter->stamp == E_MEETING_STORE (model)->priv->stamp, NULL); - - row = GPOINTER_TO_INT (iter->user_data); - - g_return_val_if_fail (ROW_VALID (E_MEETING_STORE (model), row), NULL); - - result = gtk_tree_path_new (); - gtk_tree_path_append_index (result, row); - return result; -} - -static void -get_value (GtkTreeModel *model, GtkTreeIter *iter, int col, GValue *value) -{ - EMeetingStore *store; - EMeetingAttendee *attendee; - const gchar *cn; - int row; - - g_return_if_fail (E_IS_MEETING_STORE (model)); - g_return_if_fail (col >= 0 && col < E_MEETING_STORE_COLUMN_COUNT); - - row = GPOINTER_TO_INT (iter->user_data); - store = E_MEETING_STORE (model); - - g_return_if_fail (iter->stamp == store->priv->stamp); - g_return_if_fail (ROW_VALID (E_MEETING_STORE (model), row)); - - attendee = g_ptr_array_index (store->priv->attendees, row); - - switch (col) { - case E_MEETING_STORE_ADDRESS_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, itip_strip_mailto (e_meeting_attendee_get_address (attendee))); - break; - case E_MEETING_STORE_MEMBER_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, e_meeting_attendee_get_member (attendee)); - break; - case E_MEETING_STORE_TYPE_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, type_to_text (e_meeting_attendee_get_cutype (attendee))); - break; - case E_MEETING_STORE_ROLE_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, role_to_text (e_meeting_attendee_get_role (attendee))); - break; - case E_MEETING_STORE_RSVP_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, boolean_to_text (e_meeting_attendee_get_rsvp (attendee))); - break; - case E_MEETING_STORE_DELTO_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, itip_strip_mailto (e_meeting_attendee_get_delto (attendee))); - break; - case E_MEETING_STORE_DELFROM_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, itip_strip_mailto (e_meeting_attendee_get_delfrom (attendee))); - break; - case E_MEETING_STORE_STATUS_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, partstat_to_text (e_meeting_attendee_get_status (attendee))); - break; - case E_MEETING_STORE_CN_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, e_meeting_attendee_get_cn (attendee)); - break; - case E_MEETING_STORE_LANGUAGE_COL: - g_value_init (value, G_TYPE_STRING); - g_value_set_string (value, e_meeting_attendee_get_language (attendee)); - break; - case E_MEETING_STORE_ATTENDEE_COL: - g_value_init (value, G_TYPE_STRING); - cn = e_meeting_attendee_get_cn (attendee); - if (strcmp (cn, "")) - g_value_set_string (value, cn); - else - g_value_set_string (value, itip_strip_mailto (e_meeting_attendee_get_address (attendee))); - break; - case E_MEETING_STORE_ATTENDEE_UNDERLINE_COL: - cn = e_meeting_attendee_get_cn (attendee); - g_value_init (value, PANGO_TYPE_UNDERLINE); - g_value_set_enum (value, strcmp ("", cn) == 0 ? PANGO_UNDERLINE_NONE : PANGO_UNDERLINE_SINGLE); - } -} - -static gboolean -iter_next (GtkTreeModel *model, GtkTreeIter *iter) -{ - int row; - - g_return_val_if_fail (E_IS_MEETING_STORE (model), FALSE); - g_return_val_if_fail (iter->stamp == E_MEETING_STORE (model)->priv->stamp, FALSE); - - row = GPOINTER_TO_INT (iter->user_data) + 1; - iter->user_data = GINT_TO_POINTER (row); - - return ROW_VALID (E_MEETING_STORE (model), row); -} - -static gboolean -iter_children (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *parent) -{ - EMeetingStore *store; - - g_return_val_if_fail (E_IS_MEETING_STORE (model), FALSE); - - store = E_MEETING_STORE (model); - - if (parent || store->priv->attendees->len <= 0) - return FALSE; - - iter->stamp = store->priv->stamp; - iter->user_data = GINT_TO_POINTER (0); - - return TRUE; -} - -static gboolean -iter_has_child (GtkTreeModel *model, GtkTreeIter *iter) -{ - return FALSE; -} - -static int -iter_n_children (GtkTreeModel *model, GtkTreeIter *iter) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (model), -1); - - if (!iter) - return E_MEETING_STORE (model)->priv->attendees->len; - - g_return_val_if_fail (iter->stamp == E_MEETING_STORE (model)->priv->stamp, -1); - - return 0; -} - -static gboolean -iter_nth_child (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *parent, int n) -{ - EMeetingStore *store; - - g_return_val_if_fail (E_IS_MEETING_STORE (model), FALSE); - - store = E_MEETING_STORE (model); - - if (parent || !ROW_VALID (store, n)) - return FALSE; - - iter->stamp = store->priv->stamp; - iter->user_data = GINT_TO_POINTER (n); - - return TRUE; -} - -static gboolean -iter_parent (GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *child) -{ - return FALSE; -} - -static void -ems_tree_model_init (GtkTreeModelIface *iface) -{ - iface->get_flags = get_flags; - iface->get_n_columns = get_n_columns; - iface->get_column_type = get_column_type; - iface->get_iter = get_iter; - iface->get_path = get_path; - iface->get_value = get_value; - iface->iter_next = iter_next; - iface->iter_children = iter_children; - iface->iter_has_child = iter_has_child; - iface->iter_n_children = iter_n_children; - iface->iter_nth_child = iter_nth_child; - iface->iter_parent = iter_parent; -} - -void -e_meeting_store_set_value (EMeetingStore *store, int row, int col, const gchar *val) -{ - icalparameter_cutype type; - EMeetingAttendee *attendee = g_ptr_array_index (store->priv->attendees, row); - - switch (col) { - case E_MEETING_STORE_ADDRESS_COL: - if (val != NULL && *((char *)val)) - e_meeting_attendee_set_address (attendee, g_strdup_printf ("MAILTO:%s", (char *) val)); - break; - case E_MEETING_STORE_MEMBER_COL: - e_meeting_attendee_set_member (attendee, g_strdup (val)); - break; - case E_MEETING_STORE_TYPE_COL: - type = text_to_type (val); - e_meeting_attendee_set_cutype (attendee, text_to_type (val)); - if (type == ICAL_CUTYPE_RESOURCE) { - e_meeting_attendee_set_role (attendee, ICAL_ROLE_NONPARTICIPANT); - } - break; - case E_MEETING_STORE_ROLE_COL: - e_meeting_attendee_set_role (attendee, text_to_role (val)); - break; - case E_MEETING_STORE_RSVP_COL: - e_meeting_attendee_set_rsvp (attendee, text_to_boolean (val)); - break; - case E_MEETING_STORE_DELTO_COL: - e_meeting_attendee_set_delto (attendee, g_strdup (val)); - break; - case E_MEETING_STORE_DELFROM_COL: - e_meeting_attendee_set_delfrom (attendee, g_strdup (val)); - break; - case E_MEETING_STORE_STATUS_COL: - e_meeting_attendee_set_status (attendee, text_to_partstat (val)); - break; - case E_MEETING_STORE_CN_COL: - e_meeting_attendee_set_cn (attendee, g_strdup (val)); - break; - case E_MEETING_STORE_LANGUAGE_COL: - e_meeting_attendee_set_language (attendee, g_strdup (val)); - break; - } -} - -static gboolean -is_cell_editable (EMeetingStore *etm, int col, int row) -{ - EMeetingStore *store; - EMeetingStorePrivate *priv; - EMeetingAttendee *attendee; - EMeetingAttendeeEditLevel level; - - store = E_MEETING_STORE (etm); - priv = store->priv; - - if (col == E_MEETING_STORE_DELTO_COL - || col == E_MEETING_STORE_DELFROM_COL) - return FALSE; - - if (row == -1) - return TRUE; - if (row >= priv->attendees->len) - return TRUE; - - attendee = g_ptr_array_index (priv->attendees, row); - level = e_meeting_attendee_get_edit_level (attendee); - - switch (level) { - case E_MEETING_ATTENDEE_EDIT_FULL: - return TRUE; - case E_MEETING_ATTENDEE_EDIT_STATUS: - return col == E_MEETING_STORE_STATUS_COL; - case E_MEETING_ATTENDEE_EDIT_NONE: - return FALSE; - } - - return TRUE; -} - -static void -refresh_queue_remove (EMeetingStore *store, EMeetingAttendee *attendee) -{ - EMeetingStorePrivate *priv; - EMeetingStoreQueueData *qdata; - - priv = store->priv; - - /* Free the queue data */ - qdata = g_hash_table_lookup (priv->refresh_data, attendee); - if (qdata) { - g_hash_table_remove (priv->refresh_data, attendee); - g_ptr_array_free (qdata->call_backs, TRUE); - g_ptr_array_free (qdata->data, TRUE); - g_free (qdata); - } - - /* Unref the attendee */ - g_ptr_array_remove (priv->refresh_queue, attendee); - g_object_unref (attendee); -} - -static void -ems_finalize (GObject *obj) -{ - EMeetingStore *store = E_MEETING_STORE (obj); - EMeetingStorePrivate *priv; - int i; - - priv = store->priv; - - for (i = 0; i < priv->attendees->len; i++) - g_object_unref (g_ptr_array_index (priv->attendees, i)); - g_ptr_array_free (priv->attendees, TRUE); - - if (priv->client != NULL) - g_object_unref (priv->client); - - if (priv->ebook != NULL) - g_object_unref (priv->ebook); - - while (priv->refresh_queue->len > 0) - refresh_queue_remove (store, g_ptr_array_index (priv->refresh_queue, 0)); - g_ptr_array_free (priv->refresh_queue, TRUE); - g_hash_table_destroy (priv->refresh_data); - - if (priv->refresh_idle_id) - g_source_remove (priv->refresh_idle_id); - - g_free (priv); - - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (obj); -} - -static void -ems_class_init (GObjectClass *klass) -{ - parent_class = g_type_class_peek_parent (klass); - - klass->finalize = ems_finalize; -} - - -static void -ems_init (EMeetingStore *store) -{ - EMeetingStorePrivate *priv; - - priv = g_new0 (EMeetingStorePrivate, 1); - - store->priv = priv; - - priv->attendees = g_ptr_array_new (); - - priv->zone = icaltimezone_get_builtin_timezone (calendar_config_get_timezone ()); - - priv->refresh_queue = g_ptr_array_new (); - priv->refresh_data = g_hash_table_new (g_direct_hash, g_direct_equal); - - start_addressbook_server (store); -} - -GType -e_meeting_store_get_type (void) -{ - static GType ems_type = 0; - - if (!ems_type) { - static const GTypeInfo ems_info = { - sizeof (EMeetingStoreClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) ems_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EMeetingStore), - 0, - (GInstanceInitFunc) ems_init }; - - static const GInterfaceInfo tree_model_info = { - (GInterfaceInitFunc) ems_tree_model_init, - NULL, - NULL }; - - ems_type = g_type_register_static (GTK_TYPE_LIST_STORE, - "EMeetingStore", - &ems_info, 0); - - g_type_add_interface_static (ems_type, - GTK_TYPE_TREE_MODEL, - &tree_model_info); - } - - return ems_type; -} - -GObject * -e_meeting_store_new (void) -{ - return g_object_new (E_TYPE_MEETING_STORE, NULL); -} - - -ECal * -e_meeting_store_get_e_cal (EMeetingStore *store) -{ - return store->priv->client; -} - -void -e_meeting_store_set_e_cal (EMeetingStore *store, ECal *client) -{ - if (store->priv->client != NULL) - g_object_unref (store->priv->client); - - if (client != NULL) - g_object_ref (client); - store->priv->client = client; -} - -icaltimezone * -e_meeting_store_get_zone (EMeetingStore *store) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (store), NULL); - - return store->priv->zone; -} - -void -e_meeting_store_set_zone (EMeetingStore *store, icaltimezone *zone) -{ - g_return_if_fail (E_IS_MEETING_STORE (store)); - - store->priv->zone = zone; -} - -static void -attendee_changed_cb (EMeetingAttendee *attendee, gpointer data) -{ - EMeetingStore *store = E_MEETING_STORE (data); - GtkTreePath *path; - GtkTreeIter iter; - gint row = -1, i; - - for (i = 0; i < store->priv->attendees->len; i++) { - if (attendee == g_ptr_array_index (store->priv->attendees, i)) { - row = i; - break; - } - } - - if (row == -1) - return; - - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, row); - get_iter (GTK_TREE_MODEL (store), &iter, path); - gtk_tree_model_row_changed (GTK_TREE_MODEL (store), path, &iter); - gtk_tree_path_free (path); -} - -void -e_meeting_store_add_attendee (EMeetingStore *store, EMeetingAttendee *attendee) -{ - GtkTreePath *path; - GtkTreeIter iter; - - g_return_if_fail (E_IS_MEETING_STORE (store)); - - g_object_ref (attendee); - g_ptr_array_add (store->priv->attendees, attendee); - - g_signal_connect (attendee, "changed", G_CALLBACK (attendee_changed_cb), store); - - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, store->priv->attendees->len - 1); - get_iter (GTK_TREE_MODEL (store), &iter, path); - gtk_tree_model_row_inserted (GTK_TREE_MODEL (store), path, &iter); - gtk_tree_path_free (path); -} - -EMeetingAttendee * -e_meeting_store_add_attendee_with_defaults (EMeetingStore *store) -{ - EMeetingAttendee *attendee; - char *str; - - attendee = E_MEETING_ATTENDEE (e_meeting_attendee_new ()); - - e_meeting_attendee_set_address (attendee, g_strdup ("")); - e_meeting_attendee_set_member (attendee, g_strdup ("")); - - str = g_strdup (_("Individual")); - e_meeting_attendee_set_cutype (attendee, text_to_type (str)); - g_free (str); - str = g_strdup (_("Required Participant")); - e_meeting_attendee_set_role (attendee, text_to_role (str)); - g_free (str); - str = g_strdup (_("Yes")); - e_meeting_attendee_set_rsvp (attendee, text_to_boolean (str)); - g_free (str); - - e_meeting_attendee_set_delto (attendee, g_strdup ("")); - e_meeting_attendee_set_delfrom (attendee, g_strdup ("")); - - str = g_strdup (_("Needs Action")); - e_meeting_attendee_set_status (attendee, text_to_partstat (str)); - g_free (str); - - e_meeting_attendee_set_cn (attendee, g_strdup ("")); - e_meeting_attendee_set_language (attendee, g_strdup ("en")); - - e_meeting_store_add_attendee (store, attendee); - - return attendee; -} - -void -e_meeting_store_remove_attendee (EMeetingStore *store, EMeetingAttendee *attendee) -{ - gint i, row = -1; - GtkTreePath *path; - - for (i = 0; i < store->priv->attendees->len; i++) { - if (attendee == g_ptr_array_index (store->priv->attendees, i)) { - row = i; - break; - } - } - - if (row != -1) { - g_ptr_array_remove_index (store->priv->attendees, row); - g_object_unref (attendee); - - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, row); - gtk_tree_model_row_deleted (GTK_TREE_MODEL (store), path); - gtk_tree_path_free (path); - } -} - -void -e_meeting_store_remove_all_attendees (EMeetingStore *store) -{ - gint i; - GtkTreePath *path = gtk_tree_path_new (); - - gtk_tree_path_append_index (path, 0); - - for (i = 0; i < store->priv->attendees->len; i++) { - EMeetingAttendee *attendee = g_ptr_array_index (store->priv->attendees, i); - g_object_unref (attendee); - - gtk_tree_model_row_deleted (GTK_TREE_MODEL (store), path); - gtk_tree_path_next (path); - } - - g_ptr_array_set_size (store->priv->attendees, 0); - gtk_tree_path_free (path); -} - -EMeetingAttendee * -e_meeting_store_find_attendee (EMeetingStore *store, const gchar *address, gint *row) -{ - EMeetingAttendee *attendee; - int i; - - if (address == NULL) - return NULL; - - for (i = 0; i < store->priv->attendees->len; i++) { - const gchar *attendee_address; - - attendee = g_ptr_array_index (store->priv->attendees, i); - - attendee_address = e_meeting_attendee_get_address (attendee); - if (attendee_address && !g_strcasecmp (itip_strip_mailto (attendee_address), itip_strip_mailto (address))) { - if (row != NULL) - *row = i; - - return attendee; - } - } - - return NULL; -} - -EMeetingAttendee * -e_meeting_store_find_attendee_at_row (EMeetingStore *store, gint row) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (store), NULL); - g_return_val_if_fail (ROW_VALID (store, row), NULL); - - return g_ptr_array_index (store->priv->attendees, row); -} - -gint -e_meeting_store_count_actual_attendees (EMeetingStore *store) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (store), 0); - - return store->priv->attendees->len; -} - -const GPtrArray * -e_meeting_store_get_attendees (EMeetingStore *store) -{ - g_return_val_if_fail (E_IS_MEETING_STORE (store), NULL); - - return store->priv->attendees; -} - -static icaltimezone * -find_zone (icalproperty *ip, icalcomponent *tz_top_level) -{ - icalparameter *param; - icalcomponent *sub_comp; - const char *tzid; - icalcompiter iter; - - if (tz_top_level == NULL) - return NULL; - - param = icalproperty_get_first_parameter (ip, ICAL_TZID_PARAMETER); - if (param == NULL) - return NULL; - tzid = icalparameter_get_tzid (param); - - iter = icalcomponent_begin_component (tz_top_level, ICAL_VTIMEZONE_COMPONENT); - while ((sub_comp = icalcompiter_deref (&iter)) != NULL) { - icalcomponent *clone; - icalproperty *prop; - const char *tz_tzid; - - prop = icalcomponent_get_first_property (sub_comp, ICAL_TZID_PROPERTY); - tz_tzid = icalproperty_get_tzid (prop); - if (!strcmp (tzid, tz_tzid)) { - icaltimezone *zone; - - zone = icaltimezone_new (); - clone = icalcomponent_new_clone (sub_comp); - icaltimezone_set_component (zone, clone); - - return zone; - } - - icalcompiter_next (&iter); - } - - return NULL; -} - -static void -process_callbacks (EMeetingStoreQueueData *qdata) -{ - EMeetingStore *store; - int i; - - for (i = 0; i < qdata->call_backs->len; i++) { - EMeetingStoreRefreshCallback call_back; - gpointer *data; - - call_back = g_ptr_array_index (qdata->call_backs, i); - data = g_ptr_array_index (qdata->data, i); - - call_back (data); - } - - store = qdata->store; - refresh_queue_remove (qdata->store, qdata->attendee); - g_object_unref (store); -} - -static void -process_free_busy_comp (EMeetingAttendee *attendee, - icalcomponent *fb_comp, - icaltimezone *zone, - icalcomponent *tz_top_level) -{ - icalproperty *ip; - - ip = icalcomponent_get_first_property (fb_comp, ICAL_DTSTART_PROPERTY); - if (ip != NULL) { - struct icaltimetype dtstart; - icaltimezone *ds_zone; - - dtstart = icalproperty_get_dtstart (ip); - if (!dtstart.is_utc) - ds_zone = find_zone (ip, tz_top_level); - else - ds_zone = icaltimezone_get_utc_timezone (); - icaltimezone_convert_time (&dtstart, ds_zone, zone); - e_meeting_attendee_set_start_busy_range (attendee, - dtstart.year, - dtstart.month, - dtstart.day, - dtstart.hour, - dtstart.minute); - } - - ip = icalcomponent_get_first_property (fb_comp, ICAL_DTEND_PROPERTY); - if (ip != NULL) { - struct icaltimetype dtend; - icaltimezone *de_zone; - - dtend = icalproperty_get_dtend (ip); - if (!dtend.is_utc) - de_zone = find_zone (ip, tz_top_level); - else - de_zone = icaltimezone_get_utc_timezone (); - icaltimezone_convert_time (&dtend, de_zone, zone); - e_meeting_attendee_set_end_busy_range (attendee, - dtend.year, - dtend.month, - dtend.day, - dtend.hour, - dtend.minute); - } - - ip = icalcomponent_get_first_property (fb_comp, ICAL_FREEBUSY_PROPERTY); - while (ip != NULL) { - icalparameter *param; - struct icalperiodtype fb; - EMeetingFreeBusyType busy_type = E_MEETING_FREE_BUSY_LAST; - icalparameter_fbtype fbtype = ICAL_FBTYPE_BUSY; - - fb = icalproperty_get_freebusy (ip); - param = icalproperty_get_first_parameter (ip, ICAL_FBTYPE_PARAMETER); - if (param != NULL) - fbtype = icalparameter_get_fbtype (param); - - switch (fbtype) { - case ICAL_FBTYPE_BUSY: - busy_type = E_MEETING_FREE_BUSY_BUSY; - break; - - case ICAL_FBTYPE_BUSYUNAVAILABLE: - busy_type = E_MEETING_FREE_BUSY_OUT_OF_OFFICE; - break; - - case ICAL_FBTYPE_BUSYTENTATIVE: - busy_type = E_MEETING_FREE_BUSY_TENTATIVE; - break; - - default: - break; - } - - if (busy_type != E_MEETING_FREE_BUSY_LAST) { - icaltimezone *utc_zone = icaltimezone_get_utc_timezone (); - - icaltimezone_convert_time (&fb.start, utc_zone, zone); - icaltimezone_convert_time (&fb.end, utc_zone, zone); - e_meeting_attendee_add_busy_period (attendee, - fb.start.year, - fb.start.month, - fb.start.day, - fb.start.hour, - fb.start.minute, - fb.end.year, - fb.end.month, - fb.end.day, - fb.end.hour, - fb.end.minute, - busy_type); - } - - ip = icalcomponent_get_next_property (fb_comp, ICAL_FREEBUSY_PROPERTY); - } -} - -static void -process_free_busy (EMeetingStoreQueueData *qdata, char *text) -{ - EMeetingStore *store = qdata->store; - EMeetingStorePrivate *priv; - EMeetingAttendee *attendee = qdata->attendee; - icalcomponent *main_comp; - icalcomponent_kind kind = ICAL_NO_COMPONENT; - - priv = store->priv; - - main_comp = icalparser_parse_string (text); - if (main_comp == NULL) { - process_callbacks (qdata); - return; - } - - kind = icalcomponent_isa (main_comp); - if (kind == ICAL_VCALENDAR_COMPONENT) { - icalcompiter iter; - icalcomponent *tz_top_level, *sub_comp; - - tz_top_level = e_cal_util_new_top_level (); - - iter = icalcomponent_begin_component (main_comp, ICAL_VTIMEZONE_COMPONENT); - while ((sub_comp = icalcompiter_deref (&iter)) != NULL) { - icalcomponent *clone; - - clone = icalcomponent_new_clone (sub_comp); - icalcomponent_add_component (tz_top_level, clone); - - icalcompiter_next (&iter); - } - - iter = icalcomponent_begin_component (main_comp, ICAL_VFREEBUSY_COMPONENT); - while ((sub_comp = icalcompiter_deref (&iter)) != NULL) { - process_free_busy_comp (attendee, sub_comp, priv->zone, tz_top_level); - - icalcompiter_next (&iter); - } - icalcomponent_free (tz_top_level); - } else if (kind == ICAL_VFREEBUSY_COMPONENT) { - process_free_busy_comp (attendee, main_comp, priv->zone, NULL); - } - - icalcomponent_free (main_comp); - - process_callbacks (qdata); -} - -static gboolean -refresh_busy_periods (gpointer data) -{ - EMeetingStore *store = E_MEETING_STORE (data); - EMeetingStorePrivate *priv; - EMeetingAttendee *attendee = NULL; - EMeetingStoreQueueData *qdata = NULL; - char *query; - int i; - - priv = store->priv; - - /* Check to see if there are any remaining attendees in the queue */ - for (i = 0; i < priv->refresh_queue->len; i++) { - attendee = g_ptr_array_index (priv->refresh_queue, i); - g_assert (attendee != NULL); - - qdata = g_hash_table_lookup (priv->refresh_data, attendee); - if (!qdata) - continue; - - if (!qdata->refreshing) - break; - } - - /* The everything in the queue is being refreshed */ - if (i >= priv->refresh_queue->len) { - priv->refresh_idle_id = 0; - return FALSE; - } - - /* Indicate we are trying to refresh it */ - qdata->refreshing = TRUE; - - /* We take a ref in case we get destroyed in the gui during a callback */ - g_object_ref (qdata->store); - - /* Check the server for free busy data */ - if (priv->client) { - GList *fb_data = NULL, *users = NULL; - struct icaltimetype itt; - time_t startt, endt; - const char *user; - - itt = icaltime_null_time (); - itt.year = g_date_year (&qdata->start.date); - itt.month = g_date_month (&qdata->start.date); - itt.day = g_date_day (&qdata->start.date); - itt.hour = qdata->start.hour; - itt.minute = qdata->start.minute; - startt = icaltime_as_timet_with_zone (itt, priv->zone); - - itt = icaltime_null_time (); - itt.year = g_date_year (&qdata->end.date); - itt.month = g_date_month (&qdata->end.date); - itt.day = g_date_day (&qdata->end.date); - itt.hour = qdata->end.hour; - itt.minute = qdata->end.minute; - endt = icaltime_as_timet_with_zone (itt, priv->zone); - - user = itip_strip_mailto (e_meeting_attendee_get_address (attendee)); - users = g_list_append (users, g_strdup (user)); - e_cal_get_free_busy (priv->client, users, startt, endt, &fb_data, NULL); - - g_list_foreach (users, (GFunc)g_free, NULL); - g_list_free (users); - - if (fb_data != NULL) { - ECalComponent *comp = fb_data->data; - char *comp_str; - - comp_str = e_cal_component_get_as_string (comp); - process_free_busy (qdata, comp_str); - g_free (comp_str); - return TRUE; - } - } - - /* Look for fburl's of attendee with no free busy info on server */ - if (!e_meeting_attendee_is_set_address (attendee)) { - process_callbacks (qdata); - return TRUE; - } - - query = g_strdup_printf ("(contains \"email\" \"%s\")", - itip_strip_mailto (e_meeting_attendee_get_address (attendee))); - process_callbacks (qdata); - g_free (query); - - return TRUE; -} - -static void -refresh_queue_add (EMeetingStore *store, int row, - EMeetingTime *start, - EMeetingTime *end, - EMeetingStoreRefreshCallback call_back, - gpointer data) -{ - EMeetingStorePrivate *priv; - EMeetingAttendee *attendee; - EMeetingStoreQueueData *qdata; - - priv = store->priv; - - attendee = g_ptr_array_index (priv->attendees, row); - if (attendee == NULL) - return; - - qdata = g_hash_table_lookup (priv->refresh_data, attendee); - if (qdata == NULL) { - qdata = g_new0 (EMeetingStoreQueueData, 1); - - qdata->store = store; - qdata->attendee = attendee; - e_meeting_attendee_clear_busy_periods (attendee); - e_meeting_attendee_set_has_calendar_info (attendee, FALSE); - - qdata->start = *start; - qdata->end = *end; - qdata->string = g_string_new (NULL); - qdata->call_backs = g_ptr_array_new (); - qdata->data = g_ptr_array_new (); - g_ptr_array_add (qdata->call_backs, call_back); - g_ptr_array_add (qdata->data, data); - - g_hash_table_insert (priv->refresh_data, attendee, qdata); - } else { - if (e_meeting_time_compare_times (start, &qdata->start) == -1) - qdata->start = *start; - if (e_meeting_time_compare_times (end, &qdata->end) == 1) - qdata->end = *end; - g_ptr_array_add (qdata->call_backs, call_back); - g_ptr_array_add (qdata->data, data); - } - - g_object_ref (attendee); - g_ptr_array_add (priv->refresh_queue, attendee); - - if (priv->refresh_idle_id == 0) - priv->refresh_idle_id = g_idle_add (refresh_busy_periods, store); -} - -static void -async_close (GnomeVFSAsyncHandle *handle, - GnomeVFSResult result, - gpointer data) -{ - EMeetingStoreQueueData *qdata = data; - - process_free_busy (qdata, qdata->string->str); -} - -static void -async_read (GnomeVFSAsyncHandle *handle, - GnomeVFSResult result, - gpointer buffer, - GnomeVFSFileSize requested, - GnomeVFSFileSize read, - gpointer data) -{ - EMeetingStoreQueueData *qdata = data; - GnomeVFSFileSize buf_size = BUF_SIZE - 1; - - if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) { - gnome_vfs_async_close (handle, async_close, qdata); - return; - } - - ((char *)buffer)[read] = '\0'; - qdata->string = g_string_append (qdata->string, buffer); - - if (result == GNOME_VFS_ERROR_EOF) { - gnome_vfs_async_close (handle, async_close, qdata); - return; - } - - gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata); -} - -void -e_meeting_store_refresh_all_busy_periods (EMeetingStore *store, - EMeetingTime *start, - EMeetingTime *end, - EMeetingStoreRefreshCallback call_back, - gpointer data) -{ - int i; - - g_return_if_fail (E_IS_MEETING_STORE (store)); - - for (i = 0; i < store->priv->attendees->len; i++) - refresh_queue_add (store, i, start, end, call_back, data); -} - -void -e_meeting_store_refresh_busy_periods (EMeetingStore *store, - int row, - EMeetingTime *start, - EMeetingTime *end, - EMeetingStoreRefreshCallback call_back, - gpointer data) -{ - g_return_if_fail (E_IS_MEETING_STORE (store)); - - refresh_queue_add (store, row, start, end, call_back, data); -} - |