aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/calendar-model.c
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@helixcode.com>2000-06-13 15:38:47 +0800
committerFederico Mena Quintero <federico@src.gnome.org>2000-06-13 15:38:47 +0800
commite7deedccdac5baf62f0adfd3a8cfb311157da01f (patch)
tree6114b6a4a73a6a3807398fbd607971f351f67664 /calendar/gui/calendar-model.c
parent7ba831860dfa5e96d9d19a0b5907d5237e60596a (diff)
downloadgsoc2013-evolution-e7deedccdac5baf62f0adfd3a8cfb311157da01f.tar.gz
gsoc2013-evolution-e7deedccdac5baf62f0adfd3a8cfb311157da01f.tar.zst
gsoc2013-evolution-e7deedccdac5baf62f0adfd3a8cfb311157da01f.zip
Added the array of objects and the hash table of UID->array index.
2000-06-13 Federico Mena Quintero <federico@helixcode.com> * gui/calendar-model.c (CalendarModelPrivate): Added the array of objects and the hash table of UID->array index. (calendar_model_row_count): Return the length directly from the array instead of asking the Wombat. (calendar_model_value_at): Implemented. (calendar_model_new): Create an empty model. We provide a new setter function now. (calendar_model_construct): Removed function. (calendar_model_set_cal_client): New function to set the calendar client and object type at any time. This lets us reuse a calendar model object. * cal-util/calobj.h (iCalObjectField): Just report whether the object has alarms; not every single alarm. svn path=/trunk/; revision=3547
Diffstat (limited to 'calendar/gui/calendar-model.c')
-rw-r--r--calendar/gui/calendar-model.c482
1 files changed, 482 insertions, 0 deletions
diff --git a/calendar/gui/calendar-model.c b/calendar/gui/calendar-model.c
new file mode 100644
index 0000000000..6562f225e1
--- /dev/null
+++ b/calendar/gui/calendar-model.c
@@ -0,0 +1,482 @@
+/* Evolution calendar - Data model for ETable
+ *
+ * Copyright (C) 2000 Helix Code, Inc.
+ *
+ * Authors: Federico Mena-Quintero <federico@helixcode.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "calendar-model.h"
+
+
+
+/* Private part of the ECalendarModel structure */
+typedef struct {
+ /* Calendar client we are using */
+ CalClient *client;
+
+ /* Types of objects we are dealing with */
+ CalObjType type;
+
+ /* Array of calendar objects */
+ GPtrArray *objects;
+
+ /* UID -> array index hash */
+ GHashTable *uid_index_hash;
+} CalendarModelPrivate;
+
+
+
+static void calendar_model_class_init (CalendarModelClass *class);
+static void calendar_model_init (CalendarModel *model);
+static void calendar_model_destroy (GtkObject *object);
+
+static int calendar_model_column_count (ETableModel *etm);
+static int calendar_model_row_count (ETableModel *etm);
+static void *calendar_model_value_at (ETableModel *etm, int col, int row);
+static void calendar_model_set_value_at (ETableModel *etm, int col, int row, const void *value);
+static gboolean calendar_model_is_cell_editable (ETableModel *etm, int col, int row);
+static void *calendar_model_duplicate_value (ETableModel *etm, int col, const void *value);
+static void calendar_model_free_value (ETableModel *etm, int col, void *value);
+static void *calendar_model_initialize_value (ETableModel *etm, int col);
+static gboolean calendar_model_value_is_empty (ETableModel *etm, int col, const void *value);
+
+static void calendar_model_freeze (ETableModel *etm);
+static void calendar_model_thaw (ETableModel *etm);
+
+static ETableModelClass *parent_class;
+
+
+
+/**
+ * calendar_model_get_type:
+ * @void:
+ *
+ * Registers the #CalendarModel class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the #CalendarModel class.
+ **/
+GtkType
+calendar_model_get_type (void)
+{
+ static GtkType calendar_model_type = 0;
+
+ if (!calendar_model_type) {
+ static GtkTypeInfo calendar_model_info = {
+ "CalendarModel",
+ sizeof (CalendarModel),
+ sizeof (CalendarModelClass),
+ (GtkClassInitFunc) calendar_model_class_init,
+ (GtkObjectInitFunc) calendar_model_init,
+ NULL, /* reserved_1 */
+ NULL, /* reserved_2 */
+ (GtkClassInitFunc) NULL
+ };
+
+ calendar_model_type = gtk_type_unique (E_TABLE_MODEL_TYPE, &calendar_model_info);
+ }
+
+ return calendar_model_type;
+}
+
+/* Class initialization function for the calendar table model */
+static void
+calendar_model_class_init (CalendarModelClass *class)
+{
+ GtkObjectClass *object_class;
+ ETableModelClass *etm_class;
+
+ object_class = (GtkObjectClass *) class;
+ etm_class = (ETableModelClass *) class;
+
+ parent_class = gtk_type_class (E_TABLE_MODEL_TYPE);
+
+ object_class->destroy = calendar_model_destroy;
+}
+
+/* Object initialization function for the calendar table model */
+static void
+calendar_model_init (CalendarModel *model)
+{
+ CalendarModelPrivate *priv;
+
+ priv = g_new0 (CalendarModelPrivate, 1);
+ model->priv = priv;
+
+ priv->objects = g_ptr_array_new ();
+ priv->uid_index_hash = g_hash_table_new (g_str_hash, g_str_equal);
+}
+
+/* Called from g_hash_table_foreach_remove(), frees a stored UID->index
+ * mapping.
+ */
+static gboolean
+free_uid_index (gpointer key, gpointer value, gpointer data)
+{
+ int *idx;
+
+ idx = value;
+ g_free (idx);
+
+ return TRUE;
+}
+
+/* Frees the objects stored in the calendar model */
+static void
+free_objects (CalendarModel *model)
+{
+ CalendarModelPrivate *priv;
+ int i;
+
+ priv = model->data;
+
+ g_hash_table_foreach_remove (priv->objects, free_uid_index, NULL);
+
+ for (i = 0; i < priv->objects->len; i++) {
+ iCalObject *ico;
+
+ ico = g_ptr_array_index (priv->objects, i);
+ g_assert (ico != NULL);
+ ical_object_unref (ico);
+ }
+
+ g_ptr_array_set_size (priv->objects, 0);
+}
+
+/* Destroy handler for the calendar table model */
+static void
+calendar_model_destroy (GtkObject *object)
+{
+ CalendarModel *model;
+ CalendarModelPrivate *priv;
+ int i;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (IS_CALENDAR_MODEL (object));
+
+ model = CALENDAR_MODEL (object);
+ priv = model->priv;
+
+ /* Free the calendar client interface object */
+
+ if (priv->client) {
+ gtk_object_unref (GTK_OBJECT (priv->client));
+ priv->client = NULL;
+ }
+
+ /* Free the uid->index hash data and the array of UIDs */
+
+ free_objects (model);
+
+ g_hash_table_destroy (priv->uid_index_hash);
+ priv->uid_index_hash = NULL;
+
+ g_ptr_array_free (priv->objects, TRUE);
+ priv->objects = NULL;
+
+ /* Free the private structure */
+
+ g_free (priv);
+ model->priv = NULL;
+
+ if (GTK_OBJECT_CLASS (parent_class)->destroy)
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+
+
+/* ETableModel methods */
+
+/* column_count handler for the calendar table model */
+static int
+calendar_model_column_count (ETableModel *etm)
+{
+ return ICAL_OBJECT_FIELD_NUM_FIELDS;
+}
+
+/* row_count handler for the calendar table model */
+static int
+calendar_model_row_count (ETableModel *etm)
+{
+ CalendarModel *model;
+ CalendarModelPrivate *priv;
+
+ model = CALENDAR_MODEL (etm);
+ priv = model->priv;
+
+ return priv->objects->len;
+}
+
+/* value_at handler for the calendar table model */
+static void *
+calendar_model_value_at (ETableModel *etm, int col, int row)
+{
+ CalendarModel *model;
+ CalendarModelPrivate *priv;
+ iCalObject *ico;
+ void *retval;
+
+ model = CALENDAR_MODEL (etm);
+ priv = model->priv;
+
+ if (row >= priv->objects->len) {
+ g_message ("calendar_model_value_at(): Requested invalid row index %d", row);
+ return NULL;
+ }
+
+ ico = g_ptr_array_index (priv->objects, row);
+ g_assert (ico != NULL);
+
+ switch (col) {
+ case ICAL_OBJECT_FIELD_COMMENT:
+ return ico->comment ? ico->commment : "";
+
+ case ICAL_OBJECT_FIELD_COMPLETED:
+ return &ico->completed;
+
+ case ICAL_OBJECT_FIELD_CREATED:
+ return &ico->created;
+
+ case ICAL_OBJECT_FIELD_DESCRIPTION:
+ return ico->desc ? ico->desc : "";
+
+ case ICAL_OBJECT_FIELD_DTSTAMP:
+ return &ico->dtstamp;
+
+ case ICAL_OBJECT_FIELD_DTSTART:
+ return &ico->dtstart;
+
+ case ICAL_OBJECT_FIELD_DTEND:
+ return &ico->dtend;
+
+ case ICAL_OBJECT_FIELD_GEO:
+ return &ico->geo;
+
+ case ICAL_OBJECT_FIELD_LAST_MOD:
+ return &ico->last_mod;
+
+ case ICAL_OBJECT_FIELD_LOCATION:
+ return ico->location ? ico->location : "";
+
+ case ICAL_OBJECT_FIELD_ORGANIZER:
+ return ico->organizer;
+
+ case ICAL_OBJECT_FIELD_PERCENT:
+ return &ico->percent;
+
+ case ICAL_OBJECT_FIELD_PRIORITY:
+ return &ico->priority;
+
+ case ICAL_OBJECT_FIELD_SUMMARY:
+ return ico->summary ? ico->summary : "";
+
+ case ICAL_OBJECT_FIELD_URL:
+ return ico->url ? ico->url : "";
+
+ case ICAL_OBJECT_FIELD_HAS_ALARMS:
+ return (ico->dalarm.enabled || ico->aalarm.enabled
+ || ico->palarm.enabled || ico->malarm.enabled);
+
+ default:
+ g_message ("calendar_model_value_at(): Requested invalid column %d", col);
+ return NULL;
+ }
+}
+
+
+
+/**
+ * calendar_model_new:
+ *
+ * Creates a new calendar model. It must be told about the calendar client
+ * interface object it will monitor with calendar_model_set_cal_client().
+ *
+ * Return value: A newly-created calendar model.
+ **/
+CalendarModel *
+calendar_model_new (void)
+{
+ return CALENDAR_MODEL (gtk_type_new (TYPE_CALENDAR_MODEL));
+}
+
+/* Removes an object from the model and updates all the indices that follow.
+ * Returns the index of the object that was removed, or -1 if no object with
+ * such UID was found.
+ */
+static int
+remove_object (CalendarModel *model, const char *uid)
+{
+ CalendarModelPrivate *priv;
+ int *idx;
+ iCalObject *orig_ico;
+ int i;
+ int n;
+
+ priv = model->priv;
+
+ /* Find the index of the object to be removed */
+
+ idx = g_hash_table_lookup (priv->uid_index_hash, uid);
+ if (!idx)
+ return -1;
+
+ orig_ico = g_ptr_array_index (priv->objects, *idx);
+ g_assert (orig_ico != NULL);
+
+ /* Decrease the indices of all the objects that follow in the array */
+
+ for (i = *idx + 1; i < priv->objects->len; i++) {
+ iCalObject *ico;
+ int *ico_idx;
+
+ ico = g_ptr_array_index (priv->objects, i);
+ g_assert (ico != NULL);
+
+ ico_idx = g_hash_table_lookup (priv->uid_index_hash, ico->uid);
+ g_assert (ico_idx != NULL);
+
+ *ico_idx--;
+ g_assert (*ico_idx >= 0);
+ }
+
+ /* Remove this object from the array and hash */
+
+ g_hash_table_remove (priv->uid_index_hash, uid);
+ g_array_remove (priv->objects, *idx);
+
+ ical_object_unref (orig_ico);
+
+ n = *idx;
+ g_free (idx);
+
+ return n;
+}
+
+/* Callback used when an object is updated in the server */
+static void
+obj_updated_cb (CalClient *client, const char *uid, gpointer data)
+{
+ CalendarModel *model;
+ CalendarModelPrivate *priv;
+ int orig_idx;
+
+ model = CALENDAR_MODEL (data);
+ priv = model->priv;
+
+ orig_idx = remove_object (model, uid);
+
+
+
+}
+
+/* Loads the required objects from the calendar client */
+static void
+load_objects (CalendarModel *model)
+{
+ CalendarModelPrivate *priv;
+ GList *uids;
+ GList *l;
+
+ priv = model->priv;
+
+ uids = cal_client_get_uids (priv->client, priv->type);
+
+ for (l = uids; l; l = l->next) {
+ char *uid;
+ iCalObject *ico;
+ CalClientGetStatus status;
+ int *idx;
+
+ uid = l->data;
+ status = cal_client_get_object (priv->client, uid, &ico);
+
+ switch (status) {
+ case CAL_CLIENT_GET_SUCCESS:
+ break;
+
+ case CAL_CLIENT_GET_NOT_FOUND:
+ /* Nothing; the object may have been removed from the server */
+ continue;
+
+ case CAL_CLIENT_GET_SYNTAX_ERROR:
+ g_message ("load_objects(): Syntax error when getting object %s", uid);
+ continue;
+ }
+
+ g_assert (ico->uid != NULL);
+
+ idx = g_new (int, 1);
+
+ g_ptr_array_add (priv->objects, ico);
+ *idx = priv->objects->len - 1;
+
+ g_hash_table_insert (priv->uid_index_hash, ico->uid, idx);
+ }
+
+ cal_obj_uid_list_free (uids);
+}
+
+/**
+ * calendar_model_set_cal_client:
+ * @model: A calendar model.
+ * @client: A calendar client interface object.
+ * @type: Type of objects to present.
+ *
+ * Sets the calendar client interface object that a calendar model will monitor.
+ * It also sets the types of objects this model will present to an #ETable.
+ **/
+void
+calendar_model_set_cal_client (CalendarModel *model, CalClient *client, CalObjType type)
+{
+ CalendarModelPrivate *priv;
+
+ g_return_if_fail (model != NULL);
+ g_return_if_fail (IS_CALENDAR_MODEL (model));
+
+ if (client)
+ g_return_if_fail (IS_CAL_CLIENT (client));
+
+ priv = model->priv;
+
+ if (priv->client == client && priv->type == type)
+ return;
+
+ if (client)
+ gtk_object_ref (GTK_OBJECT (client));
+
+ if (priv->client) {
+ gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), model);
+ gtk_object_unref (GTK_OBJECT (priv->client));
+ }
+
+ free_objects (model);
+
+ priv->client = client;
+ priv->type = type;
+
+ if (priv->client) {
+ gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated",
+ GTK_SIGNAL_FUNC (obj_updated_cb), model);
+ gtk_signal_connect (GTK_OBJECT (priv->clinet), "obj_removed",
+ GTK_SIGNAL_FUNC (obj_removed_cb), model);
+ }
+
+ load_objects (model);
+
+ e_table_model_changed (E_TABLE_MODEL (model));
+}