[evolution-mapi] Add 'Subscribe to folder of other MAPI user' into File menu
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-mapi] Add 'Subscribe to folder of other MAPI user' into File menu
- Date: Mon, 2 Jul 2018 12:43:04 +0000 (UTC)
commit 32533fb5ecbf735059b654fcd30f818a37dce9c5
Author: Milan Crha <mcrha redhat com>
Date: Mon Jul 2 14:41:22 2018 +0200
Add 'Subscribe to folder of other MAPI user' into File menu
Related to https://gitlab.gnome.org/GNOME/evolution-ews/issues/6
src/configuration/e-mapi-config-utils.c | 162 +++++++++++++++++--
.../e-mapi-subscribe-foreign-folder.c | 177 ++++++++++++++++++---
2 files changed, 306 insertions(+), 33 deletions(-)
---
diff --git a/src/configuration/e-mapi-config-utils.c b/src/configuration/e-mapi-config-utils.c
index 37d390d..4c7d14f 100644
--- a/src/configuration/e-mapi-config-utils.c
+++ b/src/configuration/e-mapi-config-utils.c
@@ -577,6 +577,97 @@ e_mapi_config_utils_run_folder_size_dialog (ESourceRegistry *registry,
gtk_widget_destroy (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_mapi_subscribe_foreign_folder (GTK_WINDOW (shell_window), session, NULL, client_cache);
+
+ g_object_unref (session);
+}
+
+static GtkActionEntry global_mapi_entries[] = {
+ { "mapi-global-subscribe-foreign-folder",
+ NULL,
+ N_("Subscribe to folder of other MAPI user…"),
+ NULL,
+ NULL, /* XXX Add a tooltip! */
+ G_CALLBACK (action_global_subscribe_foreign_folder_cb) }
+};
+
+static gboolean
+mapi_ui_has_mapi_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_MAPI_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 gchar *
get_profile_name_from_folder_tree (EShellView *shell_view,
gchar **pfolder_path,
@@ -802,6 +893,13 @@ static GtkActionEntry mail_folder_context_entries[] = {
};
static const gchar *mapi_ui_mail_def =
+ "<menubar name='main-menu'>\n"
+ " <menu action='file-menu'>\n"
+ " <placeholder name='long-running-actions'>\n"
+ " <menuitem action=\"mapi-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-mapi-folder-size\"/>\n"
@@ -815,6 +913,8 @@ mapi_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;
@@ -822,7 +922,7 @@ mapi_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_mapi_account;
shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
g_object_get (shell_sidebar, "folder-tree", &folder_tree, NULL);
@@ -847,21 +947,19 @@ mapi_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_mapi_account = account_node || folder_node || mapi_ui_has_mapi_account (shell_view, session);
- if (session)
- g_object_unref (session);
- }
+ if (session)
+ g_object_unref (session);
mapi_ui_enable_actions (action_group, mail_account_context_entries, G_N_ELEMENTS
(mail_account_context_entries), account_node, online);
mapi_ui_enable_actions (action_group, mail_folder_context_entries, G_N_ELEMENTS
(mail_folder_context_entries), folder_node, online);
+ mapi_ui_enable_actions (action_group, global_mapi_entries, G_N_ELEMENTS (global_mapi_entries),
has_mapi_account, online);
}
static void
@@ -885,6 +983,11 @@ mapi_ui_init_mail (GtkUIManager *ui_manager,
e_action_group_add_actions_localized (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_mapi_entries, G_N_ELEMENTS (global_mapi_entries), shell_view);
+
/* Decide whether we want this option to be visible or not */
g_signal_connect (shell_view, "update-actions",
G_CALLBACK (mapi_ui_update_actions_mail_cb),
@@ -994,6 +1097,8 @@ update_mapi_source_entries_cb (EShellView *shell_view,
action_group = e_shell_window_get_action_group (shell_window, group);
mapi_ui_enable_actions (action_group, entries, MAPI_ESOURCE_NUM_ENTRIES, is_mapi_source, is_online);
+ mapi_ui_enable_actions (action_group, global_mapi_entries, G_N_ELEMENTS (global_mapi_entries),
+ mapi_ui_has_mapi_account (shell_view, NULL), is_online);
}
static void
@@ -1003,6 +1108,7 @@ setup_mapi_source_actions (EShellView *shell_view,
guint n_entries)
{
EShellWindow *shell_window;
+ GtkActionGroup *action_group;
const gchar *group;
g_return_if_fail (shell_view != NULL);
@@ -1023,11 +1129,17 @@ setup_mapi_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, MAPI_ESOURCE_NUM_ENTRIES, shell_view);
+ /* Add global actions */
+ e_action_group_add_actions_localized (
+ action_group, GETTEXT_PACKAGE,
+ global_mapi_entries, G_N_ELEMENTS (global_mapi_entries), shell_view);
+
g_signal_connect (shell_view, "update-actions", G_CALLBACK (update_mapi_source_entries_cb), entries);
}
@@ -1095,6 +1207,13 @@ static GtkActionEntry calendar_context_entries[] = {
};
static const gchar *mapi_ui_cal_def =
+ "<menubar name='main-menu'>\n"
+ " <menu action='file-menu'>\n"
+ " <placeholder name='long-running-actions'>\n"
+ " <menuitem action=\"mapi-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-mapi-folder-permissions\"/>\n"
@@ -1125,6 +1244,13 @@ static GtkActionEntry tasks_context_entries[] = {
};
static const gchar *mapi_ui_task_def =
+ "<menubar name='main-menu'>\n"
+ " <menu action='file-menu'>\n"
+ " <placeholder name='long-running-actions'>\n"
+ " <menuitem action=\"mapi-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-mapi-folder-permissions\"/>\n"
@@ -1155,6 +1281,13 @@ static GtkActionEntry memos_context_entries[] = {
};
static const gchar *mapi_ui_memo_def =
+ "<menubar name='main-menu'>\n"
+ " <menu action='file-menu'>\n"
+ " <placeholder name='long-running-actions'>\n"
+ " <menuitem action=\"mapi-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-mapi-folder-permissions\"/>\n"
@@ -1185,6 +1318,13 @@ static GtkActionEntry contacts_context_entries[] = {
};
static const gchar *mapi_ui_book_def =
+ "<menubar name='main-menu'>\n"
+ " <menu action='file-menu'>\n"
+ " <placeholder name='long-running-actions'>\n"
+ " <menuitem action=\"mapi-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-mapi-folder-permissions\"/>\n"
diff --git a/src/configuration/e-mapi-subscribe-foreign-folder.c
b/src/configuration/e-mapi-subscribe-foreign-folder.c
index 612782e..e3f8b1e 100644
--- a/src/configuration/e-mapi-subscribe-foreign-folder.c
+++ b/src/configuration/e-mapi-subscribe-foreign-folder.c
@@ -40,13 +40,19 @@
#define PidTagMailboxOwnerName PR_USER_NAME_UNICODE
#endif
+#define STR_ACCOUNTS_COMBO "e-mapi-accounts-combo"
#define STR_USER_NAME_SELECTOR_ENTRY "e-mapi-name-selector-entry"
#define STR_FOLDER_NAME_COMBO "e-mapi-folder-name-combo"
#define STR_SUBFOLDERS_CHECK "e-mapi-subfolders-check"
#define STR_MAPI_CAMEL_SESSION "e-mapi-camel-session"
-#define STR_MAPI_CAMEL_STORE "e-mapi-camel-store"
#define STR_MAPI_DIRECT_USER_NAME "e-mapi-direct-user-name"
+enum {
+ COLUMN_UID = 0,
+ COLUMN_DISPLAY_NAME,
+ COLUMN_STORE
+};
+
static gboolean
add_foreign_folder_to_camel (CamelMapiStore *mapi_store,
const gchar *foreign_username,
@@ -154,11 +160,37 @@ add_foreign_folder_to_camel (CamelMapiStore *mapi_store,
return res;
}
+static void
+enable_ok_button_by_data (GObject *dialog)
+{
+ GtkEntry *entry;
+ GtkComboBoxText *combo;
+ const gchar *entry_text;
+ gchar *combo_text;
+
+ g_return_if_fail (dialog != NULL);
+
+ entry = g_object_get_data (dialog, STR_USER_NAME_SELECTOR_ENTRY);
+ g_return_if_fail (entry != NULL);
+
+ combo = g_object_get_data (dialog, STR_FOLDER_NAME_COMBO);
+ g_return_if_fail (combo != NULL);
+
+ entry_text = gtk_entry_get_text (entry);
+ combo_text = gtk_combo_box_text_get_active_text (combo);
+
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (dialog), GTK_RESPONSE_OK,
+ entry_text && *entry_text && *entry_text != ' ' && *entry_text != ',' &&
+ combo_text && *combo_text);
+
+ g_free (combo_text);
+}
+
static void
name_entry_changed_cb (GObject *dialog)
{
GtkEntry *entry;
- const gchar *text;
g_return_if_fail (dialog != NULL);
@@ -167,9 +199,14 @@ name_entry_changed_cb (GObject *dialog)
g_object_set_data (G_OBJECT (entry), STR_MAPI_DIRECT_USER_NAME, NULL);
- text = gtk_entry_get_text (entry);
+ enable_ok_button_by_data (dialog);
+}
- gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, text && *text && *text != '
' && *text != ',');
+static void
+folder_name_combo_changed_cb (GObject *dialog,
+ GtkComboBox *combo)
+{
+ enable_ok_button_by_data (dialog);
}
struct EMapiCheckForeignFolderData
@@ -453,6 +490,24 @@ check_foreign_folder_idle (GObject *with_object,
g_free (profile);
}
+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)
@@ -477,9 +532,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_MAPI_CAMEL_STORE);
g_return_if_fail (entry != NULL);
+
+ cstore = ref_selected_store (dialog);
g_return_if_fail (cstore != NULL);
username = NULL;
@@ -543,6 +599,7 @@ subscribe_foreign_response_cb (GObject *dialog,
e_mapi_check_foreign_folder_data_free);
g_free (description);
+ g_object_unref (cstore);
}
static void
@@ -558,15 +615,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);
- mapi_store = g_object_get_data (dialog, STR_MAPI_CAMEL_STORE);
g_return_if_fail (entry != NULL);
+
+ mapi_store = ref_selected_store (dialog);
g_return_if_fail (mapi_store != NULL);
text = g_strstrip (g_strdup (gtk_entry_get_text (entry)));
conn = camel_mapi_store_ref_connection (mapi_store, NULL, NULL);
- if (conn && e_mapi_search_gal_user_modal (GTK_WINDOW (dialog),
+ if (!conn) {
+ e_notice (dialog, GTK_MESSAGE_ERROR, "%s", _("Cannot search for user when the account is
offline"));
+ } else if (e_mapi_search_gal_user_modal (GTK_WINDOW (dialog),
conn,
text,
&searched_type,
@@ -581,14 +641,91 @@ pick_gal_user_clicked_cb (GtkButton *button,
}
}
- if (conn)
- g_object_unref (conn);
-
+ g_object_unref (mapi_store);
+ g_clear_object (&conn);
g_free (text);
g_free (display_name);
g_free (dn);
}
+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 CamelMAPIStore */
+ G_TYPE_STRING, /* COLUMN_DISPLAY_NAME */
+ CAMEL_TYPE_MAPI_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_MAPI_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
users in the given store */
void
@@ -597,20 +734,19 @@ e_mapi_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_MAPI_STORE (store));
+ if (store)
+ g_return_if_fail (CAMEL_IS_MAPI_STORE (store));
dialog = G_OBJECT (gtk_dialog_new_with_buttons (
_("Subscribe to folder of other MAPI user..."),
@@ -642,18 +778,13 @@ e_mapi_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);
@@ -729,14 +860,16 @@ e_mapi_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_MAPI_CAMEL_SESSION, g_object_ref (session), g_object_unref);
- g_object_set_data_full (dialog, STR_MAPI_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]