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 | |
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')
-rw-r--r-- | calendar/ChangeLog | 111 | ||||
-rw-r--r-- | calendar/gui/e-cal-model.c | 297 | ||||
-rw-r--r-- | calendar/gui/e-cal-model.h | 84 | ||||
-rw-r--r-- | calendar/gui/e-cal-view.c | 53 | ||||
-rw-r--r-- | calendar/gui/e-cal-view.h | 1 | ||||
-rw-r--r-- | calendar/gui/e-calendar-marshal.list | 1 | ||||
-rw-r--r-- | calendar/gui/e-calendar-view.c | 53 | ||||
-rw-r--r-- | calendar/gui/e-calendar-view.h | 1 | ||||
-rw-r--r-- | calendar/gui/e-day-view.c | 486 | ||||
-rw-r--r-- | calendar/gui/e-week-view.c | 430 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.c | 324 | ||||
-rw-r--r-- | calendar/gui/print.c | 3 |
12 files changed, 1172 insertions, 672 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 9fb75ecca2..36d40ef3b1 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,114 @@ +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 + 2004-03-15 Rodrigo Moya <rodrigo@ximian.com> Fixes #48112 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) diff --git a/calendar/gui/e-cal-model.h b/calendar/gui/e-cal-model.h index 6cb3f6ba30..8437e4d1c5 100644 --- a/calendar/gui/e-cal-model.h +++ b/calendar/gui/e-cal-model.h @@ -80,38 +80,66 @@ typedef struct { const gchar * (* get_color_for_component) (ECalModel *model, ECalModelComponent *comp_data); void (* fill_component_from_model) (ECalModel *model, ECalModelComponent *comp_data, ETableModel *source_model, gint row); -} ECalModelClass; - -GType e_cal_model_get_type (void); - -icalcomponent_kind e_cal_model_get_component_kind (ECalModel *model); -void e_cal_model_set_component_kind (ECalModel *model, icalcomponent_kind kind); -icaltimezone *e_cal_model_get_timezone (ECalModel *model); -void e_cal_model_set_timezone (ECalModel *model, icaltimezone *zone); -void e_cal_model_set_default_category (ECalModel *model, const gchar *default_cat); -gboolean e_cal_model_get_use_24_hour_format (ECalModel *model); -void e_cal_model_set_use_24_hour_format (ECalModel *model, gboolean use24); - -ECal *e_cal_model_get_default_client (ECalModel *model); -void e_cal_model_set_default_client (ECalModel *model, ECal *client); -GList *e_cal_model_get_client_list (ECalModel *model); -ECal *e_cal_model_get_client_for_uri (ECalModel *model, const char *uri); -void e_cal_model_add_client (ECalModel *model, ECal *client); -void e_cal_model_remove_client (ECalModel *model, ECal *client); -void e_cal_model_remove_all_clients (ECalModel *model); - -void e_cal_model_set_query (ECalModel *model, const gchar *sexp); + /* Signals */ + void (* time_range_changed) (ECalModel *model, time_t start, time_t end); +} ECalModelClass; -icalcomponent *e_cal_model_create_component_with_defaults (ECalModel *model); -const gchar *e_cal_model_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data); -gboolean e_cal_model_get_rgb_color_for_component (ECalModel *model, ECalModelComponent *comp_data, double *red, double *green, double *blue); -ECalModelComponent *e_cal_model_get_component_at (ECalModel *model, gint row); +GType e_cal_model_get_type (void); +icalcomponent_kind e_cal_model_get_component_kind (ECalModel *model); +void e_cal_model_set_component_kind (ECalModel *model, + icalcomponent_kind kind); +icaltimezone *e_cal_model_get_timezone (ECalModel *model); +void e_cal_model_set_timezone (ECalModel *model, + icaltimezone *zone); +void e_cal_model_set_default_category (ECalModel *model, + const gchar *default_cat); +gboolean e_cal_model_get_use_24_hour_format (ECalModel *model); +void e_cal_model_set_use_24_hour_format (ECalModel *model, + gboolean use24); +ECal * e_cal_model_get_default_client (ECalModel *model); +void e_cal_model_set_default_client (ECalModel *model, + ECal *client); +GList *e_cal_model_get_client_list (ECalModel *model); +ECal * e_cal_model_get_client_for_uri (ECalModel *model, + const char *uri); +void e_cal_model_add_client (ECalModel *model, + ECal *client); +void e_cal_model_remove_client (ECalModel *model, + ECal *client); +void e_cal_model_remove_all_clients (ECalModel *model); +void e_cal_model_get_time_range (ECalModel *model, + time_t *start, + time_t *end); +void e_cal_model_set_time_range (ECalModel *model, + time_t start, + time_t end); +const char * e_cal_model_get_search_query (ECalModel *model); +void e_cal_model_set_search_query (ECalModel *model, + const gchar *sexp); +icalcomponent *e_cal_model_create_component_with_defaults (ECalModel *model); +const gchar *e_cal_model_get_color_for_component (ECalModel *model, + ECalModelComponent *comp_data); +gboolean e_cal_model_get_rgb_color_for_component (ECalModel *model, + ECalModelComponent *comp_data, + double *red, + double *green, + double *blue); +ECalModelComponent *e_cal_model_get_component_at (ECalModel *model, + gint row); +ECalModelComponent *e_cal_model_get_component_for_uid (ECalModel *model, + const char *uid); +gchar *e_cal_model_date_value_to_string (ECalModel *model, + const void *value); +ECalModelComponent *e_cal_model_copy_component_data (ECalModelComponent *comp_data); +void e_cal_model_free_component_data (ECalModelComponent *comp_data); +void e_cal_model_generate_instances (ECalModel *model, + time_t start, + time_t end, + ECalRecurInstanceFn cb, + gpointer cb_data); -gchar *e_cal_model_date_value_to_string (ECalModel *model, const void *value); -void e_cal_model_free_component_data (ECalModelComponent *comp_data); -void e_cal_model_generate_instances (ECalModel *model, time_t start, time_t end, ECalRecurInstanceFn cb, gpointer cb_data); G_END_DECLS diff --git a/calendar/gui/e-cal-view.c b/calendar/gui/e-cal-view.c index bb33b9bfc4..8a360bc921 100644 --- a/calendar/gui/e-cal-view.c +++ b/calendar/gui/e-cal-view.c @@ -173,8 +173,7 @@ e_calendar_view_class_init (ECalendarViewClass *klass) g_object_class_install_property (gobject_class, PROP_MODEL, g_param_spec_object ("model", NULL, NULL, E_TYPE_CAL_MODEL, - G_PARAM_READABLE | G_PARAM_WRITABLE - | G_PARAM_CONSTRUCT)); + G_PARAM_READABLE | G_PARAM_WRITABLE)); /* Create class' signals */ e_calendar_view_signals[SELECTION_CHANGED] = @@ -302,37 +301,6 @@ e_calendar_view_class_init (ECalendarViewClass *klass) e_cal_view_a11y_init (); } -static void -model_changed_cb (ETableModel *etm, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} - -static void -model_row_changed_cb (ETableModel *etm, int row, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} - -static void -model_cell_changed_cb (ETableModel *etm, int col, int row, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} - -static void -model_rows_changed_cb (ETableModel *etm, int row, int count, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} void e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart, @@ -449,16 +417,6 @@ e_calendar_view_init (ECalendarView *cal_view, ECalendarViewClass *klass) cal_view->priv = g_new0 (ECalendarViewPrivate, 1); cal_view->priv->model = (ECalModel *) e_cal_model_calendar_new (); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_changed", - G_CALLBACK (model_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_row_changed", - G_CALLBACK (model_row_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_cell_changed", - G_CALLBACK (model_cell_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_inserted", - G_CALLBACK (model_rows_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_deleted", - G_CALLBACK (model_rows_changed_cb), cal_view); } static void @@ -529,14 +487,7 @@ e_calendar_view_set_model (ECalendarView *cal_view, ECalModel *model) g_object_unref (cal_view->priv->model); } - cal_view->priv->model = model; - g_object_ref (cal_view->priv->model); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_changed", G_CALLBACK (model_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_row_changed", G_CALLBACK (model_row_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_cell_changed", G_CALLBACK (model_cell_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_inserted", G_CALLBACK (model_rows_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_deleted", G_CALLBACK (model_rows_changed_cb), cal_view); - + cal_view->priv->model = g_object_ref (model); e_calendar_view_update_query (cal_view); } diff --git a/calendar/gui/e-cal-view.h b/calendar/gui/e-cal-view.h index 28190b5672..4d72f1a0c4 100644 --- a/calendar/gui/e-cal-view.h +++ b/calendar/gui/e-cal-view.h @@ -59,7 +59,6 @@ typedef enum { #define E_CALENDAR_VIEW_EVENT_FIELDS \ GnomeCanvasItem *canvas_item; \ ECalModelComponent *comp_data; \ - gboolean allocated_comp_data; \ time_t start; \ time_t end; \ guint16 start_minute; \ diff --git a/calendar/gui/e-calendar-marshal.list b/calendar/gui/e-calendar-marshal.list index 86087cf1ae..a16f42053b 100644 --- a/calendar/gui/e-calendar-marshal.list +++ b/calendar/gui/e-calendar-marshal.list @@ -13,3 +13,4 @@ NONE:STRING,STRING,STRING NONE:POINTER,ENUM NONE:POINTER,STRING NONE:POINTER,POINTER +NONE:LONG,LONG diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c index bb33b9bfc4..8a360bc921 100644 --- a/calendar/gui/e-calendar-view.c +++ b/calendar/gui/e-calendar-view.c @@ -173,8 +173,7 @@ e_calendar_view_class_init (ECalendarViewClass *klass) g_object_class_install_property (gobject_class, PROP_MODEL, g_param_spec_object ("model", NULL, NULL, E_TYPE_CAL_MODEL, - G_PARAM_READABLE | G_PARAM_WRITABLE - | G_PARAM_CONSTRUCT)); + G_PARAM_READABLE | G_PARAM_WRITABLE)); /* Create class' signals */ e_calendar_view_signals[SELECTION_CHANGED] = @@ -302,37 +301,6 @@ e_calendar_view_class_init (ECalendarViewClass *klass) e_cal_view_a11y_init (); } -static void -model_changed_cb (ETableModel *etm, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} - -static void -model_row_changed_cb (ETableModel *etm, int row, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} - -static void -model_cell_changed_cb (ETableModel *etm, int col, int row, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} - -static void -model_rows_changed_cb (ETableModel *etm, int row, int count, gpointer user_data) -{ - ECalendarView *cal_view = E_CALENDAR_VIEW (user_data); - - e_calendar_view_update_query (cal_view); -} void e_calendar_view_add_event (ECalendarView *cal_view, ECal *client, time_t dtstart, @@ -449,16 +417,6 @@ e_calendar_view_init (ECalendarView *cal_view, ECalendarViewClass *klass) cal_view->priv = g_new0 (ECalendarViewPrivate, 1); cal_view->priv->model = (ECalModel *) e_cal_model_calendar_new (); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_changed", - G_CALLBACK (model_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_row_changed", - G_CALLBACK (model_row_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_cell_changed", - G_CALLBACK (model_cell_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_inserted", - G_CALLBACK (model_rows_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_deleted", - G_CALLBACK (model_rows_changed_cb), cal_view); } static void @@ -529,14 +487,7 @@ e_calendar_view_set_model (ECalendarView *cal_view, ECalModel *model) g_object_unref (cal_view->priv->model); } - cal_view->priv->model = model; - g_object_ref (cal_view->priv->model); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_changed", G_CALLBACK (model_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_row_changed", G_CALLBACK (model_row_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_cell_changed", G_CALLBACK (model_cell_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_inserted", G_CALLBACK (model_rows_changed_cb), cal_view); - g_signal_connect (G_OBJECT (cal_view->priv->model), "model_rows_deleted", G_CALLBACK (model_rows_changed_cb), cal_view); - + cal_view->priv->model = g_object_ref (model); e_calendar_view_update_query (cal_view); } diff --git a/calendar/gui/e-calendar-view.h b/calendar/gui/e-calendar-view.h index 28190b5672..4d72f1a0c4 100644 --- a/calendar/gui/e-calendar-view.h +++ b/calendar/gui/e-calendar-view.h @@ -59,7 +59,6 @@ typedef enum { #define E_CALENDAR_VIEW_EVENT_FIELDS \ GnomeCanvasItem *canvas_item; \ ECalModelComponent *comp_data; \ - gboolean allocated_comp_data; \ time_t start; \ time_t end; \ guint16 start_minute; \ diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index 0354ba4797..2dd2c1cca2 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -165,7 +165,7 @@ static GList *e_day_view_get_selected_events (ECalendarView *cal_view); static gboolean e_day_view_get_selected_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time); static void e_day_view_set_selected_time_range (ECalendarView *cal_view, time_t start_time, time_t end_time); static gboolean e_day_view_get_visible_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time); -static void e_day_view_update_query (ECalendarView *cal_view); +static void e_day_view_update_query (EDayView *day_view); static void e_day_view_goto_start_of_work_day (EDayView *day_view); static void e_day_view_goto_end_of_work_day (EDayView *day_view); static void e_day_view_change_duration_to_start_of_work_day (EDayView *day_view); @@ -480,7 +480,6 @@ e_day_view_class_init (EDayViewClass *class) view_class->get_selected_time_range = e_day_view_get_selected_time_range; view_class->set_selected_time_range = e_day_view_set_selected_time_range; view_class->get_visible_time_range = e_day_view_get_visible_time_range; - view_class->update_query = e_day_view_update_query; view_class->event_move = e_day_view_event_move; /* init the accessibility support for e_day_view */ @@ -488,6 +487,214 @@ e_day_view_class_init (EDayViewClass *class) } static void +time_range_changed_cb (ECalModel *model, time_t start_time, time_t end_time, gpointer user_data) +{ + EDayView *day_view = E_DAY_VIEW (user_data); + time_t lower; + + g_return_if_fail (E_IS_DAY_VIEW (day_view)); + + /* Calculate the first day that should be shown, based on start_time + and the days_shown setting. If we are showing 1 day it is just the + start of the day given by start_time, otherwise it is the previous + work-week start day. */ + if (!day_view->work_week_view) { + lower = time_day_begin_with_zone (start_time, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + } else { + lower = e_day_view_find_work_week_start (day_view, start_time); + } + + /* See if we need to change the days shown. */ + if (lower != day_view->lower) + e_day_view_recalc_day_starts (day_view, lower); + + e_day_view_set_selected_time_range (E_CALENDAR_VIEW (day_view), start_time, end_time); +} + + +static void +process_component (EDayView *day_view, ECalModelComponent *comp_data) +{ + EDayViewEvent *event; + gint day, event_num; + const char *uid; + ECalComponent *comp; + AddEventData add_event_data; + + /* If our time hasn't been set yet, just return. */ + if (day_view->lower == 0 && day_view->upper == 0) + return; + + /* If the event already exists and the dates didn't change, we can + update the event fairly easily without changing the events arrays + or computing a new layout. */ + uid = icalcomponent_get_uid (comp_data->icalcomp); + + if (e_day_view_find_event_from_uid (day_view, uid, &day, &event_num)) { + if (day == E_DAY_VIEW_LONG_EVENT) + event = &g_array_index (day_view->long_events, + EDayViewEvent, event_num); + else + event = &g_array_index (day_view->events[day], + EDayViewEvent, event_num); + + if (!e_cal_util_component_has_recurrences (comp_data->icalcomp) + && e_cal_util_event_dates_match (event->comp_data->icalcomp, comp_data->icalcomp)) { +#if 0 + g_print ("updated object's dates unchanged\n"); +#endif + e_day_view_foreach_event_with_uid (day_view, uid, e_day_view_update_event_cb, comp_data); + gtk_widget_queue_draw (day_view->top_canvas); + gtk_widget_queue_draw (day_view->main_canvas); + return; + } + + /* The dates have changed, so we need to remove the + old occurrrences before adding the new ones. */ +#if 0 + g_print ("dates changed - removing occurrences\n"); +#endif + e_day_view_foreach_event_with_uid (day_view, uid, + e_day_view_remove_event_cb, + NULL); + } + + /* Add the occurrences of the event */ + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); + + add_event_data.day_view = day_view; + add_event_data.comp_data = comp_data; + e_cal_recur_generate_instances (comp, day_view->lower, + day_view->upper, + e_day_view_add_event, &add_event_data, + e_cal_resolve_tzid_cb, comp_data->client, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + + g_object_unref (comp); +} + +static void +model_changed_cb (ETableModel *etm, gpointer user_data) +{ + EDayView *day_view = E_DAY_VIEW (user_data); + + e_day_view_update_query (day_view); +} + +static void +update_row (EDayView *day_view, int row) +{ + ECalModelComponent *comp_data; + ECalModel *model; + + e_day_view_stop_editing_event (day_view); + + model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)); + comp_data = e_cal_model_get_component_at (model, row); + g_assert (comp_data != NULL); + process_component (day_view, comp_data); + + gtk_widget_queue_draw (day_view->top_canvas); + gtk_widget_queue_draw (day_view->main_canvas); + e_day_view_queue_layout (day_view); +} + +static void +model_row_changed_cb (ETableModel *etm, int row, gpointer user_data) +{ + EDayView *day_view = E_DAY_VIEW (user_data); + + update_row (day_view, row); +} + +static void +model_cell_changed_cb (ETableModel *etm, int col, int row, gpointer user_data) +{ + EDayView *day_view = E_DAY_VIEW (user_data); + + update_row (day_view, row); +} + +static void +model_rows_inserted_cb (ETableModel *etm, int row, int count, gpointer user_data) +{ + EDayView *day_view = E_DAY_VIEW (user_data); + ECalModel *model; + int i; + + e_day_view_stop_editing_event (day_view); + + model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)); + for (i = 0; i < count; i++) { + ECalModelComponent *comp_data; + + comp_data = e_cal_model_get_component_at (model, row + i); + g_assert (comp_data != NULL); + process_component (day_view, comp_data); + } + + gtk_widget_queue_draw (day_view->top_canvas); + gtk_widget_queue_draw (day_view->main_canvas); + e_day_view_queue_layout (day_view); + +} + +static gboolean +row_deleted_check_cb (EDayView *day_view, gint day, gint event_num, gpointer data) +{ + GHashTable *uids = data; + EDayViewEvent *event; + ECalModel *model; + const char *uid; + + if (day == E_DAY_VIEW_LONG_EVENT) { + event = &g_array_index (day_view->long_events, EDayViewEvent, + event_num); + } else { + event = &g_array_index (day_view->events[day], EDayViewEvent, + event_num); + } + + uid = icalcomponent_get_uid (event->comp_data->icalcomp); + model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)); + + if (!e_cal_model_get_component_for_uid (model, uid)) + g_hash_table_insert (uids, (char *)uid, GINT_TO_POINTER (1)); + + return TRUE; +} + +static void +remove_uid_cb (gpointer key, gpointer value, gpointer data) +{ + EDayView *day_view = data; + const char *uid = key; + + e_day_view_foreach_event_with_uid (day_view, uid, e_day_view_remove_event_cb, NULL); +} + +static void +model_rows_deleted_cb (ETableModel *etm, int row, int count, gpointer user_data) +{ + EDayView *day_view = E_DAY_VIEW (user_data); + GHashTable *uids; + + e_day_view_stop_editing_event (day_view); + + uids = g_hash_table_new (g_str_hash, g_str_equal); + + e_day_view_foreach_event (day_view, row_deleted_check_cb, uids); + g_hash_table_foreach (uids, remove_uid_cb, day_view); + + g_hash_table_destroy (uids); + + gtk_widget_queue_draw (day_view->top_canvas); + gtk_widget_queue_draw (day_view->main_canvas); + e_day_view_queue_layout (day_view); +} + +static void timezone_changed_cb (ECalendarView *cal_view, icaltimezone *old_zone, icaltimezone *new_zone, gpointer user_data) { @@ -509,7 +716,7 @@ timezone_changed_cb (ECalendarView *cal_view, icaltimezone *old_zone, lower = icaltime_as_timet_with_zone (tt, new_zone); e_day_view_recalc_day_starts (day_view, lower); - e_day_view_update_query ((ECalendarView *) day_view); + e_day_view_update_query (day_view); } static void @@ -517,11 +724,10 @@ e_day_view_init (EDayView *day_view) { gint day; GnomeCanvasGroup *canvas_group; - + ECalModel *model; + GTK_WIDGET_SET_FLAGS (day_view, GTK_CAN_FOCUS); - day_view->query = NULL; - day_view->long_events = g_array_new (FALSE, FALSE, sizeof (EDayViewEvent)); day_view->long_events_sorted = TRUE; @@ -827,6 +1033,24 @@ e_day_view_init (EDayView *day_view) target_table, n_targets, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK); + /* Set the default model */ + model = E_CAL_MODEL (e_cal_model_calendar_new ()); + e_calendar_view_set_model (E_CALENDAR_VIEW (day_view), model); + + /* connect to ECalModel's signals */ + g_signal_connect (G_OBJECT (model), "time_range_changed", + G_CALLBACK (time_range_changed_cb), day_view); + g_signal_connect (G_OBJECT (model), "model_changed", + G_CALLBACK (model_changed_cb), day_view); + g_signal_connect (G_OBJECT (model), "model_row_changed", + G_CALLBACK (model_row_changed_cb), day_view); + g_signal_connect (G_OBJECT (model), "model_cell_changed", + G_CALLBACK (model_cell_changed_cb), day_view); + g_signal_connect (G_OBJECT (model), "model_rows_inserted", + G_CALLBACK (model_rows_inserted_cb), day_view); + g_signal_connect (G_OBJECT (model), "model_rows_deleted", + G_CALLBACK (model_rows_deleted_cb), day_view); + /* connect to ECalendarView's signals */ g_signal_connect (G_OBJECT (day_view), "timezone_changed", G_CALLBACK (timezone_changed_cb), NULL); @@ -853,19 +1077,13 @@ e_day_view_on_canvas_realized (GtkWidget *widget, GtkWidget * e_day_view_new (void) { - GtkWidget *day_view; - ECalModel *model; - - model = E_CAL_MODEL (e_cal_model_calendar_new ()); - - day_view = GTK_WIDGET (g_object_new (e_day_view_get_type (), "model", model, NULL)); + GObject *day_view; - g_object_unref (model); + day_view = g_object_new (e_day_view_get_type (), NULL); - return day_view; + return GTK_WIDGET (day_view); } - static void e_day_view_destroy (GtkObject *object) { @@ -878,13 +1096,6 @@ e_day_view_destroy (GtkObject *object) e_day_view_stop_auto_scroll (day_view); - if (day_view->query) { - g_signal_handlers_disconnect_matched (day_view->query, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, day_view); - g_object_unref (day_view->query); - day_view->query = NULL; - } - if (day_view->large_font_desc) { pango_font_description_free (day_view->large_font_desc); day_view->large_font_desc = NULL; @@ -1454,10 +1665,8 @@ e_day_view_update_event_cb (EDayView *day_view, event_num); } - if (event->allocated_comp_data) - e_cal_model_free_component_data (event->comp_data); - event->comp_data = comp_data; - event->allocated_comp_data = FALSE; + e_cal_model_free_component_data (event->comp_data); + event->comp_data = e_cal_model_copy_component_data (comp_data); if (day == E_DAY_VIEW_LONG_EVENT) { e_day_view_update_long_event_label (day_view, event_num); @@ -1584,10 +1793,7 @@ e_day_view_remove_event_cb (EDayView *day_view, if (event->canvas_item) gtk_object_destroy (GTK_OBJECT (event->canvas_item)); - if (event->allocated_comp_data) { - e_cal_model_free_component_data (event->comp_data); - event->allocated_comp_data = FALSE; - } + e_cal_model_free_component_data (event->comp_data); if (day == E_DAY_VIEW_LONG_EVENT) { g_array_remove_index (day_view->long_events, event_num); @@ -1811,83 +2017,6 @@ e_day_view_find_event_from_uid (EDayView *day_view, return FALSE; } - -/* This sets the selected time range. The EDayView will show the day or week - corresponding to the start time. If the start_time & end_time are not equal - and are both visible in the view, then the selection is set to those times, - otherwise it is set to 1 hour from the start of the working day. */ -static void -e_day_view_set_selected_time_range (ECalendarView *cal_view, - time_t start_time, - time_t end_time) -{ - time_t lower; - gint start_row, start_col, end_row, end_col; - gboolean need_redraw = FALSE, start_in_grid, end_in_grid; - EDayView *day_view = E_DAY_VIEW (cal_view); - - g_return_if_fail (E_IS_DAY_VIEW (day_view)); - - /* Calculate the first day that should be shown, based on start_time - and the days_shown setting. If we are showing 1 day it is just the - start of the day given by start_time, otherwise it is the previous - work-week start day. */ - if (!day_view->work_week_view) { - lower = time_day_begin_with_zone (start_time, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - } else { - lower = e_day_view_find_work_week_start (day_view, start_time); - } - - /* See if we need to change the days shown. */ - if (lower != day_view->lower) { - e_day_view_recalc_day_starts (day_view, lower); - e_day_view_update_query ((ECalendarView *) day_view); - } - - /* Set the selection. */ - start_in_grid = e_day_view_convert_time_to_grid_position (day_view, - start_time, - &start_col, - &start_row); - end_in_grid = e_day_view_convert_time_to_grid_position (day_view, - end_time - 60, - &end_col, - &end_row); - - /* If either of the times isn't in the grid, or the selection covers - an entire day, we set the selection to 1 row from the start of the - working day, in the day corresponding to the start time. */ - if (!start_in_grid || !end_in_grid - || (start_row == 0 && end_row == day_view->rows - 1)) { - end_col = start_col; - - start_row = e_day_view_convert_time_to_row (day_view, day_view->work_day_start_hour, day_view->work_day_start_minute); - start_row = CLAMP (start_row, 0, day_view->rows - 1); - end_row = start_row; - } - - if (start_row != day_view->selection_start_row - || start_col != day_view->selection_start_day) { - need_redraw = TRUE; - day_view->selection_in_top_canvas = FALSE; - day_view->selection_start_row = start_row; - day_view->selection_start_day = start_col; - } - - if (end_row != day_view->selection_end_row - || end_col != day_view->selection_end_day) { - need_redraw = TRUE; - day_view->selection_in_top_canvas = FALSE; - day_view->selection_end_row = end_row; - day_view->selection_end_day = end_col; - } - - if (need_redraw) { - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - } -} - static void e_day_view_set_selected_time_range_in_top_visible (EDayView *day_view, time_t start_time, @@ -2034,6 +2163,63 @@ e_day_view_find_work_week_start (EDayView *day_view, return icaltime_as_timet_with_zone (tt, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); } + +/* This sets the selected time range. If the start_time & end_time are not equal + and are both visible in the view, then the selection is set to those times, + otherwise it is set to 1 hour from the start of the working day. */ +static void +e_day_view_set_selected_time_range (ECalendarView *cal_view, + time_t start_time, + time_t end_time) +{ + gint start_row, start_col, end_row, end_col; + gboolean need_redraw = FALSE, start_in_grid, end_in_grid; + EDayView *day_view = E_DAY_VIEW (cal_view); + + /* Set the selection. */ + start_in_grid = e_day_view_convert_time_to_grid_position (day_view, + start_time, + &start_col, + &start_row); + end_in_grid = e_day_view_convert_time_to_grid_position (day_view, + end_time - 60, + &end_col, + &end_row); + + /* If either of the times isn't in the grid, or the selection covers + an entire day, we set the selection to 1 row from the start of the + working day, in the day corresponding to the start time. */ + if (!start_in_grid || !end_in_grid + || (start_row == 0 && end_row == day_view->rows - 1)) { + end_col = start_col; + + start_row = e_day_view_convert_time_to_row (day_view, day_view->work_day_start_hour, day_view->work_day_start_minute); + start_row = CLAMP (start_row, 0, day_view->rows - 1); + end_row = start_row; + } + + if (start_row != day_view->selection_start_row + || start_col != day_view->selection_start_day) { + need_redraw = TRUE; + day_view->selection_in_top_canvas = FALSE; + day_view->selection_start_row = start_row; + day_view->selection_start_day = start_col; + } + + if (end_row != day_view->selection_end_row + || end_col != day_view->selection_end_day) { + need_redraw = TRUE; + day_view->selection_in_top_canvas = FALSE; + day_view->selection_end_row = end_row; + day_view->selection_end_day = end_col; + } + + if (need_redraw) { + gtk_widget_queue_draw (day_view->top_canvas); + gtk_widget_queue_draw (day_view->main_canvas); + } +} + /* Returns the selected time range. */ static gboolean e_day_view_get_selected_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time) @@ -2111,7 +2297,7 @@ e_day_view_recalc_day_starts (EDayView *day_view, day_view->lower = start_time; day_view->upper = day_view->day_starts[day_view->days_shown]; - e_day_view_update_query ((ECalendarView *) day_view); + e_day_view_update_query (day_view); } @@ -2171,7 +2357,7 @@ e_day_view_set_days_shown (EDayView *day_view, e_day_view_recalc_day_starts (day_view, day_view->lower); e_day_view_recalc_cell_sizes (day_view); - e_day_view_update_query ((ECalendarView *) day_view); + e_day_view_update_query (day_view); } @@ -2414,7 +2600,7 @@ e_day_view_recalc_work_week (EDayView *day_view) day_view->selection_start_day = -1; e_day_view_recalc_day_starts (day_view, lower); - e_day_view_update_query ((ECalendarView *) day_view); + e_day_view_update_query (day_view); /* This updates the date navigator. */ e_day_view_update_calendar_selection_time (day_view); @@ -3132,76 +3318,11 @@ e_day_view_get_selected_events (ECalendarView *cal_view) return list; } -static void -process_component (EDayView *day_view, ECalModelComponent *comp_data) -{ - EDayViewEvent *event; - gint day, event_num; - const char *uid; - ECalComponent *comp; - AddEventData add_event_data; - - /* If our time hasn't been set yet, just return. */ - if (day_view->lower == 0 && day_view->upper == 0) - return; - - /* If the event already exists and the dates didn't change, we can - update the event fairly easily without changing the events arrays - or computing a new layout. */ - uid = icalcomponent_get_uid (comp_data->icalcomp); - - if (e_day_view_find_event_from_uid (day_view, uid, &day, &event_num)) { - if (day == E_DAY_VIEW_LONG_EVENT) - event = &g_array_index (day_view->long_events, - EDayViewEvent, event_num); - else - event = &g_array_index (day_view->events[day], - EDayViewEvent, event_num); - - if (!e_cal_util_component_has_recurrences (comp_data->icalcomp) - && e_cal_util_event_dates_match (event->comp_data->icalcomp, comp_data->icalcomp)) { -#if 0 - g_print ("updated object's dates unchanged\n"); -#endif - e_day_view_foreach_event_with_uid (day_view, uid, e_day_view_update_event_cb, comp_data); - gtk_widget_queue_draw (day_view->top_canvas); - gtk_widget_queue_draw (day_view->main_canvas); - return; - } - - /* The dates have changed, so we need to remove the - old occurrrences before adding the new ones. */ -#if 0 - g_print ("dates changed - removing occurrences\n"); -#endif - e_day_view_foreach_event_with_uid (day_view, uid, - e_day_view_remove_event_cb, - NULL); - } - - /* Add the occurrences of the event */ - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - - add_event_data.day_view = day_view; - add_event_data.comp_data = comp_data; - e_cal_recur_generate_instances (comp, day_view->lower, - day_view->upper, - e_day_view_add_event, &add_event_data, - e_cal_resolve_tzid_cb, comp_data->client, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - - g_object_unref (comp); - - e_day_view_queue_layout (day_view); -} - /* Restarts a query for the day view */ static void -e_day_view_update_query (ECalendarView *cal_view) +e_day_view_update_query (EDayView *day_view) { gint rows, r; - EDayView *day_view = E_DAY_VIEW (cal_view); e_day_view_stop_editing_event (day_view); @@ -3314,10 +3435,12 @@ e_day_view_update_calendar_selection_time (EDayView *day_view) g_print ("End : %s", ctime (&end)); #endif +#if 0 calendar = e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view)); if (calendar) gnome_calendar_set_selected_time_range (calendar, start, end); +#endif } @@ -3936,10 +4059,7 @@ e_day_view_free_event_array (EDayView *day_view, if (event->canvas_item) gtk_object_destroy (GTK_OBJECT (event->canvas_item)); - if (event->allocated_comp_data) { - e_cal_model_free_component_data (event->comp_data); - event->allocated_comp_data = FALSE; - } + e_cal_model_free_component_data (event->comp_data); } g_array_set_size (array, 0); @@ -3979,13 +4099,11 @@ e_day_view_add_event (ECalComponent *comp, e_calendar_view_get_timezone (E_CALENDAR_VIEW (add_event_data->day_view))); if (add_event_data->comp_data) { - event.comp_data = add_event_data->comp_data; - event.allocated_comp_data = FALSE; + event.comp_data = e_cal_model_copy_component_data (add_event_data->comp_data); } else { event.comp_data = g_new0 (ECalModelComponent, 1); - event.allocated_comp_data = TRUE; - event.comp_data->client = e_cal_model_get_default_client (e_calendar_view_get_model (E_CALENDAR_VIEW (add_event_data->day_view))); + event.comp_data->client = g_object_ref (e_cal_model_get_default_client (e_calendar_view_get_model (E_CALENDAR_VIEW (add_event_data->day_view)))); e_cal_component_commit_sequence (comp); event.comp_data->icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); } diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c index 61703486a4..14ed7f72c6 100644 --- a/calendar/gui/e-week-view.c +++ b/calendar/gui/e-week-view.c @@ -123,7 +123,7 @@ static GList *e_week_view_get_selected_events (ECalendarView *cal_view); static gboolean e_week_view_get_selected_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time); static void e_week_view_set_selected_time_range (ECalendarView *cal_view, time_t start_time, time_t end_time); static gboolean e_week_view_get_visible_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time); -static void e_week_view_update_query (ECalendarView *cal_view); +static void e_week_view_update_query (EWeekView *week_view); static void e_week_view_draw_shadow (EWeekView *week_view); static gboolean e_week_view_on_button_press (GtkWidget *widget, @@ -169,7 +169,9 @@ static gboolean e_week_view_find_event_from_uid (EWeekView *week_view, typedef gboolean (* EWeekViewForeachEventCallback) (EWeekView *week_view, gint event_num, gpointer data); - +static void e_week_view_foreach_event (EWeekView *week_view, + EWeekViewForeachEventCallback callback, + gpointer data); static void e_week_view_foreach_event_with_uid (EWeekView *week_view, const gchar *uid, EWeekViewForeachEventCallback callback, @@ -242,7 +244,6 @@ e_week_view_class_init (EWeekViewClass *class) view_class->get_selected_time_range = e_week_view_get_selected_time_range; view_class->set_selected_time_range = e_week_view_set_selected_time_range; view_class->get_visible_time_range = e_week_view_get_visible_time_range; - view_class->update_query = e_week_view_update_query; view_class->event_move = e_week_view_event_move; /* init the accessibility support for e_week_view */ @@ -250,13 +251,272 @@ e_week_view_class_init (EWeekViewClass *class) } static void +time_range_changed_cb (ECalModel *model, time_t start_time, time_t end_time, gpointer user_data) +{ + EWeekView *week_view = E_WEEK_VIEW (user_data); + GDate date, base_date, end_date; + gint day_offset, weekday, week_start_offset, num_days; + gboolean update_adjustment_value = FALSE; + + g_return_if_fail (E_IS_WEEK_VIEW (week_view)); + + time_to_gdate_with_zone (&date, start_time, e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); + + if (week_view->multi_week_view) { + /* Find the number of days since the start of the month. */ + day_offset = g_date_day (&date) - 1; + + /* Find the 1st week which starts at or before the start of + the month. */ + base_date = date; + g_date_set_day (&base_date, 1); + + /* Calculate the weekday of the 1st of the month, 0 = Mon. */ + weekday = g_date_weekday (&base_date) - 1; + + /* Convert it to an offset from the start of the display. */ + week_start_offset = (weekday + 7 - week_view->display_start_day) % 7; + + /* Add it to the day offset so we go back to the 1st week at + or before the start of the month. */ + day_offset += week_start_offset; + } else { + /* Calculate the weekday of the given date, 0 = Mon. */ + weekday = g_date_weekday (&date) - 1; + + /* Convert it to an offset from the start of the display. */ + week_start_offset = (weekday + 7 - week_view->display_start_day) % 7; + + /* Set the day_offset to the result, so we move back to the + start of the week. */ + day_offset = week_start_offset; + } + + /* Calculate the base date, i.e. the first day shown when the + scrollbar adjustment value is 0. */ + base_date = date; + g_date_subtract_days (&base_date, day_offset); + + /* See if we need to update the base date. */ + if (!g_date_valid (&week_view->base_date) + || g_date_compare (&week_view->base_date, &base_date)) { + week_view->base_date = base_date; + update_adjustment_value = TRUE; + } + + /* See if we need to update the first day shown. */ + if (!g_date_valid (&week_view->first_day_shown) + || g_date_compare (&week_view->first_day_shown, &base_date)) { + week_view->first_day_shown = base_date; + start_time = time_add_day_with_zone (start_time, -day_offset, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); + start_time = time_day_begin_with_zone (start_time, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); + e_week_view_recalc_day_starts (week_view, start_time); + } + + /* Reset the adjustment value to 0 if the base address has changed. + Note that we do this after updating first_day_shown so that our + signal handler will not try to reload the events. */ + if (update_adjustment_value) + gtk_adjustment_set_value (GTK_RANGE (week_view->vscrollbar)->adjustment, 0); + + gtk_widget_queue_draw (week_view->main_canvas); + + /* FIXME Only select one day */ + e_week_view_set_selected_time_range (E_CALENDAR_VIEW (week_view), start_time, end_time); +} + + +static void +process_component (EWeekView *week_view, ECalModelComponent *comp_data) +{ + EWeekViewEvent *event; + gint event_num, num_days; + ECalComponent *comp = NULL; + AddEventData add_event_data; + const char *uid; + + /* If we don't have a valid date set yet, just return. */ + if (!g_date_valid (&week_view->first_day_shown)) + return; + + comp = e_cal_component_new (); + if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp))) { + g_object_unref (comp); + + g_message ("process_component(): Could not set icalcomponent on ECalComponent"); + return; + } + + e_cal_component_get_uid (comp, &uid); + + /* If the event already exists and the dates didn't change, we can + update the event fairly easily without changing the events arrays + or computing a new layout. */ + if (e_week_view_find_event_from_uid (week_view, uid, &event_num)) { + ECalComponent *tmp_comp; + + event = &g_array_index (week_view->events, EWeekViewEvent, + event_num); + + tmp_comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (tmp_comp, icalcomponent_new_clone (comp_data->icalcomp)); + if (!e_cal_component_has_recurrences (comp) + && !e_cal_component_has_recurrences (tmp_comp) + && e_cal_component_event_dates_match (comp, tmp_comp)) { +#if 0 + g_print ("updated object's dates unchanged\n"); +#endif + e_week_view_foreach_event_with_uid (week_view, uid, e_week_view_update_event_cb, comp_data); + g_object_unref (comp); + g_object_unref (tmp_comp); + gtk_widget_queue_draw (week_view->main_canvas); + return; + } + + /* The dates have changed, so we need to remove the + old occurrrences before adding the new ones. */ +#if 0 + g_print ("dates changed - removing occurrences\n"); +#endif + e_week_view_foreach_event_with_uid (week_view, uid, + e_week_view_remove_event_cb, + NULL); + + g_object_unref (tmp_comp); + } + + /* Add the occurrences of the event */ + num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; + + add_event_data.week_view = week_view; + add_event_data.comp_data = comp_data; + e_cal_recur_generate_instances (comp, + week_view->day_starts[0], + week_view->day_starts[num_days], + e_week_view_add_event, &add_event_data, + e_cal_resolve_tzid_cb, comp_data->client, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); + + g_object_unref (comp); + + e_week_view_queue_layout (week_view); +} + +static void +model_changed_cb (ETableModel *etm, gpointer user_data) +{ + EWeekView *week_view = E_WEEK_VIEW (user_data); + + e_week_view_update_query (week_view); +} + +static void +update_row (EWeekView *week_view, int row) +{ + ECalModelComponent *comp_data; + ECalModel *model; + + model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)); + comp_data = e_cal_model_get_component_at (model, row); + g_assert (comp_data != NULL); + process_component (week_view, comp_data); + + gtk_widget_queue_draw (week_view->main_canvas); + e_week_view_queue_layout (week_view); +} + +static void +model_row_changed_cb (ETableModel *etm, int row, gpointer user_data) +{ + EWeekView *week_view = E_WEEK_VIEW (user_data); + + update_row (week_view, row); +} + +static void +model_cell_changed_cb (ETableModel *etm, int col, int row, gpointer user_data) +{ + EWeekView *week_view = E_WEEK_VIEW (user_data); + + update_row (week_view, row); +} + +static void +model_rows_inserted_cb (ETableModel *etm, int row, int count, gpointer user_data) +{ + EWeekView *week_view = E_WEEK_VIEW (user_data); + ECalModel *model; + int i; + + model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)); + for (i = 0; i < count; i++) { + ECalModelComponent *comp_data; + + comp_data = e_cal_model_get_component_at (model, row + i); + g_assert (comp_data != NULL); + process_component (week_view, comp_data); + } + + gtk_widget_queue_draw (week_view->main_canvas); + e_week_view_queue_layout (week_view); +} + +static gboolean +row_deleted_check_cb (EWeekView *week_view, gint event_num, gpointer data) +{ + GHashTable *uids = data; + EWeekViewEvent *event; + ECalModel *model; + const char *uid; + + event = &g_array_index (week_view->events, EWeekViewEvent, event_num); + uid = icalcomponent_get_uid (event->comp_data->icalcomp); + model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)); + + if (!e_cal_model_get_component_for_uid (model, uid)) + g_hash_table_insert (uids, (char *)uid, GINT_TO_POINTER (1)); + + return TRUE; +} + +static void +remove_uid_cb (gpointer key, gpointer value, gpointer data) +{ + EWeekView *week_view = data; + const char *uid = key; + + e_week_view_foreach_event_with_uid (week_view, uid, e_week_view_remove_event_cb, NULL); +} + +static void +model_rows_deleted_cb (ETableModel *etm, int row, int count, gpointer user_data) +{ + EWeekView *week_view = E_WEEK_VIEW (user_data); + GHashTable *uids; + + /* FIXME Stop editing? */ + + uids = g_hash_table_new (g_str_hash, g_str_equal); + + e_week_view_foreach_event (week_view, row_deleted_check_cb, uids); + g_hash_table_foreach (uids, remove_uid_cb, week_view); + + g_hash_table_destroy (uids); + + gtk_widget_queue_draw (week_view->main_canvas); + e_week_view_queue_layout (week_view); +} + +static void timezone_changed_cb (ECalendarView *cal_view, icaltimezone *old_zone, icaltimezone *new_zone, gpointer user_data) { struct icaltimetype tt = icaltime_null_time (); time_t lower; EWeekView *week_view = (EWeekView *) cal_view; - + g_return_if_fail (E_IS_WEEK_VIEW (week_view)); /* If we don't have a valid date set yet, just return. */ @@ -272,7 +532,7 @@ timezone_changed_cb (ECalendarView *cal_view, icaltimezone *old_zone, lower = icaltime_as_timet_with_zone (tt, new_zone); e_week_view_recalc_day_starts (week_view, lower); - e_week_view_update_query ((ECalendarView *) week_view); + e_week_view_update_query (week_view); } static void @@ -281,6 +541,7 @@ e_week_view_init (EWeekView *week_view) GnomeCanvasGroup *canvas_group; GtkObject *adjustment; GdkPixbuf *pixbuf; + ECalModel *model; gint i; GTK_WIDGET_SET_FLAGS (week_view, GTK_CAN_FOCUS); @@ -415,6 +676,24 @@ e_week_view_init (EWeekView *week_view) week_view->resize_width_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); week_view->last_cursor_set = NULL; + /* Set the default model */ + model = E_CAL_MODEL (e_cal_model_calendar_new ()); + e_calendar_view_set_model (E_CALENDAR_VIEW (week_view), model); + + /* connect to ECalModel's signals */ + g_signal_connect (G_OBJECT (model), "time_range_changed", + G_CALLBACK (time_range_changed_cb), week_view); + g_signal_connect (G_OBJECT (model), "model_changed", + G_CALLBACK (model_changed_cb), week_view); + g_signal_connect (G_OBJECT (model), "model_row_changed", + G_CALLBACK (model_row_changed_cb), week_view); + g_signal_connect (G_OBJECT (model), "model_cell_changed", + G_CALLBACK (model_cell_changed_cb), week_view); + g_signal_connect (G_OBJECT (model), "model_rows_inserted", + G_CALLBACK (model_rows_inserted_cb), week_view); + g_signal_connect (G_OBJECT (model), "model_rows_deleted", + G_CALLBACK (model_rows_deleted_cb), week_view); + /* connect to ECalendarView's signals */ g_signal_connect (G_OBJECT (week_view), "timezone_changed", G_CALLBACK (timezone_changed_cb), NULL); @@ -431,13 +710,8 @@ GtkWidget * e_week_view_new (void) { GtkWidget *week_view; - ECalModel *model; - model = E_CAL_MODEL (e_cal_model_calendar_new ()); - - week_view = GTK_WIDGET (g_object_new (e_week_view_get_type (), "model", model, NULL)); - - g_object_unref (model); + week_view = GTK_WIDGET (g_object_new (e_week_view_get_type (), NULL)); return week_view; } @@ -1101,88 +1375,11 @@ e_week_view_get_selected_events (ECalendarView *cal_view) return list; } -static void -process_component (EWeekView *week_view, ECalModelComponent *comp_data) -{ - EWeekViewEvent *event; - gint event_num, num_days; - ECalComponent *comp = NULL; - AddEventData add_event_data; - const char *uid; - - /* If we don't have a valid date set yet, just return. */ - if (!g_date_valid (&week_view->first_day_shown)) - return; - - comp = e_cal_component_new (); - if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp))) { - g_object_unref (comp); - - g_message ("process_component(): Could not set icalcomponent on ECalComponent"); - return; - } - - e_cal_component_get_uid (comp, &uid); - - /* If the event already exists and the dates didn't change, we can - update the event fairly easily without changing the events arrays - or computing a new layout. */ - if (e_week_view_find_event_from_uid (week_view, uid, &event_num)) { - ECalComponent *tmp_comp; - - event = &g_array_index (week_view->events, EWeekViewEvent, - event_num); - - tmp_comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (tmp_comp, icalcomponent_new_clone (comp_data->icalcomp)); - if (!e_cal_component_has_recurrences (comp) - && !e_cal_component_has_recurrences (tmp_comp) - && e_cal_component_event_dates_match (comp, tmp_comp)) { -#if 0 - g_print ("updated object's dates unchanged\n"); -#endif - e_week_view_foreach_event_with_uid (week_view, uid, e_week_view_update_event_cb, comp_data); - g_object_unref (comp); - g_object_unref (tmp_comp); - gtk_widget_queue_draw (week_view->main_canvas); - return; - } - - /* The dates have changed, so we need to remove the - old occurrrences before adding the new ones. */ -#if 0 - g_print ("dates changed - removing occurrences\n"); -#endif - e_week_view_foreach_event_with_uid (week_view, uid, - e_week_view_remove_event_cb, - NULL); - - g_object_unref (tmp_comp); - } - - /* Add the occurrences of the event */ - num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7; - - add_event_data.week_view = week_view; - add_event_data.comp_data = comp_data; - e_cal_recur_generate_instances (comp, - week_view->day_starts[0], - week_view->day_starts[num_days], - e_week_view_add_event, &add_event_data, - e_cal_resolve_tzid_cb, comp_data->client, - e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - - g_object_unref (comp); - - e_week_view_queue_layout (week_view); -} - /* Restarts a query for the week view */ static void -e_week_view_update_query (ECalendarView *cal_view) +e_week_view_update_query (EWeekView *week_view) { gint rows, r; - EWeekView *week_view = E_WEEK_VIEW (cal_view); gtk_widget_queue_draw (week_view->main_canvas); e_week_view_free_events (week_view); @@ -1291,7 +1488,7 @@ e_week_view_set_selected_time_range (ECalendarView *cal_view, start_time = time_day_begin_with_zone (start_time, e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); e_week_view_recalc_day_starts (week_view, start_time); - e_week_view_update_query ((ECalendarView *) week_view); + e_week_view_update_query (week_view); } /* Set the selection to the given days. */ @@ -1475,7 +1672,7 @@ e_week_view_set_first_day_shown (EWeekView *week_view, e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); e_week_view_recalc_day_starts (week_view, start_time); - e_week_view_update_query ((ECalendarView *) week_view); + e_week_view_update_query (week_view); } /* Try to keep the previous selection, but if it is no longer shown @@ -1612,7 +1809,7 @@ e_week_view_set_weeks_shown (EWeekView *week_view, if (g_date_valid (&week_view->first_day_shown)) e_week_view_set_first_day_shown (week_view, &week_view->first_day_shown); - e_week_view_update_query ((ECalendarView *) week_view); + e_week_view_update_query (week_view); } } @@ -1756,10 +1953,8 @@ e_week_view_update_event_cb (EWeekView *week_view, event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - if (event->allocated_comp_data) - e_cal_model_free_component_data (event->comp_data); - event->comp_data = comp_data; - event->allocated_comp_data = FALSE; + e_cal_model_free_component_data (event->comp_data); + event->comp_data = e_cal_model_copy_component_data (comp_data); for (span_num = 0; span_num < event->num_spans; span_num++) { span = &g_array_index (week_view->spans, EWeekViewEventSpan, @@ -1782,6 +1977,26 @@ e_week_view_update_event_cb (EWeekView *week_view, return TRUE; } +/* This calls a given function for each event instance Note that it is + safe for the callback to remove the event (since we step backwards + through the arrays). */ +static void +e_week_view_foreach_event (EWeekView *week_view, + EWeekViewForeachEventCallback callback, + gpointer data) +{ + EWeekViewEvent *event; + gint event_num; + + for (event_num = week_view->events->len - 1; + event_num >= 0; + event_num--) { + event = &g_array_index (week_view->events, EWeekViewEvent, event_num); + + if (!(*callback) (week_view, event_num, data)) + return; + } +} /* This calls a given function for each event instance that matches the given uid. Note that it is safe for the callback to remove the event (since we @@ -1844,10 +2059,7 @@ e_week_view_remove_event_cb (EWeekView *week_view, } } - if (event->allocated_comp_data) { - e_cal_model_free_component_data (event->comp_data); - event->allocated_comp_data = FALSE; - } + e_cal_model_free_component_data (event->comp_data); g_array_remove_index (week_view->events, event_num); week_view->events_need_layout = TRUE; @@ -2018,8 +2230,6 @@ e_week_view_on_button_release (GtkWidget *widget, GdkEventButton *event, EWeekView *week_view) { - time_t start, end; - #if 0 g_print ("In e_week_view_on_button_release\n"); #endif @@ -2027,11 +2237,6 @@ e_week_view_on_button_release (GtkWidget *widget, if (week_view->selection_drag_pos != E_WEEK_VIEW_DRAG_NONE) { week_view->selection_drag_pos = E_WEEK_VIEW_DRAG_NONE; gdk_pointer_ungrab (event->time); - start = week_view->day_starts[week_view->selection_start_day]; - end = week_view->day_starts[week_view->selection_end_day + 1]; - - gnome_calendar_set_selected_time_range (e_calendar_view_get_calendar (E_CALENDAR_VIEW (week_view)), - start, end); } return FALSE; @@ -2203,8 +2408,7 @@ e_week_view_free_events (EWeekView *week_view) for (event_num = 0; event_num < week_view->events->len; event_num++) { event = &g_array_index (week_view->events, EWeekViewEvent, event_num); - if (event->allocated_comp_data) - e_cal_model_free_component_data (event->comp_data); + e_cal_model_free_component_data (event->comp_data); } g_array_set_size (week_view->events, 0); @@ -2270,13 +2474,11 @@ e_week_view_add_event (ECalComponent *comp, e_calendar_view_get_timezone (E_CALENDAR_VIEW (add_event_data->week_view))); if (add_event_data->comp_data) { - event.comp_data = add_event_data->comp_data; - event.allocated_comp_data = FALSE; + event.comp_data = e_cal_model_copy_component_data (add_event_data->comp_data); } else { event.comp_data = g_new0 (ECalModelComponent, 1); - event.allocated_comp_data = TRUE; - event.comp_data->client = e_cal_model_get_default_client (e_calendar_view_get_model (E_CALENDAR_VIEW (add_event_data->week_view))); + event.comp_data->client = g_object_ref (e_cal_model_get_default_client (e_calendar_view_get_model (E_CALENDAR_VIEW (add_event_data->week_view)))); e_cal_component_commit_sequence (comp); event.comp_data->icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); } @@ -2735,7 +2937,7 @@ e_week_view_on_adjustment_changed (GtkAdjustment *adjustment, lower = icaltime_as_timet_with_zone (start_tt, e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); e_week_view_recalc_day_starts (week_view, lower); - e_week_view_update_query ((ECalendarView *) week_view); + e_week_view_update_query (week_view); /* Update the selection, if needed. */ if (week_view->selection_start_day != -1) { diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index 381a2fe274..4b1bb840aa 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -98,13 +98,9 @@ struct _GnomeCalendarPrivate { * Fields for the calendar view */ - /* This is the last selection explicitly selected by the user. We try - to keep it the same when we switch views, but we may have to alter - it depending on the view (e.g. the week views only select days, so - any times are lost. */ - time_t selection_start_time; - time_t selection_end_time; - + /* This is the last time explicitly selected by the user */ + time_t base_view_time; + /* Widgets */ GtkWidget *search_bar; @@ -154,6 +150,9 @@ struct _GnomeCalendarPrivate { GalViewInstance *view_instance; GalViewMenus *view_menus; + /* Our current week start */ + int week_start; + /* Our current timezone. */ icaltimezone *zone; @@ -195,7 +194,7 @@ static void gnome_calendar_goto_date (GnomeCalendar *gcal, GnomeCalendarGotoDateType goto_date); static void gnome_calendar_set_pane_positions (GnomeCalendar *gcal); -static void gnome_calendar_update_view_times (GnomeCalendar *gcal); +static void update_view_times (GnomeCalendar *gcal, time_t start_time); static void gnome_calendar_update_date_navigator (GnomeCalendar *gcal); static void gnome_calendar_hpane_realized (GtkWidget *w, GnomeCalendar *gcal); @@ -450,6 +449,44 @@ gnome_calendar_get_current_view_widget (GnomeCalendar *gcal) return GTK_WIDGET (priv->views[priv->current_view_type]); } +static void +get_times_for_views (GnomeCalendar *gcal, GnomeCalendarViewType view_type, time_t *start_time, time_t *end_time) +{ + GnomeCalendarPrivate *priv; + int days_shown; + + priv = gcal->priv; + + switch (view_type) { + case GNOME_CAL_DAY_VIEW: + days_shown = e_day_view_get_days_shown (E_DAY_VIEW (priv->views[view_type])); + *start_time = time_day_begin_with_zone (*start_time, priv->zone); + *end_time = time_add_day_with_zone (*start_time, days_shown, priv->zone); + break; + case GNOME_CAL_WORK_WEEK_VIEW: + /* FIXME this should actually be the first working day */ + *start_time = time_week_begin_with_zone (*start_time, priv->week_start, priv->zone); + *end_time = time_add_day_with_zone (*start_time, 5, priv->zone); + break; + case GNOME_CAL_WEEK_VIEW: + *start_time = time_week_begin_with_zone (*start_time, priv->week_start, priv->zone); + *end_time = time_add_week_with_zone (*start_time, 1, priv->zone); + break; + case GNOME_CAL_MONTH_VIEW: + *start_time = time_month_begin_with_zone (*start_time, priv->zone); + *end_time = time_add_month_with_zone (*start_time, 1, priv->zone); + break; + case GNOME_CAL_LIST_VIEW: + /* FIXME What to do here? */ + *start_time = time_month_begin_with_zone (*start_time, priv->zone); + *end_time = time_add_month_with_zone (*start_time, 1, priv->zone); + break; + default: + g_assert_not_reached (); + return; + } +} + /* Gets the focus location based on who is the focused widget within the * calendar view. */ @@ -636,31 +673,7 @@ update_query (GnomeCalendar *gcal) } static void -adjust_e_cal_view_for_view (ECalendarView *cal_view, const char *sexp) -{ - char *real_sexp, *start, *end; - time_t ttstart, ttend; - - e_calendar_view_get_visible_time_range (cal_view, &ttstart, &ttend); - - start = isodate_from_time_t (ttstart); - end = isodate_from_time_t (ttend); - - real_sexp = g_strdup_printf ( - "(and (occur-in-time-range? (make-time \"%s\")" - " (make-time \"%s\"))" - " %s)", - start, end, sexp); - - e_cal_model_set_query (e_calendar_view_get_model (cal_view), real_sexp); - - g_free (start); - g_free (end); - g_free (real_sexp); -} - -static void -set_query (GnomeCalendar *gcal, const char *sexp) +set_search_query (GnomeCalendar *gcal, const char *sexp) { GnomeCalendarPrivate *priv; ECalModel *model; @@ -683,11 +696,11 @@ set_query (GnomeCalendar *gcal, const char *sexp) /* Set the query on the views */ for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) - adjust_e_cal_view_for_view (E_CALENDAR_VIEW (priv->views[i]), sexp); + e_cal_model_set_search_query (e_calendar_view_get_model (priv->views[i]), sexp); /* Set the query on the task pad */ model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)); - e_cal_model_set_query (model, sexp); + e_cal_model_set_search_query (model, sexp); } /* Returns the current time, for the ECalendarItem. */ @@ -717,7 +730,7 @@ search_bar_sexp_changed_cb (CalSearchBar *cal_search, const char *sexp, gpointer GnomeCalendar *gcal; gcal = GNOME_CALENDAR (data); - set_query (gcal, sexp); + set_search_query (gcal, sexp); } /* Callback used when the selected category in the search bar changes */ @@ -831,6 +844,25 @@ table_selection_change_cb (ETable *etable, gpointer data) } static void +set_week_start (GnomeCalendar *calendar) +{ + GnomeCalendarPrivate *priv; + + priv = calendar->priv; + + /* FIXME we should adjust the week and work week views */ + priv->week_start = calendar_config_get_week_start_day (); +} + +static void +week_start_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data) +{ + GnomeCalendar *calendar = data; + + set_week_start (calendar); +} + +static void set_timezone (GnomeCalendar *calendar) { GnomeCalendarPrivate *priv; @@ -871,10 +903,14 @@ setup_config (GnomeCalendar *calendar) guint not; priv = calendar->priv; - + + /* Week Start */ + set_week_start (calendar); + not = calendar_config_add_notification_week_start_day (week_start_changed_cb, calendar); + priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); + /* Timezone */ - set_timezone (calendar); - + set_timezone (calendar); not = calendar_config_add_notification_timezone (timezone_changed_cb, calendar); priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not)); @@ -1028,10 +1064,11 @@ setup_widgets (GnomeCalendar *gcal) GTK_WIDGET (priv->views[i]), gtk_label_new ("")); gtk_widget_show (GTK_WIDGET (priv->views[i])); - - /* make sure we set the initial queries for the views */ - //adjust_e_cal_view_for_view (E_CALENDAR_VIEW (priv->views[i]), ""); } + + /* make sure we set the initial time ranges for the views */ + update_view_times (gcal, time (NULL)); + gnome_calendar_update_date_navigator (gcal); } /* Object initialization function for the gnome calendar */ @@ -1054,13 +1091,9 @@ gnome_calendar_init (GnomeCalendar *gcal) setup_config (gcal); setup_widgets (gcal); - priv->dn_queries = NULL; + priv->dn_queries = NULL; priv->sexp = g_strdup ("#t"); /* Match all */ - priv->selection_start_time = time_day_begin_with_zone (time (NULL), - priv->zone); - priv->selection_end_time = time_add_day_with_zone (priv->selection_start_time, 1, priv->zone); - priv->view_instance = NULL; priv->view_menus = NULL; @@ -1185,8 +1218,7 @@ gnome_calendar_goto_date (GnomeCalendar *gcal, GnomeCalendarGotoDateType goto_date) { GnomeCalendarPrivate *priv; - time_t start_time; - time_t end_time; + time_t new_time; gboolean need_updating = FALSE; g_return_if_fail (gcal != NULL); @@ -1194,8 +1226,6 @@ gnome_calendar_goto_date (GnomeCalendar *gcal, priv = gcal->priv; - gnome_calendar_get_current_time_range (gcal, &start_time, &end_time); - switch (goto_date) { /* GNOME_CAL_GOTO_TODAY and GNOME_CAL_GOTO_DATE are currently not used @@ -1205,75 +1235,47 @@ gnome_calendar_goto_date (GnomeCalendar *gcal, case GNOME_CAL_GOTO_DATE: break; case GNOME_CAL_GOTO_FIRST_DAY_OF_MONTH: - priv->selection_start_time = - time_month_begin_with_zone (start_time, priv->zone); - priv->selection_end_time = - time_add_day_with_zone (priv->selection_start_time, - 1, priv->zone); + new_time = time_month_begin_with_zone (priv->base_view_time, priv->zone); need_updating = TRUE; break; case GNOME_CAL_GOTO_LAST_DAY_OF_MONTH: - start_time = time_add_month_with_zone (start_time, 1, - priv->zone); - priv->selection_end_time = - time_month_begin_with_zone (start_time, priv->zone); - priv->selection_start_time = - time_add_day_with_zone (priv->selection_end_time, - -1, priv->zone); + new_time = time_add_month_with_zone (priv->base_view_time, 1, priv->zone); + new_time = time_month_begin_with_zone (new_time, priv->zone); + new_time = time_add_day_with_zone (new_time, -1, priv->zone); need_updating = TRUE; break; case GNOME_CAL_GOTO_FIRST_DAY_OF_WEEK: - /* 1 for Monday */ - priv->selection_start_time = - time_week_begin_with_zone (start_time, 1, priv->zone); - priv->selection_end_time = - time_add_day_with_zone (priv->selection_start_time, - 1, priv->zone); + new_time = time_week_begin_with_zone (priv->base_view_time, priv->week_start, priv->zone); need_updating = TRUE; break; case GNOME_CAL_GOTO_LAST_DAY_OF_WEEK: - /* 1 for Monday */ - start_time = time_week_begin_with_zone (start_time, 1, - priv->zone); + new_time = time_week_begin_with_zone (priv->base_view_time, priv->week_start, priv->zone); if (priv->current_view_type == GNOME_CAL_DAY_VIEW || priv->current_view_type == GNOME_CAL_WORK_WEEK_VIEW) { + /* FIXME Shouldn't hard code work week end */ /* goto Friday of this week */ - priv->selection_start_time = - time_add_day_with_zone (start_time, - 4, priv->zone); - } - else { + new_time = time_add_day_with_zone (new_time, 4, priv->zone); + } else { /* goto Sunday of this week */ - priv->selection_start_time = - time_add_day_with_zone (start_time, - 6, priv->zone); + /* FIXME Shouldn't hard code week end */ + new_time = time_add_day_with_zone (new_time, 6, priv->zone); } - priv->selection_end_time = - time_add_day_with_zone (priv->selection_start_time, - 1, priv->zone); need_updating = TRUE; break; case GNOME_CAL_GOTO_SAME_DAY_OF_PREVIOUS_WEEK: - priv->selection_start_time = time_add_day_with_zone (start_time, - -7, priv->zone); - priv->selection_end_time = time_add_day_with_zone (end_time, - -7,priv->zone); + new_time = time_add_week_with_zone (priv->base_view_time, -1, priv->zone); need_updating = TRUE; break; case GNOME_CAL_GOTO_SAME_DAY_OF_NEXT_WEEK: - priv->selection_start_time = time_add_day_with_zone (start_time, - 7, priv->zone); - priv->selection_end_time = time_add_day_with_zone (end_time, - 7,priv->zone); + new_time = time_add_week_with_zone (priv->base_view_time, 1, priv->zone); need_updating = TRUE; break; - default: break; } if (need_updating) { - gnome_calendar_update_view_times (gcal); + update_view_times (gcal, new_time); gnome_calendar_update_date_navigator (gcal); gnome_calendar_notify_dates_shown_changed (gcal); } @@ -1283,81 +1285,67 @@ void gnome_calendar_goto (GnomeCalendar *gcal, time_t new_time) { GnomeCalendarPrivate *priv; - + g_return_if_fail (gcal != NULL); g_return_if_fail (GNOME_IS_CALENDAR (gcal)); g_return_if_fail (new_time != -1); priv = gcal->priv; - priv->selection_start_time = time_day_begin_with_zone (new_time, - priv->zone); - priv->selection_end_time = time_add_day_with_zone (priv->selection_start_time, 1, priv->zone); - - gnome_calendar_update_view_times (gcal); + update_view_times (gcal, new_time); gnome_calendar_update_date_navigator (gcal); gnome_calendar_notify_dates_shown_changed (gcal); } static void -gnome_calendar_update_view_times (GnomeCalendar *gcal) +update_view_times (GnomeCalendar *gcal, time_t start_time) { GnomeCalendarPrivate *priv; - + int i; + priv = gcal->priv; + + priv->base_view_time = start_time; - e_calendar_view_set_selected_time_range (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)), - priv->selection_start_time, - priv->selection_end_time); + for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) { + ECalModel *model; + time_t real_start_time = start_time; + time_t end_time; + + model = e_calendar_view_get_model (priv->views[i]); + get_times_for_views (gcal, i, &real_start_time, &end_time); + + e_cal_model_set_time_range (model, real_start_time, end_time); + } } static void gnome_calendar_direction (GnomeCalendar *gcal, int direction) { GnomeCalendarPrivate *priv; - time_t start_time, end_time; priv = gcal->priv; - start_time = priv->selection_start_time; - end_time = priv->selection_end_time; - switch (priv->current_view_type) { case GNOME_CAL_DAY_VIEW: - start_time = time_add_day_with_zone (start_time, direction, - priv->zone); - end_time = time_add_day_with_zone (end_time, direction, - priv->zone); + priv->base_view_time = time_add_day_with_zone (priv->base_view_time, direction, priv->zone); break; - case GNOME_CAL_WORK_WEEK_VIEW: case GNOME_CAL_WEEK_VIEW: - start_time = time_add_week_with_zone (start_time, direction, - priv->zone); - end_time = time_add_week_with_zone (end_time, direction, - priv->zone); + priv->base_view_time = time_add_week_with_zone (priv->base_view_time, direction, priv->zone); break; - case GNOME_CAL_LIST_VIEW: g_warning ("Using month view time interval for list view."); case GNOME_CAL_MONTH_VIEW: - start_time = time_add_month_with_zone (start_time, direction, - priv->zone); - end_time = time_add_month_with_zone (end_time, direction, - priv->zone); + priv->base_view_time = time_add_month_with_zone (priv->base_view_time, direction, priv->zone); break; - default: - g_warning ("Weee! Where did the penguin go?"); g_assert_not_reached (); return; } - priv->selection_start_time = start_time; - priv->selection_end_time = end_time; - - gnome_calendar_update_view_times (gcal); + update_view_times (gcal, priv->base_view_time); gnome_calendar_update_date_navigator (gcal); gnome_calendar_notify_dates_shown_changed (gcal); } @@ -1390,10 +1378,9 @@ gnome_calendar_dayjump (GnomeCalendar *gcal, time_t time) priv = gcal->priv; - priv->selection_start_time = time_day_begin_with_zone (time, - priv->zone); - priv->selection_end_time = time_add_day_with_zone (priv->selection_start_time, 1, priv->zone); + priv->base_view_time = time_day_begin_with_zone (time, priv->zone); + update_view_times (gcal, priv->base_view_time); gnome_calendar_set_view (gcal, GNOME_CAL_DAY_VIEW, FALSE, TRUE); } @@ -1447,7 +1434,7 @@ set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, gboolean range_selected, gboolean grab_focus) { GnomeCalendarPrivate *priv; - gboolean round_selection; + gboolean preserve_day; const char *view_id; static gboolean updating = FALSE; @@ -1456,7 +1443,7 @@ set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, priv = gcal->priv; - round_selection = FALSE; + preserve_day = FALSE; switch (view_type) { case GNOME_CAL_DAY_VIEW: @@ -1469,11 +1456,12 @@ set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, case GNOME_CAL_WORK_WEEK_VIEW: view_id = "Work_Week_View"; + preserve_day = TRUE; break; case GNOME_CAL_WEEK_VIEW: view_id = "Week_View"; - round_selection = TRUE; + preserve_day = TRUE; break; case GNOME_CAL_MONTH_VIEW: @@ -1482,7 +1470,7 @@ set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, if (!range_selected) e_week_view_set_weeks_shown (E_WEEK_VIEW (priv->month_view), 5); - round_selection = TRUE; + preserve_day = TRUE; break; case GNOME_CAL_LIST_VIEW: @@ -1490,7 +1478,6 @@ set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, break; default: - g_warning ("A penguin is loose!"); g_assert_not_reached (); return; } @@ -1507,7 +1494,7 @@ set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, updating = FALSE; if (grab_focus) - gtk_widget_grab_focus (GTK_WIDGET (priv->views[view_type])); + focus_current_view (gcal); gnome_calendar_set_pane_positions (gcal); @@ -1515,7 +1502,7 @@ set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, navigator to be rounded to the nearest week when the arrow buttons are pressed to move to the previous/next month. */ g_object_set (G_OBJECT (priv->date_navigator->calitem), - "round_selection_when_moving", round_selection, + "preserve_day_when_moving", preserve_day, NULL); } @@ -1540,7 +1527,6 @@ gnome_calendar_set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, g_return_if_fail (GNOME_IS_CALENDAR (gcal)); set_view (gcal, view_type, range_selected, grab_focus); - gnome_calendar_update_view_times (gcal); gnome_calendar_update_date_navigator (gcal); gnome_calendar_notify_dates_shown_changed (gcal); } @@ -1555,7 +1541,7 @@ display_view_cb (GalViewInstance *view_instance, GalView *view, gpointer data) gcal = GNOME_CALENDAR (data); if (!IS_CALENDAR_VIEW (view)) - g_error ("display_view_cb(): Unknown type of view for GnomeCalendar"); + g_error (G_STRLOC ": Unknown type of view for GnomeCalendar"); cal_view = CALENDAR_VIEW (view); @@ -2244,9 +2230,7 @@ gnome_calendar_set_selected_time_range (GnomeCalendar *gcal, priv = gcal->priv; - priv->selection_start_time = start_time; - priv->selection_end_time = end_time; - + update_view_times (gcal, start_time); gnome_calendar_update_date_navigator (gcal); gnome_calendar_notify_dates_shown_changed (gcal); } @@ -2265,17 +2249,15 @@ gnome_calendar_get_selected_time_range (GnomeCalendar *gcal, time_t *end_time) { GnomeCalendarPrivate *priv; - + ECalModel *model; + g_return_if_fail (gcal != NULL); g_return_if_fail (GNOME_IS_CALENDAR (gcal)); priv = gcal->priv; - if (start_time) - *start_time = priv->selection_start_time; - - if (end_time) - *end_time = priv->selection_end_time; + model = e_calendar_view_get_model (priv->views[priv->current_view_type]); + e_cal_model_get_time_range (model, start_time, end_time); } /** @@ -2437,15 +2419,15 @@ gnome_calendar_update_date_navigator (GnomeCalendar *gcal) &start_date, &end_date); } - static void -gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem, - GnomeCalendar *gcal) +gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem, GnomeCalendar *gcal) { GnomeCalendarPrivate *priv; + GnomeCalendarViewType view_type; GDate start_date, end_date, new_start_date, new_end_date; gint days_shown, new_days_shown; gboolean starts_on_week_start_day; + time_t new_time; struct icaltimetype tt; priv = gcal->priv; @@ -2463,14 +2445,14 @@ gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem, if (!g_date_compare (&start_date, &new_start_date) && !g_date_compare (&end_date, &new_end_date)) return; - + new_days_shown = g_date_julian (&new_end_date) - g_date_julian (&new_start_date) + 1; /* If a complete week is selected we show the Week view. Note that if weekends are compressed and the week start day is set to Sunday we don't actually show complete weeks in the Week view, so this may need tweaking. */ - if (g_date_weekday (&new_start_date) % 7 == calendar_config_get_week_start_day ()) + if (g_date_weekday (&new_start_date) % 7 == priv->week_start) starts_on_week_start_day = TRUE; /* Update selection to be in the new time range */ @@ -2478,43 +2460,37 @@ gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem, tt.year = g_date_year (&new_start_date); tt.month = g_date_month (&new_start_date); tt.day = g_date_day (&new_start_date); - priv->selection_start_time = icaltime_as_timet_with_zone (tt, priv->zone); - icaltime_adjust (&tt, 1, 0, 0, 0); - priv->selection_end_time = icaltime_as_timet_with_zone (tt, priv->zone); - + new_time = icaltime_as_timet_with_zone (tt, priv->zone); + /* Switch views as appropriate, and change the number of days or weeks shown. */ if (new_days_shown > 9) { e_week_view_set_weeks_shown (E_WEEK_VIEW (priv->month_view), (new_days_shown + 6) / 7); e_week_view_set_first_day_shown (E_WEEK_VIEW (priv->month_view), &new_start_date); - - set_view (gcal, GNOME_CAL_MONTH_VIEW, TRUE, FALSE); - gnome_calendar_update_date_navigator (gcal); - gnome_calendar_notify_dates_shown_changed (gcal); + view_type = GNOME_CAL_MONTH_VIEW; } else if (new_days_shown == 7 && starts_on_week_start_day) { e_week_view_set_first_day_shown (E_WEEK_VIEW (priv->week_view), &new_start_date); - - set_view (gcal, GNOME_CAL_WEEK_VIEW, TRUE, FALSE); - gnome_calendar_update_date_navigator (gcal); - gnome_calendar_notify_dates_shown_changed (gcal); + view_type = GNOME_CAL_WEEK_VIEW; } else { e_day_view_set_days_shown (E_DAY_VIEW (priv->day_view), new_days_shown); - if (new_days_shown == 5 && priv->current_view_type == GNOME_CAL_WORK_WEEK_VIEW) - gnome_calendar_set_view (gcal, GNOME_CAL_WORK_WEEK_VIEW, TRUE, FALSE); + if (new_days_shown == 5 && starts_on_week_start_day + && priv->current_view_type == GNOME_CAL_WORK_WEEK_VIEW) + view_type = GNOME_CAL_WORK_WEEK_VIEW; else - gnome_calendar_set_view (gcal, GNOME_CAL_DAY_VIEW, TRUE, FALSE); - + view_type = GNOME_CAL_DAY_VIEW; } - focus_current_view (gcal); -} + /* Make the views display things properly */ + update_view_times (gcal, new_time); + set_view (gcal, view_type, TRUE, TRUE); + gnome_calendar_notify_dates_shown_changed (gcal); +} static void -gnome_calendar_on_date_navigator_date_range_changed (ECalendarItem *calitem, - GnomeCalendar *gcal) +gnome_calendar_on_date_navigator_date_range_changed (ECalendarItem *calitem, GnomeCalendar *gcal) { update_query (gcal); } diff --git a/calendar/gui/print.c b/calendar/gui/print.c index 6ded2bf960..287b090de5 100644 --- a/calendar/gui/print.c +++ b/calendar/gui/print.c @@ -1550,8 +1550,7 @@ print_week_summary_cb (ECalComponent *comp, start_tt = icaltime_from_timet_with_zone (start, FALSE, zone); end_tt = icaltime_from_timet_with_zone (end, FALSE, zone); - event.comp_data = mdata->comp_data; - event.allocated_comp_data = FALSE; + event.comp_data = e_cal_model_copy_component_data (mdata->comp_data); event.start = start; event.end = end; |