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;
2270 /* Run the new folder dialog */
2272 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2277 g_free (suggested_name);
2278 suggested_name = NULL;
2280 if (result == GTK_RESPONSE_REJECT) {
2283 ModestMailOperation *mail_op;
2284 TnyFolder *new_folder = NULL;
2286 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2287 G_OBJECT(parent_window),
2288 modest_ui_actions_new_folder_error_handler,
2291 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2293 new_folder = modest_mail_operation_create_folder (mail_op,
2295 (const gchar *) folder_name);
2297 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2300 g_object_unref (new_folder);
2303 g_object_unref (mail_op);
2306 suggested_name = folder_name;
2310 g_object_unref (parent_folder);
2315 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2317 GtkWidget *folder_view;
2319 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2321 folder_view = modest_main_window_get_child_widget (main_window,
2322 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2326 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2330 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2333 GObject *win = modest_mail_operation_get_source (mail_op);
2334 const GError *error = NULL;
2335 const gchar *message = NULL;
2337 /* Get error message */
2338 error = modest_mail_operation_get_error (mail_op);
2339 if (error != NULL && error->message != NULL) {
2340 message = error->message;
2342 message = _("!!! FIXME: Unable to rename");
2345 /* Show notification dialog */
2346 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2347 g_object_unref (win);
2351 modest_ui_actions_on_rename_folder (GtkAction *action,
2352 ModestMainWindow *main_window)
2354 TnyFolderStore *folder;
2355 GtkWidget *folder_view;
2356 GtkWidget *header_view;
2358 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2360 folder_view = modest_main_window_get_child_widget (main_window,
2361 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2365 header_view = modest_main_window_get_child_widget (main_window,
2366 MODEST_WIDGET_TYPE_HEADER_VIEW);
2371 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2375 /* Offer the connection dialog if necessary: */
2376 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2377 g_object_unref (G_OBJECT (folder));
2382 if (TNY_IS_FOLDER (folder)) {
2385 const gchar *current_name;
2387 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2388 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2389 current_name, &folder_name);
2391 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2392 ModestMailOperation *mail_op;
2395 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2396 G_OBJECT(main_window),
2397 modest_ui_actions_rename_folder_error_handler,
2401 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2404 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2406 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2407 TNY_FOLDER(folder), TRUE);
2410 modest_header_view_clear ((ModestHeaderView *) header_view);
2412 modest_mail_operation_rename_folder (mail_op,
2413 TNY_FOLDER (folder),
2414 (const gchar *) folder_name);
2416 g_object_unref (mail_op);
2417 g_free (folder_name);
2420 g_object_unref (folder);
2424 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2427 GObject *win = modest_mail_operation_get_source (mail_op);
2429 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2430 _("mail_in_ui_folder_delete_error"));
2431 g_object_unref (win);
2435 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2437 TnyFolderStore *folder;
2438 GtkWidget *folder_view;
2442 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2444 folder_view = modest_main_window_get_child_widget (main_window,
2445 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2449 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2451 /* Show an error if it's an account */
2452 if (!TNY_IS_FOLDER (folder)) {
2453 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2454 _("mail_in_ui_folder_delete_error"));
2455 g_object_unref (G_OBJECT (folder));
2459 /* Offer the connection dialog if necessary: */
2460 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2461 g_object_unref (G_OBJECT (folder));
2466 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2467 tny_folder_get_name (TNY_FOLDER (folder)));
2468 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2469 (const gchar *) message);
2472 if (response == GTK_RESPONSE_OK) {
2473 ModestMailOperation *mail_op =
2474 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2475 G_OBJECT(main_window),
2476 modest_ui_actions_delete_folder_error_handler,
2479 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2481 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2482 g_object_unref (G_OBJECT (mail_op));
2485 g_object_unref (G_OBJECT (folder));
2489 modest_ui_actions_on_delete_folder (GtkAction *action,
2490 ModestMainWindow *main_window)
2492 GtkWidget *folder_view;
2493 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2495 delete_folder (main_window, FALSE);
2496 folder_view = modest_main_window_get_child_widget (main_window,
2497 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2500 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2504 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2506 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2508 delete_folder (main_window, TRUE);
2513 show_error (GtkWidget *parent_widget, const gchar* text)
2515 hildon_banner_show_information(parent_widget, NULL, text);
2518 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2520 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2527 gtk_dialog_run (dialog);
2528 gtk_widget_destroy (GTK_WIDGET (dialog));
2533 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2534 const gchar* server_account_name,
2539 ModestMainWindow *main_window)
2541 g_return_if_fail(server_account_name);
2542 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2544 /* Initalize output parameters: */
2551 #ifdef MODEST_PLATFORM_MAEMO
2552 /* Maemo uses a different (awkward) button order,
2553 * It should probably just use gtk_alternative_dialog_button_order ().
2555 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2559 GTK_RESPONSE_ACCEPT,
2561 GTK_RESPONSE_REJECT,
2564 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2568 GTK_RESPONSE_REJECT,
2570 GTK_RESPONSE_ACCEPT,
2572 #endif /* MODEST_PLATFORM_MAEMO */
2574 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2576 gchar *server_name = modest_server_account_get_hostname (
2577 modest_runtime_get_account_mgr(), server_account_name);
2578 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2579 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2584 /* This causes a warning because the logical ID has no %s in it,
2585 * though the translation does, but there is not much we can do about that: */
2586 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2587 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2590 g_free (server_name);
2594 gchar *initial_username = modest_server_account_get_username (
2595 modest_runtime_get_account_mgr(), server_account_name);
2597 GtkWidget *entry_username = gtk_entry_new ();
2598 if (initial_username)
2599 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2600 /* Dim this if a connection has ever succeeded with this username,
2601 * as per the UI spec: */
2602 const gboolean username_known =
2603 modest_server_account_get_username_has_succeeded(
2604 modest_runtime_get_account_mgr(), server_account_name);
2605 gtk_widget_set_sensitive (entry_username, !username_known);
2607 #ifdef MODEST_PLATFORM_MAEMO
2608 /* Auto-capitalization is the default, so let's turn it off: */
2609 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2611 /* Create a size group to be used by all captions.
2612 * Note that HildonCaption does not create a default size group if we do not specify one.
2613 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2614 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2616 GtkWidget *caption = hildon_caption_new (sizegroup,
2617 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2618 gtk_widget_show (entry_username);
2619 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2620 FALSE, FALSE, MODEST_MARGIN_HALF);
2621 gtk_widget_show (caption);
2623 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2625 #endif /* MODEST_PLATFORM_MAEMO */
2628 GtkWidget *entry_password = gtk_entry_new ();
2629 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2630 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2632 #ifdef MODEST_PLATFORM_MAEMO
2633 /* Auto-capitalization is the default, so let's turn it off: */
2634 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2635 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2637 caption = hildon_caption_new (sizegroup,
2638 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2639 gtk_widget_show (entry_password);
2640 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2641 FALSE, FALSE, MODEST_MARGIN_HALF);
2642 gtk_widget_show (caption);
2643 g_object_unref (sizegroup);
2645 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2647 #endif /* MODEST_PLATFORM_MAEMO */
2649 /* This is not in the Maemo UI spec:
2650 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2651 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2655 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2657 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2659 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2661 modest_server_account_set_username (
2662 modest_runtime_get_account_mgr(), server_account_name,
2665 const gboolean username_was_changed =
2666 (strcmp (*username, initial_username) != 0);
2667 if (username_was_changed) {
2668 g_warning ("%s: tinymail does not yet support changing the "
2669 "username in the get_password() callback.\n", __FUNCTION__);
2674 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2676 /* We do not save the password in the configuration,
2677 * because this function is only called for passwords that should
2678 * not be remembered:
2679 modest_server_account_set_password (
2680 modest_runtime_get_account_mgr(), server_account_name,
2689 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2701 /* This is not in the Maemo UI spec:
2702 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2708 gtk_widget_destroy (dialog);
2710 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2714 modest_ui_actions_on_cut (GtkAction *action,
2715 ModestWindow *window)
2717 GtkWidget *focused_widget;
2718 GtkClipboard *clipboard;
2720 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2721 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2722 if (GTK_IS_EDITABLE (focused_widget)) {
2723 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2724 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2725 gtk_clipboard_store (clipboard);
2726 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2727 GtkTextBuffer *buffer;
2729 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2730 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2731 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2732 gtk_clipboard_store (clipboard);
2733 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2734 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2735 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2736 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2741 modest_ui_actions_on_copy (GtkAction *action,
2742 ModestWindow *window)
2744 GtkClipboard *clipboard;
2745 GtkWidget *focused_widget;
2747 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2748 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2750 if (GTK_IS_LABEL (focused_widget)) {
2751 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2752 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2753 gtk_clipboard_store (clipboard);
2754 } else if (GTK_IS_EDITABLE (focused_widget)) {
2755 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2756 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2757 gtk_clipboard_store (clipboard);
2758 } else if (GTK_IS_HTML (focused_widget)) {
2759 gtk_html_copy (GTK_HTML (focused_widget));
2760 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2761 gtk_clipboard_store (clipboard);
2762 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2763 GtkTextBuffer *buffer;
2764 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2765 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2766 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2767 gtk_clipboard_store (clipboard);
2768 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2769 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2770 TnyIterator *iter = tny_list_create_iterator (header_list);
2771 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2773 gboolean ask = FALSE;
2775 TnyFolder *folder = tny_header_get_folder (header);
2776 TnyAccount *account = tny_folder_get_account (folder);
2777 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2778 /* If it's POP then ask */
2779 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2780 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2781 g_object_unref (account);
2782 g_object_unref (folder);
2783 g_object_unref (header);
2786 g_object_unref (iter);
2788 /* Check that the messages have been previously downloaded */
2789 gboolean continue_download = TRUE;
2791 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2792 if (continue_download)
2793 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2794 g_object_unref (header_list);
2795 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2796 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2799 /* Show information banner */
2800 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2805 modest_ui_actions_on_undo (GtkAction *action,
2806 ModestWindow *window)
2808 ModestEmailClipboard *clipboard = NULL;
2810 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2811 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2812 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2813 /* Clear clipboard source */
2814 clipboard = modest_runtime_get_email_clipboard ();
2815 modest_email_clipboard_clear (clipboard);
2818 g_return_if_reached ();
2823 modest_ui_actions_on_redo (GtkAction *action,
2824 ModestWindow *window)
2826 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2827 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2830 g_return_if_reached ();
2836 paste_msgs_cb (const GObject *object, gpointer user_data)
2838 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2839 g_return_if_fail (GTK_IS_WIDGET (user_data));
2841 /* destroy information note */
2842 gtk_widget_destroy (GTK_WIDGET(user_data));
2846 paste_as_attachment_free (gpointer data)
2848 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2850 gtk_widget_destroy (helper->banner);
2851 g_object_unref (helper->banner);
2856 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2861 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2862 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2867 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2872 modest_ui_actions_on_paste (GtkAction *action,
2873 ModestWindow *window)
2875 GtkWidget *focused_widget = NULL;
2876 GtkWidget *inf_note = NULL;
2877 ModestMailOperation *mail_op = NULL;
2879 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2880 if (GTK_IS_EDITABLE (focused_widget)) {
2881 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2882 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2883 ModestEmailClipboard *e_clipboard = NULL;
2884 e_clipboard = modest_runtime_get_email_clipboard ();
2885 if (modest_email_clipboard_cleared (e_clipboard)) {
2886 GtkTextBuffer *buffer;
2887 GtkClipboard *clipboard;
2889 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2890 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2891 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2892 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2893 ModestMailOperation *mail_op;
2894 TnyFolder *src_folder;
2897 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2898 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2899 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2900 _CS("ckct_nw_pasting"));
2901 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2902 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2904 if (helper->banner != NULL) {
2905 g_object_ref (G_OBJECT (helper->banner));
2906 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2907 gtk_widget_show (GTK_WIDGET (helper->banner));
2911 modest_mail_operation_get_msgs_full (mail_op,
2913 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2915 paste_as_attachment_free);
2918 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2919 ModestEmailClipboard *clipboard = NULL;
2920 TnyFolder *src_folder = NULL;
2921 TnyFolderStore *folder_store = NULL;
2922 TnyList *data = NULL;
2923 gboolean delete = FALSE;
2925 /* Check clipboard source */
2926 clipboard = modest_runtime_get_email_clipboard ();
2927 if (modest_email_clipboard_cleared (clipboard))
2930 /* Get elements to paste */
2931 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2933 /* Create a new mail operation */
2934 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2935 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2938 /* Get destination folder */
2939 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2941 /* Launch notification */
2942 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2943 _CS("ckct_nw_pasting"));
2944 if (inf_note != NULL) {
2945 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2946 gtk_widget_show (GTK_WIDGET(inf_note));
2949 /* transfer messages */
2951 modest_mail_operation_xfer_msgs (mail_op,
2953 TNY_FOLDER (folder_store),
2958 } else if (src_folder != NULL) {
2959 modest_mail_operation_xfer_folder (mail_op,
2969 g_object_unref (data);
2970 if (src_folder != NULL)
2971 g_object_unref (src_folder);
2972 if (folder_store != NULL)
2973 g_object_unref (folder_store);
2979 modest_ui_actions_on_select_all (GtkAction *action,
2980 ModestWindow *window)
2982 GtkWidget *focused_widget;
2984 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2985 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2986 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2987 } else if (GTK_IS_LABEL (focused_widget)) {
2988 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2989 } else if (GTK_IS_EDITABLE (focused_widget)) {
2990 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2991 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2992 GtkTextBuffer *buffer;
2993 GtkTextIter start, end;
2995 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2996 gtk_text_buffer_get_start_iter (buffer, &start);
2997 gtk_text_buffer_get_end_iter (buffer, &end);
2998 gtk_text_buffer_select_range (buffer, &start, &end);
2999 } else if (GTK_IS_HTML (focused_widget)) {
3000 gtk_html_select_all (GTK_HTML (focused_widget));
3001 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3002 GtkWidget *header_view = focused_widget;
3003 GtkTreeSelection *selection = NULL;
3005 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3006 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3007 MODEST_WIDGET_TYPE_HEADER_VIEW);
3009 /* Select all messages */
3010 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3011 gtk_tree_selection_select_all (selection);
3013 /* Set focuse on header view */
3014 gtk_widget_grab_focus (header_view);
3020 modest_ui_actions_on_mark_as_read (GtkAction *action,
3021 ModestWindow *window)
3023 g_return_if_fail (MODEST_IS_WINDOW(window));
3025 /* Mark each header as read */
3026 do_headers_action (window, headers_action_mark_as_read, NULL);
3030 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3031 ModestWindow *window)
3033 g_return_if_fail (MODEST_IS_WINDOW(window));
3035 /* Mark each header as read */
3036 do_headers_action (window, headers_action_mark_as_unread, NULL);
3040 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3041 GtkRadioAction *selected,
3042 ModestWindow *window)
3046 value = gtk_radio_action_get_current_value (selected);
3047 if (MODEST_IS_WINDOW (window)) {
3048 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3052 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3053 GtkRadioAction *selected,
3054 ModestWindow *window)
3056 TnyHeaderFlags flags;
3057 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3059 flags = gtk_radio_action_get_current_value (selected);
3060 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3063 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3064 GtkRadioAction *selected,
3065 ModestWindow *window)
3069 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3071 file_format = gtk_radio_action_get_current_value (selected);
3072 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3077 modest_ui_actions_on_zoom_plus (GtkAction *action,
3078 ModestWindow *window)
3080 g_return_if_fail (MODEST_IS_WINDOW (window));
3082 modest_window_zoom_plus (MODEST_WINDOW (window));
3086 modest_ui_actions_on_zoom_minus (GtkAction *action,
3087 ModestWindow *window)
3089 g_return_if_fail (MODEST_IS_WINDOW (window));
3091 modest_window_zoom_minus (MODEST_WINDOW (window));
3095 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3096 ModestWindow *window)
3098 ModestWindowMgr *mgr;
3099 gboolean fullscreen, active;
3100 g_return_if_fail (MODEST_IS_WINDOW (window));
3102 mgr = modest_runtime_get_window_mgr ();
3104 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3105 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3107 if (active != fullscreen) {
3108 modest_window_mgr_set_fullscreen_mode (mgr, active);
3109 gtk_window_present (GTK_WINDOW (window));
3114 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3115 ModestWindow *window)
3117 ModestWindowMgr *mgr;
3118 gboolean fullscreen;
3120 g_return_if_fail (MODEST_IS_WINDOW (window));
3122 mgr = modest_runtime_get_window_mgr ();
3123 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3124 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3126 gtk_window_present (GTK_WINDOW (window));
3130 * Used by modest_ui_actions_on_details to call do_headers_action
3133 headers_action_show_details (TnyHeader *header,
3134 ModestWindow *window,
3141 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3144 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3145 gtk_widget_show_all (dialog);
3146 gtk_dialog_run (GTK_DIALOG (dialog));
3148 gtk_widget_destroy (dialog);
3152 * Show the folder details in a ModestDetailsDialog widget
3155 show_folder_details (TnyFolder *folder,
3161 dialog = modest_details_dialog_new_with_folder (window, folder);
3164 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3165 gtk_widget_show_all (dialog);
3166 gtk_dialog_run (GTK_DIALOG (dialog));
3168 gtk_widget_destroy (dialog);
3172 * Show the header details in a ModestDetailsDialog widget
3175 modest_ui_actions_on_details (GtkAction *action,
3178 TnyList * headers_list;
3182 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3185 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3188 g_object_unref (msg);
3190 headers_list = get_selected_headers (win);
3194 iter = tny_list_create_iterator (headers_list);
3196 header = TNY_HEADER (tny_iterator_get_current (iter));
3198 headers_action_show_details (header, win, NULL);
3199 g_object_unref (header);
3202 g_object_unref (iter);
3203 g_object_unref (headers_list);
3205 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3206 GtkWidget *folder_view, *header_view;
3208 /* Check which widget has the focus */
3209 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3210 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3211 if (gtk_widget_is_focus (folder_view)) {
3212 TnyFolderStore *folder_store
3213 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3214 if (!folder_store) {
3215 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3218 /* Show only when it's a folder */
3219 /* This function should not be called for account items,
3220 * because we dim the menu item for them. */
3221 if (TNY_IS_FOLDER (folder_store)) {
3222 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3225 g_object_unref (folder_store);
3228 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3229 MODEST_WIDGET_TYPE_HEADER_VIEW);
3230 /* Show details of each header */
3231 do_headers_action (win, headers_action_show_details, header_view);
3237 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3238 ModestMsgEditWindow *window)
3240 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3242 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3246 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3247 ModestMsgEditWindow *window)
3249 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3251 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3255 modest_ui_actions_toggle_folders_view (GtkAction *action,
3256 ModestMainWindow *main_window)
3258 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3260 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3261 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3263 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3267 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3268 ModestWindow *window)
3270 gboolean active, fullscreen = FALSE;
3271 ModestWindowMgr *mgr;
3273 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3275 /* Check if we want to toggle the toolbar vuew in fullscreen
3277 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3278 "ViewShowToolbarFullScreen")) {
3282 /* Toggle toolbar */
3283 mgr = modest_runtime_get_window_mgr ();
3284 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3288 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3289 ModestMsgEditWindow *window)
3291 modest_msg_edit_window_select_font (window);
3295 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3296 const gchar *display_name,
3299 /* Do not change the application name if the widget has not
3300 the focus. This callback could be called even if the folder
3301 view has not the focus, because the handled signal could be
3302 emitted when the folder view is redrawn */
3303 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3305 gtk_window_set_title (window, display_name);
3307 gtk_window_set_title (window, " ");
3312 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3314 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3315 modest_msg_edit_window_select_contacts (window);
3319 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3321 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3322 modest_msg_edit_window_check_names (window, FALSE);
3326 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3328 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3329 GTK_WIDGET (user_data));
3333 create_move_to_dialog (GtkWindow *win,
3334 GtkWidget *folder_view,
3335 GtkWidget **tree_view)
3337 GtkWidget *dialog, *scroll;
3338 GtkWidget *new_button;
3340 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3342 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3345 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3346 /* We do this manually so GTK+ does not associate a response ID for
3348 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3349 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3350 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3352 /* Create scrolled window */
3353 scroll = gtk_scrolled_window_new (NULL, NULL);
3354 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3355 GTK_POLICY_AUTOMATIC,
3356 GTK_POLICY_AUTOMATIC);
3358 /* Create folder view */
3359 *tree_view = modest_platform_create_folder_view (NULL);
3361 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3363 /* It could happen that we're trying to move a message from a
3364 window (msg window for example) after the main window was
3365 closed, so we can not just get the model of the folder
3367 if (MODEST_IS_FOLDER_VIEW (folder_view))
3368 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3369 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3371 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3372 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3374 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3376 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3378 /* Add scroll to dialog */
3379 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3380 scroll, TRUE, TRUE, 0);
3382 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3383 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3389 * Returns TRUE if at least one of the headers of the list belongs to
3390 * a message that has been fully retrieved.
3393 has_retrieved_msgs (TnyList *list)
3396 gboolean found = FALSE;
3398 iter = tny_list_create_iterator (list);
3399 while (tny_iterator_is_done (iter) && !found) {
3401 TnyHeaderFlags flags = 0;
3403 header = TNY_HEADER (tny_iterator_get_current (iter));
3405 flags = tny_header_get_flags (header);
3406 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
3409 g_object_unref (header);
3413 tny_iterator_next (iter);
3415 g_object_unref (iter);
3421 * Shows a confirmation dialog to the user when we're moving messages
3422 * from a remote server to the local storage. Returns the dialog
3423 * response. If it's other kind of movement the it always returns
3427 msgs_move_to_confirmation (GtkWindow *win,
3428 TnyFolder *dest_folder,
3431 gint response = GTK_RESPONSE_OK;
3433 /* If the destination is a local folder */
3434 if (modest_tny_folder_is_local_folder (dest_folder)) {
3435 TnyFolder *src_folder = NULL;
3436 TnyIterator *iter = NULL;
3437 TnyHeader *header = NULL;
3439 /* Get source folder */
3440 iter = tny_list_create_iterator (headers);
3441 header = TNY_HEADER (tny_iterator_get_current (iter));
3443 src_folder = tny_header_get_folder (header);
3444 g_object_unref (header);
3447 g_object_unref (iter);
3449 /* if no src_folder, message may be an attahcment */
3450 if (src_folder == NULL)
3451 return GTK_RESPONSE_CANCEL;
3453 /* If the source is a remote folder */
3454 if (!modest_tny_folder_is_local_folder (src_folder)) {
3455 const gchar *message;
3457 if (has_retrieved_msgs (headers))
3458 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3459 tny_list_get_length (headers));
3461 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3462 tny_list_get_length (headers));
3464 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3465 (const gchar *) message);
3468 g_object_unref (src_folder);
3477 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3479 ModestMsgViewWindow *self = NULL;
3481 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3482 self = MODEST_MSG_VIEW_WINDOW (object);
3484 if (!modest_msg_view_window_select_next_message (self))
3485 if (!modest_msg_view_window_select_previous_message (self))
3486 /* No more messages to view, so close this window */
3487 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3491 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3494 GObject *win = modest_mail_operation_get_source (mail_op);
3495 const GError *error = NULL;
3496 const gchar *message = NULL;
3498 /* Get error message */
3499 error = modest_mail_operation_get_error (mail_op);
3500 if (error != NULL && error->message != NULL) {
3501 message = error->message;
3503 message = _("mail_in_ui_folder_move_target_error");
3506 /* Show notification dialog */
3507 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3508 g_object_unref (win);
3512 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3515 GObject *win = modest_mail_operation_get_source (mail_op);
3516 const GError *error = modest_mail_operation_get_error (mail_op);
3518 g_return_if_fail (error != NULL);
3519 if (error->message != NULL)
3520 g_printerr ("modest: %s\n", error->message);
3522 g_printerr ("modest: unkonw error on send&receive operation");
3524 /* Show error message */
3525 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3526 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3527 /* _CS("sfil_ib_unable_to_receive")); */
3529 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3530 /* _CS("sfil_ib_unable_to_send")); */
3531 g_object_unref (win);
3535 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3542 gint pending_purges = 0;
3543 gboolean some_purged = FALSE;
3544 ModestWindow *win = MODEST_WINDOW (user_data);
3545 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3547 /* If there was any error */
3548 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3549 modest_window_mgr_unregister_header (mgr, header);
3553 /* Once the message has been retrieved for purging, we check if
3554 * it's all ok for purging */
3556 parts = tny_simple_list_new ();
3557 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3558 iter = tny_list_create_iterator (parts);
3560 while (!tny_iterator_is_done (iter)) {
3562 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3563 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3564 if (tny_mime_part_is_purged (part))
3571 g_object_unref (part);
3573 tny_iterator_next (iter);
3576 if (pending_purges>0) {
3578 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3580 if (response == GTK_RESPONSE_OK) {
3581 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3582 tny_iterator_first (iter);
3583 while (!tny_iterator_is_done (iter)) {
3586 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3587 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3588 tny_mime_part_set_purged (part);
3591 g_object_unref (part);
3593 tny_iterator_next (iter);
3596 tny_msg_rewrite_cache (msg);
3599 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3602 /* remove attachments */
3603 tny_iterator_first (iter);
3604 while (!tny_iterator_is_done (iter)) {
3607 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3609 /* One for the reference given by tny_iterator_get_current(): */
3610 g_object_unref (part);
3612 /* TODO: Is this meant to remove the attachment by doing another unref()?
3613 * Otherwise, this seems useless. */
3616 tny_iterator_next (iter);
3618 modest_window_mgr_unregister_header (mgr, header);
3620 g_object_unref (iter);
3621 g_object_unref (parts);
3625 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3626 ModestMainWindow *win)
3628 GtkWidget *header_view;
3629 TnyList *header_list;
3632 TnyHeaderFlags flags;
3633 ModestWindow *msg_view_window = NULL;
3636 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3638 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3639 MODEST_WIDGET_TYPE_HEADER_VIEW);
3641 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3643 if (tny_list_get_length (header_list) == 1) {
3644 iter = tny_list_create_iterator (header_list);
3645 header = TNY_HEADER (tny_iterator_get_current (iter));
3646 g_object_unref (iter);
3651 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3652 header, &msg_view_window);
3653 flags = tny_header_get_flags (header);
3654 if (!(flags & TNY_HEADER_FLAG_CACHED))
3657 if (msg_view_window != NULL)
3658 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3660 /* do nothing; uid was registered before, so window is probably on it's way */
3661 g_warning ("debug: header %p has already been registered", header);
3664 ModestMailOperation *mail_op = NULL;
3665 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3666 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3668 modest_ui_actions_get_msgs_full_error_handler,
3670 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3671 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3673 g_object_unref (mail_op);
3676 g_object_unref (header);
3678 g_object_unref (header_list);
3682 * Utility function that transfer messages from both the main window
3683 * and the msg view window when using the "Move to" dialog
3686 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3689 TnyList *headers = NULL;
3691 TnyAccount *dst_account = NULL;
3692 const gchar *proto_str = NULL;
3693 gboolean dst_is_pop = FALSE;
3695 if (!TNY_IS_FOLDER (dst_folder)) {
3696 modest_platform_information_banner (GTK_WIDGET (win),
3698 _CS("ckdg_ib_unable_to_move_to_current_location"));
3702 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3703 proto_str = tny_account_get_proto (dst_account);
3704 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3705 MODEST_PROTOCOL_STORE_POP);
3706 g_object_unref (dst_account);
3708 /* Get selected headers */
3709 headers = get_selected_headers (MODEST_WINDOW (win));
3712 modest_platform_information_banner (GTK_WIDGET (win),
3714 ngettext("mail_in_ui_folder_move_target_error",
3715 "mail_in_ui_folder_move_targets_error",
3716 tny_list_get_length (headers)));
3717 g_object_unref (headers);
3721 /* Ask for user confirmation */
3722 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3723 TNY_FOLDER (dst_folder),
3726 /* Transfer messages */
3727 if (response == GTK_RESPONSE_OK) {
3728 ModestMailOperation *mail_op =
3729 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3731 modest_ui_actions_move_folder_error_handler,
3733 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3736 modest_mail_operation_xfer_msgs (mail_op,
3738 TNY_FOLDER (dst_folder),
3740 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3743 g_object_unref (G_OBJECT (mail_op));
3745 g_object_unref (headers);
3750 * UI handler for the "Move to" action when invoked from the
3754 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3755 GtkWidget *folder_view,
3756 TnyFolderStore *dst_folder,
3757 ModestMainWindow *win)
3759 GtkWidget *header_view = NULL;
3760 ModestMailOperation *mail_op = NULL;
3761 TnyFolderStore *src_folder;
3763 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3765 /* Get the source folder */
3766 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3768 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3769 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3773 /* Get header view */
3775 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3777 /* Get folder or messages to transfer */
3778 if (gtk_widget_is_focus (folder_view)) {
3780 /* Allow only to transfer folders to the local root folder */
3781 if (TNY_IS_ACCOUNT (dst_folder) &&
3782 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3785 /* Clean folder on header view before moving it */
3786 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3788 if (TNY_IS_FOLDER (src_folder)) {
3790 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3792 modest_ui_actions_move_folder_error_handler,
3794 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3797 modest_mail_operation_xfer_folder (mail_op,
3798 TNY_FOLDER (src_folder),
3801 /* Unref mail operation */
3802 g_object_unref (G_OBJECT (mail_op));
3804 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3806 } else if (gtk_widget_is_focus (header_view)) {
3807 /* Transfer messages */
3808 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3813 g_object_unref (src_folder);
3818 * UI handler for the "Move to" action when invoked from the
3819 * ModestMsgViewWindow
3822 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3823 TnyFolderStore *dst_folder,
3824 ModestMsgViewWindow *win)
3826 TnyHeader *header = NULL;
3827 TnyFolder *src_folder;
3829 /* Create header list */
3830 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3831 src_folder = tny_header_get_folder(header);
3832 g_object_unref (header);
3834 /* Transfer the message */
3835 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3836 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3838 g_object_unref (src_folder);
3842 modest_ui_actions_on_move_to (GtkAction *action,
3845 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3847 TnyFolderStore *dst_folder = NULL;
3848 ModestMainWindow *main_window;
3850 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3851 MODEST_IS_MSG_VIEW_WINDOW (win));
3853 /* Get the main window if exists */
3854 if (MODEST_IS_MAIN_WINDOW (win))
3855 main_window = MODEST_MAIN_WINDOW (win);
3858 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3860 /* Get the folder view widget if exists */
3862 folder_view = modest_main_window_get_child_widget (main_window,
3863 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3867 /* Create and run the dialog */
3868 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3869 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3870 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3871 result = gtk_dialog_run (GTK_DIALOG(dialog));
3872 g_object_ref (tree_view);
3873 gtk_widget_destroy (dialog);
3875 if (result != GTK_RESPONSE_ACCEPT)
3878 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3879 /* Offer the connection dialog if necessary: */
3880 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3883 /* Do window specific stuff */
3884 if (MODEST_IS_MAIN_WINDOW (win))
3885 modest_ui_actions_on_main_window_move_to (action,
3888 MODEST_MAIN_WINDOW (win));
3890 modest_ui_actions_on_msg_view_window_move_to (action,
3892 MODEST_MSG_VIEW_WINDOW (win));
3895 g_object_unref (dst_folder);
3899 * Calls #HeadersFunc for each header already selected in the main
3900 * window or the message currently being shown in the msg view window
3903 do_headers_action (ModestWindow *win,
3907 TnyList *headers_list = NULL;
3908 TnyIterator *iter = NULL;
3909 TnyHeader *header = NULL;
3910 TnyFolder *folder = NULL;
3913 headers_list = get_selected_headers (win);
3917 /* Get the folder */
3918 iter = tny_list_create_iterator (headers_list);
3919 header = TNY_HEADER (tny_iterator_get_current (iter));
3921 folder = tny_header_get_folder (header);
3922 g_object_unref (header);
3925 /* Call the function for each header */
3926 while (!tny_iterator_is_done (iter)) {
3927 header = TNY_HEADER (tny_iterator_get_current (iter));
3928 func (header, win, user_data);
3929 g_object_unref (header);
3930 tny_iterator_next (iter);
3933 /* Trick: do a poke status in order to speed up the signaling
3935 tny_folder_poke_status (folder);
3938 g_object_unref (folder);
3939 g_object_unref (iter);
3940 g_object_unref (headers_list);
3944 modest_ui_actions_view_attachment (GtkAction *action,
3945 ModestWindow *window)
3947 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3948 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3950 /* not supported window for this action */
3951 g_return_if_reached ();
3956 modest_ui_actions_save_attachments (GtkAction *action,
3957 ModestWindow *window)
3959 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3960 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3962 /* not supported window for this action */
3963 g_return_if_reached ();
3968 modest_ui_actions_remove_attachments (GtkAction *action,
3969 ModestWindow *window)
3971 if (MODEST_IS_MAIN_WINDOW (window)) {
3972 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3973 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3974 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3976 /* not supported window for this action */
3977 g_return_if_reached ();
3982 modest_ui_actions_on_settings (GtkAction *action,
3987 dialog = modest_platform_get_global_settings_dialog ();
3988 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3989 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3990 gtk_widget_show_all (dialog);
3992 gtk_dialog_run (GTK_DIALOG (dialog));
3994 gtk_widget_destroy (dialog);
3998 modest_ui_actions_on_help (GtkAction *action,
4001 const gchar *help_id = NULL;
4003 if (MODEST_IS_MAIN_WINDOW (win)) {
4004 const gchar *action_name;
4005 action_name = gtk_action_get_name (action);
4007 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4008 !strcmp (action_name, "HeaderViewCSMHelp")) {
4009 GtkWidget *folder_view;
4010 TnyFolderStore *folder_store;
4011 /* Get selected folder */
4012 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4013 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4014 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4016 /* Switch help_id */
4017 if (TNY_IS_FOLDER (folder_store)) {
4018 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4019 case TNY_FOLDER_TYPE_NORMAL:
4020 help_id = "applications_email_managefolders";
4022 case TNY_FOLDER_TYPE_INBOX:
4023 help_id = "applications_email_inbox";
4025 case TNY_FOLDER_TYPE_OUTBOX:
4026 help_id = "applications_email_outbox";
4028 case TNY_FOLDER_TYPE_SENT:
4029 help_id = "applications_email_sent";
4031 case TNY_FOLDER_TYPE_DRAFTS:
4032 help_id = "applications_email_drafts";
4034 case TNY_FOLDER_TYPE_ARCHIVE:
4035 help_id = "applications_email_managefolders";
4038 help_id = "applications_email_managefolders";
4041 help_id = "applications_email_mainview";
4043 g_object_unref (folder_store);
4045 help_id = "applications_email_mainview";
4047 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4048 help_id = "applications_email_viewer";
4049 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4050 help_id = "applications_email_editor";
4052 modest_platform_show_help (GTK_WINDOW (win), help_id);
4056 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4057 ModestWindow *window)
4059 ModestMailOperation *mail_op;
4063 headers = get_selected_headers (window);
4067 /* Create mail operation */
4068 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4070 modest_ui_actions_get_msgs_full_error_handler,
4072 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4073 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4076 g_object_unref (headers);
4077 g_object_unref (mail_op);
4081 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4082 ModestWindow *window)
4084 g_return_if_fail (MODEST_IS_WINDOW (window));
4086 /* Init dimming rules init data */
4089 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4091 /* Free dimming ruls init data */
4095 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4096 ModestWindow *window)
4098 g_return_if_fail (MODEST_IS_WINDOW (window));
4101 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4105 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4106 ModestWindow *window)
4108 g_return_if_fail (MODEST_IS_WINDOW (window));
4111 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4115 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4116 ModestWindow *window)
4118 g_return_if_fail (MODEST_IS_WINDOW (window));
4121 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4125 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4126 ModestWindow *window)
4128 g_return_if_fail (MODEST_IS_WINDOW (window));
4131 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4135 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4136 ModestWindow *window)
4138 g_return_if_fail (MODEST_IS_WINDOW (window));
4141 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4145 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4146 ModestWindow *window)
4148 g_return_if_fail (MODEST_IS_WINDOW (window));
4151 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4155 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4156 ModestWindow *window)
4158 g_return_if_fail (MODEST_IS_WINDOW (window));
4161 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4165 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4167 g_return_if_fail (MODEST_IS_WINDOW (window));
4170 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4174 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4176 g_return_if_fail (MODEST_IS_WINDOW (window));
4178 modest_platform_show_search_messages (GTK_WINDOW (window));
4182 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4184 g_return_if_fail (MODEST_IS_WINDOW (win));
4185 modest_platform_show_addressbook (GTK_WINDOW (win));
4190 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4191 ModestWindow *window)
4193 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4195 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4199 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4200 ModestMailOperationState *state,
4203 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4205 /* Set send/receive operation finished */
4206 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4207 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));