diff options
author | JP Rosevear <jpr@ximian.com> | 2004-03-16 00:29:52 +0800 |
---|---|---|
committer | JP Rosevear <jpr@src.gnome.org> | 2004-03-16 00:29:52 +0800 |
commit | 2060bbd57aebf43da04cb3c7e2dafb1780351422 (patch) | |
tree | 35b7b2c0cd872eb05ef9c6508ab97dd18091150a /calendar/gui/e-cal-model.c | |
parent | 717065d55acd425db5793072810e846e0aa1eb12 (diff) | |
download | gsoc2013-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.c | 297 |
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) |