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 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
373 TRUE /* enabled accounts only */);
374 gboolean accounts_exist = account_names != NULL;
375 g_slist_free (account_names);
377 if (!accounts_exist) {
378 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
379 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
380 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
381 gtk_dialog_run (GTK_DIALOG (wizard));
382 gtk_widget_destroy (GTK_WIDGET (wizard));
384 /* Show the list of accounts: */
385 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
386 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
387 gtk_dialog_run (account_win);
388 gtk_widget_destroy (GTK_WIDGET(account_win));
391 GtkWidget *dialog, *label;
393 /* Create the widgets */
395 dialog = gtk_dialog_new_with_buttons ("Message",
397 GTK_DIALOG_DESTROY_WITH_PARENT,
401 label = gtk_label_new ("Hello World!");
403 /* Ensure that the dialog box is destroyed when the user responds. */
405 g_signal_connect_swapped (dialog, "response",
406 G_CALLBACK (gtk_widget_destroy),
409 /* Add the label, and show everything we've added to the dialog. */
411 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
413 gtk_widget_show_all (dialog);
414 #endif /* MODEST_PLATFORM_MAEMO */
418 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
420 ModestWindow *main_window = MODEST_WINDOW (user_data);
422 /* Save any changes. */
423 modest_connection_specific_smtp_window_save_server_accounts (
424 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
425 modest_window_get_active_account (main_window));
426 gtk_widget_destroy (GTK_WIDGET (window));
430 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
432 /* This is currently only implemented for Maemo,
433 * because it requires an API (libconic) to detect different connection
436 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
438 /* Create the window if necessary: */
439 const gchar *active_account_name = modest_window_get_active_account (win);
441 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
442 * or show the default account?
443 * If we show the default account then the account name should be shown in
444 * the window when we show it. */
445 if (!active_account_name) {
446 g_warning ("%s: No account is active.", __FUNCTION__);
450 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
451 modest_connection_specific_smtp_window_fill_with_connections (
452 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
453 modest_runtime_get_account_mgr(),
454 active_account_name);
456 /* Show the window: */
457 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
458 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
459 gtk_widget_show (specific_window);
461 /* Save changes when the window is hidden: */
462 g_signal_connect (specific_window, "hide",
463 G_CALLBACK (on_smtp_servers_window_hide), win);
464 #endif /* MODEST_PLATFORM_MAEMO */
468 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
470 ModestWindow *msg_win;
472 TnyFolder *folder = NULL;
473 gchar *account_name = NULL;
474 gchar *from_str = NULL;
475 /* GError *err = NULL; */
476 TnyAccount *account = NULL;
477 ModestWindowMgr *mgr;
478 gchar *signature = NULL, *blank_and_signature = NULL;
480 account_name = g_strdup(modest_window_get_active_account (win));
482 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
484 g_printerr ("modest: no account found\n");
488 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
490 TNY_ACCOUNT_TYPE_STORE);
492 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
496 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
498 g_printerr ("modest: failed get from string for '%s'\n", account_name);
502 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
503 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
504 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
505 MODEST_ACCOUNT_SIGNATURE, FALSE);
506 blank_and_signature = g_strconcat ("\n", signature, NULL);
509 blank_and_signature = g_strdup ("");
512 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
514 g_printerr ("modest: failed to create new msg\n");
518 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
520 g_printerr ("modest: failed to find Drafts folder\n");
524 /* tny_folder_add_msg (folder, msg, &err); */
526 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
528 /* g_error_free (err); */
532 /* Create and register edit window */
533 /* This is destroyed by TOOD. */
534 msg_win = modest_msg_edit_window_new (msg, account_name);
535 mgr = modest_runtime_get_window_mgr ();
536 modest_window_mgr_register_window (mgr, msg_win);
539 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
541 gtk_widget_show_all (GTK_WIDGET (msg_win));
544 g_free (account_name);
546 g_free (blank_and_signature);
548 g_object_unref (G_OBJECT(account));
550 g_object_unref (G_OBJECT(msg));
552 g_object_unref (G_OBJECT(folder));
556 open_msg_cb (ModestMailOperation *mail_op,
561 ModestWindowMgr *mgr = NULL;
562 ModestWindow *parent_win = NULL;
563 ModestWindow *win = NULL;
564 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
565 gchar *account = NULL;
568 /* TODO: Show an error? (review the specs) */
572 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
573 folder = tny_header_get_folder (header);
575 /* Mark header as read */
576 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
579 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
581 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
583 /* Gets folder type (OUTBOX headers will be opened in edit window */
584 if (modest_tny_folder_is_local_folder (folder))
585 folder_type = modest_tny_folder_get_local_folder_type (folder);
587 /* If the header is in the drafts folder then open the editor,
588 else the message view window */
589 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
590 win = modest_msg_edit_window_new (msg, account);
592 gchar *uid = modest_tny_folder_get_header_unique_id (header);
594 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
595 GtkWidget *header_view;
596 GtkTreeSelection *sel;
597 GList *sel_list = NULL;
600 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
601 MODEST_WIDGET_TYPE_HEADER_VIEW);
603 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
604 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
606 if (sel_list != NULL) {
607 GtkTreeRowReference *row_reference;
609 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
610 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
611 g_list_free (sel_list);
613 win = modest_msg_view_window_new_with_header_model (msg,
618 gtk_tree_row_reference_free (row_reference);
620 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
623 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
628 /* Register and show new window */
630 mgr = modest_runtime_get_window_mgr ();
631 modest_window_mgr_register_window (mgr, win);
632 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
633 gtk_widget_show_all (GTK_WIDGET(win));
638 g_object_unref (msg);
639 g_object_unref (folder);
640 g_object_unref (header);
644 * This function is the error handler of the
645 * modest_mail_operation_get_msgs_full operation
648 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
653 error = modest_mail_operation_get_error (mail_op);
654 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
655 GObject *win = modest_mail_operation_get_source (mail_op);
657 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
663 * This function is used by both modest_ui_actions_on_open and
664 * modest_ui_actions_on_header_activated. This way we always do the
665 * same when trying to open messages.
668 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
670 ModestWindowMgr *mgr;
672 ModestMailOperation *mail_op;
674 /* Look if we already have a message view for each header. If
675 true, then remove the header from the list of headers to
677 mgr = modest_runtime_get_window_mgr ();
678 iter = tny_list_create_iterator (headers);
679 while (!tny_iterator_is_done (iter)) {
680 ModestWindow *window;
683 header = TNY_HEADER (tny_iterator_get_current (iter));
684 window = modest_window_mgr_find_window_by_header (mgr, header);
686 /* Do not open again the message and present
687 the window to the user */
688 tny_list_remove (headers, G_OBJECT (header));
689 gtk_window_present (GTK_WINDOW (window));
692 g_object_unref (header);
693 tny_iterator_next (iter);
696 /* Open each message */
697 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
699 modest_ui_actions_get_msgs_full_error_handler,
701 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
702 modest_mail_operation_get_msgs_full (mail_op,
709 g_object_unref(mail_op);
713 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
718 headers = get_selected_headers (win);
723 _modest_ui_actions_open (headers, win);
725 g_object_unref(headers);
730 free_reply_forward_helper (gpointer data)
732 ReplyForwardHelper *helper;
734 helper = (ReplyForwardHelper *) data;
735 g_free (helper->account_name);
736 g_slice_free (ReplyForwardHelper, helper);
740 reply_forward_cb (ModestMailOperation *mail_op,
746 ReplyForwardHelper *rf_helper;
747 ModestWindow *msg_win;
748 ModestEditType edit_type;
750 TnyAccount *account = NULL;
751 ModestWindowMgr *mgr;
752 gchar *signature = NULL;
754 g_return_if_fail (user_data != NULL);
755 rf_helper = (ReplyForwardHelper *) user_data;
757 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
758 rf_helper->account_name);
759 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
760 rf_helper->account_name,
761 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
762 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
763 rf_helper->account_name,
764 MODEST_ACCOUNT_SIGNATURE, FALSE);
767 /* Create reply mail */
768 switch (rf_helper->action) {
771 modest_tny_msg_create_reply_msg (msg, from, signature,
772 rf_helper->reply_forward_type,
773 MODEST_TNY_MSG_REPLY_MODE_SENDER);
775 case ACTION_REPLY_TO_ALL:
777 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
778 MODEST_TNY_MSG_REPLY_MODE_ALL);
779 edit_type = MODEST_EDIT_TYPE_REPLY;
783 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
784 edit_type = MODEST_EDIT_TYPE_FORWARD;
787 g_return_if_reached ();
794 g_printerr ("modest: failed to create message\n");
798 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
799 rf_helper->account_name,
800 TNY_ACCOUNT_TYPE_STORE);
802 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
806 /* Create and register the windows */
807 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
808 mgr = modest_runtime_get_window_mgr ();
809 modest_window_mgr_register_window (mgr, msg_win);
811 if (rf_helper->parent_window != NULL) {
814 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
815 modest_window_set_zoom (msg_win, parent_zoom);
818 /* Show edit window */
819 gtk_widget_show_all (GTK_WIDGET (msg_win));
823 g_object_unref (G_OBJECT (new_msg));
825 g_object_unref (G_OBJECT (account));
826 g_object_unref (msg);
827 g_object_unref (header);
831 * Checks a list of headers. If any of them are not currently
832 * downloaded (CACHED) then it asks the user for permission to
835 * Returns FALSE if the user does not want to download the
836 * messages. Returns TRUE if the user allowed the download or if all
837 * of them are currently downloaded
840 download_uncached_messages (TnyList *header_list, GtkWindow *win)
843 gboolean found, retval;
845 iter = tny_list_create_iterator (header_list);
847 while (!tny_iterator_is_done (iter) && !found) {
849 TnyHeaderFlags flags;
851 header = TNY_HEADER (tny_iterator_get_current (iter));
852 flags = tny_header_get_flags (header);
853 /* TODO: is this the right flag?, it seems that some
854 headers that have been previously downloaded do not
856 found = !(flags & TNY_HEADER_FLAG_CACHED);
857 g_object_unref (header);
858 tny_iterator_next (iter);
860 g_object_unref (iter);
862 /* Ask for user permission to download the messages */
865 GtkResponseType response;
867 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
868 _("mcen_nc_get_multi_msg_txt"));
869 if (response == GTK_RESPONSE_CANCEL)
877 * Common code for the reply and forward actions
880 reply_forward (ReplyForwardAction action, ModestWindow *win)
882 ModestMailOperation *mail_op = NULL;
883 TnyList *header_list = NULL;
884 ReplyForwardHelper *rf_helper = NULL;
885 guint reply_forward_type;
886 gboolean continue_download;
888 g_return_if_fail (MODEST_IS_WINDOW(win));
890 header_list = get_selected_headers (win);
894 /* Check that the messages have been previously downloaded */
895 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
896 if (!continue_download) {
897 g_object_unref (header_list);
902 modest_conf_get_int (modest_runtime_get_conf (),
903 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
905 /* We assume that we can only select messages of the
906 same folder and that we reply all of them from the
907 same account. In fact the interface currently only
908 allows single selection */
911 rf_helper = g_slice_new0 (ReplyForwardHelper);
912 rf_helper->reply_forward_type = reply_forward_type;
913 rf_helper->action = action;
914 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
915 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
916 rf_helper->parent_window = GTK_WIDGET (win);
917 if (!rf_helper->account_name)
918 rf_helper->account_name =
919 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
921 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
924 /* Get header and message. Do not free them here, the
925 reply_forward_cb must do it */
926 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
927 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
928 if (!msg || !header) {
930 g_object_unref (msg);
932 g_object_unref (header);
933 g_printerr ("modest: no message found\n");
936 reply_forward_cb (NULL, header, msg, rf_helper);
938 /* Retrieve messages */
939 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
941 modest_ui_actions_get_msgs_full_error_handler,
943 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
944 modest_mail_operation_get_msgs_full (mail_op,
948 free_reply_forward_helper);
951 g_object_unref(mail_op);
955 g_object_unref (header_list);
959 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
961 g_return_if_fail (MODEST_IS_WINDOW(win));
963 reply_forward (ACTION_REPLY, win);
967 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
969 g_return_if_fail (MODEST_IS_WINDOW(win));
971 reply_forward (ACTION_FORWARD, win);
975 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
977 g_return_if_fail (MODEST_IS_WINDOW(win));
979 reply_forward (ACTION_REPLY_TO_ALL, win);
983 modest_ui_actions_on_next (GtkAction *action,
984 ModestWindow *window)
986 if (MODEST_IS_MAIN_WINDOW (window)) {
987 GtkWidget *header_view;
989 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
990 MODEST_WIDGET_TYPE_HEADER_VIEW);
994 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
995 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
996 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
998 g_return_if_reached ();
1003 modest_ui_actions_on_prev (GtkAction *action,
1004 ModestWindow *window)
1006 g_return_if_fail (MODEST_IS_WINDOW(window));
1008 if (MODEST_IS_MAIN_WINDOW (window)) {
1009 GtkWidget *header_view;
1010 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1011 MODEST_WIDGET_TYPE_HEADER_VIEW);
1015 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1016 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1017 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1019 g_return_if_reached ();
1024 modest_ui_actions_on_sort (GtkAction *action,
1025 ModestWindow *window)
1027 g_return_if_fail (MODEST_IS_WINDOW(window));
1029 if (MODEST_IS_MAIN_WINDOW (window)) {
1030 GtkWidget *header_view;
1031 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1032 MODEST_WIDGET_TYPE_HEADER_VIEW);
1036 /* Show sorting dialog */
1037 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1042 * This function performs the send & receive required actions. The
1043 * window is used to create the mail operation. Typically it should
1044 * always be the main window, but we pass it as argument in order to
1048 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1050 gchar *acc_name = NULL;
1051 ModestMailOperation *mail_op;
1053 /* If no account name was provided then get the current account, and if
1054 there is no current account then pick the default one: */
1055 if (!account_name) {
1056 acc_name = g_strdup (modest_window_get_active_account(win));
1058 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1060 g_printerr ("modest: cannot get default account\n");
1064 acc_name = g_strdup (account_name);
1067 /* Set send/receive operation in progress */
1068 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1070 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1071 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1072 G_CALLBACK (_on_send_receive_progress_changed),
1075 /* Send & receive. */
1076 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1077 /* Receive and then send. The operation is tagged initially as
1078 a receive operation because the account update performs a
1079 receive and then a send. The operation changes its type
1080 internally, so the progress objects will receive the proper
1081 progress information */
1082 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1083 modest_mail_operation_update_account (mail_op, acc_name);
1084 g_object_unref (G_OBJECT (mail_op));
1091 * Refreshes all accounts. This function will be used by automatic
1095 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1097 GSList *account_names, *iter;
1099 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1102 iter = account_names;
1104 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1105 iter = g_slist_next (iter);
1108 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1109 g_slist_free (account_names);
1113 * Handler of the click on Send&Receive button in the main toolbar
1116 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1118 /* Check that at least one account exists: */
1119 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1120 TRUE /* enabled accounts only */);
1121 gboolean accounts_exist = account_names != NULL;
1122 g_slist_free (account_names);
1124 /* If not, allow the user to create an account before trying to send/receive. */
1125 if (!accounts_exist)
1126 modest_ui_actions_on_accounts (NULL, win);
1128 /* Refresh the active account */
1129 modest_ui_actions_do_send_receive (NULL, win);
1134 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1137 GtkWidget *header_view;
1139 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1141 header_view = modest_main_window_get_child_widget (main_window,
1142 MODEST_WIDGET_TYPE_HEADER_VIEW);
1146 conf = modest_runtime_get_conf ();
1148 /* what is saved/restored is depending on the style; thus; we save with
1149 * old style, then update the style, and restore for this new style
1151 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1153 if (modest_header_view_get_style
1154 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1155 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1156 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1158 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1159 MODEST_HEADER_VIEW_STYLE_DETAILS);
1161 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1162 MODEST_CONF_HEADER_VIEW_KEY);
1167 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1169 ModestMainWindow *main_window)
1171 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1173 /* If no header has been selected then exit */
1177 /* Update Main window title */
1178 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1179 const gchar *subject = tny_header_get_subject (header);
1180 if (subject && strcmp (subject, ""))
1181 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1183 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1186 /* Update toolbar dimming state */
1187 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1191 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1193 ModestMainWindow *main_window)
1197 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1202 headers = tny_simple_list_new ();
1203 tny_list_prepend (headers, G_OBJECT (header));
1205 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1207 g_object_unref (headers);
1211 set_active_account_from_tny_account (TnyAccount *account,
1212 ModestWindow *window)
1214 const gchar *server_acc_name = tny_account_get_id (account);
1216 /* We need the TnyAccount provided by the
1217 account store because that is the one that
1218 knows the name of the Modest account */
1219 TnyAccount *modest_server_account = modest_server_account =
1220 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1223 const gchar *modest_acc_name =
1224 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1225 modest_window_set_active_account (window, modest_acc_name);
1226 g_object_unref (modest_server_account);
1230 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1231 TnyFolderStore *folder_store,
1233 ModestMainWindow *main_window)
1236 GtkWidget *header_view;
1237 gboolean folder_empty = FALSE;
1239 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1241 header_view = modest_main_window_get_child_widget(main_window,
1242 MODEST_WIDGET_TYPE_HEADER_VIEW);
1246 conf = modest_runtime_get_conf ();
1248 if (TNY_IS_ACCOUNT (folder_store)) {
1249 /* Update active account */
1250 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1251 /* Show account details */
1252 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1254 if (TNY_IS_FOLDER (folder_store) && selected) {
1256 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1257 /* Update the active account */
1258 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1259 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1260 g_object_unref (account);
1264 /* Set folder on header view */
1265 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1266 TNY_FOLDER (folder_store));
1268 /* Set main view style */
1269 folder_empty = tny_folder_get_all_count (TNY_FOLDER (folder_store)) == 0;
1271 modest_main_window_set_contents_style (main_window,
1272 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1275 modest_main_window_set_contents_style (main_window,
1276 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1277 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1278 MODEST_CONF_HEADER_VIEW_KEY);
1281 /* Update the active account */
1282 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1283 /* Do not show folder */
1284 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1285 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1289 /* Update toolbar dimming state */
1290 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1294 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1301 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1303 if (g_main_depth > 0)
1304 gdk_threads_enter ();
1305 online = tny_device_is_online (modest_runtime_get_device());
1308 /* already online -- the item is simply not there... */
1309 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1311 GTK_MESSAGE_WARNING,
1313 _("The %s you selected cannot be found"),
1315 gtk_dialog_run (GTK_DIALOG(dialog));
1317 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1321 GTK_RESPONSE_REJECT,
1323 GTK_RESPONSE_ACCEPT,
1325 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1326 "Do you want to get online?"), item);
1327 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1328 gtk_label_new (txt), FALSE, FALSE, 0);
1329 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1332 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1333 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1334 // modest_platform_connect_and_wait ();;
1337 gtk_widget_destroy (dialog);
1338 if (g_main_depth > 0)
1339 gdk_threads_leave ();
1343 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1346 /* g_message ("%s %s", __FUNCTION__, link); */
1351 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1354 modest_platform_activate_uri (link);
1358 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1361 modest_platform_show_uri_popup (link);
1365 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1368 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1372 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1373 const gchar *address,
1376 /* g_message ("%s %s", __FUNCTION__, address); */
1380 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1382 TnyTransportAccount *transport_account;
1383 ModestMailOperation *mail_operation;
1385 gchar *account_name, *from;
1386 ModestAccountMgr *account_mgr;
1388 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1390 data = modest_msg_edit_window_get_msg_data (edit_window);
1392 account_mgr = modest_runtime_get_account_mgr();
1393 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1395 account_name = modest_account_mgr_get_default_account (account_mgr);
1396 if (!account_name) {
1397 g_printerr ("modest: no account found\n");
1398 modest_msg_edit_window_free_msg_data (edit_window, data);
1402 if (!strcmp (account_name, MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID)) {
1403 account_name = g_strdup (data->account_name);
1407 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1408 (modest_runtime_get_account_store(),
1410 TNY_ACCOUNT_TYPE_TRANSPORT));
1411 if (!transport_account) {
1412 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1413 g_free (account_name);
1414 modest_msg_edit_window_free_msg_data (edit_window, data);
1417 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1419 /* Create the mail operation */
1420 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1421 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1423 modest_mail_operation_save_to_drafts (mail_operation,
1434 data->priority_flags);
1437 g_free (account_name);
1438 g_object_unref (G_OBJECT (transport_account));
1439 g_object_unref (G_OBJECT (mail_operation));
1441 modest_msg_edit_window_free_msg_data (edit_window, data);
1443 /* Save settings and close the window */
1444 gtk_widget_destroy (GTK_WIDGET (edit_window));
1447 /* For instance, when clicking the Send toolbar button when editing a message: */
1449 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1451 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1453 if (!modest_msg_edit_window_check_names (edit_window))
1456 /* FIXME: Code added just for testing. The final version will
1457 use the send queue provided by tinymail and some
1459 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1460 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1462 account_name = modest_account_mgr_get_default_account (account_mgr);
1464 if (!account_name) {
1465 g_printerr ("modest: no account found\n");
1468 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1470 if (!strcmp (account_name, MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID)) {
1471 account_name = g_strdup (data->account_name);
1474 /* Get the currently-active transport account for this modest account: */
1475 TnyTransportAccount *transport_account =
1476 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1477 (modest_runtime_get_account_store(),
1479 if (!transport_account) {
1480 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1481 g_free (account_name);
1482 modest_msg_edit_window_free_msg_data (edit_window, data);
1486 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1488 /* mail content checks and dialogs */
1489 if (data->subject == NULL || data->subject[0] == '\0') {
1490 GtkResponseType response;
1491 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1492 _("mcen_nc_subject_is_empty_send"));
1493 if (response == GTK_RESPONSE_CANCEL) {
1494 g_free (account_name);
1499 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1500 GtkResponseType response;
1501 gchar *note_message;
1502 gchar *note_subject = data->subject;
1503 if (note_subject == NULL || note_subject[0] == '\0')
1504 note_subject = _("mail_va_no_subject");
1505 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1506 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1508 g_free (note_message);
1509 if (response == GTK_RESPONSE_CANCEL) {
1510 g_free (account_name);
1515 /* Create the mail operation */
1516 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1517 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1519 modest_mail_operation_send_new_mail (mail_operation,
1530 data->priority_flags);
1534 g_free (account_name);
1535 g_object_unref (G_OBJECT (transport_account));
1536 g_object_unref (G_OBJECT (mail_operation));
1538 modest_msg_edit_window_free_msg_data (edit_window, data);
1540 /* Save settings and close the window: */
1541 gtk_widget_destroy (GTK_WIDGET (edit_window));
1545 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1546 ModestMsgEditWindow *window)
1548 ModestMsgEditFormatState *format_state = NULL;
1550 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1551 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1553 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1556 format_state = modest_msg_edit_window_get_format_state (window);
1557 g_return_if_fail (format_state != NULL);
1559 format_state->bold = gtk_toggle_action_get_active (action);
1560 modest_msg_edit_window_set_format_state (window, format_state);
1561 g_free (format_state);
1566 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1567 ModestMsgEditWindow *window)
1569 ModestMsgEditFormatState *format_state = NULL;
1571 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1572 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1574 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1577 format_state = modest_msg_edit_window_get_format_state (window);
1578 g_return_if_fail (format_state != NULL);
1580 format_state->italics = gtk_toggle_action_get_active (action);
1581 modest_msg_edit_window_set_format_state (window, format_state);
1582 g_free (format_state);
1587 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1588 ModestMsgEditWindow *window)
1590 ModestMsgEditFormatState *format_state = NULL;
1592 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1593 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1595 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1598 format_state = modest_msg_edit_window_get_format_state (window);
1599 g_return_if_fail (format_state != NULL);
1601 format_state->bullet = gtk_toggle_action_get_active (action);
1602 modest_msg_edit_window_set_format_state (window, format_state);
1603 g_free (format_state);
1608 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1609 GtkRadioAction *selected,
1610 ModestMsgEditWindow *window)
1612 ModestMsgEditFormatState *format_state = NULL;
1613 GtkJustification value;
1615 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1617 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1620 value = gtk_radio_action_get_current_value (selected);
1622 format_state = modest_msg_edit_window_get_format_state (window);
1623 g_return_if_fail (format_state != NULL);
1625 format_state->justification = value;
1626 modest_msg_edit_window_set_format_state (window, format_state);
1627 g_free (format_state);
1631 modest_ui_actions_on_select_editor_color (GtkAction *action,
1632 ModestMsgEditWindow *window)
1634 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1635 g_return_if_fail (GTK_IS_ACTION (action));
1637 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1640 modest_msg_edit_window_select_color (window);
1644 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1645 ModestMsgEditWindow *window)
1647 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1648 g_return_if_fail (GTK_IS_ACTION (action));
1650 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1653 modest_msg_edit_window_select_background_color (window);
1657 modest_ui_actions_on_insert_image (GtkAction *action,
1658 ModestMsgEditWindow *window)
1660 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1661 g_return_if_fail (GTK_IS_ACTION (action));
1663 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1666 modest_msg_edit_window_insert_image (window);
1670 modest_ui_actions_on_attach_file (GtkAction *action,
1671 ModestMsgEditWindow *window)
1673 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1674 g_return_if_fail (GTK_IS_ACTION (action));
1676 modest_msg_edit_window_attach_file (window);
1680 modest_ui_actions_on_remove_attachments (GtkAction *action,
1681 ModestMsgEditWindow *window)
1683 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1684 g_return_if_fail (GTK_IS_ACTION (action));
1686 modest_msg_edit_window_remove_attachments (window, NULL);
1690 * Shows a dialog with an entry that asks for some text. The returned
1691 * value must be freed by the caller. The dialog window title will be
1695 ask_for_folder_name (GtkWindow *parent_window,
1698 GtkWidget *dialog, *entry;
1699 gchar *folder_name = NULL;
1701 /* Ask for folder name */
1702 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1706 GTK_RESPONSE_REJECT,
1708 GTK_RESPONSE_ACCEPT,
1710 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1711 gtk_label_new(title),
1714 entry = gtk_entry_new_with_max_length (40);
1715 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1719 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1721 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1722 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1724 gtk_widget_destroy (dialog);
1730 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1732 TnyFolderStore *parent_folder;
1733 GtkWidget *folder_view;
1735 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1737 folder_view = modest_main_window_get_child_widget (main_window,
1738 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1742 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1744 if (parent_folder) {
1745 gboolean finished = FALSE;
1747 gchar *folder_name = NULL, *suggested_name = NULL;
1749 /* Run the new folder dialog */
1751 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1756 if (result == GTK_RESPONSE_REJECT) {
1759 ModestMailOperation *mail_op;
1760 TnyFolder *new_folder = NULL;
1762 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1763 G_OBJECT(main_window));
1764 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1766 new_folder = modest_mail_operation_create_folder (mail_op,
1768 (const gchar *) folder_name);
1770 g_object_unref (new_folder);
1773 g_object_unref (mail_op);
1775 g_free (folder_name);
1779 g_object_unref (parent_folder);
1784 modest_ui_actions_on_rename_folder (GtkAction *action,
1785 ModestMainWindow *main_window)
1787 TnyFolderStore *folder;
1788 GtkWidget *folder_view;
1789 GtkWidget *header_view;
1791 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1793 folder_view = modest_main_window_get_child_widget (main_window,
1794 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1798 header_view = modest_main_window_get_child_widget (main_window,
1799 MODEST_WIDGET_TYPE_HEADER_VIEW);
1804 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1806 if (folder && TNY_IS_FOLDER (folder)) {
1808 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1809 _("Please enter a new name for the folder"));
1811 if (folder_name != NULL && strlen (folder_name) > 0) {
1812 ModestMailOperation *mail_op;
1814 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1815 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1818 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1820 modest_mail_operation_rename_folder (mail_op,
1821 TNY_FOLDER (folder),
1822 (const gchar *) folder_name);
1824 g_object_unref (mail_op);
1825 g_free (folder_name);
1827 g_object_unref (folder);
1832 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1835 GObject *win = modest_mail_operation_get_source (mail_op);
1837 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1838 _("mail_in_ui_folder_delete_error"));
1842 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1844 TnyFolderStore *folder;
1845 GtkWidget *folder_view;
1849 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1851 folder_view = modest_main_window_get_child_widget (main_window,
1852 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1856 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1858 /* Show an error if it's an account */
1859 if (!TNY_IS_FOLDER (folder)) {
1860 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1861 _("mail_in_ui_folder_delete_error"));
1866 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1867 tny_folder_get_name (TNY_FOLDER (folder)));
1868 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1869 (const gchar *) message);
1872 if (response == GTK_RESPONSE_OK) {
1873 ModestMailOperation *mail_op =
1874 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1875 G_OBJECT(main_window),
1876 modest_ui_actions_delete_folder_error_handler,
1879 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1881 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1882 g_object_unref (G_OBJECT (mail_op));
1885 g_object_unref (G_OBJECT (folder));
1889 modest_ui_actions_on_delete_folder (GtkAction *action,
1890 ModestMainWindow *main_window)
1892 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1894 delete_folder (main_window, FALSE);
1898 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1900 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1902 delete_folder (main_window, TRUE);
1906 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1907 const gchar* server_account_name,
1912 ModestMainWindow *main_window)
1914 g_return_if_fail(server_account_name);
1915 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1917 /* Initalize output parameters: */
1924 #ifdef MODEST_PLATFORM_MAEMO
1925 /* Maemo uses a different (awkward) button order,
1926 * It should probably just use gtk_alternative_dialog_button_order ().
1928 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1932 GTK_RESPONSE_ACCEPT,
1934 GTK_RESPONSE_REJECT,
1937 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1941 GTK_RESPONSE_REJECT,
1943 GTK_RESPONSE_ACCEPT,
1945 #endif /* MODEST_PLATFORM_MAEMO */
1947 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1949 gchar *server_name = modest_server_account_get_hostname (
1950 modest_runtime_get_account_mgr(), server_account_name);
1952 /* This causes a warning because the logical ID has no %s in it,
1953 * though the translation does, but there is not much we can do about that: */
1954 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1955 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1958 g_free (server_name);
1962 gchar *initial_username = modest_server_account_get_username (
1963 modest_runtime_get_account_mgr(), server_account_name);
1965 GtkWidget *entry_username = gtk_entry_new ();
1966 if (initial_username)
1967 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1968 /* Dim this if a connection has ever succeeded with this username,
1969 * as per the UI spec: */
1970 const gboolean username_known =
1971 modest_server_account_get_username_has_succeeded(
1972 modest_runtime_get_account_mgr(), server_account_name);
1973 gtk_widget_set_sensitive (entry_username, !username_known);
1975 #ifdef MODEST_PLATFORM_MAEMO
1976 /* Auto-capitalization is the default, so let's turn it off: */
1977 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1979 /* Create a size group to be used by all captions.
1980 * Note that HildonCaption does not create a default size group if we do not specify one.
1981 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1982 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1984 GtkWidget *caption = hildon_caption_new (sizegroup,
1985 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1986 gtk_widget_show (entry_username);
1987 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1988 FALSE, FALSE, MODEST_MARGIN_HALF);
1989 gtk_widget_show (caption);
1991 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1993 #endif /* MODEST_PLATFORM_MAEMO */
1996 GtkWidget *entry_password = gtk_entry_new ();
1997 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1998 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2000 #ifdef MODEST_PLATFORM_MAEMO
2001 /* Auto-capitalization is the default, so let's turn it off: */
2002 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2003 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2005 caption = hildon_caption_new (sizegroup,
2006 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2007 gtk_widget_show (entry_password);
2008 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2009 FALSE, FALSE, MODEST_MARGIN_HALF);
2010 gtk_widget_show (caption);
2011 g_object_unref (sizegroup);
2013 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2015 #endif /* MODEST_PLATFORM_MAEMO */
2017 /* This is not in the Maemo UI spec:
2018 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2019 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2023 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2025 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2027 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2029 modest_server_account_set_username (
2030 modest_runtime_get_account_mgr(), server_account_name,
2033 const gboolean username_was_changed =
2034 (strcmp (*username, initial_username) != 0);
2035 if (username_was_changed) {
2036 /* To actually use a changed username,
2037 * we must reset the connection, according to pvanhoof.
2038 * This _might_ be a sensible way to do that: */
2039 TnyDevice *device = modest_runtime_get_device();
2040 tny_device_force_offline (device);
2041 tny_device_force_online (device);
2046 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2048 /* We do not save the password in the configuration,
2049 * because this function is only called for passwords that should
2050 * not be remembered:
2051 modest_server_account_set_password (
2052 modest_runtime_get_account_mgr(), server_account_name,
2071 /* This is not in the Maemo UI spec:
2072 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2078 gtk_widget_destroy (dialog);
2080 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
2084 modest_ui_actions_on_cut (GtkAction *action,
2085 ModestWindow *window)
2087 GtkWidget *focused_widget;
2089 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2090 if (GTK_IS_EDITABLE (focused_widget)) {
2091 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2092 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2093 GtkTextBuffer *buffer;
2094 GtkClipboard *clipboard;
2096 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2097 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2098 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2103 modest_ui_actions_on_copy (GtkAction *action,
2104 ModestWindow *window)
2106 GtkClipboard *clipboard;
2107 GtkWidget *focused_widget;
2109 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2110 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2111 if (GTK_IS_LABEL (focused_widget)) {
2112 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2113 } else if (GTK_IS_EDITABLE (focused_widget)) {
2114 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2115 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2116 GtkTextBuffer *buffer;
2118 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2119 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2124 modest_ui_actions_on_undo (GtkAction *action,
2125 ModestWindow *window)
2127 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2128 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2130 g_return_if_reached ();
2135 modest_ui_actions_on_paste (GtkAction *action,
2136 ModestWindow *window)
2138 GtkWidget *focused_widget;
2140 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2141 if (GTK_IS_EDITABLE (focused_widget)) {
2142 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2143 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2144 GtkTextBuffer *buffer;
2145 GtkClipboard *clipboard;
2147 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2148 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2149 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2154 modest_ui_actions_on_select_all (GtkAction *action,
2155 ModestWindow *window)
2157 GtkWidget *focused_widget;
2159 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2160 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2161 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2162 } else if (GTK_IS_LABEL (focused_widget)) {
2163 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2164 } else if (GTK_IS_EDITABLE (focused_widget)) {
2165 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2166 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2167 GtkTextBuffer *buffer;
2168 GtkTextIter start, end;
2170 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2171 gtk_text_buffer_get_start_iter (buffer, &start);
2172 gtk_text_buffer_get_end_iter (buffer, &end);
2173 gtk_text_buffer_select_range (buffer, &start, &end);
2175 else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2176 (MODEST_IS_HEADER_VIEW (focused_widget))) {
2178 GtkTreeSelection *selection = NULL;
2180 /* Get header view */
2181 GtkWidget *header_view = focused_widget;
2182 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2183 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2184 MODEST_WIDGET_TYPE_HEADER_VIEW);
2186 /* Select all messages */
2187 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2188 gtk_tree_selection_select_all (selection);
2193 modest_ui_actions_on_mark_as_read (GtkAction *action,
2194 ModestWindow *window)
2196 g_return_if_fail (MODEST_IS_WINDOW(window));
2198 /* Mark each header as read */
2199 do_headers_action (window, headers_action_mark_as_read, NULL);
2203 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2204 ModestWindow *window)
2206 g_return_if_fail (MODEST_IS_WINDOW(window));
2208 /* Mark each header as read */
2209 do_headers_action (window, headers_action_mark_as_unread, NULL);
2213 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2214 GtkRadioAction *selected,
2215 ModestWindow *window)
2219 value = gtk_radio_action_get_current_value (selected);
2220 if (MODEST_IS_WINDOW (window)) {
2221 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2225 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2226 GtkRadioAction *selected,
2227 ModestWindow *window)
2229 TnyHeaderFlags flags;
2230 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2232 flags = gtk_radio_action_get_current_value (selected);
2233 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2236 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2237 GtkRadioAction *selected,
2238 ModestWindow *window)
2242 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2244 file_format = gtk_radio_action_get_current_value (selected);
2245 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2250 modest_ui_actions_on_zoom_plus (GtkAction *action,
2251 ModestWindow *window)
2253 g_return_if_fail (MODEST_IS_WINDOW (window));
2255 modest_window_zoom_plus (MODEST_WINDOW (window));
2259 modest_ui_actions_on_zoom_minus (GtkAction *action,
2260 ModestWindow *window)
2262 g_return_if_fail (MODEST_IS_WINDOW (window));
2264 modest_window_zoom_minus (MODEST_WINDOW (window));
2268 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2269 ModestWindow *window)
2271 ModestWindowMgr *mgr;
2272 gboolean fullscreen, active;
2273 g_return_if_fail (MODEST_IS_WINDOW (window));
2275 mgr = modest_runtime_get_window_mgr ();
2277 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2278 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2280 if (active != fullscreen) {
2281 modest_window_mgr_set_fullscreen_mode (mgr, active);
2282 gtk_window_present (GTK_WINDOW (window));
2287 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2288 ModestWindow *window)
2290 ModestWindowMgr *mgr;
2291 gboolean fullscreen;
2293 g_return_if_fail (MODEST_IS_WINDOW (window));
2295 mgr = modest_runtime_get_window_mgr ();
2296 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2297 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2299 gtk_window_present (GTK_WINDOW (window));
2303 * Used by modest_ui_actions_on_details to call do_headers_action
2306 headers_action_show_details (TnyHeader *header,
2307 ModestWindow *window,
2314 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2317 gtk_widget_show_all (dialog);
2318 gtk_dialog_run (GTK_DIALOG (dialog));
2320 gtk_widget_destroy (dialog);
2324 * Show the folder details in a ModestDetailsDialog widget
2327 show_folder_details (TnyFolder *folder,
2333 dialog = modest_details_dialog_new_with_folder (window, folder);
2336 gtk_widget_show_all (dialog);
2337 gtk_dialog_run (GTK_DIALOG (dialog));
2339 gtk_widget_destroy (dialog);
2343 * Show the header details in a ModestDetailsDialog widget
2346 modest_ui_actions_on_details (GtkAction *action,
2349 TnyList * headers_list;
2353 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2356 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2359 g_object_unref (msg);
2361 headers_list = get_selected_headers (win);
2365 iter = tny_list_create_iterator (headers_list);
2367 header = TNY_HEADER (tny_iterator_get_current (iter));
2368 headers_action_show_details (header, win, NULL);
2369 g_object_unref (header);
2371 g_object_unref (iter);
2372 g_object_unref (headers_list);
2374 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2375 GtkWidget *folder_view, *header_view;
2377 /* Check which widget has the focus */
2378 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2379 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2380 if (gtk_widget_is_focus (folder_view)) {
2383 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2385 /* Show only when it's a folder */
2386 if (!folder || !TNY_IS_FOLDER (folder))
2389 show_folder_details (folder, GTK_WINDOW (win));
2392 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2393 MODEST_WIDGET_TYPE_HEADER_VIEW);
2394 /* Show details of each header */
2395 do_headers_action (win, headers_action_show_details, header_view);
2401 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2402 ModestMsgEditWindow *window)
2404 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2406 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2410 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2411 ModestMsgEditWindow *window)
2413 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2415 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2419 modest_ui_actions_toggle_folders_view (GtkAction *action,
2420 ModestMainWindow *main_window)
2424 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2426 conf = modest_runtime_get_conf ();
2428 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2429 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2431 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2435 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2436 ModestWindow *window)
2438 gboolean active, fullscreen = FALSE;
2439 ModestWindowMgr *mgr;
2441 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2443 /* Check if we want to toggle the toolbar vuew in fullscreen
2445 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2446 "ViewShowToolbarFullScreen")) {
2450 /* Toggle toolbar */
2451 mgr = modest_runtime_get_window_mgr ();
2452 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2456 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2457 ModestMsgEditWindow *window)
2459 modest_msg_edit_window_select_font (window);
2463 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2464 const gchar *display_name,
2467 /* Do not change the application name if the widget has not
2468 the focus. This callback could be called even if the folder
2469 view has not the focus, because the handled signal could be
2470 emitted when the folder view is redrawn */
2471 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2473 gtk_window_set_title (window, display_name);
2475 gtk_window_set_title (window, " ");
2480 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2482 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2483 modest_msg_edit_window_select_contacts (window);
2487 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2489 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2490 modest_msg_edit_window_check_names (window);
2495 create_move_to_dialog (ModestWindow *win,
2496 GtkWidget *folder_view,
2497 GtkWidget **tree_view)
2499 GtkWidget *dialog, *scroll;
2501 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2503 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2505 GTK_RESPONSE_ACCEPT,
2507 GTK_RESPONSE_REJECT,
2510 /* Create scrolled window */
2511 scroll = gtk_scrolled_window_new (NULL, NULL);
2512 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2513 GTK_POLICY_AUTOMATIC,
2514 GTK_POLICY_AUTOMATIC);
2516 /* Create folder view */
2517 *tree_view = modest_folder_view_new (NULL);
2518 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2519 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2520 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2522 /* Add scroll to dialog */
2523 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2524 scroll, FALSE, FALSE, 0);
2526 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2532 * Returns TRUE if at least one of the headers of the list belongs to
2533 * a message that has been fully retrieved.
2536 has_retrieved_msgs (TnyList *list)
2539 gboolean found = FALSE;
2541 iter = tny_list_create_iterator (list);
2542 while (tny_iterator_is_done (iter) && !found) {
2544 TnyHeaderFlags flags;
2546 header = TNY_HEADER (tny_iterator_get_current (iter));
2547 flags = tny_header_get_flags (header);
2548 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2552 tny_iterator_next (iter);
2554 g_object_unref (iter);
2560 * Shows a confirmation dialog to the user when we're moving messages
2561 * from a remote server to the local storage. Returns the dialog
2562 * response. If it's other kind of movement the it always returns
2566 msgs_move_to_confirmation (GtkWindow *win,
2567 TnyFolder *dest_folder,
2570 gint response = GTK_RESPONSE_OK;
2572 /* If the destination is a local folder */
2573 if (modest_tny_folder_is_local_folder (dest_folder)) {
2574 TnyFolder *src_folder;
2578 /* Get source folder */
2579 iter = tny_list_create_iterator (headers);
2580 header = TNY_HEADER (tny_iterator_get_current (iter));
2581 src_folder = tny_header_get_folder (header);
2582 g_object_unref (header);
2583 g_object_unref (iter);
2585 /* If the source is a remote folder */
2586 if (!modest_tny_folder_is_local_folder (src_folder)) {
2587 const gchar *message;
2589 if (tny_list_get_length (headers) == 1)
2590 if (has_retrieved_msgs (headers))
2591 message = _("mcen_nc_move_retrieve");
2593 message = _("mcen_nc_move_header");
2595 if (has_retrieved_msgs (headers))
2596 message = _("mcen_nc_move_retrieves");
2598 message = _("mcen_nc_move_headers");
2600 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2601 (const gchar *) message);
2603 g_object_unref (src_folder);
2610 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2612 ModestMsgViewWindow *self = NULL;
2613 gboolean found = FALSE;
2615 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2616 self = MODEST_MSG_VIEW_WINDOW (object);
2618 found = modest_msg_view_window_select_first_message (self);
2619 g_return_if_fail (found);
2623 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2626 GObject *win = modest_mail_operation_get_source (mail_op);
2628 /* TODO: show error message */
2629 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2630 _("mail_in_ui_folder_move_target_error"));
2634 * UI handler for the "Move to" action when invoked from the
2638 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2639 ModestMainWindow *win)
2641 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2642 GtkWidget *header_view = NULL;
2644 TnyFolderStore *folder_store = NULL;
2645 ModestMailOperation *mail_op = NULL;
2647 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2649 /* Get the folder view */
2650 folder_view = modest_main_window_get_child_widget (win,
2651 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2653 /* Get header view */
2654 header_view = modest_main_window_get_child_widget (win,
2655 MODEST_WIDGET_TYPE_HEADER_VIEW);
2657 /* Create and run the dialog */
2658 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2659 result = gtk_dialog_run (GTK_DIALOG(dialog));
2660 g_object_ref (tree_view);
2662 /* We do this to save an indentation level ;-) */
2663 if (result != GTK_RESPONSE_ACCEPT)
2666 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2668 if (TNY_IS_ACCOUNT (folder_store))
2671 /* Get folder or messages to transfer */
2672 if (gtk_widget_is_focus (folder_view)) {
2673 TnyFolderStore *src_folder;
2674 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2676 /* Clean folder on header view before moving it */
2677 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2679 if (TNY_IS_FOLDER (src_folder)) {
2681 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2683 modest_ui_actions_move_folder_error_handler,
2685 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2687 modest_mail_operation_xfer_folder (mail_op,
2688 TNY_FOLDER (src_folder),
2691 /* Unref mail operation */
2692 g_object_unref (G_OBJECT (mail_op));
2696 g_object_unref (G_OBJECT (src_folder));
2698 if (gtk_widget_is_focus (header_view)) {
2702 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2704 /* Ask for user confirmation */
2705 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2706 TNY_FOLDER (folder_store),
2709 /* Transfer messages */
2710 if (response == GTK_RESPONSE_OK) {
2711 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2712 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2715 modest_mail_operation_xfer_msgs (mail_op,
2717 TNY_FOLDER (folder_store),
2722 g_object_unref (G_OBJECT (mail_op));
2724 g_object_unref (headers);
2727 g_object_unref (folder_store);
2729 gtk_widget_destroy (dialog);
2734 * UI handler for the "Move to" action when invoked from the
2735 * ModestMsgViewWindow
2738 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2739 ModestMsgViewWindow *win)
2741 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2743 ModestMainWindow *main_window;
2747 /* Get the folder view */
2748 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2749 folder_view = modest_main_window_get_child_widget (main_window,
2750 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2752 /* Create and run the dialog */
2753 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2754 result = gtk_dialog_run (GTK_DIALOG(dialog));
2755 g_object_ref (tree_view);
2757 if (result == GTK_RESPONSE_ACCEPT) {
2758 TnyFolderStore *folder_store;
2761 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2763 /* Create header list */
2764 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2765 headers = tny_simple_list_new ();
2766 tny_list_prepend (headers, G_OBJECT (header));
2767 g_object_unref (header);
2769 /* Ask user for confirmation. MSG-NOT404 */
2770 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2771 TNY_FOLDER (folder_store),
2774 /* Transfer current msg */
2775 if (response == GTK_RESPONSE_OK) {
2776 ModestMailOperation *mail_op;
2778 /* Create mail op */
2779 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2780 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2783 /* Transfer messages */
2784 modest_mail_operation_xfer_msgs (mail_op,
2786 TNY_FOLDER (folder_store),
2788 tranasfer_msgs_from_viewer_cb,
2790 g_object_unref (G_OBJECT (mail_op));
2792 g_object_unref (headers);
2793 g_object_unref (folder_store);
2795 gtk_widget_destroy (dialog);
2799 modest_ui_actions_on_move_to (GtkAction *action,
2802 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2803 MODEST_IS_MSG_VIEW_WINDOW (win));
2805 if (MODEST_IS_MAIN_WINDOW (win))
2806 modest_ui_actions_on_main_window_move_to (action,
2807 MODEST_MAIN_WINDOW (win));
2809 modest_ui_actions_on_msg_view_window_move_to (action,
2810 MODEST_MSG_VIEW_WINDOW (win));
2814 * Calls #HeadersFunc for each header already selected in the main
2815 * window or the message currently being shown in the msg view window
2818 do_headers_action (ModestWindow *win,
2822 TnyList *headers_list;
2826 headers_list = get_selected_headers (win);
2830 /* Call the function for each header */
2831 iter = tny_list_create_iterator (headers_list);
2832 while (!tny_iterator_is_done (iter)) {
2835 header = TNY_HEADER (tny_iterator_get_current (iter));
2836 func (header, win, user_data);
2837 g_object_unref (header);
2838 tny_iterator_next (iter);
2840 g_object_unref (iter);
2841 g_object_unref (headers_list);
2845 modest_ui_actions_view_attachment (GtkAction *action,
2846 ModestWindow *window)
2848 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2849 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2851 /* not supported window for this action */
2852 g_return_if_reached ();
2857 modest_ui_actions_save_attachments (GtkAction *action,
2858 ModestWindow *window)
2860 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2861 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2863 /* not supported window for this action */
2864 g_return_if_reached ();
2869 modest_ui_actions_remove_attachments (GtkAction *action,
2870 ModestWindow *window)
2872 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2873 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2875 /* not supported window for this action */
2876 g_return_if_reached ();
2881 modest_ui_actions_on_settings (GtkAction *action,
2886 dialog = modest_platform_get_global_settings_dialog ();
2887 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2888 gtk_widget_show (dialog);
2890 gtk_dialog_run (GTK_DIALOG (dialog));
2892 gtk_widget_destroy (dialog);
2896 modest_ui_actions_on_help (GtkAction *action,
2899 const gchar *help_id = NULL;
2901 if (MODEST_IS_MAIN_WINDOW (win)) {
2902 const gchar *action_name;
2903 action_name = gtk_action_get_name (action);
2905 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2906 !strcmp (action_name, "HeaderViewCSMHelp")) {
2907 GtkWidget *folder_view;
2908 TnyFolderStore *folder_store;
2909 /* Get selected folder */
2910 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2911 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2912 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2914 /* Switch help_id */
2915 if (TNY_IS_FOLDER (folder_store)) {
2916 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2917 case TNY_FOLDER_TYPE_NORMAL:
2918 help_id = "applications_email_userfolder";
2920 case TNY_FOLDER_TYPE_INBOX:
2921 help_id = "applications_email_inbox";
2923 case TNY_FOLDER_TYPE_OUTBOX:
2924 help_id = "applications_email_outbox";
2926 case TNY_FOLDER_TYPE_SENT:
2927 help_id = "applications_email_sent";
2929 case TNY_FOLDER_TYPE_DRAFTS:
2930 help_id = "applications_email_drafts";
2932 case TNY_FOLDER_TYPE_ARCHIVE:
2933 help_id = "applications_email_archive";
2940 help_id = "applications_email_mainview";
2942 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2943 help_id = "applications_email_viewer";
2944 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2945 help_id = "applications_email_editor";
2947 modest_platform_show_help (GTK_WINDOW (win), help_id);
2951 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2952 ModestWindow *window)
2954 ModestMailOperation *mail_op;
2958 headers = get_selected_headers (window);
2962 /* Create mail operation */
2963 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2965 modest_ui_actions_get_msgs_full_error_handler,
2967 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2968 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2971 g_object_unref (headers);
2972 g_object_unref (mail_op);
2976 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2977 ModestWindow *window)
2979 g_return_if_fail (MODEST_IS_WINDOW (window));
2982 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2986 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2987 ModestWindow *window)
2989 g_return_if_fail (MODEST_IS_WINDOW (window));
2992 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2996 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
2997 ModestWindow *window)
2999 g_return_if_fail (MODEST_IS_WINDOW (window));
3002 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3006 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3007 ModestWindow *window)
3009 g_return_if_fail (MODEST_IS_WINDOW (window));
3012 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3016 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3017 ModestWindow *window)
3019 g_return_if_fail (MODEST_IS_WINDOW (window));
3022 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3026 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3028 g_return_if_fail (MODEST_IS_WINDOW (window));
3031 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3035 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3037 g_return_if_fail (MODEST_IS_WINDOW (window));
3039 modest_platform_show_search_messages (GTK_WINDOW (window));
3043 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3044 ModestWindow *window)
3046 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3048 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3052 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3053 ModestMailOperationState *state,
3056 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3058 /* Set send/receive operation finished */
3059 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3060 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));