X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmodest-ui-actions.c;h=d44cd5a491d650b6b6c1ef908aa6669cdc10006b;hp=9e4b93475dfde91bff7f2cfd9f684f2661436c2c;hb=3c8a0d459b487c9d3c459927f21dd1574a402e9e;hpb=824365b716d6aedf5ef58ec1cb4b4c2248aee630 diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index 9e4b934..d44cd5a 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*/ @@ -38,7 +38,7 @@ #include #include #include - +#include "modest-error.h" #include "modest-ui-actions.h" #include "modest-tny-platform-factory.h" @@ -55,6 +55,7 @@ #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" @@ -68,6 +69,7 @@ #include #include #include +#include typedef struct _GetMsgAsyncHelper { ModestWindow *window; @@ -85,19 +87,11 @@ typedef enum _ReplyForwardAction { } ReplyForwardAction; typedef struct _ReplyForwardHelper { -guint reply_forward_type; + guint reply_forward_type; ReplyForwardAction action; gchar *account_name; - guint pending_ops; } ReplyForwardHelper; -typedef struct _HeaderActivatedHelper { - GtkTreeModel *model; - GtkTreeRowReference *row_reference; - TnyFolder *folder; - TnyHeader *header; -} HeaderActivatedHelper; - /* * The do_headers_action uses this kind of functions to perform some * action to each member of a list of headers @@ -110,9 +104,15 @@ do_headers_action (ModestWindow *win, gpointer user_data); -static void open_msg_func (const GObject *obj, const TnyMsg *msg, gpointer user_data); +static void open_msg_cb (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg, + gpointer user_data); -static void reply_forward_func (const GObject *obj, const TnyMsg *msg, gpointer user_data); +static void reply_forward_cb (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg, + gpointer user_data); static void reply_forward (ReplyForwardAction action, ModestWindow *win); @@ -144,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) { @@ -157,17 +164,16 @@ 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 @@ -211,7 +217,7 @@ headers_action_delete (TnyHeader *header, { ModestMailOperation *mail_op = NULL; - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE, G_OBJECT(win)); + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win)); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); @@ -314,7 +320,6 @@ 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. */ @@ -364,6 +369,56 @@ 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: */ + const gchar *active_account_name = modest_window_get_active_account (win); + + /* TODO: Dim the menu item (not in the UI spec)? or show a warning, + * or show the default account? + * If we show the default account then the account name should be shown in + * the window when we show it. */ + if (!active_account_name) { + g_warning ("%s: No account is active.", __FUNCTION__); + return; + } + + 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(), + active_account_name); + + /* 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) { @@ -428,6 +483,7 @@ modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win) /* } */ /* 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); @@ -450,70 +506,72 @@ cleanup: } static void -headers_action_open (TnyHeader *header, - ModestWindow *win, - gpointer user_data) -{ - modest_ui_actions_on_header_activated (MODEST_HEADER_VIEW (user_data), - header, - MODEST_MAIN_WINDOW (win)); -} - -void -modest_ui_actions_on_open (GtkAction *action, ModestWindow *win) -{ - GtkWidget *header_view; - - /* Get header view */ - header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), - MODEST_WIDGET_TYPE_HEADER_VIEW); - - /* Open each message */ - do_headers_action (win, headers_action_open, header_view); -} - - -static void -open_msg_func (const GObject *obj, const TnyMsg *msg, gpointer user_data) +open_msg_cb (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg, + gpointer user_data) { ModestWindowMgr *mgr = NULL; ModestWindow *parent_win = NULL; ModestWindow *win = NULL; - HeaderActivatedHelper *helper = NULL; TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN; gchar *account = NULL; + TnyFolder *folder; - g_return_if_fail (MODEST_IS_WINDOW(obj)); - g_return_if_fail (user_data != NULL); - /* TODO: Show an error? (review the specs) */ if (!msg) return; - parent_win = MODEST_WINDOW(obj); - helper = (HeaderActivatedHelper *) user_data; + 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 (helper->header, MODEST_WINDOW(parent_win), NULL); + 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))); + 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 foldert type (OUTBOX headers will be opened in edit window */ - if (modest_tny_folder_is_local_folder (helper->folder)) - folder_type = modest_tny_folder_get_local_folder_type (helper->folder); + /* 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); - switch (folder_type) { - case TNY_FOLDER_TYPE_DRAFTS: - win = modest_msg_edit_window_new ((TnyMsg *) msg, account); - break; - default: - if (helper->model != NULL) - win = modest_msg_view_window_new_with_header_model ((TnyMsg *) msg, account, helper->model, helper->row_reference); - else - win = modest_msg_view_window_new ((TnyMsg *) msg, account); + /* 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 */ @@ -526,15 +584,108 @@ open_msg_func (const GObject *obj, const TnyMsg *msg, gpointer user_data) /* Free */ g_free(account); -/* g_object_unref (G_OBJECT(msg)); */ - g_object_unref (G_OBJECT(helper->folder)); - g_object_unref (G_OBJECT(helper->header)); - gtk_tree_row_reference_free (helper->row_reference); - g_slice_free (HeaderActivatedHelper, helper); + g_object_unref (msg); + g_object_unref (folder); + g_object_unref (header); +} + +/* + * This function is the error handler of the + * modest_mail_operation_get_msgs_full operation + */ +static void +modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op, + gpointer user_data) +{ + const GError *error; + + error = modest_mail_operation_get_error (mail_op); + if (error->code == MODEST_MAIL_OPERATION_ERROR_SIZE_LIMIT) { + GObject *win = modest_mail_operation_get_source (mail_op); + + modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, + error->message); + } +} + +/* + * 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_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, + G_OBJECT (win), + modest_ui_actions_get_msgs_full_error_handler, + NULL); + 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) +{ + 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 -reply_forward_func (const GObject *obj, const TnyMsg *msg, gpointer user_data) +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_cb (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg, + gpointer user_data) { TnyMsg *new_msg; ReplyForwardHelper *rf_helper; @@ -550,8 +701,6 @@ reply_forward_func (const GObject *obj, const TnyMsg *msg, gpointer user_data) g_return_if_fail (user_data != NULL); rf_helper = (ReplyForwardHelper *) user_data; - rf_helper->pending_ops--; - 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(), @@ -566,19 +715,19 @@ reply_forward_func (const GObject *obj, const TnyMsg *msg, gpointer user_data) switch (rf_helper->action) { case ACTION_REPLY: new_msg = - modest_tny_msg_create_reply_msg ((TnyMsg *) msg, from, signature, + 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 ((TnyMsg *) msg, from, signature, 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 ((TnyMsg *) msg, from, signature, 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: @@ -607,7 +756,7 @@ reply_forward_func (const GObject *obj, const TnyMsg *msg, gpointer user_data) goto cleanup; } - tny_folder_add_msg (folder, (TnyMsg *) msg, &err); + tny_folder_add_msg (folder, msg, &err); if (err) { g_printerr ("modest: error adding msg to Drafts folder: %s", err->message); @@ -630,12 +779,56 @@ cleanup: g_object_unref (G_OBJECT (folder)); if (account) g_object_unref (G_OBJECT (account)); - - if (rf_helper->pending_ops == 0) { - g_free (rf_helper->account_name); - g_slice_free (ReplyForwardHelper, rf_helper); + g_object_unref (msg); + g_object_unref (header); +} + +/* + * Checks a list of headers. If any of them are not currently + * downloaded (CACHED) then it asks the user for permission to + * download them. + * + * Returns FALSE if the user does not want to download the + * messages. Returns TRUE if the user allowed the download or if all + * of them are currently downloaded + */ +static gboolean +download_uncached_messages (TnyList *header_list, GtkWindow *win) +{ + TnyIterator *iter; + gboolean found, retval; + + iter = tny_list_create_iterator (header_list); + found = FALSE; + 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); + /* TODO: is this the right flag?, it seems that some + headers that have been previously downloaded do not + come with it */ + found = !(flags & TNY_HEADER_FLAG_CACHED); + g_object_unref (header); + tny_iterator_next (iter); + } + g_object_unref (iter); + + /* Ask for user permission to download the messages */ + retval = TRUE; + if (found) { + GtkResponseType response; + response = + modest_platform_run_confirmation_dialog (GTK_WINDOW (win), + _("mcen_nc_get_multi_msg_txt")); + if (response == GTK_RESPONSE_CANCEL) + retval = FALSE; } + return retval; } + + /* * Common code for the reply and forward actions */ @@ -646,16 +839,25 @@ reply_forward (ReplyForwardAction action, ModestWindow *win) TnyList *header_list = NULL; ReplyForwardHelper *rf_helper = NULL; guint reply_forward_type; + gboolean continue_download; g_return_if_fail (MODEST_IS_WINDOW(win)); header_list = get_selected_headers (win); if (!header_list) return; + + /* Check that the messages have been previously downloaded */ + continue_download = download_uncached_messages (header_list, GTK_WINDOW (win)); + if (!continue_download) { + g_object_unref (header_list); + return; + } - reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (), - (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE, - NULL); + reply_forward_type = + modest_conf_get_int (modest_runtime_get_conf (), + (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE, + NULL); /* We assume that we can only select messages of the same folder and that we reply all of them from the same account. In fact the interface currently only @@ -665,7 +867,6 @@ 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->pending_ops = tny_list_get_length (header_list); rf_helper->account_name = g_strdup (modest_window_get_active_account (win)); if (!rf_helper->account_name) rf_helper->account_name = @@ -673,21 +874,39 @@ reply_forward (ReplyForwardAction action, ModestWindow *win) 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 (G_OBJECT(win), msg, rf_helper); + reply_forward_cb (NULL, header, msg, rf_helper); } else { - - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win)); + /* Retrieve messages */ + mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, + G_OBJECT(win), + modest_ui_actions_get_msgs_full_error_handler, + NULL); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); - modest_mail_operation_process_msg (mail_op, header_list, reply_forward_func, rf_helper); + modest_mail_operation_get_msgs_full (mail_op, + header_list, + reply_forward_cb, + rf_helper, + free_reply_forward_helper); /* Clean */ g_object_unref(mail_op); } + + /* Free */ + g_object_unref (header_list); } void @@ -773,41 +992,20 @@ modest_ui_actions_on_sort (GtkAction *action, } } -/** Check that an appropriate connection is open. - */ -gboolean check_for_connection (const gchar *account_name) -{ - TnyDevice *device = modest_runtime_get_device (); - -/* - 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; - } -} - /* * 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 + * window is used to create the mail operation. Typically it should + * always be 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) { gchar *acc_name = NULL; + ModestMailOperation *mail_op; - /* If no account name was provided get the current account, if - there is none either then pick the default one */ + /* If no account name was provided then get the current account, and if + there is no current account then pick the default one: */ if (!account_name) { acc_name = g_strdup (modest_window_get_active_account(win)); if (!acc_name) @@ -820,23 +1018,18 @@ modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win) acc_name = g_strdup (account_name); } - /* Send & receive. Do not continue if no suitable connection - is open */ - if (check_for_connection (acc_name)) { - /* 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 */ - /* 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, acc_name); - g_object_unref (G_OBJECT (mail_op)); - } + /* Send & receive. */ + /* TODO: The spec wants us to first do any pending deletions, before receiving. */ + /* Receive and then send. The operation is tagged initially as + a receive operation because the account update performs a + receive and then a send. The operation changes its type + internally, so the progress objects will receive the proper + progress information */ + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win)); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); + modest_mail_operation_update_account (mail_op, acc_name); + g_object_unref (G_OBJECT (mail_op)); + /* Free */ g_free (acc_name); } @@ -943,68 +1136,36 @@ modest_ui_actions_on_header_activated (ModestHeaderView *header_view, TnyHeader *header, ModestMainWindow *main_window) { - ModestMailOperation *mail_op = NULL; - HeaderActivatedHelper *helper = NULL; - ModestWindowMgr *mgr = NULL; - ModestWindow *win = NULL; - GtkTreeModel *model = NULL; - GtkTreeSelection *sel = NULL; - GList *sel_list = NULL; - + TnyList *headers; + g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); if (!header) return; - /* 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 (win) return; - - /* Build helper */ - helper = g_slice_new0 (HeaderActivatedHelper); - helper->folder = tny_header_get_folder (header); - helper->header = g_object_ref(header); - helper->model = NULL; - - /* Get headers tree model and selected row reference to build message 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) { - - /* Fill helpers */ - helper->model = model; - helper->row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data); + headers = tny_simple_list_new (); + tny_list_prepend (headers, G_OBJECT (header)); - g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL); - g_list_free (sel_list); - } + _modest_ui_actions_open (headers, MODEST_WINDOW (main_window)); - /* New mail operation */ - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(main_window)); - modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); - modest_mail_operation_get_msg (mail_op, header, open_msg_func, helper); - - /* Free */ - g_object_unref (mail_op); + g_object_unref (headers); } static void set_active_account_from_tny_account (TnyAccount *account, ModestWindow *window) { - TnyAccount *modest_server_account; - const gchar *server_acc_name; - gchar *modest_acc_name; - - server_acc_name = tny_account_get_id (account); + const gchar *server_acc_name = tny_account_get_id (account); + /* We need the TnyAccount provided by the account store because that is the one that knows the name of the Modest account */ - modest_server_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); - modest_acc_name = (gchar *) g_object_get_data (G_OBJECT (modest_server_account), "modest_account"); + + const gchar *modest_acc_name = + modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account); modest_window_set_active_account (window, modest_acc_name); g_object_unref (modest_server_account); } @@ -1017,7 +1178,6 @@ modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view, { ModestConf *conf; GtkWidget *header_view; - TnyAccount *account; g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); @@ -1028,14 +1188,24 @@ modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view, conf = modest_runtime_get_conf (); - if (TNY_IS_FOLDER (folder_store)) { - - if (selected) { - /* Update the active account */ - account = tny_folder_get_account (TNY_FOLDER (folder_store)); - set_active_account_from_tny_account (account, MODEST_WINDOW (main_window)); - g_object_unref (account); - + 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 )) { + //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); @@ -1050,11 +1220,6 @@ modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view, 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)) { - /* 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); } } @@ -1180,7 +1345,7 @@ modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edi 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)); + mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_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, @@ -1205,50 +1370,47 @@ modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edi /* 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) { - 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)); if (!modest_msg_edit_window_check_names (edit_window)) return; - data = modest_msg_edit_window_get_msg_data (edit_window); - /* FIXME: Code added just for testing. The final version will use the send queue provided by tinymail and some classifier */ - account_mgr = modest_runtime_get_account_mgr(); - account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window))); + ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr(); + gchar *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 = + + /* Get the currently-active transport account for this modest account: */ + TnyTransportAccount *transport_account = TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(), account_name)); 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); + + gchar *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_SEND, G_OBJECT(edit_window)); + /* Create the mail operation */ + ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window)); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation); + MsgData *data = modest_msg_edit_window_get_msg_data (edit_window); modest_mail_operation_send_new_mail (mail_operation, transport_account, from, @@ -1260,7 +1422,8 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window) data->html_body, data->attachments, data->priority_flags); - /* Frees */ + + /* Free data: */ g_free (from); g_free (account_name); g_object_unref (G_OBJECT (transport_account)); @@ -1268,7 +1431,7 @@ modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window) modest_msg_edit_window_free_msg_data (edit_window, data); - /* Save settings and close the window */ + /* Save settings and close the window: */ gtk_widget_destroy (GTK_WIDGET (edit_window)); } @@ -1487,7 +1650,7 @@ modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_windo if (result == GTK_RESPONSE_REJECT) { finished = TRUE; } else { - ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(main_window)); + ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window)); TnyFolder *new_folder = NULL; modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), @@ -1523,14 +1686,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)) { @@ -1541,10 +1711,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 (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(main_window)); + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_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); @@ -1557,6 +1729,16 @@ modest_ui_actions_on_rename_folder (GtkAction *action, } static void +modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op, + gpointer user_data) +{ + GObject *win = modest_mail_operation_get_source (mail_op); + + modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, + _("mail_in_ui_folder_delete_error")); +} + +static void delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) { TnyFolderStore *folder; @@ -1588,17 +1770,15 @@ delete_folder (ModestMainWindow *main_window, gboolean move_to_trash) g_free (message); if (response == GTK_RESPONSE_OK) { - ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE, G_OBJECT(main_window)); + ModestMailOperation *mail_op = + modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE, + G_OBJECT(main_window), + modest_ui_actions_delete_folder_error_handler, + NULL); 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)); } @@ -1634,6 +1814,13 @@ modest_ui_actions_on_password_requested (TnyAccountStore *account_store, 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 (). @@ -1789,6 +1976,8 @@ modest_ui_actions_on_password_requested (TnyAccountStore *account_store, */ gtk_widget_destroy (dialog); + + printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); } void @@ -2050,21 +2239,23 @@ modest_ui_actions_on_details (GtkAction *action, TnyMsg *msg; msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win)); - if (!msg) { + if (!msg) return; - } else { - headers_list = get_selected_headers (win); - if (!headers_list) - return; + g_object_unref (msg); - iter = tny_list_create_iterator (headers_list); + headers_list = get_selected_headers (win); + if (!headers_list) + return; - header = TNY_HEADER (tny_iterator_get_current (iter)); - headers_action_show_details (header, win, NULL); - g_object_unref (header); + 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); - g_object_unref (iter); - } } else if (MODEST_IS_MAIN_WINDOW (win)) { GtkWidget *folder_view, *header_view; @@ -2294,6 +2485,7 @@ msgs_move_to_confirmation (GtkWindow *win, response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win), (const gchar *) message); } + g_object_unref (src_folder); } return response; } @@ -2312,6 +2504,17 @@ tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data) g_return_if_fail (found); } +void +modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op, + gpointer user_data) +{ + GObject *win = modest_mail_operation_get_source (mail_op); + + /* TODO: show error message */ + modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, + _("mail_in_ui_folder_move_target_error")); +} + /* * UI handler for the "Move to" action when invoked from the * ModestMainWindow @@ -2320,9 +2523,10 @@ static void modest_ui_actions_on_main_window_move_to (GtkAction *action, ModestMainWindow *win) { - GtkWidget *dialog, *folder_view, *tree_view = NULL; + GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL; + GtkWidget *header_view = NULL; gint result; - TnyFolderStore *folder_store; + TnyFolderStore *folder_store = NULL; ModestMailOperation *mail_op = NULL; g_return_if_fail (MODEST_IS_MAIN_WINDOW (win)); @@ -2331,6 +2535,10 @@ modest_ui_actions_on_main_window_move_to (GtkAction *action, 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)); @@ -2350,24 +2558,28 @@ modest_ui_actions_on_main_window_move_to (GtkAction *action, TnyFolderStore *src_folder; src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)); - if (TNY_IS_FOLDER (src_folder)) { - 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); + /* Clean folder on header view before moving it */ + modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL); - modest_mail_operation_xfer_folder_async (mail_op, - TNY_FOLDER (src_folder), - folder_store, - TRUE); + if (TNY_IS_FOLDER (src_folder)) { + mail_op = + modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, + G_OBJECT(win), + modest_ui_actions_move_folder_error_handler, + NULL); + 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); + /* Unref mail operation */ g_object_unref (G_OBJECT (mail_op)); } /* Frees */ g_object_unref (G_OBJECT (src_folder)); } else { - GtkWidget *header_view; - header_view = modest_main_window_get_child_widget (win, - MODEST_WIDGET_TYPE_HEADER_VIEW); if (gtk_widget_is_focus (header_view)) { TnyList *headers; gint response; @@ -2381,7 +2593,7 @@ modest_ui_actions_on_main_window_move_to (GtkAction *action, /* Transfer messages */ if (response == GTK_RESPONSE_OK) { - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win)); + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win)); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); @@ -2391,13 +2603,13 @@ modest_ui_actions_on_main_window_move_to (GtkAction *action, TRUE, NULL, NULL); + g_object_unref (G_OBJECT (mail_op)); } g_object_unref (headers); } } g_object_unref (folder_store); - end: gtk_widget_destroy (dialog); } @@ -2449,7 +2661,7 @@ modest_ui_actions_on_msg_view_window_move_to (GtkAction *action, ModestMailOperation *mail_op; /* Create mail op */ - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win)); + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win)); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); @@ -2511,6 +2723,7 @@ do_headers_action (ModestWindow *win, tny_iterator_next (iter); } g_object_unref (iter); + g_object_unref (headers_list); } void @@ -2563,3 +2776,78 @@ modest_ui_actions_on_settings (GtkAction *action, 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_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE, + G_OBJECT (window), + modest_ui_actions_get_msgs_full_error_handler, + NULL); + 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); +} + +void +modest_ui_actions_on_email_menu_activated (GtkAction *action, + ModestWindow *window) +{ + g_return_if_fail (MODEST_IS_WINDOW (window)); + + /* Update dimmed */ + modest_window_check_dimming_rules (window); +} + +void +modest_ui_actions_on_edit_menu_activated (GtkAction *action, + ModestWindow *window) +{ + g_return_if_fail (MODEST_IS_WINDOW (window)); + + /* Update dimmed */ + modest_window_check_dimming_rules (window); +} + +void +modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action, + ModestWindow *window) +{ + g_return_if_fail (MODEST_IS_WINDOW (window)); + + /* Update dimmed */ + modest_window_check_dimming_rules (window); +} + +void +modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action, + ModestWindow *window) +{ + g_return_if_fail (MODEST_IS_WINDOW (window)); + + /* Update dimmed */ + modest_window_check_dimming_rules (window); +} + +void +modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action, + ModestWindow *window) +{ + g_return_if_fail (MODEST_IS_WINDOW (window)); + + /* Update dimmed */ + modest_window_check_dimming_rules (window); +}