aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2010-01-30 03:02:53 +0800
committerMatthew Barnes <mbarnes@redhat.com>2010-01-30 22:02:11 +0800
commitab794abcd3fa23969a1f8b04d0236838f721180a (patch)
tree1e70c65ac5dba3294df2754a89a939b864cf6bcf
parent8d85229f8fc9ff0e27b1f7790f61605c04337d7b (diff)
downloadgsoc2013-evolution-ab794abcd3fa23969a1f8b04d0236838f721180a.tar
gsoc2013-evolution-ab794abcd3fa23969a1f8b04d0236838f721180a.tar.gz
gsoc2013-evolution-ab794abcd3fa23969a1f8b04d0236838f721180a.tar.bz2
gsoc2013-evolution-ab794abcd3fa23969a1f8b04d0236838f721180a.tar.lz
gsoc2013-evolution-ab794abcd3fa23969a1f8b04d0236838f721180a.tar.xz
gsoc2013-evolution-ab794abcd3fa23969a1f8b04d0236838f721180a.tar.zst
gsoc2013-evolution-ab794abcd3fa23969a1f8b04d0236838f721180a.zip
Improve sidebar and ECalModel interaction.
Restores the "default client" behavior from 2.28, so that "Click to Add" task and memo fields work properly.
-rw-r--r--calendar/gui/e-cal-model.c48
-rw-r--r--modules/calendar/e-cal-shell-sidebar.c251
-rw-r--r--modules/calendar/e-cal-shell-sidebar.h2
-rw-r--r--modules/calendar/e-cal-shell-view-private.c5
-rw-r--r--modules/calendar/e-memo-shell-sidebar.c250
-rw-r--r--modules/calendar/e-memo-shell-sidebar.h2
-rw-r--r--modules/calendar/e-memo-shell-view-private.c7
-rw-r--r--modules/calendar/e-task-shell-sidebar.c250
-rw-r--r--modules/calendar/e-task-shell-sidebar.h2
-rw-r--r--modules/calendar/e-task-shell-view-private.c8
10 files changed, 693 insertions, 132 deletions
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index 58ca63e1cf..7533e56ece 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -127,6 +127,7 @@ static void remove_client (ECalModel *model, ECalModelClient *client_data);
enum {
PROP_0,
+ PROP_DEFAULT_CLIENT,
PROP_SHELL_SETTINGS,
PROP_TIMEZONE,
PROP_USE_24_HOUR_FORMAT,
@@ -165,6 +166,12 @@ cal_model_set_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
+ case PROP_DEFAULT_CLIENT:
+ e_cal_model_set_default_client (
+ E_CAL_MODEL (object),
+ g_value_get_object (value));
+ return;
+
case PROP_SHELL_SETTINGS:
cal_model_set_shell_settings (
E_CAL_MODEL (object),
@@ -200,6 +207,13 @@ cal_model_get_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
+ case PROP_DEFAULT_CLIENT:
+ g_value_set_object (
+ value,
+ e_cal_model_get_default_client (
+ E_CAL_MODEL (object)));
+ return;
+
case PROP_SHELL_SETTINGS:
g_value_set_object (
value,
@@ -357,6 +371,16 @@ e_cal_model_class_init (ECalModelClass *class)
g_object_class_install_property (
object_class,
+ PROP_DEFAULT_CLIENT,
+ g_param_spec_object (
+ "default-client",
+ _("Default Client"),
+ NULL,
+ E_TYPE_CAL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
PROP_SHELL_SETTINGS,
g_param_spec_object (
"shell-settings",
@@ -1516,10 +1540,10 @@ 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));
- g_return_if_fail (client != NULL);
- g_return_if_fail (E_IS_CAL (client));
+
+ if (client != NULL)
+ g_return_if_fail (E_IS_CAL (client));
priv = model->priv;
@@ -1533,11 +1557,16 @@ e_cal_model_set_default_client (ECalModel *model, ECal *client)
}
}
- /* Make sure its in the model */
- client_data = add_new_client (model, client, FALSE);
+ if (client != NULL) {
+ /* Make sure its in the model */
+ client_data = add_new_client (model, client, FALSE);
- /* Store the default client */
- priv->default_client = client_data->client;
+ /* Store the default client */
+ priv->default_client = client_data->client;
+ } else
+ priv->default_client = NULL;
+
+ g_object_notify (G_OBJECT (model), "default-client");
}
GList *
@@ -2147,11 +2176,6 @@ add_new_client (ECalModel *model, ECal *client, gboolean do_query)
/* Look to see if we already have this client */
client_data = find_client_data (model, client);
if (client_data) {
- if (do_query && client_data->client == priv->default_client) {
- g_warning ("%s: %s: You shouldn't request a query on a default client", G_STRLOC, G_STRFUNC);
- return client_data;
- }
-
if (client_data->do_query)
return client_data;
else
diff --git a/modules/calendar/e-cal-shell-sidebar.c b/modules/calendar/e-cal-shell-sidebar.c
index 390be5e6da..3b78afa0d3 100644
--- a/modules/calendar/e-cal-shell-sidebar.c
+++ b/modules/calendar/e-cal-shell-sidebar.c
@@ -34,8 +34,8 @@
#include "calendar/gui/e-calendar-selector.h"
#include "calendar/gui/misc.h"
-#include "e-cal-shell-backend.h"
#include "e-cal-shell-view.h"
+#include "e-cal-shell-backend.h"
#define E_CAL_SHELL_SIDEBAR_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -48,11 +48,21 @@ struct _ECalShellSidebarPrivate {
/* UID -> Client */
GHashTable *client_table;
+
+ /* The default client is for ECalModel. It follows the
+ * sidebar's primary selection, even if the highlighted
+ * source is not selected. The tricky part is we don't
+ * update the property until the client is successfully
+ * opened. So the user first highlights a source, then
+ * sometime later we update our default-client property
+ * which is bound by an EBinding to ECalModel. */
+ ECal *default_client;
};
enum {
PROP_0,
PROP_DATE_NAVIGATOR,
+ PROP_DEFAULT_CLIENT,
PROP_SELECTOR
};
@@ -166,6 +176,7 @@ cal_shell_sidebar_client_opened_cb (ECalShellSidebar *cal_shell_sidebar,
EShellView *shell_view;
EShellWindow *shell_window;
EShellSidebar *shell_sidebar;
+ const gchar *message;
shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar);
shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
@@ -175,39 +186,121 @@ cal_shell_sidebar_client_opened_cb (ECalShellSidebar *cal_shell_sidebar,
status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
e_auth_cal_forget_password (client);
+ /* Handle errors. */
switch (status) {
case E_CALENDAR_STATUS_OK:
- g_signal_handlers_disconnect_matched (
- client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
- cal_shell_sidebar_client_opened_cb, NULL);
-
- cal_shell_sidebar_emit_status_message (
- cal_shell_sidebar, _("Loading calendars"));
- cal_shell_sidebar_emit_client_added (
- cal_shell_sidebar, client);
- cal_shell_sidebar_emit_status_message (
- cal_shell_sidebar, NULL);
break;
case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
e_cal_open_async (client, FALSE);
- break;
+ return;
case E_CALENDAR_STATUS_BUSY:
- break;
+ return;
case E_CALENDAR_STATUS_REPOSITORY_OFFLINE:
e_alert_run_dialog_for_args (
GTK_WINDOW (shell_window),
"calendar:prompt-no-contents-offline-calendar",
NULL);
- break;
+ /* fall through */
default:
- cal_shell_sidebar_emit_client_removed (
- cal_shell_sidebar, client);
+ e_cal_shell_sidebar_remove_source (
+ cal_shell_sidebar,
+ e_cal_get_source (client));
+ return;
+ }
+
+ g_assert (status == E_CALENDAR_STATUS_OK);
+
+ g_signal_handlers_disconnect_matched (
+ client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
+ cal_shell_sidebar_client_opened_cb, NULL);
+
+ message = _("Loading calendars");
+ cal_shell_sidebar_emit_status_message (cal_shell_sidebar, message);
+ cal_shell_sidebar_emit_client_added (cal_shell_sidebar, client);
+ cal_shell_sidebar_emit_status_message (cal_shell_sidebar, NULL);
+}
+
+static void
+cal_shell_sidebar_default_opened_cb (ECalShellSidebar *cal_shell_sidebar,
+ ECalendarStatus status,
+ ECal *client)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+
+ shell_sidebar = E_SHELL_SIDEBAR (cal_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED ||
+ status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
+ e_auth_cal_forget_password (client);
+
+ /* Handle errors. */
+ switch (status) {
+ case E_CALENDAR_STATUS_OK:
break;
+
+ case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
+ e_cal_open_async (client, FALSE);
+ return;
+
+ case E_CALENDAR_STATUS_BUSY:
+ return;
+
+ default:
+ e_cal_shell_sidebar_remove_source (
+ cal_shell_sidebar,
+ e_cal_get_source (client));
+ return;
}
+
+ g_assert (status == E_CALENDAR_STATUS_OK);
+
+ g_signal_handlers_disconnect_matched (
+ client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
+ cal_shell_sidebar_default_opened_cb, NULL);
+
+ g_object_notify (G_OBJECT (cal_shell_sidebar), "default-client");
+}
+
+static void
+cal_shell_sidebar_set_default (ECalShellSidebar *cal_shell_sidebar,
+ ESource *source)
+{
+ ECalSourceType source_type;
+ GHashTable *client_table;
+ ECal *client;
+ const gchar *uid;
+
+ source_type = E_CAL_SOURCE_TYPE_EVENT;
+ client_table = cal_shell_sidebar->priv->client_table;
+
+ uid = e_source_peek_uid (source);
+ client = g_hash_table_lookup (client_table, uid);
+
+ if (cal_shell_sidebar->priv->default_client != NULL)
+ g_object_unref (cal_shell_sidebar->priv->default_client);
+
+ if (client != NULL)
+ g_object_ref (client);
+ else
+ client = e_auth_new_cal_from_source (source, source_type);
+
+ cal_shell_sidebar->priv->default_client = client;
+ g_return_if_fail (client != NULL);
+
+ g_signal_connect_swapped (
+ client, "cal-opened",
+ G_CALLBACK (cal_shell_sidebar_default_opened_cb),
+ cal_shell_sidebar);
+
+ e_cal_open_async (client, FALSE);
}
static void
@@ -295,6 +388,8 @@ cal_shell_sidebar_primary_selection_changed_cb (ECalShellSidebar *cal_shell_side
e_shell_settings_set_string (
shell_settings, "cal-primary-calendar",
e_source_peek_uid (source));
+
+ cal_shell_sidebar_set_default (cal_shell_sidebar, source);
}
static void
@@ -306,13 +401,22 @@ cal_shell_sidebar_get_property (GObject *object,
switch (property_id) {
case PROP_DATE_NAVIGATOR:
g_value_set_object (
- value, e_cal_shell_sidebar_get_date_navigator (
+ value,
+ e_cal_shell_sidebar_get_date_navigator (
+ E_CAL_SHELL_SIDEBAR (object)));
+ return;
+
+ case PROP_DEFAULT_CLIENT:
+ g_value_set_object (
+ value,
+ e_cal_shell_sidebar_get_default_client (
E_CAL_SHELL_SIDEBAR (object)));
return;
case PROP_SELECTOR:
g_value_set_object (
- value, e_cal_shell_sidebar_get_selector (
+ value,
+ e_cal_shell_sidebar_get_selector (
E_CAL_SHELL_SIDEBAR (object)));
return;
}
@@ -342,6 +446,11 @@ cal_shell_sidebar_dispose (GObject *object)
priv->date_navigator = NULL;
}
+ if (priv->default_client != NULL) {
+ g_object_unref (priv->default_client);
+ priv->default_client = NULL;
+ }
+
g_hash_table_remove_all (priv->client_table);
/* Chain up to parent's dispose() method. */
@@ -370,18 +479,11 @@ cal_shell_sidebar_constructed (GObject *object)
EShellBackend *shell_backend;
EShellSidebar *shell_sidebar;
EShellSettings *shell_settings;
- ESourceSelector *selector;
ESourceList *source_list;
- ESource *source;
ECalendarItem *calitem;
- GConfBridge *bridge;
- GtkTreeModel *model;
GtkWidget *container;
GtkWidget *widget;
AtkObject *a11y;
- GSList *list, *iter;
- const gchar *key;
- gchar *uid;
priv = E_CAL_SHELL_SIDEBAR_GET_PRIVATE (object);
@@ -443,16 +545,55 @@ cal_shell_sidebar_constructed (GObject *object)
e_binding_new (
shell_settings, "cal-week-start-day",
calitem, "week-start-day");
+}
- /* Restore the selector state from the last session. */
+static void
+cal_shell_sidebar_realize (GtkWidget *widget)
+{
+ ECalShellSidebarPrivate *priv;
+ EShell *shell;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ EShellSidebar *shell_sidebar;
+ EShellSettings *shell_settings;
+ ESourceSelector *selector;
+ ESourceList *source_list;
+ ESource *source;
+ GConfBridge *bridge;
+ GtkTreeModel *model;
+ GSList *list, *iter;
+ GObject *object;
+ const gchar *key;
+ gchar *uid;
+
+ priv = E_CAL_SHELL_SIDEBAR_GET_PRIVATE (widget);
+
+ /* Restore the selector state from the last session. We do this
+ * in realize() instead of constructed() so the shell view has a
+ * chance to connect handlers to our signals. */
+
+ shell_sidebar = E_SHELL_SIDEBAR (widget);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
selector = E_SOURCE_SELECTOR (priv->selector);
model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector));
+ source_list = e_cal_shell_backend_get_source_list (
+ E_CAL_SHELL_BACKEND (shell_backend));
+
g_signal_connect_swapped (
model, "row-changed",
G_CALLBACK (cal_shell_sidebar_row_changed_cb),
- object);
+ shell_sidebar);
+
+ g_signal_connect_swapped (
+ selector, "primary-selection-changed",
+ G_CALLBACK (cal_shell_sidebar_primary_selection_changed_cb),
+ shell_sidebar);
source = NULL;
uid = e_shell_settings_get_string (
@@ -483,12 +624,7 @@ cal_shell_sidebar_constructed (GObject *object)
g_signal_connect_swapped (
selector, "selection-changed",
G_CALLBACK (cal_shell_sidebar_selection_changed_cb),
- object);
-
- g_signal_connect_swapped (
- selector, "primary-selection-changed",
- G_CALLBACK (cal_shell_sidebar_primary_selection_changed_cb),
- object);
+ shell_sidebar);
/* Bind GObject properties to GConf keys. */
@@ -497,6 +633,9 @@ cal_shell_sidebar_constructed (GObject *object)
object = G_OBJECT (priv->paned);
key = "/apps/evolution/calendar/display/date_navigator_vpane_position";
gconf_bridge_bind_property_delayed (bridge, key, object, "vposition");
+
+ /* Chain up to parent's realize() method. */
+ GTK_WIDGET_CLASS (parent_class)->realize (widget);
}
static guint32
@@ -562,10 +701,10 @@ cal_shell_sidebar_client_removed (ECalShellSidebar *cal_shell_sidebar,
NULL, NULL, cal_shell_sidebar);
source = e_cal_get_source (client);
- e_source_selector_unselect_source (selector, source);
-
uid = e_source_peek_uid (source);
+
g_hash_table_remove (client_table, uid);
+ e_source_selector_unselect_source (selector, source);
cal_shell_sidebar_emit_status_message (cal_shell_sidebar, NULL);
}
@@ -574,6 +713,7 @@ static void
cal_shell_sidebar_class_init (ECalShellSidebarClass *class)
{
GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
EShellSidebarClass *shell_sidebar_class;
parent_class = g_type_class_peek_parent (class);
@@ -585,6 +725,9 @@ cal_shell_sidebar_class_init (ECalShellSidebarClass *class)
object_class->finalize = cal_shell_sidebar_finalize;
object_class->constructed = cal_shell_sidebar_constructed;
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->realize = cal_shell_sidebar_realize;
+
shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class);
shell_sidebar_class->check_state = cal_shell_sidebar_check_state;
@@ -602,6 +745,16 @@ cal_shell_sidebar_class_init (ECalShellSidebarClass *class)
g_object_class_install_property (
object_class,
+ PROP_DEFAULT_CLIENT,
+ g_param_spec_object (
+ "default-client",
+ _("Default Calendar Client"),
+ _("Default client for calendar operations"),
+ E_TYPE_CAL,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
PROP_SELECTOR,
g_param_spec_object (
"selector",
@@ -718,6 +871,15 @@ e_cal_shell_sidebar_get_date_navigator (ECalShellSidebar *cal_shell_sidebar)
return E_CALENDAR (cal_shell_sidebar->priv->date_navigator);
}
+ECal *
+e_cal_shell_sidebar_get_default_client (ECalShellSidebar *cal_shell_sidebar)
+{
+ g_return_val_if_fail (
+ E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar), NULL);
+
+ return cal_shell_sidebar->priv->default_client;
+}
+
ESourceSelector *
e_cal_shell_sidebar_get_selector (ECalShellSidebar *cal_shell_sidebar)
{
@@ -731,8 +893,10 @@ void
e_cal_shell_sidebar_add_source (ECalShellSidebar *cal_shell_sidebar,
ESource *source)
{
+ ECalSourceType source_type;
ESourceSelector *selector;
GHashTable *client_table;
+ ECal *default_client;
ECal *client;
const gchar *uid;
const gchar *uri;
@@ -741,7 +905,9 @@ e_cal_shell_sidebar_add_source (ECalShellSidebar *cal_shell_sidebar,
g_return_if_fail (E_IS_CAL_SHELL_SIDEBAR (cal_shell_sidebar));
g_return_if_fail (E_IS_SOURCE (source));
+ source_type = E_CAL_SOURCE_TYPE_EVENT;
client_table = cal_shell_sidebar->priv->client_table;
+ default_client = cal_shell_sidebar->priv->default_client;
selector = e_cal_shell_sidebar_get_selector (cal_shell_sidebar);
uid = e_source_peek_uid (source);
@@ -750,7 +916,20 @@ e_cal_shell_sidebar_add_source (ECalShellSidebar *cal_shell_sidebar,
if (client != NULL)
return;
- client = e_auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_EVENT);
+ if (default_client != NULL) {
+ ESource *default_source;
+ const gchar *default_uid;
+
+ default_source = e_cal_get_source (default_client);
+ default_uid = e_source_peek_uid (default_source);
+
+ if (g_strcmp0 (uid, default_uid) == 0)
+ client = g_object_ref (default_client);
+ }
+
+ if (client == NULL)
+ client = e_auth_new_cal_from_source (source, source_type);
+
g_return_if_fail (client != NULL);
g_signal_connect_swapped (
diff --git a/modules/calendar/e-cal-shell-sidebar.h b/modules/calendar/e-cal-shell-sidebar.h
index 6169d303d6..6919d7ab52 100644
--- a/modules/calendar/e-cal-shell-sidebar.h
+++ b/modules/calendar/e-cal-shell-sidebar.h
@@ -86,6 +86,8 @@ GList * e_cal_shell_sidebar_get_clients
(ECalShellSidebar *cal_shell_sidebar);
ECalendar * e_cal_shell_sidebar_get_date_navigator
(ECalShellSidebar *cal_shell_sidebar);
+ECal * e_cal_shell_sidebar_get_default_client
+ (ECalShellSidebar *cal_shell_sidebar);
ESourceSelector *
e_cal_shell_sidebar_get_selector
(ECalShellSidebar *cal_shell_sidebar);
diff --git a/modules/calendar/e-cal-shell-view-private.c b/modules/calendar/e-cal-shell-view-private.c
index 74a2bbcaf5..b5f9ba55d7 100644
--- a/modules/calendar/e-cal-shell-view-private.c
+++ b/modules/calendar/e-cal-shell-view-private.c
@@ -566,6 +566,11 @@ e_cal_shell_view_private_constructed (ECalShellView *cal_shell_view)
e_cal_shell_view_update_search_filter (cal_shell_view);
e_cal_shell_view_update_timezone (cal_shell_view);
+ /* Keep the ECalModel in sync with the sidebar. */
+ e_binding_new (
+ shell_sidebar, "default-client",
+ model, "default-client");
+
/* Keep the toolbar view buttons in sync with the calendar. */
e_mutual_binding_new (
calendar, "view",
diff --git a/modules/calendar/e-memo-shell-sidebar.c b/modules/calendar/e-memo-shell-sidebar.c
index e76341c83a..7ce7441eec 100644
--- a/modules/calendar/e-memo-shell-sidebar.c
+++ b/modules/calendar/e-memo-shell-sidebar.c
@@ -25,7 +25,6 @@
#include <glib/gi18n.h>
#include <libecal/e-cal.h>
-#include "e-util/e-binding.h"
#include "e-util/e-alert-dialog.h"
#include "e-util/e-util.h"
#include "calendar/common/authentication.h"
@@ -42,14 +41,23 @@
struct _EMemoShellSidebarPrivate {
GtkWidget *selector;
- icaltimezone *timezone;
/* UID -> Client */
GHashTable *client_table;
+
+ /* The default client is for ECalModel. It follows the
+ * sidebar's primary selection, even if the highlighted
+ * source is not selected. The tricky part is we don't
+ * update the property until the client is successfully
+ * opened. So the user first highlights a source, then
+ * sometime later we update our default-client property
+ * which is bound by an EBinding to ECalModel. */
+ ECal *default_client;
};
enum {
PROP_0,
+ PROP_DEFAULT_CLIENT,
PROP_SELECTOR
};
@@ -163,6 +171,7 @@ memo_shell_sidebar_client_opened_cb (EMemoShellSidebar *memo_shell_sidebar,
EShellView *shell_view;
EShellWindow *shell_window;
EShellSidebar *shell_sidebar;
+ const gchar *message;
shell_sidebar = E_SHELL_SIDEBAR (memo_shell_sidebar);
shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
@@ -172,39 +181,121 @@ memo_shell_sidebar_client_opened_cb (EMemoShellSidebar *memo_shell_sidebar,
status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
e_auth_cal_forget_password (client);
+ /* Handle errors. */
switch (status) {
case E_CALENDAR_STATUS_OK:
- g_signal_handlers_disconnect_matched (
- client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
- memo_shell_sidebar_client_opened_cb, NULL);
-
- memo_shell_sidebar_emit_status_message (
- memo_shell_sidebar, _("Loading memos"));
- memo_shell_sidebar_emit_client_added (
- memo_shell_sidebar, client);
- memo_shell_sidebar_emit_status_message (
- memo_shell_sidebar, NULL);
break;
case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
e_cal_open_async (client, FALSE);
- break;
+ return;
case E_CALENDAR_STATUS_BUSY:
- break;
+ return;
case E_CALENDAR_STATUS_REPOSITORY_OFFLINE:
e_alert_run_dialog_for_args (
GTK_WINDOW (shell_window),
"calendar:prompt-no-contents-offline-memos",
NULL);
- break;
+ /* fall through */
default:
- memo_shell_sidebar_emit_client_removed (
- memo_shell_sidebar, client);
+ e_memo_shell_sidebar_remove_source (
+ memo_shell_sidebar,
+ e_cal_get_source (client));
+ return;
+ }
+
+ g_assert (status == E_CALENDAR_STATUS_OK);
+
+ g_signal_handlers_disconnect_matched (
+ client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
+ memo_shell_sidebar_client_opened_cb, NULL);
+
+ message = _("Loading memos");
+ memo_shell_sidebar_emit_status_message (memo_shell_sidebar, message);
+ memo_shell_sidebar_emit_client_added (memo_shell_sidebar, client);
+ memo_shell_sidebar_emit_status_message (memo_shell_sidebar, NULL);
+}
+
+static void
+memo_shell_sidebar_default_opened_cb (EMemoShellSidebar *memo_shell_sidebar,
+ ECalendarStatus status,
+ ECal *client)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+
+ shell_sidebar = E_SHELL_SIDEBAR (memo_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED ||
+ status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
+ e_auth_cal_forget_password (client);
+
+ /* Handle errors. */
+ switch (status) {
+ case E_CALENDAR_STATUS_OK:
break;
+
+ case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
+ e_cal_open_async (client, FALSE);
+ return;
+
+ case E_CALENDAR_STATUS_BUSY:
+ return;
+
+ default:
+ e_memo_shell_sidebar_remove_source (
+ memo_shell_sidebar,
+ e_cal_get_source (client));
+ return;
}
+
+ g_assert (status == E_CALENDAR_STATUS_OK);
+
+ g_signal_handlers_disconnect_matched (
+ client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
+ memo_shell_sidebar_default_opened_cb, NULL);
+
+ g_object_notify (G_OBJECT (memo_shell_sidebar), "default-client");
+}
+
+static void
+memo_shell_sidebar_set_default (EMemoShellSidebar *memo_shell_sidebar,
+ ESource *source)
+{
+ ECalSourceType source_type;
+ GHashTable *client_table;
+ ECal *client;
+ const gchar *uid;
+
+ source_type = E_CAL_SOURCE_TYPE_JOURNAL;
+ client_table = memo_shell_sidebar->priv->client_table;
+
+ uid = e_source_peek_uid (source);
+ client = g_hash_table_lookup (client_table, uid);
+
+ if (memo_shell_sidebar->priv->default_client != NULL)
+ g_object_unref (memo_shell_sidebar->priv->default_client);
+
+ if (client != NULL)
+ g_object_ref (client);
+ else
+ client = e_auth_new_cal_from_source (source, source_type);
+
+ memo_shell_sidebar->priv->default_client = client;
+ g_return_if_fail (client != NULL);
+
+ g_signal_connect_swapped (
+ client, "cal-opened",
+ G_CALLBACK (memo_shell_sidebar_default_opened_cb),
+ memo_shell_sidebar);
+
+ e_cal_open_async (client, FALSE);
}
static void
@@ -292,6 +383,8 @@ memo_shell_sidebar_primary_selection_changed_cb (EMemoShellSidebar *memo_shell_s
e_shell_settings_set_string (
shell_settings, "cal-primary-memo-list",
e_source_peek_uid (source));
+
+ memo_shell_sidebar_set_default (memo_shell_sidebar, source);
}
static void
@@ -301,9 +394,17 @@ memo_shell_sidebar_get_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
+ case PROP_DEFAULT_CLIENT:
+ g_value_set_object (
+ value,
+ e_memo_shell_sidebar_get_default_client (
+ E_MEMO_SHELL_SIDEBAR (object)));
+ return;
+
case PROP_SELECTOR:
g_value_set_object (
- value, e_memo_shell_sidebar_get_selector (
+ value,
+ e_memo_shell_sidebar_get_selector (
E_MEMO_SHELL_SIDEBAR (object)));
return;
}
@@ -323,6 +424,11 @@ memo_shell_sidebar_dispose (GObject *object)
priv->selector = NULL;
}
+ if (priv->default_client != NULL) {
+ g_object_unref (priv->default_client);
+ priv->default_client = NULL;
+ }
+
g_hash_table_remove_all (priv->client_table);
/* Chain up to parent's dispose() method. */
@@ -346,20 +452,13 @@ static void
memo_shell_sidebar_constructed (GObject *object)
{
EMemoShellSidebarPrivate *priv;
- EShell *shell;
EShellView *shell_view;
EShellBackend *shell_backend;
EShellSidebar *shell_sidebar;
- EShellSettings *shell_settings;
- ESourceSelector *selector;
ESourceList *source_list;
- ESource *source;
GtkContainer *container;
- GtkTreeModel *model;
GtkWidget *widget;
AtkObject *a11y;
- GSList *list, *iter;
- gchar *uid;
priv = E_MEMO_SHELL_SIDEBAR_GET_PRIVATE (object);
@@ -370,9 +469,6 @@ memo_shell_sidebar_constructed (GObject *object)
shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
shell_backend = e_shell_view_get_shell_backend (shell_view);
- shell = e_shell_backend_get_shell (shell_backend);
- shell_settings = e_shell_get_shell_settings (shell);
-
source_list = e_memo_shell_backend_get_source_list (
E_MEMO_SHELL_BACKEND (shell_backend));
@@ -396,16 +492,52 @@ memo_shell_sidebar_constructed (GObject *object)
atk_object_set_name (a11y, _("Memo List Selector"));
priv->selector = g_object_ref (widget);
gtk_widget_show (widget);
+}
+
+static void
+memo_shell_sidebar_realize (GtkWidget *widget)
+{
+ EMemoShellSidebarPrivate *priv;
+ EShell *shell;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ EShellSidebar *shell_sidebar;
+ EShellSettings *shell_settings;
+ ESourceSelector *selector;
+ ESourceList *source_list;
+ ESource *source;
+ GtkTreeModel *model;
+ GSList *list, *iter;
+ gchar *uid;
+
+ priv = E_MEMO_SHELL_SIDEBAR_GET_PRIVATE (widget);
+
+ /* Restore the selector state from the last session. We do this
+ * in realize() instead of constructed() so the shell view has a
+ * chance to connect handlers to our signals. */
- /* Restore the selector state from the last session. */
+ shell_sidebar = E_SHELL_SIDEBAR (widget);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
selector = E_SOURCE_SELECTOR (priv->selector);
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector));
+
+ source_list = e_memo_shell_backend_get_source_list (
+ E_MEMO_SHELL_BACKEND (shell_backend));
g_signal_connect_swapped (
model, "row-changed",
G_CALLBACK (memo_shell_sidebar_row_changed_cb),
- object);
+ shell_sidebar);
+
+ g_signal_connect_swapped (
+ selector, "primary-selection-changed",
+ G_CALLBACK (memo_shell_sidebar_primary_selection_changed_cb),
+ shell_sidebar);
source = NULL;
uid = e_shell_settings_get_string (
@@ -434,14 +566,12 @@ memo_shell_sidebar_constructed (GObject *object)
/* Listen for subsequent changes to the selector. */
g_signal_connect_swapped (
- widget, "selection-changed",
+ selector, "selection-changed",
G_CALLBACK (memo_shell_sidebar_selection_changed_cb),
- object);
+ shell_sidebar);
- g_signal_connect_swapped (
- widget, "primary-selection-changed",
- G_CALLBACK (memo_shell_sidebar_primary_selection_changed_cb),
- object);
+ /* Chain up to parent's realize() method. */
+ GTK_WIDGET_CLASS (parent_class)->realize (widget);
}
static guint32
@@ -507,10 +637,10 @@ memo_shell_sidebar_client_removed (EMemoShellSidebar *memo_shell_sidebar,
NULL, NULL, memo_shell_sidebar);
source = e_cal_get_source (client);
- e_source_selector_unselect_source (selector, source);
-
uid = e_source_peek_uid (source);
+
g_hash_table_remove (client_table, uid);
+ e_source_selector_unselect_source (selector, source);
memo_shell_sidebar_emit_status_message (memo_shell_sidebar, NULL);
}
@@ -519,6 +649,7 @@ static void
memo_shell_sidebar_class_init (EMemoShellSidebarClass *class)
{
GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
EShellSidebarClass *shell_sidebar_class;
parent_class = g_type_class_peek_parent (class);
@@ -530,6 +661,9 @@ memo_shell_sidebar_class_init (EMemoShellSidebarClass *class)
object_class->finalize = memo_shell_sidebar_finalize;
object_class->constructed = memo_shell_sidebar_constructed;
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->realize = memo_shell_sidebar_realize;
+
shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class);
shell_sidebar_class->check_state = memo_shell_sidebar_check_state;
@@ -537,6 +671,16 @@ memo_shell_sidebar_class_init (EMemoShellSidebarClass *class)
g_object_class_install_property (
object_class,
+ PROP_DEFAULT_CLIENT,
+ g_param_spec_object (
+ "default-client",
+ _("Default Memo Client"),
+ _("Default client for memo operations"),
+ E_TYPE_CAL,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
PROP_SELECTOR,
g_param_spec_object (
"selector",
@@ -645,6 +789,15 @@ e_memo_shell_sidebar_get_clients (EMemoShellSidebar *memo_shell_sidebar)
return g_hash_table_get_values (client_table);
}
+ECal *
+e_memo_shell_sidebar_get_default_client (EMemoShellSidebar *memo_shell_sidebar)
+{
+ g_return_val_if_fail (
+ E_IS_MEMO_SHELL_SIDEBAR (memo_shell_sidebar), NULL);
+
+ return memo_shell_sidebar->priv->default_client;
+}
+
ESourceSelector *
e_memo_shell_sidebar_get_selector (EMemoShellSidebar *memo_shell_sidebar)
{
@@ -658,8 +811,10 @@ void
e_memo_shell_sidebar_add_source (EMemoShellSidebar *memo_shell_sidebar,
ESource *source)
{
+ ECalSourceType source_type;
ESourceSelector *selector;
GHashTable *client_table;
+ ECal *default_client;
ECal *client;
const gchar *uid;
const gchar *uri;
@@ -668,7 +823,9 @@ e_memo_shell_sidebar_add_source (EMemoShellSidebar *memo_shell_sidebar,
g_return_if_fail (E_IS_MEMO_SHELL_SIDEBAR (memo_shell_sidebar));
g_return_if_fail (E_IS_SOURCE (source));
+ source_type = E_CAL_SOURCE_TYPE_JOURNAL;
client_table = memo_shell_sidebar->priv->client_table;
+ default_client = memo_shell_sidebar->priv->default_client;
selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
uid = e_source_peek_uid (source);
@@ -677,7 +834,20 @@ e_memo_shell_sidebar_add_source (EMemoShellSidebar *memo_shell_sidebar,
if (client != NULL)
return;
- client = e_auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_JOURNAL);
+ if (default_client != NULL) {
+ ESource *default_source;
+ const gchar *default_uid;
+
+ default_source = e_cal_get_source (default_client);
+ default_uid = e_source_peek_uid (default_source);
+
+ if (g_strcmp0 (uid, default_uid) == 0)
+ client = g_object_ref (default_client);
+ }
+
+ if (client == NULL)
+ client = e_auth_new_cal_from_source (source, source_type);
+
g_return_if_fail (client != NULL);
g_signal_connect_swapped (
diff --git a/modules/calendar/e-memo-shell-sidebar.h b/modules/calendar/e-memo-shell-sidebar.h
index 8eabee103d..0d32c7b429 100644
--- a/modules/calendar/e-memo-shell-sidebar.h
+++ b/modules/calendar/e-memo-shell-sidebar.h
@@ -84,6 +84,8 @@ void e_memo_shell_sidebar_register_type
GtkWidget * e_memo_shell_sidebar_new(EShellView *shell_view);
GList * e_memo_shell_sidebar_get_clients
(EMemoShellSidebar *memo_shell_sidebar);
+ECal * e_memo_shell_sidebar_get_default_client
+ (EMemoShellSidebar *memo_shell_sidebar);
ESourceSelector *
e_memo_shell_sidebar_get_selector
(EMemoShellSidebar *memo_shell_sidebar);
diff --git a/modules/calendar/e-memo-shell-view-private.c b/modules/calendar/e-memo-shell-view-private.c
index 2caa6ec2ed..decd9002d0 100644
--- a/modules/calendar/e-memo-shell-view-private.c
+++ b/modules/calendar/e-memo-shell-view-private.c
@@ -38,8 +38,6 @@ memo_shell_view_model_row_appended_cb (EMemoShellView *memo_shell_view,
memo_shell_sidebar = memo_shell_view->priv->memo_shell_sidebar;
e_memo_shell_sidebar_add_source (memo_shell_sidebar, source);
-
- e_cal_model_add_client (model, client);
}
static void
@@ -273,6 +271,11 @@ e_memo_shell_view_private_constructed (EMemoShellView *memo_shell_view)
(GHookFunc) e_memo_shell_view_update_search_filter,
memo_shell_view);
+ /* Keep the ECalModel in sync with the sidebar. */
+ e_binding_new (
+ shell_sidebar, "default-client",
+ model, "default-client");
+
e_memo_shell_view_actions_init (memo_shell_view);
e_memo_shell_view_update_sidebar (memo_shell_view);
e_memo_shell_view_update_search_filter (memo_shell_view);
diff --git a/modules/calendar/e-task-shell-sidebar.c b/modules/calendar/e-task-shell-sidebar.c
index 7708f7234a..347c64b8b3 100644
--- a/modules/calendar/e-task-shell-sidebar.c
+++ b/modules/calendar/e-task-shell-sidebar.c
@@ -32,8 +32,8 @@
#include "calendar/gui/e-task-list-selector.h"
#include "calendar/gui/misc.h"
-#include "e-task-shell-backend.h"
#include "e-task-shell-view.h"
+#include "e-task-shell-backend.h"
#define E_TASK_SHELL_SIDEBAR_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -44,10 +44,20 @@ struct _ETaskShellSidebarPrivate {
/* UID -> Client */
GHashTable *client_table;
+
+ /* The default client is for ECalModel. It follows the
+ * sidebar's primary selection, even if the highlighted
+ * source is not selected. The tricky part is we don't
+ * update the property until the client is successfully
+ * opened. So the user first highlights a source, then
+ * sometime later we update our default-client property
+ * which is bound by an EBinding to ECalModel. */
+ ECal *default_client;
};
enum {
PROP_0,
+ PROP_DEFAULT_CLIENT,
PROP_SELECTOR
};
@@ -161,6 +171,7 @@ task_shell_sidebar_client_opened_cb (ETaskShellSidebar *task_shell_sidebar,
EShellView *shell_view;
EShellWindow *shell_window;
EShellSidebar *shell_sidebar;
+ const gchar *message;
shell_sidebar = E_SHELL_SIDEBAR (task_shell_sidebar);
shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
@@ -170,39 +181,121 @@ task_shell_sidebar_client_opened_cb (ETaskShellSidebar *task_shell_sidebar,
status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
e_auth_cal_forget_password (client);
+ /* Handle errors. */
switch (status) {
case E_CALENDAR_STATUS_OK:
- g_signal_handlers_disconnect_matched (
- client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
- task_shell_sidebar_client_opened_cb, NULL);
-
- task_shell_sidebar_emit_status_message (
- task_shell_sidebar, _("Loading tasks"));
- task_shell_sidebar_emit_client_added (
- task_shell_sidebar, client);
- task_shell_sidebar_emit_status_message (
- task_shell_sidebar, NULL);
break;
case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
e_cal_open_async (client, FALSE);
- break;
+ return;
case E_CALENDAR_STATUS_BUSY:
- break;
+ return;
case E_CALENDAR_STATUS_REPOSITORY_OFFLINE:
e_alert_run_dialog_for_args (
GTK_WINDOW (shell_window),
"calendar:prompt-no-contents-offline-tasks",
NULL);
- break;
+ /* fall through */
default:
- task_shell_sidebar_emit_client_removed (
- task_shell_sidebar, client);
+ e_task_shell_sidebar_remove_source (
+ task_shell_sidebar,
+ e_cal_get_source (client));
+ return;
+ }
+
+ g_assert (status == E_CALENDAR_STATUS_OK);
+
+ g_signal_handlers_disconnect_matched (
+ client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
+ task_shell_sidebar_client_opened_cb, NULL);
+
+ message = _("Loading tasks");
+ task_shell_sidebar_emit_status_message (task_shell_sidebar, message);
+ task_shell_sidebar_emit_client_added (task_shell_sidebar, client);
+ task_shell_sidebar_emit_status_message (task_shell_sidebar, NULL);
+}
+
+static void
+task_shell_sidebar_default_opened_cb (ETaskShellSidebar *task_shell_sidebar,
+ ECalendarStatus status,
+ ECal *client)
+{
+ EShellView *shell_view;
+ EShellWindow *shell_window;
+ EShellSidebar *shell_sidebar;
+
+ shell_sidebar = E_SHELL_SIDEBAR (task_shell_sidebar);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_window = e_shell_view_get_shell_window (shell_view);
+
+ if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED ||
+ status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
+ e_auth_cal_forget_password (client);
+
+ /* Handle errors. */
+ switch (status) {
+ case E_CALENDAR_STATUS_OK:
break;
+
+ case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
+ e_cal_open_async (client, FALSE);
+ return;
+
+ case E_CALENDAR_STATUS_BUSY:
+ return;
+
+ default:
+ e_task_shell_sidebar_remove_source (
+ task_shell_sidebar,
+ e_cal_get_source (client));
+ return;
}
+
+ g_assert (status == E_CALENDAR_STATUS_OK);
+
+ g_signal_handlers_disconnect_matched (
+ client, G_SIGNAL_MATCH_FUNC, 0, 0, NULL,
+ task_shell_sidebar_default_opened_cb, NULL);
+
+ g_object_notify (G_OBJECT (task_shell_sidebar), "default-client");
+}
+
+static void
+task_shell_sidebar_set_default (ETaskShellSidebar *task_shell_sidebar,
+ ESource *source)
+{
+ ECalSourceType source_type;
+ GHashTable *client_table;
+ ECal *client;
+ const gchar *uid;
+
+ source_type = E_CAL_SOURCE_TYPE_TODO;
+ client_table = task_shell_sidebar->priv->client_table;
+
+ uid = e_source_peek_uid (source);
+ client = g_hash_table_lookup (client_table, uid);
+
+ if (task_shell_sidebar->priv->default_client != NULL)
+ g_object_unref (task_shell_sidebar->priv->default_client);
+
+ if (client != NULL)
+ g_object_ref (client);
+ else
+ client = e_auth_new_cal_from_source (source, source_type);
+
+ task_shell_sidebar->priv->default_client = client;
+ g_return_if_fail (client != NULL);
+
+ g_signal_connect_swapped (
+ client, "cal-opened",
+ G_CALLBACK (task_shell_sidebar_default_opened_cb),
+ task_shell_sidebar);
+
+ e_cal_open_async (client, FALSE);
}
static void
@@ -290,6 +383,8 @@ task_shell_sidebar_primary_selection_changed_cb (ETaskShellSidebar *task_shell_s
e_shell_settings_set_string (
shell_settings, "cal-primary-task-list",
e_source_peek_uid (source));
+
+ task_shell_sidebar_set_default (task_shell_sidebar, source);
}
static void
@@ -299,9 +394,17 @@ task_shell_sidebar_get_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
+ case PROP_DEFAULT_CLIENT:
+ g_value_set_object (
+ value,
+ e_task_shell_sidebar_get_default_client (
+ E_TASK_SHELL_SIDEBAR (object)));
+ return;
+
case PROP_SELECTOR:
g_value_set_object (
- value, e_task_shell_sidebar_get_selector (
+ value,
+ e_task_shell_sidebar_get_selector (
E_TASK_SHELL_SIDEBAR (object)));
return;
}
@@ -321,6 +424,11 @@ task_shell_sidebar_dispose (GObject *object)
priv->selector = NULL;
}
+ if (priv->default_client != NULL) {
+ g_object_unref (priv->default_client);
+ priv->default_client = NULL;
+ }
+
g_hash_table_remove_all (priv->client_table);
/* Chain up to parent's dispose() method. */
@@ -344,20 +452,13 @@ static void
task_shell_sidebar_constructed (GObject *object)
{
ETaskShellSidebarPrivate *priv;
- EShell *shell;
EShellView *shell_view;
EShellBackend *shell_backend;
EShellSidebar *shell_sidebar;
- EShellSettings *shell_settings;
- ESourceSelector *selector;
ESourceList *source_list;
- ESource *source;
GtkContainer *container;
- GtkTreeModel *model;
GtkWidget *widget;
AtkObject *a11y;
- GSList *list, *iter;
- gchar *uid;
priv = E_TASK_SHELL_SIDEBAR_GET_PRIVATE (object);
@@ -368,9 +469,6 @@ task_shell_sidebar_constructed (GObject *object)
shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
shell_backend = e_shell_view_get_shell_backend (shell_view);
- shell = e_shell_backend_get_shell (shell_backend);
- shell_settings = e_shell_get_shell_settings (shell);
-
source_list = e_task_shell_backend_get_source_list (
E_TASK_SHELL_BACKEND (shell_backend));
@@ -394,16 +492,52 @@ task_shell_sidebar_constructed (GObject *object)
atk_object_set_name (a11y, _("Task List Selector"));
priv->selector = g_object_ref (widget);
gtk_widget_show (widget);
+}
+
+static void
+task_shell_sidebar_realize (GtkWidget *widget)
+{
+ ETaskShellSidebarPrivate *priv;
+ EShell *shell;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ EShellSidebar *shell_sidebar;
+ EShellSettings *shell_settings;
+ ESourceSelector *selector;
+ ESourceList *source_list;
+ ESource *source;
+ GtkTreeModel *model;
+ GSList *list, *iter;
+ gchar *uid;
- /* Restore the selector state from the last session. */
+ priv = E_TASK_SHELL_SIDEBAR_GET_PRIVATE (widget);
+
+ /* Restore the selector state from the last session. We do this
+ * in realize() instead of constructed() so the shell view has a
+ * chance to connect handlers to our signals. */
+
+ shell_sidebar = E_SHELL_SIDEBAR (widget);
+ shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ shell = e_shell_backend_get_shell (shell_backend);
+ shell_settings = e_shell_get_shell_settings (shell);
selector = E_SOURCE_SELECTOR (priv->selector);
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (selector));
+
+ source_list = e_task_shell_backend_get_source_list (
+ E_TASK_SHELL_BACKEND (shell_backend));
g_signal_connect_swapped (
model, "row-changed",
G_CALLBACK (task_shell_sidebar_row_changed_cb),
- object);
+ shell_sidebar);
+
+ g_signal_connect_swapped (
+ selector, "primary-selection-changed",
+ G_CALLBACK (task_shell_sidebar_primary_selection_changed_cb),
+ shell_sidebar);
source = NULL;
uid = e_shell_settings_get_string (
@@ -432,14 +566,12 @@ task_shell_sidebar_constructed (GObject *object)
/* Listen for subsequent changes to the selector. */
g_signal_connect_swapped (
- widget, "selection-changed",
+ selector, "selection-changed",
G_CALLBACK (task_shell_sidebar_selection_changed_cb),
- object);
+ shell_sidebar);
- g_signal_connect_swapped (
- widget, "primary-selection-changed",
- G_CALLBACK (task_shell_sidebar_primary_selection_changed_cb),
- object);
+ /* Chain up to parent's realize() method. */
+ GTK_WIDGET_CLASS (parent_class)->realize (widget);
}
static guint32
@@ -505,10 +637,10 @@ task_shell_sidebar_client_removed (ETaskShellSidebar *task_shell_sidebar,
NULL, NULL, task_shell_sidebar);
source = e_cal_get_source (client);
- e_source_selector_unselect_source (selector, source);
-
uid = e_source_peek_uid (source);
+
g_hash_table_remove (client_table, uid);
+ e_source_selector_unselect_source (selector, source);
task_shell_sidebar_emit_status_message (task_shell_sidebar, NULL);
}
@@ -517,6 +649,7 @@ static void
task_shell_sidebar_class_init (ETaskShellSidebarClass *class)
{
GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
EShellSidebarClass *shell_sidebar_class;
parent_class = g_type_class_peek_parent (class);
@@ -528,6 +661,9 @@ task_shell_sidebar_class_init (ETaskShellSidebarClass *class)
object_class->finalize = task_shell_sidebar_finalize;
object_class->constructed = task_shell_sidebar_constructed;
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->realize = task_shell_sidebar_realize;
+
shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class);
shell_sidebar_class->check_state = task_shell_sidebar_check_state;
@@ -535,6 +671,16 @@ task_shell_sidebar_class_init (ETaskShellSidebarClass *class)
g_object_class_install_property (
object_class,
+ PROP_DEFAULT_CLIENT,
+ g_param_spec_object (
+ "default-client",
+ _("Default Task Client"),
+ _("Default client for task operations"),
+ E_TYPE_CAL,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
PROP_SELECTOR,
g_param_spec_object (
"selector",
@@ -643,6 +789,15 @@ e_task_shell_sidebar_get_clients (ETaskShellSidebar *task_shell_sidebar)
return g_hash_table_get_values (client_table);
}
+ECal *
+e_task_shell_sidebar_get_default_client (ETaskShellSidebar *task_shell_sidebar)
+{
+ g_return_val_if_fail (
+ E_IS_TASK_SHELL_SIDEBAR (task_shell_sidebar), NULL);
+
+ return task_shell_sidebar->priv->default_client;
+}
+
ESourceSelector *
e_task_shell_sidebar_get_selector (ETaskShellSidebar *task_shell_sidebar)
{
@@ -656,8 +811,10 @@ void
e_task_shell_sidebar_add_source (ETaskShellSidebar *task_shell_sidebar,
ESource *source)
{
+ ECalSourceType source_type;
ESourceSelector *selector;
GHashTable *client_table;
+ ECal *default_client;
ECal *client;
const gchar *uid;
const gchar *uri;
@@ -666,7 +823,9 @@ e_task_shell_sidebar_add_source (ETaskShellSidebar *task_shell_sidebar,
g_return_if_fail (E_IS_TASK_SHELL_SIDEBAR (task_shell_sidebar));
g_return_if_fail (E_IS_SOURCE (source));
+ source_type = E_CAL_SOURCE_TYPE_TODO;
client_table = task_shell_sidebar->priv->client_table;
+ default_client = task_shell_sidebar->priv->default_client;
selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
uid = e_source_peek_uid (source);
@@ -675,7 +834,20 @@ e_task_shell_sidebar_add_source (ETaskShellSidebar *task_shell_sidebar,
if (client != NULL)
return;
- client = e_auth_new_cal_from_source (source, E_CAL_SOURCE_TYPE_TODO);
+ if (default_client != NULL) {
+ ESource *default_source;
+ const gchar *default_uid;
+
+ default_source = e_cal_get_source (default_client);
+ default_uid = e_source_peek_uid (default_source);
+
+ if (g_strcmp0 (uid, default_uid) == 0)
+ client = g_object_ref (default_client);
+ }
+
+ if (client == NULL)
+ client = e_auth_new_cal_from_source (source, source_type);
+
g_return_if_fail (client != NULL);
g_signal_connect_swapped (
diff --git a/modules/calendar/e-task-shell-sidebar.h b/modules/calendar/e-task-shell-sidebar.h
index 6a18279753..152c7ca32f 100644
--- a/modules/calendar/e-task-shell-sidebar.h
+++ b/modules/calendar/e-task-shell-sidebar.h
@@ -84,6 +84,8 @@ void e_task_shell_sidebar_register_type
GtkWidget * e_task_shell_sidebar_new(EShellView *shell_view);
GList * e_task_shell_sidebar_get_clients
(ETaskShellSidebar *task_shell_sidebar);
+ECal * e_task_shell_sidebar_get_default_client
+ (ETaskShellSidebar *task_shell_sidebar);
ESourceSelector *
e_task_shell_sidebar_get_selector
(ETaskShellSidebar *task_shell_sidebar);
diff --git a/modules/calendar/e-task-shell-view-private.c b/modules/calendar/e-task-shell-view-private.c
index 1cdf6697ff..ada67c7c08 100644
--- a/modules/calendar/e-task-shell-view-private.c
+++ b/modules/calendar/e-task-shell-view-private.c
@@ -38,8 +38,6 @@ task_shell_view_model_row_appended_cb (ETaskShellView *task_shell_view,
task_shell_sidebar = task_shell_view->priv->task_shell_sidebar;
e_task_shell_sidebar_add_source (task_shell_sidebar, source);
-
- e_cal_model_add_client (model, client);
}
static void
@@ -326,11 +324,15 @@ e_task_shell_view_private_constructed (ETaskShellView *task_shell_view)
task_shell_view);
/* Listen for configuration changes. */
-
e_mutual_binding_new (
shell_settings, "cal-confirm-purge",
task_shell_view, "confirm-purge");
+ /* Keep the ECalModel in sync with the sidebar. */
+ e_binding_new (
+ shell_sidebar, "default-client",
+ model, "default-client");
+
/* Hide Completed Tasks (enable/units/value) */
g_signal_connect_swapped (
shell_settings, "notify::cal-hide-completed-tasks",