aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/e-week-view.c
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui/e-week-view.c')
-rw-r--r--calendar/gui/e-week-view.c282
1 files changed, 160 insertions, 122 deletions
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index 90a7b2c695..c06b568d9d 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -109,9 +109,6 @@ static gint e_week_view_convert_position_to_day (EWeekView *week_view,
static void e_week_view_update_selection (EWeekView *week_view,
gint day);
-static void e_week_view_queue_reload_events (EWeekView *week_view);
-static gboolean e_week_view_reload_events_idle_cb (gpointer data);
-static void e_week_view_reload_events (EWeekView *week_view);
static void e_week_view_free_events (EWeekView *week_view);
static gboolean e_week_view_add_event (CalComponent *comp,
time_t start,
@@ -257,13 +254,14 @@ e_week_view_init (EWeekView *week_view)
week_view->calendar = NULL;
week_view->client = NULL;
+ week_view->sexp = g_strdup ("#t"); /* match all by default */
+ week_view->query = NULL;
week_view->events = g_array_new (FALSE, FALSE,
sizeof (EWeekViewEvent));
week_view->events_sorted = TRUE;
week_view->events_need_layout = FALSE;
week_view->events_need_reshape = FALSE;
- week_view->reload_events_idle_id = 0;
week_view->spans = NULL;
@@ -383,7 +381,7 @@ e_week_view_init (EWeekView *week_view)
/* Create the cursors. */
- week_view->normal_cursor = gdk_cursor_new (GDK_TOP_LEFT_ARROW);
+ week_view->normal_cursor = gdk_cursor_new (GDK_LEFT_PTR);
week_view->move_cursor = gdk_cursor_new (GDK_FLEUR);
week_view->resize_width_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW);
week_view->last_cursor_set = NULL;
@@ -416,17 +414,23 @@ e_week_view_destroy (GtkObject *object)
e_week_view_free_events (week_view);
- if (week_view->reload_events_idle_id != 0) {
- g_source_remove (week_view->reload_events_idle_id);
- week_view->reload_events_idle_id = 0;
- }
-
if (week_view->client) {
gtk_signal_disconnect_by_data (GTK_OBJECT (week_view->client), week_view);
gtk_object_unref (GTK_OBJECT (week_view->client));
week_view->client = NULL;
}
+ if (week_view->sexp) {
+ g_free (week_view->sexp);
+ week_view->sexp = NULL;
+ }
+
+ if (week_view->query) {
+ gtk_signal_disconnect_by_data (GTK_OBJECT (week_view->query), week_view);
+ gtk_object_unref (GTK_OBJECT (week_view->query));
+ week_view->query = NULL;
+ }
+
if (week_view->small_font)
gdk_font_unref (week_view->small_font);
@@ -880,23 +884,11 @@ e_week_view_set_calendar (EWeekView *week_view,
}
-/* Callback used when the calendar client finishes opening */
-static void
-cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
-{
- EWeekView *week_view;
-
- week_view = E_WEEK_VIEW (data);
-
- if (status != CAL_CLIENT_OPEN_SUCCESS)
- return;
-
- e_week_view_queue_reload_events (week_view);
-}
-
-/* Callback used when the calendar client tells us that an object changed */
+/* Callback used when a component is updated in the live query */
static void
-obj_updated_cb (CalClient *client, const char *uid, gpointer data)
+query_obj_updated_cb (CalQuery *query, const char *uid,
+ gboolean query_in_progress, int n_scanned, int total,
+ gpointer data)
{
EWeekView *week_view;
EWeekViewEvent *event;
@@ -906,9 +898,6 @@ obj_updated_cb (CalClient *client, const char *uid, gpointer data)
week_view = E_WEEK_VIEW (data);
- /* Sanity check. */
- g_return_if_fail (client == week_view->client);
-
/* If we don't have a valid date set yet, just return. */
if (!g_date_valid (&week_view->first_day_shown))
return;
@@ -930,12 +919,6 @@ obj_updated_cb (CalClient *client, const char *uid, gpointer data)
return;
}
- /* We only care about events. */
- if (cal_component_get_vtype (comp) != CAL_COMPONENT_EVENT) {
- gtk_object_unref (GTK_OBJECT (comp));
- 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. */
@@ -981,9 +964,9 @@ obj_updated_cb (CalClient *client, const char *uid, gpointer data)
gtk_widget_queue_draw (week_view->main_canvas);
}
-/* Callback used when the calendar client tells us that an object was removed */
+/* Callback used when a component is removed from the live query */
static void
-obj_removed_cb (CalClient *client, const char *uid, gpointer data)
+query_obj_removed_cb (CalClient *client, const char *uid, gpointer data)
{
EWeekView *week_view;
@@ -996,6 +979,117 @@ obj_removed_cb (CalClient *client, const char *uid, gpointer data)
gtk_widget_queue_draw (week_view->main_canvas);
}
+/* Callback used when a query ends */
+static void
+query_query_done_cb (CalQuery *query, CalQueryDoneStatus status, const char *error_str, gpointer data)
+{
+ EWeekView *week_view;
+
+ week_view = E_WEEK_VIEW (data);
+
+ /* FIXME */
+
+ if (status != CAL_QUERY_DONE_SUCCESS)
+ fprintf (stderr, "query done: %s\n", error_str);
+}
+
+/* Callback used when an evaluation error occurs when running a query */
+static void
+query_eval_error_cb (CalQuery *query, const char *error_str, gpointer data)
+{
+ EWeekView *week_view;
+
+ week_view = E_WEEK_VIEW (data);
+
+ /* FIXME */
+
+ fprintf (stderr, "eval error: %s\n", error_str);
+}
+
+/* Builds a complete query sexp for the week view by adding the predicates to
+ * filter only for VEVENTS that fit in the week view's time range.
+ */
+static char *
+adjust_query_sexp (EWeekView *week_view, const char *sexp)
+{
+ int num_days;
+ char *start, *end;
+ char *new_sexp;
+
+ /* If the dates have not been set yet, we just want an empty query. */
+ if (!g_date_valid (&week_view->first_day_shown))
+ return g_strdup ("#f");
+
+ num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7;
+
+ start = isodate_from_time_t (week_view->day_starts[0]);
+ end = isodate_from_time_t (week_view->day_starts[num_days]);
+
+ new_sexp = g_strdup_printf ("(and (= (get-vtype) \"VEVENT\")"
+ " (occur-in-time-range? (make-time \"%s\")"
+ " (make-time \"%s\"))"
+ " %s)",
+ start, end,
+ sexp);
+
+ g_free (start);
+ g_free (end);
+
+ return new_sexp;
+}
+
+/* Restarts a query for the week view */
+static void
+update_query (EWeekView *week_view)
+{
+ char *real_sexp;
+
+ e_week_view_free_events (week_view);
+ gtk_widget_queue_draw (week_view->main_canvas);
+
+ if (!(week_view->client
+ && cal_client_get_load_state (week_view->client) == CAL_CLIENT_LOAD_LOADED))
+ return;
+
+ if (week_view->query) {
+ gtk_signal_disconnect_by_data (GTK_OBJECT (week_view->query), week_view);
+ gtk_object_unref (GTK_OBJECT (week_view->query));
+ }
+
+ g_assert (week_view->sexp != NULL);
+ real_sexp = adjust_query_sexp (week_view, week_view->sexp);
+
+ week_view->query = cal_client_get_query (week_view->client, real_sexp);
+ g_free (real_sexp);
+
+ if (!week_view->query) {
+ g_message ("update_query(): Could not create the query");
+ return;
+ }
+
+ gtk_signal_connect (GTK_OBJECT (week_view->query), "obj_updated",
+ GTK_SIGNAL_FUNC (query_obj_updated_cb), week_view);
+ gtk_signal_connect (GTK_OBJECT (week_view->query), "obj_removed",
+ GTK_SIGNAL_FUNC (query_obj_removed_cb), week_view);
+ gtk_signal_connect (GTK_OBJECT (week_view->query), "query_done",
+ GTK_SIGNAL_FUNC (query_query_done_cb), week_view);
+ gtk_signal_connect (GTK_OBJECT (week_view->query), "eval_error",
+ GTK_SIGNAL_FUNC (query_eval_error_cb), week_view);
+}
+
+/* Callback used when the calendar client finishes opening */
+static void
+cal_opened_cb (CalClient *client, CalClientOpenStatus status, gpointer data)
+{
+ EWeekView *week_view;
+
+ week_view = E_WEEK_VIEW (data);
+
+ if (status != CAL_CLIENT_OPEN_SUCCESS)
+ return;
+
+ update_query (week_view);
+}
/**
* e_week_view_set_cal_client:
@@ -1028,17 +1122,35 @@ e_week_view_set_cal_client (EWeekView *week_view,
week_view->client = client;
if (week_view->client) {
- if (cal_client_get_load_state (week_view->client) != CAL_CLIENT_LOAD_LOADED)
+ if (cal_client_get_load_state (week_view->client) == CAL_CLIENT_LOAD_LOADED)
+ update_query (week_view);
+ else
gtk_signal_connect (GTK_OBJECT (week_view->client), "cal_opened",
GTK_SIGNAL_FUNC (cal_opened_cb), week_view);
-
- gtk_signal_connect (GTK_OBJECT (week_view->client), "obj_updated",
- GTK_SIGNAL_FUNC (obj_updated_cb), week_view);
- gtk_signal_connect (GTK_OBJECT (week_view->client), "obj_removed",
- GTK_SIGNAL_FUNC (obj_removed_cb), week_view);
}
+}
+
+/**
+ * e_week_view_set_query:
+ * @week_view: A week view.
+ * @sexp: S-expression that defines the query.
+ *
+ * Sets the query sexp that the week view will use for filtering the displayed
+ * events.
+ **/
+void
+e_week_view_set_query (EWeekView *week_view, const char *sexp)
+{
+ g_return_if_fail (week_view != NULL);
+ g_return_if_fail (E_IS_WEEK_VIEW (week_view));
+ g_return_if_fail (sexp != NULL);
+
+ if (week_view->sexp)
+ g_free (week_view->sexp);
- e_week_view_queue_reload_events (week_view);
+ week_view->sexp = g_strdup (sexp);
+
+ update_query (week_view);
}
@@ -1108,7 +1220,7 @@ e_week_view_set_selected_time_range (EWeekView *week_view,
start_time = time_add_day (start_time, -day_offset);
start_time = time_day_begin (start_time);
e_week_view_recalc_day_starts (week_view, start_time);
- e_week_view_queue_reload_events (week_view);
+ update_query (week_view);
}
/* Set the selection to the given days. */
@@ -1139,7 +1251,6 @@ e_week_view_set_selected_time_range (EWeekView *week_view,
if (update_adjustment_value)
gtk_adjustment_set_value (GTK_RANGE (week_view->vscrollbar)->adjustment, 0);
-
gtk_widget_queue_draw (week_view->main_canvas);
}
@@ -1227,7 +1338,7 @@ e_week_view_set_first_day_shown (EWeekView *week_view,
g_date_to_struct_tm (&base_date, &start_tm);
start_time = mktime (&start_tm);
e_week_view_recalc_day_starts (week_view, start_time);
- e_week_view_queue_reload_events (week_view);
+ update_query (week_view);
}
/* Try to keep the previous selection, but if it is no longer shown
@@ -1256,7 +1367,6 @@ e_week_view_set_first_day_shown (EWeekView *week_view,
if (update_adjustment_value)
gtk_adjustment_set_value (GTK_RANGE (week_view->vscrollbar)->adjustment, 0);
-
gtk_widget_queue_draw (week_view->main_canvas);
}
@@ -1364,8 +1474,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);
- /* Make sure the events are reloaded. */
- e_week_view_queue_reload_events (week_view);
+ update_query (week_view);
}
}
@@ -2019,77 +2128,6 @@ e_week_view_update_selection (EWeekView *week_view,
}
-/* This frees any events currently loaded, and queues a reload. */
-static void
-e_week_view_queue_reload_events (EWeekView *week_view)
-{
- e_week_view_free_events (week_view);
-
- if (week_view->reload_events_idle_id == 0) {
- /* We'll use a low priority here, so the user can scroll
- the view quickly. */
- week_view->reload_events_idle_id = g_idle_add_full
- (G_PRIORITY_LOW,
- e_week_view_reload_events_idle_cb, week_view, NULL);
- }
-}
-
-
-static gboolean
-e_week_view_reload_events_idle_cb (gpointer data)
-{
- EWeekView *week_view;
-
- g_return_val_if_fail (E_IS_WEEK_VIEW (data), FALSE);
-
- GDK_THREADS_ENTER ();
-
- week_view = E_WEEK_VIEW (data);
-
- week_view->reload_events_idle_id = 0;
-
- e_week_view_reload_events (week_view);
-
- GDK_THREADS_LEAVE ();
- return FALSE;
-}
-
-
-static void
-e_week_view_reload_events (EWeekView *week_view)
-{
- gint num_days;
-
- e_week_view_free_events (week_view);
-
- if (!(week_view->client
- && cal_client_get_load_state (week_view->client) == CAL_CLIENT_LOAD_LOADED))
- return;
-
- /* Only load events if the date range has been set. */
- if (g_date_valid (&week_view->first_day_shown)) {
- num_days = week_view->multi_week_view
- ? week_view->weeks_shown * 7 : 7;
-
-#if 0
- g_print ("EWeekView (%s) generating instances\n",
- week_view->multi_week_view ? "Month View" : "Week View");
-#endif
- cal_client_generate_instances (week_view->client,
- CALOBJ_TYPE_EVENT,
- week_view->day_starts[0],
- week_view->day_starts[num_days],
- e_week_view_add_event,
- week_view);
- }
-
- week_view->events_need_reshape = TRUE;
- e_week_view_check_layout (week_view);
-
- gtk_widget_queue_draw (week_view->main_canvas);
-}
-
-
static void
e_week_view_free_events (EWeekView *week_view)
{
@@ -2777,7 +2815,7 @@ e_week_view_on_adjustment_changed (GtkAdjustment *adjustment,
lower = time_day_begin (lower);
e_week_view_recalc_day_starts (week_view, lower);
- e_week_view_queue_reload_events (week_view);
+ update_query (week_view);
/* Update the selection, if needed. */
if (week_view->selection_start_day != -1) {