aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/calendar-model.c
diff options
context:
space:
mode:
authorDamon Chaplin <damon@helixcode.com>2000-07-26 03:49:15 +0800
committerDamon Chaplin <damon@src.gnome.org>2000-07-26 03:49:15 +0800
commitcd27c67fbc2f2a363579ce612c5937a4b12d1e49 (patch)
tree8e8d54ce72794dcc736ab075013264dc3d154217 /calendar/gui/calendar-model.c
parent516b594aa9e8abf1643905e7eb48e21f8684c1aa (diff)
downloadgsoc2013-evolution-cd27c67fbc2f2a363579ce612c5937a4b12d1e49.tar
gsoc2013-evolution-cd27c67fbc2f2a363579ce612c5937a4b12d1e49.tar.gz
gsoc2013-evolution-cd27c67fbc2f2a363579ce612c5937a4b12d1e49.tar.bz2
gsoc2013-evolution-cd27c67fbc2f2a363579ce612c5937a4b12d1e49.tar.lz
gsoc2013-evolution-cd27c67fbc2f2a363579ce612c5937a4b12d1e49.tar.xz
gsoc2013-evolution-cd27c67fbc2f2a363579ce612c5937a4b12d1e49.tar.zst
gsoc2013-evolution-cd27c67fbc2f2a363579ce612c5937a4b12d1e49.zip
new ECalendarTable to show an ETable view for Todo/Event items.
2000-07-25 Damon Chaplin <damon@helixcode.com> * gui/e-calendar-table.[hc]: new ECalendarTable to show an ETable view for Todo/Event items. * gui/task-assigned-to.xpm: * gui/task-recurring.xpm: * gui/task-assigned.xpm: * gui/task.xpm: new pixmaps (all the same at present) to go in the icon column of the ETable. * gui/event-editor.c: hid the silly 'Calendar' labels on the GnomeDateEdits and hid the times when you select 'All day event'. Also adjusted the time_t's so that when an all day event finishes on say midnight 13th May, we show 12th May in the dialog, since it implicitly includes all of that day up to midnight. * gui/dialogs/task-editor-dialog.glade: * gui/dialogs/task-editor.[hc]: unfinished dialog to edit tasks. * gui/gncal-todo.c: temporary hack so that we can use the simple dialog with our new ETable. svn path=/trunk/; revision=4323
Diffstat (limited to 'calendar/gui/calendar-model.c')
-rw-r--r--calendar/gui/calendar-model.c644
1 files changed, 583 insertions, 61 deletions
diff --git a/calendar/gui/calendar-model.c b/calendar/gui/calendar-model.c
index 0777685848..fbd0db7a6a 100644
--- a/calendar/gui/calendar-model.c
+++ b/calendar/gui/calendar-model.c
@@ -1,3 +1,5 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
/* Evolution calendar - Data model for ETable
*
* Copyright (C) 2000 Helix Code, Inc.
@@ -19,9 +21,17 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
+/* We need this for strptime. */
+#define _XOPEN_SOURCE
+
#include <config.h>
+#include <ctype.h>
+#include <time.h>
#include <gtk/gtksignal.h>
+#include <libgnomeui/gnome-messagebox.h>
+#include <libgnomeui/gnome-stock.h>
#include "calendar-model.h"
+#include "calendar-commands.h"
@@ -38,6 +48,12 @@ typedef struct {
/* UID -> array index hash */
GHashTable *uid_index_hash;
+
+ /* The row currently being added via the 'click-to-add' row. */
+ gint row_being_added;
+
+ /* Source ID of our idle function to add the new row. */
+ guint idle_id;
} CalendarModelPrivate;
@@ -51,11 +67,17 @@ 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 gint calendar_model_append_row (ETableModel *etm);
+static gboolean calendar_model_commit_new_row (gpointer data);
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);
+#if 0
static char * calendar_model_value_to_string (ETableModel *etm, int col, const void *value);
+#endif
+static void load_objects (CalendarModel *model);
+static int remove_object (CalendarModel *model, const char *uid);
static ETableModelClass *parent_class;
@@ -112,6 +134,7 @@ calendar_model_class_init (CalendarModelClass *class)
etm_class->value_at = calendar_model_value_at;
etm_class->set_value_at = calendar_model_set_value_at;
etm_class->is_cell_editable = calendar_model_is_cell_editable;
+ etm_class->append_row = calendar_model_append_row;
etm_class->duplicate_value = calendar_model_duplicate_value;
etm_class->free_value = calendar_model_free_value;
etm_class->initialize_value = calendar_model_initialize_value;
@@ -132,6 +155,9 @@ calendar_model_init (CalendarModel *model)
priv->objects = g_array_new (FALSE, TRUE, sizeof (iCalObject *));
priv->uid_index_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ priv->row_being_added = -1;
+ priv->idle_id = 0;
}
/* Called from g_hash_table_foreach_remove(), frees a stored UID->index
@@ -183,6 +209,10 @@ calendar_model_destroy (GtkObject *object)
model = CALENDAR_MODEL (object);
priv = model->priv;
+ /* Remove any idle function. */
+ if (priv->idle_id)
+ g_source_remove (priv->idle_id);
+
/* Free the calendar client interface object */
if (priv->client) {
@@ -234,6 +264,42 @@ calendar_model_row_count (ETableModel *etm)
return priv->objects->len;
}
+static char*
+get_time_t (time_t *t, gboolean skip_midnight)
+{
+ static char buffer[32];
+ struct tm *tmp_tm;
+
+ if (*t <= 0) {
+ buffer[0] = '\0';
+ } else {
+ tmp_tm = localtime (t);
+
+ if (skip_midnight && tmp_tm->tm_hour == 0
+ && tmp_tm->tm_min == 0 && tmp_tm->tm_sec == 0)
+ strftime (buffer, 32, "%a %x", tmp_tm);
+ else
+ strftime (buffer, 32, "%a %x %T", tmp_tm);
+ }
+
+ return buffer;
+}
+
+static char*
+get_geo (iCalGeo *geo)
+{
+ static gchar buffer[32];
+
+ if (!geo->valid)
+ buffer[0] = '\0';
+ else
+ g_snprintf (buffer, 32, "%g, %g", geo->latitude,
+ geo->longitude);
+
+ return buffer;
+}
+
+
/* value_at handler for the calendar table model */
static void *
calendar_model_value_at (ETableModel *etm, int col, int row)
@@ -241,6 +307,7 @@ calendar_model_value_at (ETableModel *etm, int col, int row)
CalendarModel *model;
CalendarModelPrivate *priv;
iCalObject *ico;
+ static char buffer[16];
model = CALENDAR_MODEL (etm);
priv = model->priv;
@@ -256,40 +323,45 @@ calendar_model_value_at (ETableModel *etm, int col, int row)
return ico->comment ? ico->comment : "";
case ICAL_OBJECT_FIELD_COMPLETED:
- return &ico->completed;
+ return get_time_t (&ico->completed, FALSE);
case ICAL_OBJECT_FIELD_CREATED:
- return &ico->created;
+ return get_time_t (&ico->created, FALSE);
case ICAL_OBJECT_FIELD_DESCRIPTION:
return ico->desc ? ico->desc : "";
case ICAL_OBJECT_FIELD_DTSTAMP:
- return &ico->dtstamp;
+ return get_time_t (&ico->dtstamp, FALSE);
case ICAL_OBJECT_FIELD_DTSTART:
- return &ico->dtstart;
+ return get_time_t (&ico->dtstart, FALSE);
case ICAL_OBJECT_FIELD_DTEND:
- return &ico->dtend;
+ return get_time_t (&ico->dtend, FALSE);
case ICAL_OBJECT_FIELD_GEO:
- return &ico->geo;
+ return get_geo (&ico->geo);
case ICAL_OBJECT_FIELD_LAST_MOD:
- return &ico->last_mod;
+ return get_time_t (&ico->last_mod, FALSE);
case ICAL_OBJECT_FIELD_LOCATION:
return ico->location ? ico->location : "";
case ICAL_OBJECT_FIELD_ORGANIZER:
- return ico->organizer;
+ if (ico->organizer && ico->organizer->name)
+ return ico->organizer->name;
+ else
+ return "";
case ICAL_OBJECT_FIELD_PERCENT:
- return &ico->percent;
+ g_snprintf (buffer, 16, "%i", ico->percent);
+ return buffer;
case ICAL_OBJECT_FIELD_PRIORITY:
- return &ico->priority;
+ g_snprintf (buffer, 16, "%i", ico->priority);
+ return buffer;
case ICAL_OBJECT_FIELD_SUMMARY:
return ico->summary ? ico->summary : "";
@@ -301,6 +373,38 @@ calendar_model_value_at (ETableModel *etm, int col, int row)
return (gpointer) (ico->dalarm.enabled || ico->aalarm.enabled
|| ico->palarm.enabled || ico->malarm.enabled);
+ case ICAL_OBJECT_FIELD_ICON:
+ /* FIXME: Also support 'Assigned to me' & 'Assigned to someone
+ else'. */
+ if (ico->recur)
+ return GINT_TO_POINTER (1);
+ else
+ return GINT_TO_POINTER (0);
+
+ case ICAL_OBJECT_FIELD_COMPLETE:
+ /* FIXME: Should check if the Completed field is set? */
+ return GINT_TO_POINTER (ico->completed > 0);
+
+ case ICAL_OBJECT_FIELD_RECURRING:
+ return GINT_TO_POINTER (ico->recur != NULL);
+
+ case ICAL_OBJECT_FIELD_OVERDUE:
+ /* I don't think calling time() is too slow. It takes about
+ 4 times as long as calling strlen() on a 20-char string
+ on my machine. */
+ if (ico->percent != 100
+ && ico->dtend > 0
+ && ico->dtend < time (NULL))
+ return GINT_TO_POINTER (TRUE);
+ return GINT_TO_POINTER (FALSE);
+
+ case ICAL_OBJECT_FIELD_COLOR:
+ if (ico->percent != 100
+ && ico->dtend > 0
+ && ico->dtend < time (NULL))
+ return "red";
+ return NULL;
+
default:
g_message ("calendar_model_value_at(): Requested invalid column %d", col);
return NULL;
@@ -320,32 +424,217 @@ set_string (char **dest, const char *value)
*dest = NULL;
}
+
+static gboolean
+string_is_empty (const char *value)
+{
+ const char *p;
+ gboolean empty = TRUE;
+
+ if (value) {
+ p = value;
+ while (*p) {
+ if (!isspace (*p)) {
+ empty = FALSE;
+ break;
+ }
+ p++;
+ }
+ }
+ return empty;
+}
+
+
+/* FIXME: We need to set the "transient_for" property for the dialog, but
+ the model doesn't know anything about the windows. */
+static void
+show_date_warning ()
+{
+ GtkWidget *dialog;
+ char buffer[32], message[256];
+ time_t t;
+ struct tm *tmp_tm;
+
+ t = time (NULL);
+ tmp_tm = localtime (&t);
+ strftime (buffer, 32, "%a %x %T", tmp_tm);
+
+ g_snprintf (message, 256,
+ _("The date must be entered in the format: \n\n%s"),
+ buffer);
+
+ dialog = gnome_message_box_new (message,
+ GNOME_MESSAGE_BOX_ERROR,
+ GNOME_STOCK_BUTTON_OK, NULL);
+ gtk_widget_show (dialog);
+}
+
+
/* Replaces a time_t value */
static void
-set_time_t (time_t *dest, const time_t *value)
+set_time_t (time_t *dest, const char *value)
+{
+ struct tm tmp_tm;
+ struct tm *today_tm;
+ time_t t;
+ const char *p;
+
+ if (string_is_empty (value)) {
+ *dest = 0;
+ } else {
+ /* Skip any weekday name. */
+ p = strptime (value, "%a", &tmp_tm);
+ if (!p)
+ p = value;
+
+ /* Try to match the full date & time, or without the seconds,
+ or just the date, or just the time with/without seconds.
+ The info pages say we should clear the tm before calling
+ strptime. It also means that if we don't match a time we
+ get 00:00:00 which is good. */
+ memset (&tmp_tm, 0, sizeof (tmp_tm));
+ if (!strptime (value, "%x %T", &tmp_tm)) {
+ memset (&tmp_tm, 0, sizeof (tmp_tm));
+ if (!strptime (value, "%x %H:%M", &tmp_tm)) {
+ memset (&tmp_tm, 0, sizeof (tmp_tm));
+ if (!strptime (value, "%x", &tmp_tm)) {
+ memset (&tmp_tm, 0, sizeof (tmp_tm));
+ if (!strptime (value, "%T", &tmp_tm)) {
+ memset (&tmp_tm, 0, sizeof (tmp_tm));
+ if (!strptime (value, "%H:%M", &tmp_tm)) {
+
+ g_warning ("Couldn't parse date string");
+ show_date_warning ();
+ return;
+ }
+ }
+
+ /* We only got a time, so we use the
+ current day. */
+ t = time (NULL);
+ today_tm = localtime (&t);
+ tmp_tm.tm_mday = today_tm->tm_mday;
+ tmp_tm.tm_mon = today_tm->tm_mon;
+ tmp_tm.tm_year = today_tm->tm_year;
+ }
+ }
+ }
+
+ tmp_tm.tm_isdst = -1;
+ *dest = mktime (&tmp_tm);
+ }
+}
+
+
+/* FIXME: We need to set the "transient_for" property for the dialog, but
+ the model doesn't know anything about the windows. */
+static void
+show_geo_warning ()
{
- *dest = *value;
+ GtkWidget *dialog;
+
+ dialog = gnome_message_box_new (_("The geographical position must be entered in the format: \n\n45.436845,125.862501"),
+ GNOME_MESSAGE_BOX_ERROR,
+ GNOME_STOCK_BUTTON_OK, NULL);
+ gtk_widget_show (dialog);
}
+
/* Replaces a geo value */
static void
-set_geo (iCalGeo *dest, const iCalGeo *value)
+set_geo (iCalGeo *dest, const char *value)
{
- *dest = *value;
+ double latitude, longitude;
+ gint matched;
+
+ if (!string_is_empty (value)) {
+ matched = sscanf (value, "%lg , %lg", &latitude, &longitude);
+
+ if (matched != 2) {
+ show_geo_warning ();
+ } else {
+ dest->valid = TRUE;
+ dest->latitude = latitude;
+ dest->longitude = longitude;
+ }
+ } else {
+ dest->valid = FALSE;
+ dest->latitude = 0.0;
+ dest->longitude = 0.0;
+ }
}
/* Replaces a person value */
static void
set_person (iCalPerson **dest, const iCalPerson *value)
{
- /* FIXME */
+ /* FIXME: This can't be set at present so it shouldn't be called. */
}
+/* FIXME: We need to set the "transient_for" property for the dialog, but
+ the model doesn't know anything about the windows. */
+static void
+show_percent_warning ()
+{
+ GtkWidget *dialog;
+
+ dialog = gnome_message_box_new (_("The percent value must be between 0 and 100"),
+ GNOME_MESSAGE_BOX_ERROR,
+ GNOME_STOCK_BUTTON_OK, NULL);
+ gtk_widget_show (dialog);
+}
+
+
/* Sets an int value */
static void
-set_int (int *dest, const int *value)
+set_percent (int *dest, const char *value)
{
- *dest = *value;
+ gint matched, percent;
+
+ if (!string_is_empty (value)) {
+ matched = sscanf (value, "%i", &percent);
+
+ if (matched != 1 || percent < 0 || percent > 100) {
+ show_percent_warning ();
+ } else {
+ *dest = percent;
+ }
+ } else {
+ *dest = 0;
+ }
+}
+
+/* FIXME: We need to set the "transient_for" property for the dialog, but
+ the model doesn't know anything about the windows. */
+static void
+show_priority_warning ()
+{
+ GtkWidget *dialog;
+
+ dialog = gnome_message_box_new (_("The priority must be between 0 and 10"),
+ GNOME_MESSAGE_BOX_ERROR,
+ GNOME_STOCK_BUTTON_OK, NULL);
+ gtk_widget_show (dialog);
+}
+
+
+/* Sets an int value */
+static void
+set_priority (int *dest, const char *value)
+{
+ gint matched, priority;
+
+ if (!string_is_empty (value)) {
+ matched = sscanf (value, "%i", &priority);
+
+ if (matched != 1 || priority < 0 || priority > 10) {
+ show_priority_warning ();
+ } else {
+ *dest = priority;
+ }
+ } else {
+ *dest = 0;
+ }
}
/* set_value_at handler for the calendar table model */
@@ -371,6 +660,7 @@ calendar_model_set_value_at (ETableModel *etm, int col, int row, const void *val
break;
case ICAL_OBJECT_FIELD_COMPLETED:
+ /* FIXME: Set status, percent etc. fields as well. */
set_time_t (&ico->completed, value);
break;
@@ -411,11 +701,12 @@ calendar_model_set_value_at (ETableModel *etm, int col, int row, const void *val
break;
case ICAL_OBJECT_FIELD_PERCENT:
- set_int (&ico->percent, value);
+ /* FIXME: If set to 0 or 100 set other fields. */
+ set_percent (&ico->percent, value);
break;
case ICAL_OBJECT_FIELD_PRIORITY:
- set_int (&ico->priority, value);
+ set_priority (&ico->priority, value);
break;
case ICAL_OBJECT_FIELD_SUMMARY:
@@ -426,8 +717,23 @@ calendar_model_set_value_at (ETableModel *etm, int col, int row, const void *val
set_string (&ico->url, value);
break;
+ case ICAL_OBJECT_FIELD_COMPLETE:
+ /* FIXME: Need a ical_object_XXX function to mark an item
+ complete, which will also set the 'Completed' time and
+ maybe others such as the last modified fields. */
+ ico->percent = 100;
+ ico->completed = time (NULL);
+ break;
+
case ICAL_OBJECT_FIELD_HAS_ALARMS:
- g_message ("calendar_model_set_value_at(): HAS_ALARMS is not a settable field!");
+ case ICAL_OBJECT_FIELD_ICON:
+ case ICAL_OBJECT_FIELD_RECURRING:
+ case ICAL_OBJECT_FIELD_OVERDUE:
+ case ICAL_OBJECT_FIELD_COLOR:
+ /* These are all computed fields which can't be set, so we
+ do nothing. Note that the 'click-to-add' item will set all
+ fields when finished, so we don't want to output warnings
+ here. */
break;
default:
@@ -435,7 +741,9 @@ calendar_model_set_value_at (ETableModel *etm, int col, int row, const void *val
break;
}
- if (!cal_client_update_object (priv->client, ico))
+ if (ico->new)
+ g_print ("Skipping update - new iCalObject\n");
+ else if (!cal_client_update_object (priv->client, ico))
g_message ("calendar_model_set_value_at(): Could not update the object!");
}
@@ -450,10 +758,19 @@ calendar_model_is_cell_editable (ETableModel *etm, int col, int row)
priv = model->priv;
g_return_val_if_fail (col >= 0 && col < ICAL_OBJECT_FIELD_NUM_FIELDS, FALSE);
- g_return_val_if_fail (row >= 0 && row < priv->objects->len, FALSE);
+ /* We can't check this as 'click-to-add' passes row 0. */
+ /*g_return_val_if_fail (row >= 0 && row < priv->objects->len, FALSE);*/
switch (col) {
+ case ICAL_OBJECT_FIELD_CREATED:
+ case ICAL_OBJECT_FIELD_DTSTAMP:
+ case ICAL_OBJECT_FIELD_LAST_MOD:
+ case ICAL_OBJECT_FIELD_GEO:
case ICAL_OBJECT_FIELD_HAS_ALARMS:
+ case ICAL_OBJECT_FIELD_ICON:
+ case ICAL_OBJECT_FIELD_RECURRING:
+ case ICAL_OBJECT_FIELD_OVERDUE:
+ case ICAL_OBJECT_FIELD_COLOR:
return FALSE;
default:
@@ -461,6 +778,82 @@ calendar_model_is_cell_editable (ETableModel *etm, int col, int row)
}
}
+static gint
+calendar_model_append_row (ETableModel *etm)
+{
+ CalendarModel *model;
+ CalendarModelPrivate *priv;
+ iCalObject *ico;
+ gint *new_idx;
+
+ g_print ("In calendar_model_append_row\n");
+
+ model = CALENDAR_MODEL (etm);
+ priv = model->priv;
+
+ if (priv->row_being_added != -1 || priv->idle_id != 0) {
+ g_warning ("Already adding row");
+ return -1;
+ }
+
+ ico = ical_new ("", user_name, "");
+ ico->type = ICAL_TODO;
+ ico->new = TRUE;
+
+ g_array_append_val (priv->objects, ico);
+ new_idx = g_new (int, 1);
+ *new_idx = priv->objects->len - 1;
+ g_hash_table_insert (priv->uid_index_hash, ico->uid, new_idx);
+
+ /* Notify the views about the new row. */
+ e_table_model_row_inserted (etm, *new_idx);
+
+ /* We add an idle function to pass the new iCalObject to the server.
+ We can't do it here since the values haven't been set yet.
+ Maybe we could connect to the "row_inserted" signal, though I'm
+ not sure when that is emitted. */
+ priv->row_being_added = *new_idx;
+ priv->idle_id = g_idle_add_full (G_PRIORITY_HIGH,
+ calendar_model_commit_new_row,
+ model, NULL);
+
+ return *new_idx;
+}
+
+static gboolean
+calendar_model_commit_new_row (gpointer data)
+{
+ CalendarModel *model;
+ CalendarModelPrivate *priv;
+ iCalObject *ico;
+
+ g_print ("Committing new row\n");
+
+ model = CALENDAR_MODEL (data);
+ priv = model->priv;
+
+ if (priv->row_being_added == -1) {
+ g_warning ("No row to commit");
+ priv->idle_id = 0;
+ return FALSE;
+ }
+
+ ico = g_array_index (priv->objects, iCalObject *,
+ priv->row_being_added);
+
+ if (!cal_client_update_object (priv->client, ico)) {
+ /* FIXME: Show error dialog. */
+ g_message ("calendar_model_commit_new_row(): Could not add new object!");
+ remove_object (model, ico->uid);
+ e_table_model_row_deleted (E_TABLE_MODEL (model),
+ priv->row_being_added);
+ }
+
+ priv->row_being_added = -1;
+ priv->idle_id = 0;
+ return FALSE;
+}
+
/* Duplicates a string value */
static char *
dup_string (const char *value)
@@ -469,44 +862,56 @@ dup_string (const char *value)
}
/* Duplicates a time_t value */
-static time_t *
-dup_time_t (const time_t *value)
+static char *
+dup_time_t (const char *value)
{
+ return g_strdup (value);
+
+#if 0
time_t *t;
t = g_new (time_t, 1);
*t = *value;
return t;
+#endif
}
/* Duplicates a geo value */
-static iCalGeo *
-dup_geo (const iCalGeo *value)
+static char *
+dup_geo (const char *value)
{
+ return g_strdup (value);
+
+#if 0
iCalGeo *geo;
geo = g_new (iCalGeo, 1);
*geo = *value;
return geo;
+#endif
}
/* Duplicates a person value */
-static iCalPerson *
-dup_person (const iCalPerson *value)
+static char *
+dup_person (const char *value)
{
/* FIXME */
- return NULL;
+ return g_strdup (value);
}
/* Duplicates an int value */
-static int *
-dup_int (const int *value)
+static char *
+dup_int (const char *value)
{
+ return g_strdup (value);
+
+#if 0
int *v;
v = g_new (int, 1);
*v = *value;
return v;
+#endif
}
/* duplicate_value handler for the calendar table model */
@@ -564,6 +969,13 @@ calendar_model_duplicate_value (ETableModel *etm, int col, const void *value)
case ICAL_OBJECT_FIELD_HAS_ALARMS:
return (void *) value;
+ case ICAL_OBJECT_FIELD_ICON:
+ case ICAL_OBJECT_FIELD_COMPLETE:
+ case ICAL_OBJECT_FIELD_RECURRING:
+ case ICAL_OBJECT_FIELD_OVERDUE:
+ case ICAL_OBJECT_FIELD_COLOR:
+ return (void *) value;
+
default:
g_message ("calendar_model_duplicate_value(): Requested invalid column %d", col);
return NULL;
@@ -575,10 +987,23 @@ static void
calendar_model_free_value (ETableModel *etm, int col, void *value)
{
g_return_if_fail (col >= 0 && col < ICAL_OBJECT_FIELD_NUM_FIELDS);
- g_return_if_fail (value != NULL);
- /* FIXME: this requires special handling for iCalPerson */
- g_free (value);
+ switch (col) {
+ case ICAL_OBJECT_FIELD_ORGANIZER:
+ /* FIXME: this requires special handling for iCalPerson */
+
+ break;
+ case ICAL_OBJECT_FIELD_HAS_ALARMS:
+ case ICAL_OBJECT_FIELD_ICON:
+ case ICAL_OBJECT_FIELD_COMPLETE:
+ case ICAL_OBJECT_FIELD_RECURRING:
+ case ICAL_OBJECT_FIELD_OVERDUE:
+ case ICAL_OBJECT_FIELD_COLOR:
+ /* Do nothing. */
+ break;
+ default:
+ g_free (value);
+ }
}
/* Initializes a string value */
@@ -589,20 +1014,25 @@ init_string (void)
}
/* Initializes a time_t value */
-static time_t *
+static char *
init_time_t (void)
{
+ return g_strdup ("");
+#if 0
time_t *t;
t = g_new (time_t, 1);
*t = -1;
return t;
+#endif
}
/* Initializes a geo value */
-static iCalGeo *
+static char *
init_geo (void)
{
+ return g_strdup ("");
+#if 0
iCalGeo *geo;
geo = g_new (iCalGeo, 1);
@@ -610,25 +1040,30 @@ init_geo (void)
geo->latitude = 0.0;
geo->longitude = 0.0;
return geo;
+#endif
}
/* Initializes a person value */
-static iCalPerson *
+static char *
init_person (void)
{
/* FIXME */
- return NULL;
+ return g_strdup ("");
}
/* Initializes an int value */
-static int *
+static char *
init_int (void)
{
+ return g_strdup ("");
+
+#if 0
int *v;
v = g_new (int, 1);
*v = 0;
return v;
+#endif
}
/* initialize_value handler for the calendar table model */
@@ -686,49 +1121,54 @@ calendar_model_initialize_value (ETableModel *etm, int col)
case ICAL_OBJECT_FIELD_HAS_ALARMS:
return NULL; /* "false" */
+ case ICAL_OBJECT_FIELD_ICON:
+ case ICAL_OBJECT_FIELD_COMPLETE:
+ case ICAL_OBJECT_FIELD_RECURRING:
+ case ICAL_OBJECT_FIELD_OVERDUE:
+ return GINT_TO_POINTER (0);
+
+ case ICAL_OBJECT_FIELD_COLOR:
+ return NULL;
+
default:
g_message ("calendar_model_initialize_value(): Requested invalid column %d", col);
return NULL;
}
}
-/* Returns whether a string is empty */
-static gboolean
-string_is_empty (const char *str)
-{
- return !(str && *str);
-}
/* Returns whether a time_t is empty */
static gboolean
-time_t_is_empty (const time_t *t)
+time_t_is_empty (const char *str)
{
- return (*t == -1);
+ return string_is_empty (str);
+#if 0
+ return (*t <= 0);
+#endif
}
/* Returns whether a geo is empty */
static gboolean
-geo_is_empty (const iCalGeo *geo)
+geo_is_empty (const char *str)
{
+ return string_is_empty (str);
+#if 0
return !geo->valid;
+#endif
}
/* Returns whether a person is empty */
static gboolean
-person_is_empty (const iCalPerson *person)
+person_is_empty (const char *str)
{
/* FIXME */
- return TRUE;
-}
-
-/* Returns whether an int is empty */
-static gboolean
-int_is_empty (const int *value)
-{
- return FALSE;
+ return string_is_empty (str);
}
-/* value_is_empty handler for the calendar model */
+/* value_is_empty handler for the calendar model. This should return TRUE
+ unless a significant value has been set. The 'click-to-add' feature
+ checks all fields to see if any are not empty and if so it adds a new
+ row, so we only want to return FALSE if we have a useful object. */
static gboolean
calendar_model_value_is_empty (ETableModel *etm, int col, const void *value)
{
@@ -769,10 +1209,10 @@ calendar_model_value_is_empty (ETableModel *etm, int col, const void *value)
return person_is_empty (value);
case ICAL_OBJECT_FIELD_PERCENT:
- return int_is_empty (value);
+ return string_is_empty (value);
case ICAL_OBJECT_FIELD_PRIORITY:
- return int_is_empty (value);
+ return string_is_empty (value);
case ICAL_OBJECT_FIELD_SUMMARY:
return string_is_empty (value);
@@ -781,7 +1221,12 @@ calendar_model_value_is_empty (ETableModel *etm, int col, const void *value)
return string_is_empty (value);
case ICAL_OBJECT_FIELD_HAS_ALARMS:
- return FALSE;
+ case ICAL_OBJECT_FIELD_ICON:
+ case ICAL_OBJECT_FIELD_COMPLETE:
+ case ICAL_OBJECT_FIELD_RECURRING:
+ case ICAL_OBJECT_FIELD_OVERDUE:
+ case ICAL_OBJECT_FIELD_COLOR:
+ return TRUE;
default:
g_message ("calendar_model_value_is_empty(): Requested invalid column %d", col);
@@ -805,6 +1250,20 @@ calendar_model_new (void)
return CALENDAR_MODEL (gtk_type_new (TYPE_CALENDAR_MODEL));
}
+
+/* Callback used when a calendar is loaded into the server */
+static void
+cal_loaded_cb (CalClient *client,
+ CalClientLoadStatus status,
+ CalendarModel *model)
+{
+ g_return_if_fail (IS_CALENDAR_MODEL (model));
+
+ load_objects (model);
+ e_table_model_changed (E_TABLE_MODEL (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.
@@ -996,6 +1455,8 @@ load_objects (CalendarModel *model)
g_assert (ico->uid != NULL);
+ /* FIXME: Why doesn't it just store the index in the hash
+ table as a GINT_TO_POINTER? - Damon. */
idx = g_new (int, 1);
g_array_append_val (priv->objects, ico);
@@ -1007,6 +1468,17 @@ load_objects (CalendarModel *model)
cal_obj_uid_list_free (uids);
}
+CalClient*
+calendar_model_get_cal_client (CalendarModel *model)
+{
+ CalendarModelPrivate *priv;
+
+ priv = model->priv;
+
+ return priv->client;
+}
+
+
/**
* calendar_model_set_cal_client:
* @model: A calendar model.
@@ -1046,6 +1518,8 @@ calendar_model_set_cal_client (CalendarModel *model, CalClient *client, CalObjTy
priv->type = type;
if (priv->client) {
+ gtk_signal_connect (GTK_OBJECT (priv->client), "cal_loaded",
+ GTK_SIGNAL_FUNC (cal_loaded_cb), model);
gtk_signal_connect (GTK_OBJECT (priv->client), "obj_updated",
GTK_SIGNAL_FUNC (obj_updated_cb), model);
gtk_signal_connect (GTK_OBJECT (priv->client), "obj_removed",
@@ -1056,3 +1530,51 @@ calendar_model_set_cal_client (CalendarModel *model, CalClient *client, CalObjTy
e_table_model_changed (E_TABLE_MODEL (model));
}
+
+
+void
+calendar_model_delete_task (CalendarModel *model,
+ gint row)
+{
+ CalendarModelPrivate *priv;
+ iCalObject *ico;
+
+ priv = model->priv;
+ ico = g_array_index (priv->objects, iCalObject *, row);
+
+ if (!cal_client_remove_object (priv->client, ico->uid))
+ g_message ("calendar_model_mark_task_complete(): Could not update the object!");
+}
+
+
+void
+calendar_model_mark_task_complete (CalendarModel *model,
+ gint row)
+{
+ CalendarModelPrivate *priv;
+ iCalObject *ico;
+
+ priv = model->priv;
+ ico = g_array_index (priv->objects, iCalObject *, row);
+
+ /* FIXME: Need a function to do all this. */
+ ico->percent = 100;
+ ico->completed = time (NULL);
+
+ if (!cal_client_update_object (priv->client, ico))
+ g_message ("calendar_model_mark_task_complete(): Could not update the object!");
+}
+
+
+/* Frees the objects stored in the calendar model */
+iCalObject*
+calendar_model_get_cal_object (CalendarModel *model,
+ gint row)
+{
+ CalendarModelPrivate *priv;
+
+ priv = model->priv;
+
+ return g_array_index (priv->objects, iCalObject *, row);
+}
+