From 48d805df31ec77d001c097b01e1788755e9fd8eb Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 25 Nov 2010 18:10:14 +0100 Subject: Bug #207580 - Allow new mail check on individual accounts --- modules/mail/e-mail-shell-backend.c | 20 -- modules/mail/e-mail-shell-view-actions.c | 68 ++++++ modules/mail/e-mail-shell-view-actions.h | 8 + modules/mail/e-mail-shell-view-private.c | 357 +++++++++++++++++++++++++++++++ modules/mail/e-mail-shell-view-private.h | 15 ++ 5 files changed, 448 insertions(+), 20 deletions(-) (limited to 'modules/mail') diff --git a/modules/mail/e-mail-shell-backend.c b/modules/mail/e-mail-shell-backend.c index 09db9ce0e8..590241a838 100644 --- a/modules/mail/e-mail-shell-backend.c +++ b/modules/mail/e-mail-shell-backend.c @@ -366,21 +366,6 @@ mail_shell_backend_prepare_for_quit_cb (EShell *shell, } } -static void -mail_shell_backend_send_receive_cb (EShell *shell, - GtkWindow *parent, - EShellBackend *shell_backend) -{ - EMailBackend *backend; - EMailSession *session; - - backend = E_MAIL_BACKEND (shell_backend); - session = e_mail_backend_get_session (backend); - - em_utils_clear_get_password_canceled_accounts_flag (); - mail_send_receive (parent, session); -} - static void mail_shell_backend_window_weak_notify_cb (EShell *shell, GObject *where_the_object_was) @@ -479,11 +464,6 @@ mail_shell_backend_constructed (GObject *object) G_CALLBACK (mail_shell_backend_prepare_for_quit_cb), shell_backend); - g_signal_connect ( - shell, "send-receive", - G_CALLBACK (mail_shell_backend_send_receive_cb), - shell_backend); - g_signal_connect ( shell, "window-created", G_CALLBACK (mail_shell_backend_window_created_cb), diff --git a/modules/mail/e-mail-shell-view-actions.c b/modules/mail/e-mail-shell-view-actions.c index b2c5b8d1bb..01c53bed6e 100644 --- a/modules/mail/e-mail-shell-view-actions.c +++ b/modules/mail/e-mail-shell-view-actions.c @@ -715,6 +715,24 @@ action_mail_label_none_cb (GtkAction *action, em_utils_uids_free (uids); } +static void +action_mail_send_receive_cb (GtkAction *action, EMailShellView *mail_shell_view) +{ + e_mail_shell_view_send_receive (mail_shell_view, E_MAIL_SEND_RECEIVE_BOTH, NULL); +} + +static void +action_mail_send_receive_receive_all_cb (GtkAction *action, EMailShellView *mail_shell_view) +{ + e_mail_shell_view_send_receive (mail_shell_view, E_MAIL_SEND_RECEIVE_RECEIVE, NULL); +} + +static void +action_mail_send_receive_send_all_cb (GtkAction *action, EMailShellView *mail_shell_view) +{ + e_mail_shell_view_send_receive (mail_shell_view, E_MAIL_SEND_RECEIVE_SEND, NULL); +} + static void action_mail_show_deleted_cb (GtkToggleAction *action, EMailShellView *mail_shell_view) @@ -1180,6 +1198,34 @@ static GtkActionEntry mail_entries[] = { N_("Subscribe or unsubscribe to folders on remote servers"), G_CALLBACK (action_mail_tools_subscriptions_cb) }, + { "mail-send-receive", + "mail-send-receive", + N_("Send / _Receive"), + "F9", + N_("Send queued items and retrieve new items"), + G_CALLBACK (action_mail_send_receive_cb) }, + + { "mail-send-receive-receive-all", + NULL, + N_("R_eceive all"), + NULL, + N_("Receive new items from all accounts"), + G_CALLBACK (action_mail_send_receive_receive_all_cb) }, + + { "mail-send-receive-send-all", + "mail-send", + N_("_Send all"), + NULL, + N_("Send queued items in all accounts"), + G_CALLBACK (action_mail_send_receive_send_all_cb) }, + + { "mail-send-receive-submenu", + "mail-send-receive", + N_("Send / _Receive"), + NULL, + NULL, + NULL }, + { "mail-smart-backward", NULL, NULL, /* No menu item; key press only */ @@ -1570,6 +1616,8 @@ e_mail_shell_view_actions_init (EMailShellView *mail_shell_view) e_shell_searchbar_set_search_option ( searchbar, GTK_RADIO_ACTION (action)); + g_object_set (ACTION (MAIL_SEND_RECEIVE), "is-important", TRUE, NULL); + /* Bind GObject properties for GConf keys. */ bridge = gconf_bridge_get (); @@ -1637,6 +1685,26 @@ e_mail_shell_view_actions_init (EMailShellView *mail_shell_view) ACTION (MAIL_STOP), "sensitive", G_BINDING_SYNC_CREATE); + g_object_bind_property ( + shell, "online", + ACTION (MAIL_SEND_RECEIVE), "sensitive", + G_BINDING_SYNC_CREATE); + + g_object_bind_property ( + shell, "online", + ACTION (MAIL_SEND_RECEIVE_RECEIVE_ALL), "sensitive", + G_BINDING_SYNC_CREATE); + + g_object_bind_property ( + shell, "online", + ACTION (MAIL_SEND_RECEIVE_SEND_ALL), "sensitive", + G_BINDING_SYNC_CREATE); + + g_object_bind_property ( + shell, "online", + ACTION (MAIL_SEND_RECEIVE_SUBMENU), "sensitive", + G_BINDING_SYNC_CREATE); + /* Keep the sensitivity of "Create Search Folder from Search" * in sync with "Save Search" so that its only selectable when * showing search results. */ diff --git a/modules/mail/e-mail-shell-view-actions.h b/modules/mail/e-mail-shell-view-actions.h index 5eb015bd47..d9b801a9c0 100644 --- a/modules/mail/e-mail-shell-view-actions.h +++ b/modules/mail/e-mail-shell-view-actions.h @@ -167,6 +167,14 @@ E_SHELL_WINDOW_ACTION ((window), "mail-search-folder-from-subject") #define E_SHELL_WINDOW_ACTION_MAIL_SELECT_ALL(window) \ E_SHELL_WINDOW_ACTION ((window), "mail-select-all") +#define E_SHELL_WINDOW_ACTION_MAIL_SEND_RECEIVE(window) \ + E_SHELL_WINDOW_ACTION ((window), "mail-send-receive") +#define E_SHELL_WINDOW_ACTION_MAIL_SEND_RECEIVE_RECEIVE_ALL(window) \ + E_SHELL_WINDOW_ACTION ((window), "mail-send-receive-receive-all") +#define E_SHELL_WINDOW_ACTION_MAIL_SEND_RECEIVE_SEND_ALL(window) \ + E_SHELL_WINDOW_ACTION ((window), "mail-send-receive-send-all") +#define E_SHELL_WINDOW_ACTION_MAIL_SEND_RECEIVE_SUBMENU(window) \ + E_SHELL_WINDOW_ACTION ((window), "mail-send-receive-submenu") #define E_SHELL_WINDOW_ACTION_MAIL_SHOW_ALL_HEADERS(window) \ E_SHELL_WINDOW_ACTION ((window), "mail-show-all-headers") #define E_SHELL_WINDOW_ACTION_MAIL_SHOW_DELETED(window) \ diff --git a/modules/mail/e-mail-shell-view-private.c b/modules/mail/e-mail-shell-view-private.c index 12ff06567d..871f9d756c 100644 --- a/modules/mail/e-mail-shell-view-private.c +++ b/modules/mail/e-mail-shell-view-private.c @@ -22,6 +22,7 @@ #include "e-mail-shell-view-private.h" #include "widgets/menus/gal-view-factory-etable.h" +#include "widgets/misc/e-menu-tool-button.h" #include "e-util/e-util-private.h" @@ -658,6 +659,11 @@ e_mail_shell_view_private_constructed (EMailShellView *mail_shell_view) G_CALLBACK (e_shell_taskbar_set_message), shell_taskbar, G_CONNECT_SWAPPED); + g_signal_connect_object ( + mail_shell_view, "toggled", + G_CALLBACK (e_mail_shell_view_update_send_receive_menus), + mail_shell_view, G_CONNECT_AFTER | G_CONNECT_SWAPPED); + /* Need to keep the handler ID so we can disconnect it in * dispose(). The shell outlives us and we don't want it * invoking callbacks on finalized shell views. */ @@ -1104,3 +1110,354 @@ e_mail_shell_view_update_sidebar (EMailShellView *mail_shell_view) g_string_free (buffer, TRUE); } + +void +e_mail_shell_view_send_receive (EMailShellView *mail_shell_view, EMailSendReceiveMode mode, const gchar *account_uid) +{ + EMailBackend *backend; + EMailSession *session; + EShellWindow *shell_window; + + g_return_if_fail (mail_shell_view != NULL); + + shell_window = e_shell_view_get_shell_window (E_SHELL_VIEW (mail_shell_view)); + backend = E_MAIL_BACKEND (e_shell_view_get_shell_backend (E_SHELL_VIEW (mail_shell_view))); + session = e_mail_backend_get_session (backend); + + em_utils_clear_get_password_canceled_accounts_flag (); + + if (!account_uid) { + switch (mode) { + case E_MAIL_SEND_RECEIVE_BOTH: + mail_send_receive (GTK_WINDOW (shell_window), session); + break; + case E_MAIL_SEND_RECEIVE_RECEIVE: + mail_receive (GTK_WINDOW (shell_window), session); + break; + case E_MAIL_SEND_RECEIVE_SEND: + mail_send (session); + break; + } + } else { + /* allow only receive on individual accounts */ + EAccount *account; + + account = e_get_account_by_uid (account_uid); + g_return_if_fail (account != NULL); + + if (account->enabled && account->source && account->source->url && *account->source->url) + mail_receive_uri (session, account->source->url, account->source->keep_on_server); + } +} + +static GtkMenuItem * +send_receive_find_account_menu_item (GtkMenuShell *menu, EAccount *account) +{ + GList *children, *child; + + g_return_val_if_fail (menu != NULL, NULL); + g_return_val_if_fail (account != NULL, NULL); + g_return_val_if_fail (account->uid != NULL, NULL); + + children = gtk_container_get_children (GTK_CONTAINER (menu)); + + for (child = children; child != NULL; child = child->next) { + GObject *obj = child->data; + const gchar *uid; + + if (!obj) + continue; + + uid = g_object_get_data (obj, "e-account-uid"); + if (!uid) + continue; + + if (g_strcmp0 (uid, account->uid) == 0) { + g_list_free (children); + + return GTK_MENU_ITEM (obj); + } + } + + g_list_free (children); + + return NULL; +} + +static gint +send_receive_get_account_index (EAccount *account) +{ + gint res; + EAccountList *accounts; + EIterator *iterator; + + g_return_val_if_fail (account != NULL, -1); + + accounts = e_get_account_list (); + g_return_val_if_fail (accounts != NULL, -1); + + res = 0; + for (iterator = e_list_get_iterator (E_LIST (accounts)); + e_iterator_is_valid (iterator); + e_iterator_next (iterator)) { + EAccount *acc = (EAccount *) e_iterator_get (iterator); + const gchar *name; + + if (!acc || !acc->enabled || !acc->source || !acc->source->url || !*acc->source->url) + continue; + + name = e_account_get_string (acc, E_ACCOUNT_NAME); + if (!name || !*name || !acc->uid || !*acc->uid) + continue; + + if (g_strcmp0 (acc->uid, account->uid) == 0) { + g_object_unref (iterator); + return res; + } + + res++; + } + + return -1; +} + +static void +send_receive_account_item_activate_cb (GtkMenuItem *item, GtkMenuShell *menu) +{ + EMailShellView *mail_shell_view; + const gchar *account_uid; + + g_return_if_fail (item != NULL); + g_return_if_fail (menu != NULL); + + mail_shell_view = g_object_get_data (G_OBJECT (menu), "mail-shell-view"); + g_return_if_fail (mail_shell_view != NULL); + + account_uid = g_object_get_data (G_OBJECT (item), "e-account-uid"); + g_return_if_fail (account_uid != NULL); + + e_mail_shell_view_send_receive (mail_shell_view, E_MAIL_SEND_RECEIVE_RECEIVE, account_uid); +} + +static void +send_receive_add_to_menu (GtkMenuShell *menu, EAccount *account, gint insert_index) +{ + const gchar *name; + GtkWidget *item; + + g_return_if_fail (menu != NULL); + g_return_if_fail (account != NULL); + + if (send_receive_find_account_menu_item (menu, account) != NULL) + return; + + if (!account->source || !account->source->url || !*account->source->url) + return; + + name = e_account_get_string (account, E_ACCOUNT_NAME); + if (!name || !*name || !account->uid || !*account->uid) + return; + + item = gtk_menu_item_new_with_label (name); + gtk_widget_show (item); + g_object_set_data_full (G_OBJECT (item), "e-account-uid", g_strdup (account->uid), g_free); + g_signal_connect (item, "activate", G_CALLBACK (send_receive_account_item_activate_cb), menu); + + /* it's index between accounts, not in the menu */ + if (insert_index < 0) + gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + else + gtk_menu_shell_insert (GTK_MENU_SHELL (menu), item, insert_index + 4); +} + +static void +send_receive_remove_from_menu (GtkMenuShell *menu, EAccount *account) +{ + GtkMenuItem *item; + + g_return_if_fail (menu != NULL); + g_return_if_fail (account != NULL); + + item = send_receive_find_account_menu_item (menu, account); + if (!item) + return; + + gtk_container_remove (GTK_CONTAINER (menu), GTK_WIDGET (item)); +} + +static void +send_receive_menu_account_added_cb (EAccountList *list, EAccount *account, GtkMenuShell *menu) +{ + g_return_if_fail (account != NULL); + g_return_if_fail (menu != NULL); + + if (account->enabled) + send_receive_add_to_menu (menu, account, send_receive_get_account_index (account)); +} + +static void +send_receive_menu_account_changed_cb (EAccountList *list, EAccount *account, GtkMenuShell *menu) +{ + g_return_if_fail (account != NULL); + g_return_if_fail (menu != NULL); + + if (account->enabled) { + GtkMenuItem *item = send_receive_find_account_menu_item (menu, account); + + if (item) { + if (!account->source || !account->source->url || !*account->source->url) { + send_receive_remove_from_menu (menu, account); + } else { + const gchar *name = e_account_get_string (account, E_ACCOUNT_NAME); + if (name && *name) + gtk_menu_item_set_label (item, name); + } + } else { + send_receive_add_to_menu (menu, account, send_receive_get_account_index (account)); + } + } else { + send_receive_remove_from_menu (menu, account); + } +} + +static void +send_receive_menu_account_removed_cb (EAccountList *list, EAccount *account, GtkMenuShell *menu) +{ + g_return_if_fail (account != NULL); + g_return_if_fail (menu != NULL); + + send_receive_remove_from_menu (menu, account); +} + +static void +menu_weak_ref_cb (gpointer accounts, GObject *freed_menu) +{ + g_return_if_fail (accounts != NULL); + + g_signal_handlers_disconnect_matched (accounts, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, freed_menu); +} + +static GtkWidget * +create_send_receive_submenu (EMailShellView *mail_shell_view) +{ + EShellWindow *shell_window; + EAccountList *accounts; + GtkWidget *menu; + GtkAccelGroup *accel_group; + GtkUIManager *ui_manager; + GtkAction *action; + + g_return_val_if_fail (mail_shell_view != NULL, NULL); + + shell_window = e_shell_view_get_shell_window (E_SHELL_VIEW (mail_shell_view)); + + accounts = e_get_account_list (); + menu = gtk_menu_new (); + ui_manager = e_shell_window_get_ui_manager (shell_window); + accel_group = gtk_ui_manager_get_accel_group (ui_manager); + + action = e_shell_window_get_action (shell_window, "mail-send-receive"); + gtk_action_set_accel_group (action, accel_group); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_action_create_menu_item (action)); + + action = e_shell_window_get_action (shell_window, "mail-send-receive-receive-all"); + gtk_action_set_accel_group (action, accel_group); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_action_create_menu_item (action)); + + action = e_shell_window_get_action (shell_window, "mail-send-receive-send-all"); + gtk_action_set_accel_group (action, accel_group); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_action_create_menu_item (action)); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ()); + + if (accounts) { + EIterator *iterator; + + for (iterator = e_list_get_iterator (E_LIST (accounts)); + e_iterator_is_valid (iterator); + e_iterator_next (iterator)) { + EAccount *account = (EAccount *) e_iterator_get (iterator); + + if (!account || !account->enabled) + continue; + + send_receive_add_to_menu (GTK_MENU_SHELL (menu), account, -1); + } + + g_signal_connect (accounts, "account-added", G_CALLBACK (send_receive_menu_account_added_cb), menu); + g_signal_connect (accounts, "account-changed", G_CALLBACK (send_receive_menu_account_changed_cb), menu); + g_signal_connect (accounts, "account-removed", G_CALLBACK (send_receive_menu_account_removed_cb), menu); + + g_object_weak_ref (G_OBJECT (menu), menu_weak_ref_cb, accounts); + } + + gtk_widget_show_all (menu); + + g_object_set_data (G_OBJECT (menu), "mail-shell-view", mail_shell_view); + + return menu; +} + +void +e_mail_shell_view_update_send_receive_menus (EMailShellView *mail_shell_view) +{ + EMailShellViewPrivate *priv; + EShellWindow *shell_window; + GtkWidget *widget, *toolbar; + GtkToolItem *tool_item; + gint index; + + g_return_if_fail (mail_shell_view != NULL); + + priv = E_MAIL_SHELL_VIEW_GET_PRIVATE (mail_shell_view); + g_return_if_fail (priv != NULL); + + if (!e_shell_view_is_active (E_SHELL_VIEW (mail_shell_view))) { + if (priv->send_receive_tool_item) { + shell_window = e_shell_view_get_shell_window (E_SHELL_VIEW (mail_shell_view)); + + toolbar = e_shell_window_get_managed_widget (shell_window, "/main-toolbar"); + g_return_if_fail (toolbar != NULL); + + gtk_container_remove (GTK_CONTAINER (toolbar), GTK_WIDGET (priv->send_receive_tool_item)); + gtk_container_remove (GTK_CONTAINER (toolbar), GTK_WIDGET (priv->send_receive_tool_separator)); + + priv->send_receive_tool_item = NULL; + priv->send_receive_tool_separator = NULL; + } + + return; + } + + shell_window = e_shell_view_get_shell_window (E_SHELL_VIEW (mail_shell_view)); + + widget = e_shell_window_get_managed_widget (shell_window, "/main-menu/file-menu/mail-send-receiver/mail-send-receive-submenu"); + if (widget) + gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), create_send_receive_submenu (mail_shell_view)); + + toolbar = e_shell_window_get_managed_widget (shell_window, "/main-toolbar"); + g_return_if_fail (toolbar != NULL); + + widget = e_shell_window_get_managed_widget (shell_window, "/main-toolbar/toolbar-actions/mail-send-receiver"); + g_return_if_fail (widget != NULL); + + index = gtk_toolbar_get_item_index (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (widget)); + + tool_item = gtk_separator_tool_item_new (); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), tool_item, index); + gtk_widget_show (GTK_WIDGET (tool_item)); + priv->send_receive_tool_separator = tool_item; + + tool_item = GTK_TOOL_ITEM (e_menu_tool_button_new (_("Send / Receive"))); + gtk_tool_item_set_is_important (tool_item, TRUE); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), tool_item, index); + gtk_widget_show (GTK_WIDGET (tool_item)); + priv->send_receive_tool_item = tool_item; + + gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (tool_item), create_send_receive_submenu (mail_shell_view)); + + g_object_bind_property ( + ACTION (MAIL_SEND_RECEIVE), "sensitive", + tool_item, "sensitive", + G_BINDING_SYNC_CREATE); +} diff --git a/modules/mail/e-mail-shell-view-private.h b/modules/mail/e-mail-shell-view-private.h index 806b408772..9f028e0e8a 100644 --- a/modules/mail/e-mail-shell-view-private.h +++ b/modules/mail/e-mail-shell-view-private.h @@ -131,6 +131,12 @@ enum { MAIL_SCOPE_ALL_ACCOUNTS }; +typedef enum { + E_MAIL_SEND_RECEIVE_BOTH, + E_MAIL_SEND_RECEIVE_RECEIVE, + E_MAIL_SEND_RECEIVE_SEND +} EMailSendReceiveMode; + struct _EMailShellViewPrivate { /*** Other Stuff ***/ @@ -156,6 +162,9 @@ struct _EMailShellViewPrivate { GCancellable *search_account_cancel; guint show_deleted : 1; + + GtkToolItem *send_receive_tool_item; + GtkToolItem *send_receive_tool_separator; }; void e_mail_shell_view_private_init @@ -186,6 +195,12 @@ void e_mail_shell_view_update_search_filter (EMailShellView *mail_shell_view); void e_mail_shell_view_update_sidebar (EMailShellView *mail_shell_view); +void e_mail_shell_view_send_receive + (EMailShellView *mail_shell_view, + EMailSendReceiveMode mode, + const gchar *account_uid); +void e_mail_shell_view_update_send_receive_menus + (EMailShellView *mail_shell_view); G_END_DECLS -- cgit v1.2.3