aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/e-cal-model.c
diff options
context:
space:
mode:
authorJP Rosevear <jpr@ximian.com>2004-03-16 00:29:52 +0800
committerJP Rosevear <jpr@src.gnome.org>2004-03-16 00:29:52 +0800
commit2060bbd57aebf43da04cb3c7e2dafb1780351422 (patch)
tree35b7b2c0cd872eb05ef9c6508ab97dd18091150a /calendar/gui/e-cal-model.c
parent717065d55acd425db5793072810e846e0aa1eb12 (diff)
downloadgsoc2013-evolution-2060bbd57aebf43da04cb3c7e2dafb1780351422.tar
gsoc2013-evolution-2060bbd57aebf43da04cb3c7e2dafb1780351422.tar.gz
gsoc2013-evolution-2060bbd57aebf43da04cb3c7e2dafb1780351422.tar.bz2
gsoc2013-evolution-2060bbd57aebf43da04cb3c7e2dafb1780351422.tar.lz
gsoc2013-evolution-2060bbd57aebf43da04cb3c7e2dafb1780351422.tar.xz
gsoc2013-evolution-2060bbd57aebf43da04cb3c7e2dafb1780351422.tar.zst
gsoc2013-evolution-2060bbd57aebf43da04cb3c7e2dafb1780351422.zip
Fixes #52253
2004-03-15 JP Rosevear <jpr@ximian.com> Fixes #52253 * gui/print.c (print_week_summary_cb): copy component data * gui/gnome-cal.c (get_times_for_views): calculate the time range for each view (set_search_query): set the search query on the model (set_week_start): set the week start day (week_start_changed_cb): track if it changes (setup_config): set its notification (setup_widgets): update the view times and date navigator (gnome_calendar_init): remove dead values (gnome_calendar_goto_date): just calc the new time and let update_view_times handle it (gnome_calendar_goto): ditto (gnome_calendar_direction): ditto o (gnome_calendar_set_selected_time_range): ditto (gnome_calendar_dayjump): ditto (update_view_times): set the time ranges on the models (set_view): use the new preserve day setting (gnome_calendar_set_view): don't update the view times, just switch (gnome_calendar_get_selected_time_range): get the time range (gnome_calendar_on_date_navigator_selection_changed): don't re-update the date navigator, centralize the view setting * gui/e-week-view.c (time_range_changed_cb): handle the time range changing (process_component): move here (model_changed_cb): handle the model changing (update_row): updated a changed row (model_row_changed_cb): update a row (model_cell_changed_cb): ditto (model_rows_inserted_cb): handle events being added (row_deleted_check_cb, remove_uid_cb, model_rows_deleted_cb): handle events being deleted (timezone_changed_cb): handle timezone changing (e_week_view_init): create the model and listen to it (e_week_view_new): don't create the model here (e_week_view_set_selected_time_range): no need to cast (e_week_view_set_first_day_shown): ditto (e_week_view_set_weeks_shown): ditto (e_week_view_update_event_cb): free and copy the data using new routines (e_week_view_foreach_event): step through every event (e_week_view_remove_event_cb): we no longer track allocated status (e_week_view_on_button_release): don't set the seleciton in the calendar (e_week_view_free_events): free the data with the util (e_week_view_add_event): no need to track allocated status (e_week_view_on_adjustment_changed): no need to cast * gui/e-day-view.c (e_day_view_class_init): update query is no longer used via class method (time_range_changed_cb): handle the time range changing (process_component): move here (model_changed_cb): handle the model changing (update_row): updated a changed row (model_row_changed_cb): update a row (model_cell_changed_cb): ditto (model_rows_inserted_cb): handle events being added (row_deleted_check_cb, remove_uid_cb, model_rows_deleted_cb): handle events being deleted (timezone_changed_cb): handle timezone changing (e_day_view_init): create a model, connect to its signals (e_day_view_destroy): we don't have our own query anymore (e_day_view_update_event_cb): free and copy the data using new routines (e_day_view_remove_event_cb): we no longer track allocated status (e_day_view_set_selected_time_range): actually set the selection (e_day_view_recalc_day_starts): no need to cast (e_day_view_recalc_work_week): ditto (e_day_view_update_calendar_selection_time): don't call back to the main calendar (e_day_view_free_event_array): use the free util (e_day_view_add_event): don't track allocated status * gui/e-calendar-marshal.list: add marshaller * gui/e-cal-view.h: remove field * gui/e-cal-view.c: no longer listen for model signals (e_calendar_view_class_init): make the model arg not construct time * gui/e-cal-model.h: update/add protos * gui/e-cal-model.c (e_cal_model_class_init): set the dispose handler and add a time_range_changed signal (e_cal_model_init): defaults for queries (e_cal_model_dispose): dispose of things (e_cal_model_finalize): remove bits that are in dispose now (search_by_uid_and_client): allow NULL client to find any uid (e_cal_view_objects_added_cb): ref the client (update_e_cal_view_for_client): use the full query (remove_client): pre change for each row and emit deleted signals (redo_queries): relaunch the query for each client (e_cal_model_get_time_range): get the time range (e_cal_model_set_time_range): set the time range and redo the queries (e_cal_model_set_search_query): get the search query (e_cal_model_set_search_query): set the search query and redo the queries (e_cal_model_get_component_for_uid): get the component info based on uid (copy_ecdv): copy and ECellDateEditValue (e_cal_model_copy_component_data): copy component data (e_cal_model_free_component_data): unref the client svn path=/trunk/; revision=25072
Diffstat (limited to 'calendar/gui/e-cal-model.c')
-rw-r--r--calendar/gui/e-cal-model.c297
1 files changed, 231 insertions, 66 deletions
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index 246444986f..adb386b79c 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -23,14 +23,13 @@
#include <glib/garray.h>
#include <libgnome/gnome-i18n.h>
#include <gal/util/e-util.h>
-#include <e-util/e-config-listener.h>
#include <e-util/e-time-utils.h>
#include <libecal/e-cal-time-util.h>
-#include "calendar-config.h"
#include "comp-util.h"
#include "e-cal-model.h"
#include "itip-utils.h"
#include "misc.h"
+#include "e-calendar-marshal.h"
typedef struct {
ECal *client;
@@ -50,8 +49,15 @@ struct _ECalModelPrivate {
icalcomponent_kind kind;
icaltimezone *zone;
+ /* The time range to display */
+ time_t start;
+ time_t end;
+
/* The search regular expression */
- gchar *sexp;
+ gchar *search_sexp;
+
+ /* The full regular expression, including time range */
+ gchar *full_sexp;
/* The default category */
gchar *default_category;
@@ -65,6 +71,7 @@ struct _ECalModelPrivate {
static void e_cal_model_class_init (ECalModelClass *klass);
static void e_cal_model_init (ECalModel *model, ECalModelClass *klass);
+static void e_cal_model_dispose (GObject *object);
static void e_cal_model_finalize (GObject *object);
static int ecm_column_count (ETableModel *etm);
@@ -81,6 +88,14 @@ static char *ecm_value_to_string (ETableModel *etm, int col, const void *value);
static const char *ecm_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data);
+/* Signal IDs */
+enum {
+ TIME_RANGE_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
static GObjectClass *parent_class = NULL;
E_MAKE_TYPE (e_cal_model, "ECalModel", ECalModel, e_cal_model_class_init,
@@ -94,6 +109,7 @@ e_cal_model_class_init (ECalModelClass *klass)
parent_class = g_type_class_peek_parent (klass);
+ object_class->dispose = e_cal_model_dispose;
object_class->finalize = e_cal_model_finalize;
etm_class->column_count = ecm_column_count;
@@ -110,6 +126,15 @@ e_cal_model_class_init (ECalModelClass *klass)
klass->get_color_for_component = ecm_get_color_for_component;
klass->fill_component_from_model = NULL;
+
+ signals[TIME_RANGE_CHANGED] =
+ g_signal_new ("time_range_changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ECalModelClass, time_range_changed),
+ NULL, NULL,
+ e_calendar_marshal_VOID__LONG_LONG,
+ G_TYPE_NONE, 2, G_TYPE_LONG, G_TYPE_LONG);
}
static void
@@ -120,7 +145,11 @@ e_cal_model_init (ECalModel *model, ECalModelClass *klass)
priv = g_new0 (ECalModelPrivate, 1);
model->priv = priv;
- priv->sexp = g_strdup ("#t"); /* match all by default */
+ /* match none by default */
+ priv->start = -1;
+ priv->end = -1;
+ priv->search_sexp = NULL;
+ priv->full_sexp = g_strdup ("#f");
priv->objects = g_ptr_array_new ();
priv->kind = ICAL_NO_COMPONENT;
@@ -183,7 +212,7 @@ clear_objects_array (ECalModelPrivate *priv)
}
static void
-e_cal_model_finalize (GObject *object)
+e_cal_model_dispose (GObject *object)
{
ECalModelPrivate *priv;
ECalModel *model = (ECalModel *) object;
@@ -191,48 +220,48 @@ e_cal_model_finalize (GObject *object)
g_return_if_fail (E_IS_CAL_MODEL (model));
priv = model->priv;
- if (priv) {
- if (priv->clients) {
- while (priv->clients != NULL) {
- ECalModelClient *client_data = (ECalModelClient *) priv->clients->data;
-
- g_signal_handlers_disconnect_matched (client_data->client, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, model);
- g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA,
- 0, 0, NULL, NULL, model);
-
- priv->clients = g_list_remove (priv->clients, client_data);
- g_object_unref (client_data->client);
- g_object_unref (client_data->query);
- g_free (client_data);
- }
- priv->clients = NULL;
+ if (priv->clients) {
+ while (priv->clients != NULL) {
+ ECalModelClient *client_data = (ECalModelClient *) priv->clients->data;
+
+ g_signal_handlers_disconnect_matched (client_data->client, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, model);
+ g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, model);
+
+ priv->clients = g_list_remove (priv->clients, client_data);
+ g_object_unref (client_data->client);
+ g_object_unref (client_data->query);
+ g_free (client_data);
}
- if (priv->sexp) {
- g_free (priv->sexp);
- priv->sexp = NULL;
- }
+ priv->clients = NULL;
+ }
- if (priv->default_category) {
- g_free (priv->default_category);
- priv->default_category = NULL;
- }
+ if (parent_class->dispose)
+ parent_class->dispose (object);
+}
- if (priv->objects) {
- clear_objects_array (priv);
- g_ptr_array_free (priv->objects, FALSE);
- priv->objects = NULL;
- }
-
- if (priv->accounts) {
- priv->accounts = NULL;
- }
+static void
+e_cal_model_finalize (GObject *object)
+{
+ ECalModelPrivate *priv;
+ ECalModel *model = (ECalModel *) object;
- g_free (priv);
- model->priv = NULL;
- }
+ g_return_if_fail (E_IS_CAL_MODEL (model));
+
+ priv = model->priv;
+
+ g_free (priv->search_sexp);
+ g_free (priv->full_sexp);
+
+ g_free (priv->default_category);
+
+ clear_objects_array (priv);
+ g_ptr_array_free (priv->objects, FALSE);
+
+ g_free (priv);
if (parent_class->finalize)
parent_class->finalize (object);
@@ -1098,6 +1127,8 @@ e_cal_model_get_client_for_uri (ECalModel *model, const char *uri)
return NULL;
}
+/* Pass NULL for the client if we just want to find based on uid */
+/* FIXME how do we prevent the same UID is different calendars? */
static ECalModelComponent *
search_by_uid_and_client (ECalModelPrivate *priv, ECal *client, const char *uid)
{
@@ -1111,7 +1142,7 @@ search_by_uid_and_client (ECalModelPrivate *priv, ECal *client, const char *uid)
tmp_uid = icalcomponent_get_uid (comp_data->icalcomp);
if (tmp_uid && *tmp_uid) {
- if (comp_data->client == client && !strcmp (uid, tmp_uid))
+ if ((!client || comp_data->client == client) && !strcmp (uid, tmp_uid))
return comp_data;
}
}
@@ -1148,7 +1179,7 @@ e_cal_view_objects_added_cb (ECalView *query, GList *objects, gpointer user_data
e_table_model_pre_change (E_TABLE_MODEL (model));
comp_data = g_new0 (ECalModelComponent, 1);
- comp_data->client = e_cal_view_get_client (query);
+ comp_data->client = g_object_ref (e_cal_view_get_client (query));
comp_data->icalcomp = icalcomponent_new_clone (l->data);
g_ptr_array_add (priv->objects, comp_data);
@@ -1219,7 +1250,7 @@ e_cal_view_objects_removed_cb (ECalView *query, GList *uids, gpointer user_data)
continue;
pos = get_position_in_array (priv->objects, comp_data);
-
+
g_ptr_array_remove (priv->objects, comp_data);
free_comp_data (comp_data);
@@ -1263,9 +1294,9 @@ update_e_cal_view_for_client (ECalModel *model, ECalModelClient *client_data)
}
/* prepare the query */
- g_assert (priv->sexp != NULL);
+ g_assert (priv->full_sexp != NULL);
- if (!e_cal_get_query (client_data->client, priv->sexp, &client_data->query, NULL)) {
+ if (!e_cal_get_query (client_data->client, priv->full_sexp, &client_data->query, NULL)) {
g_warning (G_STRLOC ": Unable to get query");
return;
@@ -1355,24 +1386,25 @@ remove_client (ECalModel *model, ECalModelClient *client_data)
model->priv->clients = g_list_remove (model->priv->clients, client_data);
/* remove all objects belonging to this client */
- e_table_model_pre_change (E_TABLE_MODEL (model));
for (i = model->priv->objects->len; i > 0; i--) {
ECalModelComponent *comp_data = (ECalModelComponent *) g_ptr_array_index (model->priv->objects, i - 1);
g_assert (comp_data != NULL);
if (comp_data->client == client_data->client) {
+ e_table_model_pre_change (E_TABLE_MODEL (model));
+
g_ptr_array_remove (model->priv->objects, comp_data);
free_comp_data (comp_data);
+
+ e_table_model_row_deleted (E_TABLE_MODEL (model), i);
}
}
- e_table_model_changed (E_TABLE_MODEL (model));
-
+
/* free all remaining memory */
g_object_unref (client_data->client);
g_object_unref (client_data->query);
g_free (client_data);
-
}
/**
@@ -1415,39 +1447,119 @@ e_cal_model_remove_all_clients (ECalModel *model)
}
}
-/**
- * e_cal_model_set_query
- */
-void
-e_cal_model_set_query (ECalModel *model, const char *sexp)
+static void
+redo_queries (ECalModel *model)
{
ECalModelPrivate *priv;
+ char *iso_start, *iso_end;
GList *l;
-
- g_return_if_fail (E_IS_CAL_MODEL (model));
- g_return_if_fail (sexp != NULL);
-
+ int len;
+
priv = model->priv;
- if (priv->sexp)
- g_free (priv->sexp);
-
- priv->sexp = g_strdup (sexp);
+ if (priv->full_sexp)
+ g_free (priv->full_sexp);
+ if (priv->start != -1 && priv->end != -1) {
+ iso_start = isodate_from_time_t (priv->start);
+ iso_end = isodate_from_time_t (priv->end);
+
+ priv->full_sexp = g_strdup_printf ("(and (occur-in-time-range? (make-time \"%s\")"
+ " (make-time \"%s\"))"
+ " %s)",
+ iso_start, iso_end,
+ priv->search_sexp ? priv->search_sexp : "");
+ } else {
+ priv->full_sexp = ("#f");
+ }
+
/* clean up the current contents */
e_table_model_pre_change (E_TABLE_MODEL (model));
+ len = priv->objects->len;
clear_objects_array (priv);
- e_table_model_changed (E_TABLE_MODEL (model));
-
+ e_table_model_rows_deleted (E_TABLE_MODEL (model), 0, len);
+
/* update the query for all clients */
for (l = priv->clients; l != NULL; l = l->next) {
ECalModelClient *client_data;
-
+
client_data = (ECalModelClient *) l->data;
update_e_cal_view_for_client (model, client_data);
}
}
+void
+e_cal_model_get_time_range (ECalModel *model, time_t *start, time_t *end)
+{
+ ECalModelPrivate *priv;
+
+ g_return_if_fail (model != NULL);
+ g_return_if_fail (E_IS_CAL_MODEL (model));
+
+ priv = model->priv;
+
+ if (start)
+ *start = priv->start;
+
+ if (end)
+ *end = priv->end;
+}
+
+void
+e_cal_model_set_time_range (ECalModel *model, time_t start, time_t end)
+{
+ ECalModelPrivate *priv;
+
+ g_return_if_fail (model != NULL);
+ g_return_if_fail (E_IS_CAL_MODEL (model));
+ g_return_if_fail (start >= 0 && end >= 0);
+ g_return_if_fail (start <= end);
+
+ priv = model->priv;
+
+ if (priv->start == start && priv->end == end)
+ return;
+
+ priv->start = start;
+ priv->end = end;
+
+ g_signal_emit (G_OBJECT (model), signals[TIME_RANGE_CHANGED], 0, start, end);
+ redo_queries (model);
+}
+
+const char *
+e_cal_model_get_search_query (ECalModel *model)
+{
+ ECalModelPrivate *priv;
+
+ g_return_val_if_fail (model != NULL, NULL);
+ g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL);
+
+ priv = model->priv;
+
+ return priv->search_sexp;
+}
+
+/**
+ * e_cal_model_set_query
+ */
+void
+e_cal_model_set_search_query (ECalModel *model, const char *sexp)
+{
+ ECalModelPrivate *priv;
+
+ g_return_if_fail (E_IS_CAL_MODEL (model));
+
+ priv = model->priv;
+
+ if (priv->search_sexp)
+ g_free (priv->search_sexp);
+
+ priv->search_sexp = g_strdup (sexp);
+
+ redo_queries (model);
+}
+
/**
* e_cal_model_create_component_with_defaults
*/
@@ -1563,6 +1675,18 @@ e_cal_model_get_component_at (ECalModel *model, gint row)
return g_ptr_array_index (priv->objects, row);
}
+ECalModelComponent *
+e_cal_model_get_component_for_uid (ECalModel *model, const char *uid)
+{
+ ECalModelPrivate *priv;
+
+ g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL);
+
+ priv = model->priv;
+
+ return search_by_uid_and_client (priv, NULL, uid);
+}
+
/**
* e_cal_model_date_value_to_string
*/
@@ -1603,6 +1727,45 @@ e_cal_model_date_value_to_string (ECalModel *model, const void *value)
return g_strdup (buffer);
}
+static ECellDateEditValue *
+copy_ecdv (ECellDateEditValue *ecdv)
+{
+ ECellDateEditValue *new_ecdv;
+
+
+ new_ecdv = g_new0 (ECellDateEditValue, 1);
+ new_ecdv->tt = ecdv->tt;
+ new_ecdv->zone = ecdv->zone;
+}
+
+/**
+ * e_cal_model_free_component_data
+ */
+ECalModelComponent *
+e_cal_model_copy_component_data (ECalModelComponent *comp_data)
+{
+ ECalModelComponent *new_data;
+
+ g_return_if_fail (comp_data != NULL);
+
+ new_data = g_new0 (ECalModelComponent, 1);
+
+ if (comp_data->icalcomp)
+ new_data->icalcomp = icalcomponent_new_clone (comp_data->icalcomp);
+ if (comp_data->client)
+ new_data->client = g_object_ref (comp_data->client);
+ if (comp_data->dtstart)
+ new_data->dtstart = copy_ecdv (comp_data->dtstart);
+ if (comp_data->dtend)
+ new_data->dtend = copy_ecdv (comp_data->dtend);
+ if (comp_data->due)
+ new_data->due = copy_ecdv (comp_data->due);
+ if (comp_data->completed)
+ new_data->completed = copy_ecdv (comp_data->completed);
+
+ return new_data;
+}
+
/**
* e_cal_model_free_component_data
*/
@@ -1611,6 +1774,8 @@ e_cal_model_free_component_data (ECalModelComponent *comp_data)
{
g_return_if_fail (comp_data != NULL);
+ if (comp_data->client)
+ g_object_unref (comp_data->client);
if (comp_data->icalcomp)
icalcomponent_free (comp_data->icalcomp);
if (comp_data->dtstart)