blob: 5422d6a9b4116016c2c1141ea81d0273d7d5512d (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* e-storage.h
*
* Copyright (C) 2000 Helix Code, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: Ettore Perazzoli
*/
#ifndef _E_STORAGE_H_
#define _E_STORAGE_H_
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gtk/gtkobject.h>
#ifdef __cplusplus
extern "C" {
#pragma }
#endif /* __cplusplus */
#define E_TYPE_STORAGE (e_storage_get_type ())
#define E_STORAGE(obj) (GTK_CHECK_CAST ((obj), E_TYPE_STORAGE, EStorage))
#define E_STORAGE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_STORAGE, EStorageClass))
#define E_IS_STORAGE(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_STORAGE))
#define E_IS_STORAGE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_STORAGE))
typedef struct _EStorage EStorage;
typedef struct _EStoragePrivate EStoragePrivate;
typedef struct _EStorageClass EStorageClass;
enum _EStorageResult {
E_STORAGE_OK,
E_STORAGE_GENERICERROR,
E_STORAGE_EXISTS,
E_STORAGE_INVALIDTYPE,
E_STORAGE_IOERROR,
E_STORAGE_NOSPACE,
E_STORAGE_NOTFOUND,
E_STORAGE_NOTIMPLEMENTED,
E_STORAGE_PERMISSIONDENIED,
E_STORAGE_UNSUPPORTEDOPERATION,
E_STORAGE_UNSUPPORTEDTYPE
};
typedef enum _EStorageResult EStorageResult;
typedef void (* EStorageResultCallback) (EStorage *storage, EStorageResult result, void *data);
#include "e-folder.h"
struct _EStorage {
GtkObject parent;
EStoragePrivate *priv;
};
struct _EStorageClass {
GtkObjectClass parent_class;
/* Signals. */
void * (* new_folder) (EStorage *storage, const char *path);
void * (* removed_folder) (EStorage *storage, const char *path);
/* Virtual methods. */
GList * (* list_folders) (EStorage *storage, const char *path);
EFolder * (* get_folder) (EStorage *storage, const char *path);
const char * (* get_name) (EStorage *storage);
void (* async_create_folder) (EStorage *storage, const char *path,
const char *type, const char *description,
EStorageResultCallback callback, void *data);
void (* async_remove_folder) (EStorage *storage, const char *path,
EStorageResultCallback callback, void *data);
};
GtkType e_storage_get_type (void);
void e_storage_construct (EStorage *storage);
EStorage *e_storage_new (void);
gboolean e_storage_path_is_relative (const char *path);
gboolean e_storage_path_is_absolute (const char *path);
GList *e_storage_list_folders (EStorage *storage, const char *path);
EFolder *e_storage_get_folder (EStorage *storage, const char *path);
const char *e_storage_get_name (EStorage *storage);
/* Folder operations. */
void e_storage_async_create_folder (EStorage *storage,
const char *path,
const char *type,
const char *description,
EStorageResultCallback callback,
void *data);
void e_storage_async_remove_folder (EStorage *storage,
const char *path,
EStorageResultCallback callback,
void *data);
const char *e_storage_result_to_string (EStorageResult result);
/* Protected. C++ anyone? */
gboolean e_storage_new_folder (EStorage *storage, const char *path, EFolder *folder);
gboolean e_storage_removed_folder (EStorage *storage, const char *path);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _E_STORAGE_H_ */
|
static void e_cal_model_finalize (GObject *object);
@@ -1120,9 +1124,6 @@ e_cal_model_set_timezone (ECalModel *model, icaltimezone *zone)
e_table_model_pre_change (E_TABLE_MODEL (model));
priv->zone = zone;
- for (l = priv->clients; l; l = l->next)
- e_cal_set_default_timezone (((ECalModelClient *)l->data)->client, priv->zone, NULL);
-
/* the timezone affects the times shown for date fields,
so we need to redisplay everything */
e_table_model_changed (E_TABLE_MODEL (model));
@@ -1364,13 +1365,11 @@ add_instance_cb (ECalComponent *comp, time_t instance_start, time_t instance_end
e_cal_component_set_dtend (comp, &to_set);
e_cal_component_free_datetime (&datetime);
- comp_data = g_new0 (ECalModelComponent, 1);
+ comp_data = g_object_new (E_TYPE_CAL_MODEL_COMPONENT, NULL);
comp_data->client = g_object_ref (rdata->client);
comp_data->icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp));
comp_data->instance_start = instance_start;
comp_data->instance_end = instance_end;
- comp_data->dtstart = comp_data->dtend = comp_data->due = comp_data->completed = NULL;
- comp_data->color = NULL;
g_ptr_array_add (priv->objects, comp_data);
e_table_model_row_inserted (E_TABLE_MODEL (rdata->model), priv->objects->len - 1);
@@ -1456,12 +1455,10 @@ e_cal_view_objects_added_cb (ECalView *query, GList *objects, gpointer user_data
} else {
e_table_model_pre_change (E_TABLE_MODEL (model));
- comp_data = g_new0 (ECalModelComponent, 1);
+ comp_data = g_object_new (E_TYPE_CAL_MODEL_COMPONENT, NULL);
comp_data->client = g_object_ref (e_cal_view_get_client (query));
comp_data->icalcomp = icalcomponent_new_clone (l->data);
e_cal_model_set_instance_times (comp_data, priv->zone);
- comp_data->dtstart = comp_data->dtend = comp_data->due = comp_data->completed = NULL;
- comp_data->color = NULL;
g_ptr_array_add (priv->objects, comp_data);
e_table_model_row_inserted (E_TABLE_MODEL (model), priv->objects->len - 1);
@@ -1525,6 +1522,7 @@ e_cal_view_done_cb (ECalView *query, ECalendarStatus status, gpointer user_data)
{
ECalModel *model = (ECalModel *) user_data;
ECal *client = e_cal_view_get_client (query);
+ ECalModelPrivate *priv = model->priv;
g_return_if_fail (E_IS_CAL_MODEL (model));
@@ -1537,6 +1535,8 @@ static void
update_e_cal_view_for_client (ECalModel *model, ECalModelClient *client_data)
{
ECalModelPrivate *priv;
+ GError *error = NULL;
+ gint tries = 0;
priv = model->priv;
@@ -1559,7 +1559,16 @@ update_e_cal_view_for_client (ECalModel *model, ECalModelClient *client_data)
if (!client_data->do_query)
return;
- if (!e_cal_get_query (client_data->client, priv->full_sexp, &client_data->query, NULL)) {
+try_again:
+ if (!e_cal_get_query (client_data->client, priv->full_sexp, &client_data->query, &error)) {
+ if (error->code == E_CALENDAR_STATUS_BUSY && tries != 3) {
+ tries++;
+ /*TODO chose an optimal value */
+ g_usleep (50);
+ g_clear_error (&error);
+ goto try_again;
+ }
+
g_warning (G_STRLOC ": Unable to get query");
return;
@@ -1597,7 +1606,6 @@ cal_opened_cb (ECal *client, ECalendarStatus status, gpointer user_data)
if (status != E_CALENDAR_STATUS_OK) {
e_cal_model_remove_client (model, client);
-
return;
}
@@ -1619,6 +1627,11 @@ add_new_client (ECalModel *model, ECal *client, gboolean do_query)
priv = model->priv;
+ /* DEBUG the load state should always be loaded here
+ if (e_cal_get_load_state (client) != E_CAL_LOAD_LOADED) {
+ g_assert_not_reached ();
+ } */
+
/* Look to see if we already have this client */
client_data = find_client_data (model, client);
if (client_data) {
@@ -2087,45 +2100,32 @@ copy_ecdv (ECellDateEditValue *ecdv)
return new_ecdv;
}
-/**
- * e_cal_model_copy_component_data
- */
-ECalModelComponent *
-e_cal_model_copy_component_data (ECalModelComponent *comp_data)
-{
- ECalModelComponent *new_data;
- g_return_val_if_fail (comp_data != NULL, NULL);
+struct _ECalModelComponentPrivate {
+};
- new_data = g_new0 (ECalModelComponent, 1);
+static void e_cal_model_component_finalize (GObject *object);
- new_data->instance_start = comp_data->instance_start;
- new_data->instance_end = comp_data->instance_end;
- 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);
- if (comp_data->color)
- new_data->color = g_strdup (comp_data->color);
+static GObjectClass *parent_class;
- return new_data;
+/* Class initialization function for the calendar component object */
+static void
+e_cal_model_component_class_init (ECalModelComponentClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = (GObjectClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->finalize = e_cal_model_component_finalize;
}
-/**
- * e_cal_model_free_component_data
- */
-void
-e_cal_model_free_component_data (ECalModelComponent *comp_data)
+
+static void
+e_cal_model_component_finalize (GObject *object)
{
- g_return_if_fail (comp_data != NULL);
+ ECalModelComponent *comp_data = E_CAL_MODEL_COMPONENT(object);
if (comp_data->client) {
g_object_unref (comp_data->client);
@@ -2155,8 +2155,64 @@ e_cal_model_free_component_data (ECalModelComponent *comp_data)
g_free (comp_data->color);
comp_data->color = NULL;
}
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+/* Object initialization function for the calendar component object */
+static void
+e_cal_model_component_init (ECalModelComponent *comp)
+{
+ comp->dtstart = NULL;
+ comp->dtend = NULL;
+ comp->due = NULL;
+ comp->completed = NULL;
+ comp->color = NULL;
+}
+
+GType
+e_cal_model_component_get_type (void)
+{
+ static GType e_cal_model_component_type = 0;
+
+ if (!e_cal_model_component_type) {
+ static GTypeInfo info = {
+ sizeof (ECalModelComponentClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) e_cal_model_component_class_init,
+ NULL, NULL,
+ sizeof (ECalModelComponent),
+ 0,
+ (GInstanceInitFunc) e_cal_model_component_init
+ };
+ e_cal_model_component_type = g_type_register_static (G_TYPE_OBJECT, "ECalModelComponent", &info, 0);
+ }
+
+ return e_cal_model_component_type;
+}
- g_free (comp_data);
+/**
+ * e_cal_model_copy_component_data
+ */
+ECalModelComponent *
+e_cal_model_copy_component_data (ECalModelComponent *comp_data)
+{
+ g_return_val_if_fail (comp_data != NULL, NULL);
+
+ return g_object_ref (comp_data);
+}
+
+/**
+ * e_cal_model_free_component_data
+ */
+void
+e_cal_model_free_component_data (ECalModelComponent *comp_data)
+{
+ g_return_if_fail (comp_data != NULL);
+
+ g_object_unref (comp_data);
}
/**
@@ -57,19 +57,39 @@ typedef enum {
E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES = 0x01
} ECalModelFlags;
-typedef struct {
+#define E_TYPE_CAL_MODEL_COMPONENT (e_cal_model_component_get_type ())
+#define E_CAL_MODEL_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CAL_MODEL_COMPONENT, ECalModelComponent))
+#define E_CAL_MODEL_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CAL_MODEL_COMPONENT, \
+ ECalComponentClass))
+#define E_IS_CAL_MODEL_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CAL_MODEL_COMPONENT))
+#define E_IS_CAL_MODEL_COMPONENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CAL_MODEL_COMPONENT))
+
+typedef struct _ECalModelComponent ECalModelComponent;
+typedef struct _ECalModelComponentClass ECalModelComponentClass;
+typedef struct _ECalModelComponentPrivate ECalModelComponentPrivate;
+
+struct _ECalModelComponent {
+ GObject object;
+
ECal *client;
icalcomponent *icalcomp;
time_t instance_start;
time_t instance_end;
-
- /* private data */
+
+ /* Private data used by ECalModelCalendar and ECalModelTasks */
+ /* keep these public to avoid many accessor functions */
ECellDateEditValue *dtstart;
ECellDateEditValue *dtend;
ECellDateEditValue *due;
ECellDateEditValue *completed;
gchar *color;
-} ECalModelComponent;
+
+ ECalModelComponentPrivate *priv;
+};
+
+struct _ECalModelComponentClass {
+ GObjectClass parent_class;
+};
typedef struct {
ECalModelComponent *comp_data;
@@ -97,6 +117,7 @@ typedef struct {
} ECalModelClass;
GType e_cal_model_get_type (void);
+GType e_cal_model_component_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);
@@ -393,8 +393,6 @@ static void
e_calendar_view_init (ECalendarView *cal_view)
{
cal_view->priv = g_new0 (ECalendarViewPrivate, 1);
-
- cal_view->priv->model = (ECalModel *) e_cal_model_calendar_new ();
}
static void
@@ -463,7 +461,6 @@ e_calendar_view_set_model (ECalendarView *cal_view, ECalModel *model)
}
cal_view->priv->model = g_object_ref (model);
- e_calendar_view_update_query (cal_view);
}
icaltimezone *
@@ -81,6 +81,8 @@ typedef struct _ECalendarViewPrivate ECalendarViewPrivate;
struct _ECalendarView {
GtkTable table;
+
+ gboolean in_focus;
ECalendarViewPrivate *priv;
};
@@ -145,15 +145,6 @@ e_day_view_config_get_view (EDayViewConfig *view_config)
}
static void
-set_timezone (EDayView *day_view)
-{
- icaltimezone *zone;
-
- zone = calendar_config_get_icaltimezone ();
- e_calendar_view_set_timezone (E_CALENDAR_VIEW (day_view), zone);
-}
-
-static void
timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
{
EDayViewConfig *view_config = data;
@@ -420,12 +411,6 @@ e_day_view_config_set_view (EDayViewConfig *view_config, EDayView *day_view)
priv->view = g_object_ref (day_view);
- /* Time zone */
- set_timezone (day_view);
-
- not = calendar_config_add_notification_timezone (timezone_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
/* Week start */
set_week_start (day_view);
@@ -486,6 +486,11 @@ time_range_changed_cb (ECalModel *model, time_t start_time, time_t end_time, gpo
g_return_if_fail (E_IS_DAY_VIEW (day_view));
+ if (!E_CALENDAR_VIEW (day_view)->in_focus) {
+ e_day_view_free_events (day_view);
+ return;
+ }
+
/* 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
@@ -568,6 +573,10 @@ model_row_changed_cb (ETableModel *etm, int row, gpointer user_data)
{
EDayView *day_view = E_DAY_VIEW (user_data);
+ if (!E_CALENDAR_VIEW (day_view)->in_focus) {
+ return;
+ }
+
update_row (day_view, row);
}
@@ -576,6 +585,10 @@ model_cell_changed_cb (ETableModel *etm, int col, int row, gpointer user_data)
{
EDayView *day_view = E_DAY_VIEW (user_data);
+ if (!E_CALENDAR_VIEW (day_view)->in_focus) {
+ return;
+ }
+
update_row (day_view, row);
}
@@ -586,6 +599,10 @@ model_rows_inserted_cb (ETableModel *etm, int row, int count, gpointer user_data
ECalModel *model;
int i;
+ if (!E_CALENDAR_VIEW (day_view)->in_focus) {
+ return;
+ }
+
e_day_view_stop_editing_event (day_view);
model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
@@ -612,6 +629,10 @@ model_rows_deleted_cb (ETableModel *etm, int row, int count, gpointer user_data)
EDayView *day_view = E_DAY_VIEW (user_data);
int i;
+ if (!E_CALENDAR_VIEW (day_view)->in_focus) {
+ return;
+ }
+
e_day_view_stop_editing_event (day_view);
for (i = row + count; i > row; i--) {
@@ -653,6 +674,10 @@ timezone_changed_cb (ECalendarView *cal_view, icaltimezone *old_zone,
g_return_if_fail (E_IS_DAY_VIEW (day_view));
+
+ if (!cal_view->in_focus)
+ return;
+
/* If our time hasn't been set yet, just return. */
if (day_view->lower == 0 && day_view->upper == 0)
return;
@@ -673,7 +698,6 @@ e_day_view_init (EDayView *day_view)
{
gint day;
GnomeCanvasGroup *canvas_group;
- ECalModel *model;
GtkWidget *w;
GTK_WIDGET_SET_FLAGS (day_view, GTK_CAN_FOCUS);
@@ -981,9 +1005,16 @@ e_day_view_init (EDayView *day_view)
target_table, n_targets,
GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK);
- /* Get the model */
- model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
+ /* connect to ECalendarView's signals */
+ g_signal_connect (G_OBJECT (day_view), "timezone_changed",
+ G_CALLBACK (timezone_changed_cb), NULL);
+}
+
+
+static void
+init_model (EDayView *day_view, ECalModel *model)
+{
/* connect to ECalModel's signals */
g_signal_connect (G_OBJECT (model), "time_range_changed",
G_CALLBACK (time_range_changed_cb), day_view);
@@ -995,10 +1026,6 @@ e_day_view_init (EDayView *day_view)
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);
}
/* Turn off the background of the canvas windows. This reduces flicker
@@ -1019,12 +1046,13 @@ e_day_view_on_canvas_realized (GtkWidget *widget,
* Creates a new #EDayView.
**/
GtkWidget *
-e_day_view_new (void)
+e_day_view_new (ECalModel *model)
{
GObject *day_view;
day_view = g_object_new (e_day_view_get_type (), NULL);
- e_cal_model_set_flags (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES);
+ e_calendar_view_set_model ((ECalendarView *)day_view, model);
+ init_model ((EDayView *) day_view, model);
return GTK_WIDGET (day_view);
}
@@ -2346,7 +2374,7 @@ e_day_view_set_mins_per_row (EDayView *day_view,
e_day_view_recalc_num_rows (day_view);
/* If we aren't visible, we'll sort it out later. */
- if (!GTK_WIDGET_VISIBLE (day_view))
+ if (!E_CALENDAR_VIEW (day_view)->in_focus)
return;
for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++)
@@ -4147,12 +4175,11 @@ e_day_view_add_event (ECalComponent *comp,
add_event_data = data;
-#if 0
+ /*
g_print ("Day view lower: %s", ctime (&add_event_data->day_view->lower));
g_print ("Day view upper: %s", ctime (&add_event_data->day_view->upper));
g_print ("Event start: %s", ctime (&start));
- g_print ("Event end : %s\n", ctime (&end));
-#endif
+ g_print ("Event end : %s\n", ctime (&end)); */
/* Check that the event times are valid. */
g_return_val_if_fail (start <= end, TRUE);
@@ -4167,7 +4194,7 @@ e_day_view_add_event (ECalComponent *comp,
if (add_event_data->comp_data) {
event.comp_data = e_cal_model_copy_component_data (add_event_data->comp_data);
} else {
- event.comp_data = g_new0 (ECalModelComponent, 1);
+ event.comp_data = g_object_new (E_TYPE_CAL_MODEL_COMPONENT, NULL);
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_abort_sequence (comp);
@@ -4241,7 +4268,7 @@ e_day_view_check_layout (EDayView *day_view)
gint day, rows_in_top_display;
/* Don't bother if we aren't visible. */
- if (!GTK_WIDGET_VISIBLE (day_view))
+ if (!E_CALENDAR_VIEW (day_view)->in_focus)
return;
/* Make sure the events are sorted (by start and size). */
@@ -474,7 +474,7 @@ struct _EDayViewClass
GType e_day_view_get_type (void);
-GtkWidget* e_day_view_new (void);
+GtkWidget* e_day_view_new (ECalModel *model);
/* Whether we are displaying a work-week, in which case the display always
starts on the first day of the working week. */
@@ -145,26 +145,6 @@ e_week_view_config_get_view (EWeekViewConfig *view_config)
}
static void
-set_timezone (EWeekView *week_view)
-{
- icaltimezone *zone;
-
- zone = calendar_config_get_icaltimezone ();
- e_calendar_view_set_timezone (E_CALENDAR_VIEW (week_view), zone);
-}
-
-static void
-timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
-{
- EWeekViewConfig *view_config = data;
- EWeekViewConfigPrivate *priv;
-
- priv = view_config->priv;
-
- set_timezone (priv->view);
-}
-
-static void
set_week_start (EWeekView *week_view)
{
int week_start_week;
@@ -280,12 +260,6 @@ e_week_view_config_set_view (EWeekViewConfig *view_config, EWeekView *week_view)
priv->view = g_object_ref (week_view);
- /* Time zone */
- set_timezone (week_view);
-
- not = calendar_config_add_notification_timezone (timezone_changed_cb, view_config);
- priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
-
/* Week start */
set_week_start (week_view);
@@ -242,6 +242,11 @@ time_range_changed_cb (ECalModel *model, time_t start_time, time_t end_time, gpo
g_return_if_fail (E_IS_WEEK_VIEW (week_view));
+ if (!E_CALENDAR_VIEW (week_view)->in_focus) {
+ e_week_view_free_events (week_view);
+ return;
+ }
+
time_to_gdate_with_zone (&date, start_time, e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view)));
/* Calculate the weekday of the given date, 0 = Mon. */
@@ -346,6 +351,11 @@ static void
model_row_changed_cb (ETableModel *etm, int row, gpointer user_data)
{
EWeekView *week_view = E_WEEK_VIEW (user_data);
+
+ if (!E_CALENDAR_VIEW (week_view)->in_focus) {
+ return;
+ }
+
update_row (week_view, row);
}
@@ -355,6 +365,10 @@ model_cell_changed_cb (ETableModel *etm, int col, int row, gpointer user_data)
{
EWeekView *week_view = E_WEEK_VIEW (user_data);
+ if (!E_CALENDAR_VIEW (week_view)->in_focus) {
+ return;
+ }
+
update_row (week_view, row);
}
@@ -365,6 +379,10 @@ model_rows_inserted_cb (ETableModel *etm, int row, int count, gpointer user_data
ECalModel *model;
int i;
+ if (!E_CALENDAR_VIEW (week_view)->in_focus) {
+ return;
+ }
+
model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view));
for (i = 0; i < count; i++) {
@@ -389,6 +407,9 @@ model_rows_deleted_cb (ETableModel *etm, int row, int count, gpointer user_data)
int i;
/* FIXME Stop editing? */
+ if (!E_CALENDAR_VIEW (week_view)->in_focus) {
+ return;
+ }
for (i = row + count; i > row; i--) {
gint event_num;
@@ -428,6 +449,9 @@ timezone_changed_cb (ECalendarView *cal_view, icaltimezone *old_zone,
g_return_if_fail (E_IS_WEEK_VIEW (week_view));
+ if (!cal_view->in_focus)
+ return;
+
/* If we don't have a valid date set yet, just return. */
if (!g_date_valid (&week_view->first_day_shown))
return;
@@ -450,7 +474,6 @@ 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);
@@ -586,9 +609,14 @@ 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;
- /* Get the model */
- model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view));
+ /* connect to ECalendarView's signals */
+ g_signal_connect (G_OBJECT (week_view), "timezone_changed",
+ G_CALLBACK (timezone_changed_cb), NULL);
+}
+static void
+init_model (EWeekView *week_view, ECalModel *model)
+{
/* connect to ECalModel's signals */
g_signal_connect (G_OBJECT (model), "time_range_changed",
G_CALLBACK (time_range_changed_cb), week_view);
@@ -601,12 +629,8 @@ e_week_view_init (EWeekView *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);
}
-
/**
* e_week_view_new:
* @Returns: a new #EWeekView.
@@ -614,12 +638,13 @@ e_week_view_init (EWeekView *week_view)
* Creates a new #EWeekView.
**/
GtkWidget *
-e_week_view_new (void)
+e_week_view_new (ECalModel *model)
{
GtkWidget *week_view;
week_view = GTK_WIDGET (g_object_new (e_week_view_get_type (), NULL));
- e_cal_model_set_flags (e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)), E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES);
+ e_calendar_view_set_model ((ECalendarView *) week_view, model);
+ init_model ((EWeekView *) week_view, model);
return week_view;
}
@@ -2403,7 +2428,7 @@ e_week_view_add_event (ECalComponent *comp,
if (add_event_data->comp_data) {
event.comp_data = e_cal_model_copy_component_data (add_event_data->comp_data);
} else {
- event.comp_data = g_new0 (ECalModelComponent, 1);
+ event.comp_data = g_object_new (E_TYPE_CAL_MODEL_COMPONENT, NULL);
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_abort_sequence (comp);
@@ -2447,7 +2472,7 @@ static void
e_week_view_check_layout (EWeekView *week_view)
{
/* Don't bother if we aren't visible. */
- if (!GTK_WIDGET_VISIBLE (week_view))
+ if (!E_CALENDAR_VIEW (week_view)->in_focus)
return;
/* Make sure the events are sorted (by start and size). */
@@ -348,7 +348,7 @@ struct _EWeekViewClass
GType e_week_view_get_type (void);
-GtkWidget* e_week_view_new (void);
+GtkWidget* e_week_view_new (ECalModel *model);
/* The first day shown. Note that it will be rounded down to the start of a
week when set. The returned value will be invalid if no date has been set
@@ -91,7 +91,7 @@
#define G_MAXINT32 ((gint32) 0x7fffffff)
#endif
-
+#define d(x) x
/* Private part of the GnomeCalendar structure */
struct _GnomeCalendarPrivate {
@@ -249,6 +249,41 @@ static void update_query (GnomeCalendar *gcal);
static void update_todo_view (GnomeCalendar *gcal);
static void update_memo_view (GnomeCalendar *gcal);
+static void default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal);
+static void client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal);
+
+/* Simple asynchronous message dispatcher */
+typedef struct _Message Message;
+typedef void (*MessageFunc) (Message *msg);
+
+struct _Message {
+ MessageFunc func;
+};
+
+static void
+message_proxy (Message *msg)
+{
+ g_return_if_fail (msg->func != NULL);
+
+ msg->func (msg);
+}
+
+static gpointer
+create_thread_pool (void)
+{
+ /* once created, run forever */
+ return g_thread_pool_new ((GFunc) message_proxy, NULL, 1, FALSE, NULL);
+}
+
+static void
+message_push (Message *msg)
+{
+ static GOnce once = G_ONCE_INIT;
+
+ g_once (&once, (GThreadFunc) create_thread_pool, NULL);
+
+ g_thread_pool_push ((GThreadPool *) once.retval, msg, NULL);
+}
G_DEFINE_TYPE (GnomeCalendar, gnome_calendar, GTK_TYPE_VBOX)
@@ -813,24 +848,22 @@ adjust_e_cal_view_sexp (GnomeCalendar *gcal, const char *sexp)
return new_sexp;
}
-/* Restarts a query for the date navigator in the calendar */
-static void
-update_query (GnomeCalendar *gcal)
+struct _date_query_msg {
+ Message header;
+ GnomeCalendar *gcal;
+};
+
+static void
+update_query_async (struct _date_query_msg *msg)
{
+ GnomeCalendar *gcal = msg->gcal;
GnomeCalendarPrivate *priv;
ECalView *old_query;
char *real_sexp;
GList *l;
priv = gcal->priv;
-
- if (priv->updating == TRUE) {
- return;
- }
- e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), _("Updating query"), -1);
- e_calendar_item_clear_marks (priv->date_navigator->calitem);
-
- priv->updating = TRUE;
+
/* free the previous queries */
for (l = priv->dn_queries; l != NULL; l = l->next) {
old_query = l->data;
@@ -849,20 +882,33 @@ update_query (GnomeCalendar *gcal)
real_sexp = adjust_e_cal_view_sexp (gcal, priv->sexp);
if (!real_sexp) {
- e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1);
- priv->updating = FALSE;
return; /* No time range is set, so don't start a query */
}
-
+
/* create queries for each loaded client */
for (l = priv->clients_list[E_CAL_SOURCE_TYPE_EVENT]; l != NULL; l = l->next) {
+ GError *error = NULL;
+ gint tries = 0;
+
/* don't create queries for clients not loaded yet */
if (e_cal_get_load_state ((ECal *) l->data) != E_CAL_LOAD_LOADED)
continue;
+try_again:
old_query = NULL;
- if (!e_cal_get_query ((ECal *) l->data, real_sexp, &old_query, NULL)) {
- g_warning (G_STRLOC ": Could not create the query");
+ if (!e_cal_get_query ((ECal *) l->data, real_sexp, &old_query, &error)) {
+ /* If calendar is busy try again for 3 times. */
+ if (error->code == E_CALENDAR_STATUS_BUSY && tries != 3) {
+ tries++;
+ /*TODO chose an optimal value */
+ g_usleep (50);
+
+ g_clear_error (&error);
+ goto try_again;
+ }
+
+ g_warning (G_STRLOC ": Could not create the query: %s ", error->message);
+ g_clear_error (&error);
continue;
}
@@ -882,10 +928,26 @@ update_query (GnomeCalendar *gcal)
}
/* free memory */
- priv->updating = FALSE;
g_free (real_sexp);
- e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1);
update_todo_view (gcal);
+
+ g_object_unref (msg->gcal);
+ g_slice_free (struct _date_query_msg, msg);
+}
+
+/* Restarts a query for the date navigator in the calendar */
+static void
+update_query (GnomeCalendar *gcal)
+{
+ struct _date_query_msg *msg;
+
+ e_calendar_item_clear_marks (gcal->priv->date_navigator->calitem);
+
+ msg = g_slice_new0 (struct _date_query_msg);
+ msg->header.func = (MessageFunc) update_query_async;
+ msg->gcal = g_object_ref (gcal);
+
+ message_push ((Message *) msg);
}
static void
@@ -908,26 +970,28 @@ set_search_query (GnomeCalendar *gcal, const char *sexp)
priv->sexp = g_strdup (sexp);
+ d(g_print ("Changing the queries %s \n", sexp));
+
update_query (gcal);
+ i = priv->current_view_type;
+
/* Set the query on the views */
- for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
- if (i == GNOME_CAL_LIST_VIEW) {
- if (!priv->lview_select_daten_range) {
- cal_search_bar_get_time_range ((CalSearchBar *)priv->search_bar, &start, &end);
- e_cal_model_set_search_query_with_time_range (e_calendar_view_get_model (priv->views [i]), sexp, start, end);
- } else {
- start = priv->base_view_time;
- get_times_for_views (gcal, GNOME_CAL_LIST_VIEW, &start, &end);
-
- e_cal_model_set_search_query_with_time_range (e_calendar_view_get_model (priv->views [i]), sexp, start, end);
-
- if (priv->current_view_type == GNOME_CAL_LIST_VIEW)
- gnome_calendar_update_date_navigator (gcal);
- }
- } else
- e_cal_model_set_search_query (e_calendar_view_get_model (priv->views[i]), sexp);
- }
+ if (i == GNOME_CAL_LIST_VIEW) {
+ if (!priv->lview_select_daten_range) {
+ cal_search_bar_get_time_range ((CalSearchBar *)priv->search_bar, &start, &end);
+ e_cal_model_set_search_query_with_time_range (e_calendar_view_get_model (priv->views [i]), sexp, start, end);
+ } else {
+ start = priv->base_view_time;
+ get_times_for_views (gcal, GNOME_CAL_LIST_VIEW, &start, &end);
+
+ e_cal_model_set_search_query_with_time_range (e_calendar_view_get_model (priv->views [i]), sexp, start, end);
+
+ if (priv->current_view_type == GNOME_CAL_LIST_VIEW)
+ gnome_calendar_update_date_navigator (gcal);
+ }
+ } else
+ e_cal_model_set_search_query (e_calendar_view_get_model (priv->views[i]), sexp);
/* Set the query on the task pad */
update_todo_view (gcal);
@@ -1224,6 +1288,9 @@ set_timezone (GnomeCalendar *calendar)
/* FIXME Error checking */
e_cal_set_default_timezone (priv->default_client[i], priv->zone, NULL);
}
+
+ if (priv->views [priv->current_view_type])
+ e_calendar_view_set_timezone (priv->views [priv->current_view_type], priv->zone);
}
static void
@@ -1506,6 +1573,7 @@ setup_widgets (GnomeCalendar *gcal)
ECalModel *w_model;
GtkWidget *vbox;
GtkWidget *label;
+ ECalModel *cal_model;
int i;
char *tmp;
@@ -1610,8 +1678,12 @@ setup_widgets (GnomeCalendar *gcal)
/* Timeout check to hide completed items */
priv->update_timeout = g_timeout_add_full (G_PRIORITY_LOW, 60000, (GSourceFunc) update_todo_view_cb, gcal, NULL);
+ /* Create the model for the views */
+ cal_model = (ECalModel *) e_cal_model_calendar_new ();
+ e_cal_model_set_flags (cal_model, E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES);
+
/* The Day View. */
- priv->day_view = e_day_view_new ();
+ priv->day_view = e_day_view_new (cal_model);
e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->day_view), gcal);
e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->day_view), priv->zone);
g_signal_connect (priv->day_view, "selection_changed",
@@ -1619,7 +1691,7 @@ setup_widgets (GnomeCalendar *gcal)
connect_day_view_focus (gcal, E_DAY_VIEW (priv->day_view));
/* The Work Week View. */
- priv->work_week_view = e_day_view_new ();
+ priv->work_week_view = e_day_view_new (cal_model);
e_day_view_set_work_week_view (E_DAY_VIEW (priv->work_week_view),
TRUE);
e_day_view_set_days_shown (E_DAY_VIEW (priv->work_week_view), 5);
@@ -1631,7 +1703,7 @@ setup_widgets (GnomeCalendar *gcal)
priv->update_marcus_bains_line_timeout = g_timeout_add_full (G_PRIORITY_LOW, 60000, (GSourceFunc) update_marcus_bains_line_cb, gcal, NULL);
/* The Week View. */
- priv->week_view = e_week_view_new ();
+ priv->week_view = e_week_view_new (cal_model);
e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->week_view), gcal);
e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->week_view), priv->zone);
g_signal_connect (priv->week_view, "selection_changed",
@@ -1650,7 +1722,7 @@ setup_widgets (GnomeCalendar *gcal)
G_CALLBACK (view_done_cb), gcal);
/* The Month View. */
- priv->month_view = e_week_view_new ();
+ priv->month_view = e_week_view_new (cal_model);
e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->month_view), gcal);
e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->month_view), priv->zone);
e_week_view_set_multi_week_view (E_WEEK_VIEW (priv->month_view), TRUE);
@@ -1666,7 +1738,7 @@ setup_widgets (GnomeCalendar *gcal)
gcal);
/* The List View. */
- priv->list_view = e_cal_list_view_new ();
+ priv->list_view = e_cal_list_view_new (cal_model);
e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->list_view), gcal);
e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->list_view), priv->zone);
@@ -1733,10 +1805,6 @@ setup_widgets (GnomeCalendar *gcal)
g_signal_connect (e_memo_table_get_model ((EMemoTable *)priv->memo), "cal_view_done",
G_CALLBACK (view_done_cb), gcal);
-
- /* 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 */
@@ -2041,25 +2109,21 @@ static void
update_view_times (GnomeCalendar *gcal, time_t start_time)
{
GnomeCalendarPrivate *priv;
- int i;
+ ECalModel *model;
+ time_t real_start_time = start_time;
+ time_t end_time;
priv = gcal->priv;
priv->base_view_time = start_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);
+ model = e_calendar_view_get_model (priv->views [priv->current_view_type]);
+ get_times_for_views (gcal, priv->current_view_type, &real_start_time, &end_time);
- if (i == GNOME_CAL_LIST_VIEW && !priv->lview_select_daten_range)
- continue;
+ if (priv->current_view_type == GNOME_CAL_LIST_VIEW && !priv->lview_select_daten_range)
+ return;
- e_cal_model_set_time_range (model, real_start_time, end_time);
- }
+ e_cal_model_set_time_range (model, real_start_time, end_time);
}
static void
@@ -2233,6 +2297,7 @@ display_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, gboolean gra
{
GnomeCalendarPrivate *priv;
gboolean preserve_day;
+ int i;
priv = gcal->priv;
@@ -2276,10 +2341,17 @@ display_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, gboolean gra
}
priv->current_view_type = view_type;
+ E_CALENDAR_VIEW (priv->views [view_type])->in_focus = TRUE;
gtk_notebook_set_current_page (
GTK_NOTEBOOK (priv->notebook), (int) view_type);
+ for (i = 0; i < GNOME_CAL_LAST_VIEW ; i++) {
+ if (i == view_type)
+ continue;
+ E_CALENDAR_VIEW (priv->views [i])->in_focus = FALSE;
+ }
+
if (grab_focus)
focus_current_view (gcal);
@@ -2331,12 +2403,15 @@ display_view_cb (GalViewInstance *view_instance, GalView *view, gpointer data)
display_view (gcal, view_type, TRUE);
+
+ if (!priv->base_view_time)
+ update_view_times (gcal, time (NULL));
+ else
+ update_view_times (gcal, priv->base_view_time);
+
gnome_calendar_update_date_navigator (gcal);
gnome_calendar_notify_dates_shown_changed (gcal);
- if (!priv->lview_select_daten_range && priv->current_view_type != GNOME_CAL_LIST_VIEW)
- update_query (gcal);
-
}
/**
@@ -2607,15 +2682,44 @@ gnome_calendar_set_pane_positions (GnomeCalendar *gcal)
}
}
+struct _mclient_msg {
+ Message header;
+ ECalModel *model;
+ ECal *client;
+};
+
+static void
+add_mclient_async (struct _mclient_msg *msg)
+{
+ e_cal_model_add_client (msg->model, msg->client);
+
+ g_object_unref (msg->client);
+ g_object_unref (msg->model);
+ g_slice_free (struct _mclient_msg, msg);
+}
+
+static void
+add_mclient (ECalModel *model, ECal *client)
+{
+ struct _mclient_msg *msg;
+
+ msg = g_slice_new0 (struct _mclient_msg);
+ msg->header.func = (MessageFunc) add_mclient_async;
+ msg->model = g_object_ref (model);
+ msg->client = g_object_ref (client);
+
+ message_push ((Message *) msg);
+}
+
static void
client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal)
{
GnomeCalendarPrivate *priv;
ECalSourceType source_type;
ESource *source;
+ ECalModel *model;
ECalLoadState state;
char *msg;
- int i;
priv = gcal->priv;
@@ -2682,7 +2786,6 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal)
g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, client_cal_opened_cb, NULL);
-
switch (source_type) {
case E_CAL_SOURCE_TYPE_EVENT :
msg = g_strdup_printf (_("Loading appointments at %s"), e_cal_get_uri (ecal));
@@ -2690,12 +2793,8 @@ client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal)
g_free (msg);
/* add client to the views */
- for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
- ECalModel *model;
-
- model = e_calendar_view_get_model (priv->views[i]);
- e_cal_model_add_client (model, ecal);
- }
+ model = e_calendar_view_get_model (priv->views[priv->current_view_type]);
+ add_mclient (model, ecal);
/* update date navigator query */
update_query (gcal);
@@ -2731,7 +2830,6 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar
ECalSourceType source_type;
ESource *source;
ECalLoadState state;
- int i;
priv = gcal->priv;
@@ -2788,11 +2886,9 @@ default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar
switch (source_type) {
case E_CAL_SOURCE_TYPE_EVENT:
- for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
e_cal_model_set_default_client (
- e_calendar_view_get_model (E_CALENDAR_VIEW (priv->views[i])),
+ e_calendar_view_get_model (E_CALENDAR_VIEW (priv->views[priv->current_view_type])),
ecal);
- }
break;
case E_CAL_SOURCE_TYPE_TODO:
@@ -3111,7 +3207,6 @@ gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_
GnomeCalendarPrivate *priv;
ECal *client;
ECalModel *model;
- int i;
GList *l;
g_return_val_if_fail (gcal != NULL, FALSE);
@@ -3143,10 +3238,8 @@ gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_
}
}
- for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
- model = e_calendar_view_get_model (priv->views[i]);
- e_cal_model_remove_client (model, client);
- }
+ model = e_calendar_view_get_model (priv->views[priv->current_view_type]);
+ e_cal_model_remove_client (model, client);
/* update date navigator query */
update_query (gcal);
@@ -3413,8 +3506,9 @@ gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem, Gnom
/* If the selection hasn't changed just return. */
if (!g_date_compare (&start_date, &new_start_date)
- && !g_date_compare (&end_date, &new_end_date))
+ && !g_date_compare (&end_date, &new_end_date)) {
return;
+ }
new_days_shown = g_date_get_julian (&new_end_date) - g_date_get_julian (&new_start_date) + 1;
@@ -3458,8 +3552,8 @@ gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem, Gnom
/* Make the views display things properly */
update_view_times (gcal, new_time);
-
set_view (gcal, view_type, TRUE);
+
gnome_calendar_notify_dates_shown_changed (gcal);
}