[evolution-ews] I#6 - Add 'Subscribe to folder of other EWS user' into File menu
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews] I#6 - Add 'Subscribe to folder of other EWS user' into File menu
- Date: Mon, 2 Jul 2018 12:32:55 +0000 (UTC)
commit f26fb7da86aa05e58b4a923e35afdb82f410ac25
Author: Milan Crha <mcrha redhat com>
Date: Mon Jul 2 14:31:42 2018 +0200
I#6 - Add 'Subscribe to folder of other EWS user' into File menu
Closes https://gitlab.gnome.org/GNOME/evolution-ews/issues/6
src/configuration/e-ews-config-utils.c | 162 +++++++++++++++++++--
src/configuration/e-ews-subscribe-foreign-folder.c | 158 ++++++++++++++++----
2 files changed, 284 insertions(+), 36 deletions(-)
---
diff --git a/src/configuration/e-ews-config-utils.c b/src/configuration/e-ews-config-utils.c
index 5a2a5dfc..467097a2 100644
--- a/src/configuration/e-ews-config-utils.c
+++ b/src/configuration/e-ews-config-utils.c
@@ -799,6 +799,97 @@ e_ews_config_utils_run_folder_sizes_dialog (GtkWindow *parent,
gtk_widget_show (GTK_WIDGET (dialog));
}
+static void
+action_global_subscribe_foreign_folder_cb (GtkAction *action,
+ EShellView *shell_view)
+{
+ EShell *shell;
+ EShellBackend *shell_backend;
+ EShellWindow *shell_window;
+ EClientCache *client_cache;
+ CamelSession *session = NULL;
+
+ g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
+
+ shell_window = e_shell_view_get_shell_window (shell_view);
+ shell = e_shell_window_get_shell (shell_window);
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+
+ if (shell_backend)
+ g_object_get (G_OBJECT (shell_backend), "session", &session, NULL);
+
+ if (!session)
+ return;
+
+ client_cache = e_shell_get_client_cache (shell);
+
+ e_ews_subscribe_foreign_folder (GTK_WINDOW (shell_window), session, NULL, client_cache);
+
+ g_object_unref (session);
+}
+
+static GtkActionEntry global_ews_entries[] = {
+ { "ews-global-subscribe-foreign-folder",
+ NULL,
+ N_("Subscribe to folder of other EWS user…"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_global_subscribe_foreign_folder_cb) }
+};
+
+static gboolean
+ews_ui_has_ews_account (EShellView *shell_view,
+ CamelSession *in_session)
+{
+ CamelSession *session = in_session;
+ EShell *shell;
+ gboolean has_any = FALSE;
+
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), FALSE);
+ if (in_session)
+ g_return_val_if_fail (CAMEL_IS_SESSION (in_session), FALSE);
+
+ shell = e_shell_window_get_shell (e_shell_view_get_shell_window (shell_view));
+
+ if (!session) {
+ EShellBackend *shell_backend;
+
+ shell_backend = e_shell_get_backend_by_name (shell, "mail");
+
+ if (shell_backend) {
+ g_object_get (G_OBJECT (shell_backend), "session", &session, NULL);
+ }
+ }
+
+ if (session) {
+ ESourceRegistry *registry;
+ GList *services, *link;
+
+ registry = e_shell_get_registry (shell);
+ services = camel_session_list_services (session);
+
+ for (link = services; link && !has_any; link = g_list_next (link)) {
+ CamelService *service = link->data;
+
+ if (CAMEL_IS_EWS_STORE (service)) {
+ ESource *source;
+
+ source = e_source_registry_ref_source (registry, camel_service_get_uid
(service));
+ has_any = source && e_source_registry_check_enabled (registry, source);
+
+ g_clear_object (&source);
+ }
+ }
+
+ g_list_free_full (services, g_object_unref);
+ }
+
+ if (session && session != in_session)
+ g_object_unref (session);
+
+ return has_any;
+}
+
static gboolean
get_ews_store_from_folder_tree (EShellView *shell_view,
gchar **pfolder_path,
@@ -1021,6 +1112,13 @@ static GtkActionEntry mail_folder_context_entries[] = {
};
static const gchar *ews_ui_mail_def =
+ "<menubar name='main-menu'>\n"
+ " <menu action='file-menu'>\n"
+ " <placeholder name='long-running-actions'>\n"
+ " <menuitem action=\"ews-global-subscribe-foreign-folder\"/>\n"
+ " </placeholder>\n"
+ " </menu>\n"
+ "</menubar>\n"
"<popup name=\"mail-folder-popup\">\n"
" <placeholder name=\"mail-folder-popup-actions\">\n"
" <menuitem action=\"mail-ews-folder-sizes\"/>\n"
@@ -1034,6 +1132,8 @@ ews_ui_update_actions_mail_cb (EShellView *shell_view,
GtkActionEntry *entries)
{
EShellWindow *shell_window;
+ EShellBackend *backend;
+ CamelSession *session = NULL;
GtkActionGroup *action_group;
GtkUIManager *ui_manager;
EShellSidebar *shell_sidebar;
@@ -1041,7 +1141,7 @@ ews_ui_update_actions_mail_cb (EShellView *shell_view,
CamelStore *selected_store = NULL;
gchar *selected_path = NULL;
gboolean account_node = FALSE, folder_node = FALSE;
- gboolean online = FALSE;
+ gboolean online, has_ews_account;
shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
@@ -1066,21 +1166,19 @@ ews_ui_update_actions_mail_cb (EShellView *shell_view,
ui_manager = e_shell_window_get_ui_manager (shell_window);
action_group = e_lookup_action_group (ui_manager, "mail");
- if (account_node || folder_node) {
- EShellBackend *backend;
- CamelSession *session = NULL;
+ backend = e_shell_view_get_shell_backend (shell_view);
+ g_object_get (G_OBJECT (backend), "session", &session, NULL);
- backend = e_shell_view_get_shell_backend (shell_view);
- g_object_get (G_OBJECT (backend), "session", &session, NULL);
+ online = session && camel_session_get_online (session);
- online = session && camel_session_get_online (session);
+ has_ews_account = account_node || folder_node || ews_ui_has_ews_account (shell_view, session);
- if (session)
- g_object_unref (session);
- }
+ if (session)
+ g_object_unref (session);
ews_ui_enable_actions (action_group, mail_account_context_entries, G_N_ELEMENTS
(mail_account_context_entries), account_node, online);
ews_ui_enable_actions (action_group, mail_folder_context_entries, G_N_ELEMENTS
(mail_folder_context_entries), folder_node, online);
+ ews_ui_enable_actions (action_group, global_ews_entries, G_N_ELEMENTS (global_ews_entries),
has_ews_account, online);
}
static void
@@ -1106,6 +1204,11 @@ ews_ui_init_mail (GtkUIManager *ui_manager,
action_group, GETTEXT_PACKAGE,
mail_folder_context_entries, G_N_ELEMENTS (mail_folder_context_entries), shell_view);
+ /* Add global actions */
+ e_action_group_add_actions_localized (
+ action_group, GETTEXT_PACKAGE,
+ global_ews_entries, G_N_ELEMENTS (global_ews_entries), shell_view);
+
/* Decide whether we want this option to be visible or not */
g_signal_connect (
shell_view, "update-actions",
@@ -1234,6 +1337,8 @@ update_ews_source_entries_cb (EShellView *shell_view,
action_group = e_shell_window_get_action_group (shell_window, group);
ews_ui_enable_actions (action_group, entries, EWS_ESOURCE_NUM_ENTRIES, is_ews_source, is_online);
+ ews_ui_enable_actions (action_group, global_ews_entries, G_N_ELEMENTS (global_ews_entries),
+ ews_ui_has_ews_account (shell_view, NULL), is_online);
}
static void
@@ -1243,6 +1348,7 @@ setup_ews_source_actions (EShellView *shell_view,
guint n_entries)
{
EShellWindow *shell_window;
+ GtkActionGroup *action_group;
const gchar *group;
g_return_if_fail (shell_view != NULL);
@@ -1263,11 +1369,17 @@ setup_ews_source_actions (EShellView *shell_view,
g_return_if_reached ();
shell_window = e_shell_view_get_shell_window (shell_view);
+ action_group = e_shell_window_get_action_group (shell_window, group);
e_action_group_add_actions_localized (
- e_shell_window_get_action_group (shell_window, group), GETTEXT_PACKAGE,
+ action_group, GETTEXT_PACKAGE,
entries, EWS_ESOURCE_NUM_ENTRIES, shell_view);
+ /* Add global actions */
+ e_action_group_add_actions_localized (
+ action_group, GETTEXT_PACKAGE,
+ global_ews_entries, G_N_ELEMENTS (global_ews_entries), shell_view);
+
g_signal_connect (shell_view, "update-actions", G_CALLBACK (update_ews_source_entries_cb), entries);
}
@@ -1336,6 +1448,13 @@ static GtkActionEntry calendar_context_entries[] = {
};
static const gchar *ews_ui_cal_def =
+ "<menubar name='main-menu'>\n"
+ " <menu action='file-menu'>\n"
+ " <placeholder name='long-running-actions'>\n"
+ " <menuitem action=\"ews-global-subscribe-foreign-folder\"/>\n"
+ " </placeholder>\n"
+ " </menu>\n"
+ "</menubar>\n"
"<popup name=\"calendar-popup\">\n"
" <placeholder name=\"calendar-popup-actions\">\n"
" <menuitem action=\"calendar-ews-folder-permissions\"/>\n"
@@ -1367,6 +1486,13 @@ static GtkActionEntry tasks_context_entries[] = {
};
static const gchar *ews_ui_task_def =
+ "<menubar name='main-menu'>\n"
+ " <menu action='file-menu'>\n"
+ " <placeholder name='long-running-actions'>\n"
+ " <menuitem action=\"ews-global-subscribe-foreign-folder\"/>\n"
+ " </placeholder>\n"
+ " </menu>\n"
+ "</menubar>\n"
"<popup name=\"task-list-popup\">\n"
" <placeholder name=\"task-list-popup-actions\">\n"
" <menuitem action=\"tasks-ews-folder-permissions\"/>\n"
@@ -1398,6 +1524,13 @@ static GtkActionEntry memos_context_entries[] = {
};
static const gchar *ews_ui_memo_def =
+ "<menubar name='main-menu'>\n"
+ " <menu action='file-menu'>\n"
+ " <placeholder name='long-running-actions'>\n"
+ " <menuitem action=\"ews-global-subscribe-foreign-folder\"/>\n"
+ " </placeholder>\n"
+ " </menu>\n"
+ "</menubar>\n"
"<popup name=\"memo-list-popup\">\n"
" <placeholder name=\"memo-list-popup-actions\">\n"
" <menuitem action=\"memos-ews-folder-permissions\"/>\n"
@@ -1429,6 +1562,13 @@ static GtkActionEntry contacts_context_entries[] = {
};
static const gchar *ews_ui_book_def =
+ "<menubar name='main-menu'>\n"
+ " <menu action='file-menu'>\n"
+ " <placeholder name='long-running-actions'>\n"
+ " <menuitem action=\"ews-global-subscribe-foreign-folder\"/>\n"
+ " </placeholder>\n"
+ " </menu>\n"
+ "</menubar>\n"
"<popup name=\"address-book-popup\">\n"
" <placeholder name=\"address-book-popup-actions\">\n"
" <menuitem action=\"contacts-ews-folder-permissions\"/>\n"
diff --git a/src/configuration/e-ews-subscribe-foreign-folder.c
b/src/configuration/e-ews-subscribe-foreign-folder.c
index 76c5d4a5..98d74405 100644
--- a/src/configuration/e-ews-subscribe-foreign-folder.c
+++ b/src/configuration/e-ews-subscribe-foreign-folder.c
@@ -38,13 +38,19 @@
#include "e-ews-search-user.h"
#include "e-ews-subscribe-foreign-folder.h"
+#define STR_ACCOUNTS_COMBO "e-ews-accounts-combo"
#define STR_USER_NAME_SELECTOR_ENTRY "e-ews-name-selector-entry"
#define STR_FOLDER_NAME_COMBO "e-ews-folder-name-combo"
#define STR_SUBFOLDERS_CHECK "e-ews-subfolders-check"
#define STR_EWS_CAMEL_SESSION "e-ews-camel-session"
-#define STR_EWS_CAMEL_STORE "e-ews-camel-store"
#define STR_EWS_DIRECT_EMAIL "e-ews-direct-email"
+enum {
+ COLUMN_UID = 0,
+ COLUMN_DISPLAY_NAME,
+ COLUMN_STORE
+};
+
static void
announce_new_folder (CamelEwsStore *ews_store,
const gchar *fid)
@@ -272,7 +278,7 @@ check_foreign_folder_thread (GObject *with_object,
if (!conn) {
g_set_error_literal (
perror, EWS_CONNECTION_ERROR, EWS_CONNECTION_ERROR_NORESPONSE,
- _("Cannot test foreign folder availability while in offline mode"));
+ _("Cannot test foreign folder availability when the account is offline"));
return;
}
@@ -289,9 +295,17 @@ check_foreign_folder_thread (GObject *with_object,
if (!e_ews_connection_resolve_names_sync (conn, G_PRIORITY_DEFAULT,
cffd->email, EWS_SEARCH_AD, NULL, FALSE,
&mailboxes, NULL, &includes_last_item,
- cancellable, perror)) {
- g_object_unref (conn);
- return;
+ cancellable, &local_error)) {
+ if (g_error_matches (local_error, EWS_CONNECTION_ERROR,
EWS_CONNECTION_ERROR_NAMERESOLUTIONNORESULTS) ||
+ g_error_matches (local_error, EWS_CONNECTION_ERROR,
EWS_CONNECTION_ERROR_NAMERESOLUTIONNOMAILBOX)) {
+ g_clear_error (&local_error);
+ mailboxes = NULL;
+ } else {
+ if (local_error)
+ g_propagate_error (perror, local_error);
+ g_object_unref (conn);
+ return;
+ }
}
if (!mailboxes) {
@@ -490,6 +504,24 @@ check_foreign_folder_idle (GObject *with_object,
g_object_unref (settings);
}
+static gpointer
+ref_selected_store (GObject *dialog)
+{
+ GtkComboBox *combo_box;
+ CamelStore *store = NULL;
+ GtkTreeIter iter;
+
+ combo_box = g_object_get_data (dialog, STR_ACCOUNTS_COMBO);
+ g_return_val_if_fail (combo_box != NULL, NULL);
+
+ if (gtk_combo_box_get_active_iter (combo_box, &iter)) {
+ gtk_tree_model_get (gtk_combo_box_get_model (combo_box), &iter,
+ COLUMN_STORE, &store, -1);
+ }
+
+ return store;
+}
+
static void
subscribe_foreign_response_cb (GObject *dialog,
gint response_id)
@@ -514,9 +546,10 @@ subscribe_foreign_response_cb (GObject *dialog,
entry = g_object_get_data (dialog, STR_USER_NAME_SELECTOR_ENTRY);
combo_text = g_object_get_data (dialog, STR_FOLDER_NAME_COMBO);
subfolders_check = g_object_get_data (dialog, STR_SUBFOLDERS_CHECK);
- cstore = g_object_get_data (dialog, STR_EWS_CAMEL_STORE);
g_return_if_fail (entry != NULL);
+
+ cstore = ref_selected_store (dialog);
g_return_if_fail (cstore != NULL);
username = NULL;
@@ -587,6 +620,7 @@ subscribe_foreign_response_cb (GObject *dialog,
g_free (description);
g_free (show_foldername);
+ g_object_unref (cstore);
}
static void
@@ -601,19 +635,18 @@ pick_gal_user_clicked_cb (GtkButton *button,
g_return_if_fail (dialog != NULL);
entry = g_object_get_data (dialog, STR_USER_NAME_SELECTOR_ENTRY);
- ews_store = g_object_get_data (dialog, STR_EWS_CAMEL_STORE);
g_return_if_fail (entry != NULL);
+
+ ews_store = ref_selected_store (dialog);
g_return_if_fail (ews_store != NULL);
text = g_strstrip (g_strdup (gtk_entry_get_text (entry)));
conn = camel_ews_store_ref_connection (ews_store);
- if (e_ews_search_user_modal (GTK_WINDOW (dialog),
- conn,
- text,
- &display_name,
- &email)) {
+ if (!conn) {
+ e_notice (dialog, GTK_MESSAGE_ERROR, "%s", _("Cannot search for user when the account is
offline"));
+ } else if (e_ews_search_user_modal (GTK_WINDOW (dialog), conn, text, &display_name, &email)) {
if (display_name && email && *email) {
gtk_entry_set_text (entry, display_name);
g_object_set_data_full (G_OBJECT (entry), STR_EWS_DIRECT_EMAIL, g_strdup (email),
g_free);
@@ -623,7 +656,86 @@ pick_gal_user_clicked_cb (GtkButton *button,
g_free (text);
g_free (display_name);
g_free (email);
- g_object_unref (conn);
+ g_object_unref (ews_store);
+ g_clear_object (&conn);
+}
+
+static gint
+sort_accounts_by_display_name_cb (gconstpointer ptr1,
+ gconstpointer ptr2)
+{
+ CamelService *service1 = (CamelService *) ptr1;
+ CamelService *service2 = (CamelService *) ptr2;
+
+ return g_utf8_collate (camel_service_get_display_name (service1), camel_service_get_display_name
(service2));
+}
+
+static GtkWidget *
+create_accounts_combo (CamelSession *session,
+ EClientCache *client_cache,
+ CamelStore *store)
+{
+ GtkListStore *list_store;
+ GtkTreeIter iter;
+ GtkComboBox *combo_box;
+ ESourceRegistry *registry;
+ GList *services, *link, *accounts = NULL;
+ GtkCellRenderer *renderer;
+
+ list_store = gtk_list_store_new (3,
+ G_TYPE_STRING, /* COLUMN_UID - UID of the CamelEwsStore */
+ G_TYPE_STRING, /* COLUMN_DISPLAY_NAME */
+ CAMEL_TYPE_EWS_STORE); /* COLUMN_STORE */
+
+ registry = e_client_cache_ref_registry (client_cache);
+ services = camel_session_list_services (session);
+
+ for (link = services; link; link = g_list_next (link)) {
+ CamelService *service = link->data;
+
+ if (CAMEL_IS_EWS_STORE (service)) {
+ ESource *source;
+
+ source = e_source_registry_ref_source (registry, camel_service_get_uid (service));
+ if (source && e_source_registry_check_enabled (registry, source)) {
+ accounts = g_list_prepend (accounts, service);
+ }
+
+ g_clear_object (&source);
+ }
+ }
+
+ accounts = g_list_sort (accounts, sort_accounts_by_display_name_cb);
+
+ for (link = accounts; link; link = g_list_next (link)) {
+ CamelService *service = link->data;
+
+ gtk_list_store_append (list_store, &iter);
+ gtk_list_store_set (list_store, &iter,
+ COLUMN_UID, camel_service_get_uid (service),
+ COLUMN_DISPLAY_NAME, camel_service_get_display_name (service),
+ COLUMN_STORE, service,
+ -1);
+ }
+
+ g_list_free_full (services, g_object_unref);
+ g_list_free (accounts);
+ g_clear_object (®istry);
+
+ combo_box = GTK_COMBO_BOX (gtk_combo_box_new_with_model (GTK_TREE_MODEL (list_store)));
+ g_object_unref (list_store);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer, "text", COLUMN_DISPLAY_NAME,
NULL);
+
+ gtk_combo_box_set_id_column (combo_box, COLUMN_UID);
+ if (store)
+ gtk_combo_box_set_active_id (combo_box, camel_service_get_uid (CAMEL_SERVICE (store)));
+ else if (accounts)
+ gtk_combo_box_set_active (combo_box, 0);
+
+ return GTK_WIDGET (combo_box);
}
/* Opens dialog to subscribe to folders of other
@@ -634,20 +746,20 @@ e_ews_subscribe_foreign_folder (GtkWindow *parent,
CamelStore *store,
EClientCache *client_cache)
{
- PangoAttrList *attrs;
ENameSelector *name_selector;
ENameSelectorModel *name_selector_model;
ENameSelectorDialog *name_selector_dialog;
GObject *dialog;
GtkWidget *content;
- GtkWidget *label, *widget, *entry, *check;
+ GtkWidget *label, *widget, *entry, *check, *accounts_combo;
GtkGrid *grid;
GtkComboBoxText *combo_text;
gint row;
g_return_if_fail (session != NULL);
- g_return_if_fail (store != NULL);
- g_return_if_fail (CAMEL_IS_EWS_STORE (store));
+ if (store)
+ g_return_if_fail (CAMEL_IS_EWS_STORE (store));
+ g_return_if_fail (E_IS_CLIENT_CACHE (client_cache));
dialog = G_OBJECT (gtk_dialog_new_with_buttons (
_("Subscribe to folder of other EWS user..."),
@@ -680,19 +792,14 @@ e_ews_subscribe_foreign_folder (GtkWindow *parent,
"halign", GTK_ALIGN_START,
NULL);
- attrs = pango_attr_list_new ();
- pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
- widget = gtk_label_new (camel_service_get_display_name (CAMEL_SERVICE (store)));
+ widget = create_accounts_combo (session, client_cache, store);
g_object_set (
G_OBJECT (widget),
"hexpand", TRUE,
"vexpand", FALSE,
- "use-underline", FALSE,
- "attributes", attrs,
- "xalign", 0.0,
"halign", GTK_ALIGN_START,
NULL);
- pango_attr_list_unref (attrs);
+ accounts_combo = widget;
gtk_grid_attach (grid, label, 0, row, 1, 1);
gtk_grid_attach (grid, widget, 1, row, 2, 1);
@@ -774,15 +881,16 @@ e_ews_subscribe_foreign_folder (GtkWindow *parent,
gtk_grid_attach (grid, check, 1, row, 2, 1);
/* remember widgets for later use */
+ g_object_set_data (dialog, STR_ACCOUNTS_COMBO, accounts_combo);
g_object_set_data (dialog, STR_USER_NAME_SELECTOR_ENTRY, entry);
g_object_set_data (dialog, STR_FOLDER_NAME_COMBO, widget);
g_object_set_data (dialog, STR_SUBFOLDERS_CHECK, check);
g_object_set_data_full (dialog, STR_EWS_CAMEL_SESSION, g_object_ref (session), g_object_unref);
- g_object_set_data_full (dialog, STR_EWS_CAMEL_STORE, g_object_ref (store), g_object_unref);
g_signal_connect_swapped (entry, "changed", G_CALLBACK (name_entry_changed_cb), dialog);
g_signal_connect_swapped (combo_text, "changed", G_CALLBACK (folder_name_combo_changed_cb), dialog);
+ g_signal_connect_swapped (accounts_combo, "changed", G_CALLBACK (name_entry_changed_cb), dialog);
name_entry_changed_cb (dialog);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]