aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/e-cal-model.c
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui/e-cal-model.c')
-rw-r--r--calendar/gui/e-cal-model.c121
1 files changed, 92 insertions, 29 deletions
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index c2d4fc57ad..ebba86d864 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -34,6 +34,8 @@
typedef struct {
ECal *client;
ECalView *query;
+
+ gboolean do_query;
} ECalModelClient;
struct _ECalModelPrivate {
@@ -88,9 +90,15 @@ 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);
+static ECalModelClient *add_new_client (ECalModel *model, ECal *client, gboolean do_query);
+static ECalModelClient *find_client_data (ECalModel *model, ECal *client);
+static void remove_client_objects (ECalModel *model, ECalModelClient *client_data);
+static void remove_client (ECalModel *model, ECalModelClient *client_data);
+
/* Signal IDs */
enum {
TIME_RANGE_CHANGED,
+ ROW_APPENDED,
LAST_SIGNAL
};
@@ -135,6 +143,15 @@ e_cal_model_class_init (ECalModelClass *klass)
NULL, NULL,
e_calendar_marshal_VOID__LONG_LONG,
G_TYPE_NONE, 2, G_TYPE_LONG, G_TYPE_LONG);
+
+ signals[ROW_APPENDED] =
+ g_signal_new ("row_appended",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ECalModelClass, row_appended),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
@@ -758,9 +775,13 @@ ecm_append_row (ETableModel *etm, ETableModel *source, int row)
g_warning (G_STRLOC ": Could not create the object!");
/* FIXME: show error dialog */
+ icalcomponent_free (comp_data.icalcomp);
+ return;
}
icalcomponent_free (comp_data.icalcomp);
+
+ g_signal_emit (G_OBJECT (model), signals[ROW_APPENDED], 0);
}
static void *
@@ -1097,6 +1118,8 @@ e_cal_model_get_default_client (ECalModel *model)
priv = model->priv;
+ /* FIXME Should we force the client to be open? */
+
/* we always return a valid ECal, since we rely on it in many places */
if (priv->default_client)
return priv->default_client;
@@ -1113,6 +1136,7 @@ void
e_cal_model_set_default_client (ECalModel *model, ECal *client)
{
ECalModelPrivate *priv;
+ ECalModelClient *client_data;
g_return_if_fail (model != NULL);
g_return_if_fail (E_IS_CAL_MODEL (model));
@@ -1121,11 +1145,21 @@ e_cal_model_set_default_client (ECalModel *model, ECal *client)
priv = model->priv;
+ if (priv->default_client) {
+ ECalModelClient *client_data;
+
+ client_data = find_client_data (model, priv->default_client);
+ g_assert (client_data);
+
+ if (!client_data->do_query)
+ remove_client (model, client_data);
+ }
+
/* Make sure its in the model */
- e_cal_model_add_client (model, client);
+ client_data = add_new_client (model, client, FALSE);
/* Store the default client */
- priv->default_client = e_cal_model_get_client_for_uri (model, e_cal_get_uri (client));
+ priv->default_client = client_data->client;
}
/**
@@ -1366,6 +1400,10 @@ update_e_cal_view_for_client (ECalModel *model, ECalModelClient *client_data)
/* prepare the query */
g_assert (priv->full_sexp != NULL);
+ /* Don't create the new query if we won't use it */
+ if (!client_data->do_query)
+ return;
+
if (!e_cal_get_query (client_data->client, priv->full_sexp, &client_data->query, NULL)) {
g_warning (G_STRLOC ": Unable to get query");
@@ -1412,24 +1450,46 @@ cal_opened_cb (ECal *client, ECalendarStatus status, gpointer user_data)
update_e_cal_view_for_client (model, client_data);
}
+
static ECalModelClient *
-add_new_client (ECalModel *model, ECal *client)
+add_new_client (ECalModel *model, ECal *client, gboolean do_query)
{
ECalModelPrivate *priv;
ECalModelClient *client_data;
-
+ ECal *existing_client;
+
priv = model->priv;
+ /* Look for an existing client with the same URI */
+ existing_client = e_cal_model_get_client_for_uri (model, e_cal_get_uri (client));
+ if (existing_client) {
+ client_data = find_client_data (model, client);
+ g_assert (client_data);
+
+ if (!client_data->do_query)
+ client_data->do_query = do_query;
+
+ goto load;
+ }
+
client_data = g_new0 (ECalModelClient, 1);
- client_data->client = client;
+ client_data->client = g_object_ref (client);
client_data->query = NULL;
- g_object_ref (client_data->client);
+ client_data->do_query = do_query;
priv->clients = g_list_append (priv->clients, client_data);
g_signal_connect (G_OBJECT (client_data->client), "backend_died",
G_CALLBACK (backend_died_cb), model);
+ load:
+ if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) {
+ update_e_cal_view_for_client (model, client_data);
+ } else {
+ g_signal_connect (client, "cal_opened", G_CALLBACK (cal_opened_cb), model);
+ e_cal_open_async (client, TRUE);
+ }
+
return client_data;
}
@@ -1447,29 +1507,14 @@ e_cal_model_add_client (ECalModel *model, ECal *client)
priv = model->priv;
- if (e_cal_model_get_client_for_uri (model, e_cal_get_uri (client)))
- return;
-
- client_data = add_new_client (model, client);
- if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED) {
- update_e_cal_view_for_client (model, client_data);
- } else {
- g_signal_connect (client, "cal_opened", G_CALLBACK (cal_opened_cb), model);
- e_cal_open_async (client, TRUE);
- }
+ client_data = add_new_client (model, client, TRUE);
}
static void
-remove_client (ECalModel *model, ECalModelClient *client_data)
+remove_client_objects (ECalModel *model, ECalModelClient *client_data)
{
- gint i;
-
- g_signal_handlers_disconnect_matched (client_data->client, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model);
- if (client_data->query)
- g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model);
-
- model->priv->clients = g_list_remove (model->priv->clients, client_data);
-
+ int i;
+
/* remove all objects belonging to this client */
for (i = model->priv->objects->len; i > 0; i--) {
ECalModelComponent *comp_data = (ECalModelComponent *) g_ptr_array_index (model->priv->objects, i - 1);
@@ -1485,11 +1530,29 @@ remove_client (ECalModel *model, ECalModelClient *client_data)
e_table_model_row_deleted (E_TABLE_MODEL (model), i - 1);
}
}
+}
+
+static void
+remove_client (ECalModel *model, ECalModelClient *client_data)
+{
+ /* FIXME We might not want to disconnect the open signal for the default client */
+ g_signal_handlers_disconnect_matched (client_data->client, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model);
+ if (client_data->query)
+ g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, model);
+
+ remove_client_objects (model, client_data);
+
+ /* If this is the default client and we were querying (so it
+ * was also a source), keep it around but don't query it */
+ if (model->priv->default_client == client_data->client && client_data->do_query) {
+ client_data->do_query = FALSE;
+
+ return;
+ }
+
+ /* Remove the client from the list */
+ model->priv->clients = g_list_remove (model->priv->clients, client_data);
- /* If this was the default client, unset it */
- if (model->priv->default_client == client_data->client)
- model->priv->default_client = NULL;
-
/* free all remaining memory */
g_object_unref (client_data->client);
if (client_data->query)