aboutsummaryrefslogtreecommitdiffstats
path: root/modules/calendar/e-cal-shell-sidebar.c
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 /modules/calendar/e-cal-shell-sidebar.c
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.
Diffstat (limited to 'modules/calendar/e-cal-shell-sidebar.c')
-rw-r--r--modules/calendar/e-cal-shell-sidebar.c251
1 files changed, 215 insertions, 36 deletions
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 (