aboutsummaryrefslogtreecommitdiffstats
path: root/modules/calendar/e-memo-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-memo-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-memo-shell-sidebar.c')
-rw-r--r--modules/calendar/e-memo-shell-sidebar.c250
1 files changed, 210 insertions, 40 deletions
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 (