diff options
Diffstat (limited to 'modules/calendar/e-memo-shell-sidebar.c')
-rw-r--r-- | modules/calendar/e-memo-shell-sidebar.c | 250 |
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 ( |