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"
48 #ifdef MODEST_PLATFORM_MAEMO
49 #include "maemo/modest-osso-state-saving.h"
50 #endif /* MODEST_PLATFORM_MAEMO */
52 #include "widgets/modest-ui-constants.h"
53 #include <widgets/modest-main-window.h>
54 #include <widgets/modest-msg-view-window.h>
55 #include <widgets/modest-account-view-window.h>
56 #include <widgets/modest-details-dialog.h>
57 #include <widgets/modest-attachments-view.h>
58 #include "widgets/modest-global-settings-dialog.h"
59 #include "modest-connection-specific-smtp-window.h"
60 #include "modest-account-mgr-helpers.h"
61 #include "modest-mail-operation.h"
62 #include "modest-text-utils.h"
64 #ifdef MODEST_HAVE_EASYSETUP
65 #include "easysetup/modest-easysetup-wizard.h"
66 #endif /* MODEST_HAVE_EASYSETUP */
68 #include <modest-widget-memory.h>
69 #include <tny-error.h>
70 #include <tny-simple-list.h>
71 #include <tny-msg-view.h>
72 #include <tny-device.h>
73 #include <tny-merge-folder.h>
75 typedef struct _GetMsgAsyncHelper {
77 ModestMailOperation *mail_op;
84 typedef enum _ReplyForwardAction {
90 typedef struct _ReplyForwardHelper {
91 guint reply_forward_type;
92 ReplyForwardAction action;
94 GtkWidget *parent_window;
98 * The do_headers_action uses this kind of functions to perform some
99 * action to each member of a list of headers
101 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
104 do_headers_action (ModestWindow *win,
109 static void open_msg_cb (ModestMailOperation *mail_op,
114 static void reply_forward_cb (ModestMailOperation *mail_op,
119 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
121 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
124 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
125 ModestMailOperationState *state,
131 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
134 const gchar *authors[] = {
135 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
138 about = gtk_about_dialog_new ();
139 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
140 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
141 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
142 _("Copyright (c) 2006, Nokia Corporation\n"
143 "All rights reserved."));
144 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
145 _("a modest e-mail client\n\n"
146 "design and implementation: Dirk-Jan C. Binnema\n"
147 "contributions from the fine people at KC and Ig\n"
148 "uses the tinymail email framework written by Philip van Hoof"));
149 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
150 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
152 gtk_dialog_run (GTK_DIALOG (about));
153 gtk_widget_destroy(about);
157 * Gets the list of currently selected messages. If the win is the
158 * main window, then it returns a newly allocated list of the headers
159 * selected in the header view. If win is the msg view window, then
160 * the value returned is a list with just a single header.
162 * The caller of this funcion must free the list.
165 get_selected_headers (ModestWindow *win)
167 if (MODEST_IS_MAIN_WINDOW(win)) {
168 GtkWidget *header_view;
170 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
171 MODEST_WIDGET_TYPE_HEADER_VIEW);
172 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
174 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
175 /* for MsgViewWindows, we simply return a list with one element */
177 TnyList *list = NULL;
179 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
180 if (header != NULL) {
181 list = tny_simple_list_new ();
182 tny_list_prepend (list, G_OBJECT(header));
183 g_object_unref (G_OBJECT(header));
193 headers_action_mark_as_read (TnyHeader *header,
197 TnyHeaderFlags flags;
199 g_return_if_fail (TNY_IS_HEADER(header));
201 flags = tny_header_get_flags (header);
202 if (flags & TNY_HEADER_FLAG_SEEN) return;
203 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
207 headers_action_mark_as_unread (TnyHeader *header,
211 TnyHeaderFlags flags;
213 g_return_if_fail (TNY_IS_HEADER(header));
215 flags = tny_header_get_flags (header);
216 if (flags & TNY_HEADER_FLAG_SEEN) {
217 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
223 headers_action_delete (TnyHeader *header,
227 ModestMailOperation *mail_op = NULL;
229 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
230 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
233 /* Always delete. TODO: Move to trash still not supported */
234 modest_mail_operation_remove_msg (mail_op, header, FALSE);
235 g_object_unref (G_OBJECT (mail_op));
239 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
241 TnyList *header_list = NULL;
242 TnyIterator *iter = NULL;
243 TnyHeader *header = NULL;
244 gchar *message = NULL;
248 ModestWindowMgr *mgr;
250 g_return_if_fail (MODEST_IS_WINDOW(win));
252 header_list = get_selected_headers (win);
253 if (!header_list) return;
255 /* Check if any of the headers is already opened */
256 iter = tny_list_create_iterator (header_list);
258 mgr = modest_runtime_get_window_mgr ();
259 while (!tny_iterator_is_done (iter) && !found) {
260 header = TNY_HEADER (tny_iterator_get_current (iter));
261 if (modest_window_mgr_find_window_by_header (mgr, header))
263 g_object_unref (header);
264 tny_iterator_next (iter);
266 g_object_unref (iter);
271 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
272 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
274 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
278 g_object_unref (header_list);
283 if (tny_list_get_length(header_list) > 1)
284 message = g_strdup(_("emev_nc_delete_messages"));
286 iter = tny_list_create_iterator (header_list);
287 header = TNY_HEADER (tny_iterator_get_current (iter));
288 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
289 message = g_strdup_printf(_("emev_nc_delete_message"), desc);
290 g_object_unref (header);
291 g_object_unref (iter);
294 /* Confirmation dialog */
295 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
299 if (response == GTK_RESPONSE_OK) {
300 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
302 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
306 /* Remove each header */
307 do_headers_action (win, headers_action_delete, NULL);
309 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
310 gtk_widget_destroy (GTK_WIDGET(win));
317 g_object_unref (header_list);
322 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
324 #ifdef MODEST_PLATFORM_MAEMO
325 modest_osso_save_state();
326 #endif /* MODEST_PLATFORM_MAEMO */
332 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
334 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
335 gtk_widget_destroy (GTK_WIDGET (win));
336 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
338 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
339 } else if (MODEST_IS_WINDOW (win)) {
340 gtk_widget_destroy (GTK_WIDGET (win));
342 g_return_if_reached ();
347 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
349 GtkClipboard *clipboard = NULL;
350 gchar *selection = NULL;
352 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
353 selection = gtk_clipboard_wait_for_text (clipboard);
355 /* Question: why is the clipboard being used here?
356 * It doesn't really make a lot of sense. */
360 modest_address_book_add_address (selection);
366 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
368 /* This is currently only implemented for Maemo,
369 * because it requires a providers preset file which is not publically available.
371 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
372 gboolean accounts_exist = modest_account_mgr_has_accounts(
373 modest_runtime_get_account_mgr(), TRUE);
375 if (!accounts_exist) {
376 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
377 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
378 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
379 gtk_dialog_run (GTK_DIALOG (wizard));
380 gtk_widget_destroy (GTK_WIDGET (wizard));
382 /* Show the list of accounts: */
383 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
384 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
385 gtk_dialog_run (account_win);
386 gtk_widget_destroy (GTK_WIDGET(account_win));
389 GtkWidget *dialog, *label;
391 /* Create the widgets */
393 dialog = gtk_dialog_new_with_buttons ("Message",
395 GTK_DIALOG_DESTROY_WITH_PARENT,
399 label = gtk_label_new ("Hello World!");
401 /* Ensure that the dialog box is destroyed when the user responds. */
403 g_signal_connect_swapped (dialog, "response",
404 G_CALLBACK (gtk_widget_destroy),
407 /* Add the label, and show everything we've added to the dialog. */
409 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
411 gtk_widget_show_all (dialog);
412 #endif /* MODEST_PLATFORM_MAEMO */
416 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
418 ModestWindow *main_window = MODEST_WINDOW (user_data);
420 /* Save any changes. */
421 modest_connection_specific_smtp_window_save_server_accounts (
422 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
423 modest_window_get_active_account (main_window));
424 gtk_widget_destroy (GTK_WIDGET (window));
428 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
430 /* This is currently only implemented for Maemo,
431 * because it requires an API (libconic) to detect different connection
434 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
436 /* Create the window if necessary: */
437 const gchar *active_account_name = modest_window_get_active_account (win);
439 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
440 * or show the default account?
441 * If we show the default account then the account name should be shown in
442 * the window when we show it. */
443 if (!active_account_name) {
444 g_warning ("%s: No account is active.", __FUNCTION__);
448 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
449 modest_connection_specific_smtp_window_fill_with_connections (
450 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
451 modest_runtime_get_account_mgr(),
452 active_account_name);
454 /* Show the window: */
455 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
456 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
457 gtk_widget_show (specific_window);
459 /* Save changes when the window is hidden: */
460 g_signal_connect (specific_window, "hide",
461 G_CALLBACK (on_smtp_servers_window_hide), win);
462 #endif /* MODEST_PLATFORM_MAEMO */
466 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
468 ModestWindow *msg_win;
470 TnyFolder *folder = NULL;
471 gchar *account_name = NULL;
472 gchar *from_str = NULL;
473 /* GError *err = NULL; */
474 TnyAccount *account = NULL;
475 ModestWindowMgr *mgr;
476 gchar *signature = NULL, *blank_and_signature = NULL;
478 account_name = g_strdup(modest_window_get_active_account (win));
480 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
482 g_printerr ("modest: no account found\n");
486 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
488 TNY_ACCOUNT_TYPE_STORE);
490 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
494 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
496 g_printerr ("modest: failed get from string for '%s'\n", account_name);
500 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
501 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
502 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
503 MODEST_ACCOUNT_SIGNATURE, FALSE);
504 blank_and_signature = g_strconcat ("\n", signature, NULL);
507 blank_and_signature = g_strdup ("");
510 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
512 g_printerr ("modest: failed to create new msg\n");
516 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
518 g_printerr ("modest: failed to find Drafts folder\n");
522 /* tny_folder_add_msg (folder, msg, &err); */
524 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
526 /* g_error_free (err); */
530 /* Create and register edit window */
531 /* This is destroyed by TOOD. */
532 msg_win = modest_msg_edit_window_new (msg, account_name);
533 mgr = modest_runtime_get_window_mgr ();
534 modest_window_mgr_register_window (mgr, msg_win);
537 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
539 gtk_widget_show_all (GTK_WIDGET (msg_win));
542 g_free (account_name);
544 g_free (blank_and_signature);
546 g_object_unref (G_OBJECT(account));
548 g_object_unref (G_OBJECT(msg));
550 g_object_unref (G_OBJECT(folder));
554 open_msg_cb (ModestMailOperation *mail_op,
559 ModestWindowMgr *mgr = NULL;
560 ModestWindow *parent_win = NULL;
561 ModestWindow *win = NULL;
562 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
563 gchar *account = NULL;
566 /* TODO: Show an error? (review the specs) */
570 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
571 folder = tny_header_get_folder (header);
573 /* Mark header as read */
574 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
577 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
579 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
581 /* Gets folder type (OUTBOX headers will be opened in edit window */
582 if (modest_tny_folder_is_local_folder (folder))
583 folder_type = modest_tny_folder_get_local_folder_type (folder);
585 /* If the header is in the drafts folder then open the editor,
586 else the message view window */
587 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
588 win = modest_msg_edit_window_new (msg, account);
590 gchar *uid = modest_tny_folder_get_header_unique_id (header);
592 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
593 GtkWidget *header_view;
594 GtkTreeSelection *sel;
595 GList *sel_list = NULL;
598 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
599 MODEST_WIDGET_TYPE_HEADER_VIEW);
601 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
602 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
604 if (sel_list != NULL) {
605 GtkTreeRowReference *row_reference;
607 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
608 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
609 g_list_free (sel_list);
611 win = modest_msg_view_window_new_with_header_model (msg,
616 gtk_tree_row_reference_free (row_reference);
618 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
621 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
626 /* Register and show new window */
628 mgr = modest_runtime_get_window_mgr ();
629 modest_window_mgr_register_window (mgr, win);
630 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
631 gtk_widget_show_all (GTK_WIDGET(win));
636 g_object_unref (msg);
637 g_object_unref (folder);
638 g_object_unref (header);
642 * This function is the error handler of the
643 * modest_mail_operation_get_msgs_full operation
646 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
651 error = modest_mail_operation_get_error (mail_op);
652 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
653 GObject *win = modest_mail_operation_get_source (mail_op);
655 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
661 * This function is used by both modest_ui_actions_on_open and
662 * modest_ui_actions_on_header_activated. This way we always do the
663 * same when trying to open messages.
666 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
668 ModestWindowMgr *mgr;
670 ModestMailOperation *mail_op;
672 /* Look if we already have a message view for each header. If
673 true, then remove the header from the list of headers to
675 mgr = modest_runtime_get_window_mgr ();
676 iter = tny_list_create_iterator (headers);
677 while (!tny_iterator_is_done (iter)) {
678 ModestWindow *window;
681 header = TNY_HEADER (tny_iterator_get_current (iter));
682 window = modest_window_mgr_find_window_by_header (mgr, header);
684 /* Do not open again the message and present
685 the window to the user */
686 tny_list_remove (headers, G_OBJECT (header));
687 gtk_window_present (GTK_WINDOW (window));
690 g_object_unref (header);
691 tny_iterator_next (iter);
695 /* Open each message */
696 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
698 modest_ui_actions_get_msgs_full_error_handler,
700 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
701 modest_mail_operation_get_msgs_full (mail_op,
707 g_object_unref (iter);
708 g_object_unref(mail_op);
712 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
717 headers = get_selected_headers (win);
722 _modest_ui_actions_open (headers, win);
724 g_object_unref(headers);
729 free_reply_forward_helper (gpointer data)
731 ReplyForwardHelper *helper;
733 helper = (ReplyForwardHelper *) data;
734 g_free (helper->account_name);
735 g_slice_free (ReplyForwardHelper, helper);
739 reply_forward_cb (ModestMailOperation *mail_op,
745 ReplyForwardHelper *rf_helper;
746 ModestWindow *msg_win;
747 ModestEditType edit_type;
749 TnyAccount *account = NULL;
750 ModestWindowMgr *mgr;
751 gchar *signature = NULL;
753 g_return_if_fail (user_data != NULL);
754 rf_helper = (ReplyForwardHelper *) user_data;
756 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
757 rf_helper->account_name);
758 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
759 rf_helper->account_name,
760 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
761 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
762 rf_helper->account_name,
763 MODEST_ACCOUNT_SIGNATURE, FALSE);
766 /* Create reply mail */
767 switch (rf_helper->action) {
770 modest_tny_msg_create_reply_msg (msg, from, signature,
771 rf_helper->reply_forward_type,
772 MODEST_TNY_MSG_REPLY_MODE_SENDER);
774 case ACTION_REPLY_TO_ALL:
776 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
777 MODEST_TNY_MSG_REPLY_MODE_ALL);
778 edit_type = MODEST_EDIT_TYPE_REPLY;
782 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
783 edit_type = MODEST_EDIT_TYPE_FORWARD;
786 g_return_if_reached ();
793 g_printerr ("modest: failed to create message\n");
797 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
798 rf_helper->account_name,
799 TNY_ACCOUNT_TYPE_STORE);
801 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
805 /* Create and register the windows */
806 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
807 mgr = modest_runtime_get_window_mgr ();
808 modest_window_mgr_register_window (mgr, msg_win);
810 if (rf_helper->parent_window != NULL) {
813 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
814 modest_window_set_zoom (msg_win, parent_zoom);
817 /* Show edit window */
818 gtk_widget_show_all (GTK_WIDGET (msg_win));
822 g_object_unref (G_OBJECT (new_msg));
824 g_object_unref (G_OBJECT (account));
825 g_object_unref (msg);
826 g_object_unref (header);
830 * Checks a list of headers. If any of them are not currently
831 * downloaded (CACHED) then it asks the user for permission to
834 * Returns FALSE if the user does not want to download the
835 * messages. Returns TRUE if the user allowed the download or if all
836 * of them are currently downloaded
839 download_uncached_messages (TnyList *header_list, GtkWindow *win)
842 gboolean found, retval;
844 iter = tny_list_create_iterator (header_list);
846 while (!tny_iterator_is_done (iter) && !found) {
848 TnyHeaderFlags flags;
850 header = TNY_HEADER (tny_iterator_get_current (iter));
851 flags = tny_header_get_flags (header);
852 /* TODO: is this the right flag?, it seems that some
853 headers that have been previously downloaded do not
855 found = !(flags & TNY_HEADER_FLAG_CACHED);
856 g_object_unref (header);
857 tny_iterator_next (iter);
859 g_object_unref (iter);
861 /* Ask for user permission to download the messages */
864 GtkResponseType response;
866 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
867 _("mcen_nc_get_multi_msg_txt"));
868 if (response == GTK_RESPONSE_CANCEL)
876 * Common code for the reply and forward actions
879 reply_forward (ReplyForwardAction action, ModestWindow *win)
881 ModestMailOperation *mail_op = NULL;
882 TnyList *header_list = NULL;
883 ReplyForwardHelper *rf_helper = NULL;
884 guint reply_forward_type;
885 gboolean continue_download;
887 g_return_if_fail (MODEST_IS_WINDOW(win));
889 header_list = get_selected_headers (win);
893 /* Check that the messages have been previously downloaded */
894 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
895 if (!continue_download) {
896 g_object_unref (header_list);
901 modest_conf_get_int (modest_runtime_get_conf (),
902 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
904 /* We assume that we can only select messages of the
905 same folder and that we reply all of them from the
906 same account. In fact the interface currently only
907 allows single selection */
910 rf_helper = g_slice_new0 (ReplyForwardHelper);
911 rf_helper->reply_forward_type = reply_forward_type;
912 rf_helper->action = action;
913 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
914 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
915 rf_helper->parent_window = GTK_WIDGET (win);
916 if (!rf_helper->account_name)
917 rf_helper->account_name =
918 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
920 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
923 /* Get header and message. Do not free them here, the
924 reply_forward_cb must do it */
925 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
926 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
927 if (!msg || !header) {
929 g_object_unref (msg);
931 g_object_unref (header);
932 g_printerr ("modest: no message found\n");
935 reply_forward_cb (NULL, header, msg, rf_helper);
937 /* Retrieve messages */
938 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
940 modest_ui_actions_get_msgs_full_error_handler,
942 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
943 modest_mail_operation_get_msgs_full (mail_op,
947 free_reply_forward_helper);
950 g_object_unref(mail_op);
954 g_object_unref (header_list);
958 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
960 g_return_if_fail (MODEST_IS_WINDOW(win));
962 reply_forward (ACTION_REPLY, win);
966 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
968 g_return_if_fail (MODEST_IS_WINDOW(win));
970 reply_forward (ACTION_FORWARD, win);
974 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
976 g_return_if_fail (MODEST_IS_WINDOW(win));
978 reply_forward (ACTION_REPLY_TO_ALL, win);
982 modest_ui_actions_on_next (GtkAction *action,
983 ModestWindow *window)
985 if (MODEST_IS_MAIN_WINDOW (window)) {
986 GtkWidget *header_view;
988 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
989 MODEST_WIDGET_TYPE_HEADER_VIEW);
993 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
994 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
995 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
997 g_return_if_reached ();
1002 modest_ui_actions_on_prev (GtkAction *action,
1003 ModestWindow *window)
1005 g_return_if_fail (MODEST_IS_WINDOW(window));
1007 if (MODEST_IS_MAIN_WINDOW (window)) {
1008 GtkWidget *header_view;
1009 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1010 MODEST_WIDGET_TYPE_HEADER_VIEW);
1014 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1015 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1016 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1018 g_return_if_reached ();
1023 modest_ui_actions_on_sort (GtkAction *action,
1024 ModestWindow *window)
1026 g_return_if_fail (MODEST_IS_WINDOW(window));
1028 if (MODEST_IS_MAIN_WINDOW (window)) {
1029 GtkWidget *header_view;
1030 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1031 MODEST_WIDGET_TYPE_HEADER_VIEW);
1035 /* Show sorting dialog */
1036 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1041 * This function performs the send & receive required actions. The
1042 * window is used to create the mail operation. Typically it should
1043 * always be the main window, but we pass it as argument in order to
1047 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1049 gchar *acc_name = NULL;
1050 ModestMailOperation *mail_op;
1052 /* If no account name was provided then get the current account, and if
1053 there is no current account then pick the default one: */
1054 if (!account_name) {
1055 acc_name = g_strdup (modest_window_get_active_account(win));
1057 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1059 g_printerr ("modest: cannot get default account\n");
1063 acc_name = g_strdup (account_name);
1066 /* Set send/receive operation in progress */
1067 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1069 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1070 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1071 G_CALLBACK (_on_send_receive_progress_changed),
1074 /* Send & receive. */
1075 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1076 /* Receive and then send. The operation is tagged initially as
1077 a receive operation because the account update performs a
1078 receive and then a send. The operation changes its type
1079 internally, so the progress objects will receive the proper
1080 progress information */
1081 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1082 modest_mail_operation_update_account (mail_op, acc_name);
1083 g_object_unref (G_OBJECT (mail_op));
1090 * Refreshes all accounts. This function will be used by automatic
1094 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1096 GSList *account_names, *iter;
1098 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1101 iter = account_names;
1103 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1104 iter = g_slist_next (iter);
1107 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1108 g_slist_free (account_names);
1112 * Handler of the click on Send&Receive button in the main toolbar
1115 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1117 /* Check if accounts exist */
1118 gboolean accounts_exist =
1119 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1121 /* If not, allow the user to create an account before trying to send/receive. */
1122 if (!accounts_exist)
1123 modest_ui_actions_on_accounts (NULL, win);
1125 /* Refresh the active account */
1126 modest_ui_actions_do_send_receive (NULL, win);
1131 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1134 GtkWidget *header_view;
1136 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1138 header_view = modest_main_window_get_child_widget (main_window,
1139 MODEST_WIDGET_TYPE_HEADER_VIEW);
1143 conf = modest_runtime_get_conf ();
1145 /* what is saved/restored is depending on the style; thus; we save with
1146 * old style, then update the style, and restore for this new style
1148 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1150 if (modest_header_view_get_style
1151 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1152 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1153 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1155 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1156 MODEST_HEADER_VIEW_STYLE_DETAILS);
1158 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1159 MODEST_CONF_HEADER_VIEW_KEY);
1164 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1166 ModestMainWindow *main_window)
1168 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1169 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1171 /* If no header has been selected then exit */
1175 /* Update Main window title */
1176 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1177 const gchar *subject = tny_header_get_subject (header);
1178 if (subject && strlen(subject) > 0)
1179 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1181 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1184 /* Update toolbar dimming state */
1185 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1189 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1191 ModestMainWindow *main_window)
1195 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1200 headers = tny_simple_list_new ();
1201 tny_list_prepend (headers, G_OBJECT (header));
1203 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1205 g_object_unref (headers);
1209 set_active_account_from_tny_account (TnyAccount *account,
1210 ModestWindow *window)
1212 const gchar *server_acc_name = tny_account_get_id (account);
1214 /* We need the TnyAccount provided by the
1215 account store because that is the one that
1216 knows the name of the Modest account */
1217 TnyAccount *modest_server_account = modest_server_account =
1218 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1221 const gchar *modest_acc_name =
1222 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1223 modest_window_set_active_account (window, modest_acc_name);
1224 g_object_unref (modest_server_account);
1228 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1229 TnyFolderStore *folder_store,
1231 ModestMainWindow *main_window)
1234 GtkWidget *header_view;
1235 gboolean folder_empty = FALSE;
1237 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1239 header_view = modest_main_window_get_child_widget(main_window,
1240 MODEST_WIDGET_TYPE_HEADER_VIEW);
1244 conf = modest_runtime_get_conf ();
1246 if (TNY_IS_ACCOUNT (folder_store)) {
1247 /* Update active account */
1248 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1249 /* Show account details */
1250 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1252 if (TNY_IS_FOLDER (folder_store) && selected) {
1254 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1255 /* Update the active account */
1256 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1257 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1258 g_object_unref (account);
1262 /* Set folder on header view */
1263 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1264 TNY_FOLDER (folder_store));
1266 /* Set main view style */
1267 folder_empty = tny_folder_get_all_count (TNY_FOLDER (folder_store)) == 0;
1269 modest_main_window_set_contents_style (main_window,
1270 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1273 modest_main_window_set_contents_style (main_window,
1274 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1275 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1276 MODEST_CONF_HEADER_VIEW_KEY);
1279 /* Update the active account */
1280 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1281 /* Do not show folder */
1282 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1283 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1287 /* Update toolbar dimming state */
1288 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1292 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1299 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1301 if (g_main_depth > 0)
1302 gdk_threads_enter ();
1303 online = tny_device_is_online (modest_runtime_get_device());
1306 /* already online -- the item is simply not there... */
1307 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1309 GTK_MESSAGE_WARNING,
1311 _("The %s you selected cannot be found"),
1313 gtk_dialog_run (GTK_DIALOG(dialog));
1315 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1319 GTK_RESPONSE_REJECT,
1321 GTK_RESPONSE_ACCEPT,
1323 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1324 "Do you want to get online?"), item);
1325 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1326 gtk_label_new (txt), FALSE, FALSE, 0);
1327 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1330 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1331 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1332 // modest_platform_connect_and_wait ();;
1335 gtk_widget_destroy (dialog);
1336 if (g_main_depth > 0)
1337 gdk_threads_leave ();
1341 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1344 /* g_message ("%s %s", __FUNCTION__, link); */
1349 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1352 modest_platform_activate_uri (link);
1356 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1359 modest_platform_show_uri_popup (link);
1363 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1366 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1370 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1371 const gchar *address,
1374 /* g_message ("%s %s", __FUNCTION__, address); */
1378 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1380 TnyTransportAccount *transport_account;
1381 ModestMailOperation *mail_operation;
1383 gchar *account_name, *from;
1384 ModestAccountMgr *account_mgr;
1386 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1388 data = modest_msg_edit_window_get_msg_data (edit_window);
1390 account_mgr = modest_runtime_get_account_mgr();
1391 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1393 account_name = modest_account_mgr_get_default_account (account_mgr);
1394 if (!account_name) {
1395 g_printerr ("modest: no account found\n");
1396 modest_msg_edit_window_free_msg_data (edit_window, data);
1400 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1401 account_name = g_strdup (data->account_name);
1405 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1406 (modest_runtime_get_account_store(),
1408 TNY_ACCOUNT_TYPE_TRANSPORT));
1409 if (!transport_account) {
1410 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1411 g_free (account_name);
1412 modest_msg_edit_window_free_msg_data (edit_window, data);
1415 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1417 /* Create the mail operation */
1418 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1419 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1421 modest_mail_operation_save_to_drafts (mail_operation,
1432 data->priority_flags);
1435 g_free (account_name);
1436 g_object_unref (G_OBJECT (transport_account));
1437 g_object_unref (G_OBJECT (mail_operation));
1439 modest_msg_edit_window_free_msg_data (edit_window, data);
1441 /* Save settings and close the window */
1442 gtk_widget_destroy (GTK_WIDGET (edit_window));
1445 /* For instance, when clicking the Send toolbar button when editing a message: */
1447 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1449 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1451 if (!modest_msg_edit_window_check_names (edit_window))
1454 /* FIXME: Code added just for testing. The final version will
1455 use the send queue provided by tinymail and some
1457 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1458 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1460 account_name = modest_account_mgr_get_default_account (account_mgr);
1462 if (!account_name) {
1463 g_printerr ("modest: no account found\n");
1467 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1469 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1470 account_name = g_strdup (data->account_name);
1473 /* Get the currently-active transport account for this modest account: */
1474 TnyTransportAccount *transport_account =
1475 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1476 (modest_runtime_get_account_store(),
1478 if (!transport_account) {
1479 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1480 g_free (account_name);
1481 modest_msg_edit_window_free_msg_data (edit_window, data);
1485 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1487 /* mail content checks and dialogs */
1488 if (data->subject == NULL || data->subject[0] == '\0') {
1489 GtkResponseType response;
1490 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1491 _("mcen_nc_subject_is_empty_send"));
1492 if (response == GTK_RESPONSE_CANCEL) {
1493 g_free (account_name);
1498 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1499 GtkResponseType response;
1500 gchar *note_message;
1501 gchar *note_subject = data->subject;
1502 if (note_subject == NULL || note_subject[0] == '\0')
1503 note_subject = _("mail_va_no_subject");
1504 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1505 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1507 g_free (note_message);
1508 if (response == GTK_RESPONSE_CANCEL) {
1509 g_free (account_name);
1514 /* Create the mail operation */
1515 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1516 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1518 modest_mail_operation_send_new_mail (mail_operation,
1529 data->priority_flags);
1533 g_free (account_name);
1534 g_object_unref (G_OBJECT (transport_account));
1535 g_object_unref (G_OBJECT (mail_operation));
1537 modest_msg_edit_window_free_msg_data (edit_window, data);
1539 /* Save settings and close the window: */
1540 gtk_widget_destroy (GTK_WIDGET (edit_window));
1544 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1545 ModestMsgEditWindow *window)
1547 ModestMsgEditFormatState *format_state = NULL;
1549 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1550 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1552 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1555 format_state = modest_msg_edit_window_get_format_state (window);
1556 g_return_if_fail (format_state != NULL);
1558 format_state->bold = gtk_toggle_action_get_active (action);
1559 modest_msg_edit_window_set_format_state (window, format_state);
1560 g_free (format_state);
1565 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1566 ModestMsgEditWindow *window)
1568 ModestMsgEditFormatState *format_state = NULL;
1570 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1571 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1573 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1576 format_state = modest_msg_edit_window_get_format_state (window);
1577 g_return_if_fail (format_state != NULL);
1579 format_state->italics = gtk_toggle_action_get_active (action);
1580 modest_msg_edit_window_set_format_state (window, format_state);
1581 g_free (format_state);
1586 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1587 ModestMsgEditWindow *window)
1589 ModestMsgEditFormatState *format_state = NULL;
1591 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1592 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1594 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1597 format_state = modest_msg_edit_window_get_format_state (window);
1598 g_return_if_fail (format_state != NULL);
1600 format_state->bullet = gtk_toggle_action_get_active (action);
1601 modest_msg_edit_window_set_format_state (window, format_state);
1602 g_free (format_state);
1607 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1608 GtkRadioAction *selected,
1609 ModestMsgEditWindow *window)
1611 ModestMsgEditFormatState *format_state = NULL;
1612 GtkJustification value;
1614 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1616 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1619 value = gtk_radio_action_get_current_value (selected);
1621 format_state = modest_msg_edit_window_get_format_state (window);
1622 g_return_if_fail (format_state != NULL);
1624 format_state->justification = value;
1625 modest_msg_edit_window_set_format_state (window, format_state);
1626 g_free (format_state);
1630 modest_ui_actions_on_select_editor_color (GtkAction *action,
1631 ModestMsgEditWindow *window)
1633 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1634 g_return_if_fail (GTK_IS_ACTION (action));
1636 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1639 modest_msg_edit_window_select_color (window);
1643 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1644 ModestMsgEditWindow *window)
1646 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1647 g_return_if_fail (GTK_IS_ACTION (action));
1649 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1652 modest_msg_edit_window_select_background_color (window);
1656 modest_ui_actions_on_insert_image (GtkAction *action,
1657 ModestMsgEditWindow *window)
1659 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1660 g_return_if_fail (GTK_IS_ACTION (action));
1662 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1665 modest_msg_edit_window_insert_image (window);
1669 modest_ui_actions_on_attach_file (GtkAction *action,
1670 ModestMsgEditWindow *window)
1672 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1673 g_return_if_fail (GTK_IS_ACTION (action));
1675 modest_msg_edit_window_attach_file (window);
1679 modest_ui_actions_on_remove_attachments (GtkAction *action,
1680 ModestMsgEditWindow *window)
1682 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1683 g_return_if_fail (GTK_IS_ACTION (action));
1685 modest_msg_edit_window_remove_attachments (window, NULL);
1689 * Shows a dialog with an entry that asks for some text. The returned
1690 * value must be freed by the caller. The dialog window title will be
1694 ask_for_folder_name (GtkWindow *parent_window,
1697 GtkWidget *dialog, *entry;
1698 gchar *folder_name = NULL;
1700 /* Ask for folder name */
1701 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1705 GTK_RESPONSE_REJECT,
1707 GTK_RESPONSE_ACCEPT,
1709 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1710 gtk_label_new(title),
1713 entry = gtk_entry_new_with_max_length (40);
1714 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1718 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1720 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1721 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1723 gtk_widget_destroy (dialog);
1729 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1731 TnyFolderStore *parent_folder;
1732 GtkWidget *folder_view;
1734 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1736 folder_view = modest_main_window_get_child_widget (main_window,
1737 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1741 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1743 if (parent_folder) {
1744 gboolean finished = FALSE;
1746 gchar *folder_name = NULL, *suggested_name = NULL;
1748 /* Run the new folder dialog */
1750 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1755 if (result == GTK_RESPONSE_REJECT) {
1758 ModestMailOperation *mail_op;
1759 TnyFolder *new_folder = NULL;
1761 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1762 G_OBJECT(main_window));
1763 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1765 new_folder = modest_mail_operation_create_folder (mail_op,
1767 (const gchar *) folder_name);
1769 g_object_unref (new_folder);
1772 g_object_unref (mail_op);
1774 g_free (folder_name);
1778 g_object_unref (parent_folder);
1783 modest_ui_actions_on_rename_folder (GtkAction *action,
1784 ModestMainWindow *main_window)
1786 TnyFolderStore *folder;
1787 GtkWidget *folder_view;
1788 GtkWidget *header_view;
1790 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1792 folder_view = modest_main_window_get_child_widget (main_window,
1793 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1797 header_view = modest_main_window_get_child_widget (main_window,
1798 MODEST_WIDGET_TYPE_HEADER_VIEW);
1803 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1805 if (folder && TNY_IS_FOLDER (folder)) {
1807 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1808 _("Please enter a new name for the folder"));
1810 if (folder_name != NULL && strlen (folder_name) > 0) {
1811 ModestMailOperation *mail_op;
1813 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1814 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1817 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1819 modest_mail_operation_rename_folder (mail_op,
1820 TNY_FOLDER (folder),
1821 (const gchar *) folder_name);
1823 g_object_unref (mail_op);
1824 g_free (folder_name);
1826 g_object_unref (folder);
1831 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1834 GObject *win = modest_mail_operation_get_source (mail_op);
1836 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1837 _("mail_in_ui_folder_delete_error"));
1841 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1843 TnyFolderStore *folder;
1844 GtkWidget *folder_view;
1848 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1850 folder_view = modest_main_window_get_child_widget (main_window,
1851 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1855 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1857 /* Show an error if it's an account */
1858 if (!TNY_IS_FOLDER (folder)) {
1859 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1860 _("mail_in_ui_folder_delete_error"));
1865 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1866 tny_folder_get_name (TNY_FOLDER (folder)));
1867 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1868 (const gchar *) message);
1871 if (response == GTK_RESPONSE_OK) {
1872 ModestMailOperation *mail_op =
1873 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1874 G_OBJECT(main_window),
1875 modest_ui_actions_delete_folder_error_handler,
1878 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1880 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1881 g_object_unref (G_OBJECT (mail_op));
1884 g_object_unref (G_OBJECT (folder));
1888 modest_ui_actions_on_delete_folder (GtkAction *action,
1889 ModestMainWindow *main_window)
1891 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1893 delete_folder (main_window, FALSE);
1897 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1899 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1901 delete_folder (main_window, TRUE);
1905 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1906 const gchar* server_account_name,
1911 ModestMainWindow *main_window)
1913 g_return_if_fail(server_account_name);
1914 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1916 /* Initalize output parameters: */
1923 #ifdef MODEST_PLATFORM_MAEMO
1924 /* Maemo uses a different (awkward) button order,
1925 * It should probably just use gtk_alternative_dialog_button_order ().
1927 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1931 GTK_RESPONSE_ACCEPT,
1933 GTK_RESPONSE_REJECT,
1936 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1940 GTK_RESPONSE_REJECT,
1942 GTK_RESPONSE_ACCEPT,
1944 #endif /* MODEST_PLATFORM_MAEMO */
1946 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1948 gchar *server_name = modest_server_account_get_hostname (
1949 modest_runtime_get_account_mgr(), server_account_name);
1950 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
1951 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
1956 /* This causes a warning because the logical ID has no %s in it,
1957 * though the translation does, but there is not much we can do about that: */
1958 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1959 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1962 g_free (server_name);
1966 gchar *initial_username = modest_server_account_get_username (
1967 modest_runtime_get_account_mgr(), server_account_name);
1969 GtkWidget *entry_username = gtk_entry_new ();
1970 if (initial_username)
1971 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1972 /* Dim this if a connection has ever succeeded with this username,
1973 * as per the UI spec: */
1974 const gboolean username_known =
1975 modest_server_account_get_username_has_succeeded(
1976 modest_runtime_get_account_mgr(), server_account_name);
1977 gtk_widget_set_sensitive (entry_username, !username_known);
1979 #ifdef MODEST_PLATFORM_MAEMO
1980 /* Auto-capitalization is the default, so let's turn it off: */
1981 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1983 /* Create a size group to be used by all captions.
1984 * Note that HildonCaption does not create a default size group if we do not specify one.
1985 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1986 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1988 GtkWidget *caption = hildon_caption_new (sizegroup,
1989 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1990 gtk_widget_show (entry_username);
1991 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1992 FALSE, FALSE, MODEST_MARGIN_HALF);
1993 gtk_widget_show (caption);
1995 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1997 #endif /* MODEST_PLATFORM_MAEMO */
2000 GtkWidget *entry_password = gtk_entry_new ();
2001 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2002 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2004 #ifdef MODEST_PLATFORM_MAEMO
2005 /* Auto-capitalization is the default, so let's turn it off: */
2006 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2007 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2009 caption = hildon_caption_new (sizegroup,
2010 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2011 gtk_widget_show (entry_password);
2012 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2013 FALSE, FALSE, MODEST_MARGIN_HALF);
2014 gtk_widget_show (caption);
2015 g_object_unref (sizegroup);
2017 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2019 #endif /* MODEST_PLATFORM_MAEMO */
2021 /* This is not in the Maemo UI spec:
2022 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2023 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2027 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2029 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2031 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2033 modest_server_account_set_username (
2034 modest_runtime_get_account_mgr(), server_account_name,
2037 const gboolean username_was_changed =
2038 (strcmp (*username, initial_username) != 0);
2039 if (username_was_changed) {
2040 /* To actually use a changed username,
2041 * we must reset the connection, according to pvanhoof.
2042 * This _might_ be a sensible way to do that: */
2043 TnyDevice *device = modest_runtime_get_device();
2044 tny_device_force_offline (device);
2045 tny_device_force_online (device);
2050 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2052 /* We do not save the password in the configuration,
2053 * because this function is only called for passwords that should
2054 * not be remembered:
2055 modest_server_account_set_password (
2056 modest_runtime_get_account_mgr(), server_account_name,
2075 /* This is not in the Maemo UI spec:
2076 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2082 gtk_widget_destroy (dialog);
2084 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2088 modest_ui_actions_on_cut (GtkAction *action,
2089 ModestWindow *window)
2091 GtkWidget *focused_widget;
2093 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2094 if (GTK_IS_EDITABLE (focused_widget)) {
2095 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2096 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2097 GtkTextBuffer *buffer;
2098 GtkClipboard *clipboard;
2100 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2101 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2102 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2107 modest_ui_actions_on_copy (GtkAction *action,
2108 ModestWindow *window)
2110 GtkClipboard *clipboard;
2111 GtkWidget *focused_widget;
2113 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2114 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2115 if (GTK_IS_LABEL (focused_widget)) {
2116 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2117 } else if (GTK_IS_EDITABLE (focused_widget)) {
2118 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2119 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2120 GtkTextBuffer *buffer;
2122 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2123 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2128 modest_ui_actions_on_undo (GtkAction *action,
2129 ModestWindow *window)
2131 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2132 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2134 g_return_if_reached ();
2139 modest_ui_actions_on_paste (GtkAction *action,
2140 ModestWindow *window)
2142 GtkWidget *focused_widget;
2144 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2145 if (GTK_IS_EDITABLE (focused_widget)) {
2146 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2147 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2148 GtkTextBuffer *buffer;
2149 GtkClipboard *clipboard;
2151 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2152 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2153 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2158 modest_ui_actions_on_select_all (GtkAction *action,
2159 ModestWindow *window)
2161 GtkWidget *focused_widget;
2163 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2164 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2165 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2166 } else if (GTK_IS_LABEL (focused_widget)) {
2167 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2168 } else if (GTK_IS_EDITABLE (focused_widget)) {
2169 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2170 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2171 GtkTextBuffer *buffer;
2172 GtkTextIter start, end;
2174 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2175 gtk_text_buffer_get_start_iter (buffer, &start);
2176 gtk_text_buffer_get_end_iter (buffer, &end);
2177 gtk_text_buffer_select_range (buffer, &start, &end);
2179 else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2180 (MODEST_IS_HEADER_VIEW (focused_widget))) {
2182 GtkTreeSelection *selection = NULL;
2184 /* Get header view */
2185 GtkWidget *header_view = focused_widget;
2186 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2187 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2188 MODEST_WIDGET_TYPE_HEADER_VIEW);
2190 /* Select all messages */
2191 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2192 gtk_tree_selection_select_all (selection);
2197 modest_ui_actions_on_mark_as_read (GtkAction *action,
2198 ModestWindow *window)
2200 g_return_if_fail (MODEST_IS_WINDOW(window));
2202 /* Mark each header as read */
2203 do_headers_action (window, headers_action_mark_as_read, NULL);
2207 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2208 ModestWindow *window)
2210 g_return_if_fail (MODEST_IS_WINDOW(window));
2212 /* Mark each header as read */
2213 do_headers_action (window, headers_action_mark_as_unread, NULL);
2217 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2218 GtkRadioAction *selected,
2219 ModestWindow *window)
2223 value = gtk_radio_action_get_current_value (selected);
2224 if (MODEST_IS_WINDOW (window)) {
2225 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2229 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2230 GtkRadioAction *selected,
2231 ModestWindow *window)
2233 TnyHeaderFlags flags;
2234 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2236 flags = gtk_radio_action_get_current_value (selected);
2237 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2240 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2241 GtkRadioAction *selected,
2242 ModestWindow *window)
2246 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2248 file_format = gtk_radio_action_get_current_value (selected);
2249 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2254 modest_ui_actions_on_zoom_plus (GtkAction *action,
2255 ModestWindow *window)
2257 g_return_if_fail (MODEST_IS_WINDOW (window));
2259 modest_window_zoom_plus (MODEST_WINDOW (window));
2263 modest_ui_actions_on_zoom_minus (GtkAction *action,
2264 ModestWindow *window)
2266 g_return_if_fail (MODEST_IS_WINDOW (window));
2268 modest_window_zoom_minus (MODEST_WINDOW (window));
2272 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2273 ModestWindow *window)
2275 ModestWindowMgr *mgr;
2276 gboolean fullscreen, active;
2277 g_return_if_fail (MODEST_IS_WINDOW (window));
2279 mgr = modest_runtime_get_window_mgr ();
2281 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2282 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2284 if (active != fullscreen) {
2285 modest_window_mgr_set_fullscreen_mode (mgr, active);
2286 gtk_window_present (GTK_WINDOW (window));
2291 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2292 ModestWindow *window)
2294 ModestWindowMgr *mgr;
2295 gboolean fullscreen;
2297 g_return_if_fail (MODEST_IS_WINDOW (window));
2299 mgr = modest_runtime_get_window_mgr ();
2300 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2301 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2303 gtk_window_present (GTK_WINDOW (window));
2307 * Used by modest_ui_actions_on_details to call do_headers_action
2310 headers_action_show_details (TnyHeader *header,
2311 ModestWindow *window,
2318 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2321 gtk_widget_show_all (dialog);
2322 gtk_dialog_run (GTK_DIALOG (dialog));
2324 gtk_widget_destroy (dialog);
2328 * Show the folder details in a ModestDetailsDialog widget
2331 show_folder_details (TnyFolder *folder,
2337 dialog = modest_details_dialog_new_with_folder (window, folder);
2340 gtk_widget_show_all (dialog);
2341 gtk_dialog_run (GTK_DIALOG (dialog));
2343 gtk_widget_destroy (dialog);
2347 * Show the header details in a ModestDetailsDialog widget
2350 modest_ui_actions_on_details (GtkAction *action,
2353 TnyList * headers_list;
2357 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2360 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2363 g_object_unref (msg);
2365 headers_list = get_selected_headers (win);
2369 iter = tny_list_create_iterator (headers_list);
2371 header = TNY_HEADER (tny_iterator_get_current (iter));
2372 headers_action_show_details (header, win, NULL);
2373 g_object_unref (header);
2375 g_object_unref (iter);
2376 g_object_unref (headers_list);
2378 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2379 GtkWidget *folder_view, *header_view;
2381 /* Check which widget has the focus */
2382 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2383 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2384 if (gtk_widget_is_focus (folder_view)) {
2387 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2389 /* Show only when it's a folder */
2390 if (!folder || !TNY_IS_FOLDER (folder))
2393 show_folder_details (folder, GTK_WINDOW (win));
2396 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2397 MODEST_WIDGET_TYPE_HEADER_VIEW);
2398 /* Show details of each header */
2399 do_headers_action (win, headers_action_show_details, header_view);
2405 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2406 ModestMsgEditWindow *window)
2408 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2410 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2414 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2415 ModestMsgEditWindow *window)
2417 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2419 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2423 modest_ui_actions_toggle_folders_view (GtkAction *action,
2424 ModestMainWindow *main_window)
2428 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2430 conf = modest_runtime_get_conf ();
2432 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2433 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2435 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2439 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2440 ModestWindow *window)
2442 gboolean active, fullscreen = FALSE;
2443 ModestWindowMgr *mgr;
2445 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2447 /* Check if we want to toggle the toolbar vuew in fullscreen
2449 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2450 "ViewShowToolbarFullScreen")) {
2454 /* Toggle toolbar */
2455 mgr = modest_runtime_get_window_mgr ();
2456 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2460 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2461 ModestMsgEditWindow *window)
2463 modest_msg_edit_window_select_font (window);
2467 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2468 const gchar *display_name,
2471 /* Do not change the application name if the widget has not
2472 the focus. This callback could be called even if the folder
2473 view has not the focus, because the handled signal could be
2474 emitted when the folder view is redrawn */
2475 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2477 gtk_window_set_title (window, display_name);
2479 gtk_window_set_title (window, " ");
2484 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2486 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2487 modest_msg_edit_window_select_contacts (window);
2491 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2493 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2494 modest_msg_edit_window_check_names (window);
2499 create_move_to_dialog (ModestWindow *win,
2500 GtkWidget *folder_view,
2501 GtkWidget **tree_view)
2503 GtkWidget *dialog, *scroll;
2505 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2507 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2509 GTK_RESPONSE_ACCEPT,
2511 GTK_RESPONSE_REJECT,
2514 /* Create scrolled window */
2515 scroll = gtk_scrolled_window_new (NULL, NULL);
2516 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2517 GTK_POLICY_AUTOMATIC,
2518 GTK_POLICY_AUTOMATIC);
2520 /* Create folder view */
2521 *tree_view = modest_folder_view_new (NULL);
2522 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2523 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2524 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2526 /* Add scroll to dialog */
2527 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2528 scroll, FALSE, FALSE, 0);
2530 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2536 * Returns TRUE if at least one of the headers of the list belongs to
2537 * a message that has been fully retrieved.
2540 has_retrieved_msgs (TnyList *list)
2543 gboolean found = FALSE;
2545 iter = tny_list_create_iterator (list);
2546 while (tny_iterator_is_done (iter) && !found) {
2548 TnyHeaderFlags flags;
2550 header = TNY_HEADER (tny_iterator_get_current (iter));
2551 flags = tny_header_get_flags (header);
2552 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2556 tny_iterator_next (iter);
2558 g_object_unref (iter);
2564 * Shows a confirmation dialog to the user when we're moving messages
2565 * from a remote server to the local storage. Returns the dialog
2566 * response. If it's other kind of movement the it always returns
2570 msgs_move_to_confirmation (GtkWindow *win,
2571 TnyFolder *dest_folder,
2574 gint response = GTK_RESPONSE_OK;
2576 /* If the destination is a local folder */
2577 if (modest_tny_folder_is_local_folder (dest_folder)) {
2578 TnyFolder *src_folder;
2582 /* Get source folder */
2583 iter = tny_list_create_iterator (headers);
2584 header = TNY_HEADER (tny_iterator_get_current (iter));
2585 src_folder = tny_header_get_folder (header);
2586 g_object_unref (header);
2587 g_object_unref (iter);
2589 /* If the source is a remote folder */
2590 if (!modest_tny_folder_is_local_folder (src_folder)) {
2591 const gchar *message;
2593 if (tny_list_get_length (headers) == 1)
2594 if (has_retrieved_msgs (headers))
2595 message = _("mcen_nc_move_retrieve");
2597 message = _("mcen_nc_move_header");
2599 if (has_retrieved_msgs (headers))
2600 message = _("mcen_nc_move_retrieves");
2602 message = _("mcen_nc_move_headers");
2604 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2605 (const gchar *) message);
2607 g_object_unref (src_folder);
2614 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2616 ModestMsgViewWindow *self = NULL;
2617 gboolean found = FALSE;
2619 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2620 self = MODEST_MSG_VIEW_WINDOW (object);
2622 found = modest_msg_view_window_select_first_message (self);
2623 g_return_if_fail (found);
2627 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2630 GObject *win = modest_mail_operation_get_source (mail_op);
2632 /* TODO: show error message */
2633 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2634 _("mail_in_ui_folder_move_target_error"));
2638 * UI handler for the "Move to" action when invoked from the
2642 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2643 ModestMainWindow *win)
2645 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2646 GtkWidget *header_view = NULL;
2648 TnyFolderStore *folder_store = NULL;
2649 ModestMailOperation *mail_op = NULL;
2651 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2653 /* Get the folder view */
2654 folder_view = modest_main_window_get_child_widget (win,
2655 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2657 /* Get header view */
2658 header_view = modest_main_window_get_child_widget (win,
2659 MODEST_WIDGET_TYPE_HEADER_VIEW);
2661 /* Create and run the dialog */
2662 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2663 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
2664 result = gtk_dialog_run (GTK_DIALOG(dialog));
2665 g_object_ref (tree_view);
2667 /* We do this to save an indentation level ;-) */
2668 if (result != GTK_RESPONSE_ACCEPT)
2671 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2673 if (TNY_IS_ACCOUNT (folder_store))
2676 /* Get folder or messages to transfer */
2677 if (gtk_widget_is_focus (folder_view)) {
2678 TnyFolderStore *src_folder;
2679 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2681 /* Clean folder on header view before moving it */
2682 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2684 if (TNY_IS_FOLDER (src_folder)) {
2686 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2688 modest_ui_actions_move_folder_error_handler,
2690 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2692 modest_mail_operation_xfer_folder (mail_op,
2693 TNY_FOLDER (src_folder),
2696 /* Unref mail operation */
2697 g_object_unref (G_OBJECT (mail_op));
2701 g_object_unref (G_OBJECT (src_folder));
2703 if (gtk_widget_is_focus (header_view)) {
2707 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2709 /* Ask for user confirmation */
2710 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2711 TNY_FOLDER (folder_store),
2714 /* Transfer messages */
2715 if (response == GTK_RESPONSE_OK) {
2716 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2717 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2720 modest_mail_operation_xfer_msgs (mail_op,
2722 TNY_FOLDER (folder_store),
2727 g_object_unref (G_OBJECT (mail_op));
2729 g_object_unref (headers);
2732 g_object_unref (folder_store);
2734 gtk_widget_destroy (dialog);
2739 * UI handler for the "Move to" action when invoked from the
2740 * ModestMsgViewWindow
2743 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2744 ModestMsgViewWindow *win)
2746 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2748 ModestMainWindow *main_window;
2752 /* Get the folder view */
2753 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2754 folder_view = modest_main_window_get_child_widget (main_window,
2755 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2757 /* Create and run the dialog */
2758 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2759 result = gtk_dialog_run (GTK_DIALOG(dialog));
2760 g_object_ref (tree_view);
2762 if (result == GTK_RESPONSE_ACCEPT) {
2763 TnyFolderStore *folder_store;
2766 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2768 /* Create header list */
2769 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2770 headers = tny_simple_list_new ();
2771 tny_list_prepend (headers, G_OBJECT (header));
2772 g_object_unref (header);
2774 /* Ask user for confirmation. MSG-NOT404 */
2775 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2776 TNY_FOLDER (folder_store),
2779 /* Transfer current msg */
2780 if (response == GTK_RESPONSE_OK) {
2781 ModestMailOperation *mail_op;
2783 /* Create mail op */
2784 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2785 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2788 /* Transfer messages */
2789 modest_mail_operation_xfer_msgs (mail_op,
2791 TNY_FOLDER (folder_store),
2793 tranasfer_msgs_from_viewer_cb,
2795 g_object_unref (G_OBJECT (mail_op));
2797 g_object_unref (headers);
2798 g_object_unref (folder_store);
2800 gtk_widget_destroy (dialog);
2804 modest_ui_actions_on_move_to (GtkAction *action,
2807 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2808 MODEST_IS_MSG_VIEW_WINDOW (win));
2810 if (MODEST_IS_MAIN_WINDOW (win))
2811 modest_ui_actions_on_main_window_move_to (action,
2812 MODEST_MAIN_WINDOW (win));
2814 modest_ui_actions_on_msg_view_window_move_to (action,
2815 MODEST_MSG_VIEW_WINDOW (win));
2819 * Calls #HeadersFunc for each header already selected in the main
2820 * window or the message currently being shown in the msg view window
2823 do_headers_action (ModestWindow *win,
2827 TnyList *headers_list;
2831 headers_list = get_selected_headers (win);
2835 /* Call the function for each header */
2836 iter = tny_list_create_iterator (headers_list);
2837 while (!tny_iterator_is_done (iter)) {
2840 header = TNY_HEADER (tny_iterator_get_current (iter));
2841 func (header, win, user_data);
2842 g_object_unref (header);
2843 tny_iterator_next (iter);
2845 g_object_unref (iter);
2846 g_object_unref (headers_list);
2850 modest_ui_actions_view_attachment (GtkAction *action,
2851 ModestWindow *window)
2853 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2854 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2856 /* not supported window for this action */
2857 g_return_if_reached ();
2862 modest_ui_actions_save_attachments (GtkAction *action,
2863 ModestWindow *window)
2865 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2866 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2868 /* not supported window for this action */
2869 g_return_if_reached ();
2874 modest_ui_actions_remove_attachments (GtkAction *action,
2875 ModestWindow *window)
2877 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2878 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2880 /* not supported window for this action */
2881 g_return_if_reached ();
2886 modest_ui_actions_on_settings (GtkAction *action,
2891 dialog = modest_platform_get_global_settings_dialog ();
2892 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2893 gtk_widget_show (dialog);
2895 gtk_dialog_run (GTK_DIALOG (dialog));
2897 gtk_widget_destroy (dialog);
2901 modest_ui_actions_on_help (GtkAction *action,
2904 const gchar *help_id = NULL;
2906 if (MODEST_IS_MAIN_WINDOW (win)) {
2907 const gchar *action_name;
2908 action_name = gtk_action_get_name (action);
2910 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2911 !strcmp (action_name, "HeaderViewCSMHelp")) {
2912 GtkWidget *folder_view;
2913 TnyFolderStore *folder_store;
2914 /* Get selected folder */
2915 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2916 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2917 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2919 /* Switch help_id */
2920 if (TNY_IS_FOLDER (folder_store)) {
2921 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2922 case TNY_FOLDER_TYPE_NORMAL:
2923 help_id = "applications_email_userfolder";
2925 case TNY_FOLDER_TYPE_INBOX:
2926 help_id = "applications_email_inbox";
2928 case TNY_FOLDER_TYPE_OUTBOX:
2929 help_id = "applications_email_outbox";
2931 case TNY_FOLDER_TYPE_SENT:
2932 help_id = "applications_email_sent";
2934 case TNY_FOLDER_TYPE_DRAFTS:
2935 help_id = "applications_email_drafts";
2937 case TNY_FOLDER_TYPE_ARCHIVE:
2938 help_id = "applications_email_archive";
2945 help_id = "applications_email_mainview";
2947 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2948 help_id = "applications_email_viewer";
2949 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2950 help_id = "applications_email_editor";
2952 modest_platform_show_help (GTK_WINDOW (win), help_id);
2956 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2957 ModestWindow *window)
2959 ModestMailOperation *mail_op;
2963 headers = get_selected_headers (window);
2967 /* Create mail operation */
2968 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2970 modest_ui_actions_get_msgs_full_error_handler,
2972 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2973 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2976 g_object_unref (headers);
2977 g_object_unref (mail_op);
2981 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2982 ModestWindow *window)
2984 g_return_if_fail (MODEST_IS_WINDOW (window));
2987 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2991 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2992 ModestWindow *window)
2994 g_return_if_fail (MODEST_IS_WINDOW (window));
2997 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3001 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3002 ModestWindow *window)
3004 g_return_if_fail (MODEST_IS_WINDOW (window));
3007 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3011 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3012 ModestWindow *window)
3014 g_return_if_fail (MODEST_IS_WINDOW (window));
3017 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3021 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3022 ModestWindow *window)
3024 g_return_if_fail (MODEST_IS_WINDOW (window));
3027 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3031 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3033 g_return_if_fail (MODEST_IS_WINDOW (window));
3036 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3040 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3042 g_return_if_fail (MODEST_IS_WINDOW (window));
3044 modest_platform_show_search_messages (GTK_WINDOW (window));
3048 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3050 g_return_if_fail (MODEST_IS_WINDOW (win));
3051 modest_platform_show_addressbook (GTK_WINDOW (win));
3056 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3057 ModestWindow *window)
3059 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3061 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3065 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3066 ModestMailOperationState *state,
3069 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3071 /* Set send/receive operation finished */
3072 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3073 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));