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 _MoveToHelper {
107 GtkTreeRowReference *reference;
111 typedef struct _PasteAsAttachmentHelper {
112 ModestMsgEditWindow *window;
114 } PasteAsAttachmentHelper;
118 * The do_headers_action uses this kind of functions to perform some
119 * action to each member of a list of headers
121 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
123 static void do_headers_action (ModestWindow *win,
127 static void open_msg_cb (ModestMailOperation *mail_op,
132 static void reply_forward_cb (ModestMailOperation *mail_op,
137 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
139 static void folder_refreshed_cb (ModestMailOperation *mail_op,
143 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
144 ModestMailOperationState *state,
147 static gint header_list_count_uncached_msgs (TnyList *header_list);
148 static gboolean connect_to_get_msg (
150 gint num_of_uncached_msgs);
152 static gboolean remote_folder_is_pop (const TnyFolderStore *folder);
154 static gboolean msgs_already_deleted_from_server ( TnyList *headers,
155 const TnyFolderStore *src_folder);
159 * This function checks whether a TnyFolderStore is a pop account
162 remote_folder_is_pop (const TnyFolderStore *folder)
164 const gchar *proto = NULL;
165 TnyAccount *account = NULL;
167 g_return_val_if_fail (TNY_IS_FOLDER_STORE(folder), FALSE);
169 if (TNY_IS_ACCOUNT (folder)) {
170 account = TNY_ACCOUNT(folder);
171 g_object_ref(account);
172 } else if (TNY_IS_FOLDER (folder)) {
173 account = tny_folder_get_account(TNY_FOLDER(folder));
176 proto = tny_account_get_proto(account);
177 g_object_unref (account);
180 (modest_protocol_info_get_transport_store_protocol (proto) == MODEST_PROTOCOL_STORE_POP);
184 * This functions checks whether if a list of messages are already
185 * deleted from the server: that is, if the server is a POP account
186 * and all messages are already cached.
189 msgs_already_deleted_from_server (TnyList *headers, const TnyFolderStore *src_folder)
191 g_return_val_if_fail (TNY_IS_FOLDER_STORE(src_folder), FALSE);
192 g_return_val_if_fail (TNY_IS_LIST(headers), FALSE);
194 gboolean src_is_pop = remote_folder_is_pop (src_folder);
195 gint uncached_msgs = header_list_count_uncached_msgs (headers);
197 return (src_is_pop && !uncached_msgs);
201 /* FIXME: this should be merged with the similar code in modest-account-view-window */
202 /* Show the account creation wizard dialog.
203 * returns: TRUE if an account was created. FALSE if the user cancelled.
206 modest_run_account_setup_wizard (ModestWindow *win)
208 gboolean result = FALSE;
209 GtkDialog *wizard, *dialog;
211 /* Show the easy-setup wizard: */
212 dialog = modest_window_mgr_get_modal_dialog (modest_runtime_get_window_mgr());
213 if (dialog && MODEST_IS_EASYSETUP_WIZARD_DIALOG(dialog)) {
214 /* old wizard is active already;
216 gtk_window_present (GTK_WINDOW(dialog));
221 /* there is no such wizard yet */
223 wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
225 g_printerr ("modest: failed to create easysetup wizard\n");
229 modest_window_mgr_set_modal_dialog
230 (modest_runtime_get_window_mgr(), GTK_DIALOG(wizard));
233 /* there is no such wizard yet */
234 wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
235 modest_window_mgr_set_modal_dialog (modest_runtime_get_window_mgr(),
238 /* make it non-modal; if though we register it as a modal dialog above
239 * apparently, making it modal *at all* gives hangs -- FIXME: check this*/
240 gtk_window_set_modal (GTK_WINDOW(dialog), FALSE);
242 /* always present a main window in the background
243 * we do it here, so we cannot end up with to wizards (as this
244 * function might be called in modest_window_mgr_get_main_window as well */
246 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
248 /* make sure the mainwindow is visible */
249 gtk_widget_show_all (GTK_WIDGET(win));
250 gtk_window_present (GTK_WINDOW(win));
253 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
255 /* Don't make this a modal window, because secondary windows will then
256 * be unusable, freezing the UI: */
257 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
259 gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
260 if (dialog_response == GTK_RESPONSE_CANCEL)
263 /* Check whether an account was created: */
264 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
267 gtk_widget_destroy (GTK_WIDGET (wizard));
269 /* clear it from the window mgr */
270 modest_window_mgr_set_modal_dialog
271 (modest_runtime_get_window_mgr(), NULL);
278 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
281 const gchar *authors[] = {
282 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
285 about = gtk_about_dialog_new ();
286 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
287 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
288 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
289 _("Copyright (c) 2006, Nokia Corporation\n"
290 "All rights reserved."));
291 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
292 _("a modest e-mail client\n\n"
293 "design and implementation: Dirk-Jan C. Binnema\n"
294 "contributions from the fine people at KC and Ig\n"
295 "uses the tinymail email framework written by Philip van Hoof"));
296 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
297 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
298 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
299 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
301 gtk_dialog_run (GTK_DIALOG (about));
302 gtk_widget_destroy(about);
306 * Gets the list of currently selected messages. If the win is the
307 * main window, then it returns a newly allocated list of the headers
308 * selected in the header view. If win is the msg view window, then
309 * the value returned is a list with just a single header.
311 * The caller of this funcion must free the list.
314 get_selected_headers (ModestWindow *win)
316 if (MODEST_IS_MAIN_WINDOW(win)) {
317 GtkWidget *header_view;
319 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
320 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
321 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
323 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
324 /* for MsgViewWindows, we simply return a list with one element */
326 TnyList *list = NULL;
328 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
329 if (header != NULL) {
330 list = tny_simple_list_new ();
331 tny_list_prepend (list, G_OBJECT(header));
332 g_object_unref (G_OBJECT(header));
341 static GtkTreeRowReference *
342 get_next_after_selected_headers (ModestHeaderView *header_view)
344 GtkTreeSelection *sel;
345 GList *selected_rows, *node;
347 GtkTreeRowReference *result;
350 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
351 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
352 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
354 if (selected_rows == NULL)
357 node = g_list_last (selected_rows);
358 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
359 gtk_tree_path_next (path);
361 result = gtk_tree_row_reference_new (model, path);
363 gtk_tree_path_free (path);
364 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
365 g_list_free (selected_rows);
371 headers_action_mark_as_read (TnyHeader *header,
375 TnyHeaderFlags flags;
377 g_return_if_fail (TNY_IS_HEADER(header));
379 flags = tny_header_get_flags (header);
380 if (flags & TNY_HEADER_FLAG_SEEN) return;
381 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
385 headers_action_mark_as_unread (TnyHeader *header,
389 TnyHeaderFlags flags;
391 g_return_if_fail (TNY_IS_HEADER(header));
393 flags = tny_header_get_flags (header);
394 if (flags & TNY_HEADER_FLAG_SEEN) {
395 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
399 /** A convenience method, because deleting a message is
400 * otherwise complicated, and it's best to change it in one place
403 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
405 ModestMailOperation *mail_op = NULL;
406 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
407 win ? G_OBJECT(win) : NULL);
408 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
411 /* Always delete. TODO: Move to trash still not supported */
412 modest_mail_operation_remove_msg (mail_op, header, FALSE);
413 g_object_unref (G_OBJECT (mail_op));
416 /** A convenience method, because deleting a message is
417 * otherwise complicated, and it's best to change it in one place
420 void modest_do_messages_delete (TnyList *headers, ModestWindow *win)
422 ModestMailOperation *mail_op = NULL;
423 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
424 win ? G_OBJECT(win) : NULL);
425 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
428 /* Always delete. TODO: Move to trash still not supported */
429 modest_mail_operation_remove_msgs (mail_op, headers, FALSE);
430 g_object_unref (G_OBJECT (mail_op));
433 /** After deleing a message that is currently visible in a window,
434 * show the next message from the list, or close the window if there are no more messages.
437 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
439 /* Close msg view window or select next */
440 if (modest_msg_view_window_last_message_selected (win) &&
441 modest_msg_view_window_first_message_selected (win)) {
442 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
443 } else if (!modest_msg_view_window_select_next_message (win)) {
445 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
450 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
452 TnyList *header_list = NULL;
453 TnyIterator *iter = NULL;
454 TnyHeader *header = NULL;
455 gchar *message = NULL;
458 ModestWindowMgr *mgr;
459 GtkWidget *header_view = NULL;
461 g_return_if_fail (MODEST_IS_WINDOW(win));
463 /* Check first if the header view has the focus */
464 if (MODEST_IS_MAIN_WINDOW (win)) {
466 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
467 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
468 if (!gtk_widget_is_focus (header_view))
472 /* Get the headers, either from the header view (if win is the main window),
473 * or from the message view window: */
474 header_list = get_selected_headers (win);
475 if (!header_list) return;
477 /* Check if any of the headers are already opened, or in the process of being opened */
478 if (MODEST_IS_MAIN_WINDOW (win)) {
479 gint opened_headers = 0;
481 iter = tny_list_create_iterator (header_list);
482 mgr = modest_runtime_get_window_mgr ();
483 while (!tny_iterator_is_done (iter)) {
484 header = TNY_HEADER (tny_iterator_get_current (iter));
486 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
488 g_object_unref (header);
490 tny_iterator_next (iter);
492 g_object_unref (iter);
494 if (opened_headers > 0) {
497 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
500 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
503 g_object_unref (header_list);
509 if (tny_list_get_length(header_list) == 1) {
510 iter = tny_list_create_iterator (header_list);
511 header = TNY_HEADER (tny_iterator_get_current (iter));
513 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
514 g_object_unref (header);
517 g_object_unref (iter);
519 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
520 tny_list_get_length(header_list)), desc);
522 /* Confirmation dialog */
523 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
527 if (response == GTK_RESPONSE_OK) {
528 ModestWindow *main_window = NULL;
529 ModestWindowMgr *mgr = NULL;
530 GtkTreeModel *model = NULL;
531 GtkTreeSelection *sel = NULL;
532 GList *sel_list = NULL, *tmp = NULL;
533 GtkTreeRowReference *next_row_reference = NULL;
534 GtkTreeRowReference *prev_row_reference = NULL;
535 GtkTreePath *next_path = NULL;
536 GtkTreePath *prev_path = NULL;
539 /* Find last selected row */
540 if (MODEST_IS_MAIN_WINDOW (win)) {
541 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
542 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
543 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
544 for (tmp=sel_list; tmp; tmp=tmp->next) {
545 if (tmp->next == NULL) {
546 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
547 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
549 gtk_tree_path_prev (prev_path);
550 gtk_tree_path_next (next_path);
552 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
553 next_row_reference = gtk_tree_row_reference_new (model, next_path);
558 /* Disable window dimming management */
559 modest_window_disable_dimming (MODEST_WINDOW(win));
561 /* Remove each header. If it's a view window header_view == NULL */
562 modest_do_messages_delete (header_list, win);
564 /* Enable window dimming management */
566 gtk_tree_selection_unselect_all (sel);
568 modest_window_enable_dimming (MODEST_WINDOW(win));
570 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
571 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
573 /* Get main window */
574 mgr = modest_runtime_get_window_mgr ();
575 main_window = modest_window_mgr_get_main_window (mgr);
578 /* Move cursor to next row */
581 /* Select next or previous row */
582 if (gtk_tree_row_reference_valid (next_row_reference)) {
583 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
584 gtk_tree_selection_select_path (sel, next_path);
586 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
587 gtk_tree_selection_select_path (sel, prev_path);
591 if (next_row_reference != NULL)
592 gtk_tree_row_reference_free (next_row_reference);
593 if (next_path != NULL)
594 gtk_tree_path_free (next_path);
595 if (prev_row_reference != NULL)
596 gtk_tree_row_reference_free (prev_row_reference);
597 if (prev_path != NULL)
598 gtk_tree_path_free (prev_path);
602 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
606 /* Update toolbar dimming state */
607 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
610 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
611 g_list_free (sel_list);
617 g_object_unref (header_list);
623 /* delete either message or folder, based on where we are */
625 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
627 g_return_if_fail (MODEST_IS_WINDOW(win));
629 /* Check first if the header view has the focus */
630 if (MODEST_IS_MAIN_WINDOW (win)) {
632 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
633 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
634 if (gtk_widget_is_focus (w)) {
635 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
639 modest_ui_actions_on_delete_message (action, win);
645 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
647 ModestWindowMgr *mgr = NULL;
649 #ifdef MODEST_PLATFORM_MAEMO
650 modest_osso_save_state();
651 #endif /* MODEST_PLATFORM_MAEMO */
653 g_debug ("closing down, clearing %d item(s) from operation queue",
654 modest_mail_operation_queue_num_elements
655 (modest_runtime_get_mail_operation_queue()));
657 /* cancel all outstanding operations */
658 modest_mail_operation_queue_cancel_all
659 (modest_runtime_get_mail_operation_queue());
661 g_debug ("queue has been cleared");
664 /* Check if there are opened editing windows */
665 mgr = modest_runtime_get_window_mgr ();
666 modest_window_mgr_close_all_windows (mgr);
668 /* note: when modest-tny-account-store is finalized,
669 it will automatically set all network connections
672 /* gtk_main_quit (); */
676 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
680 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
682 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
683 /* gtk_widget_destroy (GTK_WIDGET (win)); */
684 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
685 /* gboolean ret_value; */
686 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
687 /* } else if (MODEST_IS_WINDOW (win)) { */
688 /* gtk_widget_destroy (GTK_WIDGET (win)); */
690 /* g_return_if_reached (); */
695 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
697 GtkClipboard *clipboard = NULL;
698 gchar *selection = NULL;
700 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
701 selection = gtk_clipboard_wait_for_text (clipboard);
703 /* Question: why is the clipboard being used here?
704 * It doesn't really make a lot of sense. */
708 modest_address_book_add_address (selection);
714 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
716 /* This is currently only implemented for Maemo */
717 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
718 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
719 modest_run_account_setup_wizard (win);
722 /* Show the list of accounts: */
723 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
724 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
726 /* The accounts dialog must be modal */
727 gtk_window_set_modal (GTK_WINDOW (account_win), TRUE);
728 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
731 GtkWidget *dialog, *label;
733 /* Create the widgets */
735 dialog = gtk_dialog_new_with_buttons ("Message",
737 GTK_DIALOG_DESTROY_WITH_PARENT,
741 label = gtk_label_new ("Hello World!");
743 /* Ensure that the dialog box is destroyed when the user responds. */
745 g_signal_connect_swapped (dialog, "response",
746 G_CALLBACK (gtk_widget_destroy),
749 /* Add the label, and show everything we've added to the dialog. */
751 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
753 gtk_widget_show_all (dialog);
754 #endif /* MODEST_PLATFORM_MAEMO */
758 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
760 /* Save any changes. */
761 modest_connection_specific_smtp_window_save_server_accounts (
762 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
763 gtk_widget_destroy (GTK_WIDGET (window));
769 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
771 /* This is currently only implemented for Maemo,
772 * because it requires an API (libconic) to detect different connection
775 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
777 /* Create the window if necessary: */
778 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
779 modest_connection_specific_smtp_window_fill_with_connections (
780 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
781 modest_runtime_get_account_mgr());
783 /* Show the window: */
784 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
785 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
786 gtk_widget_show (specific_window);
788 /* Save changes when the window is hidden: */
789 g_signal_connect (specific_window, "hide",
790 G_CALLBACK (on_smtp_servers_window_hide), win);
791 #endif /* MODEST_PLATFORM_MAEMO */
795 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
797 ModestWindow *msg_win = NULL;
799 TnyFolder *folder = NULL;
800 gchar *account_name = NULL;
801 gchar *from_str = NULL;
802 /* GError *err = NULL; */
803 TnyAccount *account = NULL;
804 ModestWindowMgr *mgr;
805 gchar *signature = NULL, *blank_and_signature = NULL;
807 /* if there are no accounts yet, just show the wizard */
808 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
809 const gboolean created = modest_run_account_setup_wizard (win);
814 account_name = g_strdup (modest_window_get_active_account (win));
816 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
818 g_printerr ("modest: no account found\n");
822 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
824 TNY_ACCOUNT_TYPE_STORE);
826 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
830 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
832 g_printerr ("modest: failed get from string for '%s'\n", account_name);
836 gboolean use_signature = FALSE;
837 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
840 blank_and_signature = g_strconcat ("\n", signature, NULL);
842 blank_and_signature = g_strdup ("");
847 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
849 g_printerr ("modest: failed to create new msg\n");
853 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
855 g_printerr ("modest: failed to find Drafts folder\n");
860 /* Create and register edit window */
861 /* This is destroyed by TODO. */
862 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
863 mgr = modest_runtime_get_window_mgr ();
864 modest_window_mgr_register_window (mgr, msg_win);
867 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
869 gtk_widget_show_all (GTK_WIDGET (msg_win));
872 g_free (account_name);
874 g_free (blank_and_signature);
876 g_object_unref (msg_win);
878 g_object_unref (G_OBJECT(account));
880 g_object_unref (G_OBJECT(msg));
882 g_object_unref (G_OBJECT(folder));
886 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
890 ModestMailOperationStatus status;
892 /* If there is no message or the operation was not successful */
893 status = modest_mail_operation_get_status (mail_op);
894 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
896 /* Remove the header from the preregistered uids */
897 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
907 open_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg, gpointer user_data)
909 ModestWindowMgr *mgr = NULL;
910 ModestWindow *parent_win = NULL;
911 ModestWindow *win = NULL;
912 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
913 gchar *account = NULL;
916 /* Do nothing if there was any problem with the mail
917 operation. The error will be shown by the error_handler of
918 the mail operation */
919 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
922 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
923 folder = tny_header_get_folder (header);
925 /* Mark header as read */
926 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
929 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
931 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
933 /* Gets folder type (OUTBOX headers will be opened in edit window */
934 if (modest_tny_folder_is_local_folder (folder))
935 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
937 /* If the header is in the drafts folder then open the editor,
938 else the message view window */
939 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
940 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
941 /* we cannot edit without a valid account... */
942 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
943 const gboolean created = modest_run_account_setup_wizard(parent_win);
947 win = modest_msg_edit_window_new (msg, account, TRUE);
951 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
954 gchar *uid = modest_tny_folder_get_header_unique_id (header);
956 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
957 GtkWidget *header_view;
958 GtkTreeSelection *sel;
959 GList *sel_list = NULL;
962 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
963 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
965 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
966 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
968 if (sel_list != NULL) {
969 GtkTreeRowReference *row_reference;
971 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
972 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
973 g_list_free (sel_list);
975 win = modest_msg_view_window_new_with_header_model (
976 msg, account, (const gchar*) uid,
977 model, row_reference);
978 gtk_tree_row_reference_free (row_reference);
980 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
983 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
988 /* Register and show new window */
990 mgr = modest_runtime_get_window_mgr ();
991 modest_window_mgr_register_window (mgr, win);
992 g_object_unref (win);
993 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
994 gtk_widget_show_all (GTK_WIDGET(win));
997 /* Update toolbar dimming state */
998 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
999 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1005 g_object_unref (parent_win);
1006 g_object_unref (folder);
1010 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
1013 const GError *error;
1014 GObject *win = modest_mail_operation_get_source (mail_op);
1016 error = modest_mail_operation_get_error (mail_op);
1017 /* printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message); */
1019 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
1021 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1024 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1025 _("mail_ni_ui_folder_get_msg_folder_error"));
1029 g_object_unref (win);
1033 * This function is used by both modest_ui_actions_on_open and
1034 * modest_ui_actions_on_header_activated. This way we always do the
1035 * same when trying to open messages.
1038 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
1040 ModestWindowMgr *mgr = NULL;
1041 TnyIterator *iter = NULL;
1042 ModestMailOperation *mail_op = NULL;
1043 TnyList *not_opened_headers = NULL;
1044 TnyHeaderFlags flags = 0;
1046 g_return_if_fail (headers != NULL);
1048 /* Check that only one message is selected for opening */
1049 if (tny_list_get_length (headers) != 1) {
1050 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1051 _("mcen_ib_select_one_message"));
1056 /* Look if we already have a message view for each header. If
1057 true, then remove the header from the list of headers to
1059 mgr = modest_runtime_get_window_mgr ();
1060 iter = tny_list_create_iterator (headers);
1061 not_opened_headers = tny_simple_list_new ();
1063 while (!tny_iterator_is_done (iter)) {
1065 ModestWindow *window = NULL;
1066 TnyHeader *header = NULL;
1067 gboolean found = FALSE;
1069 header = TNY_HEADER (tny_iterator_get_current (iter));
1071 flags = tny_header_get_flags (header);
1074 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1076 /* Do not open again the message and present the
1077 window to the user */
1080 gtk_window_present (GTK_WINDOW (window));
1082 /* the header has been registered already, we don't do
1083 * anything but wait for the window to come up*/
1084 g_debug ("header %p already registered, waiting for window", header);
1086 tny_list_append (not_opened_headers, G_OBJECT (header));
1090 g_object_unref (header);
1092 tny_iterator_next (iter);
1094 g_object_unref (iter);
1097 /* If some messages would have to be downloaded, ask the user to
1098 * make a connection. It's generally easier to do this here (in the mainloop)
1099 * than later in a thread:
1101 if (tny_list_get_length (not_opened_headers) > 0) {
1103 gboolean found = FALSE;
1105 iter = tny_list_create_iterator (not_opened_headers);
1106 while (!tny_iterator_is_done (iter) && !found) {
1107 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1108 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1111 tny_iterator_next (iter);
1113 g_object_unref (header);
1115 g_object_unref (iter);
1117 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
1118 g_object_unref (not_opened_headers);
1123 /* Register the headers before actually creating the windows: */
1124 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
1125 while (!tny_iterator_is_done (iter_not_opened)) {
1126 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1128 modest_window_mgr_register_header (mgr, header);
1129 g_object_unref (header);
1132 tny_iterator_next (iter_not_opened);
1134 g_object_unref (iter_not_opened);
1135 iter_not_opened = NULL;
1137 /* Open each message */
1138 if (tny_list_get_length (not_opened_headers) > 0) {
1139 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1141 modest_ui_actions_get_msgs_full_error_handler,
1143 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1144 if (tny_list_get_length (not_opened_headers) > 1) {
1145 modest_mail_operation_get_msgs_full (mail_op,
1151 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1152 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1153 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1154 g_object_unref (header);
1155 g_object_unref (iter);
1157 g_object_unref (mail_op);
1161 if (not_opened_headers != NULL)
1162 g_object_unref (not_opened_headers);
1166 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1171 headers = get_selected_headers (win);
1176 _modest_ui_actions_open (headers, win);
1178 g_object_unref(headers);
1183 free_reply_forward_helper (gpointer data)
1185 ReplyForwardHelper *helper;
1187 helper = (ReplyForwardHelper *) data;
1188 g_free (helper->account_name);
1189 g_slice_free (ReplyForwardHelper, helper);
1193 reply_forward_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg,
1197 ReplyForwardHelper *rf_helper;
1198 ModestWindow *msg_win = NULL;
1199 ModestEditType edit_type;
1201 TnyAccount *account = NULL;
1202 ModestWindowMgr *mgr = NULL;
1203 gchar *signature = NULL;
1205 /* If there was any error. The mail operation could be NULL,
1206 this means that we already have the message downloaded and
1207 that we didn't do a mail operation to retrieve it */
1208 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1211 g_return_if_fail (user_data != NULL);
1212 rf_helper = (ReplyForwardHelper *) user_data;
1214 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1215 rf_helper->account_name);
1216 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1217 rf_helper->account_name,
1218 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1219 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1220 rf_helper->account_name,
1221 MODEST_ACCOUNT_SIGNATURE, FALSE);
1224 /* Create reply mail */
1225 switch (rf_helper->action) {
1228 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1229 rf_helper->reply_forward_type,
1230 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1232 case ACTION_REPLY_TO_ALL:
1234 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1235 MODEST_TNY_MSG_REPLY_MODE_ALL);
1236 edit_type = MODEST_EDIT_TYPE_REPLY;
1238 case ACTION_FORWARD:
1240 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1241 edit_type = MODEST_EDIT_TYPE_FORWARD;
1244 g_return_if_reached ();
1251 g_printerr ("modest: failed to create message\n");
1255 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1256 rf_helper->account_name,
1257 TNY_ACCOUNT_TYPE_STORE);
1259 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1263 /* Create and register the windows */
1264 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1265 mgr = modest_runtime_get_window_mgr ();
1266 modest_window_mgr_register_window (mgr, msg_win);
1268 if (rf_helper->parent_window != NULL) {
1269 gdouble parent_zoom;
1271 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1272 modest_window_set_zoom (msg_win, parent_zoom);
1275 /* Show edit window */
1276 gtk_widget_show_all (GTK_WIDGET (msg_win));
1280 g_object_unref (msg_win);
1282 g_object_unref (G_OBJECT (new_msg));
1284 g_object_unref (G_OBJECT (account));
1285 /* g_object_unref (msg); */
1286 free_reply_forward_helper (rf_helper);
1289 /* Checks a list of headers. If any of them are not currently
1290 * downloaded (CACHED) then returns TRUE else returns FALSE.
1293 header_list_count_uncached_msgs (TnyList *header_list)
1296 gint uncached_messages = 0;
1298 iter = tny_list_create_iterator (header_list);
1299 while (!tny_iterator_is_done (iter)) {
1302 header = TNY_HEADER (tny_iterator_get_current (iter));
1304 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1305 uncached_messages ++;
1306 g_object_unref (header);
1309 tny_iterator_next (iter);
1311 g_object_unref (iter);
1313 return uncached_messages;
1316 /* Returns FALSE if the user does not want to download the
1317 * messages. Returns TRUE if the user allowed the download.
1320 connect_to_get_msg (GtkWindow *win,
1321 gint num_of_uncached_msgs)
1323 /* Allways download if we are online. */
1324 if (tny_device_is_online (modest_runtime_get_device ()))
1327 /* If offline, then ask for user permission to download the messages */
1328 GtkResponseType response;
1329 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1330 ngettext("mcen_nc_get_msg",
1332 num_of_uncached_msgs));
1333 if (response == GTK_RESPONSE_CANCEL)
1336 return modest_platform_connect_and_wait(win, NULL);
1340 * Common code for the reply and forward actions
1343 reply_forward (ReplyForwardAction action, ModestWindow *win)
1345 ModestMailOperation *mail_op = NULL;
1346 TnyList *header_list = NULL;
1347 ReplyForwardHelper *rf_helper = NULL;
1348 guint reply_forward_type;
1349 gboolean continue_download = TRUE;
1350 gboolean do_retrieve = TRUE;
1352 g_return_if_fail (MODEST_IS_WINDOW(win));
1354 /* we need an account when editing */
1355 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1356 const gboolean created = modest_run_account_setup_wizard (win);
1361 header_list = get_selected_headers (win);
1365 reply_forward_type =
1366 modest_conf_get_int (modest_runtime_get_conf (),
1367 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1370 /* check if we need to download msg before asking about it */
1371 do_retrieve = (action == ACTION_FORWARD) ||
1372 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1375 gint num_of_unc_msgs;
1376 /* check that the messages have been previously downloaded */
1377 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1378 /* If there are any uncached message ask the user
1379 * whether he/she wants to download them. */
1380 if (num_of_unc_msgs)
1381 continue_download = connect_to_get_msg (
1386 if (!continue_download) {
1387 g_object_unref (header_list);
1391 /* We assume that we can only select messages of the
1392 same folder and that we reply all of them from the
1393 same account. In fact the interface currently only
1394 allows single selection */
1397 rf_helper = g_slice_new0 (ReplyForwardHelper);
1398 rf_helper->reply_forward_type = reply_forward_type;
1399 rf_helper->action = action;
1400 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1402 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1403 rf_helper->parent_window = GTK_WIDGET (win);
1404 if (!rf_helper->account_name)
1405 rf_helper->account_name =
1406 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1408 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1411 /* Get header and message. Do not free them here, the
1412 reply_forward_cb must do it */
1413 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1414 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1415 if (!msg || !header) {
1417 g_object_unref (msg);
1418 g_printerr ("modest: no message found\n");
1421 reply_forward_cb (NULL, header, msg, rf_helper);
1424 g_object_unref (header);
1429 /* Only reply/forward to one message */
1430 iter = tny_list_create_iterator (header_list);
1431 header = TNY_HEADER (tny_iterator_get_current (iter));
1432 g_object_unref (iter);
1435 /* Retrieve messages */
1437 mail_op = modest_mail_operation_new_with_error_handling (
1438 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1440 modest_ui_actions_get_msgs_full_error_handler,
1442 modest_mail_operation_queue_add (
1443 modest_runtime_get_mail_operation_queue (), mail_op);
1445 modest_mail_operation_get_msg (mail_op,
1450 g_object_unref(mail_op);
1452 /* we put a ref here to prevent double unref as the reply
1453 * forward callback unrefs the header at its end */
1454 reply_forward_cb (NULL, header, NULL, rf_helper);
1458 g_object_unref (header);
1464 g_object_unref (header_list);
1468 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1470 g_return_if_fail (MODEST_IS_WINDOW(win));
1472 reply_forward (ACTION_REPLY, win);
1476 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1478 g_return_if_fail (MODEST_IS_WINDOW(win));
1480 reply_forward (ACTION_FORWARD, win);
1484 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1486 g_return_if_fail (MODEST_IS_WINDOW(win));
1488 reply_forward (ACTION_REPLY_TO_ALL, win);
1492 modest_ui_actions_on_next (GtkAction *action,
1493 ModestWindow *window)
1495 if (MODEST_IS_MAIN_WINDOW (window)) {
1496 GtkWidget *header_view;
1498 header_view = modest_main_window_get_child_widget (
1499 MODEST_MAIN_WINDOW(window),
1500 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1504 modest_header_view_select_next (
1505 MODEST_HEADER_VIEW(header_view));
1506 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1507 modest_msg_view_window_select_next_message (
1508 MODEST_MSG_VIEW_WINDOW (window));
1510 g_return_if_reached ();
1515 modest_ui_actions_on_prev (GtkAction *action,
1516 ModestWindow *window)
1518 g_return_if_fail (MODEST_IS_WINDOW(window));
1520 if (MODEST_IS_MAIN_WINDOW (window)) {
1521 GtkWidget *header_view;
1522 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1523 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1527 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1528 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1529 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1531 g_return_if_reached ();
1536 modest_ui_actions_on_sort (GtkAction *action,
1537 ModestWindow *window)
1539 g_return_if_fail (MODEST_IS_WINDOW(window));
1541 if (MODEST_IS_MAIN_WINDOW (window)) {
1542 GtkWidget *header_view;
1543 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1544 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1546 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1551 /* Show sorting dialog */
1552 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1557 new_messages_arrived (ModestMailOperation *self,
1558 TnyList *new_headers,
1561 ModestMainWindow *win = NULL;
1562 GtkWidget *folder_view = NULL;
1563 TnyFolderStore *folder = NULL;
1564 gboolean folder_empty = FALSE;
1566 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1567 win = MODEST_MAIN_WINDOW (user_data);
1569 /* Don't do anything if there are not new headers, this could
1570 happen if there was any problem with the mail operation */
1574 /* Set contents style of headers view */
1575 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1576 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1577 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1578 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1581 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1584 modest_main_window_set_contents_style (win,
1585 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1588 /* Notify new messages have been downloaded */
1589 if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0)) {
1590 TnyIterator *iter = tny_list_create_iterator (new_headers);
1592 TnyHeader *header = NULL;
1594 header = TNY_HEADER (tny_iterator_get_current (iter));
1595 modest_platform_on_new_header_received (header);
1596 g_object_unref (header);
1598 tny_iterator_next (iter);
1599 } while (!tny_iterator_is_done (iter));
1600 g_object_unref (iter);
1605 * This function performs the send & receive required actions. The
1606 * window is used to create the mail operation. Typically it should
1607 * always be the main window, but we pass it as argument in order to
1611 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1613 gchar *acc_name = NULL;
1614 ModestMailOperation *mail_op;
1615 TnyAccount *store_account = NULL;
1617 /* If no account name was provided then get the current account, and if
1618 there is no current account then pick the default one: */
1619 if (!account_name) {
1620 acc_name = g_strdup (modest_window_get_active_account(win));
1622 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1624 g_printerr ("modest: cannot get default account\n");
1628 acc_name = g_strdup (account_name);
1632 /* Ensure that we have a connection available */
1634 modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
1636 TNY_ACCOUNT_TYPE_STORE);
1637 if (!modest_platform_connect_and_wait (NULL, TNY_ACCOUNT (store_account))) {
1638 g_object_unref (store_account);
1641 g_object_unref (store_account);
1643 /* Set send/receive operation in progress */
1644 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1646 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1648 modest_ui_actions_send_receive_error_handler,
1651 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1652 G_CALLBACK (_on_send_receive_progress_changed),
1655 /* Send & receive. */
1656 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1657 /* Receive and then send. The operation is tagged initially as
1658 a receive operation because the account update performs a
1659 receive and then a send. The operation changes its type
1660 internally, so the progress objects will receive the proper
1661 progress information */
1662 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1663 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1664 g_object_unref (G_OBJECT (mail_op));
1672 modest_ui_actions_do_cancel_send (const gchar *account_name,
1675 TnyTransportAccount *transport_account;
1676 TnySendQueue *send_queue = NULL;
1677 GError *error = NULL;
1679 /* Get transport account */
1681 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1682 (modest_runtime_get_account_store(),
1684 TNY_ACCOUNT_TYPE_TRANSPORT));
1685 if (!transport_account) {
1686 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1691 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1692 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1693 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1694 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1695 "modest: could not find send queue for account\n");
1697 /* Keeep messages in outbox folder */
1698 tny_send_queue_cancel (send_queue, FALSE, &error);
1702 if (transport_account != NULL)
1703 g_object_unref (G_OBJECT (transport_account));
1707 modest_ui_actions_cancel_send_all (ModestWindow *win)
1709 GSList *account_names, *iter;
1711 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1714 iter = account_names;
1716 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1717 iter = g_slist_next (iter);
1720 modest_account_mgr_free_account_names (account_names);
1721 account_names = NULL;
1725 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1728 /* Check if accounts exist */
1729 gboolean accounts_exist =
1730 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1732 /* If not, allow the user to create an account before trying to send/receive. */
1733 if (!accounts_exist)
1734 modest_ui_actions_on_accounts (NULL, win);
1736 /* Cancel all sending operaitons */
1737 modest_ui_actions_cancel_send_all (win);
1741 * Refreshes all accounts. This function will be used by automatic
1745 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1747 GSList *account_names, *iter;
1749 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1752 iter = account_names;
1754 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1755 iter = g_slist_next (iter);
1758 modest_account_mgr_free_account_names (account_names);
1759 account_names = NULL;
1763 modest_do_refresh_current_folder(ModestWindow *win)
1765 /* Refresh currently selected folder. Note that if we only
1766 want to retreive the headers, then the refresh only will
1767 invoke a poke_status over all folders, i.e., only the
1768 total/unread count will be updated */
1769 if (MODEST_IS_MAIN_WINDOW (win)) {
1770 GtkWidget *header_view, *folder_view;
1771 TnyFolderStore *folder_store;
1773 /* Get folder and header view */
1775 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1776 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1780 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1782 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1784 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1785 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1787 /* We do not need to set the contents style
1788 because it hasn't changed. We also do not
1789 need to save the widget status. Just force
1791 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1792 TNY_FOLDER (folder_store),
1793 folder_refreshed_cb,
1794 MODEST_MAIN_WINDOW (win));
1798 g_object_unref (folder_store);
1804 * Handler of the click on Send&Receive button in the main toolbar
1807 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1809 /* Check if accounts exist */
1810 gboolean accounts_exist =
1811 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1813 /* If not, allow the user to create an account before trying to send/receive. */
1814 if (!accounts_exist)
1815 modest_ui_actions_on_accounts (NULL, win);
1817 modest_do_refresh_current_folder (win);
1819 /* Refresh the active account */
1820 modest_ui_actions_do_send_receive (NULL, win);
1825 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1828 GtkWidget *header_view;
1830 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1832 header_view = modest_main_window_get_child_widget (main_window,
1833 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1837 conf = modest_runtime_get_conf ();
1839 /* what is saved/restored is depending on the style; thus; we save with
1840 * old style, then update the style, and restore for this new style
1842 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1844 if (modest_header_view_get_style
1845 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1846 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1847 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1849 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1850 MODEST_HEADER_VIEW_STYLE_DETAILS);
1852 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1853 MODEST_CONF_HEADER_VIEW_KEY);
1858 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1860 ModestMainWindow *main_window)
1862 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1863 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1865 /* in the case the folder is empty, show the empty folder message and focus
1867 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1868 if (modest_header_view_is_empty (header_view)) {
1869 TnyFolder *folder = modest_header_view_get_folder (header_view);
1870 GtkWidget *folder_view =
1871 modest_main_window_get_child_widget (main_window,
1872 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1874 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1875 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1879 /* If no header has been selected then exit */
1884 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1885 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1887 /* Update toolbar dimming state */
1888 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1892 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1894 ModestMainWindow *main_window)
1898 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1903 if (modest_header_view_count_selected_headers (header_view) > 1) {
1904 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1909 /* headers = tny_simple_list_new (); */
1910 /* tny_list_prepend (headers, G_OBJECT (header)); */
1911 headers = modest_header_view_get_selected_headers (header_view);
1913 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1915 g_object_unref (headers);
1919 set_active_account_from_tny_account (TnyAccount *account,
1920 ModestWindow *window)
1922 const gchar *server_acc_name = tny_account_get_id (account);
1924 /* We need the TnyAccount provided by the
1925 account store because that is the one that
1926 knows the name of the Modest account */
1927 TnyAccount *modest_server_account = modest_server_account =
1928 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1929 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1931 if (!modest_server_account) {
1932 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1936 /* Update active account, but only if it's not a pseudo-account */
1937 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1938 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1939 const gchar *modest_acc_name =
1940 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1941 if (modest_acc_name)
1942 modest_window_set_active_account (window, modest_acc_name);
1945 g_object_unref (modest_server_account);
1950 folder_refreshed_cb (ModestMailOperation *mail_op,
1954 ModestMainWindow *win = NULL;
1955 GtkWidget *header_view;
1956 gboolean folder_empty = FALSE;
1957 gboolean all_marked_as_deleted = FALSE;
1959 g_return_if_fail (TNY_IS_FOLDER (folder));
1961 win = MODEST_MAIN_WINDOW (user_data);
1963 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1966 TnyFolder *current_folder;
1968 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1969 if (current_folder != NULL && folder != current_folder) {
1970 g_object_unref (current_folder);
1973 g_object_unref (current_folder);
1976 /* Check if folder is empty and set headers view contents style */
1977 folder_empty = (tny_folder_get_all_count (folder) == 0);
1978 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1979 if (folder_empty || all_marked_as_deleted)
1980 modest_main_window_set_contents_style (win,
1981 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1985 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1986 TnyFolderStore *folder_store,
1988 ModestMainWindow *main_window)
1991 GtkWidget *header_view;
1993 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1995 header_view = modest_main_window_get_child_widget(main_window,
1996 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2000 conf = modest_runtime_get_conf ();
2002 if (TNY_IS_ACCOUNT (folder_store)) {
2004 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2006 /* Show account details */
2007 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2010 if (TNY_IS_FOLDER (folder_store) && selected) {
2012 /* Update the active account */
2013 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2015 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2016 g_object_unref (account);
2020 /* Set the header style by default, it could
2021 be changed later by the refresh callback to
2023 modest_main_window_set_contents_style (main_window,
2024 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2026 /* Set folder on header view. This function
2027 will call tny_folder_refresh_async so we
2028 pass a callback that will be called when
2029 finished. We use that callback to set the
2030 empty view if there are no messages */
2031 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2032 TNY_FOLDER (folder_store),
2033 folder_refreshed_cb,
2036 /* Restore configuration. We need to do this
2037 *after* the set_folder because the widget
2038 memory asks the header view about its
2040 modest_widget_memory_restore (modest_runtime_get_conf (),
2041 G_OBJECT(header_view),
2042 MODEST_CONF_HEADER_VIEW_KEY);
2044 /* Update the active account */
2045 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2046 /* Save only if we're seeing headers */
2047 if (modest_main_window_get_contents_style (main_window) ==
2048 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2049 modest_widget_memory_save (conf, G_OBJECT (header_view),
2050 MODEST_CONF_HEADER_VIEW_KEY);
2051 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2055 /* Update toolbar dimming state */
2056 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2060 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2067 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2069 online = tny_device_is_online (modest_runtime_get_device());
2072 /* already online -- the item is simply not there... */
2073 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2075 GTK_MESSAGE_WARNING,
2077 _("The %s you selected cannot be found"),
2079 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2080 gtk_dialog_run (GTK_DIALOG(dialog));
2082 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2085 _("mcen_bd_dialog_cancel"),
2086 GTK_RESPONSE_REJECT,
2087 _("mcen_bd_dialog_ok"),
2088 GTK_RESPONSE_ACCEPT,
2090 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2091 "Do you want to get online?"), item);
2092 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2093 gtk_label_new (txt), FALSE, FALSE, 0);
2094 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2097 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2098 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2099 /* TODO: Comment about why is this commented out: */
2100 /* modest_platform_connect_and_wait (); */
2103 gtk_widget_destroy (dialog);
2107 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2110 /* g_message ("%s %s", __FUNCTION__, link); */
2115 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2118 modest_platform_activate_uri (link);
2122 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2125 modest_platform_show_uri_popup (link);
2129 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2132 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2136 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2137 const gchar *address,
2140 /* g_message ("%s %s", __FUNCTION__, address); */
2144 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2146 TnyTransportAccount *transport_account;
2147 ModestMailOperation *mail_operation;
2149 gchar *account_name, *from;
2150 ModestAccountMgr *account_mgr;
2151 gchar *info_text = NULL;
2153 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2155 data = modest_msg_edit_window_get_msg_data (edit_window);
2157 account_mgr = modest_runtime_get_account_mgr();
2158 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2160 account_name = modest_account_mgr_get_default_account (account_mgr);
2161 if (!account_name) {
2162 g_printerr ("modest: no account found\n");
2163 modest_msg_edit_window_free_msg_data (edit_window, data);
2167 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2168 account_name = g_strdup (data->account_name);
2172 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2173 (modest_runtime_get_account_store(),
2175 TNY_ACCOUNT_TYPE_TRANSPORT));
2176 if (!transport_account) {
2177 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2178 g_free (account_name);
2179 modest_msg_edit_window_free_msg_data (edit_window, data);
2182 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2184 /* Create the mail operation */
2185 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2186 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2188 modest_mail_operation_save_to_drafts (mail_operation,
2200 data->priority_flags);
2203 g_free (account_name);
2204 g_object_unref (G_OBJECT (transport_account));
2205 g_object_unref (G_OBJECT (mail_operation));
2207 modest_msg_edit_window_free_msg_data (edit_window, data);
2209 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2210 modest_platform_information_banner (NULL, NULL, info_text);
2211 modest_msg_edit_window_reset_modified (edit_window);
2215 /* For instance, when clicking the Send toolbar button when editing a message: */
2217 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2219 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2221 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2224 /* Offer the connection dialog, if necessary: */
2225 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2228 /* FIXME: Code added just for testing. The final version will
2229 use the send queue provided by tinymail and some
2231 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2232 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2234 account_name = modest_account_mgr_get_default_account (account_mgr);
2236 if (!account_name) {
2237 /* Run account setup wizard */
2238 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2243 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2245 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2246 account_name = g_strdup (data->account_name);
2249 /* Get the currently-active transport account for this modest account: */
2250 TnyTransportAccount *transport_account =
2251 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2252 (modest_runtime_get_account_store(),
2254 if (!transport_account) {
2255 /* Run account setup wizard */
2256 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2261 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2263 /* Create the mail operation */
2264 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2265 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2267 modest_mail_operation_send_new_mail (mail_operation,
2278 data->priority_flags);
2282 g_free (account_name);
2283 g_object_unref (G_OBJECT (transport_account));
2284 g_object_unref (G_OBJECT (mail_operation));
2286 modest_msg_edit_window_free_msg_data (edit_window, data);
2287 modest_msg_edit_window_set_sent (edit_window, TRUE);
2289 /* Save settings and close the window: */
2290 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2294 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2295 ModestMsgEditWindow *window)
2297 ModestMsgEditFormatState *format_state = NULL;
2299 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2300 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2302 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2305 format_state = modest_msg_edit_window_get_format_state (window);
2306 g_return_if_fail (format_state != NULL);
2308 format_state->bold = gtk_toggle_action_get_active (action);
2309 modest_msg_edit_window_set_format_state (window, format_state);
2310 g_free (format_state);
2315 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2316 ModestMsgEditWindow *window)
2318 ModestMsgEditFormatState *format_state = NULL;
2320 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2321 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2323 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2326 format_state = modest_msg_edit_window_get_format_state (window);
2327 g_return_if_fail (format_state != NULL);
2329 format_state->italics = gtk_toggle_action_get_active (action);
2330 modest_msg_edit_window_set_format_state (window, format_state);
2331 g_free (format_state);
2336 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2337 ModestMsgEditWindow *window)
2339 ModestMsgEditFormatState *format_state = NULL;
2341 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2342 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2344 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2347 format_state = modest_msg_edit_window_get_format_state (window);
2348 g_return_if_fail (format_state != NULL);
2350 format_state->bullet = gtk_toggle_action_get_active (action);
2351 modest_msg_edit_window_set_format_state (window, format_state);
2352 g_free (format_state);
2357 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2358 GtkRadioAction *selected,
2359 ModestMsgEditWindow *window)
2361 ModestMsgEditFormatState *format_state = NULL;
2362 GtkJustification value;
2364 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2366 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2369 value = gtk_radio_action_get_current_value (selected);
2371 format_state = modest_msg_edit_window_get_format_state (window);
2372 g_return_if_fail (format_state != NULL);
2374 format_state->justification = value;
2375 modest_msg_edit_window_set_format_state (window, format_state);
2376 g_free (format_state);
2380 modest_ui_actions_on_select_editor_color (GtkAction *action,
2381 ModestMsgEditWindow *window)
2383 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2384 g_return_if_fail (GTK_IS_ACTION (action));
2386 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2389 modest_msg_edit_window_select_color (window);
2393 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2394 ModestMsgEditWindow *window)
2396 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2397 g_return_if_fail (GTK_IS_ACTION (action));
2399 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2402 modest_msg_edit_window_select_background_color (window);
2406 modest_ui_actions_on_insert_image (GtkAction *action,
2407 ModestMsgEditWindow *window)
2409 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2410 g_return_if_fail (GTK_IS_ACTION (action));
2412 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2415 modest_msg_edit_window_insert_image (window);
2419 modest_ui_actions_on_attach_file (GtkAction *action,
2420 ModestMsgEditWindow *window)
2422 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2423 g_return_if_fail (GTK_IS_ACTION (action));
2425 modest_msg_edit_window_offer_attach_file (window);
2429 modest_ui_actions_on_remove_attachments (GtkAction *action,
2430 ModestMsgEditWindow *window)
2432 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2433 g_return_if_fail (GTK_IS_ACTION (action));
2435 modest_msg_edit_window_remove_attachments (window, NULL);
2439 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2442 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2443 const GError *error = modest_mail_operation_get_error (mail_op);
2446 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2447 _("mail_in_ui_folder_create_error"));
2452 modest_ui_actions_create_folder(GtkWidget *parent_window,
2453 GtkWidget *folder_view)
2455 TnyFolderStore *parent_folder;
2457 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2459 if (parent_folder) {
2460 gboolean finished = FALSE;
2462 gchar *folder_name = NULL, *suggested_name = NULL;
2463 const gchar *proto_str = NULL;
2464 TnyAccount *account;
2466 if (TNY_IS_ACCOUNT (parent_folder))
2467 account = g_object_ref (parent_folder);
2469 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2470 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2472 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2473 MODEST_PROTOCOL_STORE_POP) {
2475 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2477 g_object_unref (account);
2479 /* Run the new folder dialog */
2481 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2486 g_free (suggested_name);
2487 suggested_name = NULL;
2489 if (result == GTK_RESPONSE_REJECT) {
2492 ModestMailOperation *mail_op;
2493 TnyFolder *new_folder = NULL;
2495 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2496 G_OBJECT(parent_window),
2497 modest_ui_actions_new_folder_error_handler,
2500 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2502 new_folder = modest_mail_operation_create_folder (mail_op,
2504 (const gchar *) folder_name);
2506 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2509 g_object_unref (new_folder);
2512 g_object_unref (mail_op);
2515 suggested_name = folder_name;
2519 g_object_unref (parent_folder);
2524 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2526 GtkWidget *folder_view;
2528 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2530 folder_view = modest_main_window_get_child_widget (main_window,
2531 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2535 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2539 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2542 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2543 const GError *error = NULL;
2544 const gchar *message = NULL;
2546 /* Get error message */
2547 error = modest_mail_operation_get_error (mail_op);
2549 g_return_if_reached ();
2551 switch (error->code) {
2552 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2553 message = _CS("ckdg_ib_folder_already_exists");
2556 g_return_if_reached ();
2559 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2563 modest_ui_actions_on_rename_folder (GtkAction *action,
2564 ModestMainWindow *main_window)
2566 TnyFolderStore *folder;
2567 GtkWidget *folder_view;
2568 GtkWidget *header_view;
2570 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2572 folder_view = modest_main_window_get_child_widget (main_window,
2573 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2577 header_view = modest_main_window_get_child_widget (main_window,
2578 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2583 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2588 if (TNY_IS_FOLDER (folder)) {
2591 const gchar *current_name;
2592 TnyFolderStore *parent;
2593 gboolean do_rename = TRUE;
2595 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2596 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2597 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2598 parent, current_name,
2600 g_object_unref (parent);
2602 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2604 } else if (modest_platform_is_network_folderstore(folder) &&
2605 !tny_device_is_online (modest_runtime_get_device())) {
2606 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2607 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2608 g_object_unref(account);
2612 ModestMailOperation *mail_op;
2613 GtkTreeSelection *sel = NULL;
2616 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2617 G_OBJECT(main_window),
2618 modest_ui_actions_rename_folder_error_handler,
2621 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2624 /* Clear the headers view */
2625 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2626 gtk_tree_selection_unselect_all (sel);
2628 /* Select *after* the changes */
2629 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2630 TNY_FOLDER(folder), TRUE);
2632 /* Actually rename the folder */
2633 modest_mail_operation_rename_folder (mail_op,
2634 TNY_FOLDER (folder),
2635 (const gchar *) folder_name);
2637 g_object_unref (mail_op);
2638 g_free (folder_name);
2641 g_object_unref (folder);
2645 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2648 GObject *win = modest_mail_operation_get_source (mail_op);
2650 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2651 _("mail_in_ui_folder_delete_error"));
2652 g_object_unref (win);
2656 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2658 TnyFolderStore *folder;
2659 GtkWidget *folder_view;
2662 gboolean do_delete = TRUE;
2664 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2666 folder_view = modest_main_window_get_child_widget (main_window,
2667 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2671 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2673 /* Show an error if it's an account */
2674 if (!TNY_IS_FOLDER (folder)) {
2675 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2676 _("mail_in_ui_folder_delete_error"));
2677 g_object_unref (G_OBJECT (folder));
2682 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2683 tny_folder_get_name (TNY_FOLDER (folder)));
2684 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2685 (const gchar *) message);
2688 if (response != GTK_RESPONSE_OK) {
2690 } else if (modest_platform_is_network_folderstore(folder) &&
2691 !tny_device_is_online (modest_runtime_get_device())) {
2692 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2693 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2694 g_object_unref(account);
2698 ModestMailOperation *mail_op;
2699 GtkTreeSelection *sel;
2701 /* Unselect the folder before deleting it to free the headers */
2702 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2703 gtk_tree_selection_unselect_all (sel);
2705 /* Create the mail operation */
2707 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2708 G_OBJECT(main_window),
2709 modest_ui_actions_delete_folder_error_handler,
2712 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2714 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2715 g_object_unref (G_OBJECT (mail_op));
2718 g_object_unref (G_OBJECT (folder));
2724 modest_ui_actions_on_delete_folder (GtkAction *action,
2725 ModestMainWindow *main_window)
2727 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2729 if (delete_folder (main_window, FALSE)) {
2730 GtkWidget *folder_view;
2732 folder_view = modest_main_window_get_child_widget (main_window,
2733 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2734 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2739 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2741 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2743 delete_folder (main_window, TRUE);
2748 show_error (GtkWidget *parent_widget, const gchar* text)
2750 hildon_banner_show_information(parent_widget, NULL, text);
2753 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2755 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2762 gtk_dialog_run (dialog);
2763 gtk_widget_destroy (GTK_WIDGET (dialog));
2768 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2769 const gchar* server_account_name,
2774 ModestMainWindow *main_window)
2776 g_return_if_fail(server_account_name);
2777 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2779 /* Initalize output parameters: */
2786 #ifdef MODEST_PLATFORM_MAEMO
2787 /* Maemo uses a different (awkward) button order,
2788 * It should probably just use gtk_alternative_dialog_button_order ().
2790 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2793 _("mcen_bd_dialog_ok"),
2794 GTK_RESPONSE_ACCEPT,
2795 _("mcen_bd_dialog_cancel"),
2796 GTK_RESPONSE_REJECT,
2799 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2803 GTK_RESPONSE_REJECT,
2805 GTK_RESPONSE_ACCEPT,
2807 #endif /* MODEST_PLATFORM_MAEMO */
2809 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2811 gchar *server_name = modest_server_account_get_hostname (
2812 modest_runtime_get_account_mgr(), server_account_name);
2813 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2814 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2819 /* This causes a warning because the logical ID has no %s in it,
2820 * though the translation does, but there is not much we can do about that: */
2821 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2822 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2825 g_free (server_name);
2829 gchar *initial_username = modest_server_account_get_username (
2830 modest_runtime_get_account_mgr(), server_account_name);
2832 GtkWidget *entry_username = gtk_entry_new ();
2833 if (initial_username)
2834 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2835 /* Dim this if a connection has ever succeeded with this username,
2836 * as per the UI spec: */
2837 const gboolean username_known =
2838 modest_server_account_get_username_has_succeeded(
2839 modest_runtime_get_account_mgr(), server_account_name);
2840 gtk_widget_set_sensitive (entry_username, !username_known);
2842 #ifdef MODEST_PLATFORM_MAEMO
2843 /* Auto-capitalization is the default, so let's turn it off: */
2844 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2846 /* Create a size group to be used by all captions.
2847 * Note that HildonCaption does not create a default size group if we do not specify one.
2848 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2849 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2851 GtkWidget *caption = hildon_caption_new (sizegroup,
2852 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2853 gtk_widget_show (entry_username);
2854 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2855 FALSE, FALSE, MODEST_MARGIN_HALF);
2856 gtk_widget_show (caption);
2858 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2860 #endif /* MODEST_PLATFORM_MAEMO */
2863 GtkWidget *entry_password = gtk_entry_new ();
2864 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2865 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2867 #ifdef MODEST_PLATFORM_MAEMO
2868 /* Auto-capitalization is the default, so let's turn it off: */
2869 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2870 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2872 caption = hildon_caption_new (sizegroup,
2873 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2874 gtk_widget_show (entry_password);
2875 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2876 FALSE, FALSE, MODEST_MARGIN_HALF);
2877 gtk_widget_show (caption);
2878 g_object_unref (sizegroup);
2880 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2882 #endif /* MODEST_PLATFORM_MAEMO */
2884 if (initial_username != NULL)
2885 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
2887 /* This is not in the Maemo UI spec:
2888 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2889 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2893 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2895 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2897 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2899 modest_server_account_set_username (
2900 modest_runtime_get_account_mgr(), server_account_name,
2903 const gboolean username_was_changed =
2904 (strcmp (*username, initial_username) != 0);
2905 if (username_was_changed) {
2906 g_warning ("%s: tinymail does not yet support changing the "
2907 "username in the get_password() callback.\n", __FUNCTION__);
2912 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2914 /* We do not save the password in the configuration,
2915 * because this function is only called for passwords that should
2916 * not be remembered:
2917 modest_server_account_set_password (
2918 modest_runtime_get_account_mgr(), server_account_name,
2927 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2939 /* This is not in the Maemo UI spec:
2940 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2946 gtk_widget_destroy (dialog);
2948 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2952 modest_ui_actions_on_cut (GtkAction *action,
2953 ModestWindow *window)
2955 GtkWidget *focused_widget;
2956 GtkClipboard *clipboard;
2958 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2959 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2960 if (GTK_IS_EDITABLE (focused_widget)) {
2961 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2962 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2963 gtk_clipboard_store (clipboard);
2964 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2965 GtkTextBuffer *buffer;
2967 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2968 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2969 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2970 gtk_clipboard_store (clipboard);
2971 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2972 TnyList *header_list = modest_header_view_get_selected_headers (
2973 MODEST_HEADER_VIEW (focused_widget));
2974 gboolean continue_download = FALSE;
2975 gint num_of_unc_msgs;
2977 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2979 if (num_of_unc_msgs)
2980 continue_download = connect_to_get_msg(
2981 GTK_WINDOW (window),
2984 if (num_of_unc_msgs == 0 || continue_download) {
2985 /* modest_platform_information_banner (
2986 NULL, NULL, _CS("mcen_ib_getting_items"));*/
2987 modest_header_view_cut_selection (
2988 MODEST_HEADER_VIEW (focused_widget));
2991 g_object_unref (header_list);
2992 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2993 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2998 modest_ui_actions_on_copy (GtkAction *action,
2999 ModestWindow *window)
3001 GtkClipboard *clipboard;
3002 GtkWidget *focused_widget;
3003 gboolean copied = TRUE;
3005 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3006 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3008 if (GTK_IS_LABEL (focused_widget)) {
3009 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
3010 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3011 gtk_clipboard_store (clipboard);
3012 } else if (GTK_IS_EDITABLE (focused_widget)) {
3013 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3014 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3015 gtk_clipboard_store (clipboard);
3016 } else if (GTK_IS_HTML (focused_widget)) {
3017 gtk_html_copy (GTK_HTML (focused_widget));
3018 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3019 gtk_clipboard_store (clipboard);
3020 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3021 GtkTextBuffer *buffer;
3022 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3023 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3024 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3025 gtk_clipboard_store (clipboard);
3026 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3027 TnyList *header_list = modest_header_view_get_selected_headers (
3028 MODEST_HEADER_VIEW (focused_widget));
3029 gboolean continue_download = FALSE;
3030 gint num_of_unc_msgs;
3032 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3034 if (num_of_unc_msgs)
3035 continue_download = connect_to_get_msg(
3036 GTK_WINDOW (window),
3039 if (num_of_unc_msgs == 0 || continue_download) {
3040 modest_platform_information_banner (
3041 NULL, NULL, _CS("mcen_ib_getting_items"));
3042 modest_header_view_copy_selection (
3043 MODEST_HEADER_VIEW (focused_widget));
3047 g_object_unref (header_list);
3049 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3050 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3053 /* Show information banner if there was a copy to clipboard */
3055 modest_platform_information_banner (
3056 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3060 modest_ui_actions_on_undo (GtkAction *action,
3061 ModestWindow *window)
3063 ModestEmailClipboard *clipboard = NULL;
3065 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3066 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3067 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3068 /* Clear clipboard source */
3069 clipboard = modest_runtime_get_email_clipboard ();
3070 modest_email_clipboard_clear (clipboard);
3073 g_return_if_reached ();
3078 modest_ui_actions_on_redo (GtkAction *action,
3079 ModestWindow *window)
3081 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3082 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3085 g_return_if_reached ();
3091 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3093 /* destroy information note */
3094 gtk_widget_destroy (GTK_WIDGET(user_data));
3099 paste_as_attachment_free (gpointer data)
3101 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3103 gtk_widget_destroy (helper->banner);
3104 g_object_unref (helper->banner);
3109 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3114 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3115 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3120 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3125 modest_ui_actions_on_paste (GtkAction *action,
3126 ModestWindow *window)
3128 GtkWidget *focused_widget = NULL;
3129 GtkWidget *inf_note = NULL;
3130 ModestMailOperation *mail_op = NULL;
3132 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3133 if (GTK_IS_EDITABLE (focused_widget)) {
3134 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3135 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3136 ModestEmailClipboard *e_clipboard = NULL;
3137 e_clipboard = modest_runtime_get_email_clipboard ();
3138 if (modest_email_clipboard_cleared (e_clipboard)) {
3139 GtkTextBuffer *buffer;
3140 GtkClipboard *clipboard;
3142 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3143 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3144 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3145 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3146 ModestMailOperation *mail_op;
3147 TnyFolder *src_folder;
3150 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3151 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3152 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3153 _CS("ckct_nw_pasting"));
3154 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3155 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3157 if (helper->banner != NULL) {
3158 g_object_ref (G_OBJECT (helper->banner));
3159 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3160 gtk_widget_show (GTK_WIDGET (helper->banner));
3164 modest_mail_operation_get_msgs_full (mail_op,
3166 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3168 paste_as_attachment_free);
3171 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3172 ModestEmailClipboard *clipboard = NULL;
3173 TnyFolder *src_folder = NULL;
3174 TnyFolderStore *folder_store = NULL;
3175 TnyList *data = NULL;
3176 gboolean delete = FALSE;
3178 /* Check clipboard source */
3179 clipboard = modest_runtime_get_email_clipboard ();
3180 if (modest_email_clipboard_cleared (clipboard))
3183 /* Get elements to paste */
3184 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3186 /* Create a new mail operation */
3187 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3189 /* Get destination folder */
3190 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3192 /* transfer messages */
3196 /* Ask for user confirmation */
3198 modest_ui_actions_msgs_move_to_confirmation (GTK_WINDOW (window),
3199 TNY_FOLDER (folder_store),
3203 if (response == GTK_RESPONSE_OK) {
3204 /* Launch notification */
3205 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3206 _CS("ckct_nw_pasting"));
3207 if (inf_note != NULL) {
3208 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3209 gtk_widget_show (GTK_WIDGET(inf_note));
3212 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3213 modest_mail_operation_xfer_msgs (mail_op,
3215 TNY_FOLDER (folder_store),
3217 destroy_information_note,
3220 g_object_unref (mail_op);
3223 } else if (src_folder != NULL) {
3224 /* Launch notification */
3225 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3226 _CS("ckct_nw_pasting"));
3227 if (inf_note != NULL) {
3228 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3229 gtk_widget_show (GTK_WIDGET(inf_note));
3232 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3233 modest_mail_operation_xfer_folder (mail_op,
3237 destroy_information_note,
3243 g_object_unref (data);
3244 if (src_folder != NULL)
3245 g_object_unref (src_folder);
3246 if (folder_store != NULL)
3247 g_object_unref (folder_store);
3253 modest_ui_actions_on_select_all (GtkAction *action,
3254 ModestWindow *window)
3256 GtkWidget *focused_widget;
3258 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3259 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3260 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3261 } else if (GTK_IS_LABEL (focused_widget)) {
3262 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3263 } else if (GTK_IS_EDITABLE (focused_widget)) {
3264 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3265 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3266 GtkTextBuffer *buffer;
3267 GtkTextIter start, end;
3269 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3270 gtk_text_buffer_get_start_iter (buffer, &start);
3271 gtk_text_buffer_get_end_iter (buffer, &end);
3272 gtk_text_buffer_select_range (buffer, &start, &end);
3273 } else if (GTK_IS_HTML (focused_widget)) {
3274 gtk_html_select_all (GTK_HTML (focused_widget));
3275 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3276 GtkWidget *header_view = focused_widget;
3277 GtkTreeSelection *selection = NULL;
3279 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3280 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3281 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3284 /* Disable window dimming management */
3285 modest_window_disable_dimming (MODEST_WINDOW(window));
3287 /* Select all messages */
3288 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3289 gtk_tree_selection_select_all (selection);
3291 /* Set focuse on header view */
3292 gtk_widget_grab_focus (header_view);
3295 /* Enable window dimming management */
3296 modest_window_enable_dimming (MODEST_WINDOW(window));
3297 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3303 modest_ui_actions_on_mark_as_read (GtkAction *action,
3304 ModestWindow *window)
3306 g_return_if_fail (MODEST_IS_WINDOW(window));
3308 /* Mark each header as read */
3309 do_headers_action (window, headers_action_mark_as_read, NULL);
3313 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3314 ModestWindow *window)
3316 g_return_if_fail (MODEST_IS_WINDOW(window));
3318 /* Mark each header as read */
3319 do_headers_action (window, headers_action_mark_as_unread, NULL);
3323 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3324 GtkRadioAction *selected,
3325 ModestWindow *window)
3329 value = gtk_radio_action_get_current_value (selected);
3330 if (MODEST_IS_WINDOW (window)) {
3331 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3336 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3337 GtkRadioAction *selected,
3338 ModestWindow *window)
3340 TnyHeaderFlags flags;
3341 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3343 flags = gtk_radio_action_get_current_value (selected);
3344 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3348 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3349 GtkRadioAction *selected,
3350 ModestWindow *window)
3354 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3356 file_format = gtk_radio_action_get_current_value (selected);
3357 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3362 modest_ui_actions_on_zoom_plus (GtkAction *action,
3363 ModestWindow *window)
3365 g_return_if_fail (MODEST_IS_WINDOW (window));
3367 modest_window_zoom_plus (MODEST_WINDOW (window));
3371 modest_ui_actions_on_zoom_minus (GtkAction *action,
3372 ModestWindow *window)
3374 g_return_if_fail (MODEST_IS_WINDOW (window));
3376 modest_window_zoom_minus (MODEST_WINDOW (window));
3380 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3381 ModestWindow *window)
3383 ModestWindowMgr *mgr;
3384 gboolean fullscreen, active;
3385 g_return_if_fail (MODEST_IS_WINDOW (window));
3387 mgr = modest_runtime_get_window_mgr ();
3389 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3390 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3392 if (active != fullscreen) {
3393 modest_window_mgr_set_fullscreen_mode (mgr, active);
3394 gtk_window_present (GTK_WINDOW (window));
3399 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3400 ModestWindow *window)
3402 ModestWindowMgr *mgr;
3403 gboolean fullscreen;
3405 g_return_if_fail (MODEST_IS_WINDOW (window));
3407 mgr = modest_runtime_get_window_mgr ();
3408 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3409 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3411 gtk_window_present (GTK_WINDOW (window));
3415 * Used by modest_ui_actions_on_details to call do_headers_action
3418 headers_action_show_details (TnyHeader *header,
3419 ModestWindow *window,
3426 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3429 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3430 gtk_widget_show_all (dialog);
3431 gtk_dialog_run (GTK_DIALOG (dialog));
3433 gtk_widget_destroy (dialog);
3437 * Show the folder details in a ModestDetailsDialog widget
3440 show_folder_details (TnyFolder *folder,
3446 dialog = modest_details_dialog_new_with_folder (window, folder);
3449 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3450 gtk_widget_show_all (dialog);
3451 gtk_dialog_run (GTK_DIALOG (dialog));
3453 gtk_widget_destroy (dialog);
3457 * Show the header details in a ModestDetailsDialog widget
3460 modest_ui_actions_on_details (GtkAction *action,
3463 TnyList * headers_list;
3467 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3470 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3473 g_object_unref (msg);
3475 headers_list = get_selected_headers (win);
3479 iter = tny_list_create_iterator (headers_list);
3481 header = TNY_HEADER (tny_iterator_get_current (iter));
3483 headers_action_show_details (header, win, NULL);
3484 g_object_unref (header);
3487 g_object_unref (iter);
3488 g_object_unref (headers_list);
3490 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3491 GtkWidget *folder_view, *header_view;
3493 /* Check which widget has the focus */
3494 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3495 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3496 if (gtk_widget_is_focus (folder_view)) {
3497 TnyFolderStore *folder_store
3498 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3499 if (!folder_store) {
3500 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3503 /* Show only when it's a folder */
3504 /* This function should not be called for account items,
3505 * because we dim the menu item for them. */
3506 if (TNY_IS_FOLDER (folder_store)) {
3507 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3510 g_object_unref (folder_store);
3513 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3514 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3515 /* Show details of each header */
3516 do_headers_action (win, headers_action_show_details, header_view);
3522 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3523 ModestMsgEditWindow *window)
3525 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3527 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3531 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3532 ModestMsgEditWindow *window)
3534 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3536 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3540 modest_ui_actions_toggle_folders_view (GtkAction *action,
3541 ModestMainWindow *main_window)
3543 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3545 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3546 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3548 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3552 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3553 ModestWindow *window)
3555 gboolean active, fullscreen = FALSE;
3556 ModestWindowMgr *mgr;
3558 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3560 /* Check if we want to toggle the toolbar vuew in fullscreen
3562 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3563 "ViewShowToolbarFullScreen")) {
3567 /* Toggle toolbar */
3568 mgr = modest_runtime_get_window_mgr ();
3569 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3573 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3574 ModestMsgEditWindow *window)
3576 modest_msg_edit_window_select_font (window);
3580 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3581 const gchar *display_name,
3584 /* Do not change the application name if the widget has not
3585 the focus. This callback could be called even if the folder
3586 view has not the focus, because the handled signal could be
3587 emitted when the folder view is redrawn */
3588 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3590 gtk_window_set_title (window, display_name);
3592 gtk_window_set_title (window, " ");
3597 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3599 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3600 modest_msg_edit_window_select_contacts (window);
3604 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3606 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3607 modest_msg_edit_window_check_names (window, FALSE);
3611 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3613 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3614 GTK_WIDGET (user_data));
3618 * This function is used to track changes in the selection of the
3619 * folder view that is inside the "move to" dialog to enable/disable
3620 * the OK button because we do not want the user to select a disallowed
3621 * destination for a folder.
3622 * The user also not desired to be able to use NEW button on items where
3623 * folder creation is not possibel.
3626 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3627 TnyFolderStore *folder_store,
3631 GtkWidget *dialog = NULL;
3632 GtkWidget *ok_button = NULL, *new_button = NULL;
3633 GList *children = NULL;
3634 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3635 gboolean moving_folder = FALSE;
3636 gboolean is_local_account = TRUE;
3637 GtkWidget *folder_view = NULL;
3638 ModestTnyFolderRules rules;
3643 /* Get the OK button */
3644 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3648 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3649 ok_button = GTK_WIDGET (children->next->next->data);
3650 new_button = GTK_WIDGET (children->next->data);
3651 g_list_free (children);
3653 /* check if folder_store is an remote account */
3654 if (TNY_IS_ACCOUNT (folder_store)) {
3655 TnyAccount *local_account = NULL;
3656 ModestTnyAccountStore *account_store = NULL;
3658 account_store = modest_runtime_get_account_store ();
3659 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3661 if ((gpointer) local_account != (gpointer) folder_store) {
3662 is_local_account = FALSE;
3663 /* New button should be dimmed on remote
3665 new_sensitive = FALSE;
3667 g_object_unref (local_account);
3670 /* Check the target folder rules */
3671 if (TNY_IS_FOLDER (folder_store)) {
3672 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3673 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3674 ok_sensitive = FALSE;
3675 new_sensitive = FALSE;
3680 /* Check if we're moving a folder */
3681 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3682 /* Get the widgets */
3683 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3684 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3685 if (gtk_widget_is_focus (folder_view))
3686 moving_folder = TRUE;
3689 if (moving_folder) {
3690 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3692 /* Get the folder to move */
3693 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3695 /* Check that we're not moving to the same folder */
3696 if (TNY_IS_FOLDER (moved_folder)) {
3697 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3698 if (parent == folder_store)
3699 ok_sensitive = FALSE;
3700 g_object_unref (parent);
3703 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3704 /* Do not allow to move to an account unless it's the
3705 local folders account */
3706 if (!is_local_account)
3707 ok_sensitive = FALSE;
3710 if (ok_sensitive && (moved_folder == folder_store)) {
3711 /* Do not allow to move to itself */
3712 ok_sensitive = FALSE;
3714 g_object_unref (moved_folder);
3716 TnyHeader *header = NULL;
3717 TnyFolder *src_folder = NULL;
3719 /* Moving a message */
3720 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3721 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3722 src_folder = tny_header_get_folder (header);
3723 g_object_unref (header);
3726 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3729 /* Do not allow to move the msg to the same folder */
3730 /* Do not allow to move the msg to an account */
3731 if ((gpointer) src_folder == (gpointer) folder_store ||
3732 TNY_IS_ACCOUNT (folder_store))
3733 ok_sensitive = FALSE;
3734 g_object_unref (src_folder);
3738 /* Set sensitivity of the OK button */
3739 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3740 /* Set sensitivity of the NEW button */
3741 gtk_widget_set_sensitive (new_button, new_sensitive);
3745 create_move_to_dialog (GtkWindow *win,
3746 GtkWidget *folder_view,
3747 GtkWidget **tree_view)
3749 GtkWidget *dialog, *scroll;
3750 GtkWidget *new_button;
3752 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3754 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3757 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3758 /* We do this manually so GTK+ does not associate a response ID for
3760 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3761 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3762 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3764 /* Create scrolled window */
3765 scroll = gtk_scrolled_window_new (NULL, NULL);
3766 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3767 GTK_POLICY_AUTOMATIC,
3768 GTK_POLICY_AUTOMATIC);
3770 /* Create folder view */
3771 *tree_view = modest_platform_create_folder_view (NULL);
3773 /* Track changes in the selection to
3774 * disable the OK button whenever "Move to" is not possible
3775 * disbale NEW button whenever New is not possible */
3776 g_signal_connect (*tree_view,
3777 "folder_selection_changed",
3778 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3781 /* Listen to clicks on New button */
3782 g_signal_connect (G_OBJECT (new_button),
3784 G_CALLBACK(create_move_to_dialog_on_new_folder),
3787 /* It could happen that we're trying to move a message from a
3788 window (msg window for example) after the main window was
3789 closed, so we can not just get the model of the folder
3791 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3792 const gchar *visible_id = NULL;
3794 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3795 MODEST_FOLDER_VIEW(*tree_view));
3798 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3800 /* Show the same account than the one that is shown in the main window */
3801 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3804 const gchar *active_account_name = NULL;
3805 ModestAccountMgr *mgr = NULL;
3806 ModestAccountData *acc_data = NULL;
3808 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3809 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3811 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3812 mgr = modest_runtime_get_account_mgr ();
3813 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3815 /* Set the new visible & active account */
3816 if (acc_data && acc_data->store_account) {
3817 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3818 acc_data->store_account->account_name);
3819 modest_account_mgr_free_account_data (mgr, acc_data);
3823 /* Hide special folders */
3824 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3826 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3828 /* Add scroll to dialog */
3829 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3830 scroll, TRUE, TRUE, 0);
3832 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3833 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3839 * Returns TRUE if at least one of the headers of the list belongs to
3840 * a message that has been fully retrieved.
3842 #if 0 /* no longer in use. delete in 2007.10 */
3844 has_retrieved_msgs (TnyList *list)
3847 gboolean found = FALSE;
3849 iter = tny_list_create_iterator (list);
3850 while (!tny_iterator_is_done (iter) && !found) {
3852 TnyHeaderFlags flags = 0;
3854 header = TNY_HEADER (tny_iterator_get_current (iter));
3856 flags = tny_header_get_flags (header);
3857 if (flags & TNY_HEADER_FLAG_CACHED)
3858 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3861 g_object_unref (header);
3865 tny_iterator_next (iter);
3867 g_object_unref (iter);
3875 * Shows a confirmation dialog to the user when we're moving messages
3876 * from a remote server to the local storage. Returns the dialog
3877 * response. If it's other kind of movement then it always returns
3880 * This one is used by the next functions:
3881 * modest_ui_actions_on_paste - commented out
3882 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3885 modest_ui_actions_msgs_move_to_confirmation (GtkWindow *win,
3886 TnyFolder *dest_folder,
3890 gint response = GTK_RESPONSE_OK;
3892 /* return with OK if the destination is a remote folder */
3893 if (modest_tny_folder_is_remote_folder (dest_folder))
3894 return GTK_RESPONSE_OK;
3896 TnyFolder *src_folder = NULL;
3897 TnyIterator *iter = NULL;
3898 TnyHeader *header = NULL;
3900 /* Get source folder */
3901 iter = tny_list_create_iterator (headers);
3902 header = TNY_HEADER (tny_iterator_get_current (iter));
3904 src_folder = tny_header_get_folder (header);
3905 g_object_unref (header);
3907 g_object_unref (iter);
3909 /* if no src_folder, message may be an attahcment */
3910 if (src_folder == NULL)
3911 return GTK_RESPONSE_CANCEL;
3913 /* If the source is a local or MMC folder */
3914 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3915 g_object_unref (src_folder);
3916 return GTK_RESPONSE_OK;
3918 g_object_unref (src_folder);
3920 /* now if offline we ask the user */
3921 if(connect_to_get_msg( GTK_WINDOW (win),
3922 tny_list_get_length (headers)))
3923 response = GTK_RESPONSE_OK;
3925 response = GTK_RESPONSE_CANCEL;
3933 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3935 MoveToHelper *helper = (MoveToHelper *) user_data;
3937 /* Note that the operation could have failed, in that case do
3939 if (modest_mail_operation_get_status (mail_op) ==
3940 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
3942 GObject *object = modest_mail_operation_get_source (mail_op);
3943 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3944 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
3946 if (!modest_msg_view_window_select_next_message (self))
3947 if (!modest_msg_view_window_select_previous_message (self))
3948 /* No more messages to view, so close this window */
3949 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3950 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
3951 GtkWidget *header_view;
3953 GtkTreeSelection *sel;
3955 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
3956 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3957 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
3958 path = gtk_tree_row_reference_get_path (helper->reference);
3959 gtk_tree_selection_select_path (sel, path);
3960 gtk_tree_path_free (path);
3962 g_object_unref (object);
3965 /* Close the "Pasting" information banner */
3966 gtk_widget_destroy (GTK_WIDGET(helper->banner));
3967 if (helper->reference != NULL)
3968 gtk_tree_row_reference_free (helper->reference);
3973 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3976 ModestWindow *main_window = NULL;
3977 GtkWidget *folder_view = NULL;
3978 GObject *win = modest_mail_operation_get_source (mail_op);
3979 const GError *error = NULL;
3980 const gchar *message = NULL;
3982 /* Get error message */
3983 error = modest_mail_operation_get_error (mail_op);
3984 if (error != NULL && error->message != NULL) {
3985 message = error->message;
3987 message = _("mail_in_ui_folder_move_target_error");
3990 /* Disable next automatic folder selection */
3991 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
3992 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
3993 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3994 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
3996 if (user_data && TNY_IS_FOLDER (user_data)) {
3997 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3998 TNY_FOLDER (user_data), FALSE);
4001 /* Show notification dialog */
4002 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
4003 g_object_unref (win);
4007 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
4010 GObject *win = modest_mail_operation_get_source (mail_op);
4011 const GError *error = modest_mail_operation_get_error (mail_op);
4013 g_return_if_fail (error != NULL);
4014 if (error->message != NULL)
4015 g_printerr ("modest: %s\n", error->message);
4017 g_printerr ("modest: unkonw error on send&receive operation");
4019 /* Show error message */
4020 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
4021 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4022 /* _CS("sfil_ib_unable_to_receive")); */
4024 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4025 /* _CS("sfil_ib_unable_to_send")); */
4026 g_object_unref (win);
4030 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4037 gint pending_purges = 0;
4038 gboolean some_purged = FALSE;
4039 ModestWindow *win = MODEST_WINDOW (user_data);
4040 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4042 /* If there was any error */
4043 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4044 modest_window_mgr_unregister_header (mgr, header);
4048 /* Once the message has been retrieved for purging, we check if
4049 * it's all ok for purging */
4051 parts = tny_simple_list_new ();
4052 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4053 iter = tny_list_create_iterator (parts);
4055 while (!tny_iterator_is_done (iter)) {
4057 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4058 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4059 if (tny_mime_part_is_purged (part))
4066 g_object_unref (part);
4068 tny_iterator_next (iter);
4070 g_object_unref (iter);
4073 if (pending_purges>0) {
4075 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4077 if (response == GTK_RESPONSE_OK) {
4078 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4079 iter = tny_list_create_iterator (parts);
4080 while (!tny_iterator_is_done (iter)) {
4083 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4084 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4085 tny_mime_part_set_purged (part);
4088 g_object_unref (part);
4090 tny_iterator_next (iter);
4093 tny_msg_rewrite_cache (msg);
4096 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4098 g_object_unref (iter);
4100 modest_window_mgr_unregister_header (mgr, header);
4102 g_object_unref (parts);
4106 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4107 ModestMainWindow *win)
4109 GtkWidget *header_view;
4110 TnyList *header_list;
4113 TnyHeaderFlags flags;
4114 ModestWindow *msg_view_window = NULL;
4117 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4119 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4120 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4122 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4124 if (tny_list_get_length (header_list) == 1) {
4125 iter = tny_list_create_iterator (header_list);
4126 header = TNY_HEADER (tny_iterator_get_current (iter));
4127 g_object_unref (iter);
4132 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4133 header, &msg_view_window);
4134 flags = tny_header_get_flags (header);
4135 if (!(flags & TNY_HEADER_FLAG_CACHED))
4138 if (msg_view_window != NULL)
4139 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4141 /* do nothing; uid was registered before, so window is probably on it's way */
4142 g_warning ("debug: header %p has already been registered", header);
4145 ModestMailOperation *mail_op = NULL;
4146 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4147 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4149 modest_ui_actions_get_msgs_full_error_handler,
4151 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4152 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4154 g_object_unref (mail_op);
4157 g_object_unref (header);
4159 g_object_unref (header_list);
4163 * Utility function that transfer messages from both the main window
4164 * and the msg view window when using the "Move to" dialog
4167 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4170 TnyList *headers = NULL;
4171 TnyAccount *dst_account = NULL;
4172 const gchar *proto_str = NULL;
4173 gboolean dst_is_pop = FALSE;
4175 if (!TNY_IS_FOLDER (dst_folder)) {
4176 modest_platform_information_banner (GTK_WIDGET (win),
4178 _CS("ckdg_ib_unable_to_move_to_current_location"));
4182 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4183 proto_str = tny_account_get_proto (dst_account);
4185 /* tinymail will return NULL for local folders it seems */
4186 dst_is_pop = proto_str &&
4187 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4188 MODEST_PROTOCOL_STORE_POP);
4190 g_object_unref (dst_account);
4192 /* Get selected headers */
4193 headers = get_selected_headers (MODEST_WINDOW (win));
4196 modest_platform_information_banner (GTK_WIDGET (win),
4198 ngettext("mail_in_ui_folder_move_target_error",
4199 "mail_in_ui_folder_move_targets_error",
4200 tny_list_get_length (headers)));
4201 g_object_unref (headers);
4205 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4206 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4207 _CS("ckct_nw_pasting"));
4208 if (helper->banner != NULL) {
4209 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4210 gtk_widget_show (GTK_WIDGET(helper->banner));
4213 if (MODEST_IS_MAIN_WINDOW (win)) {
4214 GtkWidget *header_view =
4215 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4216 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4217 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4220 ModestMailOperation *mail_op =
4221 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4223 modest_ui_actions_move_folder_error_handler,
4225 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4228 modest_mail_operation_xfer_msgs (mail_op,
4230 TNY_FOLDER (dst_folder),
4235 g_object_unref (G_OBJECT (mail_op));
4236 g_object_unref (headers);
4240 * UI handler for the "Move to" action when invoked from the
4244 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4245 GtkWidget *folder_view,
4246 TnyFolderStore *dst_folder,
4247 ModestMainWindow *win)
4249 ModestHeaderView *header_view = NULL;
4250 ModestMailOperation *mail_op = NULL;
4251 TnyFolderStore *src_folder;
4252 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4254 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4256 /* Get the source folder */
4257 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4259 /* Get header view */
4260 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4262 /* Get folder or messages to transfer */
4263 if (gtk_widget_is_focus (folder_view)) {
4264 GtkTreeSelection *sel;
4265 gboolean do_xfer = TRUE;
4267 /* Allow only to transfer folders to the local root folder */
4268 if (TNY_IS_ACCOUNT (dst_folder) &&
4269 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4271 } else if (!TNY_IS_FOLDER (src_folder)) {
4272 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4274 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4275 guint num_headers = tny_folder_get_all_count(TNY_FOLDER(src_folder));
4276 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4282 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4283 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4284 _CS("ckct_nw_pasting"));
4285 if (helper->banner != NULL) {
4286 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4287 gtk_widget_show (GTK_WIDGET(helper->banner));
4289 /* Clean folder on header view before moving it */
4290 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4291 gtk_tree_selection_unselect_all (sel);
4294 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4296 modest_ui_actions_move_folder_error_handler,
4298 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4301 /* Select *after* the changes */
4302 /* TODO: this function hangs UI after transfer */
4303 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4304 /* TNY_FOLDER (src_folder), TRUE); */
4306 modest_mail_operation_xfer_folder (mail_op,
4307 TNY_FOLDER (src_folder),
4312 /* Unref mail operation */
4313 g_object_unref (G_OBJECT (mail_op));
4315 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4316 gboolean do_xfer = TRUE;
4317 /* Ask for confirmation if the source folder is remote and we're not connected */
4318 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4319 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4320 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4321 guint num_headers = tny_list_get_length(headers);
4322 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4326 g_object_unref(headers);
4328 if (do_xfer) /* Transfer messages */
4329 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4333 g_object_unref (src_folder);
4338 * UI handler for the "Move to" action when invoked from the
4339 * ModestMsgViewWindow
4342 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4343 TnyFolderStore *dst_folder,
4344 ModestMsgViewWindow *win)
4346 TnyHeader *header = NULL;
4347 TnyFolderStore *src_folder;
4349 /* Create header list */
4350 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4351 src_folder = TNY_FOLDER_STORE(tny_header_get_folder(header));
4352 g_object_unref (header);
4354 /* Transfer the message if online or confirmed by the user */
4355 if (tny_device_is_online (modest_runtime_get_device()) || remote_folder_is_pop(src_folder) ||
4356 (modest_platform_is_network_folderstore(src_folder) && connect_to_get_msg(GTK_WINDOW(win), 1))) {
4357 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4360 g_object_unref (src_folder);
4364 modest_ui_actions_on_move_to (GtkAction *action,
4367 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4369 TnyFolderStore *dst_folder = NULL;
4370 ModestMainWindow *main_window;
4372 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4373 MODEST_IS_MSG_VIEW_WINDOW (win));
4375 /* Get the main window if exists */
4376 if (MODEST_IS_MAIN_WINDOW (win))
4377 main_window = MODEST_MAIN_WINDOW (win);
4380 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4382 /* Get the folder view widget if exists */
4384 folder_view = modest_main_window_get_child_widget (main_window,
4385 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4389 /* Create and run the dialog */
4390 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4391 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4392 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4393 result = gtk_dialog_run (GTK_DIALOG(dialog));
4394 g_object_ref (tree_view);
4395 gtk_widget_destroy (dialog);
4397 if (result != GTK_RESPONSE_ACCEPT)
4400 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4401 /* Do window specific stuff */
4402 if (MODEST_IS_MAIN_WINDOW (win)) {
4403 modest_ui_actions_on_main_window_move_to (action,
4406 MODEST_MAIN_WINDOW (win));
4408 modest_ui_actions_on_msg_view_window_move_to (action,
4410 MODEST_MSG_VIEW_WINDOW (win));
4414 g_object_unref (dst_folder);
4418 * Calls #HeadersFunc for each header already selected in the main
4419 * window or the message currently being shown in the msg view window
4422 do_headers_action (ModestWindow *win,
4426 TnyList *headers_list = NULL;
4427 TnyIterator *iter = NULL;
4428 TnyHeader *header = NULL;
4429 TnyFolder *folder = NULL;
4432 headers_list = get_selected_headers (win);
4436 /* Get the folder */
4437 iter = tny_list_create_iterator (headers_list);
4438 header = TNY_HEADER (tny_iterator_get_current (iter));
4440 folder = tny_header_get_folder (header);
4441 g_object_unref (header);
4444 /* Call the function for each header */
4445 while (!tny_iterator_is_done (iter)) {
4446 header = TNY_HEADER (tny_iterator_get_current (iter));
4447 func (header, win, user_data);
4448 g_object_unref (header);
4449 tny_iterator_next (iter);
4452 /* Trick: do a poke status in order to speed up the signaling
4454 tny_folder_poke_status (folder);
4457 g_object_unref (folder);
4458 g_object_unref (iter);
4459 g_object_unref (headers_list);
4463 modest_ui_actions_view_attachment (GtkAction *action,
4464 ModestWindow *window)
4466 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4467 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4469 /* not supported window for this action */
4470 g_return_if_reached ();
4475 modest_ui_actions_save_attachments (GtkAction *action,
4476 ModestWindow *window)
4478 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4479 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4481 /* not supported window for this action */
4482 g_return_if_reached ();
4487 modest_ui_actions_remove_attachments (GtkAction *action,
4488 ModestWindow *window)
4490 if (MODEST_IS_MAIN_WINDOW (window)) {
4491 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4492 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4493 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4495 /* not supported window for this action */
4496 g_return_if_reached ();
4501 modest_ui_actions_on_settings (GtkAction *action,
4506 dialog = modest_platform_get_global_settings_dialog ();
4507 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4508 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4509 gtk_widget_show_all (dialog);
4511 gtk_dialog_run (GTK_DIALOG (dialog));
4513 gtk_widget_destroy (dialog);
4517 modest_ui_actions_on_help (GtkAction *action,
4520 const gchar *help_id = NULL;
4522 if (MODEST_IS_MAIN_WINDOW (win)) {
4523 GtkWidget *folder_view;
4524 TnyFolderStore *folder_store;
4526 /* Get selected folder */
4527 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4528 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4529 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4531 /* Switch help_id */
4532 if (TNY_IS_FOLDER (folder_store)) {
4533 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4534 case TNY_FOLDER_TYPE_NORMAL:
4535 help_id = "applications_email_managefolders";
4537 case TNY_FOLDER_TYPE_INBOX:
4538 help_id = "applications_email_inbox";
4540 case TNY_FOLDER_TYPE_OUTBOX:
4541 help_id = "applications_email_outbox";
4543 case TNY_FOLDER_TYPE_SENT:
4544 help_id = "applications_email_sent";
4546 case TNY_FOLDER_TYPE_DRAFTS:
4547 help_id = "applications_email_drafts";
4549 case TNY_FOLDER_TYPE_ARCHIVE:
4550 help_id = "applications_email_managefolders";
4553 help_id = "applications_email_managefolders";
4556 help_id = "applications_email_mainview";
4558 g_object_unref (folder_store);
4559 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4560 help_id = "applications_email_viewer";
4561 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4562 help_id = "applications_email_editor";
4564 modest_platform_show_help (GTK_WINDOW (win), help_id);
4568 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4569 ModestWindow *window)
4571 ModestMailOperation *mail_op;
4575 headers = get_selected_headers (window);
4579 /* Create mail operation */
4580 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4582 modest_ui_actions_get_msgs_full_error_handler,
4584 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4585 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4588 g_object_unref (headers);
4589 g_object_unref (mail_op);
4593 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4594 ModestWindow *window)
4596 g_return_if_fail (MODEST_IS_WINDOW (window));
4599 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4603 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4604 ModestWindow *window)
4606 g_return_if_fail (MODEST_IS_WINDOW (window));
4609 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4613 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4614 ModestWindow *window)
4616 g_return_if_fail (MODEST_IS_WINDOW (window));
4619 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4623 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4624 ModestWindow *window)
4626 g_return_if_fail (MODEST_IS_WINDOW (window));
4629 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4633 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4634 ModestWindow *window)
4636 g_return_if_fail (MODEST_IS_WINDOW (window));
4639 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4643 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4644 ModestWindow *window)
4646 g_return_if_fail (MODEST_IS_WINDOW (window));
4649 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4653 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4654 ModestWindow *window)
4656 g_return_if_fail (MODEST_IS_WINDOW (window));
4659 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4663 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4664 ModestWindow *window)
4666 g_return_if_fail (MODEST_IS_WINDOW (window));
4669 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4673 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4674 ModestWindow *window)
4676 g_return_if_fail (MODEST_IS_WINDOW (window));
4679 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4683 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4685 g_return_if_fail (MODEST_IS_WINDOW (window));
4688 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4692 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4694 g_return_if_fail (MODEST_IS_WINDOW (window));
4696 modest_platform_show_search_messages (GTK_WINDOW (window));
4700 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4702 g_return_if_fail (MODEST_IS_WINDOW (win));
4703 modest_platform_show_addressbook (GTK_WINDOW (win));
4708 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4709 ModestWindow *window)
4711 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4713 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4717 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4718 ModestMailOperationState *state,
4721 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4723 /* Set send/receive operation finished */
4724 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4725 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
4731 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4737 const gchar* server_name = NULL;
4738 TnyTransportAccount *server_account;
4739 gchar *message = NULL;
4741 /* Don't show anything if the user cancelled something */
4742 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4745 /* Get the server name: */
4747 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4748 if (server_account) {
4749 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4751 g_object_unref (server_account);
4752 server_account = NULL;
4755 g_return_if_fail (server_name);
4757 /* Show the appropriate message text for the GError: */
4758 switch (err->code) {
4759 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4760 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4762 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4763 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4765 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4766 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4768 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4769 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4772 g_return_if_reached ();
4775 /* TODO if the username or the password where not defined we
4776 should show the Accounts Settings dialog or the Connection
4777 specific SMTP server window */
4779 modest_platform_run_information_dialog (NULL, message);
4784 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4789 ModestMainWindow *main_window = NULL;
4790 ModestWindowMgr *mgr = NULL;
4791 GtkWidget *folder_view = NULL, *header_view = NULL;
4792 TnyFolderStore *selected_folder = NULL;
4793 TnyFolderType folder_type;
4795 mgr = modest_runtime_get_window_mgr ();
4796 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4801 /* Check if selected folder is OUTBOX */
4802 folder_view = modest_main_window_get_child_widget (main_window,
4803 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4804 header_view = modest_main_window_get_child_widget (main_window,
4805 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4807 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4808 if (!TNY_IS_FOLDER (selected_folder))
4811 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4812 #if GTK_CHECK_VERSION(2, 8, 0)
4813 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4814 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4815 GtkTreeViewColumn *tree_column;
4817 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4818 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4819 gtk_tree_view_column_queue_resize (tree_column);
4822 gtk_widget_queue_draw (header_view);
4827 if (selected_folder != NULL)
4828 g_object_unref (selected_folder);