1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
44 #include "modest-tny-platform-factory.h"
45 #include "modest-platform.h"
46 #include "modest-debug.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
51 #ifdef MODEST_TOOLKIT_HILDON2
52 #include <modest-accounts-window.h>
53 #include <hildon/hildon-pannable-area.h>
54 #include <hildon/hildon-gtk.h>
55 #include <modest-header-window.h>
58 #ifdef MODEST_PLATFORM_MAEMO
59 #include "maemo/modest-osso-state-saving.h"
60 #endif /* MODEST_PLATFORM_MAEMO */
61 #ifndef MODEST_TOOLKIT_GTK
62 #include "maemo/modest-hildon-includes.h"
63 #include "maemo/modest-connection-specific-smtp-window.h"
64 #endif /* !MODEST_TOOLKIT_GTK */
65 #include <modest-utils.h>
67 #include "widgets/modest-ui-constants.h"
68 #include <widgets/modest-main-window.h>
69 #include <widgets/modest-msg-view-window.h>
70 #include <widgets/modest-account-view-window.h>
71 #include <widgets/modest-details-dialog.h>
72 #include <widgets/modest-attachments-view.h>
73 #include "widgets/modest-folder-view.h"
74 #include "widgets/modest-global-settings-dialog.h"
75 #include "modest-account-mgr-helpers.h"
76 #include "modest-mail-operation.h"
77 #include "modest-text-utils.h"
78 #include <modest-widget-memory.h>
79 #include <tny-error.h>
80 #include <tny-simple-list.h>
81 #include <tny-msg-view.h>
82 #include <tny-device.h>
83 #include <tny-merge-folder.h>
85 #include <gtkhtml/gtkhtml.h>
87 #define MIN_FREE_SPACE 5 * 1024 * 1024
88 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
90 typedef struct _GetMsgAsyncHelper {
92 ModestMailOperation *mail_op;
99 typedef enum _ReplyForwardAction {
103 } ReplyForwardAction;
105 typedef struct _ReplyForwardHelper {
106 guint reply_forward_type;
107 ReplyForwardAction action;
109 GtkWidget *parent_window;
111 } ReplyForwardHelper;
113 typedef struct _MoveToHelper {
114 GtkTreeRowReference *reference;
118 typedef struct _PasteAsAttachmentHelper {
119 ModestMsgEditWindow *window;
121 } PasteAsAttachmentHelper;
129 * The do_headers_action uses this kind of functions to perform some
130 * action to each member of a list of headers
132 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
134 static void do_headers_action (ModestWindow *win,
138 static void open_msg_cb (ModestMailOperation *mail_op,
145 static void reply_forward_cb (ModestMailOperation *mail_op,
152 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
154 static void folder_refreshed_cb (ModestMailOperation *mail_op,
158 static void on_send_receive_finished (ModestMailOperation *mail_op,
161 static gint header_list_count_uncached_msgs (TnyList *header_list);
163 static gboolean connect_to_get_msg (ModestWindow *win,
164 gint num_of_uncached_msgs,
165 TnyAccount *account);
167 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
169 static void do_create_folder (GtkWindow *window,
170 TnyFolderStore *parent_folder,
171 const gchar *suggested_name);
173 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
175 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
176 GtkWidget *folder_view,
177 TnyFolderStore *dst_folder,
178 ModestMainWindow *win);
180 static void modest_ui_actions_on_window_move_to (GtkAction *action,
181 TnyList *list_to_move,
182 TnyFolderStore *dst_folder,
186 * This function checks whether a TnyFolderStore is a pop account
189 remote_folder_has_leave_on_server (TnyFolderStore *folder)
194 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
196 account = get_account_from_folder_store (folder);
197 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
198 modest_tny_account_get_protocol_type (account)));
199 g_object_unref (account);
204 /* FIXME: this should be merged with the similar code in modest-account-view-window */
205 /* Show the account creation wizard dialog.
206 * returns: TRUE if an account was created. FALSE if the user cancelled.
209 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
211 gboolean result = FALSE;
213 gint dialog_response;
215 /* there is no such wizard yet */
216 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
217 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
219 /* always present a main window in the background
220 * we do it here, so we cannot end up with two wizards (as this
221 * function might be called in modest_window_mgr_get_main_window as well */
223 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
224 TRUE); /* create if not existent */
226 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
228 /* make sure the mainwindow is visible. We need to present the
229 wizard again to give it the focus back. show_all are needed
230 in order to get the widgets properly drawn (MainWindow main
231 paned won't be in its right position and the dialog will be
233 #ifndef MODEST_TOOLKIT_HILDON2
234 gtk_widget_show_all (GTK_WIDGET (win));
235 gtk_widget_show_all (GTK_WIDGET (wizard));
236 gtk_window_present (GTK_WINDOW (win));
237 gtk_window_present (GTK_WINDOW (wizard));
240 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
241 gtk_widget_destroy (GTK_WIDGET (wizard));
242 if (gtk_events_pending ())
243 gtk_main_iteration ();
245 if (dialog_response == GTK_RESPONSE_CANCEL) {
248 /* Check whether an account was created: */
249 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
256 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
259 const gchar *authors[] = {
260 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
263 about = gtk_about_dialog_new ();
264 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
265 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
266 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
267 _("Copyright (c) 2006, Nokia Corporation\n"
268 "All rights reserved."));
269 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
270 _("a modest e-mail client\n\n"
271 "design and implementation: Dirk-Jan C. Binnema\n"
272 "contributions from the fine people at KC and Ig\n"
273 "uses the tinymail email framework written by Philip van Hoof"));
274 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
275 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
276 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
277 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
279 gtk_dialog_run (GTK_DIALOG (about));
280 gtk_widget_destroy(about);
284 * Gets the list of currently selected messages. If the win is the
285 * main window, then it returns a newly allocated list of the headers
286 * selected in the header view. If win is the msg view window, then
287 * the value returned is a list with just a single header.
289 * The caller of this funcion must free the list.
292 get_selected_headers (ModestWindow *win)
294 if (MODEST_IS_MAIN_WINDOW(win)) {
295 GtkWidget *header_view;
297 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
298 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
299 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
301 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
302 /* for MsgViewWindows, we simply return a list with one element */
304 TnyList *list = NULL;
306 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
307 if (header != NULL) {
308 list = tny_simple_list_new ();
309 tny_list_prepend (list, G_OBJECT(header));
310 g_object_unref (G_OBJECT(header));
315 #ifdef MODEST_TOOLKIT_HILDON2
316 } else if (MODEST_IS_HEADER_WINDOW (win)) {
317 GtkWidget *header_view;
319 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
320 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
326 static GtkTreeRowReference *
327 get_next_after_selected_headers (ModestHeaderView *header_view)
329 GtkTreeSelection *sel;
330 GList *selected_rows, *node;
332 GtkTreeRowReference *result;
335 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
336 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
337 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
339 if (selected_rows == NULL)
342 node = g_list_last (selected_rows);
343 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
344 gtk_tree_path_next (path);
346 result = gtk_tree_row_reference_new (model, path);
348 gtk_tree_path_free (path);
349 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
350 g_list_free (selected_rows);
356 headers_action_mark_as_read (TnyHeader *header,
360 TnyHeaderFlags flags;
362 g_return_if_fail (TNY_IS_HEADER(header));
364 flags = tny_header_get_flags (header);
365 if (flags & TNY_HEADER_FLAG_SEEN) return;
366 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
370 headers_action_mark_as_unread (TnyHeader *header,
374 TnyHeaderFlags flags;
376 g_return_if_fail (TNY_IS_HEADER(header));
378 flags = tny_header_get_flags (header);
379 if (flags & TNY_HEADER_FLAG_SEEN) {
380 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
384 /** After deleing a message that is currently visible in a window,
385 * show the next message from the list, or close the window if there are no more messages.
388 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
390 /* Close msg view window or select next */
391 if (!modest_msg_view_window_select_next_message (win) &&
392 !modest_msg_view_window_select_previous_message (win)) {
394 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
400 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
402 modest_ui_actions_on_edit_mode_delete_message (win);
406 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
408 TnyList *header_list = NULL;
409 TnyIterator *iter = NULL;
410 TnyHeader *header = NULL;
411 gchar *message = NULL;
414 ModestWindowMgr *mgr;
415 GtkWidget *header_view = NULL;
416 gboolean retval = TRUE;
418 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
420 /* Check first if the header view has the focus */
421 if (MODEST_IS_MAIN_WINDOW (win)) {
423 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
424 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
425 if (!gtk_widget_is_focus (header_view))
429 /* Get the headers, either from the header view (if win is the main window),
430 * or from the message view window: */
431 header_list = get_selected_headers (win);
432 if (!header_list) return FALSE;
434 /* Check if any of the headers are already opened, or in the process of being opened */
435 if (MODEST_IS_MAIN_WINDOW (win)) {
436 gint opened_headers = 0;
438 iter = tny_list_create_iterator (header_list);
439 mgr = modest_runtime_get_window_mgr ();
440 while (!tny_iterator_is_done (iter)) {
441 header = TNY_HEADER (tny_iterator_get_current (iter));
443 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
445 g_object_unref (header);
447 tny_iterator_next (iter);
449 g_object_unref (iter);
451 if (opened_headers > 0) {
454 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
457 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
460 g_object_unref (header_list);
466 if (tny_list_get_length(header_list) == 1) {
467 iter = tny_list_create_iterator (header_list);
468 header = TNY_HEADER (tny_iterator_get_current (iter));
471 subject = tny_header_dup_subject (header);
473 subject = g_strdup (_("mail_va_no_subject"));
474 desc = g_strdup_printf ("%s", subject);
476 g_object_unref (header);
479 g_object_unref (iter);
481 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
482 tny_list_get_length(header_list)), desc);
484 /* Confirmation dialog */
485 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
489 if (response == GTK_RESPONSE_OK) {
490 ModestWindow *main_window = NULL;
491 ModestWindowMgr *mgr = NULL;
492 GtkTreeModel *model = NULL;
493 GtkTreeSelection *sel = NULL;
494 GList *sel_list = NULL, *tmp = NULL;
495 GtkTreeRowReference *next_row_reference = NULL;
496 GtkTreeRowReference *prev_row_reference = NULL;
497 GtkTreePath *next_path = NULL;
498 GtkTreePath *prev_path = NULL;
499 ModestMailOperation *mail_op = NULL;
501 /* Find last selected row */
502 if (MODEST_IS_MAIN_WINDOW (win)) {
503 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
504 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
505 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
506 for (tmp=sel_list; tmp; tmp=tmp->next) {
507 if (tmp->next == NULL) {
508 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
509 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
511 gtk_tree_path_prev (prev_path);
512 gtk_tree_path_next (next_path);
514 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
515 next_row_reference = gtk_tree_row_reference_new (model, next_path);
520 /* Disable window dimming management */
521 modest_window_disable_dimming (MODEST_WINDOW(win));
523 /* Remove each header. If it's a view window header_view == NULL */
524 mail_op = modest_mail_operation_new ((GObject *) win);
525 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
527 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
528 g_object_unref (mail_op);
530 /* Enable window dimming management */
532 gtk_tree_selection_unselect_all (sel);
534 modest_window_enable_dimming (MODEST_WINDOW(win));
536 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
537 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
539 /* Get main window */
540 mgr = modest_runtime_get_window_mgr ();
541 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
542 } else if (MODEST_IS_MAIN_WINDOW (win)) {
543 /* Move cursor to next row */
546 /* Select next or previous row */
547 if (gtk_tree_row_reference_valid (next_row_reference)) {
548 gtk_tree_selection_select_path (sel, next_path);
550 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
551 gtk_tree_selection_select_path (sel, prev_path);
555 if (gtk_tree_row_reference_valid (next_row_reference))
556 gtk_tree_row_reference_free (next_row_reference);
557 if (next_path != NULL)
558 gtk_tree_path_free (next_path);
559 if (gtk_tree_row_reference_valid (prev_row_reference))
560 gtk_tree_row_reference_free (prev_row_reference);
561 if (prev_path != NULL)
562 gtk_tree_path_free (prev_path);
565 /* Update toolbar dimming state */
567 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
568 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
572 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
573 g_list_free (sel_list);
582 g_object_unref (header_list);
590 /* delete either message or folder, based on where we are */
592 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
594 g_return_if_fail (MODEST_IS_WINDOW(win));
596 /* Check first if the header view has the focus */
597 if (MODEST_IS_MAIN_WINDOW (win)) {
599 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
600 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
601 if (gtk_widget_is_focus (w)) {
602 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
606 modest_ui_actions_on_delete_message (action, win);
610 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
612 ModestWindowMgr *mgr = NULL;
614 #ifdef MODEST_PLATFORM_MAEMO
615 modest_osso_save_state();
616 #endif /* MODEST_PLATFORM_MAEMO */
618 g_debug ("closing down, clearing %d item(s) from operation queue",
619 modest_mail_operation_queue_num_elements
620 (modest_runtime_get_mail_operation_queue()));
622 /* cancel all outstanding operations */
623 modest_mail_operation_queue_cancel_all
624 (modest_runtime_get_mail_operation_queue());
626 g_debug ("queue has been cleared");
629 /* Check if there are opened editing windows */
630 mgr = modest_runtime_get_window_mgr ();
631 modest_window_mgr_close_all_windows (mgr);
633 /* note: when modest-tny-account-store is finalized,
634 it will automatically set all network connections
637 /* gtk_main_quit (); */
641 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
645 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
647 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
648 /* gtk_widget_destroy (GTK_WIDGET (win)); */
649 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
650 /* gboolean ret_value; */
651 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
652 /* } else if (MODEST_IS_WINDOW (win)) { */
653 /* gtk_widget_destroy (GTK_WIDGET (win)); */
655 /* g_return_if_reached (); */
660 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
662 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
664 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
668 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
670 GtkClipboard *clipboard = NULL;
671 gchar *selection = NULL;
673 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
674 selection = gtk_clipboard_wait_for_text (clipboard);
676 /* Question: why is the clipboard being used here?
677 * It doesn't really make a lot of sense. */
681 modest_address_book_add_address (selection);
687 modest_ui_actions_on_accounts (GtkAction *action,
690 /* This is currently only implemented for Maemo */
691 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
692 if (!modest_ui_actions_run_account_setup_wizard (win))
693 g_debug ("%s: wizard was already running", __FUNCTION__);
697 /* Show the list of accounts */
698 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
700 /* The accounts dialog must be modal */
701 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
702 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
707 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
709 /* This is currently only implemented for Maemo,
710 * because it requires an API (libconic) to detect different connection
713 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
715 /* Create the window if necessary: */
716 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
717 modest_connection_specific_smtp_window_fill_with_connections (
718 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
719 modest_runtime_get_account_mgr());
721 /* Show the window: */
722 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
723 GTK_WINDOW (specific_window), (GtkWindow *) win);
724 gtk_widget_show (specific_window);
725 #endif /* !MODEST_TOOLKIT_GTK */
729 modest_ui_actions_compose_msg(ModestWindow *win,
732 const gchar *bcc_str,
733 const gchar *subject_str,
734 const gchar *body_str,
736 gboolean set_as_modified)
738 gchar *account_name = NULL;
740 TnyAccount *account = NULL;
741 TnyFolder *folder = NULL;
742 gchar *from_str = NULL, *signature = NULL, *body = NULL;
743 gboolean use_signature = FALSE;
744 ModestWindow *msg_win = NULL;
745 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
746 ModestTnyAccountStore *store = modest_runtime_get_account_store();
747 GnomeVFSFileSize total_size, allowed_size;
749 /* we check for low-mem */
750 if (modest_platform_check_memory_low (win, TRUE))
753 #ifdef MODEST_TOOLKIT_HILDON2
754 account_name = g_strdup (modest_window_get_active_account(win));
757 account_name = modest_account_mgr_get_default_account(mgr);
760 g_printerr ("modest: no account found\n");
763 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
765 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
768 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
770 g_printerr ("modest: failed to find Drafts folder\n");
773 from_str = modest_account_mgr_get_from_string (mgr, account_name);
775 g_printerr ("modest: failed get from string for '%s'\n", account_name);
779 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
780 if (body_str != NULL) {
781 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
783 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
786 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
788 g_printerr ("modest: failed to create new msg\n");
792 /* Create and register edit window */
793 /* This is destroyed by TODO. */
795 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
796 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
798 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
799 gtk_widget_destroy (GTK_WIDGET (msg_win));
802 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
803 gtk_widget_show_all (GTK_WIDGET (msg_win));
805 while (attachments) {
807 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
808 attachments->data, allowed_size);
810 if (total_size > allowed_size) {
811 g_warning ("%s: total size: %u",
812 __FUNCTION__, (unsigned int)total_size);
815 allowed_size -= total_size;
817 attachments = g_slist_next(attachments);
824 g_free (account_name);
826 g_object_unref (G_OBJECT(account));
828 g_object_unref (G_OBJECT(folder));
830 g_object_unref (G_OBJECT(msg));
834 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
836 /* if there are no accounts yet, just show the wizard */
837 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
838 if (!modest_ui_actions_run_account_setup_wizard (win))
841 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
846 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
850 ModestMailOperationStatus status;
852 /* If there is no message or the operation was not successful */
853 status = modest_mail_operation_get_status (mail_op);
854 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
857 /* If it's a memory low issue, then show a banner */
858 error = modest_mail_operation_get_error (mail_op);
859 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
860 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
861 GObject *source = modest_mail_operation_get_source (mail_op);
862 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
863 dgettext("ke-recv","memr_ib_operation_disabled"),
865 g_object_unref (source);
868 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
869 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
870 gchar *subject, *msg;
871 subject = tny_header_dup_subject (header);
873 subject = g_strdup (_("mail_va_no_subject"));;
874 msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
876 modest_platform_run_information_dialog (NULL, msg, FALSE);
881 /* Remove the header from the preregistered uids */
882 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
900 OpenMsgBannerInfo *banner_info;
901 GtkTreeRowReference *rowref;
905 open_msg_banner_idle (gpointer userdata)
907 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
909 gdk_threads_enter ();
910 banner_info->idle_handler = 0;
911 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
913 g_object_ref (banner_info->banner);
915 gdk_threads_leave ();
922 get_header_view_from_window (ModestWindow *window)
924 GtkWidget *header_view;
926 if (MODEST_IS_MAIN_WINDOW (window)) {
927 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
928 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
929 #ifdef MODEST_TOOLKIT_HILDON2
930 } else if (MODEST_IS_HEADER_WINDOW (window)){
931 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
941 get_info_from_header (TnyHeader *header, gboolean *is_draft)
944 gchar *account = NULL;
945 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
949 folder = tny_header_get_folder (header);
950 /* Gets folder type (OUTBOX headers will be opened in edit window */
951 if (modest_tny_folder_is_local_folder (folder)) {
952 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
953 if (folder_type == TNY_FOLDER_TYPE_INVALID)
954 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
957 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
958 TnyTransportAccount *traccount = NULL;
959 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
960 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
962 ModestTnySendQueue *send_queue = NULL;
963 ModestTnySendQueueStatus status;
965 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
966 TNY_ACCOUNT(traccount)));
967 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
968 if (TNY_IS_SEND_QUEUE (send_queue)) {
969 msg_id = modest_tny_send_queue_get_msg_id (header);
970 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
972 /* Only open messages in outbox with the editor if they are in Failed state */
973 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
976 #ifdef MODEST_TOOLKIT_HILDON2
978 /* In Fremantle we can not
979 open any message from
980 outbox which is not in
982 g_object_unref(traccount);
986 g_object_unref(traccount);
988 g_warning("Cannot get transport account for message in outbox!!");
990 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
991 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
994 g_object_unref (folder);
1000 open_msg_cb (ModestMailOperation *mail_op,
1007 ModestWindowMgr *mgr = NULL;
1008 ModestWindow *parent_win = NULL;
1009 ModestWindow *win = NULL;
1010 gchar *account = NULL;
1011 gboolean open_in_editor = FALSE;
1012 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1014 /* Do nothing if there was any problem with the mail
1015 operation. The error will be shown by the error_handler of
1016 the mail operation */
1017 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1020 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1022 /* Mark header as read */
1023 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1025 account = get_info_from_header (header, &open_in_editor);
1029 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1031 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1033 if (open_in_editor) {
1034 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1035 gchar *from_header = NULL, *acc_name;
1037 from_header = tny_header_dup_from (header);
1039 /* we cannot edit without a valid account... */
1040 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1041 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1042 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1044 g_free (from_header);
1049 acc_name = modest_utils_get_account_name_from_recipient (from_header);
1050 g_free (from_header);
1056 win = modest_msg_edit_window_new (msg, account, TRUE);
1058 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1060 if (helper->rowref && helper->model) {
1061 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
1062 helper->model, helper->rowref);
1064 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1069 /* Register and show new window */
1071 mgr = modest_runtime_get_window_mgr ();
1072 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1073 gtk_widget_destroy (GTK_WIDGET (win));
1076 gtk_widget_show_all (GTK_WIDGET(win));
1079 /* Update toolbar dimming state */
1080 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1081 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1087 g_object_unref (parent_win);
1091 is_memory_full_error (GError *error)
1093 gboolean enough_free_space = TRUE;
1094 GnomeVFSURI *cache_dir_uri;
1095 const gchar *cache_dir;
1096 GnomeVFSFileSize free_space;
1098 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1099 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1100 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1101 if (free_space < MIN_FREE_SPACE)
1102 enough_free_space = FALSE;
1104 gnome_vfs_uri_unref (cache_dir_uri);
1106 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1107 /* When asking for a mail and no space left on device
1108 tinymail returns this error */
1109 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1110 /* When the folder summary could not be read or
1112 error->code == TNY_IO_ERROR_WRITE ||
1113 error->code == TNY_IO_ERROR_READ) &&
1114 !enough_free_space) {
1122 check_memory_full_error (GtkWidget *parent_window, GError *err)
1127 if (is_memory_full_error (err))
1128 modest_platform_information_banner (parent_window,
1129 NULL, dgettext("ke-recv",
1130 "cerm_device_memory_full"));
1131 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1132 /* If the account was created in memory full
1133 conditions then tinymail won't be able to
1134 connect so it'll return this error code */
1135 modest_platform_information_banner (parent_window,
1136 NULL, _("emev_ui_imap_inbox_select_error"));
1144 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1147 const GError *error;
1148 GObject *win = NULL;
1149 ModestMailOperationStatus status;
1151 win = modest_mail_operation_get_source (mail_op);
1152 error = modest_mail_operation_get_error (mail_op);
1153 status = modest_mail_operation_get_status (mail_op);
1155 /* If the mail op has been cancelled then it's not an error:
1156 don't show any message */
1157 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1158 if (is_memory_full_error ((GError *) error)) {
1159 modest_platform_information_banner ((GtkWidget *) win,
1160 NULL, dgettext("ke-recv",
1161 "cerm_device_memory_full"));
1162 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1163 modest_platform_information_banner ((GtkWidget *) win,
1164 NULL, _("emev_ui_imap_inbox_select_error"));
1165 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1166 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1167 modest_platform_information_banner ((GtkWidget *) win,
1168 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1169 } else if (user_data) {
1170 modest_platform_information_banner ((GtkWidget *) win,
1176 g_object_unref (win);
1180 * Returns the account a list of headers belongs to. It returns a
1181 * *new* reference so don't forget to unref it
1184 get_account_from_header_list (TnyList *headers)
1186 TnyAccount *account = NULL;
1188 if (tny_list_get_length (headers) > 0) {
1189 TnyIterator *iter = tny_list_create_iterator (headers);
1190 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1191 TnyFolder *folder = tny_header_get_folder (header);
1194 g_object_unref (header);
1196 while (!tny_iterator_is_done (iter)) {
1197 header = TNY_HEADER (tny_iterator_get_current (iter));
1198 folder = tny_header_get_folder (header);
1201 g_object_unref (header);
1203 tny_iterator_next (iter);
1208 account = tny_folder_get_account (folder);
1209 g_object_unref (folder);
1213 g_object_unref (header);
1215 g_object_unref (iter);
1221 get_account_from_header (TnyHeader *header)
1223 TnyAccount *account = NULL;
1226 folder = tny_header_get_folder (header);
1229 account = tny_folder_get_account (folder);
1230 g_object_unref (folder);
1237 open_msg_helper_destroyer (gpointer user_data)
1239 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1241 if (helper->banner_info) {
1242 g_free (helper->banner_info->message);
1243 if (helper->banner_info->idle_handler > 0) {
1244 g_source_remove (helper->banner_info->idle_handler);
1245 helper->banner_info->idle_handler = 0;
1247 if (helper->banner_info->banner != NULL) {
1248 gtk_widget_destroy (helper->banner_info->banner);
1249 g_object_unref (helper->banner_info->banner);
1250 helper->banner_info->banner = NULL;
1252 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1253 helper->banner_info = NULL;
1255 g_object_unref (helper->model);
1256 g_object_unref (helper->header);
1257 gtk_tree_row_reference_free (helper->rowref);
1258 g_slice_free (OpenMsgHelper, helper);
1262 open_msg_performer(gboolean canceled,
1264 GtkWindow *parent_window,
1265 TnyAccount *account,
1268 ModestMailOperation *mail_op = NULL;
1270 ModestProtocolType proto;
1271 TnyConnectionStatus status;
1272 gboolean show_open_draft = FALSE;
1273 OpenMsgHelper *helper = NULL;
1275 helper = (OpenMsgHelper *) user_data;
1277 status = tny_account_get_connection_status (account);
1278 if (err || canceled) {
1279 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1280 /* Free the helper */
1281 open_msg_helper_destroyer (helper);
1283 /* In memory full conditions we could get this error here */
1284 check_memory_full_error ((GtkWidget *) parent_window, err);
1289 /* Get the error message depending on the protocol */
1290 proto = modest_tny_account_get_protocol_type (account);
1291 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1292 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1295 ModestProtocol *protocol;
1296 ModestProtocolRegistry *protocol_registry;
1299 protocol_registry = modest_runtime_get_protocol_registry ();
1300 subject = tny_header_dup_subject (helper->header);
1302 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1303 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1307 if (error_msg == NULL) {
1308 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1311 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1313 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1315 TnyFolderType folder_type;
1317 folder = tny_header_get_folder (helper->header);
1318 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1319 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1320 g_object_unref (folder);
1323 #ifdef MODEST_TOOLKIT_HILDON2
1325 gchar *account_name = get_info_from_header (helper->header, &is_draft);
1328 ModestWindow *window;
1329 GtkWidget *header_view;
1332 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1333 uid = modest_tny_folder_get_header_unique_id (helper->header);
1335 window = modest_msg_view_window_new_from_header_view
1336 (MODEST_HEADER_VIEW (header_view), account_name, uid, helper->rowref);
1337 if (window != NULL) {
1338 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1340 gtk_widget_destroy (GTK_WIDGET (window));
1342 gtk_widget_show_all (GTK_WIDGET(window));
1346 g_free (account_name);
1348 open_msg_helper_destroyer (helper);
1351 g_free (account_name);
1353 /* Create the mail operation */
1355 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1356 modest_ui_actions_disk_operations_error_handler,
1358 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1361 if (show_open_draft) {
1362 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1363 #ifdef MODEST_TOOLKIT_HILDON2
1364 helper->banner_info->message = g_strdup (_("mail_me_opening"));
1366 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1368 helper->banner_info->banner = NULL;
1369 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1370 helper->banner_info);
1374 headers = TNY_LIST (tny_simple_list_new ());
1375 tny_list_prepend (headers, G_OBJECT (helper->header));
1376 modest_mail_operation_get_msgs_full (mail_op,
1380 open_msg_helper_destroyer);
1381 g_object_unref (headers);
1386 g_object_unref (mail_op);
1387 g_object_unref (account);
1391 * This function is used by both modest_ui_actions_on_open and
1392 * modest_ui_actions_on_header_activated. This way we always do the
1393 * same when trying to open messages.
1396 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1398 ModestWindowMgr *mgr = NULL;
1399 TnyAccount *account;
1400 gboolean cached = FALSE;
1402 GtkWidget *header_view = NULL;
1403 OpenMsgHelper *helper;
1404 ModestWindow *window;
1406 g_return_if_fail (header != NULL && rowref != NULL);
1408 mgr = modest_runtime_get_window_mgr ();
1411 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1412 if (header_view == NULL)
1415 /* Get the account */
1416 account = get_account_from_header (header);
1421 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1423 /* Do not open again the message and present the
1424 window to the user */
1427 #ifndef MODEST_TOOLKIT_HILDON2
1428 gtk_window_present (GTK_WINDOW (window));
1431 /* the header has been registered already, we don't do
1432 * anything but wait for the window to come up*/
1433 g_debug ("header %p already registered, waiting for window", header);
1438 /* Open each message */
1439 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1441 /* Allways download if we are online. */
1442 if (!tny_device_is_online (modest_runtime_get_device ())) {
1445 /* If ask for user permission to download the messages */
1446 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1447 _("mcen_nc_get_msg"));
1449 /* End if the user does not want to continue */
1450 if (response == GTK_RESPONSE_CANCEL) {
1456 /* We register the window for opening */
1457 modest_window_mgr_register_header (mgr, header, NULL);
1459 /* Create the helper. We need to get a reference to the model
1460 here because it could change while the message is readed
1461 (the user could switch between folders) */
1462 helper = g_slice_new (OpenMsgHelper);
1463 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1464 helper->header = g_object_ref (header);
1465 helper->rowref = gtk_tree_row_reference_copy (rowref);
1466 helper->banner_info = NULL;
1468 /* Connect to the account and perform */
1470 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1471 open_msg_performer, helper);
1473 /* Call directly the performer, do not need to connect */
1474 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1475 g_object_ref (account), helper);
1480 g_object_unref (account);
1484 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1491 /* we check for low-mem; in that case, show a warning, and don't allow
1494 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1498 headers = get_selected_headers (win);
1502 headers_count = tny_list_get_length (headers);
1503 if (headers_count != 1) {
1504 if (headers_count > 1) {
1505 /* Don't allow activation if there are more than one message selected */
1506 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1509 g_object_unref (headers);
1513 iter = tny_list_create_iterator (headers);
1514 header = TNY_HEADER (tny_iterator_get_current (iter));
1515 g_object_unref (iter);
1519 open_msg_from_header (header, NULL, win);
1520 g_object_unref (header);
1523 g_object_unref(headers);
1527 rf_helper_window_closed (gpointer data,
1530 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1532 helper->parent_window = NULL;
1535 static ReplyForwardHelper*
1536 create_reply_forward_helper (ReplyForwardAction action,
1538 guint reply_forward_type,
1541 ReplyForwardHelper *rf_helper = NULL;
1542 const gchar *active_acc = modest_window_get_active_account (win);
1544 rf_helper = g_slice_new0 (ReplyForwardHelper);
1545 rf_helper->reply_forward_type = reply_forward_type;
1546 rf_helper->action = action;
1547 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1548 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1549 rf_helper->account_name = (active_acc) ?
1550 g_strdup (active_acc) :
1551 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1553 /* Note that window could be destroyed just AFTER calling
1554 register_window so we must ensure that this pointer does
1555 not hold invalid references */
1556 if (rf_helper->parent_window)
1557 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1558 rf_helper_window_closed, rf_helper);
1564 free_reply_forward_helper (gpointer data)
1566 ReplyForwardHelper *helper;
1568 helper = (ReplyForwardHelper *) data;
1569 g_free (helper->account_name);
1571 g_object_unref (helper->header);
1572 if (helper->parent_window)
1573 g_object_weak_unref (G_OBJECT (helper->parent_window),
1574 rf_helper_window_closed, helper);
1575 g_slice_free (ReplyForwardHelper, helper);
1579 reply_forward_cb (ModestMailOperation *mail_op,
1586 TnyMsg *new_msg = NULL;
1587 ReplyForwardHelper *rf_helper;
1588 ModestWindow *msg_win = NULL;
1589 ModestEditType edit_type;
1591 TnyAccount *account = NULL;
1592 ModestWindowMgr *mgr = NULL;
1593 gchar *signature = NULL;
1594 gboolean use_signature;
1596 /* If there was any error. The mail operation could be NULL,
1597 this means that we already have the message downloaded and
1598 that we didn't do a mail operation to retrieve it */
1599 rf_helper = (ReplyForwardHelper *) user_data;
1600 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1603 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1604 rf_helper->account_name);
1605 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1606 rf_helper->account_name,
1609 /* Create reply mail */
1610 switch (rf_helper->action) {
1613 modest_tny_msg_create_reply_msg (msg, header, from,
1614 (use_signature) ? signature : NULL,
1615 rf_helper->reply_forward_type,
1616 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1618 case ACTION_REPLY_TO_ALL:
1620 modest_tny_msg_create_reply_msg (msg, header, from,
1621 (use_signature) ? signature : NULL,
1622 rf_helper->reply_forward_type,
1623 MODEST_TNY_MSG_REPLY_MODE_ALL);
1624 edit_type = MODEST_EDIT_TYPE_REPLY;
1626 case ACTION_FORWARD:
1628 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1629 rf_helper->reply_forward_type);
1630 edit_type = MODEST_EDIT_TYPE_FORWARD;
1633 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1635 g_return_if_reached ();
1643 g_warning ("%s: failed to create message\n", __FUNCTION__);
1647 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1648 rf_helper->account_name,
1649 TNY_ACCOUNT_TYPE_STORE);
1651 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1655 /* Create and register the windows */
1656 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1657 mgr = modest_runtime_get_window_mgr ();
1658 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1660 /* Note that register_window could have deleted the account */
1661 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1662 gdouble parent_zoom;
1664 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1665 modest_window_set_zoom (msg_win, parent_zoom);
1668 /* Show edit window */
1669 gtk_widget_show_all (GTK_WIDGET (msg_win));
1672 /* We always unregister the header because the message is
1673 forwarded or replied so the original one is no longer
1675 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1678 g_object_unref (G_OBJECT (new_msg));
1680 g_object_unref (G_OBJECT (account));
1681 free_reply_forward_helper (rf_helper);
1684 /* Checks a list of headers. If any of them are not currently
1685 * downloaded (CACHED) then returns TRUE else returns FALSE.
1688 header_list_count_uncached_msgs (TnyList *header_list)
1691 gint uncached_messages = 0;
1693 iter = tny_list_create_iterator (header_list);
1694 while (!tny_iterator_is_done (iter)) {
1697 header = TNY_HEADER (tny_iterator_get_current (iter));
1699 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1700 uncached_messages ++;
1701 g_object_unref (header);
1704 tny_iterator_next (iter);
1706 g_object_unref (iter);
1708 return uncached_messages;
1711 /* Returns FALSE if the user does not want to download the
1712 * messages. Returns TRUE if the user allowed the download.
1715 connect_to_get_msg (ModestWindow *win,
1716 gint num_of_uncached_msgs,
1717 TnyAccount *account)
1719 GtkResponseType response;
1721 /* Allways download if we are online. */
1722 if (tny_device_is_online (modest_runtime_get_device ()))
1725 /* If offline, then ask for user permission to download the messages */
1726 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1727 ngettext("mcen_nc_get_msg",
1729 num_of_uncached_msgs));
1731 if (response == GTK_RESPONSE_CANCEL)
1734 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1738 reply_forward_performer (gboolean canceled,
1740 GtkWindow *parent_window,
1741 TnyAccount *account,
1744 ReplyForwardHelper *rf_helper = NULL;
1745 ModestMailOperation *mail_op;
1747 rf_helper = (ReplyForwardHelper *) user_data;
1749 if (canceled || err) {
1750 free_reply_forward_helper (rf_helper);
1754 /* Retrieve the message */
1755 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1756 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1757 modest_ui_actions_disk_operations_error_handler,
1759 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1760 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1763 g_object_unref(mail_op);
1767 * Common code for the reply and forward actions
1770 reply_forward (ReplyForwardAction action, ModestWindow *win)
1772 ReplyForwardHelper *rf_helper = NULL;
1773 guint reply_forward_type;
1775 g_return_if_fail (MODEST_IS_WINDOW(win));
1777 /* we check for low-mem; in that case, show a warning, and don't allow
1778 * reply/forward (because it could potentially require a lot of memory */
1779 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1783 /* we need an account when editing */
1784 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1785 if (!modest_ui_actions_run_account_setup_wizard (win))
1789 reply_forward_type =
1790 modest_conf_get_int (modest_runtime_get_conf (),
1791 (action == ACTION_FORWARD) ?
1792 MODEST_CONF_FORWARD_TYPE :
1793 MODEST_CONF_REPLY_TYPE,
1796 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1798 TnyHeader *header = NULL;
1799 /* Get header and message. Do not free them here, the
1800 reply_forward_cb must do it */
1801 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1802 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1804 if (msg && header) {
1806 rf_helper = create_reply_forward_helper (action, win,
1807 reply_forward_type, header);
1808 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1810 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1814 g_object_unref (msg);
1816 g_object_unref (header);
1818 TnyHeader *header = NULL;
1820 gboolean do_retrieve = TRUE;
1821 TnyList *header_list = NULL;
1823 header_list = get_selected_headers (win);
1826 /* Check that only one message is selected for replying */
1827 if (tny_list_get_length (header_list) != 1) {
1828 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1829 NULL, _("mcen_ib_select_one_message"));
1830 g_object_unref (header_list);
1834 /* Only reply/forward to one message */
1835 iter = tny_list_create_iterator (header_list);
1836 header = TNY_HEADER (tny_iterator_get_current (iter));
1837 g_object_unref (iter);
1839 /* Retrieve messages */
1840 do_retrieve = (action == ACTION_FORWARD) ||
1841 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1844 TnyAccount *account = NULL;
1845 TnyFolder *folder = NULL;
1846 gdouble download = TRUE;
1847 guint uncached_msgs = 0;
1849 folder = tny_header_get_folder (header);
1851 goto do_retrieve_frees;
1852 account = tny_folder_get_account (folder);
1854 goto do_retrieve_frees;
1856 uncached_msgs = header_list_count_uncached_msgs (header_list);
1858 if (uncached_msgs > 0) {
1859 /* Allways download if we are online. */
1860 if (!tny_device_is_online (modest_runtime_get_device ())) {
1863 /* If ask for user permission to download the messages */
1864 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1865 ngettext("mcen_nc_get_msg",
1869 /* End if the user does not want to continue */
1870 if (response == GTK_RESPONSE_CANCEL)
1877 rf_helper = create_reply_forward_helper (action, win,
1878 reply_forward_type, header);
1879 if (uncached_msgs > 0) {
1880 modest_platform_connect_and_perform (GTK_WINDOW (win),
1882 reply_forward_performer,
1885 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1886 account, rf_helper);
1891 g_object_unref (account);
1893 g_object_unref (folder);
1895 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1898 g_object_unref (header_list);
1899 g_object_unref (header);
1904 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1906 g_return_if_fail (MODEST_IS_WINDOW(win));
1908 reply_forward (ACTION_REPLY, win);
1912 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1914 g_return_if_fail (MODEST_IS_WINDOW(win));
1916 reply_forward (ACTION_FORWARD, win);
1920 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1922 g_return_if_fail (MODEST_IS_WINDOW(win));
1924 reply_forward (ACTION_REPLY_TO_ALL, win);
1928 modest_ui_actions_on_next (GtkAction *action,
1929 ModestWindow *window)
1931 if (MODEST_IS_MAIN_WINDOW (window)) {
1932 GtkWidget *header_view;
1934 header_view = modest_main_window_get_child_widget (
1935 MODEST_MAIN_WINDOW(window),
1936 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1940 modest_header_view_select_next (
1941 MODEST_HEADER_VIEW(header_view));
1942 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1943 modest_msg_view_window_select_next_message (
1944 MODEST_MSG_VIEW_WINDOW (window));
1946 g_return_if_reached ();
1951 modest_ui_actions_on_prev (GtkAction *action,
1952 ModestWindow *window)
1954 g_return_if_fail (MODEST_IS_WINDOW(window));
1956 if (MODEST_IS_MAIN_WINDOW (window)) {
1957 GtkWidget *header_view;
1958 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1959 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1963 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1964 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1965 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1967 g_return_if_reached ();
1972 modest_ui_actions_on_sort (GtkAction *action,
1973 ModestWindow *window)
1975 GtkWidget *header_view = NULL;
1977 g_return_if_fail (MODEST_IS_WINDOW(window));
1979 if (MODEST_IS_MAIN_WINDOW (window)) {
1980 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1981 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1982 #ifdef MODEST_TOOLKIT_HILDON2
1983 } else if (MODEST_IS_HEADER_WINDOW (window)) {
1984 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1989 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1994 /* Show sorting dialog */
1995 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1999 new_messages_arrived (ModestMailOperation *self,
2000 TnyList *new_headers,
2004 gboolean show_visual_notifications;
2006 source = modest_mail_operation_get_source (self);
2007 show_visual_notifications = (source) ? FALSE : TRUE;
2009 g_object_unref (source);
2011 /* Notify new messages have been downloaded. If the
2012 send&receive was invoked by the user then do not show any
2013 visual notification, only play a sound and activate the LED
2014 (for the Maemo version) */
2015 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
2016 modest_platform_on_new_headers_received (new_headers,
2017 show_visual_notifications);
2022 retrieve_all_messages_cb (GObject *source,
2024 guint retrieve_limit)
2030 window = GTK_WINDOW (source);
2031 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
2032 num_msgs, retrieve_limit);
2034 /* Ask the user if they want to retrieve all the messages */
2036 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2037 _("mcen_bd_get_all"),
2038 _("mcen_bd_newest_only"));
2039 /* Free and return */
2041 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2045 TnyAccount *account;
2047 gchar *account_name;
2048 gboolean poke_status;
2049 gboolean interactive;
2050 ModestMailOperation *mail_op;
2054 do_send_receive_performer (gboolean canceled,
2056 GtkWindow *parent_window,
2057 TnyAccount *account,
2060 SendReceiveInfo *info;
2062 info = (SendReceiveInfo *) user_data;
2064 if (err || canceled) {
2065 /* In memory full conditions we could get this error here */
2066 check_memory_full_error ((GtkWidget *) parent_window, err);
2068 if (info->mail_op) {
2069 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2075 /* Set send/receive operation in progress */
2076 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2077 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2080 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2081 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2082 G_CALLBACK (on_send_receive_finished),
2085 /* Send & receive. */
2086 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2087 (info->win) ? retrieve_all_messages_cb : NULL,
2088 new_messages_arrived, info->win);
2093 g_object_unref (G_OBJECT (info->mail_op));
2094 if (info->account_name)
2095 g_free (info->account_name);
2097 g_object_unref (info->win);
2099 g_object_unref (info->account);
2100 g_slice_free (SendReceiveInfo, info);
2104 * This function performs the send & receive required actions. The
2105 * window is used to create the mail operation. Typically it should
2106 * always be the main window, but we pass it as argument in order to
2110 modest_ui_actions_do_send_receive (const gchar *account_name,
2111 gboolean force_connection,
2112 gboolean poke_status,
2113 gboolean interactive,
2116 gchar *acc_name = NULL;
2117 SendReceiveInfo *info;
2118 ModestTnyAccountStore *acc_store;
2120 /* If no account name was provided then get the current account, and if
2121 there is no current account then pick the default one: */
2122 if (!account_name) {
2124 acc_name = g_strdup (modest_window_get_active_account (win));
2126 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2128 g_printerr ("modest: cannot get default account\n");
2132 acc_name = g_strdup (account_name);
2135 acc_store = modest_runtime_get_account_store ();
2137 /* Create the info for the connect and perform */
2138 info = g_slice_new (SendReceiveInfo);
2139 info->account_name = acc_name;
2140 info->win = (win) ? g_object_ref (win) : NULL;
2141 info->poke_status = poke_status;
2142 info->interactive = interactive;
2143 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2144 TNY_ACCOUNT_TYPE_STORE);
2145 /* We need to create the operation here, because otherwise it
2146 could happen that the queue emits the queue-empty signal
2147 while we're trying to connect the account */
2148 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2149 modest_ui_actions_disk_operations_error_handler,
2151 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2153 /* Invoke the connect and perform */
2154 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2155 force_connection, info->account,
2156 do_send_receive_performer, info);
2161 modest_ui_actions_do_cancel_send (const gchar *account_name,
2164 TnyTransportAccount *transport_account;
2165 TnySendQueue *send_queue = NULL;
2166 GError *error = NULL;
2168 /* Get transport account */
2170 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2171 (modest_runtime_get_account_store(),
2173 TNY_ACCOUNT_TYPE_TRANSPORT));
2174 if (!transport_account) {
2175 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2180 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2181 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2182 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2183 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2184 "modest: could not find send queue for account\n");
2186 /* Cancel the current send */
2187 tny_account_cancel (TNY_ACCOUNT (transport_account));
2189 /* Suspend all pending messages */
2190 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2194 if (transport_account != NULL)
2195 g_object_unref (G_OBJECT (transport_account));
2199 modest_ui_actions_cancel_send_all (ModestWindow *win)
2201 GSList *account_names, *iter;
2203 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2206 iter = account_names;
2208 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2209 iter = g_slist_next (iter);
2212 modest_account_mgr_free_account_names (account_names);
2213 account_names = NULL;
2217 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2220 /* Check if accounts exist */
2221 gboolean accounts_exist =
2222 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2224 /* If not, allow the user to create an account before trying to send/receive. */
2225 if (!accounts_exist)
2226 modest_ui_actions_on_accounts (NULL, win);
2228 /* Cancel all sending operaitons */
2229 modest_ui_actions_cancel_send_all (win);
2233 * Refreshes all accounts. This function will be used by automatic
2237 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2238 gboolean force_connection,
2239 gboolean poke_status,
2240 gboolean interactive)
2242 GSList *account_names, *iter;
2244 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2247 iter = account_names;
2249 modest_ui_actions_do_send_receive ((const char*) iter->data,
2251 poke_status, interactive, win);
2252 iter = g_slist_next (iter);
2255 modest_account_mgr_free_account_names (account_names);
2256 account_names = NULL;
2260 * Handler of the click on Send&Receive button in the main toolbar
2263 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2265 /* Check if accounts exist */
2266 gboolean accounts_exist;
2269 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2271 /* If not, allow the user to create an account before trying to send/receive. */
2272 if (!accounts_exist)
2273 modest_ui_actions_on_accounts (NULL, win);
2275 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2276 if (MODEST_IS_MAIN_WINDOW (win)) {
2277 GtkWidget *folder_view;
2278 TnyFolderStore *folder_store;
2281 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2282 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2286 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2289 g_object_unref (folder_store);
2290 /* Refresh the active account. Force the connection if needed
2291 and poke the status of all folders */
2292 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2293 #ifdef MODEST_TOOLKIT_HILDON2
2294 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2295 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2298 const gchar *active_account;
2299 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2301 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2308 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2311 GtkWidget *header_view;
2313 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2315 header_view = modest_main_window_get_child_widget (main_window,
2316 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2320 conf = modest_runtime_get_conf ();
2322 /* what is saved/restored is depending on the style; thus; we save with
2323 * old style, then update the style, and restore for this new style
2325 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2327 if (modest_header_view_get_style
2328 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2329 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2330 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2332 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2333 MODEST_HEADER_VIEW_STYLE_DETAILS);
2335 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2336 MODEST_CONF_HEADER_VIEW_KEY);
2341 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2343 ModestMainWindow *main_window)
2345 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2346 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2348 /* in the case the folder is empty, show the empty folder message and focus
2350 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2351 if (modest_header_view_is_empty (header_view)) {
2352 TnyFolder *folder = modest_header_view_get_folder (header_view);
2353 GtkWidget *folder_view =
2354 modest_main_window_get_child_widget (main_window,
2355 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2356 if (folder != NULL) {
2357 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2358 g_object_unref (folder);
2360 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2364 /* If no header has been selected then exit */
2369 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2370 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2372 /* Update toolbar dimming state */
2373 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2374 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2378 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2381 ModestWindow *window)
2383 GtkWidget *open_widget;
2384 GtkTreeRowReference *rowref;
2386 g_return_if_fail (MODEST_IS_WINDOW(window));
2387 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2388 g_return_if_fail (TNY_IS_HEADER (header));
2390 if (modest_header_view_count_selected_headers (header_view) > 1) {
2391 /* Don't allow activation if there are more than one message selected */
2392 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2396 /* we check for low-mem; in that case, show a warning, and don't allow
2397 * activating headers
2399 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2402 if (MODEST_IS_MAIN_WINDOW (window)) {
2403 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2404 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2405 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2409 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2410 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2411 gtk_tree_row_reference_free (rowref);
2415 set_active_account_from_tny_account (TnyAccount *account,
2416 ModestWindow *window)
2418 const gchar *server_acc_name = tny_account_get_id (account);
2420 /* We need the TnyAccount provided by the
2421 account store because that is the one that
2422 knows the name of the Modest account */
2423 TnyAccount *modest_server_account = modest_server_account =
2424 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2425 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2427 if (!modest_server_account) {
2428 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2432 /* Update active account, but only if it's not a pseudo-account */
2433 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2434 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2435 const gchar *modest_acc_name =
2436 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2437 if (modest_acc_name)
2438 modest_window_set_active_account (window, modest_acc_name);
2441 g_object_unref (modest_server_account);
2446 folder_refreshed_cb (ModestMailOperation *mail_op,
2450 ModestMainWindow *win = NULL;
2451 GtkWidget *folder_view;
2452 const GError *error;
2454 g_return_if_fail (TNY_IS_FOLDER (folder));
2456 win = MODEST_MAIN_WINDOW (user_data);
2458 /* Check if the operation failed due to memory low conditions */
2459 error = modest_mail_operation_get_error (mail_op);
2460 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2461 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2462 modest_platform_run_information_dialog (GTK_WINDOW (win),
2463 dgettext("ke-recv","memr_ib_operation_disabled"),
2469 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2472 TnyFolderStore *current_folder;
2474 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2475 if (current_folder) {
2476 gboolean different = ((TnyFolderStore *) folder != current_folder);
2477 g_object_unref (current_folder);
2483 /* Check if folder is empty and set headers view contents style */
2484 if (tny_folder_get_all_count (folder) == 0)
2485 modest_main_window_set_contents_style (win,
2486 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2491 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2492 TnyFolderStore *folder_store,
2494 ModestMainWindow *main_window)
2497 GtkWidget *header_view;
2499 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2501 header_view = modest_main_window_get_child_widget(main_window,
2502 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2506 conf = modest_runtime_get_conf ();
2508 if (TNY_IS_ACCOUNT (folder_store)) {
2510 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2512 /* Show account details */
2513 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2516 if (TNY_IS_FOLDER (folder_store) && selected) {
2517 TnyAccount *account;
2518 const gchar *account_name = NULL;
2520 /* Update the active account */
2521 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2523 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2525 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2526 g_object_unref (account);
2530 /* Set the header style by default, it could
2531 be changed later by the refresh callback to
2533 modest_main_window_set_contents_style (main_window,
2534 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2536 /* Set folder on header view. This function
2537 will call tny_folder_refresh_async so we
2538 pass a callback that will be called when
2539 finished. We use that callback to set the
2540 empty view if there are no messages */
2541 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2542 TNY_FOLDER (folder_store),
2544 MODEST_WINDOW (main_window),
2545 folder_refreshed_cb,
2548 /* Restore configuration. We need to do this
2549 *after* the set_folder because the widget
2550 memory asks the header view about its
2552 modest_widget_memory_restore (modest_runtime_get_conf (),
2553 G_OBJECT(header_view),
2554 MODEST_CONF_HEADER_VIEW_KEY);
2556 /* No need to save the header view
2557 configuration for Maemo because it only
2558 saves the sorting stuff and that it's
2559 already being done by the sort
2560 dialog. Remove it when the GNOME version
2561 has the same behaviour */
2562 #ifdef MODEST_TOOLKIT_GTK
2563 if (modest_main_window_get_contents_style (main_window) ==
2564 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2565 modest_widget_memory_save (conf, G_OBJECT (header_view),
2566 MODEST_CONF_HEADER_VIEW_KEY);
2568 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2572 /* Update dimming state */
2573 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2574 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2578 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2585 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2587 online = tny_device_is_online (modest_runtime_get_device());
2590 /* already online -- the item is simply not there... */
2591 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2593 GTK_MESSAGE_WARNING,
2595 _("The %s you selected cannot be found"),
2597 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2598 gtk_dialog_run (GTK_DIALOG(dialog));
2600 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2603 _("mcen_bd_dialog_cancel"),
2604 GTK_RESPONSE_REJECT,
2605 _("mcen_bd_dialog_ok"),
2606 GTK_RESPONSE_ACCEPT,
2608 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2609 "Do you want to get online?"), item);
2610 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2611 gtk_label_new (txt), FALSE, FALSE, 0);
2612 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2615 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2616 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2617 /* TODO: Comment about why is this commented out: */
2618 /* modest_platform_connect_and_wait (); */
2621 gtk_widget_destroy (dialog);
2625 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2628 /* g_message ("%s %s", __FUNCTION__, link); */
2633 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2636 modest_platform_activate_uri (link);
2640 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2643 modest_platform_show_uri_popup (link);
2647 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2650 /* we check for low-mem; in that case, show a warning, and don't allow
2651 * viewing attachments
2653 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2656 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2660 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2661 const gchar *address,
2664 /* g_message ("%s %s", __FUNCTION__, address); */
2668 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2669 TnyMsg *saved_draft,
2672 ModestMsgEditWindow *edit_window;
2674 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2675 #ifndef MODEST_TOOLKIT_HILDON2
2676 ModestMainWindow *win;
2678 /* FIXME. Make the header view sensitive again. This is a
2679 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2681 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2682 modest_runtime_get_window_mgr(), FALSE));
2684 GtkWidget *hdrview = modest_main_window_get_child_widget(
2685 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2686 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2690 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2692 /* Set draft is there was no error */
2693 if (!modest_mail_operation_get_error (mail_op))
2694 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2696 g_object_unref(edit_window);
2700 enough_space_for_message (ModestMsgEditWindow *edit_window,
2703 TnyAccountStore *acc_store;
2704 guint64 available_disk, expected_size;
2709 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2710 available_disk = modest_utils_get_available_space (NULL);
2711 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2712 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2717 /* Double check: memory full condition or message too big */
2718 if (available_disk < MIN_FREE_SPACE ||
2719 expected_size > available_disk) {
2721 modest_platform_information_banner (NULL, NULL,
2723 "cerm_device_memory_full"));
2728 * djcb: if we're in low-memory state, we only allow for
2729 * saving messages smaller than
2730 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2731 * should still allow for sending anything critical...
2733 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2734 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2738 * djcb: we also make sure that the attachments are smaller than the max size
2739 * this is for the case where we'd try to forward a message with attachments
2740 * bigger than our max allowed size, or sending an message from drafts which
2741 * somehow got past our checks when attaching.
2743 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2744 modest_platform_run_information_dialog (
2745 GTK_WINDOW(edit_window),
2746 dgettext("ke-recv","memr_ib_operation_disabled"),
2755 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2757 TnyTransportAccount *transport_account;
2758 ModestMailOperation *mail_operation;
2760 gchar *account_name, *from;
2761 ModestAccountMgr *account_mgr;
2762 gboolean had_error = FALSE;
2763 ModestMainWindow *win = NULL;
2765 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2767 data = modest_msg_edit_window_get_msg_data (edit_window);
2770 if (!enough_space_for_message (edit_window, data)) {
2771 modest_msg_edit_window_free_msg_data (edit_window, data);
2775 account_name = g_strdup (data->account_name);
2776 account_mgr = modest_runtime_get_account_mgr();
2778 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2780 account_name = modest_account_mgr_get_default_account (account_mgr);
2781 if (!account_name) {
2782 g_printerr ("modest: no account found\n");
2783 modest_msg_edit_window_free_msg_data (edit_window, data);
2787 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2788 account_name = g_strdup (data->account_name);
2792 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2793 (modest_runtime_get_account_store (),
2795 TNY_ACCOUNT_TYPE_TRANSPORT));
2796 if (!transport_account) {
2797 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2798 g_free (account_name);
2799 modest_msg_edit_window_free_msg_data (edit_window, data);
2802 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2804 /* Create the mail operation */
2805 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2807 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2809 modest_mail_operation_save_to_drafts (mail_operation,
2821 data->priority_flags,
2822 on_save_to_drafts_cb,
2823 g_object_ref(edit_window));
2825 #ifdef MODEST_TOOLKIT_HILDON2
2826 /* In hildon2 we always show the information banner on saving to drafts.
2827 * It will be a system information banner in this case.
2829 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2830 modest_platform_information_banner (NULL, NULL, text);
2833 /* Use the main window as the parent of the banner, if the
2834 main window does not exist it won't be shown, if the parent
2835 window exists then it's properly shown. We don't use the
2836 editor window because it could be closed (save to drafts
2837 could happen after closing the window */
2838 win = (ModestMainWindow *)
2839 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2841 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2842 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2846 modest_msg_edit_window_set_modified (edit_window, FALSE);
2850 g_free (account_name);
2851 g_object_unref (G_OBJECT (transport_account));
2852 g_object_unref (G_OBJECT (mail_operation));
2854 modest_msg_edit_window_free_msg_data (edit_window, data);
2857 * If the drafts folder is selected then make the header view
2858 * insensitive while the message is being saved to drafts
2859 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2860 * is not very clean but it avoids letting the drafts folder
2861 * in an inconsistent state: the user could edit the message
2862 * being saved and undesirable things would happen.
2863 * In the average case the user won't notice anything at
2864 * all. In the worst case (the user is editing a really big
2865 * file from Drafts) the header view will be insensitive
2866 * during the saving process (10 or 20 seconds, depending on
2867 * the message). Anyway this is just a quick workaround: once
2868 * we find a better solution it should be removed
2869 * See NB#65125 (commend #18) for details.
2871 if (!had_error && win != NULL) {
2872 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2873 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2875 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2877 if (modest_tny_folder_is_local_folder(folder)) {
2878 TnyFolderType folder_type;
2879 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2880 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2881 GtkWidget *hdrview = modest_main_window_get_child_widget(
2882 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2883 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2887 if (folder != NULL) g_object_unref(folder);
2894 /* For instance, when clicking the Send toolbar button when editing a message: */
2896 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2898 TnyTransportAccount *transport_account = NULL;
2899 gboolean had_error = FALSE;
2901 ModestAccountMgr *account_mgr;
2902 gchar *account_name;
2904 ModestMailOperation *mail_operation;
2906 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2908 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2911 data = modest_msg_edit_window_get_msg_data (edit_window);
2914 if (!enough_space_for_message (edit_window, data)) {
2915 modest_msg_edit_window_free_msg_data (edit_window, data);
2919 account_mgr = modest_runtime_get_account_mgr();
2920 account_name = g_strdup (data->account_name);
2922 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2925 account_name = modest_account_mgr_get_default_account (account_mgr);
2927 if (!account_name) {
2928 modest_msg_edit_window_free_msg_data (edit_window, data);
2929 /* Run account setup wizard */
2930 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2935 /* Get the currently-active transport account for this modest account: */
2936 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2938 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2939 (modest_runtime_get_account_store (),
2940 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2943 if (!transport_account) {
2944 modest_msg_edit_window_free_msg_data (edit_window, data);
2945 /* Run account setup wizard */
2946 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2951 /* Create the mail operation */
2952 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2953 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2954 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2956 modest_mail_operation_send_new_mail (mail_operation,
2968 data->priority_flags);
2970 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2971 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2974 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2975 const GError *error = modest_mail_operation_get_error (mail_operation);
2976 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2977 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2978 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2979 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2986 g_free (account_name);
2987 g_object_unref (G_OBJECT (transport_account));
2988 g_object_unref (G_OBJECT (mail_operation));
2990 modest_msg_edit_window_free_msg_data (edit_window, data);
2993 modest_msg_edit_window_set_sent (edit_window, TRUE);
2995 /* Save settings and close the window: */
2996 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3003 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3004 ModestMsgEditWindow *window)
3006 ModestMsgEditFormatState *format_state = NULL;
3008 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3009 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3011 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3014 format_state = modest_msg_edit_window_get_format_state (window);
3015 g_return_if_fail (format_state != NULL);
3017 format_state->bold = gtk_toggle_action_get_active (action);
3018 modest_msg_edit_window_set_format_state (window, format_state);
3019 g_free (format_state);
3024 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3025 ModestMsgEditWindow *window)
3027 ModestMsgEditFormatState *format_state = NULL;
3029 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3030 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3032 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3035 format_state = modest_msg_edit_window_get_format_state (window);
3036 g_return_if_fail (format_state != NULL);
3038 format_state->italics = gtk_toggle_action_get_active (action);
3039 modest_msg_edit_window_set_format_state (window, format_state);
3040 g_free (format_state);
3045 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3046 ModestMsgEditWindow *window)
3048 ModestMsgEditFormatState *format_state = NULL;
3050 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3051 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3053 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3056 format_state = modest_msg_edit_window_get_format_state (window);
3057 g_return_if_fail (format_state != NULL);
3059 format_state->bullet = gtk_toggle_action_get_active (action);
3060 modest_msg_edit_window_set_format_state (window, format_state);
3061 g_free (format_state);
3066 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3067 GtkRadioAction *selected,
3068 ModestMsgEditWindow *window)
3070 ModestMsgEditFormatState *format_state = NULL;
3071 GtkJustification value;
3073 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3075 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3078 value = gtk_radio_action_get_current_value (selected);
3080 format_state = modest_msg_edit_window_get_format_state (window);
3081 g_return_if_fail (format_state != NULL);
3083 format_state->justification = value;
3084 modest_msg_edit_window_set_format_state (window, format_state);
3085 g_free (format_state);
3089 modest_ui_actions_on_select_editor_color (GtkAction *action,
3090 ModestMsgEditWindow *window)
3092 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3093 g_return_if_fail (GTK_IS_ACTION (action));
3095 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3098 modest_msg_edit_window_select_color (window);
3102 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3103 ModestMsgEditWindow *window)
3105 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3106 g_return_if_fail (GTK_IS_ACTION (action));
3108 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3111 modest_msg_edit_window_select_background_color (window);
3115 modest_ui_actions_on_insert_image (GtkAction *action,
3116 ModestMsgEditWindow *window)
3118 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3119 g_return_if_fail (GTK_IS_ACTION (action));
3122 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3125 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3128 modest_msg_edit_window_insert_image (window);
3132 modest_ui_actions_on_attach_file (GtkAction *action,
3133 ModestMsgEditWindow *window)
3135 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3136 g_return_if_fail (GTK_IS_ACTION (action));
3138 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3141 modest_msg_edit_window_offer_attach_file (window);
3145 modest_ui_actions_on_remove_attachments (GtkAction *action,
3146 ModestMsgEditWindow *window)
3148 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3149 g_return_if_fail (GTK_IS_ACTION (action));
3151 modest_msg_edit_window_remove_attachments (window, NULL);
3155 #ifndef MODEST_TOOLKIT_GTK
3160 TnyFolderStore *folder;
3161 } CreateFolderHelper;
3164 show_create_folder_in_timeout (gpointer data)
3166 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3168 /* Remove the timeout ASAP, we can not wait until the dialog
3169 is shown because it could take a lot of time and so the
3170 timeout could be called twice or more times */
3171 g_source_remove (helper->handler);
3173 gdk_threads_enter ();
3174 do_create_folder (helper->win, helper->folder, helper->name);
3175 gdk_threads_leave ();
3177 g_object_unref (helper->win);
3178 g_object_unref (helper->folder);
3179 g_free (helper->name);
3180 g_slice_free (CreateFolderHelper, helper);
3187 do_create_folder_cb (ModestMailOperation *mail_op,
3188 TnyFolderStore *parent_folder,
3189 TnyFolder *new_folder,
3192 gchar *suggested_name = (gchar *) user_data;
3193 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3195 if (modest_mail_operation_get_error (mail_op)) {
3197 /* Show an error. If there was some problem writing to
3198 disk, show it, otherwise show the generic folder
3199 create error. We do it here and not in an error
3200 handler because the call to do_create_folder will
3201 stop the main loop in a gtk_dialog_run and then,
3202 the message won't be shown until that dialog is
3204 modest_ui_actions_disk_operations_error_handler (mail_op,
3205 _("mail_in_ui_folder_create_error"));
3207 /* Try again. Do *NOT* show any error because the mail
3208 operations system will do it for us because we
3209 created the mail_op with new_with_error_handler */
3210 #ifndef MODEST_TOOLKIT_GTK
3211 CreateFolderHelper *helper;
3212 helper = g_slice_new0 (CreateFolderHelper);
3213 helper->name = g_strdup (suggested_name);
3214 helper->folder = g_object_ref (parent_folder);
3215 helper->win = g_object_ref (source_win);
3217 /* Ugly but neccesary stuff. The problem is that the
3218 dialog when is shown calls a function that destroys
3219 all the temporary windows, so the banner is
3221 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3223 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3226 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3227 * FIXME: any other? */
3228 GtkWidget *folder_view;
3230 if (MODEST_IS_MAIN_WINDOW(source_win))
3232 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3233 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3235 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3236 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3238 /* Select the newly created folder. It could happen
3239 that the widget is no longer there (i.e. the window
3240 has been destroyed, so we need to check this */
3242 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3244 g_object_unref (new_folder);
3246 /* Free. Note that the first time it'll be NULL so noop */
3247 g_free (suggested_name);
3248 g_object_unref (source_win);
3252 do_create_folder (GtkWindow *parent_window,
3253 TnyFolderStore *parent_folder,
3254 const gchar *suggested_name)
3257 gchar *folder_name = NULL;
3259 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3261 (gchar *) suggested_name,
3264 if (result == GTK_RESPONSE_ACCEPT) {
3265 ModestMailOperation *mail_op;
3267 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3268 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3270 modest_mail_operation_create_folder (mail_op,
3272 (const gchar *) folder_name,
3273 do_create_folder_cb,
3275 g_object_unref (mail_op);
3280 create_folder_performer (gboolean canceled,
3282 GtkWindow *parent_window,
3283 TnyAccount *account,
3286 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3288 if (canceled || err) {
3289 /* In memory full conditions we could get this error here */
3290 check_memory_full_error ((GtkWidget *) parent_window, err);
3294 /* Run the new folder dialog */
3295 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3298 g_object_unref (parent_folder);
3302 modest_ui_actions_create_folder(GtkWidget *parent_window,
3303 GtkWidget *folder_view)
3305 TnyFolderStore *parent_folder;
3307 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3309 if (parent_folder) {
3310 /* The parent folder will be freed in the callback */
3311 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3314 create_folder_performer,
3320 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
3322 GtkWidget *folder_view;
3324 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3326 folder_view = modest_main_window_get_child_widget (main_window,
3327 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3331 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
3335 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3338 const GError *error = NULL;
3339 const gchar *message = NULL;
3341 /* Get error message */
3342 error = modest_mail_operation_get_error (mail_op);
3344 g_return_if_reached ();
3346 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3347 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3348 message = _CS("ckdg_ib_folder_already_exists");
3349 } else if (error->domain == TNY_ERROR_DOMAIN &&
3350 error->code == TNY_SERVICE_ERROR_STATE) {
3351 /* This means that the folder is already in use (a
3352 message is opened for example */
3353 message = _("emev_ni_internal_error");
3355 message = _("emev_ib_ui_imap_unable_to_rename");
3358 /* We don't set a parent for the dialog because the dialog
3359 will be destroyed so the banner won't appear */
3360 modest_platform_information_banner (NULL, NULL, message);
3364 TnyFolderStore *folder;
3369 on_rename_folder_cb (ModestMailOperation *mail_op,
3370 TnyFolder *new_folder,
3373 ModestFolderView *folder_view;
3375 /* If the window was closed when renaming a folder this could
3377 if (!MODEST_IS_FOLDER_VIEW (user_data))
3380 folder_view = MODEST_FOLDER_VIEW (user_data);
3381 /* Note that if the rename fails new_folder will be NULL */
3383 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3385 modest_folder_view_select_first_inbox_or_local (folder_view);
3387 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3391 on_rename_folder_performer (gboolean canceled,
3393 GtkWindow *parent_window,
3394 TnyAccount *account,
3397 ModestMailOperation *mail_op = NULL;
3398 GtkTreeSelection *sel = NULL;
3399 GtkWidget *folder_view = NULL;
3400 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3402 if (canceled || err) {
3403 /* In memory full conditions we could get this error here */
3404 check_memory_full_error ((GtkWidget *) parent_window, err);
3405 } else if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3407 folder_view = modest_main_window_get_child_widget (
3408 MODEST_MAIN_WINDOW (parent_window),
3409 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3412 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3413 modest_ui_actions_rename_folder_error_handler,
3414 parent_window, NULL);
3416 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3419 /* Clear the headers view */
3420 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3421 gtk_tree_selection_unselect_all (sel);
3423 /* Actually rename the folder */
3424 modest_mail_operation_rename_folder (mail_op,
3425 TNY_FOLDER (data->folder),
3426 (const gchar *) (data->new_name),
3427 on_rename_folder_cb,
3429 g_object_unref (data->folder);
3430 g_object_unref (mail_op);
3433 g_free (data->new_name);
3438 modest_ui_actions_on_rename_folder (GtkAction *action,
3439 ModestMainWindow *main_window)
3441 TnyFolderStore *folder;
3442 GtkWidget *folder_view;
3443 GtkWidget *header_view;
3445 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3447 folder_view = modest_main_window_get_child_widget (main_window,
3448 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3452 header_view = modest_main_window_get_child_widget (main_window,
3453 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3458 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3463 if (TNY_IS_FOLDER (folder)) {
3464 gchar *folder_name = NULL;
3466 const gchar *current_name;
3467 TnyFolderStore *parent;
3468 gboolean do_rename = TRUE;
3470 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3471 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3472 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
3473 parent, current_name,
3475 g_object_unref (parent);
3477 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3480 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3481 rename_folder_data->folder = g_object_ref (folder);
3482 rename_folder_data->new_name = folder_name;
3483 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
3484 folder, on_rename_folder_performer, rename_folder_data);
3487 g_object_unref (folder);
3491 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3494 GObject *win = modest_mail_operation_get_source (mail_op);
3496 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3497 _("mail_in_ui_folder_delete_error"),
3499 g_object_unref (win);
3503 TnyFolderStore *folder;
3504 gboolean move_to_trash;
3508 on_delete_folder_cb (gboolean canceled,
3510 GtkWindow *parent_window,
3511 TnyAccount *account,
3514 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3515 GtkWidget *folder_view;
3516 ModestMailOperation *mail_op;
3517 GtkTreeSelection *sel;
3519 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
3520 g_object_unref (G_OBJECT (info->folder));
3525 folder_view = modest_main_window_get_child_widget (
3526 MODEST_MAIN_WINDOW (parent_window),
3527 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3529 /* Unselect the folder before deleting it to free the headers */
3530 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3531 gtk_tree_selection_unselect_all (sel);
3533 /* Create the mail operation */
3535 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3536 modest_ui_actions_delete_folder_error_handler,
3539 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3541 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3543 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3545 g_object_unref (G_OBJECT (mail_op));
3546 g_object_unref (G_OBJECT (info->folder));
3551 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
3553 TnyFolderStore *folder;
3554 GtkWidget *folder_view;
3558 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3560 folder_view = modest_main_window_get_child_widget (main_window,
3561 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3565 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3567 /* Show an error if it's an account */
3568 if (!TNY_IS_FOLDER (folder)) {
3569 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
3570 _("mail_in_ui_folder_delete_error"),
3572 g_object_unref (G_OBJECT (folder));
3577 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3578 tny_folder_get_name (TNY_FOLDER (folder)));
3579 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
3580 (const gchar *) message);
3583 if (response == GTK_RESPONSE_OK) {
3584 DeleteFolderInfo *info;
3585 info = g_new0(DeleteFolderInfo, 1);
3586 info->folder = folder;
3587 info->move_to_trash = move_to_trash;
3588 g_object_ref (G_OBJECT (info->folder));
3589 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3590 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
3592 TNY_FOLDER_STORE (account),
3593 on_delete_folder_cb, info);
3594 g_object_unref (account);
3596 g_object_unref (G_OBJECT (folder));
3600 modest_ui_actions_on_delete_folder (GtkAction *action,
3601 ModestMainWindow *main_window)
3603 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3605 delete_folder (main_window, FALSE);
3609 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3611 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3613 delete_folder (main_window, TRUE);
3617 typedef struct _PasswordDialogFields {
3618 GtkWidget *username;
3619 GtkWidget *password;
3621 } PasswordDialogFields;
3624 password_dialog_check_field (GtkEditable *editable,
3625 PasswordDialogFields *fields)
3628 gboolean any_value_empty = FALSE;
3630 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3631 if ((value == NULL) || value[0] == '\0') {
3632 any_value_empty = TRUE;
3634 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3635 if ((value == NULL) || value[0] == '\0') {
3636 any_value_empty = TRUE;
3638 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3642 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3643 const gchar* server_account_name,
3648 ModestMainWindow *main_window)
3650 g_return_if_fail(server_account_name);
3651 gboolean completed = FALSE;
3652 PasswordDialogFields *fields = NULL;
3654 /* Initalize output parameters: */
3661 #ifndef MODEST_TOOLKIT_GTK
3662 /* Maemo uses a different (awkward) button order,
3663 * It should probably just use gtk_alternative_dialog_button_order ().
3665 #ifdef MODEST_TOOLKIT_HILDON2
3667 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3670 _HL("wdgt_bd_done"),
3671 GTK_RESPONSE_ACCEPT,
3675 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3678 _("mcen_bd_dialog_ok"),
3679 GTK_RESPONSE_ACCEPT,
3680 _("mcen_bd_dialog_cancel"),
3681 GTK_RESPONSE_REJECT,
3683 #endif /* MODEST_TOOLKIT_HILDON2 */
3686 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3690 GTK_RESPONSE_REJECT,
3692 GTK_RESPONSE_ACCEPT,
3694 #endif /* MODEST_TOOLKIT_GTK */
3696 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3698 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3699 modest_runtime_get_account_mgr(), server_account_name);
3700 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3701 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3704 gtk_widget_destroy (dialog);
3708 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3709 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3712 g_free (server_name);
3716 gchar *initial_username = modest_account_mgr_get_server_account_username (
3717 modest_runtime_get_account_mgr(), server_account_name);
3719 GtkWidget *entry_username = gtk_entry_new ();
3720 if (initial_username)
3721 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3722 /* Dim this if a connection has ever succeeded with this username,
3723 * as per the UI spec: */
3724 /* const gboolean username_known = */
3725 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3726 /* modest_runtime_get_account_mgr(), server_account_name); */
3727 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3729 /* We drop the username sensitive code and disallow changing it here
3730 * as tinymail does not support really changing the username in the callback
3732 gtk_widget_set_sensitive (entry_username, FALSE);
3734 #ifndef MODEST_TOOLKIT_GTK
3735 /* Auto-capitalization is the default, so let's turn it off: */
3736 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3738 /* Create a size group to be used by all captions.
3739 * Note that HildonCaption does not create a default size group if we do not specify one.
3740 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3741 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3743 GtkWidget *caption = hildon_caption_new (sizegroup,
3744 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3745 gtk_widget_show (entry_username);
3746 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3747 FALSE, FALSE, MODEST_MARGIN_HALF);
3748 gtk_widget_show (caption);
3750 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3752 #endif /* !MODEST_TOOLKIT_GTK */
3755 GtkWidget *entry_password = gtk_entry_new ();
3756 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3757 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3759 #ifndef MODEST_TOOLKIT_GTK
3760 /* Auto-capitalization is the default, so let's turn it off: */
3761 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3762 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3764 caption = hildon_caption_new (sizegroup,
3765 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3766 gtk_widget_show (entry_password);
3767 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3768 FALSE, FALSE, MODEST_MARGIN_HALF);
3769 gtk_widget_show (caption);
3770 g_object_unref (sizegroup);
3772 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3774 #endif /* !MODEST_TOOLKIT_GTK */
3776 if (initial_username != NULL)
3777 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3779 /* This is not in the Maemo UI spec:
3780 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3781 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3785 fields = g_slice_new0 (PasswordDialogFields);
3786 fields->username = entry_username;
3787 fields->password = entry_password;
3788 fields->dialog = dialog;
3790 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3791 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3792 password_dialog_check_field (NULL, fields);
3794 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3796 while (!completed) {
3798 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3800 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3802 /* Note that an empty field becomes the "" string */
3803 if (*username && strlen (*username) > 0) {
3804 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3805 server_account_name,
3809 const gboolean username_was_changed =
3810 (strcmp (*username, initial_username) != 0);
3811 if (username_was_changed) {
3812 g_warning ("%s: tinymail does not yet support changing the "
3813 "username in the get_password() callback.\n", __FUNCTION__);
3819 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3820 _("mcen_ib_username_pw_incorrect"));
3826 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3828 /* We do not save the password in the configuration,
3829 * because this function is only called for passwords that should
3830 * not be remembered:
3831 modest_server_account_set_password (
3832 modest_runtime_get_account_mgr(), server_account_name,
3839 #ifndef MODEST_TOOLKIT_HILDON2
3840 /* Set parent to NULL or the banner will disappear with its parent dialog */
3841 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3853 /* This is not in the Maemo UI spec:
3854 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3860 g_free (initial_username);
3861 gtk_widget_destroy (dialog);
3862 g_slice_free (PasswordDialogFields, fields);
3864 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3868 modest_ui_actions_on_cut (GtkAction *action,
3869 ModestWindow *window)
3871 GtkWidget *focused_widget;
3872 GtkClipboard *clipboard;
3874 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3875 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3876 if (GTK_IS_EDITABLE (focused_widget)) {
3877 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3878 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3879 gtk_clipboard_store (clipboard);
3880 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3881 GtkTextBuffer *buffer;
3883 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3884 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3885 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3886 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3887 gtk_clipboard_store (clipboard);
3889 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3890 TnyList *header_list = modest_header_view_get_selected_headers (
3891 MODEST_HEADER_VIEW (focused_widget));
3892 gboolean continue_download = FALSE;
3893 gint num_of_unc_msgs;
3895 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3897 if (num_of_unc_msgs) {
3898 TnyAccount *account = get_account_from_header_list (header_list);
3900 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3901 g_object_unref (account);
3905 if (num_of_unc_msgs == 0 || continue_download) {
3906 /* modest_platform_information_banner (
3907 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3908 modest_header_view_cut_selection (
3909 MODEST_HEADER_VIEW (focused_widget));
3912 g_object_unref (header_list);
3913 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3914 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3919 modest_ui_actions_on_copy (GtkAction *action,
3920 ModestWindow *window)
3922 GtkClipboard *clipboard;
3923 GtkWidget *focused_widget;
3924 gboolean copied = TRUE;
3926 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3927 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3929 if (GTK_IS_LABEL (focused_widget)) {
3931 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3932 gtk_clipboard_set_text (clipboard, selection, -1);
3934 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3935 gtk_clipboard_store (clipboard);
3936 } else if (GTK_IS_EDITABLE (focused_widget)) {
3937 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3938 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3939 gtk_clipboard_store (clipboard);
3940 } else if (GTK_IS_HTML (focused_widget)) {
3943 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3944 if ((sel == NULL) || (sel[0] == '\0')) {
3947 gtk_html_copy (GTK_HTML (focused_widget));
3948 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3949 gtk_clipboard_store (clipboard);
3951 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3952 GtkTextBuffer *buffer;
3953 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3954 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3955 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3956 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3957 gtk_clipboard_store (clipboard);
3959 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3960 TnyList *header_list = modest_header_view_get_selected_headers (
3961 MODEST_HEADER_VIEW (focused_widget));
3962 gboolean continue_download = FALSE;
3963 gint num_of_unc_msgs;
3965 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3967 if (num_of_unc_msgs) {
3968 TnyAccount *account = get_account_from_header_list (header_list);
3970 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3971 g_object_unref (account);
3975 if (num_of_unc_msgs == 0 || continue_download) {
3976 modest_platform_information_banner (
3977 NULL, NULL, _CS("mcen_ib_getting_items"));
3978 modest_header_view_copy_selection (
3979 MODEST_HEADER_VIEW (focused_widget));
3983 g_object_unref (header_list);
3985 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3986 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3989 /* Show information banner if there was a copy to clipboard */
3991 modest_platform_information_banner (
3992 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3996 modest_ui_actions_on_undo (GtkAction *action,
3997 ModestWindow *window)
3999 ModestEmailClipboard *clipboard = NULL;
4001 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4002 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4003 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4004 /* Clear clipboard source */
4005 clipboard = modest_runtime_get_email_clipboard ();
4006 modest_email_clipboard_clear (clipboard);
4009 g_return_if_reached ();
4014 modest_ui_actions_on_redo (GtkAction *action,
4015 ModestWindow *window)
4017 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4018 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4021 g_return_if_reached ();
4027 destroy_information_note (ModestMailOperation *mail_op,
4030 /* destroy information note */
4031 gtk_widget_destroy (GTK_WIDGET(user_data));
4035 destroy_folder_information_note (ModestMailOperation *mail_op,
4036 TnyFolder *new_folder,
4039 /* destroy information note */
4040 gtk_widget_destroy (GTK_WIDGET(user_data));
4045 paste_as_attachment_free (gpointer data)
4047 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4049 if (helper->banner) {
4050 gtk_widget_destroy (helper->banner);
4051 g_object_unref (helper->banner);
4057 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4062 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4063 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4068 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4073 modest_ui_actions_on_paste (GtkAction *action,
4074 ModestWindow *window)
4076 GtkWidget *focused_widget = NULL;
4077 GtkWidget *inf_note = NULL;
4078 ModestMailOperation *mail_op = NULL;
4080 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4081 if (GTK_IS_EDITABLE (focused_widget)) {
4082 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4083 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4084 ModestEmailClipboard *e_clipboard = NULL;
4085 e_clipboard = modest_runtime_get_email_clipboard ();
4086 if (modest_email_clipboard_cleared (e_clipboard)) {
4087 GtkTextBuffer *buffer;
4088 GtkClipboard *clipboard;
4090 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4091 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4092 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4093 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4094 ModestMailOperation *mail_op;
4095 TnyFolder *src_folder = NULL;
4096 TnyList *data = NULL;
4098 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4099 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4100 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4101 _CS("ckct_nw_pasting"));
4102 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4103 mail_op = modest_mail_operation_new (G_OBJECT (window));
4104 if (helper->banner != NULL) {
4105 g_object_ref (G_OBJECT (helper->banner));
4106 gtk_widget_show (GTK_WIDGET (helper->banner));
4110 modest_mail_operation_get_msgs_full (mail_op,
4112 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4114 paste_as_attachment_free);
4118 g_object_unref (data);
4120 g_object_unref (src_folder);
4123 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4124 ModestEmailClipboard *clipboard = NULL;
4125 TnyFolder *src_folder = NULL;
4126 TnyFolderStore *folder_store = NULL;
4127 TnyList *data = NULL;
4128 gboolean delete = FALSE;
4130 /* Check clipboard source */
4131 clipboard = modest_runtime_get_email_clipboard ();
4132 if (modest_email_clipboard_cleared (clipboard))
4135 /* Get elements to paste */
4136 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4138 /* Create a new mail operation */
4139 mail_op = modest_mail_operation_new (G_OBJECT(window));
4141 /* Get destination folder */
4142 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4144 /* transfer messages */
4148 /* Ask for user confirmation */
4150 modest_ui_actions_msgs_move_to_confirmation (window,
4151 TNY_FOLDER (folder_store),
4155 if (response == GTK_RESPONSE_OK) {
4156 /* Launch notification */
4157 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4158 _CS("ckct_nw_pasting"));
4159 if (inf_note != NULL) {
4160 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4161 gtk_widget_show (GTK_WIDGET(inf_note));
4164 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4165 modest_mail_operation_xfer_msgs (mail_op,
4167 TNY_FOLDER (folder_store),
4169 destroy_information_note,
4172 g_object_unref (mail_op);
4175 } else if (src_folder != NULL) {
4176 /* Launch notification */
4177 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4178 _CS("ckct_nw_pasting"));
4179 if (inf_note != NULL) {
4180 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4181 gtk_widget_show (GTK_WIDGET(inf_note));
4184 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4185 modest_mail_operation_xfer_folder (mail_op,
4189 destroy_folder_information_note,
4195 g_object_unref (data);
4196 if (src_folder != NULL)
4197 g_object_unref (src_folder);
4198 if (folder_store != NULL)
4199 g_object_unref (folder_store);
4205 modest_ui_actions_on_select_all (GtkAction *action,
4206 ModestWindow *window)
4208 GtkWidget *focused_widget;
4210 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4211 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4212 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4213 } else if (GTK_IS_LABEL (focused_widget)) {
4214 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4215 } else if (GTK_IS_EDITABLE (focused_widget)) {
4216 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4217 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4218 GtkTextBuffer *buffer;
4219 GtkTextIter start, end;
4221 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4222 gtk_text_buffer_get_start_iter (buffer, &start);
4223 gtk_text_buffer_get_end_iter (buffer, &end);
4224 gtk_text_buffer_select_range (buffer, &start, &end);
4225 } else if (GTK_IS_HTML (focused_widget)) {
4226 gtk_html_select_all (GTK_HTML (focused_widget));
4227 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4228 GtkWidget *header_view = focused_widget;
4229 GtkTreeSelection *selection = NULL;
4231 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4232 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4233 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4236 /* Disable window dimming management */
4237 modest_window_disable_dimming (MODEST_WINDOW(window));
4239 /* Select all messages */
4240 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4241 gtk_tree_selection_select_all (selection);
4243 /* Set focuse on header view */
4244 gtk_widget_grab_focus (header_view);
4246 /* Enable window dimming management */
4247 modest_window_enable_dimming (MODEST_WINDOW(window));
4248 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4249 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4255 modest_ui_actions_on_mark_as_read (GtkAction *action,
4256 ModestWindow *window)
4258 g_return_if_fail (MODEST_IS_WINDOW(window));
4260 /* Mark each header as read */
4261 do_headers_action (window, headers_action_mark_as_read, NULL);
4265 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4266 ModestWindow *window)
4268 g_return_if_fail (MODEST_IS_WINDOW(window));
4270 /* Mark each header as read */
4271 do_headers_action (window, headers_action_mark_as_unread, NULL);
4275 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4276 GtkRadioAction *selected,
4277 ModestWindow *window)
4281 value = gtk_radio_action_get_current_value (selected);
4282 if (MODEST_IS_WINDOW (window)) {
4283 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4288 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4289 GtkRadioAction *selected,
4290 ModestWindow *window)
4292 TnyHeaderFlags flags;
4293 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4295 flags = gtk_radio_action_get_current_value (selected);
4296 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4300 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4301 GtkRadioAction *selected,
4302 ModestWindow *window)
4306 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4308 file_format = gtk_radio_action_get_current_value (selected);
4309 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4314 modest_ui_actions_on_zoom_plus (GtkAction *action,
4315 ModestWindow *window)
4317 g_return_if_fail (MODEST_IS_WINDOW (window));
4319 modest_window_zoom_plus (MODEST_WINDOW (window));
4323 modest_ui_actions_on_zoom_minus (GtkAction *action,
4324 ModestWindow *window)
4326 g_return_if_fail (MODEST_IS_WINDOW (window));
4328 modest_window_zoom_minus (MODEST_WINDOW (window));
4332 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4333 ModestWindow *window)
4335 ModestWindowMgr *mgr;
4336 gboolean fullscreen, active;
4337 g_return_if_fail (MODEST_IS_WINDOW (window));
4339 mgr = modest_runtime_get_window_mgr ();
4341 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4342 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4344 if (active != fullscreen) {
4345 modest_window_mgr_set_fullscreen_mode (mgr, active);
4346 #ifndef MODEST_TOOLKIT_HILDON2
4347 gtk_window_present (GTK_WINDOW (window));
4353 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4354 ModestWindow *window)
4356 ModestWindowMgr *mgr;
4357 gboolean fullscreen;
4359 g_return_if_fail (MODEST_IS_WINDOW (window));
4361 mgr = modest_runtime_get_window_mgr ();
4362 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4363 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4365 #ifndef MODEST_TOOLKIT_HILDON2
4366 gtk_window_present (GTK_WINDOW (window));
4371 * Used by modest_ui_actions_on_details to call do_headers_action
4374 headers_action_show_details (TnyHeader *header,
4375 ModestWindow *window,
4379 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4383 * Show the header details in a ModestDetailsDialog widget
4386 modest_ui_actions_on_details (GtkAction *action,
4389 TnyList * headers_list;
4393 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4396 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4399 g_object_unref (msg);
4401 headers_list = get_selected_headers (win);
4405 iter = tny_list_create_iterator (headers_list);
4407 header = TNY_HEADER (tny_iterator_get_current (iter));
4409 headers_action_show_details (header, win, NULL);
4410 g_object_unref (header);
4413 g_object_unref (iter);
4414 g_object_unref (headers_list);
4416 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4417 GtkWidget *folder_view, *header_view;
4419 /* Check which widget has the focus */
4420 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4421 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4422 if (gtk_widget_is_focus (folder_view)) {
4423 TnyFolderStore *folder_store
4424 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4425 if (!folder_store) {
4426 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4429 /* Show only when it's a folder */
4430 /* This function should not be called for account items,
4431 * because we dim the menu item for them. */
4432 if (TNY_IS_FOLDER (folder_store)) {
4433 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4434 TNY_FOLDER (folder_store));
4437 g_object_unref (folder_store);
4440 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4441 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4442 /* Show details of each header */
4443 do_headers_action (win, headers_action_show_details, header_view);
4445 #ifdef MODEST_TOOLKIT_HILDON2
4446 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4448 GtkWidget *header_view;
4450 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4451 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4453 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4455 g_object_unref (folder);
4462 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4463 ModestMsgEditWindow *window)
4465 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4467 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4471 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4472 ModestMsgEditWindow *window)
4474 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4476 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4480 modest_ui_actions_toggle_folders_view (GtkAction *action,
4481 ModestMainWindow *main_window)
4483 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4485 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4486 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4488 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4492 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4493 ModestWindow *window)
4495 gboolean active, fullscreen = FALSE;
4496 ModestWindowMgr *mgr;
4498 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4500 /* Check if we want to toggle the toolbar view in fullscreen
4502 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4503 "ViewShowToolbarFullScreen")) {
4507 /* Toggle toolbar */
4508 mgr = modest_runtime_get_window_mgr ();
4509 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4513 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4514 ModestMsgEditWindow *window)
4516 modest_msg_edit_window_select_font (window);
4521 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4522 const gchar *display_name,
4525 /* don't update the display name if it was already set;
4526 * updating the display name apparently is expensive */
4527 const gchar* old_name = gtk_window_get_title (window);
4529 if (display_name == NULL)
4532 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4533 return; /* don't do anything */
4535 /* This is usually used to change the title of the main window, which
4536 * is the one that holds the folder view. Note that this change can
4537 * happen even when the widget doesn't have the focus. */
4538 gtk_window_set_title (window, display_name);
4543 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4545 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4546 modest_msg_edit_window_select_contacts (window);
4550 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4552 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4553 modest_msg_edit_window_check_names (window, FALSE);
4556 #ifndef MODEST_TOOLKIT_HILDON2
4558 * This function is used to track changes in the selection of the
4559 * folder view that is inside the "move to" dialog to enable/disable
4560 * the OK button because we do not want the user to select a disallowed
4561 * destination for a folder.
4562 * The user also not desired to be able to use NEW button on items where
4563 * folder creation is not possibel.
4566 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4567 TnyFolderStore *folder_store,
4571 GtkWidget *dialog = NULL;
4572 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4573 gboolean moving_folder = FALSE;
4574 gboolean is_local_account = TRUE;
4575 GtkWidget *folder_view = NULL;
4576 ModestTnyFolderRules rules;
4578 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4583 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4587 /* check if folder_store is an remote account */
4588 if (TNY_IS_ACCOUNT (folder_store)) {
4589 TnyAccount *local_account = NULL;
4590 TnyAccount *mmc_account = NULL;
4591 ModestTnyAccountStore *account_store = NULL;
4593 account_store = modest_runtime_get_account_store ();
4594 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4595 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4597 if ((gpointer) local_account != (gpointer) folder_store &&
4598 (gpointer) mmc_account != (gpointer) folder_store) {
4599 ModestProtocolType proto;
4600 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4601 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4602 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4604 is_local_account = FALSE;
4605 /* New button should be dimmed on remote
4607 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4609 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4611 g_object_unref (local_account);
4613 /* It could not exist */
4615 g_object_unref (mmc_account);
4618 /* Check the target folder rules */
4619 if (TNY_IS_FOLDER (folder_store)) {
4620 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4621 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4622 ok_sensitive = FALSE;
4623 new_sensitive = FALSE;
4628 /* Check if we're moving a folder */
4629 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4630 /* Get the widgets */
4631 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4632 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4633 if (gtk_widget_is_focus (folder_view))
4634 moving_folder = TRUE;
4637 if (moving_folder) {
4638 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4640 /* Get the folder to move */
4641 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4643 /* Check that we're not moving to the same folder */
4644 if (TNY_IS_FOLDER (moved_folder)) {
4645 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4646 if (parent == folder_store)
4647 ok_sensitive = FALSE;
4648 g_object_unref (parent);
4651 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4652 /* Do not allow to move to an account unless it's the
4653 local folders account */
4654 if (!is_local_account)
4655 ok_sensitive = FALSE;
4658 if (ok_sensitive && (moved_folder == folder_store)) {
4659 /* Do not allow to move to itself */
4660 ok_sensitive = FALSE;
4662 g_object_unref (moved_folder);
4664 TnyFolder *src_folder = NULL;
4666 /* Moving a message */
4667 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4669 TnyHeader *header = NULL;
4670 header = modest_msg_view_window_get_header
4671 (MODEST_MSG_VIEW_WINDOW (user_data));
4672 if (!TNY_IS_HEADER(header))
4673 g_warning ("%s: could not get source header", __FUNCTION__);
4675 src_folder = tny_header_get_folder (header);
4678 g_object_unref (header);
4681 TNY_FOLDER (modest_folder_view_get_selected
4682 (MODEST_FOLDER_VIEW (folder_view)));
4685 if (TNY_IS_FOLDER(src_folder)) {
4686 /* Do not allow to move the msg to the same folder */
4687 /* Do not allow to move the msg to an account */
4688 if ((gpointer) src_folder == (gpointer) folder_store ||
4689 TNY_IS_ACCOUNT (folder_store))
4690 ok_sensitive = FALSE;
4691 g_object_unref (src_folder);
4693 g_warning ("%s: could not get source folder", __FUNCTION__);
4697 /* Set sensitivity of the OK and NEW button */
4698 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4699 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4704 on_move_to_dialog_response (GtkDialog *dialog,
4708 GtkWidget *parent_win, *folder_view;
4709 MoveToInfo *helper = NULL;
4711 helper = (MoveToInfo *) user_data;
4713 parent_win = (GtkWidget *) helper->win;
4714 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog),
4715 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4718 TnyFolderStore *dst_folder;
4720 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4721 modest_ui_actions_create_folder (GTK_WIDGET (dialog), folder_view);
4723 case GTK_RESPONSE_NONE:
4724 case GTK_RESPONSE_CANCEL:
4725 case GTK_RESPONSE_DELETE_EVENT:
4727 case GTK_RESPONSE_OK:
4728 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4729 /* Do window specific stuff */
4730 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4731 modest_ui_actions_on_main_window_move_to (NULL,
4734 MODEST_MAIN_WINDOW (parent_win));
4736 /* Moving from headers window in edit mode */
4737 modest_ui_actions_on_window_move_to (NULL, helper->list,
4739 MODEST_WINDOW (parent_win));
4743 g_object_unref (dst_folder);
4747 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4750 /* Free the helper and exit */
4751 g_object_unref (helper->list);
4752 g_slice_free (MoveToInfo, helper);
4753 gtk_widget_destroy (GTK_WIDGET (dialog));
4757 create_move_to_dialog (GtkWindow *win,
4758 GtkWidget *folder_view)
4760 GtkWidget *dialog, *tree_view = NULL;
4762 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4764 #ifndef MODEST_TOOLKIT_HILDON2
4765 /* Track changes in the selection to
4766 * disable the OK button whenever "Move to" is not possible
4767 * disbale NEW button whenever New is not possible */
4768 g_signal_connect (tree_view,
4769 "folder_selection_changed",
4770 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4774 /* It could happen that we're trying to move a message from a
4775 window (msg window for example) after the main window was
4776 closed, so we can not just get the model of the folder
4778 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4779 const gchar *visible_id = NULL;
4781 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4782 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4783 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4784 MODEST_FOLDER_VIEW(tree_view));
4787 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4789 /* Show the same account than the one that is shown in the main window */
4790 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4793 const gchar *active_account_name = NULL;
4794 ModestAccountMgr *mgr = NULL;
4795 ModestAccountSettings *settings = NULL;
4796 ModestServerAccountSettings *store_settings = NULL;
4798 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4799 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4800 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
4801 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4803 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4804 mgr = modest_runtime_get_account_mgr ();
4805 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4808 const gchar *store_account_name;
4809 store_settings = modest_account_settings_get_store_settings (settings);
4810 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4812 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4813 store_account_name);
4814 g_object_unref (store_settings);
4815 g_object_unref (settings);
4819 /* we keep a pointer to the embedded folder view, so we can
4820 * retrieve it with get_folder_view_from_move_to_dialog (see
4821 * above) later (needed for focus handling)
4823 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4825 /* Hide special folders */
4826 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
4827 #ifndef MODEST_TOOLKIT_HILDON2
4828 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4831 gtk_widget_show (GTK_WIDGET (tree_view));
4837 * Shows a confirmation dialog to the user when we're moving messages
4838 * from a remote server to the local storage. Returns the dialog
4839 * response. If it's other kind of movement then it always returns
4842 * This one is used by the next functions:
4843 * modest_ui_actions_on_paste - commented out
4844 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4847 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4848 TnyFolder *dest_folder,
4852 gint response = GTK_RESPONSE_OK;
4853 TnyAccount *account = NULL;
4854 TnyFolder *src_folder = NULL;
4855 TnyIterator *iter = NULL;
4856 TnyHeader *header = NULL;
4858 /* return with OK if the destination is a remote folder */
4859 if (modest_tny_folder_is_remote_folder (dest_folder))
4860 return GTK_RESPONSE_OK;
4862 /* Get source folder */
4863 iter = tny_list_create_iterator (headers);
4864 header = TNY_HEADER (tny_iterator_get_current (iter));
4866 src_folder = tny_header_get_folder (header);
4867 g_object_unref (header);
4869 g_object_unref (iter);
4871 /* if no src_folder, message may be an attahcment */
4872 if (src_folder == NULL)
4873 return GTK_RESPONSE_CANCEL;
4875 /* If the source is a local or MMC folder */
4876 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4877 g_object_unref (src_folder);
4878 return GTK_RESPONSE_OK;
4881 /* Get the account */
4882 account = tny_folder_get_account (src_folder);
4884 /* now if offline we ask the user */
4885 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4886 response = GTK_RESPONSE_OK;
4888 response = GTK_RESPONSE_CANCEL;
4891 g_object_unref (src_folder);
4892 g_object_unref (account);
4898 move_to_helper_destroyer (gpointer user_data)
4900 MoveToHelper *helper = (MoveToHelper *) user_data;
4902 /* Close the "Pasting" information banner */
4903 if (helper->banner) {
4904 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4905 g_object_unref (helper->banner);
4907 if (gtk_tree_row_reference_valid (helper->reference)) {
4908 gtk_tree_row_reference_free (helper->reference);
4909 helper->reference = NULL;
4915 move_to_cb (ModestMailOperation *mail_op,
4918 MoveToHelper *helper = (MoveToHelper *) user_data;
4920 /* Note that the operation could have failed, in that case do
4922 if (modest_mail_operation_get_status (mail_op) ==
4923 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4925 GObject *object = modest_mail_operation_get_source (mail_op);
4926 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4927 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4929 if (!modest_msg_view_window_select_next_message (self) &&
4930 !modest_msg_view_window_select_previous_message (self)) {
4931 /* No more messages to view, so close this window */
4932 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4934 } else if (MODEST_IS_MAIN_WINDOW (object) &&
4935 gtk_tree_row_reference_valid (helper->reference)) {
4936 GtkWidget *header_view;
4938 GtkTreeSelection *sel;
4940 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4941 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4942 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4943 path = gtk_tree_row_reference_get_path (helper->reference);
4944 /* We need to unselect the previous one
4945 because we could be copying instead of
4947 gtk_tree_selection_unselect_all (sel);
4948 gtk_tree_selection_select_path (sel, path);
4949 gtk_tree_path_free (path);
4951 g_object_unref (object);
4953 /* Destroy the helper */
4954 move_to_helper_destroyer (helper);
4958 folder_move_to_cb (ModestMailOperation *mail_op,
4959 TnyFolder *new_folder,
4962 GtkWidget *folder_view;
4965 object = modest_mail_operation_get_source (mail_op);
4966 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4967 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4968 g_object_ref (folder_view);
4969 g_object_unref (object);
4970 move_to_cb (mail_op, user_data);
4971 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4972 g_object_unref (folder_view);
4976 msgs_move_to_cb (ModestMailOperation *mail_op,
4979 move_to_cb (mail_op, user_data);
4983 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4986 ModestWindow *main_window = NULL;
4988 /* Disable next automatic folder selection */
4989 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4990 FALSE); /* don't create */
4992 GObject *win = NULL;
4993 GtkWidget *folder_view = NULL;
4995 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4996 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4997 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4999 if (user_data && TNY_IS_FOLDER (user_data)) {
5000 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5001 TNY_FOLDER (user_data), FALSE);
5004 /* Show notification dialog only if the main window exists */
5005 win = modest_mail_operation_get_source (mail_op);
5006 modest_platform_run_information_dialog ((GtkWindow *) win,
5007 _("mail_in_ui_folder_move_target_error"),
5010 g_object_unref (win);
5015 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5024 gint pending_purges = 0;
5025 gboolean some_purged = FALSE;
5026 ModestWindow *win = MODEST_WINDOW (user_data);
5027 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5029 /* If there was any error */
5030 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5031 modest_window_mgr_unregister_header (mgr, header);
5035 /* Once the message has been retrieved for purging, we check if
5036 * it's all ok for purging */
5038 parts = tny_simple_list_new ();
5039 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5040 iter = tny_list_create_iterator (parts);
5042 while (!tny_iterator_is_done (iter)) {
5044 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5045 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5046 if (tny_mime_part_is_purged (part))
5053 g_object_unref (part);
5055 tny_iterator_next (iter);
5057 g_object_unref (iter);
5060 if (pending_purges>0) {
5062 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5064 if (response == GTK_RESPONSE_OK) {
5067 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5068 iter = tny_list_create_iterator (parts);
5069 while (!tny_iterator_is_done (iter)) {
5072 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5073 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5074 tny_mime_part_set_purged (part);
5077 g_object_unref (part);
5079 tny_iterator_next (iter);
5081 g_object_unref (iter);
5083 tny_msg_rewrite_cache (msg);
5085 gtk_widget_destroy (info);
5089 modest_window_mgr_unregister_header (mgr, header);
5091 g_object_unref (parts);
5095 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5096 ModestMainWindow *win)
5098 GtkWidget *header_view;
5099 TnyList *header_list;
5101 TnyHeaderFlags flags;
5102 ModestWindow *msg_view_window = NULL;
5105 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5107 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5108 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5110 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5112 g_warning ("%s: no header selected", __FUNCTION__);
5116 if (tny_list_get_length (header_list) == 1) {
5117 TnyIterator *iter = tny_list_create_iterator (header_list);
5118 header = TNY_HEADER (tny_iterator_get_current (iter));
5119 g_object_unref (iter);
5123 if (!header || !TNY_IS_HEADER(header)) {
5124 g_warning ("%s: header is not valid", __FUNCTION__);
5128 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5129 header, &msg_view_window);
5130 flags = tny_header_get_flags (header);
5131 if (!(flags & TNY_HEADER_FLAG_CACHED))
5134 if (msg_view_window != NULL)
5135 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5137 /* do nothing; uid was registered before, so window is probably on it's way */
5138 g_warning ("debug: header %p has already been registered", header);
5141 ModestMailOperation *mail_op = NULL;
5142 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5143 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5144 modest_ui_actions_disk_operations_error_handler,
5146 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5147 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5149 g_object_unref (mail_op);
5152 g_object_unref (header);
5154 g_object_unref (header_list);
5158 * Checks if we need a connection to do the transfer and if the user
5159 * wants to connect to complete it
5162 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5163 TnyFolderStore *src_folder,
5165 TnyFolder *dst_folder,
5166 gboolean delete_originals,
5167 gboolean *need_connection,
5170 TnyAccount *src_account;
5171 gint uncached_msgs = 0;
5173 uncached_msgs = header_list_count_uncached_msgs (headers);
5175 /* We don't need any further check if
5177 * 1- the source folder is local OR
5178 * 2- the device is already online
5180 if (!modest_tny_folder_store_is_remote (src_folder) ||
5181 tny_device_is_online (modest_runtime_get_device())) {
5182 *need_connection = FALSE;
5187 /* We must ask for a connection when
5189 * - the message(s) is not already cached OR
5190 * - the message(s) is cached but the leave_on_server setting
5191 * is FALSE (because we need to sync the source folder to
5192 * delete the message from the server (for IMAP we could do it
5193 * offline, it'll take place the next time we get a
5196 src_account = get_account_from_folder_store (src_folder);
5197 if (uncached_msgs > 0) {
5201 *need_connection = TRUE;
5202 num_headers = tny_list_get_length (headers);
5203 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5205 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5206 GTK_RESPONSE_CANCEL) {
5212 /* The transfer is possible and the user wants to */
5215 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5216 const gchar *account_name;
5217 gboolean leave_on_server;
5219 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5220 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5223 if (leave_on_server == TRUE) {
5224 *need_connection = FALSE;
5226 *need_connection = TRUE;
5229 *need_connection = FALSE;
5234 g_object_unref (src_account);
5238 xfer_messages_error_handler (ModestMailOperation *mail_op,
5241 ModestWindow *main_window = NULL;
5243 /* Disable next automatic folder selection */
5244 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5245 FALSE); /* don't create */
5247 GObject *win = modest_mail_operation_get_source (mail_op);
5248 modest_platform_run_information_dialog ((GtkWindow *) win,
5249 _("mail_in_ui_folder_move_target_error"),
5252 g_object_unref (win);
5254 move_to_helper_destroyer (user_data);
5258 TnyFolderStore *dst_folder;
5263 * Utility function that transfer messages from both the main window
5264 * and the msg view window when using the "Move to" dialog
5267 xfer_messages_performer (gboolean canceled,
5269 GtkWindow *parent_window,
5270 TnyAccount *account,
5273 ModestWindow *win = MODEST_WINDOW (parent_window);
5274 TnyAccount *dst_account = NULL;
5275 gboolean dst_forbids_message_add = FALSE;
5276 XferMsgsHelper *helper;
5277 MoveToHelper *movehelper;
5278 ModestMailOperation *mail_op;
5280 helper = (XferMsgsHelper *) user_data;
5282 if (canceled || err) {
5283 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5284 /* Show the proper error message */
5285 modest_ui_actions_on_account_connection_error (parent_window, account);
5290 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5292 /* tinymail will return NULL for local folders it seems */
5293 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5294 modest_tny_account_get_protocol_type (dst_account),
5295 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5296 g_object_unref (dst_account);
5298 if (dst_forbids_message_add) {
5299 modest_platform_information_banner (GTK_WIDGET (win),
5301 ngettext("mail_in_ui_folder_move_target_error",
5302 "mail_in_ui_folder_move_targets_error",
5303 tny_list_get_length (helper->headers)));
5307 movehelper = g_new0 (MoveToHelper, 1);
5308 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5309 _CS("ckct_nw_pasting"));
5310 if (movehelper->banner != NULL) {
5311 g_object_ref (movehelper->banner);
5312 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5315 if (MODEST_IS_MAIN_WINDOW (win)) {
5316 GtkWidget *header_view =
5317 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5318 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5319 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5322 /* Perform the mail operation */
5323 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5324 xfer_messages_error_handler,
5326 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5329 modest_mail_operation_xfer_msgs (mail_op,
5331 TNY_FOLDER (helper->dst_folder),
5336 g_object_unref (G_OBJECT (mail_op));
5338 g_object_unref (helper->dst_folder);
5339 g_object_unref (helper->headers);
5340 g_slice_free (XferMsgsHelper, helper);
5344 TnyFolder *src_folder;
5345 TnyFolderStore *dst_folder;
5346 gboolean delete_original;
5347 GtkWidget *folder_view;
5351 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5352 TnyAccount *account, gpointer user_data)
5354 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5355 GtkTreeSelection *sel;
5356 ModestMailOperation *mail_op = NULL;
5358 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5359 g_object_unref (G_OBJECT (info->src_folder));
5360 g_object_unref (G_OBJECT (info->dst_folder));
5365 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5366 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5367 _CS("ckct_nw_pasting"));
5368 if (helper->banner != NULL) {
5369 g_object_ref (helper->banner);
5370 gtk_widget_show (GTK_WIDGET(helper->banner));
5372 /* Clean folder on header view before moving it */
5373 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5374 gtk_tree_selection_unselect_all (sel);
5376 /* Let gtk events run. We need that the folder
5377 view frees its reference to the source
5378 folder *before* issuing the mail operation
5379 so we need the signal handler of selection
5380 changed to happen before the mail
5382 while (gtk_events_pending ())
5383 gtk_main_iteration (); */
5386 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5387 modest_ui_actions_move_folder_error_handler,
5388 info->src_folder, NULL);
5389 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5392 /* Select *after* the changes */
5393 /* TODO: this function hangs UI after transfer */
5394 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5395 /* TNY_FOLDER (src_folder), TRUE); */
5397 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5398 TNY_FOLDER (info->dst_folder), TRUE);
5399 modest_mail_operation_xfer_folder (mail_op,
5400 TNY_FOLDER (info->src_folder),
5402 info->delete_original,
5405 g_object_unref (G_OBJECT (info->src_folder));
5407 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5410 /* Unref mail operation */
5411 g_object_unref (G_OBJECT (mail_op));
5412 g_object_unref (G_OBJECT (info->dst_folder));
5417 get_account_from_folder_store (TnyFolderStore *folder_store)
5419 if (TNY_IS_ACCOUNT (folder_store))
5420 return g_object_ref (folder_store);
5422 return tny_folder_get_account (TNY_FOLDER (folder_store));
5426 * UI handler for the "Move to" action when invoked from the
5430 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5431 GtkWidget *folder_view,
5432 TnyFolderStore *dst_folder,
5433 ModestMainWindow *win)
5435 ModestHeaderView *header_view = NULL;
5436 TnyFolderStore *src_folder = NULL;
5438 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5440 /* Get the source folder */
5441 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5443 /* Get header view */
5444 header_view = (ModestHeaderView *)
5445 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5447 /* Get folder or messages to transfer */
5448 if (gtk_widget_is_focus (folder_view)) {
5449 gboolean do_xfer = TRUE;
5451 /* Allow only to transfer folders to the local root folder */
5452 if (TNY_IS_ACCOUNT (dst_folder) &&
5453 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5454 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5456 } else if (!TNY_IS_FOLDER (src_folder)) {
5457 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5462 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5463 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5465 info->src_folder = g_object_ref (src_folder);
5466 info->dst_folder = g_object_ref (dst_folder);
5467 info->delete_original = TRUE;
5468 info->folder_view = folder_view;
5470 connect_info->callback = on_move_folder_cb;
5471 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5472 connect_info->data = info;
5474 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5475 TNY_FOLDER_STORE (src_folder),
5478 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5481 headers = modest_header_view_get_selected_headers(header_view);
5483 /* Transfer the messages */
5484 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5485 headers, TNY_FOLDER (dst_folder));
5487 g_object_unref (headers);
5491 g_object_unref (src_folder);
5496 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5497 TnyFolder *src_folder,
5499 TnyFolder *dst_folder)
5501 gboolean need_connection = TRUE;
5502 gboolean do_xfer = TRUE;
5503 XferMsgsHelper *helper;
5505 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5506 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5507 g_return_if_fail (TNY_IS_LIST (headers));
5509 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5510 headers, TNY_FOLDER (dst_folder),
5511 TRUE, &need_connection,
5514 /* If we don't want to transfer just return */
5518 /* Create the helper */
5519 helper = g_slice_new (XferMsgsHelper);
5520 helper->dst_folder = g_object_ref (dst_folder);
5521 helper->headers = g_object_ref (headers);
5523 if (need_connection) {
5524 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5525 connect_info->callback = xfer_messages_performer;
5526 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5527 connect_info->data = helper;
5529 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5530 TNY_FOLDER_STORE (src_folder),
5533 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5534 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5535 src_account, helper);
5536 g_object_unref (src_account);
5541 * UI handler for the "Move to" action when invoked from the
5542 * ModestMsgViewWindow
5545 modest_ui_actions_on_window_move_to (GtkAction *action,
5547 TnyFolderStore *dst_folder,
5550 TnyFolder *src_folder = NULL;
5552 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5555 TnyHeader *header = NULL;
5558 iter = tny_list_create_iterator (headers);
5559 header = (TnyHeader *) tny_iterator_get_current (iter);
5560 src_folder = tny_header_get_folder (header);
5562 /* Transfer the messages */
5563 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5565 TNY_FOLDER (dst_folder));
5568 g_object_unref (header);
5569 g_object_unref (iter);
5570 g_object_unref (src_folder);
5575 modest_ui_actions_on_move_to (GtkAction *action,
5578 GtkWidget *dialog = NULL, *folder_view = NULL;
5579 ModestMainWindow *main_window;
5580 MoveToInfo *helper = NULL;
5582 g_return_if_fail (MODEST_IS_WINDOW (win));
5584 /* Get the main window if exists */
5585 if (MODEST_IS_MAIN_WINDOW (win))
5586 main_window = MODEST_MAIN_WINDOW (win);
5589 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5590 FALSE)); /* don't create */
5592 /* Get the folder view widget if exists */
5594 folder_view = modest_main_window_get_child_widget (main_window,
5595 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5599 /* Create and run the dialog */
5600 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view);
5601 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5602 GTK_WINDOW (dialog),
5606 helper = g_slice_new0 (MoveToInfo);
5607 helper->list = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5610 /* Listen to response signal */
5611 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5613 /* Show the dialog */
5614 gtk_widget_show (dialog);
5618 * Calls #HeadersFunc for each header already selected in the main
5619 * window or the message currently being shown in the msg view window
5622 do_headers_action (ModestWindow *win,
5626 TnyList *headers_list = NULL;
5627 TnyIterator *iter = NULL;
5628 TnyHeader *header = NULL;
5629 TnyFolder *folder = NULL;
5632 headers_list = get_selected_headers (win);
5636 /* Get the folder */
5637 iter = tny_list_create_iterator (headers_list);
5638 header = TNY_HEADER (tny_iterator_get_current (iter));
5640 folder = tny_header_get_folder (header);
5641 g_object_unref (header);
5644 /* Call the function for each header */
5645 while (!tny_iterator_is_done (iter)) {
5646 header = TNY_HEADER (tny_iterator_get_current (iter));
5647 func (header, win, user_data);
5648 g_object_unref (header);
5649 tny_iterator_next (iter);
5652 /* Trick: do a poke status in order to speed up the signaling
5654 tny_folder_poke_status (folder);
5657 g_object_unref (folder);
5658 g_object_unref (iter);
5659 g_object_unref (headers_list);
5663 modest_ui_actions_view_attachment (GtkAction *action,
5664 ModestWindow *window)
5666 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5667 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5669 /* not supported window for this action */
5670 g_return_if_reached ();
5675 modest_ui_actions_save_attachments (GtkAction *action,
5676 ModestWindow *window)
5678 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5680 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5683 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5685 /* not supported window for this action */
5686 g_return_if_reached ();
5691 modest_ui_actions_remove_attachments (GtkAction *action,
5692 ModestWindow *window)
5694 if (MODEST_IS_MAIN_WINDOW (window)) {
5695 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5696 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5697 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5699 /* not supported window for this action */
5700 g_return_if_reached ();
5705 modest_ui_actions_on_settings (GtkAction *action,
5710 dialog = modest_platform_get_global_settings_dialog ();
5711 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5712 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5713 gtk_widget_show_all (dialog);
5715 gtk_dialog_run (GTK_DIALOG (dialog));
5717 gtk_widget_destroy (dialog);
5721 modest_ui_actions_on_help (GtkAction *action,
5724 /* Help app is not available at all in fremantle */
5725 #ifndef MODEST_TOOLKIT_HILDON2
5726 const gchar *help_id;
5728 g_return_if_fail (win && GTK_IS_WINDOW(win));
5730 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5733 modest_platform_show_help (GTK_WINDOW (win), help_id);
5738 modest_ui_actions_on_csm_help (GtkAction *action,
5741 /* Help app is not available at all in fremantle */
5742 #ifndef MODEST_TOOLKIT_HILDON2
5744 const gchar* help_id = NULL;
5745 GtkWidget *folder_view;
5746 TnyFolderStore *folder_store;
5748 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5750 /* Get selected folder */
5751 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5752 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5753 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5755 /* Switch help_id */
5756 if (folder_store && TNY_IS_FOLDER (folder_store))
5757 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5760 g_object_unref (folder_store);
5763 modest_platform_show_help (GTK_WINDOW (win), help_id);
5765 modest_ui_actions_on_help (action, win);
5770 retrieve_contents_cb (ModestMailOperation *mail_op,
5777 /* We only need this callback to show an error in case of
5778 memory low condition */
5779 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5783 retrieve_msg_contents_performer (gboolean canceled,
5785 GtkWindow *parent_window,
5786 TnyAccount *account,
5789 ModestMailOperation *mail_op;
5790 TnyList *headers = TNY_LIST (user_data);
5792 if (err || canceled) {
5793 check_memory_full_error ((GtkWidget *) parent_window, err);
5797 /* Create mail operation */
5798 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5799 modest_ui_actions_disk_operations_error_handler,
5801 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5802 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5805 g_object_unref (mail_op);
5807 g_object_unref (headers);
5808 g_object_unref (account);
5812 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5813 ModestWindow *window)
5815 TnyList *headers = NULL;
5816 TnyAccount *account = NULL;
5817 TnyIterator *iter = NULL;
5818 TnyHeader *header = NULL;
5819 TnyFolder *folder = NULL;
5822 headers = get_selected_headers (window);
5826 /* Pick the account */
5827 iter = tny_list_create_iterator (headers);
5828 header = TNY_HEADER (tny_iterator_get_current (iter));
5829 folder = tny_header_get_folder (header);
5830 account = tny_folder_get_account (folder);
5831 g_object_unref (folder);
5832 g_object_unref (header);
5833 g_object_unref (iter);
5835 /* Connect and perform the message retrieval */
5836 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5837 g_object_ref (account),
5838 retrieve_msg_contents_performer,
5839 g_object_ref (headers));
5842 g_object_unref (account);
5843 g_object_unref (headers);
5847 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5849 g_return_if_fail (MODEST_IS_WINDOW (window));
5852 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5856 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5858 g_return_if_fail (MODEST_IS_WINDOW (window));
5861 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5865 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5866 ModestWindow *window)
5868 g_return_if_fail (MODEST_IS_WINDOW (window));
5871 modest_ui_actions_check_menu_dimming_rules (window);
5875 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5876 ModestWindow *window)
5878 g_return_if_fail (MODEST_IS_WINDOW (window));
5881 modest_ui_actions_check_menu_dimming_rules (window);
5885 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5886 ModestWindow *window)
5888 g_return_if_fail (MODEST_IS_WINDOW (window));
5891 modest_ui_actions_check_menu_dimming_rules (window);
5895 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5896 ModestWindow *window)
5898 g_return_if_fail (MODEST_IS_WINDOW (window));
5901 modest_ui_actions_check_menu_dimming_rules (window);
5905 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5906 ModestWindow *window)
5908 g_return_if_fail (MODEST_IS_WINDOW (window));
5911 modest_ui_actions_check_menu_dimming_rules (window);
5915 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5916 ModestWindow *window)
5918 g_return_if_fail (MODEST_IS_WINDOW (window));
5921 modest_ui_actions_check_menu_dimming_rules (window);
5925 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5926 ModestWindow *window)
5928 g_return_if_fail (MODEST_IS_WINDOW (window));
5931 modest_ui_actions_check_menu_dimming_rules (window);
5935 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5936 ModestWindow *window)
5938 g_return_if_fail (MODEST_IS_WINDOW (window));
5941 modest_ui_actions_check_menu_dimming_rules (window);
5945 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5946 ModestWindow *window)
5948 g_return_if_fail (MODEST_IS_WINDOW (window));
5951 modest_ui_actions_check_menu_dimming_rules (window);
5955 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5957 g_return_if_fail (MODEST_IS_WINDOW (window));
5959 /* we check for low-mem; in that case, show a warning, and don't allow
5962 if (modest_platform_check_memory_low (window, TRUE))
5965 modest_platform_show_search_messages (GTK_WINDOW (window));
5969 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5971 g_return_if_fail (MODEST_IS_WINDOW (win));
5974 /* we check for low-mem; in that case, show a warning, and don't allow
5975 * for the addressbook
5977 if (modest_platform_check_memory_low (win, TRUE))
5981 modest_platform_show_addressbook (GTK_WINDOW (win));
5986 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5987 ModestWindow *window)
5989 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5991 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5995 on_send_receive_finished (ModestMailOperation *mail_op,
5998 GtkWidget *header_view, *folder_view;
5999 TnyFolderStore *folder_store;
6000 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6002 /* Set send/receive operation finished */
6003 modest_main_window_notify_send_receive_completed (main_win);
6005 /* Don't refresh the current folder if there were any errors */
6006 if (modest_mail_operation_get_status (mail_op) !=
6007 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6010 /* Refresh the current folder if we're viewing a window. We do
6011 this because the user won't be able to see the new mails in
6012 the selected folder after a Send&Receive because it only
6013 performs a poke_status, i.e, only the number of read/unread
6014 messages is updated, but the new headers are not
6016 folder_view = modest_main_window_get_child_widget (main_win,
6017 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6021 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6023 /* Do not need to refresh INBOX again because the
6024 update_account does it always automatically */
6025 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6026 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6027 ModestMailOperation *refresh_op;
6029 header_view = modest_main_window_get_child_widget (main_win,
6030 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6032 /* We do not need to set the contents style
6033 because it hasn't changed. We also do not
6034 need to save the widget status. Just force
6036 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6037 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6038 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6039 folder_refreshed_cb, main_win);
6040 g_object_unref (refresh_op);
6044 g_object_unref (folder_store);
6049 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6055 const gchar* server_name = NULL;
6056 TnyTransportAccount *server_account;
6057 gchar *message = NULL;
6059 /* Don't show anything if the user cancelled something or the
6060 * send receive request is not interactive. Authentication
6061 * errors are managed by the account store so no need to show
6062 * a dialog here again */
6063 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6064 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6065 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6069 /* Get the server name: */
6071 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6073 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6075 g_return_if_reached ();
6077 /* Show the appropriate message text for the GError: */
6078 switch (err->code) {
6079 case TNY_SERVICE_ERROR_CONNECT:
6080 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6082 case TNY_SERVICE_ERROR_SEND:
6083 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6085 case TNY_SERVICE_ERROR_UNAVAILABLE:
6086 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6089 g_warning ("%s: unexpected ERROR %d",
6090 __FUNCTION__, err->code);
6091 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6095 modest_platform_run_information_dialog (NULL, message, FALSE);
6097 g_object_unref (server_account);
6101 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6106 ModestMainWindow *main_window = NULL;
6107 ModestWindowMgr *mgr = NULL;
6108 GtkWidget *folder_view = NULL, *header_view = NULL;
6109 TnyFolderStore *selected_folder = NULL;
6110 TnyFolderType folder_type;
6112 mgr = modest_runtime_get_window_mgr ();
6113 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6114 FALSE));/* don't create */
6118 /* Check if selected folder is OUTBOX */
6119 folder_view = modest_main_window_get_child_widget (main_window,
6120 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6121 header_view = modest_main_window_get_child_widget (main_window,
6122 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6124 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6125 if (!TNY_IS_FOLDER (selected_folder))
6128 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6129 #if GTK_CHECK_VERSION(2, 8, 0)
6130 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6131 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6132 GtkTreeViewColumn *tree_column;
6134 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6135 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6137 gtk_tree_view_column_queue_resize (tree_column);
6140 gtk_widget_queue_draw (header_view);
6143 /* Rerun dimming rules, because the message could become deletable for example */
6144 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6145 MODEST_DIMMING_RULES_TOOLBAR);
6146 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6147 MODEST_DIMMING_RULES_MENU);
6151 if (selected_folder != NULL)
6152 g_object_unref (selected_folder);
6156 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6157 TnyAccount *account)
6159 ModestProtocolType protocol_type;
6160 ModestProtocol *protocol;
6161 gchar *error_note = NULL;
6163 protocol_type = modest_tny_account_get_protocol_type (account);
6164 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6167 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6168 if (error_note == NULL) {
6169 g_warning ("%s: This should not be reached", __FUNCTION__);
6171 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6172 g_free (error_note);
6177 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6181 TnyFolderStore *folder = NULL;
6182 TnyAccount *account = NULL;
6183 ModestProtocolType proto;
6184 ModestProtocol *protocol;
6185 TnyHeader *header = NULL;
6187 if (MODEST_IS_MAIN_WINDOW (win)) {
6188 GtkWidget *header_view;
6189 TnyList* headers = NULL;
6191 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6192 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6193 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6194 if (!headers || tny_list_get_length (headers) == 0) {
6196 g_object_unref (headers);
6199 iter = tny_list_create_iterator (headers);
6200 header = TNY_HEADER (tny_iterator_get_current (iter));
6201 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6202 g_object_unref (iter);
6203 g_object_unref (headers);
6204 #ifdef MODEST_TOOLKIT_HILDON2
6205 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6206 GtkWidget *header_view;
6207 TnyList* headers = NULL;
6209 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6210 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6211 if (!headers || tny_list_get_length (headers) == 0) {
6213 g_object_unref (headers);
6216 iter = tny_list_create_iterator (headers);
6217 header = TNY_HEADER (tny_iterator_get_current (iter));
6218 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6219 g_object_unref (iter);
6220 g_object_unref (headers);
6222 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6223 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6224 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6227 /* Get the account type */
6228 account = tny_folder_get_account (TNY_FOLDER (folder));
6229 proto = modest_tny_account_get_protocol_type (account);
6230 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6233 subject = tny_header_dup_subject (header);
6234 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6238 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6242 g_object_unref (account);
6243 g_object_unref (folder);
6244 g_object_unref (header);
6250 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6251 const gchar *account_name,
6252 const gchar *account_title)
6254 ModestAccountMgr *account_mgr;
6257 ModestProtocol *protocol;
6258 gboolean removed = FALSE;
6260 g_return_val_if_fail (account_name, FALSE);
6261 g_return_val_if_fail (account_title, FALSE);
6263 account_mgr = modest_runtime_get_account_mgr();
6265 /* The warning text depends on the account type: */
6266 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6267 modest_account_mgr_get_store_protocol (account_mgr,
6269 txt = modest_protocol_get_translation (protocol,
6270 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6273 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6275 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6279 if (response == GTK_RESPONSE_OK) {
6280 /* Remove account. If it succeeds then it also removes
6281 the account from the ModestAccountView: */
6282 gboolean is_default = FALSE;
6283 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6284 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6286 g_free (default_account_name);
6288 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6290 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);