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,
143 download_uncached_messages (TnyList *header_list, GtkWindow *win,
148 run_account_setup_wizard (ModestWindow *win)
150 ModestEasysetupWizardDialog *wizard;
152 g_return_if_fail (MODEST_IS_WINDOW(win));
154 wizard = modest_easysetup_wizard_dialog_new ();
155 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
157 /* Don't make this a modal window, because secondary windows will then
158 * be unusable, freezing the UI: */
159 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
161 gtk_dialog_run (GTK_DIALOG (wizard));
162 gtk_widget_destroy (GTK_WIDGET (wizard));
167 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
170 const gchar *authors[] = {
171 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
174 about = gtk_about_dialog_new ();
175 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
176 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
177 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
178 _("Copyright (c) 2006, Nokia Corporation\n"
179 "All rights reserved."));
180 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
181 _("a modest e-mail client\n\n"
182 "design and implementation: Dirk-Jan C. Binnema\n"
183 "contributions from the fine people at KC and Ig\n"
184 "uses the tinymail email framework written by Philip van Hoof"));
185 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
186 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
187 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
188 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
190 gtk_dialog_run (GTK_DIALOG (about));
191 gtk_widget_destroy(about);
195 * Gets the list of currently selected messages. If the win is the
196 * main window, then it returns a newly allocated list of the headers
197 * selected in the header view. If win is the msg view window, then
198 * the value returned is a list with just a single header.
200 * The caller of this funcion must free the list.
203 get_selected_headers (ModestWindow *win)
205 if (MODEST_IS_MAIN_WINDOW(win)) {
206 GtkWidget *header_view;
208 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
209 MODEST_WIDGET_TYPE_HEADER_VIEW);
210 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
212 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
213 /* for MsgViewWindows, we simply return a list with one element */
215 TnyList *list = NULL;
217 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
218 if (header != NULL) {
219 list = tny_simple_list_new ();
220 tny_list_prepend (list, G_OBJECT(header));
221 g_object_unref (G_OBJECT(header));
231 headers_action_mark_as_read (TnyHeader *header,
235 TnyHeaderFlags flags;
237 g_return_if_fail (TNY_IS_HEADER(header));
239 flags = tny_header_get_flags (header);
240 if (flags & TNY_HEADER_FLAG_SEEN) return;
241 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
245 headers_action_mark_as_unread (TnyHeader *header,
249 TnyHeaderFlags flags;
251 g_return_if_fail (TNY_IS_HEADER(header));
253 flags = tny_header_get_flags (header);
254 if (flags & TNY_HEADER_FLAG_SEEN) {
255 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
259 /** A convenience method, because deleting a message is
260 * otherwise complicated, and it's best to change it in one place
263 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
265 ModestMailOperation *mail_op = NULL;
266 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
267 win ? G_OBJECT(win) : NULL);
268 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
271 /* Always delete. TODO: Move to trash still not supported */
272 modest_mail_operation_remove_msg (mail_op, header, FALSE);
273 g_object_unref (G_OBJECT (mail_op));
277 headers_action_delete (TnyHeader *header,
281 modest_do_message_delete (header, win);
284 /** After deleing a message that is currently visible in a window,
285 * show the next message from the list, or close the window if there are no more messages.
287 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
289 /* Close msg view window or select next */
290 if (modest_msg_view_window_last_message_selected (win) &&
291 modest_msg_view_window_first_message_selected (win)) {
292 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
294 if (!modest_msg_view_window_select_next_message (win)) {
296 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
302 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
304 TnyList *header_list = NULL;
305 TnyIterator *iter = NULL;
306 TnyHeader *header = NULL;
307 gchar *message = NULL;
310 ModestWindowMgr *mgr;
311 GtkWidget *header_view = NULL;
313 g_return_if_fail (MODEST_IS_WINDOW(win));
315 /* Check first if the header view has the focus */
316 if (MODEST_IS_MAIN_WINDOW (win)) {
318 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
319 MODEST_WIDGET_TYPE_HEADER_VIEW);
320 if (!gtk_widget_is_focus (header_view))
324 /* Get the headers, either from the header view (if win is the main window),
325 * or from the message view window: */
326 header_list = get_selected_headers (win);
327 if (!header_list) return;
329 /* Check if any of the headers are already opened, or in the process of being opened */
330 if (MODEST_IS_MAIN_WINDOW (win)) {
332 iter = tny_list_create_iterator (header_list);
334 mgr = modest_runtime_get_window_mgr ();
335 while (!tny_iterator_is_done (iter) && !found) {
336 header = TNY_HEADER (tny_iterator_get_current (iter));
338 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
339 g_object_unref (header);
342 tny_iterator_next (iter);
344 g_object_unref (iter);
349 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
350 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
352 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
356 g_object_unref (header_list);
362 if (tny_list_get_length(header_list) == 1) {
363 iter = tny_list_create_iterator (header_list);
364 header = TNY_HEADER (tny_iterator_get_current (iter));
366 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
367 g_object_unref (header);
370 g_object_unref (iter);
372 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
373 tny_list_get_length(header_list)), desc);
375 /* Confirmation dialog */
376 printf("DEBUG: %s\n", __FUNCTION__);
377 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
381 if (response == GTK_RESPONSE_OK) {
382 ModestWindow *main_window = NULL;
383 ModestWindowMgr *mgr = NULL;
384 GtkTreeModel *model = NULL;
385 GtkTreeSelection *sel = NULL;
386 GList *sel_list = NULL, *tmp = NULL;
387 GtkTreeRowReference *row_reference = NULL;
388 GtkTreePath *next_path = NULL;
389 TnyFolder *folder = NULL;
392 /* Find last selected row */
393 if (MODEST_IS_MAIN_WINDOW (win)) {
394 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
395 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
396 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
397 for (tmp=sel_list; tmp; tmp=tmp->next) {
398 if (tmp->next == NULL) {
399 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
400 gtk_tree_path_next (next_path);
401 row_reference = gtk_tree_row_reference_new (model, next_path);
402 gtk_tree_path_free (next_path);
407 /* Remove each header. If it's a view window header_view == NULL */
408 do_headers_action (win, headers_action_delete, header_view);
410 /* refresh the header view (removing marked-as-deleted)*/
411 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view));
413 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
414 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
416 /* Get main window */
417 mgr = modest_runtime_get_window_mgr ();
418 main_window = modest_window_mgr_get_main_window (mgr);
421 /* Move cursor to next row */
424 /* Select next row */
425 if (gtk_tree_row_reference_valid (row_reference)) {
426 next_path = gtk_tree_row_reference_get_path (row_reference);
427 gtk_tree_selection_select_path (sel, next_path);
428 gtk_tree_path_free (next_path);
430 if (row_reference != NULL)
431 gtk_tree_row_reference_free (row_reference);
434 /* Get folder from first header and sync it */
435 iter = tny_list_create_iterator (header_list);
436 header = TNY_HEADER (tny_iterator_get_current (iter));
437 folder = tny_header_get_folder (header);
438 if (TNY_IS_CAMEL_IMAP_FOLDER (folder))
439 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */
440 tny_folder_sync (folder, FALSE, &err); /* FALSE --> don't expunge */
441 /* else if (TNY_IS_CAMEL_POP_FOLDER (folder)) */
442 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* TRUE --> dont expunge *\/ */
443 /* tny_folder_sync (folder, TRUE, &err); /\* TRUE --> expunge *\/ */
446 /* tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /\* TRUE --> expunge *\/ */
447 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
450 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
454 g_object_unref (header);
455 g_object_unref (iter);
456 g_object_unref (folder);
458 /* Update toolbar dimming state */
459 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
462 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
463 g_list_free (sel_list);
469 g_object_unref (header_list);
475 /* delete either message or folder, based on where we are */
477 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
479 g_return_if_fail (MODEST_IS_WINDOW(win));
481 /* Check first if the header view has the focus */
482 if (MODEST_IS_MAIN_WINDOW (win)) {
484 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
485 MODEST_WIDGET_TYPE_FOLDER_VIEW);
486 if (gtk_widget_is_focus (w)) {
487 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
491 modest_ui_actions_on_delete_message (action, win);
497 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
499 #ifdef MODEST_PLATFORM_MAEMO
500 modest_osso_save_state();
501 #endif /* MODEST_PLATFORM_MAEMO */
503 g_debug ("closing down, clearing %d item(s) from operation queue",
504 modest_mail_operation_queue_num_elements
505 (modest_runtime_get_mail_operation_queue()));
507 /* cancel all outstanding operations */
508 modest_mail_operation_queue_cancel_all
509 (modest_runtime_get_mail_operation_queue());
511 g_debug ("queue has been cleared");
513 /* note: when modest-tny-account-store is finalized,
514 it will automatically set all network connections
521 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
525 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
527 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
528 /* gtk_widget_destroy (GTK_WIDGET (win)); */
529 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
530 /* gboolean ret_value; */
531 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
532 /* } else if (MODEST_IS_WINDOW (win)) { */
533 /* gtk_widget_destroy (GTK_WIDGET (win)); */
535 /* g_return_if_reached (); */
540 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
542 GtkClipboard *clipboard = NULL;
543 gchar *selection = NULL;
545 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
546 selection = gtk_clipboard_wait_for_text (clipboard);
548 /* Question: why is the clipboard being used here?
549 * It doesn't really make a lot of sense. */
553 modest_address_book_add_address (selection);
559 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
561 /* This is currently only implemented for Maemo */
562 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
563 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
564 run_account_setup_wizard (win);
567 /* Show the list of accounts: */
568 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
569 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
571 /* Don't make this a modal window, because secondary windows will then
572 * be unusable, freezing the UI: */
573 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
574 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
577 GtkWidget *dialog, *label;
579 /* Create the widgets */
581 dialog = gtk_dialog_new_with_buttons ("Message",
583 GTK_DIALOG_DESTROY_WITH_PARENT,
587 label = gtk_label_new ("Hello World!");
589 /* Ensure that the dialog box is destroyed when the user responds. */
591 g_signal_connect_swapped (dialog, "response",
592 G_CALLBACK (gtk_widget_destroy),
595 /* Add the label, and show everything we've added to the dialog. */
597 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
599 gtk_widget_show_all (dialog);
600 #endif /* MODEST_PLATFORM_MAEMO */
604 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
606 ModestWindow *main_window = MODEST_WINDOW (user_data);
608 /* Save any changes. */
609 modest_connection_specific_smtp_window_save_server_accounts (
610 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
611 modest_window_get_active_account (main_window));
612 gtk_widget_destroy (GTK_WIDGET (window));
618 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
620 /* This is currently only implemented for Maemo,
621 * because it requires an API (libconic) to detect different connection
624 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
626 /* Create the window if necessary: */
627 const gchar *active_account_name = modest_window_get_active_account (win);
629 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
630 * or show the default account?
631 * If we show the default account then the account name should be shown in
632 * the window when we show it. */
633 if (!active_account_name) {
634 g_warning ("%s: No account is active.", __FUNCTION__);
638 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
639 modest_connection_specific_smtp_window_fill_with_connections (
640 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
641 modest_runtime_get_account_mgr(),
642 active_account_name);
644 /* Show the window: */
645 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
646 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
647 gtk_widget_show (specific_window);
649 /* Save changes when the window is hidden: */
650 g_signal_connect (specific_window, "hide",
651 G_CALLBACK (on_smtp_servers_window_hide), win);
652 #endif /* MODEST_PLATFORM_MAEMO */
656 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
658 ModestWindow *msg_win = NULL;
660 TnyFolder *folder = NULL;
661 gchar *account_name = NULL;
662 gchar *from_str = NULL;
663 /* GError *err = NULL; */
664 TnyAccount *account = NULL;
665 ModestWindowMgr *mgr;
666 gchar *signature = NULL, *blank_and_signature = NULL;
668 /* if there are no accounts yet, just show the wizard */
669 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
670 run_account_setup_wizard (win);
674 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
676 account_name = g_strdup (modest_window_get_active_account (win));
678 g_printerr ("modest: no account found\n");
682 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
684 TNY_ACCOUNT_TYPE_STORE);
686 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
690 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
692 g_printerr ("modest: failed get from string for '%s'\n", account_name);
696 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
697 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
698 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
699 MODEST_ACCOUNT_SIGNATURE, FALSE);
700 blank_and_signature = g_strconcat ("\n", signature, NULL);
703 blank_and_signature = g_strdup ("");
706 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
708 g_printerr ("modest: failed to create new msg\n");
712 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
714 g_printerr ("modest: failed to find Drafts folder\n");
719 /* Create and register edit window */
720 /* This is destroyed by TOOD. */
721 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
722 mgr = modest_runtime_get_window_mgr ();
723 modest_window_mgr_register_window (mgr, msg_win);
726 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
728 gtk_widget_show_all (GTK_WIDGET (msg_win));
731 g_free (account_name);
733 g_free (blank_and_signature);
735 g_object_unref (msg_win);
737 g_object_unref (G_OBJECT(account));
739 g_object_unref (G_OBJECT(msg));
741 g_object_unref (G_OBJECT(folder));
745 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
749 ModestMailOperationStatus status;
751 /* If there is no message or the operation was not successful */
752 status = modest_mail_operation_get_status (mail_op);
753 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
755 /* Remove the header from the preregistered uids */
756 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
766 open_msg_cb (ModestMailOperation *mail_op,
771 ModestWindowMgr *mgr = NULL;
772 ModestWindow *parent_win = NULL;
773 ModestWindow *win = NULL;
774 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
775 gchar *account = NULL;
778 /* Do nothing if there was any problem with the mail
779 operation. The error will be shown by the error_handler of
780 the mail operation */
781 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
785 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
786 folder = tny_header_get_folder (header);
788 /* Mark header as read */
789 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
792 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
794 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
796 /* Gets folder type (OUTBOX headers will be opened in edit window */
797 if (modest_tny_folder_is_local_folder (folder))
798 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
800 /* If the header is in the drafts folder then open the editor,
801 else the message view window */
802 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
803 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
804 /* we cannot edit without a valid account... */
805 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
806 run_account_setup_wizard(parent_win);
809 win = modest_msg_edit_window_new (msg, account, TRUE);
812 gchar *uid = modest_tny_folder_get_header_unique_id (header);
814 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
815 GtkWidget *header_view;
816 GtkTreeSelection *sel;
817 GList *sel_list = NULL;
820 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
821 MODEST_WIDGET_TYPE_HEADER_VIEW);
823 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
824 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
826 if (sel_list != NULL) {
827 GtkTreeRowReference *row_reference;
829 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
830 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
831 g_list_free (sel_list);
833 win = modest_msg_view_window_new_with_header_model (msg,
838 gtk_tree_row_reference_free (row_reference);
840 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
843 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
848 /* Register and show new window */
850 mgr = modest_runtime_get_window_mgr ();
851 modest_window_mgr_register_window (mgr, win);
852 g_object_unref (win);
853 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
854 gtk_widget_show_all (GTK_WIDGET(win));
857 /* Update toolbar dimming state */
858 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
859 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
865 g_object_unref (parent_win);
866 g_object_unref (folder);
870 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
874 GObject *win = modest_mail_operation_get_source (mail_op);
876 error = modest_mail_operation_get_error (mail_op);
877 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
879 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
881 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
884 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
885 _("mail_ni_ui_folder_get_msg_folder_error"));
889 g_object_unref (win);
893 * This function is used by both modest_ui_actions_on_open and
894 * modest_ui_actions_on_header_activated. This way we always do the
895 * same when trying to open messages.
898 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
900 ModestWindowMgr *mgr = NULL;
901 TnyIterator *iter = NULL;
902 ModestMailOperation *mail_op = NULL;
903 TnyList *not_opened_headers = NULL;
904 TnyHeaderFlags flags = 0;
906 /* Look if we already have a message view for each header. If
907 true, then remove the header from the list of headers to
909 mgr = modest_runtime_get_window_mgr ();
910 iter = tny_list_create_iterator (headers);
911 not_opened_headers = tny_simple_list_new ();
913 while (!tny_iterator_is_done (iter)) {
915 ModestWindow *window = NULL;
916 TnyHeader *header = NULL;
917 gboolean found = FALSE;
919 header = TNY_HEADER (tny_iterator_get_current (iter));
921 flags = tny_header_get_flags (header);
924 found = modest_window_mgr_find_registered_header (mgr, header, &window);
926 /* Do not open again the message and present the
927 window to the user */
930 gtk_window_present (GTK_WINDOW (window));
932 /* the header has been registered already, we don't do
933 * anything but wait for the window to come up*/
934 g_debug ("header %p already registered, waiting for window", header);
936 tny_list_append (not_opened_headers, G_OBJECT (header));
940 g_object_unref (header);
942 tny_iterator_next (iter);
944 g_object_unref (iter);
947 /* If some messages would have to be downloaded, ask the user to
948 * make a connection. It's generally easier to do this here (in the mainloop)
949 * than later in a thread:
951 if (tny_list_get_length (not_opened_headers) > 0) {
953 gboolean found = FALSE;
955 iter = tny_list_create_iterator (not_opened_headers);
956 while (!tny_iterator_is_done (iter) && !found) {
957 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
958 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
961 tny_iterator_next (iter);
963 g_object_unref (header);
965 g_object_unref (iter);
967 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
968 g_object_unref (not_opened_headers);
973 /* Register the headers before actually creating the windows: */
974 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
975 while (!tny_iterator_is_done (iter_not_opened)) {
976 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
978 modest_window_mgr_register_header (mgr, header);
979 g_object_unref (header);
982 tny_iterator_next (iter_not_opened);
984 g_object_unref (iter_not_opened);
985 iter_not_opened = NULL;
987 /* Open each message */
988 if (tny_list_get_length (not_opened_headers) > 0) {
989 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
991 modest_ui_actions_get_msgs_full_error_handler,
993 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
994 if (tny_list_get_length (not_opened_headers) > 1) {
995 modest_mail_operation_get_msgs_full (mail_op,
1001 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1002 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1003 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1004 g_object_unref (header);
1005 g_object_unref (iter);
1007 g_object_unref (mail_op);
1011 if (not_opened_headers != NULL)
1012 g_object_unref (not_opened_headers);
1016 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1021 headers = get_selected_headers (win);
1026 _modest_ui_actions_open (headers, win);
1028 g_object_unref(headers);
1033 free_reply_forward_helper (gpointer data)
1035 ReplyForwardHelper *helper;
1037 helper = (ReplyForwardHelper *) data;
1038 g_free (helper->account_name);
1039 g_slice_free (ReplyForwardHelper, helper);
1043 reply_forward_cb (ModestMailOperation *mail_op,
1049 ReplyForwardHelper *rf_helper;
1050 ModestWindow *msg_win = NULL;
1051 ModestEditType edit_type;
1053 TnyAccount *account = NULL;
1054 ModestWindowMgr *mgr = NULL;
1055 gchar *signature = NULL;
1057 /* If there was any error. The mail operation could be NULL,
1058 this means that we already have the message downloaded and
1059 that we didn't do a mail operation to retrieve it */
1060 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1063 g_return_if_fail (user_data != NULL);
1064 rf_helper = (ReplyForwardHelper *) user_data;
1066 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1067 rf_helper->account_name);
1068 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1069 rf_helper->account_name,
1070 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1071 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1072 rf_helper->account_name,
1073 MODEST_ACCOUNT_SIGNATURE, FALSE);
1076 /* Create reply mail */
1077 switch (rf_helper->action) {
1080 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1081 rf_helper->reply_forward_type,
1082 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1084 case ACTION_REPLY_TO_ALL:
1086 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1087 MODEST_TNY_MSG_REPLY_MODE_ALL);
1088 edit_type = MODEST_EDIT_TYPE_REPLY;
1090 case ACTION_FORWARD:
1092 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1093 edit_type = MODEST_EDIT_TYPE_FORWARD;
1096 g_return_if_reached ();
1103 g_printerr ("modest: failed to create message\n");
1107 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1108 rf_helper->account_name,
1109 TNY_ACCOUNT_TYPE_STORE);
1111 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1115 /* Create and register the windows */
1116 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1117 mgr = modest_runtime_get_window_mgr ();
1118 modest_window_mgr_register_window (mgr, msg_win);
1120 if (rf_helper->parent_window != NULL) {
1121 gdouble parent_zoom;
1123 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1124 modest_window_set_zoom (msg_win, parent_zoom);
1127 /* Show edit window */
1128 gtk_widget_show_all (GTK_WIDGET (msg_win));
1132 g_object_unref (msg_win);
1134 g_object_unref (G_OBJECT (new_msg));
1136 g_object_unref (G_OBJECT (account));
1137 /* g_object_unref (msg); */
1138 free_reply_forward_helper (rf_helper);
1142 * Checks a list of headers. If any of them are not currently
1143 * downloaded (CACHED) then it asks the user for permission to
1146 * Returns FALSE if the user does not want to download the
1147 * messages. Returns TRUE if the user allowed the download or if all
1148 * of them are currently downloaded
1151 download_uncached_messages (TnyList *header_list,
1157 gint uncached_messages = 0;
1159 iter = tny_list_create_iterator (header_list);
1160 while (!tny_iterator_is_done (iter)) {
1163 header = TNY_HEADER (tny_iterator_get_current (iter));
1165 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1166 uncached_messages ++;
1167 g_object_unref (header);
1170 tny_iterator_next (iter);
1172 g_object_unref (iter);
1174 /* Ask for user permission to download the messages */
1176 if (uncached_messages > 0) {
1177 GtkResponseType response;
1179 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1180 _("emev_nc_include_original"));
1183 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1184 ngettext("mcen_nc_get_msg",
1186 uncached_messages));
1187 if (response == GTK_RESPONSE_CANCEL)
1190 /* If a download will be necessary, make sure that we have a connection: */
1191 retval = modest_platform_connect_and_wait(win, NULL);
1199 * Common code for the reply and forward actions
1202 reply_forward (ReplyForwardAction action, ModestWindow *win)
1204 ModestMailOperation *mail_op = NULL;
1205 TnyList *header_list = NULL;
1206 ReplyForwardHelper *rf_helper = NULL;
1207 guint reply_forward_type;
1208 gboolean continue_download = TRUE;
1209 gboolean do_retrieve = TRUE;
1211 g_return_if_fail (MODEST_IS_WINDOW(win));
1213 /* we need an account when editing */
1214 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1215 run_account_setup_wizard (win);
1219 header_list = get_selected_headers (win);
1223 reply_forward_type =
1224 modest_conf_get_int (modest_runtime_get_conf (),
1225 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1228 /* Check that the messages have been previously downloaded */
1229 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1231 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win), TRUE);
1232 if (!continue_download) {
1233 g_object_unref (header_list);
1237 /* We assume that we can only select messages of the
1238 same folder and that we reply all of them from the
1239 same account. In fact the interface currently only
1240 allows single selection */
1243 rf_helper = g_slice_new0 (ReplyForwardHelper);
1244 rf_helper->reply_forward_type = reply_forward_type;
1245 rf_helper->action = action;
1246 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1248 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1249 rf_helper->parent_window = GTK_WIDGET (win);
1250 if (!rf_helper->account_name)
1251 rf_helper->account_name =
1252 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1254 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1257 /* Get header and message. Do not free them here, the
1258 reply_forward_cb must do it */
1259 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1260 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1261 if (!msg || !header) {
1263 g_object_unref (msg);
1264 g_printerr ("modest: no message found\n");
1267 reply_forward_cb (NULL, header, msg, rf_helper);
1270 g_object_unref (header);
1275 /* Only reply/forward to one message */
1276 iter = tny_list_create_iterator (header_list);
1277 header = TNY_HEADER (tny_iterator_get_current (iter));
1278 g_object_unref (iter);
1281 /* Retrieve messages */
1283 mail_op = modest_mail_operation_new_with_error_handling (
1284 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1286 modest_ui_actions_get_msgs_full_error_handler,
1288 modest_mail_operation_queue_add (
1289 modest_runtime_get_mail_operation_queue (), mail_op);
1291 modest_mail_operation_get_msg (mail_op,
1296 g_object_unref(mail_op);
1298 /* we put a ref here to prevent double unref as the reply
1299 * forward callback unrefs the header at its end */
1300 reply_forward_cb (NULL, header, NULL, rf_helper);
1304 g_object_unref (header);
1310 g_object_unref (header_list);
1314 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1316 g_return_if_fail (MODEST_IS_WINDOW(win));
1318 reply_forward (ACTION_REPLY, win);
1322 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1324 g_return_if_fail (MODEST_IS_WINDOW(win));
1326 reply_forward (ACTION_FORWARD, win);
1330 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1332 g_return_if_fail (MODEST_IS_WINDOW(win));
1334 reply_forward (ACTION_REPLY_TO_ALL, win);
1338 modest_ui_actions_on_next (GtkAction *action,
1339 ModestWindow *window)
1341 if (MODEST_IS_MAIN_WINDOW (window)) {
1342 GtkWidget *header_view;
1344 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1345 MODEST_WIDGET_TYPE_HEADER_VIEW);
1349 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1350 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1351 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1353 g_return_if_reached ();
1358 modest_ui_actions_on_prev (GtkAction *action,
1359 ModestWindow *window)
1361 g_return_if_fail (MODEST_IS_WINDOW(window));
1363 if (MODEST_IS_MAIN_WINDOW (window)) {
1364 GtkWidget *header_view;
1365 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1366 MODEST_WIDGET_TYPE_HEADER_VIEW);
1370 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1371 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1372 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1374 g_return_if_reached ();
1379 modest_ui_actions_on_sort (GtkAction *action,
1380 ModestWindow *window)
1382 g_return_if_fail (MODEST_IS_WINDOW(window));
1384 if (MODEST_IS_MAIN_WINDOW (window)) {
1385 GtkWidget *header_view;
1386 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1387 MODEST_WIDGET_TYPE_HEADER_VIEW);
1389 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1394 /* Show sorting dialog */
1395 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1400 new_messages_arrived (ModestMailOperation *self,
1404 if (new_messages == 0)
1407 modest_platform_on_new_msg ();
1411 * This function performs the send & receive required actions. The
1412 * window is used to create the mail operation. Typically it should
1413 * always be the main window, but we pass it as argument in order to
1417 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1419 gchar *acc_name = NULL;
1420 ModestMailOperation *mail_op;
1422 /* If no account name was provided then get the current account, and if
1423 there is no current account then pick the default one: */
1424 if (!account_name) {
1425 acc_name = g_strdup (modest_window_get_active_account(win));
1427 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1429 g_printerr ("modest: cannot get default account\n");
1433 acc_name = g_strdup (account_name);
1436 /* Set send/receive operation in progress */
1437 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1439 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1441 modest_ui_actions_send_receive_error_handler,
1444 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1445 G_CALLBACK (_on_send_receive_progress_changed),
1448 /* Send & receive. */
1449 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1450 /* Receive and then send. The operation is tagged initially as
1451 a receive operation because the account update performs a
1452 receive and then a send. The operation changes its type
1453 internally, so the progress objects will receive the proper
1454 progress information */
1455 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1456 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1457 g_object_unref (G_OBJECT (mail_op));
1465 modest_ui_actions_do_cancel_send (const gchar *account_name,
1468 TnyTransportAccount *transport_account;
1469 TnySendQueue *send_queue = NULL;
1470 GError *error = NULL;
1472 /* Get transport account */
1474 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1475 (modest_runtime_get_account_store(),
1477 TNY_ACCOUNT_TYPE_TRANSPORT));
1478 if (!transport_account) {
1479 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1484 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1485 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1486 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1487 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1488 "modest: could not find send queue for account\n");
1490 /* Keeep messages in outbox folder */
1491 tny_send_queue_cancel (send_queue, FALSE, &error);
1495 if (transport_account != NULL)
1496 g_object_unref (G_OBJECT (transport_account));
1500 modest_ui_actions_cancel_send_all (ModestWindow *win)
1502 GSList *account_names, *iter;
1504 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1507 iter = account_names;
1509 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1510 iter = g_slist_next (iter);
1513 modest_account_mgr_free_account_names (account_names);
1514 account_names = NULL;
1518 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1521 /* Check if accounts exist */
1522 gboolean accounts_exist =
1523 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1525 /* If not, allow the user to create an account before trying to send/receive. */
1526 if (!accounts_exist)
1527 modest_ui_actions_on_accounts (NULL, win);
1529 /* Cancel all sending operaitons */
1530 modest_ui_actions_cancel_send_all (win);
1534 * Refreshes all accounts. This function will be used by automatic
1538 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1540 GSList *account_names, *iter;
1542 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1545 iter = account_names;
1547 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1548 iter = g_slist_next (iter);
1551 modest_account_mgr_free_account_names (account_names);
1552 account_names = NULL;
1556 modest_do_refresh_current_folder(ModestWindow *win)
1558 /* Refresh currently selected folder. Note that if we only
1559 want to retreive the headers, then the refresh only will
1560 invoke a poke_status over all folders, i.e., only the
1561 total/unread count will be updated */
1562 if (MODEST_IS_MAIN_WINDOW (win)) {
1563 GtkWidget *header_view, *folder_view;
1564 TnyFolderStore *folder_store;
1566 /* Get folder and header view */
1568 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1569 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1571 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1573 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1575 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1576 MODEST_WIDGET_TYPE_HEADER_VIEW);
1578 /* We do not need to set the contents style
1579 because it hasn't changed. We also do not
1580 need to save the widget status. Just force
1582 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1583 TNY_FOLDER (folder_store),
1584 folder_refreshed_cb,
1585 MODEST_MAIN_WINDOW (win));
1589 g_object_unref (folder_store);
1595 * Handler of the click on Send&Receive button in the main toolbar
1598 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1600 /* Check if accounts exist */
1601 gboolean accounts_exist =
1602 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1604 /* If not, allow the user to create an account before trying to send/receive. */
1605 if (!accounts_exist)
1606 modest_ui_actions_on_accounts (NULL, win);
1608 modest_do_refresh_current_folder (win);
1610 /* Refresh the active account */
1611 modest_ui_actions_do_send_receive (NULL, win);
1616 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1619 GtkWidget *header_view;
1621 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1623 header_view = modest_main_window_get_child_widget (main_window,
1624 MODEST_WIDGET_TYPE_HEADER_VIEW);
1628 conf = modest_runtime_get_conf ();
1630 /* what is saved/restored is depending on the style; thus; we save with
1631 * old style, then update the style, and restore for this new style
1633 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1635 if (modest_header_view_get_style
1636 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1637 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1638 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1640 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1641 MODEST_HEADER_VIEW_STYLE_DETAILS);
1643 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1644 MODEST_CONF_HEADER_VIEW_KEY);
1649 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1651 ModestMainWindow *main_window)
1653 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1654 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1656 /* in the case the folder is empty, show the empty folder message and focus
1658 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1659 if (modest_header_view_is_empty (header_view)) {
1660 TnyFolder *folder = modest_header_view_get_folder (header_view);
1661 GtkWidget *folder_view =
1662 modest_main_window_get_child_widget (main_window,
1663 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1665 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1666 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1670 /* If no header has been selected then exit */
1675 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1676 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1678 /* Update Main window title */
1679 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1680 const gchar *subject = tny_header_get_subject (header);
1681 if (subject && strlen(subject) > 0)
1682 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1684 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1687 /* Update toolbar dimming state */
1688 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1692 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1694 ModestMainWindow *main_window)
1698 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1703 headers = tny_simple_list_new ();
1704 tny_list_prepend (headers, G_OBJECT (header));
1706 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1708 g_object_unref (headers);
1712 set_active_account_from_tny_account (TnyAccount *account,
1713 ModestWindow *window)
1715 const gchar *server_acc_name = tny_account_get_id (account);
1717 /* We need the TnyAccount provided by the
1718 account store because that is the one that
1719 knows the name of the Modest account */
1720 TnyAccount *modest_server_account = modest_server_account =
1721 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1722 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1725 const gchar *modest_acc_name =
1726 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1727 modest_window_set_active_account (window, modest_acc_name);
1728 g_object_unref (modest_server_account);
1733 folder_refreshed_cb (ModestMailOperation *mail_op,
1737 ModestMainWindow *win = NULL;
1738 GtkWidget *header_view;
1739 TnyFolder *current_folder;
1741 g_return_if_fail (TNY_IS_FOLDER (folder));
1743 win = MODEST_MAIN_WINDOW (user_data);
1745 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1748 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1749 if (current_folder != NULL && folder != current_folder) {
1754 /* Check if folder is empty and set headers view contents style */
1755 if (tny_folder_get_all_count (folder) == 0) {
1756 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1757 modest_main_window_set_contents_style (win,
1758 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1760 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1765 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1766 TnyFolderStore *folder_store,
1768 ModestMainWindow *main_window)
1771 GtkWidget *header_view;
1773 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1775 header_view = modest_main_window_get_child_widget(main_window,
1776 MODEST_WIDGET_TYPE_HEADER_VIEW);
1780 conf = modest_runtime_get_conf ();
1782 if (TNY_IS_ACCOUNT (folder_store)) {
1784 /* Update active account */
1785 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1786 /* Show account details */
1787 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1790 if (TNY_IS_FOLDER (folder_store) && selected) {
1792 /* Update the active account */
1793 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1795 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1796 g_object_unref (account);
1800 /* Set the header style by default, it could
1801 be changed later by the refresh callback to
1803 modest_main_window_set_contents_style (main_window,
1804 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1806 /* Set folder on header view. This function
1807 will call tny_folder_refresh_async so we
1808 pass a callback that will be called when
1809 finished. We use that callback to set the
1810 empty view if there are no messages */
1811 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1812 TNY_FOLDER (folder_store),
1813 folder_refreshed_cb,
1816 /* Restore configuration. We need to do this
1817 *after* the set_folder because the widget
1818 memory asks the header view about its
1820 modest_widget_memory_restore (modest_runtime_get_conf (),
1821 G_OBJECT(header_view),
1822 MODEST_CONF_HEADER_VIEW_KEY);
1824 /* Update the active account */
1825 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1826 /* Save only if we're seeing headers */
1827 if (modest_main_window_get_contents_style (main_window) ==
1828 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1829 modest_widget_memory_save (conf, G_OBJECT (header_view),
1830 MODEST_CONF_HEADER_VIEW_KEY);
1831 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1835 /* Update toolbar dimming state */
1836 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1840 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1847 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1849 online = tny_device_is_online (modest_runtime_get_device());
1852 /* already online -- the item is simply not there... */
1853 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1855 GTK_MESSAGE_WARNING,
1857 _("The %s you selected cannot be found"),
1859 gtk_dialog_run (GTK_DIALOG(dialog));
1861 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1865 GTK_RESPONSE_REJECT,
1867 GTK_RESPONSE_ACCEPT,
1869 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1870 "Do you want to get online?"), item);
1871 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1872 gtk_label_new (txt), FALSE, FALSE, 0);
1873 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1876 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1877 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1878 /* TODO: Comment about why is this commented out: */
1879 /* modest_platform_connect_and_wait (); */
1882 gtk_widget_destroy (dialog);
1886 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1889 /* g_message ("%s %s", __FUNCTION__, link); */
1894 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1897 modest_platform_activate_uri (link);
1901 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1904 modest_platform_show_uri_popup (link);
1908 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1911 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1915 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1916 const gchar *address,
1919 /* g_message ("%s %s", __FUNCTION__, address); */
1923 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1925 TnyTransportAccount *transport_account;
1926 ModestMailOperation *mail_operation;
1928 gchar *account_name, *from;
1929 ModestAccountMgr *account_mgr;
1930 gchar *info_text = NULL;
1932 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1934 data = modest_msg_edit_window_get_msg_data (edit_window);
1936 account_mgr = modest_runtime_get_account_mgr();
1937 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1939 account_name = modest_account_mgr_get_default_account (account_mgr);
1940 if (!account_name) {
1941 g_printerr ("modest: no account found\n");
1942 modest_msg_edit_window_free_msg_data (edit_window, data);
1946 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1947 account_name = g_strdup (data->account_name);
1951 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1952 (modest_runtime_get_account_store(),
1954 TNY_ACCOUNT_TYPE_TRANSPORT));
1955 if (!transport_account) {
1956 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1957 g_free (account_name);
1958 modest_msg_edit_window_free_msg_data (edit_window, data);
1961 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1963 /* Create the mail operation */
1964 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1965 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1967 modest_mail_operation_save_to_drafts (mail_operation,
1979 data->priority_flags);
1982 g_free (account_name);
1983 g_object_unref (G_OBJECT (transport_account));
1984 g_object_unref (G_OBJECT (mail_operation));
1986 modest_msg_edit_window_free_msg_data (edit_window, data);
1988 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1989 modest_platform_information_banner (NULL, NULL, info_text);
1993 /* For instance, when clicking the Send toolbar button when editing a message: */
1995 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1997 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1999 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2002 /* Offer the connection dialog, if necessary: */
2003 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2006 /* FIXME: Code added just for testing. The final version will
2007 use the send queue provided by tinymail and some
2009 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2010 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2012 account_name = modest_account_mgr_get_default_account (account_mgr);
2014 if (!account_name) {
2015 /* Run account setup wizard */
2016 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2020 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2022 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2023 account_name = g_strdup (data->account_name);
2026 /* Get the currently-active transport account for this modest account: */
2027 TnyTransportAccount *transport_account =
2028 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2029 (modest_runtime_get_account_store(),
2031 if (!transport_account) {
2032 /* Run account setup wizard */
2033 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2037 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2039 /* mail content checks and dialogs */
2040 if (data->subject == NULL || data->subject[0] == '\0') {
2041 GtkResponseType response;
2042 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2043 _("mcen_nc_subject_is_empty_send"));
2044 if (response == GTK_RESPONSE_CANCEL) {
2045 g_free (account_name);
2050 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2051 GtkResponseType response;
2052 gchar *note_message;
2053 gchar *note_subject = data->subject;
2054 if (note_subject == NULL || note_subject[0] == '\0')
2055 note_subject = _("mail_va_no_subject");
2056 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2057 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2059 g_free (note_message);
2060 if (response == GTK_RESPONSE_CANCEL) {
2061 g_free (account_name);
2066 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2068 /* Create the mail operation */
2069 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2070 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2072 modest_mail_operation_send_new_mail (mail_operation,
2083 data->priority_flags);
2087 g_free (account_name);
2088 g_object_unref (G_OBJECT (transport_account));
2089 g_object_unref (G_OBJECT (mail_operation));
2091 modest_msg_edit_window_free_msg_data (edit_window, data);
2092 modest_msg_edit_window_set_sent (edit_window, TRUE);
2094 /* Save settings and close the window: */
2095 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2099 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2100 ModestMsgEditWindow *window)
2102 ModestMsgEditFormatState *format_state = NULL;
2104 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2105 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2107 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2110 format_state = modest_msg_edit_window_get_format_state (window);
2111 g_return_if_fail (format_state != NULL);
2113 format_state->bold = gtk_toggle_action_get_active (action);
2114 modest_msg_edit_window_set_format_state (window, format_state);
2115 g_free (format_state);
2120 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2121 ModestMsgEditWindow *window)
2123 ModestMsgEditFormatState *format_state = NULL;
2125 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2126 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2128 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2131 format_state = modest_msg_edit_window_get_format_state (window);
2132 g_return_if_fail (format_state != NULL);
2134 format_state->italics = gtk_toggle_action_get_active (action);
2135 modest_msg_edit_window_set_format_state (window, format_state);
2136 g_free (format_state);
2141 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2142 ModestMsgEditWindow *window)
2144 ModestMsgEditFormatState *format_state = NULL;
2146 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2147 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2149 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2152 format_state = modest_msg_edit_window_get_format_state (window);
2153 g_return_if_fail (format_state != NULL);
2155 format_state->bullet = gtk_toggle_action_get_active (action);
2156 modest_msg_edit_window_set_format_state (window, format_state);
2157 g_free (format_state);
2162 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2163 GtkRadioAction *selected,
2164 ModestMsgEditWindow *window)
2166 ModestMsgEditFormatState *format_state = NULL;
2167 GtkJustification value;
2169 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2171 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2174 value = gtk_radio_action_get_current_value (selected);
2176 format_state = modest_msg_edit_window_get_format_state (window);
2177 g_return_if_fail (format_state != NULL);
2179 format_state->justification = value;
2180 modest_msg_edit_window_set_format_state (window, format_state);
2181 g_free (format_state);
2185 modest_ui_actions_on_select_editor_color (GtkAction *action,
2186 ModestMsgEditWindow *window)
2188 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2189 g_return_if_fail (GTK_IS_ACTION (action));
2191 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2194 modest_msg_edit_window_select_color (window);
2198 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2199 ModestMsgEditWindow *window)
2201 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2202 g_return_if_fail (GTK_IS_ACTION (action));
2204 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2207 modest_msg_edit_window_select_background_color (window);
2211 modest_ui_actions_on_insert_image (GtkAction *action,
2212 ModestMsgEditWindow *window)
2214 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2215 g_return_if_fail (GTK_IS_ACTION (action));
2217 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2220 modest_msg_edit_window_insert_image (window);
2224 modest_ui_actions_on_attach_file (GtkAction *action,
2225 ModestMsgEditWindow *window)
2227 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2228 g_return_if_fail (GTK_IS_ACTION (action));
2230 modest_msg_edit_window_offer_attach_file (window);
2234 modest_ui_actions_on_remove_attachments (GtkAction *action,
2235 ModestMsgEditWindow *window)
2237 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2238 g_return_if_fail (GTK_IS_ACTION (action));
2240 modest_msg_edit_window_remove_attachments (window, NULL);
2244 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2247 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2248 const GError *error = modest_mail_operation_get_error (mail_op);
2252 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2253 modest_mail_operation_get_error (mail_op)->message);
2258 modest_ui_actions_create_folder(GtkWidget *parent_window,
2259 GtkWidget *folder_view)
2261 TnyFolderStore *parent_folder;
2263 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2265 if (parent_folder) {
2266 gboolean finished = FALSE;
2268 gchar *folder_name = NULL, *suggested_name = NULL;
2269 const gchar *proto_str = NULL;
2270 TnyAccount *account;
2272 if (TNY_IS_ACCOUNT (parent_folder))
2273 account = g_object_ref (parent_folder);
2275 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2276 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2278 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2279 MODEST_PROTOCOL_STORE_POP) {
2281 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2283 g_object_unref (account);
2285 /* Run the new folder dialog */
2287 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2292 g_free (suggested_name);
2293 suggested_name = NULL;
2295 if (result == GTK_RESPONSE_REJECT) {
2298 ModestMailOperation *mail_op;
2299 TnyFolder *new_folder = NULL;
2301 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2302 G_OBJECT(parent_window),
2303 modest_ui_actions_new_folder_error_handler,
2306 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2308 new_folder = modest_mail_operation_create_folder (mail_op,
2310 (const gchar *) folder_name);
2312 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2315 g_object_unref (new_folder);
2318 g_object_unref (mail_op);
2321 suggested_name = folder_name;
2325 g_object_unref (parent_folder);
2330 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2332 GtkWidget *folder_view;
2334 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2336 folder_view = modest_main_window_get_child_widget (main_window,
2337 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2341 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2345 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2348 GObject *win = modest_mail_operation_get_source (mail_op);
2349 const GError *error = NULL;
2350 const gchar *message = NULL;
2352 /* Get error message */
2353 error = modest_mail_operation_get_error (mail_op);
2354 if (error != NULL && error->message != NULL) {
2355 message = error->message;
2357 message = _("!!! FIXME: Unable to rename");
2360 /* Show notification dialog */
2361 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2362 g_object_unref (win);
2366 modest_ui_actions_on_rename_folder (GtkAction *action,
2367 ModestMainWindow *main_window)
2369 TnyFolderStore *folder;
2370 GtkWidget *folder_view;
2371 GtkWidget *header_view;
2373 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2375 folder_view = modest_main_window_get_child_widget (main_window,
2376 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2380 header_view = modest_main_window_get_child_widget (main_window,
2381 MODEST_WIDGET_TYPE_HEADER_VIEW);
2386 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2390 /* Offer the connection dialog if necessary: */
2391 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2392 g_object_unref (G_OBJECT (folder));
2397 if (TNY_IS_FOLDER (folder)) {
2400 const gchar *current_name;
2402 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2403 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2404 current_name, &folder_name);
2406 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2407 ModestMailOperation *mail_op;
2410 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2411 G_OBJECT(main_window),
2412 modest_ui_actions_rename_folder_error_handler,
2416 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2419 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2421 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2422 TNY_FOLDER(folder), TRUE);
2425 modest_header_view_clear ((ModestHeaderView *) header_view);
2427 modest_mail_operation_rename_folder (mail_op,
2428 TNY_FOLDER (folder),
2429 (const gchar *) folder_name);
2431 g_object_unref (mail_op);
2432 g_free (folder_name);
2435 g_object_unref (folder);
2439 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2442 GObject *win = modest_mail_operation_get_source (mail_op);
2444 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2445 _("mail_in_ui_folder_delete_error"));
2446 g_object_unref (win);
2450 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2452 TnyFolderStore *folder;
2453 GtkWidget *folder_view;
2457 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2459 folder_view = modest_main_window_get_child_widget (main_window,
2460 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2464 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2466 /* Show an error if it's an account */
2467 if (!TNY_IS_FOLDER (folder)) {
2468 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2469 _("mail_in_ui_folder_delete_error"));
2470 g_object_unref (G_OBJECT (folder));
2474 /* Offer the connection dialog if necessary: */
2475 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2476 g_object_unref (G_OBJECT (folder));
2481 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2482 tny_folder_get_name (TNY_FOLDER (folder)));
2483 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2484 (const gchar *) message);
2487 if (response == GTK_RESPONSE_OK) {
2488 ModestMailOperation *mail_op =
2489 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2490 G_OBJECT(main_window),
2491 modest_ui_actions_delete_folder_error_handler,
2494 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2496 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2497 g_object_unref (G_OBJECT (mail_op));
2500 g_object_unref (G_OBJECT (folder));
2504 modest_ui_actions_on_delete_folder (GtkAction *action,
2505 ModestMainWindow *main_window)
2507 GtkWidget *folder_view;
2508 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2510 delete_folder (main_window, FALSE);
2511 folder_view = modest_main_window_get_child_widget (main_window,
2512 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2515 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2519 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2521 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2523 delete_folder (main_window, TRUE);
2528 show_error (GtkWidget *parent_widget, const gchar* text)
2530 hildon_banner_show_information(parent_widget, NULL, text);
2533 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2535 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2542 gtk_dialog_run (dialog);
2543 gtk_widget_destroy (GTK_WIDGET (dialog));
2548 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2549 const gchar* server_account_name,
2554 ModestMainWindow *main_window)
2556 g_return_if_fail(server_account_name);
2557 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2559 /* Initalize output parameters: */
2566 #ifdef MODEST_PLATFORM_MAEMO
2567 /* Maemo uses a different (awkward) button order,
2568 * It should probably just use gtk_alternative_dialog_button_order ().
2570 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2574 GTK_RESPONSE_ACCEPT,
2576 GTK_RESPONSE_REJECT,
2579 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2583 GTK_RESPONSE_REJECT,
2585 GTK_RESPONSE_ACCEPT,
2587 #endif /* MODEST_PLATFORM_MAEMO */
2589 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2591 gchar *server_name = modest_server_account_get_hostname (
2592 modest_runtime_get_account_mgr(), server_account_name);
2593 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2594 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2599 /* This causes a warning because the logical ID has no %s in it,
2600 * though the translation does, but there is not much we can do about that: */
2601 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2602 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2605 g_free (server_name);
2609 gchar *initial_username = modest_server_account_get_username (
2610 modest_runtime_get_account_mgr(), server_account_name);
2612 GtkWidget *entry_username = gtk_entry_new ();
2613 if (initial_username)
2614 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2615 /* Dim this if a connection has ever succeeded with this username,
2616 * as per the UI spec: */
2617 const gboolean username_known =
2618 modest_server_account_get_username_has_succeeded(
2619 modest_runtime_get_account_mgr(), server_account_name);
2620 gtk_widget_set_sensitive (entry_username, !username_known);
2622 #ifdef MODEST_PLATFORM_MAEMO
2623 /* Auto-capitalization is the default, so let's turn it off: */
2624 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2626 /* Create a size group to be used by all captions.
2627 * Note that HildonCaption does not create a default size group if we do not specify one.
2628 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2629 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2631 GtkWidget *caption = hildon_caption_new (sizegroup,
2632 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2633 gtk_widget_show (entry_username);
2634 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2635 FALSE, FALSE, MODEST_MARGIN_HALF);
2636 gtk_widget_show (caption);
2638 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2640 #endif /* MODEST_PLATFORM_MAEMO */
2643 GtkWidget *entry_password = gtk_entry_new ();
2644 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2645 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2647 #ifdef MODEST_PLATFORM_MAEMO
2648 /* Auto-capitalization is the default, so let's turn it off: */
2649 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2650 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2652 caption = hildon_caption_new (sizegroup,
2653 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2654 gtk_widget_show (entry_password);
2655 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2656 FALSE, FALSE, MODEST_MARGIN_HALF);
2657 gtk_widget_show (caption);
2658 g_object_unref (sizegroup);
2660 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2662 #endif /* MODEST_PLATFORM_MAEMO */
2664 /* This is not in the Maemo UI spec:
2665 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2666 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2670 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2672 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2674 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2676 modest_server_account_set_username (
2677 modest_runtime_get_account_mgr(), server_account_name,
2680 const gboolean username_was_changed =
2681 (strcmp (*username, initial_username) != 0);
2682 if (username_was_changed) {
2683 g_warning ("%s: tinymail does not yet support changing the "
2684 "username in the get_password() callback.\n", __FUNCTION__);
2689 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2691 /* We do not save the password in the configuration,
2692 * because this function is only called for passwords that should
2693 * not be remembered:
2694 modest_server_account_set_password (
2695 modest_runtime_get_account_mgr(), server_account_name,
2704 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2716 /* This is not in the Maemo UI spec:
2717 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2723 gtk_widget_destroy (dialog);
2725 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2729 modest_ui_actions_on_cut (GtkAction *action,
2730 ModestWindow *window)
2732 GtkWidget *focused_widget;
2733 GtkClipboard *clipboard;
2735 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2736 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2737 if (GTK_IS_EDITABLE (focused_widget)) {
2738 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2739 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2740 gtk_clipboard_store (clipboard);
2741 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2742 GtkTextBuffer *buffer;
2744 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2745 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2746 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2747 gtk_clipboard_store (clipboard);
2748 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2749 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2750 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2751 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2756 modest_ui_actions_on_copy (GtkAction *action,
2757 ModestWindow *window)
2759 GtkClipboard *clipboard;
2760 GtkWidget *focused_widget;
2762 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2763 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2765 if (GTK_IS_LABEL (focused_widget)) {
2766 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2767 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2768 gtk_clipboard_store (clipboard);
2769 } else if (GTK_IS_EDITABLE (focused_widget)) {
2770 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2771 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2772 gtk_clipboard_store (clipboard);
2773 } else if (GTK_IS_HTML (focused_widget)) {
2774 gtk_html_copy (GTK_HTML (focused_widget));
2775 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2776 gtk_clipboard_store (clipboard);
2777 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2778 GtkTextBuffer *buffer;
2779 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2780 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2781 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2782 gtk_clipboard_store (clipboard);
2783 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2784 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2785 TnyIterator *iter = tny_list_create_iterator (header_list);
2786 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2788 gboolean ask = FALSE;
2790 TnyFolder *folder = tny_header_get_folder (header);
2791 TnyAccount *account = tny_folder_get_account (folder);
2792 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2793 /* If it's POP then ask */
2794 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2795 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2796 g_object_unref (account);
2797 g_object_unref (folder);
2798 g_object_unref (header);
2801 g_object_unref (iter);
2803 /* Check that the messages have been previously downloaded */
2804 gboolean continue_download = TRUE;
2806 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2807 if (continue_download)
2808 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2809 g_object_unref (header_list);
2810 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2811 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2814 /* Show information banner */
2815 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2820 modest_ui_actions_on_undo (GtkAction *action,
2821 ModestWindow *window)
2823 ModestEmailClipboard *clipboard = NULL;
2825 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2826 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2827 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2828 /* Clear clipboard source */
2829 clipboard = modest_runtime_get_email_clipboard ();
2830 modest_email_clipboard_clear (clipboard);
2833 g_return_if_reached ();
2838 modest_ui_actions_on_redo (GtkAction *action,
2839 ModestWindow *window)
2841 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2842 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2845 g_return_if_reached ();
2851 paste_msgs_cb (const GObject *object, gpointer user_data)
2853 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2854 g_return_if_fail (GTK_IS_WIDGET (user_data));
2856 /* destroy information note */
2857 gtk_widget_destroy (GTK_WIDGET(user_data));
2861 paste_as_attachment_free (gpointer data)
2863 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2865 gtk_widget_destroy (helper->banner);
2866 g_object_unref (helper->banner);
2871 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2876 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2877 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2882 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2887 modest_ui_actions_on_paste (GtkAction *action,
2888 ModestWindow *window)
2890 GtkWidget *focused_widget = NULL;
2891 GtkWidget *inf_note = NULL;
2892 ModestMailOperation *mail_op = NULL;
2894 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2895 if (GTK_IS_EDITABLE (focused_widget)) {
2896 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2897 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2898 ModestEmailClipboard *e_clipboard = NULL;
2899 e_clipboard = modest_runtime_get_email_clipboard ();
2900 if (modest_email_clipboard_cleared (e_clipboard)) {
2901 GtkTextBuffer *buffer;
2902 GtkClipboard *clipboard;
2904 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2905 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2906 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2907 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2908 ModestMailOperation *mail_op;
2909 TnyFolder *src_folder;
2912 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2913 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2914 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2915 _CS("ckct_nw_pasting"));
2916 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2917 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2919 if (helper->banner != NULL) {
2920 g_object_ref (G_OBJECT (helper->banner));
2921 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2922 gtk_widget_show (GTK_WIDGET (helper->banner));
2926 modest_mail_operation_get_msgs_full (mail_op,
2928 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2930 paste_as_attachment_free);
2933 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2934 ModestEmailClipboard *clipboard = NULL;
2935 TnyFolder *src_folder = NULL;
2936 TnyFolderStore *folder_store = NULL;
2937 TnyList *data = NULL;
2938 gboolean delete = FALSE;
2940 /* Check clipboard source */
2941 clipboard = modest_runtime_get_email_clipboard ();
2942 if (modest_email_clipboard_cleared (clipboard))
2945 /* Get elements to paste */
2946 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2948 /* Create a new mail operation */
2949 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2950 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2953 /* Get destination folder */
2954 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2956 /* Launch notification */
2957 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2958 _CS("ckct_nw_pasting"));
2959 if (inf_note != NULL) {
2960 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2961 gtk_widget_show (GTK_WIDGET(inf_note));
2964 /* transfer messages */
2966 modest_mail_operation_xfer_msgs (mail_op,
2968 TNY_FOLDER (folder_store),
2973 } else if (src_folder != NULL) {
2974 modest_mail_operation_xfer_folder (mail_op,
2984 g_object_unref (data);
2985 if (src_folder != NULL)
2986 g_object_unref (src_folder);
2987 if (folder_store != NULL)
2988 g_object_unref (folder_store);
2994 modest_ui_actions_on_select_all (GtkAction *action,
2995 ModestWindow *window)
2997 GtkWidget *focused_widget;
2999 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3000 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3001 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3002 } else if (GTK_IS_LABEL (focused_widget)) {
3003 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3004 } else if (GTK_IS_EDITABLE (focused_widget)) {
3005 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3006 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3007 GtkTextBuffer *buffer;
3008 GtkTextIter start, end;
3010 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3011 gtk_text_buffer_get_start_iter (buffer, &start);
3012 gtk_text_buffer_get_end_iter (buffer, &end);
3013 gtk_text_buffer_select_range (buffer, &start, &end);
3014 } else if (GTK_IS_HTML (focused_widget)) {
3015 gtk_html_select_all (GTK_HTML (focused_widget));
3016 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3017 GtkWidget *header_view = focused_widget;
3018 GtkTreeSelection *selection = NULL;
3020 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3021 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3022 MODEST_WIDGET_TYPE_HEADER_VIEW);
3024 /* Select all messages */
3025 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3026 gtk_tree_selection_select_all (selection);
3028 /* Set focuse on header view */
3029 gtk_widget_grab_focus (header_view);
3035 modest_ui_actions_on_mark_as_read (GtkAction *action,
3036 ModestWindow *window)
3038 g_return_if_fail (MODEST_IS_WINDOW(window));
3040 /* Mark each header as read */
3041 do_headers_action (window, headers_action_mark_as_read, NULL);
3045 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3046 ModestWindow *window)
3048 g_return_if_fail (MODEST_IS_WINDOW(window));
3050 /* Mark each header as read */
3051 do_headers_action (window, headers_action_mark_as_unread, NULL);
3055 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3056 GtkRadioAction *selected,
3057 ModestWindow *window)
3061 value = gtk_radio_action_get_current_value (selected);
3062 if (MODEST_IS_WINDOW (window)) {
3063 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3067 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3068 GtkRadioAction *selected,
3069 ModestWindow *window)
3071 TnyHeaderFlags flags;
3072 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3074 flags = gtk_radio_action_get_current_value (selected);
3075 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3078 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3079 GtkRadioAction *selected,
3080 ModestWindow *window)
3084 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3086 file_format = gtk_radio_action_get_current_value (selected);
3087 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3092 modest_ui_actions_on_zoom_plus (GtkAction *action,
3093 ModestWindow *window)
3095 g_return_if_fail (MODEST_IS_WINDOW (window));
3097 modest_window_zoom_plus (MODEST_WINDOW (window));
3101 modest_ui_actions_on_zoom_minus (GtkAction *action,
3102 ModestWindow *window)
3104 g_return_if_fail (MODEST_IS_WINDOW (window));
3106 modest_window_zoom_minus (MODEST_WINDOW (window));
3110 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3111 ModestWindow *window)
3113 ModestWindowMgr *mgr;
3114 gboolean fullscreen, active;
3115 g_return_if_fail (MODEST_IS_WINDOW (window));
3117 mgr = modest_runtime_get_window_mgr ();
3119 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3120 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3122 if (active != fullscreen) {
3123 modest_window_mgr_set_fullscreen_mode (mgr, active);
3124 gtk_window_present (GTK_WINDOW (window));
3129 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3130 ModestWindow *window)
3132 ModestWindowMgr *mgr;
3133 gboolean fullscreen;
3135 g_return_if_fail (MODEST_IS_WINDOW (window));
3137 mgr = modest_runtime_get_window_mgr ();
3138 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3139 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3141 gtk_window_present (GTK_WINDOW (window));
3145 * Used by modest_ui_actions_on_details to call do_headers_action
3148 headers_action_show_details (TnyHeader *header,
3149 ModestWindow *window,
3156 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3159 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3160 gtk_widget_show_all (dialog);
3161 gtk_dialog_run (GTK_DIALOG (dialog));
3163 gtk_widget_destroy (dialog);
3167 * Show the folder details in a ModestDetailsDialog widget
3170 show_folder_details (TnyFolder *folder,
3176 dialog = modest_details_dialog_new_with_folder (window, folder);
3179 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3180 gtk_widget_show_all (dialog);
3181 gtk_dialog_run (GTK_DIALOG (dialog));
3183 gtk_widget_destroy (dialog);
3187 * Show the header details in a ModestDetailsDialog widget
3190 modest_ui_actions_on_details (GtkAction *action,
3193 TnyList * headers_list;
3197 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3200 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3203 g_object_unref (msg);
3205 headers_list = get_selected_headers (win);
3209 iter = tny_list_create_iterator (headers_list);
3211 header = TNY_HEADER (tny_iterator_get_current (iter));
3213 headers_action_show_details (header, win, NULL);
3214 g_object_unref (header);
3217 g_object_unref (iter);
3218 g_object_unref (headers_list);
3220 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3221 GtkWidget *folder_view, *header_view;
3223 /* Check which widget has the focus */
3224 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3225 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3226 if (gtk_widget_is_focus (folder_view)) {
3227 TnyFolderStore *folder_store
3228 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3229 if (!folder_store) {
3230 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3233 /* Show only when it's a folder */
3234 /* This function should not be called for account items,
3235 * because we dim the menu item for them. */
3236 if (TNY_IS_FOLDER (folder_store)) {
3237 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3240 g_object_unref (folder_store);
3243 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3244 MODEST_WIDGET_TYPE_HEADER_VIEW);
3245 /* Show details of each header */
3246 do_headers_action (win, headers_action_show_details, header_view);
3252 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3253 ModestMsgEditWindow *window)
3255 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3257 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3261 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3262 ModestMsgEditWindow *window)
3264 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3266 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3270 modest_ui_actions_toggle_folders_view (GtkAction *action,
3271 ModestMainWindow *main_window)
3273 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3275 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3276 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3278 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3282 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3283 ModestWindow *window)
3285 gboolean active, fullscreen = FALSE;
3286 ModestWindowMgr *mgr;
3288 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3290 /* Check if we want to toggle the toolbar vuew in fullscreen
3292 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3293 "ViewShowToolbarFullScreen")) {
3297 /* Toggle toolbar */
3298 mgr = modest_runtime_get_window_mgr ();
3299 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3303 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3304 ModestMsgEditWindow *window)
3306 modest_msg_edit_window_select_font (window);
3310 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3311 const gchar *display_name,
3314 /* Do not change the application name if the widget has not
3315 the focus. This callback could be called even if the folder
3316 view has not the focus, because the handled signal could be
3317 emitted when the folder view is redrawn */
3318 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3320 gtk_window_set_title (window, display_name);
3322 gtk_window_set_title (window, " ");
3327 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3329 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3330 modest_msg_edit_window_select_contacts (window);
3334 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3336 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3337 modest_msg_edit_window_check_names (window, FALSE);
3341 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3343 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3344 GTK_WIDGET (user_data));
3348 create_move_to_dialog (GtkWindow *win,
3349 GtkWidget *folder_view,
3350 GtkWidget **tree_view)
3352 GtkWidget *dialog, *scroll;
3353 GtkWidget *new_button;
3355 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3357 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3360 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3361 /* We do this manually so GTK+ does not associate a response ID for
3363 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3364 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3365 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3367 /* Create scrolled window */
3368 scroll = gtk_scrolled_window_new (NULL, NULL);
3369 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3370 GTK_POLICY_AUTOMATIC,
3371 GTK_POLICY_AUTOMATIC);
3373 /* Create folder view */
3374 *tree_view = modest_platform_create_folder_view (NULL);
3376 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3378 /* It could happen that we're trying to move a message from a
3379 window (msg window for example) after the main window was
3380 closed, so we can not just get the model of the folder
3382 if (MODEST_IS_FOLDER_VIEW (folder_view))
3383 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3384 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3386 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3387 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3389 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3391 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3393 /* Add scroll to dialog */
3394 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3395 scroll, TRUE, TRUE, 0);
3397 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3398 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3404 * Returns TRUE if at least one of the headers of the list belongs to
3405 * a message that has been fully retrieved.
3408 has_retrieved_msgs (TnyList *list)
3411 gboolean found = FALSE;
3413 iter = tny_list_create_iterator (list);
3414 while (tny_iterator_is_done (iter) && !found) {
3416 TnyHeaderFlags flags = 0;
3418 header = TNY_HEADER (tny_iterator_get_current (iter));
3420 flags = tny_header_get_flags (header);
3421 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
3424 g_object_unref (header);
3428 tny_iterator_next (iter);
3430 g_object_unref (iter);
3436 * Shows a confirmation dialog to the user when we're moving messages
3437 * from a remote server to the local storage. Returns the dialog
3438 * response. If it's other kind of movement the it always returns
3442 msgs_move_to_confirmation (GtkWindow *win,
3443 TnyFolder *dest_folder,
3446 gint response = GTK_RESPONSE_OK;
3448 /* If the destination is a local folder */
3449 if (modest_tny_folder_is_local_folder (dest_folder)) {
3450 TnyFolder *src_folder = NULL;
3451 TnyIterator *iter = NULL;
3452 TnyHeader *header = NULL;
3454 /* Get source folder */
3455 iter = tny_list_create_iterator (headers);
3456 header = TNY_HEADER (tny_iterator_get_current (iter));
3458 src_folder = tny_header_get_folder (header);
3459 g_object_unref (header);
3462 g_object_unref (iter);
3464 /* if no src_folder, message may be an attahcment */
3465 if (src_folder == NULL)
3466 return GTK_RESPONSE_CANCEL;
3468 /* If the source is a remote folder */
3469 if (!modest_tny_folder_is_local_folder (src_folder)) {
3470 const gchar *message;
3472 if (has_retrieved_msgs (headers))
3473 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3474 tny_list_get_length (headers));
3476 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3477 tny_list_get_length (headers));
3479 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3480 (const gchar *) message);
3483 g_object_unref (src_folder);
3492 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3494 ModestMsgViewWindow *self = NULL;
3496 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3497 self = MODEST_MSG_VIEW_WINDOW (object);
3499 if (!modest_msg_view_window_select_next_message (self))
3500 if (!modest_msg_view_window_select_previous_message (self))
3501 /* No more messages to view, so close this window */
3502 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3506 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3509 GObject *win = modest_mail_operation_get_source (mail_op);
3510 const GError *error = NULL;
3511 const gchar *message = NULL;
3513 /* Get error message */
3514 error = modest_mail_operation_get_error (mail_op);
3515 if (error != NULL && error->message != NULL) {
3516 message = error->message;
3518 message = _("mail_in_ui_folder_move_target_error");
3521 /* Show notification dialog */
3522 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3523 g_object_unref (win);
3527 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3530 GObject *win = modest_mail_operation_get_source (mail_op);
3531 const GError *error = modest_mail_operation_get_error (mail_op);
3533 g_return_if_fail (error != NULL);
3534 if (error->message != NULL)
3535 g_printerr ("modest: %s\n", error->message);
3537 g_printerr ("modest: unkonw error on send&receive operation");
3539 /* Show error message */
3540 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3541 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3542 /* _CS("sfil_ib_unable_to_receive")); */
3544 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3545 /* _CS("sfil_ib_unable_to_send")); */
3546 g_object_unref (win);
3550 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3557 gint pending_purges = 0;
3558 gboolean some_purged = FALSE;
3559 ModestWindow *win = MODEST_WINDOW (user_data);
3560 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3562 /* If there was any error */
3563 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3564 modest_window_mgr_unregister_header (mgr, header);
3568 /* Once the message has been retrieved for purging, we check if
3569 * it's all ok for purging */
3571 parts = tny_simple_list_new ();
3572 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3573 iter = tny_list_create_iterator (parts);
3575 while (!tny_iterator_is_done (iter)) {
3577 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3578 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3579 if (tny_mime_part_is_purged (part))
3586 g_object_unref (part);
3588 tny_iterator_next (iter);
3591 if (pending_purges>0) {
3593 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3595 if (response == GTK_RESPONSE_OK) {
3596 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3597 tny_iterator_first (iter);
3598 while (!tny_iterator_is_done (iter)) {
3601 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3602 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3603 tny_mime_part_set_purged (part);
3606 g_object_unref (part);
3608 tny_iterator_next (iter);
3611 tny_msg_rewrite_cache (msg);
3614 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3617 /* remove attachments */
3618 tny_iterator_first (iter);
3619 while (!tny_iterator_is_done (iter)) {
3622 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3624 /* One for the reference given by tny_iterator_get_current(): */
3625 g_object_unref (part);
3627 /* TODO: Is this meant to remove the attachment by doing another unref()?
3628 * Otherwise, this seems useless. */
3631 tny_iterator_next (iter);
3633 modest_window_mgr_unregister_header (mgr, header);
3635 g_object_unref (iter);
3636 g_object_unref (parts);
3640 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3641 ModestMainWindow *win)
3643 GtkWidget *header_view;
3644 TnyList *header_list;
3647 TnyHeaderFlags flags;
3648 ModestWindow *msg_view_window = NULL;
3651 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3653 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3654 MODEST_WIDGET_TYPE_HEADER_VIEW);
3656 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3658 if (tny_list_get_length (header_list) == 1) {
3659 iter = tny_list_create_iterator (header_list);
3660 header = TNY_HEADER (tny_iterator_get_current (iter));
3661 g_object_unref (iter);
3666 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3667 header, &msg_view_window);
3668 flags = tny_header_get_flags (header);
3669 if (!(flags & TNY_HEADER_FLAG_CACHED))
3672 if (msg_view_window != NULL)
3673 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3675 /* do nothing; uid was registered before, so window is probably on it's way */
3676 g_warning ("debug: header %p has already been registered", header);
3679 ModestMailOperation *mail_op = NULL;
3680 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3681 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3683 modest_ui_actions_get_msgs_full_error_handler,
3685 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3686 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3688 g_object_unref (mail_op);
3691 g_object_unref (header);
3693 g_object_unref (header_list);
3697 * Utility function that transfer messages from both the main window
3698 * and the msg view window when using the "Move to" dialog
3701 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3704 TnyList *headers = NULL;
3706 TnyAccount *dst_account = NULL;
3707 const gchar *proto_str = NULL;
3708 gboolean dst_is_pop = FALSE;
3710 if (!TNY_IS_FOLDER (dst_folder)) {
3711 modest_platform_information_banner (GTK_WIDGET (win),
3713 _CS("ckdg_ib_unable_to_move_to_current_location"));
3717 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3718 proto_str = tny_account_get_proto (dst_account);
3719 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3720 MODEST_PROTOCOL_STORE_POP);
3721 g_object_unref (dst_account);
3723 /* Get selected headers */
3724 headers = get_selected_headers (MODEST_WINDOW (win));
3727 modest_platform_information_banner (GTK_WIDGET (win),
3729 ngettext("mail_in_ui_folder_move_target_error",
3730 "mail_in_ui_folder_move_targets_error",
3731 tny_list_get_length (headers)));
3732 g_object_unref (headers);
3736 /* Ask for user confirmation */
3737 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3738 TNY_FOLDER (dst_folder),
3741 /* Transfer messages */
3742 if (response == GTK_RESPONSE_OK) {
3743 ModestMailOperation *mail_op =
3744 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3746 modest_ui_actions_move_folder_error_handler,
3748 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3751 modest_mail_operation_xfer_msgs (mail_op,
3753 TNY_FOLDER (dst_folder),
3755 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3758 g_object_unref (G_OBJECT (mail_op));
3760 g_object_unref (headers);
3765 * UI handler for the "Move to" action when invoked from the
3769 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3770 GtkWidget *folder_view,
3771 TnyFolderStore *dst_folder,
3772 ModestMainWindow *win)
3774 GtkWidget *header_view = NULL;
3775 ModestMailOperation *mail_op = NULL;
3776 TnyFolderStore *src_folder;
3778 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3780 /* Get the source folder */
3781 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3783 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3784 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3788 /* Get header view */
3790 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3792 /* Get folder or messages to transfer */
3793 if (gtk_widget_is_focus (folder_view)) {
3795 /* Allow only to transfer folders to the local root folder */
3796 if (TNY_IS_ACCOUNT (dst_folder) &&
3797 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3800 /* Clean folder on header view before moving it */
3801 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3803 if (TNY_IS_FOLDER (src_folder)) {
3805 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3807 modest_ui_actions_move_folder_error_handler,
3809 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3812 modest_mail_operation_xfer_folder (mail_op,
3813 TNY_FOLDER (src_folder),
3816 /* Unref mail operation */
3817 g_object_unref (G_OBJECT (mail_op));
3819 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3821 } else if (gtk_widget_is_focus (header_view)) {
3822 /* Transfer messages */
3823 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3828 g_object_unref (src_folder);
3833 * UI handler for the "Move to" action when invoked from the
3834 * ModestMsgViewWindow
3837 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3838 TnyFolderStore *dst_folder,
3839 ModestMsgViewWindow *win)
3841 TnyHeader *header = NULL;
3842 TnyFolder *src_folder;
3844 /* Create header list */
3845 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3846 src_folder = tny_header_get_folder(header);
3847 g_object_unref (header);
3849 /* Transfer the message */
3850 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3851 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3853 g_object_unref (src_folder);
3857 modest_ui_actions_on_move_to (GtkAction *action,
3860 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3862 TnyFolderStore *dst_folder = NULL;
3863 ModestMainWindow *main_window;
3865 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3866 MODEST_IS_MSG_VIEW_WINDOW (win));
3868 /* Get the main window if exists */
3869 if (MODEST_IS_MAIN_WINDOW (win))
3870 main_window = MODEST_MAIN_WINDOW (win);
3873 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3875 /* Get the folder view widget if exists */
3877 folder_view = modest_main_window_get_child_widget (main_window,
3878 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3882 /* Create and run the dialog */
3883 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3884 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3885 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3886 result = gtk_dialog_run (GTK_DIALOG(dialog));
3887 g_object_ref (tree_view);
3888 gtk_widget_destroy (dialog);
3890 if (result != GTK_RESPONSE_ACCEPT)
3893 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3894 /* Offer the connection dialog if necessary: */
3895 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3898 /* Do window specific stuff */
3899 if (MODEST_IS_MAIN_WINDOW (win))
3900 modest_ui_actions_on_main_window_move_to (action,
3903 MODEST_MAIN_WINDOW (win));
3905 modest_ui_actions_on_msg_view_window_move_to (action,
3907 MODEST_MSG_VIEW_WINDOW (win));
3910 g_object_unref (dst_folder);
3914 * Calls #HeadersFunc for each header already selected in the main
3915 * window or the message currently being shown in the msg view window
3918 do_headers_action (ModestWindow *win,
3922 TnyList *headers_list = NULL;
3923 TnyIterator *iter = NULL;
3924 TnyHeader *header = NULL;
3925 TnyFolder *folder = NULL;
3928 headers_list = get_selected_headers (win);
3932 /* Get the folder */
3933 iter = tny_list_create_iterator (headers_list);
3934 header = TNY_HEADER (tny_iterator_get_current (iter));
3936 folder = tny_header_get_folder (header);
3937 g_object_unref (header);
3940 /* Call the function for each header */
3941 while (!tny_iterator_is_done (iter)) {
3942 header = TNY_HEADER (tny_iterator_get_current (iter));
3943 func (header, win, user_data);
3944 g_object_unref (header);
3945 tny_iterator_next (iter);
3948 /* Trick: do a poke status in order to speed up the signaling
3950 tny_folder_poke_status (folder);
3953 g_object_unref (folder);
3954 g_object_unref (iter);
3955 g_object_unref (headers_list);
3959 modest_ui_actions_view_attachment (GtkAction *action,
3960 ModestWindow *window)
3962 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3963 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3965 /* not supported window for this action */
3966 g_return_if_reached ();
3971 modest_ui_actions_save_attachments (GtkAction *action,
3972 ModestWindow *window)
3974 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3975 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3977 /* not supported window for this action */
3978 g_return_if_reached ();
3983 modest_ui_actions_remove_attachments (GtkAction *action,
3984 ModestWindow *window)
3986 if (MODEST_IS_MAIN_WINDOW (window)) {
3987 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3988 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3989 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3991 /* not supported window for this action */
3992 g_return_if_reached ();
3997 modest_ui_actions_on_settings (GtkAction *action,
4002 dialog = modest_platform_get_global_settings_dialog ();
4003 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4004 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4005 gtk_widget_show_all (dialog);
4007 gtk_dialog_run (GTK_DIALOG (dialog));
4009 gtk_widget_destroy (dialog);
4013 modest_ui_actions_on_help (GtkAction *action,
4016 const gchar *help_id = NULL;
4018 if (MODEST_IS_MAIN_WINDOW (win)) {
4019 const gchar *action_name;
4020 action_name = gtk_action_get_name (action);
4022 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4023 !strcmp (action_name, "HeaderViewCSMHelp")) {
4024 GtkWidget *folder_view;
4025 TnyFolderStore *folder_store;
4026 /* Get selected folder */
4027 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4028 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4029 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4031 /* Switch help_id */
4032 if (TNY_IS_FOLDER (folder_store)) {
4033 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4034 case TNY_FOLDER_TYPE_NORMAL:
4035 help_id = "applications_email_managefolders";
4037 case TNY_FOLDER_TYPE_INBOX:
4038 help_id = "applications_email_inbox";
4040 case TNY_FOLDER_TYPE_OUTBOX:
4041 help_id = "applications_email_outbox";
4043 case TNY_FOLDER_TYPE_SENT:
4044 help_id = "applications_email_sent";
4046 case TNY_FOLDER_TYPE_DRAFTS:
4047 help_id = "applications_email_drafts";
4049 case TNY_FOLDER_TYPE_ARCHIVE:
4050 help_id = "applications_email_managefolders";
4053 help_id = "applications_email_managefolders";
4056 help_id = "applications_email_mainview";
4058 g_object_unref (folder_store);
4060 help_id = "applications_email_mainview";
4062 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4063 help_id = "applications_email_viewer";
4064 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4065 help_id = "applications_email_editor";
4067 modest_platform_show_help (GTK_WINDOW (win), help_id);
4071 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4072 ModestWindow *window)
4074 ModestMailOperation *mail_op;
4078 headers = get_selected_headers (window);
4082 /* Create mail operation */
4083 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4085 modest_ui_actions_get_msgs_full_error_handler,
4087 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4088 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4091 g_object_unref (headers);
4092 g_object_unref (mail_op);
4096 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4097 ModestWindow *window)
4099 g_return_if_fail (MODEST_IS_WINDOW (window));
4102 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4106 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4107 ModestWindow *window)
4109 g_return_if_fail (MODEST_IS_WINDOW (window));
4112 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4116 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4117 ModestWindow *window)
4119 g_return_if_fail (MODEST_IS_WINDOW (window));
4122 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4126 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4127 ModestWindow *window)
4129 g_return_if_fail (MODEST_IS_WINDOW (window));
4132 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4136 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4137 ModestWindow *window)
4139 g_return_if_fail (MODEST_IS_WINDOW (window));
4142 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4146 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4147 ModestWindow *window)
4149 g_return_if_fail (MODEST_IS_WINDOW (window));
4152 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4156 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4157 ModestWindow *window)
4159 g_return_if_fail (MODEST_IS_WINDOW (window));
4162 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4166 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4167 ModestWindow *window)
4169 g_return_if_fail (MODEST_IS_WINDOW (window));
4172 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4176 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4178 g_return_if_fail (MODEST_IS_WINDOW (window));
4181 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4185 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4187 g_return_if_fail (MODEST_IS_WINDOW (window));
4189 modest_platform_show_search_messages (GTK_WINDOW (window));
4193 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4195 g_return_if_fail (MODEST_IS_WINDOW (win));
4196 modest_platform_show_addressbook (GTK_WINDOW (win));
4201 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4202 ModestWindow *window)
4204 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4206 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4210 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4211 ModestMailOperationState *state,
4214 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4216 /* Set send/receive operation finished */
4217 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4218 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));