X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmodest-ui-actions.c;h=b2c6eb25c4f7efa252d488df52941ccefa13045e;hp=82c12373c55c57679a93b9324d1282b2217d65c0;hb=96d9a8c787c693406a0f26e3d3a00065c7236fe5;hpb=b3bfcfba0e231b9ff2d5ff6429e5953709b253ed diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index 82c1237..b2c6eb2 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -26,7 +26,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - + #ifdef HAVE_CONFIG_H #include #endif /*HAVE_CONFIG_H*/ @@ -44,28 +44,39 @@ #include "modest-tny-platform-factory.h" #include "modest-platform.h" +#ifdef MODEST_PLATFORM_MAEMO +#include "maemo/modest-osso-state-saving.h" +#endif /* MODEST_PLATFORM_MAEMO */ + +#include "widgets/modest-ui-constants.h" #include #include #include -#include - +#include +#include +#include "widgets/modest-global-settings-dialog.h" +#include "modest-connection-specific-smtp-window.h" #include "modest-account-mgr-helpers.h" #include "modest-mail-operation.h" +#include "modest-text-utils.h" #ifdef MODEST_HAVE_EASYSETUP #include "easysetup/modest-easysetup-wizard.h" -#endif /*MODEST_HAVE_EASYSETUP*/ +#endif /* MODEST_HAVE_EASYSETUP */ #include #include #include #include #include +#include -typedef struct _GetMsgAsyncHelper { +typedef struct _GetMsgAsyncHelper { ModestWindow *window; + ModestMailOperation *mail_op; TnyIterator *iter; - GFunc func; + guint num_ops; + GFunc func; gpointer user_data; } GetMsgAsyncHelper; @@ -76,21 +87,36 @@ typedef enum _ReplyForwardAction { } ReplyForwardAction; typedef struct _ReplyForwardHelper { -guint reply_forward_type; + guint reply_forward_type; ReplyForwardAction action; gchar *account_name; } ReplyForwardHelper; +/* + * The do_headers_action uses this kind of functions to perform some + * action to each member of a list of headers + */ +typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data); + +static void +do_headers_action (ModestWindow *win, + HeadersFunc func, + gpointer user_data); + + +static void open_msg_cb (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg, + gpointer user_data); -static void reply_forward_func (gpointer data, gpointer user_data); -static void read_msg_func (gpointer data, gpointer user_data); -static void get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, +static void reply_forward_cb (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg, gpointer user_data); + static void reply_forward (ReplyForwardAction action, ModestWindow *win); -static void modest_ui_actions_message_details_cb (gpointer msg_data, - gpointer helper_data); -static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title); +static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title); void modest_ui_actions_on_about (GtkAction *action, ModestWindow *win) @@ -109,7 +135,7 @@ modest_ui_actions_on_about (GtkAction *action, ModestWindow *win) gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about), _("a modest e-mail client\n\n" "design and implementation: Dirk-Jan C. Binnema\n" - "contributions from the fine people at KernelConcepts and Igalia\n" + "contributions from the fine people at KC and Ig\n" "uses the tinymail email framework written by Philip van Hoof")); gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors); gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org"); @@ -118,7 +144,14 @@ modest_ui_actions_on_about (GtkAction *action, ModestWindow *win) gtk_widget_destroy(about); } - +/* + * Gets the list of currently selected messages. If the win is the + * main window, then it returns a newly allocated list of the headers + * selected in the header view. If win is the msg view window, then + * the value returned is a list with just a single header. + * + * The caller of this funcion must free the list. + */ static TnyList * get_selected_headers (ModestWindow *win) { @@ -131,71 +164,128 @@ get_selected_headers (ModestWindow *win) } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) { /* for MsgViewWindows, we simply return a list with one element */ - TnyMsg *msg; TnyHeader *header; TnyList *list = NULL; - msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win)); - if (msg) { - header = tny_msg_get_header (msg); + header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win)); + if (header != NULL) { list = tny_simple_list_new (); tny_list_prepend (list, G_OBJECT(header)); g_object_unref (G_OBJECT(header)); } + return list; } else return NULL; } +static void +headers_action_mark_as_read (TnyHeader *header, + ModestWindow *win, + gpointer user_data) +{ + TnyHeaderFlags flags; + + g_return_if_fail (TNY_IS_HEADER(header)); + + flags = tny_header_get_flags (header); + if (flags & TNY_HEADER_FLAG_SEEN) return; + tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN); +} + +static void +headers_action_mark_as_unread (TnyHeader *header, + ModestWindow *win, + gpointer user_data) +{ + TnyHeaderFlags flags; + + g_return_if_fail (TNY_IS_HEADER(header)); + + flags = tny_header_get_flags (header); + if (flags & TNY_HEADER_FLAG_SEEN) { + tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN); + } +} + + +static void +headers_action_delete (TnyHeader *header, + ModestWindow *win, + gpointer user_data) +{ + ModestMailOperation *mail_op = NULL; + + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE, G_OBJECT(win)); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), + mail_op); + + /* Always delete. TODO: Move to trash still not supported */ + modest_mail_operation_remove_msg (mail_op, header, FALSE); + g_object_unref (G_OBJECT (mail_op)); +} + void modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win) { - TnyList *header_list; - TnyIterator *iter; + TnyList *header_list = NULL; + TnyIterator *iter = NULL; + TnyHeader *header = NULL; + gchar *message = NULL; + gchar *desc = NULL; + gint response; g_return_if_fail (MODEST_IS_WINDOW(win)); - - header_list = get_selected_headers (win); - - if (header_list) { - iter = tny_list_create_iterator (header_list); - do { - TnyHeader *header; - ModestMailOperation *mail_op; - - header = TNY_HEADER (tny_iterator_get_current (iter)); - /* TODO: thick grain mail operation involving - a list of objects. Composite pattern ??? */ - /* TODO: add confirmation dialog */ - mail_op = modest_mail_operation_new (); - modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), - mail_op); - /* Always delete. TODO: Move to trash still not supported */ - modest_mail_operation_remove_msg (mail_op, header, FALSE); + header_list = get_selected_headers (win); + if (!header_list) return; - /* Frees */ - g_object_unref (G_OBJECT (mail_op)); - g_object_unref (G_OBJECT (header)); + /* Select message */ + if (tny_list_get_length(header_list) > 1) + message = g_strdup(_("emev_nc_delete_messages")); + else { + iter = tny_list_create_iterator (header_list); + header = TNY_HEADER (tny_iterator_get_current (iter)); + desc = g_strdup_printf ("%s", tny_header_get_subject (header)); + message = g_strdup_printf(_("emev_nc_delete_message"), desc); + } - tny_iterator_next (iter); + /* Confirmation dialog */ + response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win), + message); + - } while (!tny_iterator_is_done (iter)); + if (response == GTK_RESPONSE_OK) { + if (MODEST_IS_MSG_EDIT_WINDOW (win)) { + gboolean ret_value; + g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); + return; + } + + /* Remove each header */ + do_headers_action (win, headers_action_delete, NULL); - /* Free iter */ - g_object_unref (G_OBJECT (iter)); + if (MODEST_IS_MSG_VIEW_WINDOW (win)) { + gtk_widget_destroy (GTK_WIDGET(win)); + } } - if (MODEST_IS_MSG_VIEW_WINDOW (win)) { - gtk_widget_destroy (GTK_WIDGET(win)); - } + /* free */ + g_free(message); + g_free(desc); + g_object_unref (header_list); + g_object_unref (iter); } void modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win) { + #ifdef MODEST_PLATFORM_MAEMO + modest_osso_save_state(); + #endif /* MODEST_PLATFORM_MAEMO */ + gtk_main_quit (); } @@ -204,6 +294,9 @@ modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win) { if (MODEST_IS_MSG_VIEW_WINDOW (win)) { gtk_widget_destroy (GTK_WIDGET (win)); + } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { + gboolean ret_value; + g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); } else if (MODEST_IS_WINDOW (win)) { gtk_widget_destroy (GTK_WIDGET (win)); } else { @@ -227,16 +320,15 @@ modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win) void modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win) { - /* This is currently only implemented for Maemo, * because it requires a providers preset file which is not publically available. */ #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */ - GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr()); + GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), + TRUE /* enabled accounts only */); gboolean accounts_exist = account_names != NULL; g_slist_free (account_names); -/* To test, while modest_account_mgr_account_names() is broken: accounts_exist = TRUE; */ if (!accounts_exist) { /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */ ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new (); @@ -277,6 +369,45 @@ modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win) #endif /* MODEST_PLATFORM_MAEMO */ } +static void +on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data) +{ + ModestWindow *main_window = MODEST_WINDOW (user_data); + + /* Save any changes. */ + modest_connection_specific_smtp_window_save_server_accounts ( + MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window), + modest_window_get_active_account (main_window)); + gtk_widget_destroy (GTK_WIDGET (window)); +} + +void +modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win) +{ + /* This is currently only implemented for Maemo, + * because it requires an API (libconic) to detect different connection + * possiblities. + */ +#ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */ + + /* Create the window if necessary: */ + GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ()); + modest_connection_specific_smtp_window_fill_with_connections ( + MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window), + modest_runtime_get_account_mgr(), + modest_window_get_active_account (win)); + + /* Show the window: */ + gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win)); + gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE); + gtk_widget_show (specific_window); + + /* Save changes when the window is hidden: */ + g_signal_connect (specific_window, "hide", + G_CALLBACK (on_smtp_servers_window_hide), win); +#endif /* MODEST_PLATFORM_MAEMO */ +} + void modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win) { @@ -285,9 +416,10 @@ modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win) TnyFolder *folder = NULL; gchar *account_name = NULL; gchar *from_str = NULL; - GError *err = NULL; +/* GError *err = NULL; */ TnyAccount *account = NULL; ModestWindowMgr *mgr; + gchar *signature = NULL; account_name = g_strdup(modest_window_get_active_account (win)); if (!account_name) @@ -311,7 +443,15 @@ modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win) goto cleanup; } - msg = modest_tny_msg_new ("", from_str, "", "", "", "", NULL); + if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name, + MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) { + signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name, + MODEST_ACCOUNT_SIGNATURE, FALSE); + } else { + signature = g_strdup (""); + } + + msg = modest_tny_msg_new ("", from_str, "", "", "", signature, NULL); if (!msg) { g_printerr ("modest: failed to create new msg\n"); goto cleanup; @@ -323,15 +463,16 @@ modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win) goto cleanup; } - tny_folder_add_msg (folder, msg, &err); - if (err) { - g_printerr ("modest: error adding msg to Drafts folder: %s", - err->message); - g_error_free (err); - goto cleanup; - } +/* tny_folder_add_msg (folder, msg, &err); */ +/* if (err) { */ +/* g_printerr ("modest: error adding msg to Drafts folder: %s", */ +/* err->message); */ +/* g_error_free (err); */ +/* goto cleanup; */ +/* } */ /* Create and register edit window */ + /* This is destroyed by TOOD. */ msg_win = modest_msg_edit_window_new (msg, account_name); mgr = modest_runtime_get_window_mgr (); modest_window_mgr_register_window (mgr, msg_win); @@ -344,6 +485,7 @@ modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win) cleanup: g_free (account_name); g_free (from_str); + g_free (signature); if (account) g_object_unref (G_OBJECT(account)); if (msg) @@ -352,20 +494,167 @@ cleanup: g_object_unref (G_OBJECT(folder)); } +static void +open_msg_cb (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg, + gpointer user_data) +{ + ModestWindowMgr *mgr = NULL; + ModestWindow *parent_win = NULL; + ModestWindow *win = NULL; + TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN; + gchar *account = NULL; + TnyFolder *folder; + + /* TODO: Show an error? (review the specs) */ + if (!msg) + return; + + parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op); + folder = tny_header_get_folder (header); + + /* Mark header as read */ + headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL); + + /* Get account */ + account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win))); + if (!account) + account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr()); + + /* Gets folder type (OUTBOX headers will be opened in edit window */ + if (modest_tny_folder_is_local_folder (folder)) + folder_type = modest_tny_folder_get_local_folder_type (folder); + + /* If the header is in the drafts folder then open the editor, + else the message view window */ + if (folder_type == TNY_FOLDER_TYPE_DRAFTS) { + win = modest_msg_edit_window_new (msg, account); + } else { + if (MODEST_IS_MAIN_WINDOW (parent_win)) { + GtkWidget *header_view; + GtkTreeSelection *sel; + GList *sel_list = NULL; + GtkTreeModel *model; + + header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win), + MODEST_WIDGET_TYPE_HEADER_VIEW); + + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view)); + sel_list = gtk_tree_selection_get_selected_rows (sel, &model); + + if (sel_list != NULL) { + GtkTreeRowReference *row_reference; + + row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data); + g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL); + g_list_free (sel_list); + + win = modest_msg_view_window_new_with_header_model (msg, + account, + model, + row_reference); + gtk_tree_row_reference_free (row_reference); + } else { + win = modest_msg_view_window_new (msg, account); + } + } else { + win = modest_msg_view_window_new (msg, account); + } + } + + /* Register and show new window */ + if (win != NULL) { + mgr = modest_runtime_get_window_mgr (); + modest_window_mgr_register_window (mgr, win); + gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win)); + gtk_widget_show_all (GTK_WIDGET(win)); + } + + /* Free */ + g_free(account); + g_object_unref (msg); + g_object_unref (folder); + g_object_unref (header); +} + +/* + * This function is used by both modest_ui_actions_on_open and + * modest_ui_actions_on_header_activated. This way we always do the + * same when trying to open messages. + */ +static void +_modest_ui_actions_open (TnyList *headers, ModestWindow *win) +{ + ModestWindowMgr *mgr; + TnyIterator *iter; + ModestMailOperation *mail_op; + + /* Look if we already have a message view for each header. If + true, then remove the header from the list of headers to + open */ + mgr = modest_runtime_get_window_mgr (); + iter = tny_list_create_iterator (headers); + while (!tny_iterator_is_done (iter)) { + ModestWindow *window; + TnyHeader *header; + + header = TNY_HEADER (tny_iterator_get_current (iter)); + window = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header)); + if (window) + tny_list_remove (headers, G_OBJECT (header)); + + g_object_unref (header); + tny_iterator_next (iter); + } + + /* Open each message */ + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT (win)); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); + modest_mail_operation_get_msgs_full (mail_op, + headers, + open_msg_cb, + NULL, + NULL); + + /* Clean */ + g_object_unref(mail_op); +} void modest_ui_actions_on_open (GtkAction *action, ModestWindow *win) { - modest_runtime_not_implemented (GTK_WINDOW(win)); /* FIXME */ + TnyList *headers; + + /* Get headers */ + headers = get_selected_headers (win); + if (!headers) + return; + + /* Open them */ + _modest_ui_actions_open (headers, win); + + g_object_unref(headers); } +static void +free_reply_forward_helper (gpointer data) +{ + ReplyForwardHelper *helper; + + helper = (ReplyForwardHelper *) data; + g_free (helper->account_name); + g_slice_free (ReplyForwardHelper, helper); +} static void -reply_forward_func (gpointer data, gpointer user_data) +reply_forward_cb (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg, + gpointer user_data) { - TnyMsg *msg, *new_msg; - GetMsgAsyncHelper *helper; + TnyMsg *new_msg; ReplyForwardHelper *rf_helper; ModestWindow *msg_win; ModestEditType edit_type; @@ -374,30 +663,38 @@ reply_forward_func (gpointer data, gpointer user_data) TnyFolder *folder = NULL; TnyAccount *account = NULL; ModestWindowMgr *mgr; - - msg = TNY_MSG (data); - helper = (GetMsgAsyncHelper *) user_data; - rf_helper = (ReplyForwardHelper *) helper->user_data; + gchar *signature = NULL; + + g_return_if_fail (user_data != NULL); + rf_helper = (ReplyForwardHelper *) user_data; from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), rf_helper->account_name); + if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(), + rf_helper->account_name, + MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) { + signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), + rf_helper->account_name, + MODEST_ACCOUNT_SIGNATURE, FALSE); + } + /* Create reply mail */ switch (rf_helper->action) { case ACTION_REPLY: new_msg = - modest_tny_msg_create_reply_msg (msg, from, + modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type, MODEST_TNY_MSG_REPLY_MODE_SENDER); break; case ACTION_REPLY_TO_ALL: new_msg = - modest_tny_msg_create_reply_msg (msg, from, rf_helper->reply_forward_type, + modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type, MODEST_TNY_MSG_REPLY_MODE_ALL); edit_type = MODEST_EDIT_TYPE_REPLY; break; case ACTION_FORWARD: new_msg = - modest_tny_msg_create_forward_msg (msg, from, rf_helper->reply_forward_type); + modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type); edit_type = MODEST_EDIT_TYPE_FORWARD; break; default: @@ -405,6 +702,8 @@ reply_forward_func (gpointer data, gpointer user_data) return; } + g_free (signature); + if (!new_msg) { g_printerr ("modest: failed to create message\n"); goto cleanup; @@ -447,22 +746,20 @@ cleanup: g_object_unref (G_OBJECT (folder)); if (account) g_object_unref (G_OBJECT (account)); - - g_free (rf_helper->account_name); - g_slice_free (ReplyForwardHelper, rf_helper); + g_object_unref (msg); + g_object_unref (header); } + /* * Common code for the reply and forward actions */ static void reply_forward (ReplyForwardAction action, ModestWindow *win) { - TnyList *header_list; + ModestMailOperation *mail_op = NULL; + TnyList *header_list = NULL; + ReplyForwardHelper *rf_helper = NULL; guint reply_forward_type; - TnyHeader *header; - TnyFolder *folder; - GetMsgAsyncHelper *helper; - ReplyForwardHelper *rf_helper; g_return_if_fail (MODEST_IS_WINDOW(win)); @@ -482,41 +779,44 @@ reply_forward (ReplyForwardAction action, ModestWindow *win) rf_helper = g_slice_new0 (ReplyForwardHelper); rf_helper->reply_forward_type = reply_forward_type; rf_helper->action = action; - rf_helper->account_name = g_strdup (modest_window_get_active_account (win)); if (!rf_helper->account_name) rf_helper->account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr()); - helper = g_slice_new0 (GetMsgAsyncHelper); - helper->window = win; - helper->func = reply_forward_func; - helper->iter = tny_list_create_iterator (header_list); - helper->user_data = rf_helper; - if (MODEST_IS_MSG_VIEW_WINDOW(win)) { TnyMsg *msg; - msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win)); - if (!msg) { + TnyHeader *header; + /* Get header and message. Do not free them here, the + reply_forward_cb must do it */ + msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win)); + header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win)); + if (!msg || !header) { + if (msg) + g_object_unref (msg); + if (header) + g_object_unref (header); g_printerr ("modest: no message found\n"); return; } else - reply_forward_func (msg, helper); + reply_forward_cb (NULL, header, msg, rf_helper); } else { - header = TNY_HEADER (tny_iterator_get_current (helper->iter)); - folder = tny_header_get_folder (header); - if (folder) { - /* The callback will call it per each header */ - tny_folder_get_msg_async (folder, header, get_msg_cb, NULL, helper); - g_object_unref (G_OBJECT (folder)); - } else - g_printerr ("modest: no folder for header\n"); - + /* Retrieve messages */ + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win)); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); + modest_mail_operation_get_msgs_full (mail_op, + header_list, + reply_forward_cb, + rf_helper, + free_reply_forward_helper); + /* Clean */ - g_object_unref (G_OBJECT (header)); + g_object_unref(mail_op); } -} + /* Free */ + g_object_unref (header_list); +} void modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win) @@ -588,98 +888,143 @@ modest_ui_actions_on_sort (GtkAction *action, ModestWindow *window) { g_return_if_fail (MODEST_IS_WINDOW(window)); - /* FIXME: unimplemented */ -} + if (MODEST_IS_MAIN_WINDOW (window)) { + GtkWidget *header_view; + header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window), + MODEST_WIDGET_TYPE_HEADER_VIEW); + if (!header_view) + return; -static gboolean -action_send (const gchar* account_name) -{ - TnyAccount *tny_account; - ModestTnySendQueue *send_queue; - - g_return_val_if_fail (account_name, FALSE); - - tny_account = - modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(), - account_name, - TNY_ACCOUNT_TYPE_TRANSPORT); - if (!tny_account) { - g_printerr ("modest: cannot get tny transport account for %s\n", account_name); - return FALSE; + /* Show sorting dialog */ + modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS); } - send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account)); - if (!send_queue) { - g_object_unref (G_OBJECT(tny_account)); - g_printerr ("modest: cannot get send queue for %s\n", account_name); - return FALSE; - } - - //modest_tny_send_queue_flush (send_queue); +} - g_object_unref (G_OBJECT(send_queue)); - g_object_unref (G_OBJECT(tny_account)); +/** Check that an appropriate connection is open. + */ +gboolean check_for_connection (const gchar *account_name) +{ + TnyDevice *device = modest_runtime_get_device (); - return TRUE; +/* + g_assert (TNY_IS_MAEMO_CONIC_DEVICE (device)); + + TnyMaemoConicDevice *maemo_device = TNY_MAEMO_CONIC_DEVICE (device); +*/ + + if (tny_device_is_online (device)) + return TRUE; + else { + modest_platform_connect_and_wait (NULL); + + /* TODO: Wait until a result. */ + return TRUE; + } } - -static gboolean -action_receive (const gchar* account_name) +/* + * This function performs the send & receive required actions. The + * window it's used to create the mail operation. Tipically it should + * be allways the main window, but we pass it as argument in order to + * be more flexible. + */ +void +modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win) { - TnyAccount *tny_account; - ModestMailOperation *mail_op; + gchar *acc_name = NULL; - g_return_val_if_fail (account_name, FALSE); - - tny_account = - modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(), - account_name, - TNY_ACCOUNT_TYPE_STORE); - if (!tny_account) { - g_printerr ("modest: cannot get tny store account for %s\n", account_name); - return FALSE; + /* If no account name was provided get the current account, if + there is none either then pick the default one */ + if (!account_name) { + acc_name = g_strdup (modest_window_get_active_account(win)); + if (!acc_name) + acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr()); + if (!acc_name) { + g_printerr ("modest: cannot get default account\n"); + return; + } + } else { + acc_name = g_strdup (account_name); } + /* Send & receive. */ + + /* Do not continue if no suitable connection + is open */ + if (!check_for_connection (acc_name)) { + g_free (acc_name); + return; + } + + /* TODO: Do not continue if an operation is already in progress: + * Maybe there are some operations that tinymail allows to + * happen simulatenously. + * TODO: Maybe a simple global gboolean is_updating is enough? + * murrayc. + */ + + /* As per the UI spec, + * for POP accounts, we should receive, + * for IMAP we should synchronize everything, including receiving, + * for SMTP we should send, + * first receiving, then sending: + */ /* Create the mail operation */ - mail_op = modest_mail_operation_new (); + /* TODO: The spec wants us to first do any pending deletions, before receiving. */ + ModestMailOperation *mail_op; + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win)); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); - modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account)); - - g_object_unref (G_OBJECT(tny_account)); + modest_mail_operation_update_account (mail_op, acc_name); g_object_unref (G_OBJECT (mail_op)); - - return TRUE; + + /* Free */ + g_free (acc_name); } +/* + * Refreshes all accounts. This function will be used by automatic + * updates + */ +void +modest_ui_actions_do_send_receive_all (ModestWindow *win) +{ + GSList *account_names, *iter; + + account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), + TRUE); + iter = account_names; + while (iter) { + modest_ui_actions_do_send_receive ((const char*) iter->data, win); + iter = g_slist_next (iter); + } + + g_slist_foreach (account_names, (GFunc) g_free, NULL); + g_slist_free (account_names); +} +/* + * Handler of the click on Send&Receive button in the main toolbar + */ void modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win) { - gchar *account_name; - + /* Check that at least one account exists: */ + GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(), + TRUE /* enabled accounts only */); + gboolean accounts_exist = account_names != NULL; + g_slist_free (account_names); - g_message ("online? %s", - tny_device_is_online(modest_runtime_get_device()) ? "yes":"no"); - - account_name = - g_strdup(modest_window_get_active_account(MODEST_WINDOW(win))); - if (!account_name) - account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr()); - if (!account_name) { - g_printerr ("modest: cannot get account\n"); - return; - } - - if (!action_send(account_name)) - g_printerr ("modest: failed to send\n"); - if (!action_receive(account_name)) - g_printerr ("modest: failed to receive\n"); + /* If not, allow the user to create an account before trying to send/receive. */ + if (!accounts_exist) + modest_ui_actions_on_accounts (NULL, win); + + /* Refresh the active account */ + modest_ui_actions_do_send_receive (NULL, win); } - void modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window) { @@ -698,7 +1043,7 @@ modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow * /* what is saved/restored is depending on the style; thus; we save with * old style, then update the style, and restore for this new style */ - modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view"); + modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY); if (modest_header_view_get_style (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS) @@ -709,191 +1054,71 @@ modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow * MODEST_HEADER_VIEW_STYLE_DETAILS); modest_widget_memory_restore (conf, G_OBJECT(header_view), - "header-view"); + MODEST_CONF_HEADER_VIEW_KEY); } - -/* - * Marks a message as read and passes it to the msg preview widget - */ -static void -read_msg_func (gpointer data, gpointer user_data) +void +modest_ui_actions_on_header_selected (ModestHeaderView *header_view, + TnyHeader *header, + ModestMainWindow *main_window) { - TnyMsg *msg; - TnyHeader *header; - GetMsgAsyncHelper *helper; - TnyHeaderFlags header_flags; - GtkWidget *msg_preview; - - msg = TNY_MSG (data); - helper = (GetMsgAsyncHelper *) user_data; + g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); - msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window), - MODEST_WIDGET_TYPE_MSG_PREVIEW); - if (!msg_preview) + /* If no header has been selected then exit */ + if (!header) return; - - header = TNY_HEADER (tny_iterator_get_current (helper->iter)); - header_flags = tny_header_get_flags (header); - tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN); - g_object_unref (G_OBJECT (header)); - /* Set message on msg view */ - modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg); + /* Update Main window title */ + if (GTK_WIDGET_HAS_FOCUS (header_view)) { + const gchar *subject = tny_header_get_subject (header); + if (subject && strcmp (subject, "")) + gtk_window_set_title (GTK_WINDOW (main_window), subject); + else + gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject")); + } } -/* - * This function is a generic handler for the tny_folder_get_msg_async - * call. It expects as user_data a #GetMsgAsyncHelper. This helper - * contains a user provided function that is called inside this - * method. This will allow us to use this callback in many different - * places. This callback performs the common actions for the - * get_msg_async call, more specific actions will be done by the user - * function - */ -static void -get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data) +void +modest_ui_actions_on_header_activated (ModestHeaderView *header_view, + TnyHeader *header, + ModestMainWindow *main_window) { - GetMsgAsyncHelper *helper; + TnyList *headers; - helper = (GetMsgAsyncHelper *) user_data; - - if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) { - modest_ui_actions_on_item_not_found (NULL, - MODEST_ITEM_TYPE_MESSAGE, - helper->window); + g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); + + if (!header) return; - } - /* Call user function */ - helper->func (msg, user_data); - - /* Process next element (if exists) */ - tny_iterator_next (helper->iter); - if (tny_iterator_is_done (helper->iter)) { - TnyList *headers; - headers = tny_iterator_get_list (helper->iter); - /* Free resources */ - g_object_unref (G_OBJECT (headers)); - g_object_unref (G_OBJECT (helper->iter)); - g_slice_free (GetMsgAsyncHelper, helper); - } else { - TnyHeader *header; - header = TNY_HEADER (tny_iterator_get_current (helper->iter)); - tny_folder_get_msg_async (folder, header, - get_msg_cb, NULL, helper); - g_object_unref (G_OBJECT(header)); - } -} - -void -modest_ui_actions_on_header_selected (ModestHeaderView *header_view, - TnyHeader *header, - ModestMainWindow *main_window) -{ - TnyFolder *folder; - GetMsgAsyncHelper *helper; - TnyList *list; - - g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); - - /* when there's no header, clear the msgview */ - if (!header) { - GtkWidget *msg_preview; - - /* Clear msg preview if exists */ - msg_preview = modest_main_window_get_child_widget(main_window, - MODEST_WIDGET_TYPE_MSG_PREVIEW); - - if (msg_preview) - modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL); - return; - } - - /* Update Main window title */ - if (GTK_WIDGET_HAS_FOCUS (header_view)) { - const gchar *subject = tny_header_get_subject (header); - if (subject && strcmp (subject, "")) - gtk_window_set_title (GTK_WINDOW (main_window), subject); - else - gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject")); - } - - /* Create list */ - list = tny_simple_list_new (); - tny_list_prepend (list, G_OBJECT (header)); - - /* Fill helper data */ - helper = g_slice_new0 (GetMsgAsyncHelper); - helper->window = MODEST_WINDOW (main_window); - helper->iter = tny_list_create_iterator (list); - helper->func = read_msg_func; + headers = tny_simple_list_new (); + tny_list_prepend (headers, G_OBJECT (header)); - folder = tny_header_get_folder (TNY_HEADER(header)); + _modest_ui_actions_open (headers, MODEST_WINDOW (main_window)); - tny_folder_get_msg_async (TNY_FOLDER(folder), - header, get_msg_cb, - NULL, helper); - - /* Frees */ - g_object_unref (G_OBJECT (folder)); + g_object_unref (headers); } - - -void -modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header, - ModestMainWindow *main_window) +static void +set_active_account_from_tny_account (TnyAccount *account, + ModestWindow *window) { - ModestWindow *win = NULL; - TnyFolder *folder = NULL; - TnyMsg *msg = NULL; - ModestWindowMgr *mgr; - - g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); + const gchar *server_acc_name = tny_account_get_id (account); - if (!header) - return; - - folder = tny_header_get_folder (header); - if (!folder) { - g_printerr ("modest: cannot get folder for header\n"); - return; - } - - /* FIXME: make async?; check error */ - msg = tny_folder_get_msg (folder, header, NULL); - if (!msg) { - g_printerr ("modest: cannot get msg for header\n"); - goto cleanup; - } - - /* Look if we already have a message view for that header */ - mgr = modest_runtime_get_window_mgr (); - win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header)); - - /* If not, create a new window */ - if (!win) { - gchar *account; + printf("%s: server_acc_name=%s\n", __FUNCTION__, server_acc_name); + /* We need the TnyAccount provided by the + account store because that is the one that + knows the name of the Modest account */ + TnyAccount *modest_server_account = modest_server_account = + modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (), + server_acc_name); + printf("%s: modest_server_account name=%s\n", __FUNCTION__, tny_account_get_id (modest_server_account)); - account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window))); - if (!account) - account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr()); + const gchar *modest_acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account); + printf("%s: modest_acc_name=%s\n", __FUNCTION__, modest_acc_name); - win = modest_msg_view_window_new (msg, account); - modest_window_mgr_register_window (mgr, win); - - gtk_window_set_transient_for (GTK_WINDOW (win), - GTK_WINDOW (main_window)); - } - - gtk_widget_show_all (GTK_WIDGET(win)); - - g_object_unref (G_OBJECT (msg)); - -cleanup: - g_object_unref (G_OBJECT (folder)); + modest_window_set_active_account (window, modest_acc_name); + g_object_unref (modest_server_account); } void @@ -914,28 +1139,39 @@ modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view, conf = modest_runtime_get_conf (); - if (TNY_IS_FOLDER (folder_store)) { - - modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS); - - if (selected) { - modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), + if (TNY_IS_ACCOUNT (folder_store)) { + /* Update active account */ + set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window)); + /* Show account details */ + modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS); + } else if (modest_tny_folder_store_is_virtual_local_folders (folder_store )) { + printf ("DEBUG: %s: folder store.\n", __FUNCTION__); + //TODO: Set the virtual folder store as the "active account" somehow: + modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS); + } else { + if (TNY_IS_FOLDER (folder_store) && selected) { + + if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */ + /* Update the active account */ + TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder_store)); + set_active_account_from_tny_account (account, MODEST_WINDOW (main_window)); + g_object_unref (account); + } + + /* Set folder on header view */ + modest_main_window_set_contents_style (main_window, + MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS); + modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), TNY_FOLDER (folder_store)); modest_widget_memory_restore (conf, G_OBJECT(header_view), - "header-view"); + MODEST_CONF_HEADER_VIEW_KEY); } else { - modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view"); + /* Update the active account */ + modest_window_set_active_account (MODEST_WINDOW (main_window), NULL); + /* Do not show folder */ + modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY); modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL); } - } else if (TNY_IS_ACCOUNT (folder_store)) { - - modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS); - -/* if (selected) { */ - -/* } else { */ -/* /\* TODO *\/ */ -/* } */ } } @@ -980,7 +1216,7 @@ modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemTyp gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300); if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { -// tny_device_force_online (modest_runtime_get_device()); +// modest_platform_connect_and_wait ();; } } gtk_widget_destroy (dialog); @@ -992,7 +1228,7 @@ void modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link, ModestWindow *win) { - g_message ("%s %s", __FUNCTION__, link); + /* g_message ("%s %s", __FUNCTION__, link); */ } @@ -1014,8 +1250,7 @@ void modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part, ModestWindow *win) { - g_message (__FUNCTION__); - + modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part); } void @@ -1023,9 +1258,72 @@ modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview, const gchar *address, ModestWindow *win) { - g_message ("%s %s", __FUNCTION__, address); + /* g_message ("%s %s", __FUNCTION__, address); */ +} + +void +modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window) +{ + TnyTransportAccount *transport_account; + ModestMailOperation *mail_operation; + MsgData *data; + gchar *account_name, *from; + ModestAccountMgr *account_mgr; + + g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window)); + + data = modest_msg_edit_window_get_msg_data (edit_window); + + account_mgr = modest_runtime_get_account_mgr(); + account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window))); + if (!account_name) + account_name = modest_account_mgr_get_default_account (account_mgr); + if (!account_name) { + g_printerr ("modest: no account found\n"); + modest_msg_edit_window_free_msg_data (edit_window, data); + return; + } + transport_account = + TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account + (modest_runtime_get_account_store(), + account_name, + TNY_ACCOUNT_TYPE_TRANSPORT)); + if (!transport_account) { + g_printerr ("modest: no transport account found for '%s'\n", account_name); + g_free (account_name); + modest_msg_edit_window_free_msg_data (edit_window, data); + return; + } + from = modest_account_mgr_get_from_string (account_mgr, account_name); + + /* Create the mail operation */ + mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(edit_window)); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation); + + modest_mail_operation_save_to_drafts (mail_operation, + transport_account, + from, + data->to, + data->cc, + data->bcc, + data->subject, + data->plain_body, + data->html_body, + data->attachments, + data->priority_flags); + /* Frees */ + g_free (from); + g_free (account_name); + g_object_unref (G_OBJECT (transport_account)); + g_object_unref (G_OBJECT (mail_operation)); + + modest_msg_edit_window_free_msg_data (edit_window, data); + + /* Save settings and close the window */ + gtk_widget_destroy (GTK_WIDGET (edit_window)); } +/* For instance, when clicking the Send toolbar button when editing a message: */ void modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window) { @@ -1036,6 +1334,9 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window) ModestAccountMgr *account_mgr; g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window)); + + if (!modest_msg_edit_window_check_names (edit_window)) + return; data = modest_msg_edit_window_get_msg_data (edit_window); @@ -1052,10 +1353,9 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window) return; } transport_account = - TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account + TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(), - account_name, - TNY_ACCOUNT_TYPE_TRANSPORT)); + account_name)); if (!transport_account) { g_printerr ("modest: no transport account found for '%s'\n", account_name); g_free (account_name); @@ -1065,7 +1365,7 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window) from = modest_account_mgr_get_from_string (account_mgr, account_name); /* Create the mail operation */ - mail_operation = modest_mail_operation_new (); + mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_SEND, G_OBJECT(edit_window)); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation); modest_mail_operation_send_new_mail (mail_operation, @@ -1216,6 +1516,26 @@ modest_ui_actions_on_insert_image (GtkAction *action, modest_msg_edit_window_insert_image (window); } +void +modest_ui_actions_on_attach_file (GtkAction *action, + ModestMsgEditWindow *window) +{ + g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window)); + g_return_if_fail (GTK_IS_ACTION (action)); + + modest_msg_edit_window_attach_file (window); +} + +void +modest_ui_actions_on_remove_attachments (GtkAction *action, + ModestMsgEditWindow *window) +{ + g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window)); + g_return_if_fail (GTK_IS_ACTION (action)); + + modest_msg_edit_window_remove_attachments (window, NULL); +} + /* * Shows a dialog with an entry that asks for some text. The returned * value must be freed by the caller. The dialog window title will be @@ -1272,27 +1592,46 @@ modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_windo parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view)); if (parent_folder) { - gchar *folder_name; - - folder_name = ask_for_folder_name (GTK_WINDOW (main_window), - _("Please enter a name for the new folder")); - - if (folder_name != NULL && strlen (folder_name) > 0) { - TnyFolder *new_folder; - ModestMailOperation *mail_op; - - mail_op = modest_mail_operation_new (); - modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), - mail_op); - - new_folder = modest_mail_operation_create_folder (mail_op, - parent_folder, - (const gchar *) folder_name); - if (new_folder) - g_object_unref (new_folder); - g_object_unref (mail_op); + gboolean finished = FALSE; + gint result; + gchar *folder_name = NULL, *suggested_name = NULL; + + /* Run the new folder dialog */ + while (!finished) { + result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window), + parent_folder, + suggested_name, + &folder_name); + + if (result == GTK_RESPONSE_REJECT) { + finished = TRUE; + } else { + ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(main_window)); + TnyFolder *new_folder = NULL; + + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), + mail_op); + + new_folder = modest_mail_operation_create_folder (mail_op, + parent_folder, + (const gchar *) folder_name); + if (new_folder) { + g_object_unref (new_folder); + finished = TRUE; + } +/* else { */ +/* /\* TODO: check error and follow proper actions *\/ */ +/* /\* suggested_name = X; *\/ */ +/* /\* Show error to the user *\/ */ +/* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */ +/* _("mail_in_ui_folder_create_error")); */ +/* } */ + g_object_unref (mail_op); + } g_free (folder_name); + folder_name = NULL; } + g_object_unref (parent_folder); } } @@ -1303,14 +1642,21 @@ modest_ui_actions_on_rename_folder (GtkAction *action, { TnyFolderStore *folder; GtkWidget *folder_view; - + GtkWidget *header_view; + g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); folder_view = modest_main_window_get_child_widget (main_window, MODEST_WIDGET_TYPE_FOLDER_VIEW); if (!folder_view) return; + + header_view = modest_main_window_get_child_widget (main_window, + MODEST_WIDGET_TYPE_HEADER_VIEW); + if (!header_view) + return; + folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view)); if (folder && TNY_IS_FOLDER (folder)) { @@ -1321,10 +1667,12 @@ modest_ui_actions_on_rename_folder (GtkAction *action, if (folder_name != NULL && strlen (folder_name) > 0) { ModestMailOperation *mail_op; - mail_op = modest_mail_operation_new (); + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(main_window)); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); + modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL); + modest_mail_operation_rename_folder (mail_op, TNY_FOLDER (folder), (const gchar *) folder_name); @@ -1340,8 +1688,9 @@ static void delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) { TnyFolderStore *folder; - ModestMailOperation *mail_op; GtkWidget *folder_view; + gint response; + gchar *message; g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); @@ -1351,13 +1700,36 @@ delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) return; folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)); - - mail_op = modest_mail_operation_new (); - modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), - mail_op); - modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash); - g_object_unref (G_OBJECT (mail_op)); + /* Show an error if it's an account */ + if (!TNY_IS_FOLDER (folder)) { + modest_platform_run_information_dialog (GTK_WINDOW (main_window), + _("mail_in_ui_folder_delete_error")); + return ; + } + + /* Ask the user */ + message = g_strdup_printf (_("mcen_nc_delete_folder_text"), + tny_folder_get_name (TNY_FOLDER (folder))); + response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window), + (const gchar *) message); + g_free (message); + + if (response == GTK_RESPONSE_OK) { + ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE, G_OBJECT(main_window)); + + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), + mail_op); + modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash); + + /* Show error if happened */ + if (modest_mail_operation_get_error (mail_op)) + modest_platform_run_information_dialog (GTK_WINDOW (main_window), + _("mail_in_ui_folder_delete_error")); + + g_object_unref (G_OBJECT (mail_op)); + } + g_object_unref (G_OBJECT (folder)); } @@ -1380,16 +1752,37 @@ modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainW void modest_ui_actions_on_password_requested (TnyAccountStore *account_store, - const gchar* account_name, + const gchar* server_account_name, + gchar **username, gchar **password, gboolean *cancel, gboolean *remember, ModestMainWindow *main_window) { - gchar *txt; - GtkWidget *dialog, *entry, *remember_pass_check; - - dialog = gtk_dialog_new_with_buttons (_("Password requested"), + g_return_if_fail(server_account_name); + /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */ + + /* Initalize output parameters: */ + if (cancel) + *cancel = FALSE; + + if (remember) + *remember = TRUE; + +#ifdef MODEST_PLATFORM_MAEMO + /* Maemo uses a different (awkward) button order, + * It should probably just use gtk_alternative_dialog_button_order (). + */ + GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"), + NULL, + GTK_DIALOG_MODAL, + GTK_STOCK_OK, + GTK_RESPONSE_ACCEPT, + GTK_STOCK_CANCEL, + GTK_RESPONSE_REJECT, + NULL); +#else + GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"), NULL, GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, @@ -1397,40 +1790,142 @@ modest_ui_actions_on_password_requested (TnyAccountStore *account_store, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); +#endif /* MODEST_PLATFORM_MAEMO */ + gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window)); - txt = g_strdup_printf (_("Please enter your password for %s"), account_name); + gchar *server_name = modest_server_account_get_hostname ( + modest_runtime_get_account_mgr(), server_account_name); + + /* This causes a warning because the logical ID has no %s in it, + * though the translation does, but there is not much we can do about that: */ + gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name); gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt), FALSE, FALSE, 0); g_free (txt); + g_free (server_name); + server_name = NULL; - entry = gtk_entry_new_with_max_length (40); - gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE); - gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */ + /* username: */ + gchar *initial_username = modest_server_account_get_username ( + modest_runtime_get_account_mgr(), server_account_name); - gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry, - TRUE, FALSE, 0); - + GtkWidget *entry_username = gtk_entry_new (); + if (initial_username) + gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username); + /* Dim this if a connection has ever succeeded with this username, + * as per the UI spec: */ + const gboolean username_known = + modest_server_account_get_username_has_succeeded( + modest_runtime_get_account_mgr(), server_account_name); + gtk_widget_set_sensitive (entry_username, !username_known); + +#ifdef MODEST_PLATFORM_MAEMO + /* Auto-capitalization is the default, so let's turn it off: */ + hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL); + + /* Create a size group to be used by all captions. + * Note that HildonCaption does not create a default size group if we do not specify one. + * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */ + GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + + GtkWidget *caption = hildon_caption_new (sizegroup, + _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY); + gtk_widget_show (entry_username); + gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, + FALSE, FALSE, MODEST_MARGIN_HALF); + gtk_widget_show (caption); +#else + gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username, + TRUE, FALSE, 0); +#endif /* MODEST_PLATFORM_MAEMO */ + + /* password: */ + GtkWidget *entry_password = gtk_entry_new (); + gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE); + /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */ + +#ifdef MODEST_PLATFORM_MAEMO + /* Auto-capitalization is the default, so let's turn it off: */ + hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password), + HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE); + + caption = hildon_caption_new (sizegroup, + _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY); + gtk_widget_show (entry_password); + gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption, + FALSE, FALSE, MODEST_MARGIN_HALF); + gtk_widget_show (caption); + g_object_unref (sizegroup); +#else + gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password, + TRUE, FALSE, 0); +#endif /* MODEST_PLATFORM_MAEMO */ + +/* This is not in the Maemo UI spec: remember_pass_check = gtk_check_button_new_with_label (_("Remember password")); gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check, TRUE, FALSE, 0); +*/ gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox)); if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { - *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry))); - *cancel = FALSE; + if (username) { + *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username))); + + modest_server_account_set_username ( + modest_runtime_get_account_mgr(), server_account_name, + *username); + + const gboolean username_was_changed = + (strcmp (*username, initial_username) != 0); + if (username_was_changed) { + /* To actually use a changed username, + * we must reset the connection, according to pvanhoof. + * This _might_ be a sensible way to do that: */ + TnyDevice *device = modest_runtime_get_device(); + tny_device_force_offline (device); + tny_device_force_online (device); + } + } + + if (password) { + *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password))); + + /* We do not save the password in the configuration, + * because this function is only called for passwords that should + * not be remembered: + modest_server_account_set_password ( + modest_runtime_get_account_mgr(), server_account_name, + *password); + */ + } + + if (cancel) + *cancel = FALSE; + } else { - *password = NULL; - *cancel = TRUE; + if (username) + *username = NULL; + + if (password) + *password = NULL; + + if (cancel) + *cancel = TRUE; } +/* This is not in the Maemo UI spec: if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check))) *remember = TRUE; else *remember = FALSE; +*/ gtk_widget_destroy (dialog); + + printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); } void @@ -1510,7 +2005,9 @@ modest_ui_actions_on_select_all (GtkAction *action, GtkWidget *focused_widget; focused_widget = gtk_window_get_focus (GTK_WINDOW (window)); - if (GTK_IS_LABEL (focused_widget)) { + if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) { + modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget)); + } else if (GTK_IS_LABEL (focused_widget)) { gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1); } else if (GTK_IS_EDITABLE (focused_widget)) { gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1); @@ -1526,6 +2023,26 @@ modest_ui_actions_on_select_all (GtkAction *action, } void +modest_ui_actions_on_mark_as_read (GtkAction *action, + ModestWindow *window) +{ + g_return_if_fail (MODEST_IS_WINDOW(window)); + + /* Mark each header as read */ + do_headers_action (window, headers_action_mark_as_read, NULL); +} + +void +modest_ui_actions_on_mark_as_unread (GtkAction *action, + ModestWindow *window) +{ + g_return_if_fail (MODEST_IS_WINDOW(window)); + + /* Mark each header as read */ + do_headers_action (window, headers_action_mark_as_unread, NULL); +} + +void modest_ui_actions_on_change_zoom (GtkRadioAction *action, GtkRadioAction *selected, ModestWindow *window) @@ -1615,42 +2132,56 @@ modest_ui_actions_on_change_fullscreen (GtkAction *action, gtk_window_present (GTK_WINDOW (window)); } +/* + * Used by modest_ui_actions_on_details to call do_headers_action + */ static void -modest_ui_actions_message_details_cb (gpointer msg_data, - gpointer helper_data) +headers_action_show_details (TnyHeader *header, + ModestWindow *window, + gpointer user_data) + { GtkWidget *dialog; - TnyMsg *msg = (TnyMsg *) msg_data; - TnyHeader *header; - GetMsgAsyncHelper *helper = (GetMsgAsyncHelper *) helper_data; - - header = tny_msg_get_header (msg); - dialog = modest_msg_view_details_dialog_new (GTK_WINDOW (helper->window), header); - g_object_unref (header); + /* Create dialog */ + dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header); + + /* Run dialog */ gtk_widget_show_all (dialog); + gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_widget_destroy (dialog); +} + +/* + * Show the folder details in a ModestDetailsDialog widget + */ +static void +show_folder_details (TnyFolder *folder, + GtkWindow *window) +{ + GtkWidget *dialog; + + /* Create dialog */ + dialog = modest_details_dialog_new_with_folder (window, folder); + /* Run dialog */ + gtk_widget_show_all (dialog); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); } +/* + * Show the header details in a ModestDetailsDialog widget + */ void -modest_ui_actions_on_message_details (GtkAction *action, - ModestWindow *win) +modest_ui_actions_on_details (GtkAction *action, + ModestWindow *win) { TnyList * headers_list; - GetMsgAsyncHelper *helper; - - headers_list = get_selected_headers (win); - if (!headers_list) - return; - - helper = g_slice_new0 (GetMsgAsyncHelper); - helper->window = win; - helper->func = modest_ui_actions_message_details_cb; - helper->iter = tny_list_create_iterator (headers_list); - helper->user_data = NULL; + TnyIterator *iter; + TnyHeader *header; if (MODEST_IS_MSG_VIEW_WINDOW (win)) { TnyMsg *msg; @@ -1658,13 +2189,44 @@ modest_ui_actions_on_message_details (GtkAction *action, msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win)); if (!msg) return; - else { - modest_ui_actions_message_details_cb (msg, helper); + g_object_unref (msg); + + headers_list = get_selected_headers (win); + if (!headers_list) + return; + + iter = tny_list_create_iterator (headers_list); + + header = TNY_HEADER (tny_iterator_get_current (iter)); + headers_action_show_details (header, win, NULL); + g_object_unref (header); + + g_object_unref (iter); + g_object_unref (headers_list); + + } else if (MODEST_IS_MAIN_WINDOW (win)) { + GtkWidget *folder_view, *header_view; + + /* Check which widget has the focus */ + folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), + MODEST_WIDGET_TYPE_FOLDER_VIEW); + if (gtk_widget_is_focus (folder_view)) { + TnyFolder *folder; + + folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)); + + /* Show only when it's a folder */ + if (!folder || !TNY_IS_FOLDER (folder)) + return; + + show_folder_details (folder, GTK_WINDOW (win)); + + } else { + header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), + MODEST_WIDGET_TYPE_HEADER_VIEW); + /* Show details of each header */ + do_headers_action (win, headers_action_show_details, header_view); } - } else { - /* here we should add an implementation to run the message details dialog - from the main window */ - g_return_if_reached (); } } @@ -1739,7 +2301,7 @@ modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view, the focus. This callback could be called even if the folder view has not the focus, because the handled signal could be emitted when the folder view is redrawn */ - if (GTK_WIDGET_HAS_FOCUS (folder_view)) { + if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) { if (display_name) gtk_window_set_title (window, display_name); else @@ -1753,3 +2315,435 @@ modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *wi g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window)); modest_msg_edit_window_select_contacts (window); } + +void +modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window) +{ + g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window)); + modest_msg_edit_window_check_names (window); +} + + +static GtkWidget* +create_move_to_dialog (ModestWindow *win, + GtkWidget *folder_view, + GtkWidget **tree_view) +{ + GtkWidget *dialog, *scroll; + + dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"), + GTK_WINDOW (win), + GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_OK, + GTK_RESPONSE_ACCEPT, + GTK_STOCK_CANCEL, + GTK_RESPONSE_REJECT, + NULL); + + /* Create scrolled window */ + scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + + /* Create folder view */ + *tree_view = modest_folder_view_new (NULL); + gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view), + gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view))); + gtk_container_add (GTK_CONTAINER (scroll), *tree_view); + + /* Add scroll to dialog */ + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), + scroll, FALSE, FALSE, 0); + + gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox)); + + return dialog; +} + +/* + * Returns TRUE if at least one of the headers of the list belongs to + * a message that has been fully retrieved. + */ +static gboolean +has_retrieved_msgs (TnyList *list) +{ + TnyIterator *iter; + gboolean found = FALSE; + + iter = tny_list_create_iterator (list); + while (tny_iterator_is_done (iter) && !found) { + TnyHeader *header; + TnyHeaderFlags flags; + + header = TNY_HEADER (tny_iterator_get_current (iter)); + flags = tny_header_get_flags (header); + if (!(flags & TNY_HEADER_FLAG_PARTIAL)) + found = TRUE; + + if (!found) + tny_iterator_next (iter); + } + g_object_unref (iter); + + return found; +} + +/* + * Shows a confirmation dialog to the user when we're moving messages + * from a remote server to the local storage. Returns the dialog + * response. If it's other kind of movement the it always returns + * GTK_RESPONSE_OK + */ +static gint +msgs_move_to_confirmation (GtkWindow *win, + TnyFolder *dest_folder, + TnyList *headers) +{ + gint response = GTK_RESPONSE_OK; + + /* If the destination is a local folder */ + if (modest_tny_folder_is_local_folder (dest_folder)) { + TnyFolder *src_folder; + TnyIterator *iter; + TnyHeader *header; + + /* Get source folder */ + iter = tny_list_create_iterator (headers); + header = TNY_HEADER (tny_iterator_get_current (iter)); + src_folder = tny_header_get_folder (header); + g_object_unref (header); + g_object_unref (iter); + + /* If the source is a remote folder */ + if (!modest_tny_folder_is_local_folder (src_folder)) { + const gchar *message; + + if (tny_list_get_length (headers) == 1) + if (has_retrieved_msgs (headers)) + message = _("mcen_nc_move_retrieve"); + else + message = _("mcen_nc_move_header"); + else + if (has_retrieved_msgs (headers)) + message = _("mcen_nc_move_retrieves"); + else + message = _("mcen_nc_move_headers"); + + response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win), + (const gchar *) message); + } + g_object_unref (src_folder); + } + return response; +} + + +static void +tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data) +{ + ModestMsgViewWindow *self = NULL; + gboolean found = FALSE; + + g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object)); + self = MODEST_MSG_VIEW_WINDOW (object); + + found = modest_msg_view_window_select_first_message (self); + g_return_if_fail (found); +} + +static void +move_to_error_checking (const GObject *obj, gpointer user_data) +{ + ModestWindow *win = NULL; + + g_return_if_fail (MODEST_IS_WINDOW (obj)); + win = MODEST_WINDOW (obj); + + /* TODO: show error message */ +/* modest_platform_run_information_dialog (GTK_WINDOW (win), */ +/* _("mail_in_ui_folder_move_target_error")); */ +} + +/* + * UI handler for the "Move to" action when invoked from the + * ModestMainWindow + */ +static void +modest_ui_actions_on_main_window_move_to (GtkAction *action, + ModestMainWindow *win) +{ + GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL; + GtkWidget *header_view = NULL; + gint result; + TnyFolderStore *folder_store = NULL; + ModestMailOperation *mail_op = NULL; + + g_return_if_fail (MODEST_IS_MAIN_WINDOW (win)); + + /* Get the folder view */ + folder_view = modest_main_window_get_child_widget (win, + MODEST_WIDGET_TYPE_FOLDER_VIEW); + + /* Get header view */ + header_view = modest_main_window_get_child_widget (win, + MODEST_WIDGET_TYPE_HEADER_VIEW); + + /* Create and run the dialog */ + dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view); + result = gtk_dialog_run (GTK_DIALOG(dialog)); + g_object_ref (tree_view); + + /* We do this to save an indentation level ;-) */ + if (result != GTK_RESPONSE_ACCEPT) + goto end; + + folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view)); + + if (TNY_IS_ACCOUNT (folder_store)) + goto end; + + /* Get folder or messages to transfer */ + if (gtk_widget_is_focus (folder_view)) { + TnyFolderStore *src_folder; + src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)); + + /* Clean folder on header view before moving it */ + modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL); + + if (TNY_IS_FOLDER (src_folder)) { + mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_ID_RECEIVE, + G_OBJECT(win), + move_to_error_checking); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), + mail_op); + + modest_mail_operation_xfer_folder (mail_op, + TNY_FOLDER (src_folder), + folder_store, + TRUE); + g_object_unref (G_OBJECT (mail_op)); + + } + + /* Frees */ + g_object_unref (G_OBJECT (src_folder)); + } else { + if (gtk_widget_is_focus (header_view)) { + TnyList *headers; + gint response; + + headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view)); + + /* Ask for user confirmation */ + response = msgs_move_to_confirmation (GTK_WINDOW (win), + TNY_FOLDER (folder_store), + headers); + + /* Transfer messages */ + if (response == GTK_RESPONSE_OK) { + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win)); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), + mail_op); + + modest_mail_operation_xfer_msgs (mail_op, + headers, + TNY_FOLDER (folder_store), + TRUE, + NULL, + NULL); + g_object_unref (G_OBJECT (mail_op)); + } + g_object_unref (headers); + } + } + g_object_unref (folder_store); + + end: + gtk_widget_destroy (dialog); +} + + +/* + * UI handler for the "Move to" action when invoked from the + * ModestMsgViewWindow + */ +static void +modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, + ModestMsgViewWindow *win) +{ + GtkWidget *dialog, *folder_view, *tree_view = NULL; + gint result; + ModestMainWindow *main_window; + TnyHeader *header; + TnyList *headers; + + /* Get the folder view */ + main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ())); + folder_view = modest_main_window_get_child_widget (main_window, + MODEST_WIDGET_TYPE_FOLDER_VIEW); + + /* Create and run the dialog */ + dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view); + result = gtk_dialog_run (GTK_DIALOG(dialog)); + g_object_ref (tree_view); + + if (result == GTK_RESPONSE_ACCEPT) { + TnyFolderStore *folder_store; + gint response; + + folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view)); + + /* Create header list */ + header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win)); + headers = tny_simple_list_new (); + tny_list_prepend (headers, G_OBJECT (header)); + g_object_unref (header); + + /* Ask user for confirmation. MSG-NOT404 */ + response = msgs_move_to_confirmation (GTK_WINDOW (win), + TNY_FOLDER (folder_store), + headers); + + /* Transfer current msg */ + if (response == GTK_RESPONSE_OK) { + ModestMailOperation *mail_op; + + /* Create mail op */ + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win)); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), + mail_op); + + /* Transfer messages */ + modest_mail_operation_xfer_msgs (mail_op, + headers, + TNY_FOLDER (folder_store), + TRUE, + tranasfer_msgs_from_viewer_cb, + NULL); + g_object_unref (G_OBJECT (mail_op)); + } + g_object_unref (headers); + g_object_unref (folder_store); + } + gtk_widget_destroy (dialog); +} + +void +modest_ui_actions_on_move_to (GtkAction *action, + ModestWindow *win) +{ + g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) || + MODEST_IS_MSG_VIEW_WINDOW (win)); + + if (MODEST_IS_MAIN_WINDOW (win)) + modest_ui_actions_on_main_window_move_to (action, + MODEST_MAIN_WINDOW (win)); + else + modest_ui_actions_on_msg_view_window_move_to (action, + MODEST_MSG_VIEW_WINDOW (win)); +} + +/* + * Calls #HeadersFunc for each header already selected in the main + * window or the message currently being shown in the msg view window + */ +static void +do_headers_action (ModestWindow *win, + HeadersFunc func, + gpointer user_data) +{ + TnyList *headers_list; + TnyIterator *iter; + + /* Get headers */ + headers_list = get_selected_headers (win); + if (!headers_list) + return; + + /* Call the function for each header */ + iter = tny_list_create_iterator (headers_list); + while (!tny_iterator_is_done (iter)) { + TnyHeader *header; + + header = TNY_HEADER (tny_iterator_get_current (iter)); + func (header, win, user_data); + g_object_unref (header); + tny_iterator_next (iter); + } + g_object_unref (iter); + g_object_unref (headers_list); +} + +void +modest_ui_actions_view_attachment (GtkAction *action, + ModestWindow *window) +{ + if (MODEST_IS_MSG_VIEW_WINDOW (window)) { + modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL); + } else { + /* not supported window for this action */ + g_return_if_reached (); + } +} + +void +modest_ui_actions_save_attachments (GtkAction *action, + ModestWindow *window) +{ + if (MODEST_IS_MSG_VIEW_WINDOW (window)) { + modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL); + } else { + /* not supported window for this action */ + g_return_if_reached (); + } +} + +void +modest_ui_actions_remove_attachments (GtkAction *action, + ModestWindow *window) +{ + if (MODEST_IS_MSG_VIEW_WINDOW (window)) { + modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL); + } else { + /* not supported window for this action */ + g_return_if_reached (); + } +} + +void +modest_ui_actions_on_settings (GtkAction *action, + ModestWindow *win) +{ + GtkWidget *dialog; + + dialog = modest_platform_get_global_settings_dialog (); + gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win)); + gtk_widget_show (dialog); + + gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_widget_destroy (dialog); +} + +void +modest_ui_actions_on_retrieve_msg_contents (GtkAction *action, + ModestWindow *window) +{ + ModestMailOperation *mail_op; + TnyList *headers; + + /* Get headers */ + headers = get_selected_headers (window); + if (!headers) + return; + + /* Create mail operation */ + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT (window)); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); + modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL); + + /* Frees */ + g_object_unref (headers); + g_object_unref (mail_op); +}