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"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.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>
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #include "maemo/modest-maemo-utils.h"
55 #include "maemo/modest-hildon-includes.h"
56 #endif /* MODEST_PLATFORM_MAEMO */
58 #include "widgets/modest-ui-constants.h"
59 #include <widgets/modest-main-window.h>
60 #include <widgets/modest-msg-view-window.h>
61 #include <widgets/modest-account-view-window.h>
62 #include <widgets/modest-details-dialog.h>
63 #include <widgets/modest-attachments-view.h>
64 #include "widgets/modest-folder-view.h"
65 #include "widgets/modest-global-settings-dialog.h"
66 #include "modest-connection-specific-smtp-window.h"
67 #include "modest-account-mgr-helpers.h"
68 #include "modest-mail-operation.h"
69 #include "modest-text-utils.h"
71 #ifdef MODEST_HAVE_EASYSETUP
72 #include "easysetup/modest-easysetup-wizard.h"
73 #endif /* MODEST_HAVE_EASYSETUP */
75 #include <modest-widget-memory.h>
76 #include <tny-error.h>
77 #include <tny-simple-list.h>
78 #include <tny-msg-view.h>
79 #include <tny-device.h>
80 #include <tny-merge-folder.h>
82 #include <gtkhtml/gtkhtml.h>
84 typedef struct _GetMsgAsyncHelper {
86 ModestMailOperation *mail_op;
93 typedef enum _ReplyForwardAction {
99 typedef struct _ReplyForwardHelper {
100 guint reply_forward_type;
101 ReplyForwardAction action;
103 GtkWidget *parent_window;
104 } ReplyForwardHelper;
106 typedef struct _PasteAsAttachmentHelper {
107 ModestMsgEditWindow *window;
109 } PasteAsAttachmentHelper;
113 * The do_headers_action uses this kind of functions to perform some
114 * action to each member of a list of headers
116 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
118 static void do_headers_action (ModestWindow *win,
122 static void open_msg_cb (ModestMailOperation *mail_op,
127 static void reply_forward_cb (ModestMailOperation *mail_op,
132 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
134 static void folder_refreshed_cb (ModestMailOperation *mail_op,
138 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
139 ModestMailOperationState *state,
142 static gboolean download_uncached_messages (TnyList *header_list,
147 /* Show the account creation wizard dialog.
148 * returns: TRUE if an account was created. FALSE if the user cancelled.
151 modest_run_account_setup_wizard (ModestWindow *win)
153 gboolean result = FALSE;
156 wizard = modest_window_mgr_get_easysetup_dialog
157 (modest_runtime_get_window_mgr());
159 /* old wizard is active already; present it and
160 * act as if the user cancelled the non-existing
163 printf ("wizard already active\n");
166 /* there is no such wizard yet */
167 wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
168 modest_window_mgr_set_easysetup_dialog
169 (modest_runtime_get_window_mgr(), GTK_DIALOG(wizard));
173 /* always present a main window in the background
174 * we do it here, so we cannot end up with to wizards (as this
175 * function might be called in modest_window_mgr_get_main_window as well */
177 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
179 /* make sure the mainwindow is visible */
180 gtk_widget_show_all (GTK_WIDGET(win));
181 gtk_window_present (GTK_WINDOW(win));
184 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
186 /* Don't make this a modal window, because secondary windows will then
187 * be unusable, freezing the UI: */
188 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
190 gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
191 if (dialog_response == GTK_RESPONSE_CANCEL)
194 /* Check whether an account was created: */
195 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
198 gtk_widget_destroy (GTK_WIDGET (wizard));
200 /* clear it from the window mgr */
201 modest_window_mgr_set_easysetup_dialog
202 (modest_runtime_get_window_mgr(), NULL);
209 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
212 const gchar *authors[] = {
213 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
216 about = gtk_about_dialog_new ();
217 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
218 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
219 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
220 _("Copyright (c) 2006, Nokia Corporation\n"
221 "All rights reserved."));
222 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
223 _("a modest e-mail client\n\n"
224 "design and implementation: Dirk-Jan C. Binnema\n"
225 "contributions from the fine people at KC and Ig\n"
226 "uses the tinymail email framework written by Philip van Hoof"));
227 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
228 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
229 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
230 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
232 gtk_dialog_run (GTK_DIALOG (about));
233 gtk_widget_destroy(about);
237 * Gets the list of currently selected messages. If the win is the
238 * main window, then it returns a newly allocated list of the headers
239 * selected in the header view. If win is the msg view window, then
240 * the value returned is a list with just a single header.
242 * The caller of this funcion must free the list.
245 get_selected_headers (ModestWindow *win)
247 if (MODEST_IS_MAIN_WINDOW(win)) {
248 GtkWidget *header_view;
250 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
251 MODEST_WIDGET_TYPE_HEADER_VIEW);
252 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
254 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
255 /* for MsgViewWindows, we simply return a list with one element */
257 TnyList *list = NULL;
259 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
260 if (header != NULL) {
261 list = tny_simple_list_new ();
262 tny_list_prepend (list, G_OBJECT(header));
263 g_object_unref (G_OBJECT(header));
273 headers_action_mark_as_read (TnyHeader *header,
277 TnyHeaderFlags flags;
279 g_return_if_fail (TNY_IS_HEADER(header));
281 flags = tny_header_get_flags (header);
282 if (flags & TNY_HEADER_FLAG_SEEN) return;
283 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
287 headers_action_mark_as_unread (TnyHeader *header,
291 TnyHeaderFlags flags;
293 g_return_if_fail (TNY_IS_HEADER(header));
295 flags = tny_header_get_flags (header);
296 if (flags & TNY_HEADER_FLAG_SEEN) {
297 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
301 /** A convenience method, because deleting a message is
302 * otherwise complicated, and it's best to change it in one place
305 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
307 ModestMailOperation *mail_op = NULL;
308 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
309 win ? G_OBJECT(win) : NULL);
310 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
313 /* Always delete. TODO: Move to trash still not supported */
314 modest_mail_operation_remove_msg (mail_op, header, FALSE);
315 g_object_unref (G_OBJECT (mail_op));
318 /** A convenience method, because deleting a message is
319 * otherwise complicated, and it's best to change it in one place
322 void modest_do_messages_delete (TnyList *headers, ModestWindow *win)
324 ModestMailOperation *mail_op = NULL;
325 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
326 win ? G_OBJECT(win) : NULL);
327 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
330 /* Always delete. TODO: Move to trash still not supported */
331 modest_mail_operation_remove_msgs (mail_op, headers, FALSE);
332 g_object_unref (G_OBJECT (mail_op));
336 /* headers_action_delete (TnyHeader *header, */
337 /* ModestWindow *win, */
338 /* gpointer user_data) */
340 /* modest_do_message_delete (header, win); */
344 /** After deleing a message that is currently visible in a window,
345 * show the next message from the list, or close the window if there are no more messages.
347 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
349 /* Close msg view window or select next */
350 if (modest_msg_view_window_last_message_selected (win) &&
351 modest_msg_view_window_first_message_selected (win)) {
352 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
354 if (!modest_msg_view_window_select_next_message (win)) {
356 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
362 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
364 TnyList *header_list = NULL;
365 TnyIterator *iter = NULL;
366 TnyHeader *header = NULL;
367 gchar *message = NULL;
370 ModestWindowMgr *mgr;
371 GtkWidget *header_view = NULL;
373 g_return_if_fail (MODEST_IS_WINDOW(win));
375 /* Check first if the header view has the focus */
376 if (MODEST_IS_MAIN_WINDOW (win)) {
378 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
379 MODEST_WIDGET_TYPE_HEADER_VIEW);
380 if (!gtk_widget_is_focus (header_view))
384 /* Get the headers, either from the header view (if win is the main window),
385 * or from the message view window: */
386 header_list = get_selected_headers (win);
387 if (!header_list) return;
389 /* Check if any of the headers are already opened, or in the process of being opened */
390 if (MODEST_IS_MAIN_WINDOW (win)) {
392 iter = tny_list_create_iterator (header_list);
394 mgr = modest_runtime_get_window_mgr ();
395 while (!tny_iterator_is_done (iter) && !found) {
396 header = TNY_HEADER (tny_iterator_get_current (iter));
398 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
399 g_object_unref (header);
402 tny_iterator_next (iter);
404 g_object_unref (iter);
409 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
410 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
412 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
416 g_object_unref (header_list);
422 if (tny_list_get_length(header_list) == 1) {
423 iter = tny_list_create_iterator (header_list);
424 header = TNY_HEADER (tny_iterator_get_current (iter));
426 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
427 g_object_unref (header);
430 g_object_unref (iter);
432 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
433 tny_list_get_length(header_list)), desc);
435 /* Confirmation dialog */
436 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
440 if (response == GTK_RESPONSE_OK) {
441 ModestWindow *main_window = NULL;
442 ModestWindowMgr *mgr = NULL;
443 GtkTreeModel *model = NULL;
444 GtkTreeSelection *sel = NULL;
445 GList *sel_list = NULL, *tmp = NULL;
446 GtkTreeRowReference *row_reference = NULL;
447 GtkTreePath *next_path = NULL;
450 /* Find last selected row */
451 if (MODEST_IS_MAIN_WINDOW (win)) {
452 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
453 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
454 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
455 for (tmp=sel_list; tmp; tmp=tmp->next) {
456 if (tmp->next == NULL) {
457 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
458 gtk_tree_path_next (next_path);
459 row_reference = gtk_tree_row_reference_new (model, next_path);
460 gtk_tree_path_free (next_path);
465 /* Disable window dimming management */
466 modest_window_disable_dimming (MODEST_WINDOW(win));
468 /* Remove each header. If it's a view window header_view == NULL */
469 /* do_headers_action (win, headers_action_delete, header_view); */
470 modest_do_messages_delete (header_list, win);
473 /* Enable window dimming management */
474 gtk_tree_selection_unselect_all (sel);
475 modest_window_enable_dimming (MODEST_WINDOW(win));
477 /* FIXME: May be folder_monitor will also refilter treemode on EXPUNGE changes ? */
478 /* refresh the header view (removing marked-as-deleted) */
479 /* modest_header_view_refilter (MODEST_HEADER_VIEW(header_view)); */
481 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
482 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
484 /* Get main window */
485 mgr = modest_runtime_get_window_mgr ();
486 main_window = modest_window_mgr_get_main_window (mgr);
489 /* Move cursor to next row */
492 /* Select next row */
493 if (gtk_tree_row_reference_valid (row_reference)) {
494 next_path = gtk_tree_row_reference_get_path (row_reference);
495 gtk_tree_selection_select_path (sel, next_path);
496 gtk_tree_path_free (next_path);
498 if (row_reference != NULL)
499 gtk_tree_row_reference_free (row_reference);
503 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
507 /* Update toolbar dimming state */
508 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
511 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
512 g_list_free (sel_list);
518 g_object_unref (header_list);
524 /* delete either message or folder, based on where we are */
526 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
528 g_return_if_fail (MODEST_IS_WINDOW(win));
530 /* Check first if the header view has the focus */
531 if (MODEST_IS_MAIN_WINDOW (win)) {
533 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
534 MODEST_WIDGET_TYPE_FOLDER_VIEW);
535 if (gtk_widget_is_focus (w)) {
536 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
540 modest_ui_actions_on_delete_message (action, win);
546 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
548 #ifdef MODEST_PLATFORM_MAEMO
549 modest_osso_save_state();
550 #endif /* MODEST_PLATFORM_MAEMO */
552 g_debug ("closing down, clearing %d item(s) from operation queue",
553 modest_mail_operation_queue_num_elements
554 (modest_runtime_get_mail_operation_queue()));
556 /* cancel all outstanding operations */
557 modest_mail_operation_queue_cancel_all
558 (modest_runtime_get_mail_operation_queue());
560 g_debug ("queue has been cleared");
562 /* note: when modest-tny-account-store is finalized,
563 it will automatically set all network connections
570 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
574 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
576 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
577 /* gtk_widget_destroy (GTK_WIDGET (win)); */
578 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
579 /* gboolean ret_value; */
580 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
581 /* } else if (MODEST_IS_WINDOW (win)) { */
582 /* gtk_widget_destroy (GTK_WIDGET (win)); */
584 /* g_return_if_reached (); */
589 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
591 GtkClipboard *clipboard = NULL;
592 gchar *selection = NULL;
594 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
595 selection = gtk_clipboard_wait_for_text (clipboard);
597 /* Question: why is the clipboard being used here?
598 * It doesn't really make a lot of sense. */
602 modest_address_book_add_address (selection);
608 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
610 /* This is currently only implemented for Maemo */
611 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
612 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
613 modest_run_account_setup_wizard (win);
616 /* Show the list of accounts: */
617 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
618 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
620 /* Don't make this a modal window, because secondary windows will then
621 * be unusable, freezing the UI: */
622 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
623 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
626 GtkWidget *dialog, *label;
628 /* Create the widgets */
630 dialog = gtk_dialog_new_with_buttons ("Message",
632 GTK_DIALOG_DESTROY_WITH_PARENT,
636 label = gtk_label_new ("Hello World!");
638 /* Ensure that the dialog box is destroyed when the user responds. */
640 g_signal_connect_swapped (dialog, "response",
641 G_CALLBACK (gtk_widget_destroy),
644 /* Add the label, and show everything we've added to the dialog. */
646 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
648 gtk_widget_show_all (dialog);
649 #endif /* MODEST_PLATFORM_MAEMO */
653 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
655 ModestWindow *main_window = MODEST_WINDOW (user_data);
657 /* Save any changes. */
658 modest_connection_specific_smtp_window_save_server_accounts (
659 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
660 modest_window_get_active_account (main_window));
661 gtk_widget_destroy (GTK_WIDGET (window));
667 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
669 /* This is currently only implemented for Maemo,
670 * because it requires an API (libconic) to detect different connection
673 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
675 /* Create the window if necessary: */
676 const gchar *active_account_name = modest_window_get_active_account (win);
678 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
679 * or show the default account?
680 * If we show the default account then the account name should be shown in
681 * the window when we show it. */
682 if (!active_account_name) {
683 g_warning ("%s: No account is active.", __FUNCTION__);
687 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
688 modest_connection_specific_smtp_window_fill_with_connections (
689 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
690 modest_runtime_get_account_mgr(),
691 active_account_name);
693 /* Show the window: */
694 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
695 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
696 gtk_widget_show (specific_window);
698 /* Save changes when the window is hidden: */
699 g_signal_connect (specific_window, "hide",
700 G_CALLBACK (on_smtp_servers_window_hide), win);
701 #endif /* MODEST_PLATFORM_MAEMO */
705 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
707 ModestWindow *msg_win = NULL;
709 TnyFolder *folder = NULL;
710 gchar *account_name = NULL;
711 gchar *from_str = NULL;
712 /* GError *err = NULL; */
713 TnyAccount *account = NULL;
714 ModestWindowMgr *mgr;
715 gchar *signature = NULL, *blank_and_signature = NULL;
717 /* if there are no accounts yet, just show the wizard */
718 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
719 const gboolean created = modest_run_account_setup_wizard (win);
724 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
726 account_name = g_strdup (modest_window_get_active_account (win));
728 g_printerr ("modest: no account found\n");
732 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
734 TNY_ACCOUNT_TYPE_STORE);
736 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
740 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
742 g_printerr ("modest: failed get from string for '%s'\n", account_name);
746 gboolean use_signature = FALSE;
747 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
750 blank_and_signature = g_strconcat ("\n", signature, NULL);
752 blank_and_signature = g_strdup ("");
757 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
759 g_printerr ("modest: failed to create new msg\n");
763 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
765 g_printerr ("modest: failed to find Drafts folder\n");
770 /* Create and register edit window */
771 /* This is destroyed by TODO. */
772 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
773 mgr = modest_runtime_get_window_mgr ();
774 modest_window_mgr_register_window (mgr, msg_win);
777 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
779 gtk_widget_show_all (GTK_WIDGET (msg_win));
782 g_free (account_name);
784 g_free (blank_and_signature);
786 g_object_unref (msg_win);
788 g_object_unref (G_OBJECT(account));
790 g_object_unref (G_OBJECT(msg));
792 g_object_unref (G_OBJECT(folder));
796 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
800 ModestMailOperationStatus status;
802 /* If there is no message or the operation was not successful */
803 status = modest_mail_operation_get_status (mail_op);
804 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
806 /* Remove the header from the preregistered uids */
807 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
817 open_msg_cb (ModestMailOperation *mail_op,
822 ModestWindowMgr *mgr = NULL;
823 ModestWindow *parent_win = NULL;
824 ModestWindow *win = NULL;
825 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
826 gchar *account = NULL;
829 /* Do nothing if there was any problem with the mail
830 operation. The error will be shown by the error_handler of
831 the mail operation */
832 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
836 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
837 folder = tny_header_get_folder (header);
839 /* Mark header as read */
840 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
843 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
845 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
847 /* Gets folder type (OUTBOX headers will be opened in edit window */
848 if (modest_tny_folder_is_local_folder (folder))
849 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
851 /* If the header is in the drafts folder then open the editor,
852 else the message view window */
853 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
854 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
855 /* we cannot edit without a valid account... */
856 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
857 const gboolean created = modest_run_account_setup_wizard(parent_win);
861 win = modest_msg_edit_window_new (msg, account, TRUE);
864 gchar *uid = modest_tny_folder_get_header_unique_id (header);
866 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
867 GtkWidget *header_view;
868 GtkTreeSelection *sel;
869 GList *sel_list = NULL;
872 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
873 MODEST_WIDGET_TYPE_HEADER_VIEW);
875 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
876 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
878 if (sel_list != NULL) {
879 GtkTreeRowReference *row_reference;
881 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
882 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
883 g_list_free (sel_list);
885 win = modest_msg_view_window_new_with_header_model (
886 msg, account, (const gchar*) uid,
887 model, row_reference);
888 gtk_tree_row_reference_free (row_reference);
890 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
893 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
898 /* Register and show new window */
900 mgr = modest_runtime_get_window_mgr ();
901 modest_window_mgr_register_window (mgr, win);
902 g_object_unref (win);
903 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
904 gtk_widget_show_all (GTK_WIDGET(win));
907 /* Update toolbar dimming state */
908 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
909 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
915 g_object_unref (parent_win);
916 g_object_unref (folder);
920 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
924 GObject *win = modest_mail_operation_get_source (mail_op);
926 error = modest_mail_operation_get_error (mail_op);
927 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
929 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
931 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
934 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
935 _("mail_ni_ui_folder_get_msg_folder_error"));
939 g_object_unref (win);
943 * This function is used by both modest_ui_actions_on_open and
944 * modest_ui_actions_on_header_activated. This way we always do the
945 * same when trying to open messages.
948 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
950 ModestWindowMgr *mgr = NULL;
951 TnyIterator *iter = NULL;
952 ModestMailOperation *mail_op = NULL;
953 TnyList *not_opened_headers = NULL;
954 TnyHeaderFlags flags = 0;
956 g_return_if_fail (headers != NULL);
958 /* Check that only one message is selected for opening */
959 if (tny_list_get_length (headers) != 1) {
960 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
961 _("mcen_ib_select_one_message"));
966 /* Look if we already have a message view for each header. If
967 true, then remove the header from the list of headers to
969 mgr = modest_runtime_get_window_mgr ();
970 iter = tny_list_create_iterator (headers);
971 not_opened_headers = tny_simple_list_new ();
973 while (!tny_iterator_is_done (iter)) {
975 ModestWindow *window = NULL;
976 TnyHeader *header = NULL;
977 gboolean found = FALSE;
979 header = TNY_HEADER (tny_iterator_get_current (iter));
981 flags = tny_header_get_flags (header);
984 found = modest_window_mgr_find_registered_header (mgr, header, &window);
986 /* Do not open again the message and present the
987 window to the user */
990 gtk_window_present (GTK_WINDOW (window));
992 /* the header has been registered already, we don't do
993 * anything but wait for the window to come up*/
994 g_debug ("header %p already registered, waiting for window", header);
996 tny_list_append (not_opened_headers, G_OBJECT (header));
1000 g_object_unref (header);
1002 tny_iterator_next (iter);
1004 g_object_unref (iter);
1007 /* If some messages would have to be downloaded, ask the user to
1008 * make a connection. It's generally easier to do this here (in the mainloop)
1009 * than later in a thread:
1011 if (tny_list_get_length (not_opened_headers) > 0) {
1013 gboolean found = FALSE;
1015 iter = tny_list_create_iterator (not_opened_headers);
1016 while (!tny_iterator_is_done (iter) && !found) {
1017 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1018 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1021 tny_iterator_next (iter);
1023 g_object_unref (header);
1025 g_object_unref (iter);
1027 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
1028 g_object_unref (not_opened_headers);
1033 /* Register the headers before actually creating the windows: */
1034 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
1035 while (!tny_iterator_is_done (iter_not_opened)) {
1036 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1038 modest_window_mgr_register_header (mgr, header);
1039 g_object_unref (header);
1042 tny_iterator_next (iter_not_opened);
1044 g_object_unref (iter_not_opened);
1045 iter_not_opened = NULL;
1047 /* Open each message */
1048 if (tny_list_get_length (not_opened_headers) > 0) {
1049 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1051 modest_ui_actions_get_msgs_full_error_handler,
1053 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1054 if (tny_list_get_length (not_opened_headers) > 1) {
1055 modest_mail_operation_get_msgs_full (mail_op,
1061 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1062 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1063 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1064 g_object_unref (header);
1065 g_object_unref (iter);
1067 g_object_unref (mail_op);
1071 if (not_opened_headers != NULL)
1072 g_object_unref (not_opened_headers);
1076 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1081 headers = get_selected_headers (win);
1086 _modest_ui_actions_open (headers, win);
1088 g_object_unref(headers);
1093 free_reply_forward_helper (gpointer data)
1095 ReplyForwardHelper *helper;
1097 helper = (ReplyForwardHelper *) data;
1098 g_free (helper->account_name);
1099 g_slice_free (ReplyForwardHelper, helper);
1103 reply_forward_cb (ModestMailOperation *mail_op,
1109 ReplyForwardHelper *rf_helper;
1110 ModestWindow *msg_win = NULL;
1111 ModestEditType edit_type;
1113 TnyAccount *account = NULL;
1114 ModestWindowMgr *mgr = NULL;
1115 gchar *signature = NULL;
1117 /* If there was any error. The mail operation could be NULL,
1118 this means that we already have the message downloaded and
1119 that we didn't do a mail operation to retrieve it */
1120 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1123 g_return_if_fail (user_data != NULL);
1124 rf_helper = (ReplyForwardHelper *) user_data;
1126 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1127 rf_helper->account_name);
1128 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1129 rf_helper->account_name,
1130 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1131 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1132 rf_helper->account_name,
1133 MODEST_ACCOUNT_SIGNATURE, FALSE);
1136 /* Create reply mail */
1137 switch (rf_helper->action) {
1140 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1141 rf_helper->reply_forward_type,
1142 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1144 case ACTION_REPLY_TO_ALL:
1146 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1147 MODEST_TNY_MSG_REPLY_MODE_ALL);
1148 edit_type = MODEST_EDIT_TYPE_REPLY;
1150 case ACTION_FORWARD:
1152 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1153 edit_type = MODEST_EDIT_TYPE_FORWARD;
1156 g_return_if_reached ();
1163 g_printerr ("modest: failed to create message\n");
1167 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1168 rf_helper->account_name,
1169 TNY_ACCOUNT_TYPE_STORE);
1171 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1175 /* Create and register the windows */
1176 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1177 mgr = modest_runtime_get_window_mgr ();
1178 modest_window_mgr_register_window (mgr, msg_win);
1180 if (rf_helper->parent_window != NULL) {
1181 gdouble parent_zoom;
1183 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1184 modest_window_set_zoom (msg_win, parent_zoom);
1187 /* Show edit window */
1188 gtk_widget_show_all (GTK_WIDGET (msg_win));
1192 g_object_unref (msg_win);
1194 g_object_unref (G_OBJECT (new_msg));
1196 g_object_unref (G_OBJECT (account));
1197 /* g_object_unref (msg); */
1198 free_reply_forward_helper (rf_helper);
1202 * Checks a list of headers. If any of them are not currently
1203 * downloaded (CACHED) then it asks the user for permission to
1206 * Returns FALSE if the user does not want to download the
1207 * messages. Returns TRUE if the user allowed the download or if all
1208 * of them are currently downloaded
1211 download_uncached_messages (TnyList *header_list,
1216 gint uncached_messages = 0;
1218 iter = tny_list_create_iterator (header_list);
1219 while (!tny_iterator_is_done (iter)) {
1222 header = TNY_HEADER (tny_iterator_get_current (iter));
1224 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1225 uncached_messages ++;
1226 g_object_unref (header);
1229 tny_iterator_next (iter);
1231 g_object_unref (iter);
1233 /* Ask for user permission to download the messages */
1235 if (uncached_messages > 0) {
1236 gboolean download = TRUE;
1237 if (!tny_device_is_online (modest_runtime_get_device())) {
1238 GtkResponseType response =
1239 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1240 ngettext("mcen_nc_get_msg",
1242 uncached_messages));
1243 if (response == GTK_RESPONSE_CANCEL) download = FALSE;
1246 /* If a download will be necessary, make sure that we have a connection: */
1247 retval = modest_platform_connect_and_wait(win, NULL);
1257 * Common code for the reply and forward actions
1260 reply_forward (ReplyForwardAction action, ModestWindow *win)
1262 ModestMailOperation *mail_op = NULL;
1263 TnyList *header_list = NULL;
1264 ReplyForwardHelper *rf_helper = NULL;
1265 guint reply_forward_type;
1266 gboolean continue_download = TRUE;
1267 gboolean do_retrieve = TRUE;
1269 g_return_if_fail (MODEST_IS_WINDOW(win));
1271 /* we need an account when editing */
1272 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1273 const gboolean created = modest_run_account_setup_wizard (win);
1278 header_list = get_selected_headers (win);
1282 reply_forward_type =
1283 modest_conf_get_int (modest_runtime_get_conf (),
1284 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1287 /* Check that the messages have been previously downloaded */
1288 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1290 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1291 if (!continue_download) {
1292 g_object_unref (header_list);
1296 /* We assume that we can only select messages of the
1297 same folder and that we reply all of them from the
1298 same account. In fact the interface currently only
1299 allows single selection */
1302 rf_helper = g_slice_new0 (ReplyForwardHelper);
1303 rf_helper->reply_forward_type = reply_forward_type;
1304 rf_helper->action = action;
1305 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1307 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1308 rf_helper->parent_window = GTK_WIDGET (win);
1309 if (!rf_helper->account_name)
1310 rf_helper->account_name =
1311 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1313 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1316 /* Get header and message. Do not free them here, the
1317 reply_forward_cb must do it */
1318 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1319 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1320 if (!msg || !header) {
1322 g_object_unref (msg);
1323 g_printerr ("modest: no message found\n");
1326 reply_forward_cb (NULL, header, msg, rf_helper);
1329 g_object_unref (header);
1334 /* Only reply/forward to one message */
1335 iter = tny_list_create_iterator (header_list);
1336 header = TNY_HEADER (tny_iterator_get_current (iter));
1337 g_object_unref (iter);
1340 /* Retrieve messages */
1342 mail_op = modest_mail_operation_new_with_error_handling (
1343 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1345 modest_ui_actions_get_msgs_full_error_handler,
1347 modest_mail_operation_queue_add (
1348 modest_runtime_get_mail_operation_queue (), mail_op);
1350 modest_mail_operation_get_msg (mail_op,
1355 g_object_unref(mail_op);
1357 /* we put a ref here to prevent double unref as the reply
1358 * forward callback unrefs the header at its end */
1359 reply_forward_cb (NULL, header, NULL, rf_helper);
1363 g_object_unref (header);
1369 g_object_unref (header_list);
1373 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1375 g_return_if_fail (MODEST_IS_WINDOW(win));
1377 reply_forward (ACTION_REPLY, win);
1381 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1383 g_return_if_fail (MODEST_IS_WINDOW(win));
1385 reply_forward (ACTION_FORWARD, win);
1389 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1391 g_return_if_fail (MODEST_IS_WINDOW(win));
1393 reply_forward (ACTION_REPLY_TO_ALL, win);
1397 modest_ui_actions_on_next (GtkAction *action,
1398 ModestWindow *window)
1400 if (MODEST_IS_MAIN_WINDOW (window)) {
1401 GtkWidget *header_view;
1403 header_view = modest_main_window_get_child_widget (
1404 MODEST_MAIN_WINDOW(window),
1405 MODEST_WIDGET_TYPE_HEADER_VIEW);
1409 modest_header_view_select_next (
1410 MODEST_HEADER_VIEW(header_view));
1411 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1412 modest_msg_view_window_select_next_message (
1413 MODEST_MSG_VIEW_WINDOW (window));
1415 g_return_if_reached ();
1420 modest_ui_actions_on_prev (GtkAction *action,
1421 ModestWindow *window)
1423 g_return_if_fail (MODEST_IS_WINDOW(window));
1425 if (MODEST_IS_MAIN_WINDOW (window)) {
1426 GtkWidget *header_view;
1427 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1428 MODEST_WIDGET_TYPE_HEADER_VIEW);
1432 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1433 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1434 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1436 g_return_if_reached ();
1441 modest_ui_actions_on_sort (GtkAction *action,
1442 ModestWindow *window)
1444 g_return_if_fail (MODEST_IS_WINDOW(window));
1446 if (MODEST_IS_MAIN_WINDOW (window)) {
1447 GtkWidget *header_view;
1448 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1449 MODEST_WIDGET_TYPE_HEADER_VIEW);
1451 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1456 /* Show sorting dialog */
1457 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1462 new_messages_arrived (ModestMailOperation *self,
1466 ModestMainWindow *win = NULL;
1467 GtkWidget *folder_view = NULL;
1468 TnyFolderStore *folder = NULL;
1469 gboolean folder_empty = FALSE;
1471 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1472 win = MODEST_MAIN_WINDOW (user_data);
1474 /* Set contents style of headers view */
1475 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1476 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1477 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1478 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1481 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1484 modest_main_window_set_contents_style (win,
1485 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1488 /* Notify new messages have been downloaded */
1489 if (new_messages > 0)
1490 modest_platform_on_new_msg ();
1494 * This function performs the send & receive required actions. The
1495 * window is used to create the mail operation. Typically it should
1496 * always be the main window, but we pass it as argument in order to
1500 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1502 gchar *acc_name = NULL;
1503 ModestMailOperation *mail_op;
1505 /* If no account name was provided then get the current account, and if
1506 there is no current account then pick the default one: */
1507 if (!account_name) {
1508 acc_name = g_strdup (modest_window_get_active_account(win));
1510 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1512 g_printerr ("modest: cannot get default account\n");
1516 acc_name = g_strdup (account_name);
1519 /* Set send/receive operation in progress */
1520 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1522 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1524 modest_ui_actions_send_receive_error_handler,
1527 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1528 G_CALLBACK (_on_send_receive_progress_changed),
1531 /* Send & receive. */
1532 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1533 /* Receive and then send. The operation is tagged initially as
1534 a receive operation because the account update performs a
1535 receive and then a send. The operation changes its type
1536 internally, so the progress objects will receive the proper
1537 progress information */
1538 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1539 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1540 g_object_unref (G_OBJECT (mail_op));
1548 modest_ui_actions_do_cancel_send (const gchar *account_name,
1551 TnyTransportAccount *transport_account;
1552 TnySendQueue *send_queue = NULL;
1553 GError *error = NULL;
1555 /* Get transport account */
1557 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1558 (modest_runtime_get_account_store(),
1560 TNY_ACCOUNT_TYPE_TRANSPORT));
1561 if (!transport_account) {
1562 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1567 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1568 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1569 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1570 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1571 "modest: could not find send queue for account\n");
1573 /* Keeep messages in outbox folder */
1574 tny_send_queue_cancel (send_queue, FALSE, &error);
1578 if (transport_account != NULL)
1579 g_object_unref (G_OBJECT (transport_account));
1583 modest_ui_actions_cancel_send_all (ModestWindow *win)
1585 GSList *account_names, *iter;
1587 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1590 iter = account_names;
1592 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1593 iter = g_slist_next (iter);
1596 modest_account_mgr_free_account_names (account_names);
1597 account_names = NULL;
1601 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1604 /* Check if accounts exist */
1605 gboolean accounts_exist =
1606 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1608 /* If not, allow the user to create an account before trying to send/receive. */
1609 if (!accounts_exist)
1610 modest_ui_actions_on_accounts (NULL, win);
1612 /* Cancel all sending operaitons */
1613 modest_ui_actions_cancel_send_all (win);
1617 * Refreshes all accounts. This function will be used by automatic
1621 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1623 GSList *account_names, *iter;
1625 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1628 iter = account_names;
1630 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1631 iter = g_slist_next (iter);
1634 modest_account_mgr_free_account_names (account_names);
1635 account_names = NULL;
1639 modest_do_refresh_current_folder(ModestWindow *win)
1641 /* Refresh currently selected folder. Note that if we only
1642 want to retreive the headers, then the refresh only will
1643 invoke a poke_status over all folders, i.e., only the
1644 total/unread count will be updated */
1645 if (MODEST_IS_MAIN_WINDOW (win)) {
1646 GtkWidget *header_view, *folder_view;
1647 TnyFolderStore *folder_store;
1649 /* Get folder and header view */
1651 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1652 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1656 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1658 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1660 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1661 MODEST_WIDGET_TYPE_HEADER_VIEW);
1663 /* We do not need to set the contents style
1664 because it hasn't changed. We also do not
1665 need to save the widget status. Just force
1667 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1668 TNY_FOLDER (folder_store),
1669 folder_refreshed_cb,
1670 MODEST_MAIN_WINDOW (win));
1674 g_object_unref (folder_store);
1680 * Handler of the click on Send&Receive button in the main toolbar
1683 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1685 /* Check if accounts exist */
1686 gboolean accounts_exist =
1687 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1689 /* If not, allow the user to create an account before trying to send/receive. */
1690 if (!accounts_exist)
1691 modest_ui_actions_on_accounts (NULL, win);
1693 modest_do_refresh_current_folder (win);
1695 /* Refresh the active account */
1696 modest_ui_actions_do_send_receive (NULL, win);
1701 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1704 GtkWidget *header_view;
1706 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1708 header_view = modest_main_window_get_child_widget (main_window,
1709 MODEST_WIDGET_TYPE_HEADER_VIEW);
1713 conf = modest_runtime_get_conf ();
1715 /* what is saved/restored is depending on the style; thus; we save with
1716 * old style, then update the style, and restore for this new style
1718 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1720 if (modest_header_view_get_style
1721 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1722 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1723 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1725 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1726 MODEST_HEADER_VIEW_STYLE_DETAILS);
1728 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1729 MODEST_CONF_HEADER_VIEW_KEY);
1734 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1736 ModestMainWindow *main_window)
1738 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1739 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1741 /* in the case the folder is empty, show the empty folder message and focus
1743 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1744 if (modest_header_view_is_empty (header_view)) {
1745 TnyFolder *folder = modest_header_view_get_folder (header_view);
1746 GtkWidget *folder_view =
1747 modest_main_window_get_child_widget (main_window,
1748 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1750 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1751 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1755 /* If no header has been selected then exit */
1760 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1761 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1763 /* Update toolbar dimming state */
1764 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1768 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1770 ModestMainWindow *main_window)
1774 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1780 /* headers = tny_simple_list_new (); */
1781 /* tny_list_prepend (headers, G_OBJECT (header)); */
1782 headers = modest_header_view_get_selected_headers (header_view);
1784 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1786 g_object_unref (headers);
1790 set_active_account_from_tny_account (TnyAccount *account,
1791 ModestWindow *window)
1793 const gchar *server_acc_name = tny_account_get_id (account);
1795 /* We need the TnyAccount provided by the
1796 account store because that is the one that
1797 knows the name of the Modest account */
1798 TnyAccount *modest_server_account = modest_server_account =
1799 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1800 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1803 const gchar *modest_acc_name =
1804 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1805 modest_window_set_active_account (window, modest_acc_name);
1806 g_object_unref (modest_server_account);
1811 folder_refreshed_cb (ModestMailOperation *mail_op,
1815 ModestMainWindow *win = NULL;
1816 GtkWidget *header_view;
1817 TnyFolder *current_folder;
1818 gboolean folder_empty = FALSE;
1819 gboolean all_marked_as_deleted = FALSE;
1821 g_return_if_fail (TNY_IS_FOLDER (folder));
1823 win = MODEST_MAIN_WINDOW (user_data);
1825 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1828 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1829 if (current_folder != NULL && folder != current_folder) {
1834 /* Check if folder is empty and set headers view contents style */
1835 folder_empty = (tny_folder_get_all_count (folder) == 0);
1836 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1837 folder_empty = folder_empty || all_marked_as_deleted ;
1840 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1841 modest_main_window_set_contents_style (win,
1842 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1844 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1849 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1850 TnyFolderStore *folder_store,
1852 ModestMainWindow *main_window)
1855 GtkWidget *header_view;
1857 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1859 header_view = modest_main_window_get_child_widget(main_window,
1860 MODEST_WIDGET_TYPE_HEADER_VIEW);
1864 conf = modest_runtime_get_conf ();
1866 if (TNY_IS_ACCOUNT (folder_store)) {
1868 /* Update active account */
1869 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1870 /* Show account details */
1871 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1874 if (TNY_IS_FOLDER (folder_store) && selected) {
1876 /* Update the active account */
1877 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1879 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1880 g_object_unref (account);
1884 /* Set the header style by default, it could
1885 be changed later by the refresh callback to
1887 modest_main_window_set_contents_style (main_window,
1888 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1890 /* Set folder on header view. This function
1891 will call tny_folder_refresh_async so we
1892 pass a callback that will be called when
1893 finished. We use that callback to set the
1894 empty view if there are no messages */
1895 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1896 TNY_FOLDER (folder_store),
1897 folder_refreshed_cb,
1900 /* Restore configuration. We need to do this
1901 *after* the set_folder because the widget
1902 memory asks the header view about its
1904 modest_widget_memory_restore (modest_runtime_get_conf (),
1905 G_OBJECT(header_view),
1906 MODEST_CONF_HEADER_VIEW_KEY);
1908 /* Update the active account */
1909 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1910 /* Save only if we're seeing headers */
1911 if (modest_main_window_get_contents_style (main_window) ==
1912 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1913 modest_widget_memory_save (conf, G_OBJECT (header_view),
1914 MODEST_CONF_HEADER_VIEW_KEY);
1915 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1919 /* Update toolbar dimming state */
1920 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1924 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1931 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1933 online = tny_device_is_online (modest_runtime_get_device());
1936 /* already online -- the item is simply not there... */
1937 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1939 GTK_MESSAGE_WARNING,
1941 _("The %s you selected cannot be found"),
1943 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
1944 gtk_dialog_run (GTK_DIALOG(dialog));
1946 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1949 _("mcen_bd_dialog_cancel"),
1950 GTK_RESPONSE_REJECT,
1951 _("mcen_bd_dialog_ok"),
1952 GTK_RESPONSE_ACCEPT,
1954 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1955 "Do you want to get online?"), item);
1956 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1957 gtk_label_new (txt), FALSE, FALSE, 0);
1958 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1961 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1962 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1963 /* TODO: Comment about why is this commented out: */
1964 /* modest_platform_connect_and_wait (); */
1967 gtk_widget_destroy (dialog);
1971 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1974 /* g_message ("%s %s", __FUNCTION__, link); */
1979 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1982 modest_platform_activate_uri (link);
1986 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1989 modest_platform_show_uri_popup (link);
1993 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1996 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2000 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2001 const gchar *address,
2004 /* g_message ("%s %s", __FUNCTION__, address); */
2008 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2010 TnyTransportAccount *transport_account;
2011 ModestMailOperation *mail_operation;
2013 gchar *account_name, *from;
2014 ModestAccountMgr *account_mgr;
2015 gchar *info_text = NULL;
2017 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2019 data = modest_msg_edit_window_get_msg_data (edit_window);
2021 account_mgr = modest_runtime_get_account_mgr();
2022 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2024 account_name = modest_account_mgr_get_default_account (account_mgr);
2025 if (!account_name) {
2026 g_printerr ("modest: no account found\n");
2027 modest_msg_edit_window_free_msg_data (edit_window, data);
2031 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2032 account_name = g_strdup (data->account_name);
2036 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2037 (modest_runtime_get_account_store(),
2039 TNY_ACCOUNT_TYPE_TRANSPORT));
2040 if (!transport_account) {
2041 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2042 g_free (account_name);
2043 modest_msg_edit_window_free_msg_data (edit_window, data);
2046 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2048 /* Create the mail operation */
2049 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2050 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2052 modest_mail_operation_save_to_drafts (mail_operation,
2064 data->priority_flags);
2067 g_free (account_name);
2068 g_object_unref (G_OBJECT (transport_account));
2069 g_object_unref (G_OBJECT (mail_operation));
2071 modest_msg_edit_window_free_msg_data (edit_window, data);
2073 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2074 modest_platform_information_banner (NULL, NULL, info_text);
2078 /* For instance, when clicking the Send toolbar button when editing a message: */
2080 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2082 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2084 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2087 /* Offer the connection dialog, if necessary: */
2088 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2091 /* FIXME: Code added just for testing. The final version will
2092 use the send queue provided by tinymail and some
2094 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2095 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2097 account_name = modest_account_mgr_get_default_account (account_mgr);
2099 if (!account_name) {
2100 /* Run account setup wizard */
2101 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2106 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2108 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2109 account_name = g_strdup (data->account_name);
2112 /* Get the currently-active transport account for this modest account: */
2113 TnyTransportAccount *transport_account =
2114 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2115 (modest_runtime_get_account_store(),
2117 if (!transport_account) {
2118 /* Run account setup wizard */
2119 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2124 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2126 /* Create the mail operation */
2127 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2128 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2130 modest_mail_operation_send_new_mail (mail_operation,
2141 data->priority_flags);
2145 g_free (account_name);
2146 g_object_unref (G_OBJECT (transport_account));
2147 g_object_unref (G_OBJECT (mail_operation));
2149 modest_msg_edit_window_free_msg_data (edit_window, data);
2150 modest_msg_edit_window_set_sent (edit_window, TRUE);
2152 /* Save settings and close the window: */
2153 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2157 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2158 ModestMsgEditWindow *window)
2160 ModestMsgEditFormatState *format_state = NULL;
2162 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2163 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2165 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2168 format_state = modest_msg_edit_window_get_format_state (window);
2169 g_return_if_fail (format_state != NULL);
2171 format_state->bold = gtk_toggle_action_get_active (action);
2172 modest_msg_edit_window_set_format_state (window, format_state);
2173 g_free (format_state);
2178 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2179 ModestMsgEditWindow *window)
2181 ModestMsgEditFormatState *format_state = NULL;
2183 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2184 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2186 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2189 format_state = modest_msg_edit_window_get_format_state (window);
2190 g_return_if_fail (format_state != NULL);
2192 format_state->italics = gtk_toggle_action_get_active (action);
2193 modest_msg_edit_window_set_format_state (window, format_state);
2194 g_free (format_state);
2199 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2200 ModestMsgEditWindow *window)
2202 ModestMsgEditFormatState *format_state = NULL;
2204 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2205 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2207 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2210 format_state = modest_msg_edit_window_get_format_state (window);
2211 g_return_if_fail (format_state != NULL);
2213 format_state->bullet = gtk_toggle_action_get_active (action);
2214 modest_msg_edit_window_set_format_state (window, format_state);
2215 g_free (format_state);
2220 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2221 GtkRadioAction *selected,
2222 ModestMsgEditWindow *window)
2224 ModestMsgEditFormatState *format_state = NULL;
2225 GtkJustification value;
2227 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2229 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2232 value = gtk_radio_action_get_current_value (selected);
2234 format_state = modest_msg_edit_window_get_format_state (window);
2235 g_return_if_fail (format_state != NULL);
2237 format_state->justification = value;
2238 modest_msg_edit_window_set_format_state (window, format_state);
2239 g_free (format_state);
2243 modest_ui_actions_on_select_editor_color (GtkAction *action,
2244 ModestMsgEditWindow *window)
2246 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2247 g_return_if_fail (GTK_IS_ACTION (action));
2249 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2252 modest_msg_edit_window_select_color (window);
2256 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2257 ModestMsgEditWindow *window)
2259 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2260 g_return_if_fail (GTK_IS_ACTION (action));
2262 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2265 modest_msg_edit_window_select_background_color (window);
2269 modest_ui_actions_on_insert_image (GtkAction *action,
2270 ModestMsgEditWindow *window)
2272 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2273 g_return_if_fail (GTK_IS_ACTION (action));
2275 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2278 modest_msg_edit_window_insert_image (window);
2282 modest_ui_actions_on_attach_file (GtkAction *action,
2283 ModestMsgEditWindow *window)
2285 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2286 g_return_if_fail (GTK_IS_ACTION (action));
2288 modest_msg_edit_window_offer_attach_file (window);
2292 modest_ui_actions_on_remove_attachments (GtkAction *action,
2293 ModestMsgEditWindow *window)
2295 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2296 g_return_if_fail (GTK_IS_ACTION (action));
2298 modest_msg_edit_window_remove_attachments (window, NULL);
2302 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2305 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2306 const GError *error = modest_mail_operation_get_error (mail_op);
2310 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2311 modest_mail_operation_get_error (mail_op)->message);
2316 modest_ui_actions_create_folder(GtkWidget *parent_window,
2317 GtkWidget *folder_view)
2319 TnyFolderStore *parent_folder;
2321 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2323 if (parent_folder) {
2324 gboolean finished = FALSE;
2326 gchar *folder_name = NULL, *suggested_name = NULL;
2327 const gchar *proto_str = NULL;
2328 TnyAccount *account;
2330 if (TNY_IS_ACCOUNT (parent_folder))
2331 account = g_object_ref (parent_folder);
2333 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2334 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2336 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2337 MODEST_PROTOCOL_STORE_POP) {
2339 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2341 g_object_unref (account);
2343 /* Run the new folder dialog */
2345 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2350 g_free (suggested_name);
2351 suggested_name = NULL;
2353 if (result == GTK_RESPONSE_REJECT) {
2356 ModestMailOperation *mail_op;
2357 TnyFolder *new_folder = NULL;
2359 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2360 G_OBJECT(parent_window),
2361 modest_ui_actions_new_folder_error_handler,
2364 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2366 new_folder = modest_mail_operation_create_folder (mail_op,
2368 (const gchar *) folder_name);
2370 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2373 g_object_unref (new_folder);
2376 g_object_unref (mail_op);
2379 suggested_name = folder_name;
2383 g_object_unref (parent_folder);
2388 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2390 GtkWidget *folder_view;
2392 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2394 folder_view = modest_main_window_get_child_widget (main_window,
2395 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2399 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2403 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2406 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2407 const GError *error = NULL;
2408 const gchar *message = NULL;
2410 /* Get error message */
2411 error = modest_mail_operation_get_error (mail_op);
2413 g_return_if_reached ();
2415 switch (error->code) {
2416 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2417 message = _CS("ckdg_ib_folder_already_exists");
2420 g_return_if_reached ();
2423 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2427 modest_ui_actions_on_rename_folder (GtkAction *action,
2428 ModestMainWindow *main_window)
2430 TnyFolderStore *folder;
2431 GtkWidget *folder_view;
2432 GtkWidget *header_view;
2434 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2436 folder_view = modest_main_window_get_child_widget (main_window,
2437 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2441 header_view = modest_main_window_get_child_widget (main_window,
2442 MODEST_WIDGET_TYPE_HEADER_VIEW);
2447 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2451 /* Offer the connection dialog if necessary: */
2452 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2453 g_object_unref (G_OBJECT (folder));
2458 if (TNY_IS_FOLDER (folder)) {
2461 const gchar *current_name;
2462 TnyFolderStore *parent;
2464 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2465 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2466 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2467 parent, current_name,
2469 g_object_unref (parent);
2471 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2472 ModestMailOperation *mail_op;
2473 GtkTreeSelection *sel = NULL;
2476 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2477 G_OBJECT(main_window),
2478 modest_ui_actions_rename_folder_error_handler,
2482 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2485 /* Clear the headers view */
2486 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2487 gtk_tree_selection_unselect_all (sel);
2489 /* Select *after* the changes */
2490 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2491 TNY_FOLDER(folder), TRUE);
2493 modest_mail_operation_rename_folder (mail_op,
2494 TNY_FOLDER (folder),
2495 (const gchar *) folder_name);
2497 g_object_unref (mail_op);
2498 g_free (folder_name);
2501 g_object_unref (folder);
2505 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2508 GObject *win = modest_mail_operation_get_source (mail_op);
2510 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2511 _("mail_in_ui_folder_delete_error"));
2512 g_object_unref (win);
2516 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2518 TnyFolderStore *folder;
2519 GtkWidget *folder_view;
2523 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2525 folder_view = modest_main_window_get_child_widget (main_window,
2526 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2530 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2532 /* Show an error if it's an account */
2533 if (!TNY_IS_FOLDER (folder)) {
2534 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2535 _("mail_in_ui_folder_delete_error"));
2536 g_object_unref (G_OBJECT (folder));
2540 /* Offer the connection dialog if necessary: */
2541 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2542 g_object_unref (G_OBJECT (folder));
2547 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2548 tny_folder_get_name (TNY_FOLDER (folder)));
2549 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2550 (const gchar *) message);
2553 if (response == GTK_RESPONSE_OK) {
2554 ModestMailOperation *mail_op;
2555 GtkTreeSelection *sel;
2557 /* Unselect the folder before deleting it to free the headers */
2558 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2559 gtk_tree_selection_unselect_all (sel);
2561 /* Create the mail operation */
2563 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2564 G_OBJECT(main_window),
2565 modest_ui_actions_delete_folder_error_handler,
2568 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2570 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2571 g_object_unref (G_OBJECT (mail_op));
2574 g_object_unref (G_OBJECT (folder));
2578 modest_ui_actions_on_delete_folder (GtkAction *action,
2579 ModestMainWindow *main_window)
2581 GtkWidget *folder_view;
2582 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2584 delete_folder (main_window, FALSE);
2585 folder_view = modest_main_window_get_child_widget (main_window,
2586 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2589 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2593 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2595 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2597 delete_folder (main_window, TRUE);
2602 show_error (GtkWidget *parent_widget, const gchar* text)
2604 hildon_banner_show_information(parent_widget, NULL, text);
2607 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2609 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2616 gtk_dialog_run (dialog);
2617 gtk_widget_destroy (GTK_WIDGET (dialog));
2622 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2623 const gchar* server_account_name,
2628 ModestMainWindow *main_window)
2630 g_return_if_fail(server_account_name);
2631 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2633 /* Initalize output parameters: */
2640 #ifdef MODEST_PLATFORM_MAEMO
2641 /* Maemo uses a different (awkward) button order,
2642 * It should probably just use gtk_alternative_dialog_button_order ().
2644 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2647 _("mcen_bd_dialog_ok"),
2648 GTK_RESPONSE_ACCEPT,
2649 _("mcen_bd_dialog_cancel"),
2650 GTK_RESPONSE_REJECT,
2653 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2657 GTK_RESPONSE_REJECT,
2659 GTK_RESPONSE_ACCEPT,
2661 #endif /* MODEST_PLATFORM_MAEMO */
2663 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2665 gchar *server_name = modest_server_account_get_hostname (
2666 modest_runtime_get_account_mgr(), server_account_name);
2667 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2668 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2673 /* This causes a warning because the logical ID has no %s in it,
2674 * though the translation does, but there is not much we can do about that: */
2675 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2676 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2679 g_free (server_name);
2683 gchar *initial_username = modest_server_account_get_username (
2684 modest_runtime_get_account_mgr(), server_account_name);
2686 GtkWidget *entry_username = gtk_entry_new ();
2687 if (initial_username)
2688 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2689 /* Dim this if a connection has ever succeeded with this username,
2690 * as per the UI spec: */
2691 const gboolean username_known =
2692 modest_server_account_get_username_has_succeeded(
2693 modest_runtime_get_account_mgr(), server_account_name);
2694 gtk_widget_set_sensitive (entry_username, !username_known);
2696 #ifdef MODEST_PLATFORM_MAEMO
2697 /* Auto-capitalization is the default, so let's turn it off: */
2698 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2700 /* Create a size group to be used by all captions.
2701 * Note that HildonCaption does not create a default size group if we do not specify one.
2702 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2703 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2705 GtkWidget *caption = hildon_caption_new (sizegroup,
2706 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2707 gtk_widget_show (entry_username);
2708 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2709 FALSE, FALSE, MODEST_MARGIN_HALF);
2710 gtk_widget_show (caption);
2712 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2714 #endif /* MODEST_PLATFORM_MAEMO */
2717 GtkWidget *entry_password = gtk_entry_new ();
2718 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2719 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2721 #ifdef MODEST_PLATFORM_MAEMO
2722 /* Auto-capitalization is the default, so let's turn it off: */
2723 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2724 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2726 caption = hildon_caption_new (sizegroup,
2727 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2728 gtk_widget_show (entry_password);
2729 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2730 FALSE, FALSE, MODEST_MARGIN_HALF);
2731 gtk_widget_show (caption);
2732 g_object_unref (sizegroup);
2734 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2736 #endif /* MODEST_PLATFORM_MAEMO */
2738 /* This is not in the Maemo UI spec:
2739 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2740 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2744 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2746 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2748 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2750 modest_server_account_set_username (
2751 modest_runtime_get_account_mgr(), server_account_name,
2754 const gboolean username_was_changed =
2755 (strcmp (*username, initial_username) != 0);
2756 if (username_was_changed) {
2757 g_warning ("%s: tinymail does not yet support changing the "
2758 "username in the get_password() callback.\n", __FUNCTION__);
2763 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2765 /* We do not save the password in the configuration,
2766 * because this function is only called for passwords that should
2767 * not be remembered:
2768 modest_server_account_set_password (
2769 modest_runtime_get_account_mgr(), server_account_name,
2778 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2790 /* This is not in the Maemo UI spec:
2791 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2797 gtk_widget_destroy (dialog);
2799 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2803 modest_ui_actions_on_cut (GtkAction *action,
2804 ModestWindow *window)
2806 GtkWidget *focused_widget;
2807 GtkClipboard *clipboard;
2809 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2810 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2811 if (GTK_IS_EDITABLE (focused_widget)) {
2812 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2813 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2814 gtk_clipboard_store (clipboard);
2815 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2816 GtkTextBuffer *buffer;
2818 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2819 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2820 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2821 gtk_clipboard_store (clipboard);
2822 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2823 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2824 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2825 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2830 modest_ui_actions_on_copy (GtkAction *action,
2831 ModestWindow *window)
2833 GtkClipboard *clipboard;
2834 GtkWidget *focused_widget;
2836 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2837 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2839 if (GTK_IS_LABEL (focused_widget)) {
2840 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2841 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2842 gtk_clipboard_store (clipboard);
2843 } else if (GTK_IS_EDITABLE (focused_widget)) {
2844 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2845 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2846 gtk_clipboard_store (clipboard);
2847 } else if (GTK_IS_HTML (focused_widget)) {
2848 gtk_html_copy (GTK_HTML (focused_widget));
2849 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2850 gtk_clipboard_store (clipboard);
2851 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2852 GtkTextBuffer *buffer;
2853 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2854 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2855 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2856 gtk_clipboard_store (clipboard);
2857 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2858 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2859 TnyIterator *iter = tny_list_create_iterator (header_list);
2860 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2862 gboolean ask = FALSE;
2864 TnyFolder *folder = tny_header_get_folder (header);
2865 TnyAccount *account = tny_folder_get_account (folder);
2866 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2867 /* If it's POP then ask */
2868 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2869 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2870 g_object_unref (account);
2871 g_object_unref (folder);
2872 g_object_unref (header);
2875 g_object_unref (iter);
2877 /* Check that the messages have been previously downloaded */
2878 gboolean continue_download = TRUE;
2880 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2881 if (continue_download)
2882 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2883 g_object_unref (header_list);
2884 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2885 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2888 /* Show information banner */
2889 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2894 modest_ui_actions_on_undo (GtkAction *action,
2895 ModestWindow *window)
2897 ModestEmailClipboard *clipboard = NULL;
2899 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2900 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2901 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2902 /* Clear clipboard source */
2903 clipboard = modest_runtime_get_email_clipboard ();
2904 modest_email_clipboard_clear (clipboard);
2907 g_return_if_reached ();
2912 modest_ui_actions_on_redo (GtkAction *action,
2913 ModestWindow *window)
2915 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2916 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2919 g_return_if_reached ();
2925 paste_msgs_cb (const GObject *object, gpointer user_data)
2927 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2928 g_return_if_fail (GTK_IS_WIDGET (user_data));
2930 /* destroy information note */
2931 gtk_widget_destroy (GTK_WIDGET(user_data));
2935 paste_as_attachment_free (gpointer data)
2937 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2939 gtk_widget_destroy (helper->banner);
2940 g_object_unref (helper->banner);
2945 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2950 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2951 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2956 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2961 modest_ui_actions_on_paste (GtkAction *action,
2962 ModestWindow *window)
2964 GtkWidget *focused_widget = NULL;
2965 GtkWidget *inf_note = NULL;
2966 ModestMailOperation *mail_op = NULL;
2968 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2969 if (GTK_IS_EDITABLE (focused_widget)) {
2970 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2971 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2972 ModestEmailClipboard *e_clipboard = NULL;
2973 e_clipboard = modest_runtime_get_email_clipboard ();
2974 if (modest_email_clipboard_cleared (e_clipboard)) {
2975 GtkTextBuffer *buffer;
2976 GtkClipboard *clipboard;
2978 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2979 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2980 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2981 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2982 ModestMailOperation *mail_op;
2983 TnyFolder *src_folder;
2986 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2987 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2988 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2989 _CS("ckct_nw_pasting"));
2990 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2991 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2993 if (helper->banner != NULL) {
2994 g_object_ref (G_OBJECT (helper->banner));
2995 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2996 gtk_widget_show (GTK_WIDGET (helper->banner));
3000 modest_mail_operation_get_msgs_full (mail_op,
3002 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3004 paste_as_attachment_free);
3007 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3008 ModestEmailClipboard *clipboard = NULL;
3009 TnyFolder *src_folder = NULL;
3010 TnyFolderStore *folder_store = NULL;
3011 TnyList *data = NULL;
3012 gboolean delete = FALSE;
3014 /* Check clipboard source */
3015 clipboard = modest_runtime_get_email_clipboard ();
3016 if (modest_email_clipboard_cleared (clipboard))
3019 /* Get elements to paste */
3020 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3022 /* Create a new mail operation */
3023 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3025 /* Get destination folder */
3026 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3028 /* transfer messages */
3032 /* Ask for user confirmation */
3033 response = msgs_move_to_confirmation (GTK_WINDOW (window),
3034 TNY_FOLDER (folder_store),
3038 if (response == GTK_RESPONSE_OK) {
3039 /* Launch notification */
3040 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3041 _CS("ckct_nw_pasting"));
3042 if (inf_note != NULL) {
3043 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3044 gtk_widget_show (GTK_WIDGET(inf_note));
3047 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3048 modest_mail_operation_xfer_msgs (mail_op,
3050 TNY_FOLDER (folder_store),
3055 g_object_unref (mail_op);
3058 } else if (src_folder != NULL) {
3059 /* Launch notification */
3060 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3061 _CS("ckct_nw_pasting"));
3062 if (inf_note != NULL) {
3063 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3064 gtk_widget_show (GTK_WIDGET(inf_note));
3067 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3068 modest_mail_operation_xfer_folder (mail_op,
3078 g_object_unref (data);
3079 if (src_folder != NULL)
3080 g_object_unref (src_folder);
3081 if (folder_store != NULL)
3082 g_object_unref (folder_store);
3088 modest_ui_actions_on_select_all (GtkAction *action,
3089 ModestWindow *window)
3091 GtkWidget *focused_widget;
3093 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3094 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3095 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3096 } else if (GTK_IS_LABEL (focused_widget)) {
3097 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3098 } else if (GTK_IS_EDITABLE (focused_widget)) {
3099 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3100 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3101 GtkTextBuffer *buffer;
3102 GtkTextIter start, end;
3104 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3105 gtk_text_buffer_get_start_iter (buffer, &start);
3106 gtk_text_buffer_get_end_iter (buffer, &end);
3107 gtk_text_buffer_select_range (buffer, &start, &end);
3108 } else if (GTK_IS_HTML (focused_widget)) {
3109 gtk_html_select_all (GTK_HTML (focused_widget));
3110 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3111 GtkWidget *header_view = focused_widget;
3112 GtkTreeSelection *selection = NULL;
3114 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3115 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3116 MODEST_WIDGET_TYPE_HEADER_VIEW);
3119 /* Disable window dimming management */
3120 modest_window_disable_dimming (MODEST_WINDOW(window));
3122 /* Select all messages */
3123 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3124 gtk_tree_selection_select_all (selection);
3126 /* Set focuse on header view */
3127 gtk_widget_grab_focus (header_view);
3130 /* Enable window dimming management */
3131 modest_window_enable_dimming (MODEST_WINDOW(window));
3132 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3138 modest_ui_actions_on_mark_as_read (GtkAction *action,
3139 ModestWindow *window)
3141 g_return_if_fail (MODEST_IS_WINDOW(window));
3143 /* Mark each header as read */
3144 do_headers_action (window, headers_action_mark_as_read, NULL);
3148 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3149 ModestWindow *window)
3151 g_return_if_fail (MODEST_IS_WINDOW(window));
3153 /* Mark each header as read */
3154 do_headers_action (window, headers_action_mark_as_unread, NULL);
3158 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3159 GtkRadioAction *selected,
3160 ModestWindow *window)
3164 value = gtk_radio_action_get_current_value (selected);
3165 if (MODEST_IS_WINDOW (window)) {
3166 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3170 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3171 GtkRadioAction *selected,
3172 ModestWindow *window)
3174 TnyHeaderFlags flags;
3175 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3177 flags = gtk_radio_action_get_current_value (selected);
3178 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3181 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3182 GtkRadioAction *selected,
3183 ModestWindow *window)
3187 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3189 file_format = gtk_radio_action_get_current_value (selected);
3190 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3195 modest_ui_actions_on_zoom_plus (GtkAction *action,
3196 ModestWindow *window)
3198 g_return_if_fail (MODEST_IS_WINDOW (window));
3200 modest_window_zoom_plus (MODEST_WINDOW (window));
3204 modest_ui_actions_on_zoom_minus (GtkAction *action,
3205 ModestWindow *window)
3207 g_return_if_fail (MODEST_IS_WINDOW (window));
3209 modest_window_zoom_minus (MODEST_WINDOW (window));
3213 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3214 ModestWindow *window)
3216 ModestWindowMgr *mgr;
3217 gboolean fullscreen, active;
3218 g_return_if_fail (MODEST_IS_WINDOW (window));
3220 mgr = modest_runtime_get_window_mgr ();
3222 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3223 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3225 if (active != fullscreen) {
3226 modest_window_mgr_set_fullscreen_mode (mgr, active);
3227 gtk_window_present (GTK_WINDOW (window));
3232 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3233 ModestWindow *window)
3235 ModestWindowMgr *mgr;
3236 gboolean fullscreen;
3238 g_return_if_fail (MODEST_IS_WINDOW (window));
3240 mgr = modest_runtime_get_window_mgr ();
3241 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3242 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3244 gtk_window_present (GTK_WINDOW (window));
3248 * Used by modest_ui_actions_on_details to call do_headers_action
3251 headers_action_show_details (TnyHeader *header,
3252 ModestWindow *window,
3259 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3262 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3263 gtk_widget_show_all (dialog);
3264 gtk_dialog_run (GTK_DIALOG (dialog));
3266 gtk_widget_destroy (dialog);
3270 * Show the folder details in a ModestDetailsDialog widget
3273 show_folder_details (TnyFolder *folder,
3279 dialog = modest_details_dialog_new_with_folder (window, folder);
3282 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3283 gtk_widget_show_all (dialog);
3284 gtk_dialog_run (GTK_DIALOG (dialog));
3286 gtk_widget_destroy (dialog);
3290 * Show the header details in a ModestDetailsDialog widget
3293 modest_ui_actions_on_details (GtkAction *action,
3296 TnyList * headers_list;
3300 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3303 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3306 g_object_unref (msg);
3308 headers_list = get_selected_headers (win);
3312 iter = tny_list_create_iterator (headers_list);
3314 header = TNY_HEADER (tny_iterator_get_current (iter));
3316 headers_action_show_details (header, win, NULL);
3317 g_object_unref (header);
3320 g_object_unref (iter);
3321 g_object_unref (headers_list);
3323 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3324 GtkWidget *folder_view, *header_view;
3326 /* Check which widget has the focus */
3327 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3328 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3329 if (gtk_widget_is_focus (folder_view)) {
3330 TnyFolderStore *folder_store
3331 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3332 if (!folder_store) {
3333 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3336 /* Show only when it's a folder */
3337 /* This function should not be called for account items,
3338 * because we dim the menu item for them. */
3339 if (TNY_IS_FOLDER (folder_store)) {
3340 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3343 g_object_unref (folder_store);
3346 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3347 MODEST_WIDGET_TYPE_HEADER_VIEW);
3348 /* Show details of each header */
3349 do_headers_action (win, headers_action_show_details, header_view);
3355 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3356 ModestMsgEditWindow *window)
3358 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3360 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3364 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3365 ModestMsgEditWindow *window)
3367 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3369 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3373 modest_ui_actions_toggle_folders_view (GtkAction *action,
3374 ModestMainWindow *main_window)
3376 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3378 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3379 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3381 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3385 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3386 ModestWindow *window)
3388 gboolean active, fullscreen = FALSE;
3389 ModestWindowMgr *mgr;
3391 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3393 /* Check if we want to toggle the toolbar vuew in fullscreen
3395 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3396 "ViewShowToolbarFullScreen")) {
3400 /* Toggle toolbar */
3401 mgr = modest_runtime_get_window_mgr ();
3402 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3406 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3407 ModestMsgEditWindow *window)
3409 modest_msg_edit_window_select_font (window);
3413 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3414 const gchar *display_name,
3417 /* Do not change the application name if the widget has not
3418 the focus. This callback could be called even if the folder
3419 view has not the focus, because the handled signal could be
3420 emitted when the folder view is redrawn */
3421 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3423 gtk_window_set_title (window, display_name);
3425 gtk_window_set_title (window, " ");
3430 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3432 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3433 modest_msg_edit_window_select_contacts (window);
3437 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3439 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3440 modest_msg_edit_window_check_names (window, FALSE);
3444 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3446 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3447 GTK_WIDGET (user_data));
3451 create_move_to_dialog (GtkWindow *win,
3452 GtkWidget *folder_view,
3453 GtkWidget **tree_view)
3455 GtkWidget *dialog, *scroll;
3456 GtkWidget *new_button;
3458 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3460 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3463 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3464 /* We do this manually so GTK+ does not associate a response ID for
3466 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3467 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3468 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3470 /* Create scrolled window */
3471 scroll = gtk_scrolled_window_new (NULL, NULL);
3472 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3473 GTK_POLICY_AUTOMATIC,
3474 GTK_POLICY_AUTOMATIC);
3476 /* Create folder view */
3477 *tree_view = modest_platform_create_folder_view (NULL);
3479 g_signal_connect (G_OBJECT (new_button),
3481 G_CALLBACK(create_move_to_dialog_on_new_folder),
3484 /* It could happen that we're trying to move a message from a
3485 window (msg window for example) after the main window was
3486 closed, so we can not just get the model of the folder
3488 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3489 const gchar *visible_id = NULL;
3491 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3492 MODEST_FOLDER_VIEW(*tree_view));
3495 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3497 /* Show the same account than the one that is shown in the main window */
3498 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3501 const gchar *active_account_name = NULL;
3502 ModestAccountMgr *mgr = NULL;
3503 ModestAccountData *acc_data = NULL;
3505 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3506 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3508 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3509 mgr = modest_runtime_get_account_mgr ();
3510 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3512 /* Set the new visible & active account */
3513 if (acc_data && acc_data->store_account) {
3514 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3515 acc_data->store_account->account_name);
3516 modest_account_mgr_free_account_data (mgr, acc_data);
3520 /* Hide special folders */
3521 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3523 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3525 /* Add scroll to dialog */
3526 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3527 scroll, TRUE, TRUE, 0);
3529 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3530 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3536 * Returns TRUE if at least one of the headers of the list belongs to
3537 * a message that has been fully retrieved.
3539 #if 0 /* no longer in use. delete in 2007.10 */
3541 has_retrieved_msgs (TnyList *list)
3544 gboolean found = FALSE;
3546 iter = tny_list_create_iterator (list);
3547 while (!tny_iterator_is_done (iter) && !found) {
3549 TnyHeaderFlags flags = 0;
3551 header = TNY_HEADER (tny_iterator_get_current (iter));
3553 flags = tny_header_get_flags (header);
3554 if (flags & TNY_HEADER_FLAG_CACHED)
3555 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3558 g_object_unref (header);
3562 tny_iterator_next (iter);
3564 g_object_unref (iter);
3572 * Shows a confirmation dialog to the user when we're moving messages
3573 * from a remote server to the local storage. Returns the dialog
3574 * response. If it's other kind of movement the it always returns
3578 msgs_move_to_confirmation (GtkWindow *win,
3579 TnyFolder *dest_folder,
3583 gint response = GTK_RESPONSE_OK;
3585 /* If the destination is a local folder (or MMC folder )*/
3586 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3591 TnyFolder *src_folder = NULL;
3592 TnyIterator *iter = NULL;
3593 TnyHeader *header = NULL;
3595 /* get the device */
3597 device = modest_runtime_get_device ();
3599 is_online = tny_device_is_online (device);
3601 g_warning ("failed to get tny device"); /* should not happend */
3605 /* Get source folder */
3606 iter = tny_list_create_iterator (headers);
3607 header = TNY_HEADER (tny_iterator_get_current (iter));
3609 src_folder = tny_header_get_folder (header);
3610 g_object_unref (header);
3613 g_object_unref (iter);
3615 /* if no src_folder, message may be an attahcment */
3616 if (src_folder == NULL)
3617 return GTK_RESPONSE_CANCEL;
3619 /* If the source is a remote folder */
3620 if (!is_online && modest_tny_folder_is_remote_folder (src_folder)) {
3622 const gchar *message = NULL;
3623 message = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs",
3624 tny_list_get_length (headers));
3625 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3626 (const gchar *) message);
3628 response = GTK_RESPONSE_OK;
3630 g_object_unref (src_folder);
3639 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3641 ModestMsgViewWindow *self = NULL;
3643 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3644 self = MODEST_MSG_VIEW_WINDOW (object);
3646 if (!modest_msg_view_window_select_next_message (self))
3647 if (!modest_msg_view_window_select_previous_message (self))
3648 /* No more messages to view, so close this window */
3649 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3653 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3656 GObject *win = modest_mail_operation_get_source (mail_op);
3657 const GError *error = NULL;
3658 const gchar *message = NULL;
3660 /* Get error message */
3661 error = modest_mail_operation_get_error (mail_op);
3662 if (error != NULL && error->message != NULL) {
3663 message = error->message;
3665 message = _("mail_in_ui_folder_move_target_error");
3668 /* Show notification dialog */
3669 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3670 g_object_unref (win);
3674 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3677 GObject *win = modest_mail_operation_get_source (mail_op);
3678 const GError *error = modest_mail_operation_get_error (mail_op);
3680 g_return_if_fail (error != NULL);
3681 if (error->message != NULL)
3682 g_printerr ("modest: %s\n", error->message);
3684 g_printerr ("modest: unkonw error on send&receive operation");
3686 /* Show error message */
3687 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3688 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3689 /* _CS("sfil_ib_unable_to_receive")); */
3691 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3692 /* _CS("sfil_ib_unable_to_send")); */
3693 g_object_unref (win);
3697 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3704 gint pending_purges = 0;
3705 gboolean some_purged = FALSE;
3706 ModestWindow *win = MODEST_WINDOW (user_data);
3707 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3709 /* If there was any error */
3710 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3711 modest_window_mgr_unregister_header (mgr, header);
3715 /* Once the message has been retrieved for purging, we check if
3716 * it's all ok for purging */
3718 parts = tny_simple_list_new ();
3719 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3720 iter = tny_list_create_iterator (parts);
3722 while (!tny_iterator_is_done (iter)) {
3724 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3725 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3726 if (tny_mime_part_is_purged (part))
3733 g_object_unref (part);
3735 tny_iterator_next (iter);
3738 if (pending_purges>0) {
3740 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3742 if (response == GTK_RESPONSE_OK) {
3743 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3744 tny_iterator_first (iter);
3745 while (!tny_iterator_is_done (iter)) {
3748 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3749 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3750 tny_mime_part_set_purged (part);
3753 g_object_unref (part);
3755 tny_iterator_next (iter);
3758 tny_msg_rewrite_cache (msg);
3761 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3764 /* remove attachments */
3765 tny_iterator_first (iter);
3766 while (!tny_iterator_is_done (iter)) {
3769 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3771 /* One for the reference given by tny_iterator_get_current(): */
3772 g_object_unref (part);
3774 /* TODO: Is this meant to remove the attachment by doing another unref()?
3775 * Otherwise, this seems useless. */
3778 tny_iterator_next (iter);
3780 modest_window_mgr_unregister_header (mgr, header);
3782 g_object_unref (iter);
3783 g_object_unref (parts);
3787 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3788 ModestMainWindow *win)
3790 GtkWidget *header_view;
3791 TnyList *header_list;
3794 TnyHeaderFlags flags;
3795 ModestWindow *msg_view_window = NULL;
3798 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3800 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3801 MODEST_WIDGET_TYPE_HEADER_VIEW);
3803 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3805 if (tny_list_get_length (header_list) == 1) {
3806 iter = tny_list_create_iterator (header_list);
3807 header = TNY_HEADER (tny_iterator_get_current (iter));
3808 g_object_unref (iter);
3813 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3814 header, &msg_view_window);
3815 flags = tny_header_get_flags (header);
3816 if (!(flags & TNY_HEADER_FLAG_CACHED))
3819 if (msg_view_window != NULL)
3820 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3822 /* do nothing; uid was registered before, so window is probably on it's way */
3823 g_warning ("debug: header %p has already been registered", header);
3826 ModestMailOperation *mail_op = NULL;
3827 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3828 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3830 modest_ui_actions_get_msgs_full_error_handler,
3832 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3833 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3835 g_object_unref (mail_op);
3838 g_object_unref (header);
3840 g_object_unref (header_list);
3844 * Utility function that transfer messages from both the main window
3845 * and the msg view window when using the "Move to" dialog
3848 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3851 TnyList *headers = NULL;
3853 TnyAccount *dst_account = NULL;
3854 const gchar *proto_str = NULL;
3855 gboolean dst_is_pop = FALSE;
3857 if (!TNY_IS_FOLDER (dst_folder)) {
3858 modest_platform_information_banner (GTK_WIDGET (win),
3860 _CS("ckdg_ib_unable_to_move_to_current_location"));
3864 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3865 proto_str = tny_account_get_proto (dst_account);
3867 /* tinymail will return NULL for local folders it seems */
3868 dst_is_pop = proto_str &&
3869 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3870 MODEST_PROTOCOL_STORE_POP);
3872 g_object_unref (dst_account);
3874 /* Get selected headers */
3875 headers = get_selected_headers (MODEST_WINDOW (win));
3878 modest_platform_information_banner (GTK_WIDGET (win),
3880 ngettext("mail_in_ui_folder_move_target_error",
3881 "mail_in_ui_folder_move_targets_error",
3882 tny_list_get_length (headers)));
3883 g_object_unref (headers);
3887 /* Ask for user confirmation */
3888 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3889 TNY_FOLDER (dst_folder),
3893 /* Transfer messages */
3894 if (response == GTK_RESPONSE_OK) {
3895 ModestMailOperation *mail_op =
3896 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3898 modest_ui_actions_move_folder_error_handler,
3900 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3903 modest_mail_operation_xfer_msgs (mail_op,
3905 TNY_FOLDER (dst_folder),
3907 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3910 g_object_unref (G_OBJECT (mail_op));
3912 g_object_unref (headers);
3916 * UI handler for the "Move to" action when invoked from the
3920 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3921 GtkWidget *folder_view,
3922 TnyFolderStore *dst_folder,
3923 ModestMainWindow *win)
3925 GtkWidget *header_view = NULL;
3926 ModestMailOperation *mail_op = NULL;
3927 TnyFolderStore *src_folder;
3929 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3931 /* Get the source folder */
3932 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3934 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3935 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3939 /* Get header view */
3941 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3943 /* Get folder or messages to transfer */
3944 if (gtk_widget_is_focus (folder_view)) {
3945 GtkTreeSelection *sel;
3947 /* Allow only to transfer folders to the local root folder */
3948 if (TNY_IS_ACCOUNT (dst_folder) &&
3949 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3952 /* Clean folder on header view before moving it */
3953 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3954 gtk_tree_selection_unselect_all (sel);
3956 if (TNY_IS_FOLDER (src_folder)) {
3958 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3960 modest_ui_actions_move_folder_error_handler,
3962 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3965 modest_mail_operation_xfer_folder (mail_op,
3966 TNY_FOLDER (src_folder),
3969 /* Unref mail operation */
3970 g_object_unref (G_OBJECT (mail_op));
3972 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3974 } else if (gtk_widget_is_focus (header_view)) {
3975 /* Transfer messages */
3976 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3981 g_object_unref (src_folder);
3986 * UI handler for the "Move to" action when invoked from the
3987 * ModestMsgViewWindow
3990 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3991 TnyFolderStore *dst_folder,
3992 ModestMsgViewWindow *win)
3994 TnyHeader *header = NULL;
3995 TnyFolder *src_folder;
3997 /* Create header list */
3998 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3999 src_folder = tny_header_get_folder(header);
4000 g_object_unref (header);
4002 /* Transfer the message */
4003 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
4004 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4006 g_object_unref (src_folder);
4010 modest_ui_actions_on_move_to (GtkAction *action,
4013 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4015 TnyFolderStore *dst_folder = NULL;
4016 ModestMainWindow *main_window;
4018 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4019 MODEST_IS_MSG_VIEW_WINDOW (win));
4021 /* Get the main window if exists */
4022 if (MODEST_IS_MAIN_WINDOW (win))
4023 main_window = MODEST_MAIN_WINDOW (win);
4026 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4028 /* Get the folder view widget if exists */
4030 folder_view = modest_main_window_get_child_widget (main_window,
4031 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4035 /* Create and run the dialog */
4036 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4037 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4038 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4039 result = gtk_dialog_run (GTK_DIALOG(dialog));
4040 g_object_ref (tree_view);
4041 gtk_widget_destroy (dialog);
4043 if (result != GTK_RESPONSE_ACCEPT)
4046 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4047 /* Offer the connection dialog if necessary: */
4048 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
4051 /* Do window specific stuff */
4052 if (MODEST_IS_MAIN_WINDOW (win))
4053 modest_ui_actions_on_main_window_move_to (action,
4056 MODEST_MAIN_WINDOW (win));
4058 modest_ui_actions_on_msg_view_window_move_to (action,
4060 MODEST_MSG_VIEW_WINDOW (win));
4063 g_object_unref (dst_folder);
4067 * Calls #HeadersFunc for each header already selected in the main
4068 * window or the message currently being shown in the msg view window
4071 do_headers_action (ModestWindow *win,
4075 TnyList *headers_list = NULL;
4076 TnyIterator *iter = NULL;
4077 TnyHeader *header = NULL;
4078 TnyFolder *folder = NULL;
4081 headers_list = get_selected_headers (win);
4085 /* Get the folder */
4086 iter = tny_list_create_iterator (headers_list);
4087 header = TNY_HEADER (tny_iterator_get_current (iter));
4089 folder = tny_header_get_folder (header);
4090 g_object_unref (header);
4093 /* Call the function for each header */
4094 while (!tny_iterator_is_done (iter)) {
4095 header = TNY_HEADER (tny_iterator_get_current (iter));
4096 func (header, win, user_data);
4097 g_object_unref (header);
4098 tny_iterator_next (iter);
4101 /* Trick: do a poke status in order to speed up the signaling
4103 tny_folder_poke_status (folder);
4106 g_object_unref (folder);
4107 g_object_unref (iter);
4108 g_object_unref (headers_list);
4112 modest_ui_actions_view_attachment (GtkAction *action,
4113 ModestWindow *window)
4115 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4116 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4118 /* not supported window for this action */
4119 g_return_if_reached ();
4124 modest_ui_actions_save_attachments (GtkAction *action,
4125 ModestWindow *window)
4127 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4128 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4130 /* not supported window for this action */
4131 g_return_if_reached ();
4136 modest_ui_actions_remove_attachments (GtkAction *action,
4137 ModestWindow *window)
4139 if (MODEST_IS_MAIN_WINDOW (window)) {
4140 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4141 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4142 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4144 /* not supported window for this action */
4145 g_return_if_reached ();
4150 modest_ui_actions_on_settings (GtkAction *action,
4155 dialog = modest_platform_get_global_settings_dialog ();
4156 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4157 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4158 gtk_widget_show_all (dialog);
4160 gtk_dialog_run (GTK_DIALOG (dialog));
4162 gtk_widget_destroy (dialog);
4166 modest_ui_actions_on_help (GtkAction *action,
4169 const gchar *help_id = NULL;
4171 if (MODEST_IS_MAIN_WINDOW (win)) {
4172 const gchar *action_name;
4173 action_name = gtk_action_get_name (action);
4175 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4176 !strcmp (action_name, "HeaderViewCSMHelp")) {
4177 GtkWidget *folder_view;
4178 TnyFolderStore *folder_store;
4179 /* Get selected folder */
4180 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4181 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4182 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4184 /* Switch help_id */
4185 if (TNY_IS_FOLDER (folder_store)) {
4186 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4187 case TNY_FOLDER_TYPE_NORMAL:
4188 help_id = "applications_email_managefolders";
4190 case TNY_FOLDER_TYPE_INBOX:
4191 help_id = "applications_email_inbox";
4193 case TNY_FOLDER_TYPE_OUTBOX:
4194 help_id = "applications_email_outbox";
4196 case TNY_FOLDER_TYPE_SENT:
4197 help_id = "applications_email_sent";
4199 case TNY_FOLDER_TYPE_DRAFTS:
4200 help_id = "applications_email_drafts";
4202 case TNY_FOLDER_TYPE_ARCHIVE:
4203 help_id = "applications_email_managefolders";
4206 help_id = "applications_email_managefolders";
4209 help_id = "applications_email_mainview";
4211 g_object_unref (folder_store);
4213 help_id = "applications_email_mainview";
4215 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4216 help_id = "applications_email_viewer";
4217 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4218 help_id = "applications_email_editor";
4220 modest_platform_show_help (GTK_WINDOW (win), help_id);
4224 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4225 ModestWindow *window)
4227 ModestMailOperation *mail_op;
4231 headers = get_selected_headers (window);
4235 /* Create mail operation */
4236 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4238 modest_ui_actions_get_msgs_full_error_handler,
4240 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4241 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4244 g_object_unref (headers);
4245 g_object_unref (mail_op);
4249 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4250 ModestWindow *window)
4252 g_return_if_fail (MODEST_IS_WINDOW (window));
4255 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4259 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4260 ModestWindow *window)
4262 g_return_if_fail (MODEST_IS_WINDOW (window));
4265 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4269 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4270 ModestWindow *window)
4272 g_return_if_fail (MODEST_IS_WINDOW (window));
4275 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4279 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4280 ModestWindow *window)
4282 g_return_if_fail (MODEST_IS_WINDOW (window));
4285 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4289 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4290 ModestWindow *window)
4292 g_return_if_fail (MODEST_IS_WINDOW (window));
4295 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4299 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4300 ModestWindow *window)
4302 g_return_if_fail (MODEST_IS_WINDOW (window));
4305 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4309 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4310 ModestWindow *window)
4312 g_return_if_fail (MODEST_IS_WINDOW (window));
4315 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4319 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4320 ModestWindow *window)
4322 g_return_if_fail (MODEST_IS_WINDOW (window));
4325 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4329 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4331 g_return_if_fail (MODEST_IS_WINDOW (window));
4334 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4338 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4340 g_return_if_fail (MODEST_IS_WINDOW (window));
4342 modest_platform_show_search_messages (GTK_WINDOW (window));
4346 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4348 g_return_if_fail (MODEST_IS_WINDOW (win));
4349 modest_platform_show_addressbook (GTK_WINDOW (win));
4354 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4355 ModestWindow *window)
4357 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4359 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4363 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4364 ModestMailOperationState *state,
4367 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4369 /* Set send/receive operation finished */
4370 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4371 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));