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_server_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_server_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_LOCAL_FOLDERS_ACCOUNT_ID)) {
1403 account_name = g_strdup (data->account_name);
1407 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_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");
1469 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1471 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1472 account_name = g_strdup (data->account_name);
1475 /* Get the currently-active transport account for this modest account: */
1476 TnyTransportAccount *transport_account =
1477 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1478 (modest_runtime_get_account_store(),
1480 if (!transport_account) {
1481 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1482 g_free (account_name);
1483 modest_msg_edit_window_free_msg_data (edit_window, data);
1487 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1489 /* mail content checks and dialogs */
1490 if (data->subject == NULL || data->subject[0] == '\0') {
1491 GtkResponseType response;
1492 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1493 _("mcen_nc_subject_is_empty_send"));
1494 if (response == GTK_RESPONSE_CANCEL) {
1495 g_free (account_name);
1500 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1501 GtkResponseType response;
1502 gchar *note_message;
1503 gchar *note_subject = data->subject;
1504 if (note_subject == NULL || note_subject[0] == '\0')
1505 note_subject = _("mail_va_no_subject");
1506 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1507 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1509 g_free (note_message);
1510 if (response == GTK_RESPONSE_CANCEL) {
1511 g_free (account_name);
1516 /* Create the mail operation */
1517 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1518 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1520 modest_mail_operation_send_new_mail (mail_operation,
1531 data->priority_flags);
1535 g_free (account_name);
1536 g_object_unref (G_OBJECT (transport_account));
1537 g_object_unref (G_OBJECT (mail_operation));
1539 modest_msg_edit_window_free_msg_data (edit_window, data);
1541 /* Save settings and close the window: */
1542 gtk_widget_destroy (GTK_WIDGET (edit_window));
1546 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1547 ModestMsgEditWindow *window)
1549 ModestMsgEditFormatState *format_state = NULL;
1551 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1552 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1554 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1557 format_state = modest_msg_edit_window_get_format_state (window);
1558 g_return_if_fail (format_state != NULL);
1560 format_state->bold = gtk_toggle_action_get_active (action);
1561 modest_msg_edit_window_set_format_state (window, format_state);
1562 g_free (format_state);
1567 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1568 ModestMsgEditWindow *window)
1570 ModestMsgEditFormatState *format_state = NULL;
1572 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1573 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1575 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1578 format_state = modest_msg_edit_window_get_format_state (window);
1579 g_return_if_fail (format_state != NULL);
1581 format_state->italics = gtk_toggle_action_get_active (action);
1582 modest_msg_edit_window_set_format_state (window, format_state);
1583 g_free (format_state);
1588 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1589 ModestMsgEditWindow *window)
1591 ModestMsgEditFormatState *format_state = NULL;
1593 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1594 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1596 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1599 format_state = modest_msg_edit_window_get_format_state (window);
1600 g_return_if_fail (format_state != NULL);
1602 format_state->bullet = gtk_toggle_action_get_active (action);
1603 modest_msg_edit_window_set_format_state (window, format_state);
1604 g_free (format_state);
1609 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1610 GtkRadioAction *selected,
1611 ModestMsgEditWindow *window)
1613 ModestMsgEditFormatState *format_state = NULL;
1614 GtkJustification value;
1616 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1618 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1621 value = gtk_radio_action_get_current_value (selected);
1623 format_state = modest_msg_edit_window_get_format_state (window);
1624 g_return_if_fail (format_state != NULL);
1626 format_state->justification = value;
1627 modest_msg_edit_window_set_format_state (window, format_state);
1628 g_free (format_state);
1632 modest_ui_actions_on_select_editor_color (GtkAction *action,
1633 ModestMsgEditWindow *window)
1635 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1636 g_return_if_fail (GTK_IS_ACTION (action));
1638 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1641 modest_msg_edit_window_select_color (window);
1645 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1646 ModestMsgEditWindow *window)
1648 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1649 g_return_if_fail (GTK_IS_ACTION (action));
1651 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1654 modest_msg_edit_window_select_background_color (window);
1658 modest_ui_actions_on_insert_image (GtkAction *action,
1659 ModestMsgEditWindow *window)
1661 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1662 g_return_if_fail (GTK_IS_ACTION (action));
1664 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1667 modest_msg_edit_window_insert_image (window);
1671 modest_ui_actions_on_attach_file (GtkAction *action,
1672 ModestMsgEditWindow *window)
1674 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1675 g_return_if_fail (GTK_IS_ACTION (action));
1677 modest_msg_edit_window_attach_file (window);
1681 modest_ui_actions_on_remove_attachments (GtkAction *action,
1682 ModestMsgEditWindow *window)
1684 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1685 g_return_if_fail (GTK_IS_ACTION (action));
1687 modest_msg_edit_window_remove_attachments (window, NULL);
1691 * Shows a dialog with an entry that asks for some text. The returned
1692 * value must be freed by the caller. The dialog window title will be
1696 ask_for_folder_name (GtkWindow *parent_window,
1699 GtkWidget *dialog, *entry;
1700 gchar *folder_name = NULL;
1702 /* Ask for folder name */
1703 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1707 GTK_RESPONSE_REJECT,
1709 GTK_RESPONSE_ACCEPT,
1711 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1712 gtk_label_new(title),
1715 entry = gtk_entry_new_with_max_length (40);
1716 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1720 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1722 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1723 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1725 gtk_widget_destroy (dialog);
1731 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1733 TnyFolderStore *parent_folder;
1734 GtkWidget *folder_view;
1736 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1738 folder_view = modest_main_window_get_child_widget (main_window,
1739 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1743 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1745 if (parent_folder) {
1746 gboolean finished = FALSE;
1748 gchar *folder_name = NULL, *suggested_name = NULL;
1750 /* Run the new folder dialog */
1752 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1757 if (result == GTK_RESPONSE_REJECT) {
1760 ModestMailOperation *mail_op;
1761 TnyFolder *new_folder = NULL;
1763 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1764 G_OBJECT(main_window));
1765 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1767 new_folder = modest_mail_operation_create_folder (mail_op,
1769 (const gchar *) folder_name);
1771 g_object_unref (new_folder);
1774 g_object_unref (mail_op);
1776 g_free (folder_name);
1780 g_object_unref (parent_folder);
1785 modest_ui_actions_on_rename_folder (GtkAction *action,
1786 ModestMainWindow *main_window)
1788 TnyFolderStore *folder;
1789 GtkWidget *folder_view;
1790 GtkWidget *header_view;
1792 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1794 folder_view = modest_main_window_get_child_widget (main_window,
1795 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1799 header_view = modest_main_window_get_child_widget (main_window,
1800 MODEST_WIDGET_TYPE_HEADER_VIEW);
1805 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1807 if (folder && TNY_IS_FOLDER (folder)) {
1809 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1810 _("Please enter a new name for the folder"));
1812 if (folder_name != NULL && strlen (folder_name) > 0) {
1813 ModestMailOperation *mail_op;
1815 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1816 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1819 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1821 modest_mail_operation_rename_folder (mail_op,
1822 TNY_FOLDER (folder),
1823 (const gchar *) folder_name);
1825 g_object_unref (mail_op);
1826 g_free (folder_name);
1828 g_object_unref (folder);
1833 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1836 GObject *win = modest_mail_operation_get_source (mail_op);
1838 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1839 _("mail_in_ui_folder_delete_error"));
1843 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1845 TnyFolderStore *folder;
1846 GtkWidget *folder_view;
1850 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1852 folder_view = modest_main_window_get_child_widget (main_window,
1853 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1857 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1859 /* Show an error if it's an account */
1860 if (!TNY_IS_FOLDER (folder)) {
1861 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1862 _("mail_in_ui_folder_delete_error"));
1867 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1868 tny_folder_get_name (TNY_FOLDER (folder)));
1869 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1870 (const gchar *) message);
1873 if (response == GTK_RESPONSE_OK) {
1874 ModestMailOperation *mail_op =
1875 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1876 G_OBJECT(main_window),
1877 modest_ui_actions_delete_folder_error_handler,
1880 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1882 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1883 g_object_unref (G_OBJECT (mail_op));
1886 g_object_unref (G_OBJECT (folder));
1890 modest_ui_actions_on_delete_folder (GtkAction *action,
1891 ModestMainWindow *main_window)
1893 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1895 delete_folder (main_window, FALSE);
1899 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1901 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1903 delete_folder (main_window, TRUE);
1907 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1908 const gchar* server_account_name,
1913 ModestMainWindow *main_window)
1915 g_return_if_fail(server_account_name);
1916 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1918 /* Initalize output parameters: */
1925 #ifdef MODEST_PLATFORM_MAEMO
1926 /* Maemo uses a different (awkward) button order,
1927 * It should probably just use gtk_alternative_dialog_button_order ().
1929 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1933 GTK_RESPONSE_ACCEPT,
1935 GTK_RESPONSE_REJECT,
1938 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1942 GTK_RESPONSE_REJECT,
1944 GTK_RESPONSE_ACCEPT,
1946 #endif /* MODEST_PLATFORM_MAEMO */
1948 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1950 gchar *server_name = modest_server_account_get_hostname (
1951 modest_runtime_get_account_mgr(), server_account_name);
1953 /* This causes a warning because the logical ID has no %s in it,
1954 * though the translation does, but there is not much we can do about that: */
1955 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1956 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1959 g_free (server_name);
1963 gchar *initial_username = modest_server_account_get_username (
1964 modest_runtime_get_account_mgr(), server_account_name);
1966 GtkWidget *entry_username = gtk_entry_new ();
1967 if (initial_username)
1968 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1969 /* Dim this if a connection has ever succeeded with this username,
1970 * as per the UI spec: */
1971 const gboolean username_known =
1972 modest_server_account_get_username_has_succeeded(
1973 modest_runtime_get_account_mgr(), server_account_name);
1974 gtk_widget_set_sensitive (entry_username, !username_known);
1976 #ifdef MODEST_PLATFORM_MAEMO
1977 /* Auto-capitalization is the default, so let's turn it off: */
1978 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1980 /* Create a size group to be used by all captions.
1981 * Note that HildonCaption does not create a default size group if we do not specify one.
1982 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1983 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1985 GtkWidget *caption = hildon_caption_new (sizegroup,
1986 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1987 gtk_widget_show (entry_username);
1988 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1989 FALSE, FALSE, MODEST_MARGIN_HALF);
1990 gtk_widget_show (caption);
1992 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1994 #endif /* MODEST_PLATFORM_MAEMO */
1997 GtkWidget *entry_password = gtk_entry_new ();
1998 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
1999 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2001 #ifdef MODEST_PLATFORM_MAEMO
2002 /* Auto-capitalization is the default, so let's turn it off: */
2003 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2004 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2006 caption = hildon_caption_new (sizegroup,
2007 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2008 gtk_widget_show (entry_password);
2009 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2010 FALSE, FALSE, MODEST_MARGIN_HALF);
2011 gtk_widget_show (caption);
2012 g_object_unref (sizegroup);
2014 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2016 #endif /* MODEST_PLATFORM_MAEMO */
2018 /* This is not in the Maemo UI spec:
2019 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2020 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2024 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2026 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2028 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2030 modest_server_account_set_username (
2031 modest_runtime_get_account_mgr(), server_account_name,
2034 const gboolean username_was_changed =
2035 (strcmp (*username, initial_username) != 0);
2036 if (username_was_changed) {
2037 /* To actually use a changed username,
2038 * we must reset the connection, according to pvanhoof.
2039 * This _might_ be a sensible way to do that: */
2040 TnyDevice *device = modest_runtime_get_device();
2041 tny_device_force_offline (device);
2042 tny_device_force_online (device);
2047 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2049 /* We do not save the password in the configuration,
2050 * because this function is only called for passwords that should
2051 * not be remembered:
2052 modest_server_account_set_password (
2053 modest_runtime_get_account_mgr(), server_account_name,
2072 /* This is not in the Maemo UI spec:
2073 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2079 gtk_widget_destroy (dialog);
2081 printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel);
2085 modest_ui_actions_on_cut (GtkAction *action,
2086 ModestWindow *window)
2088 GtkWidget *focused_widget;
2090 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2091 if (GTK_IS_EDITABLE (focused_widget)) {
2092 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2093 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2094 GtkTextBuffer *buffer;
2095 GtkClipboard *clipboard;
2097 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2098 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2099 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2104 modest_ui_actions_on_copy (GtkAction *action,
2105 ModestWindow *window)
2107 GtkClipboard *clipboard;
2108 GtkWidget *focused_widget;
2110 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2111 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2112 if (GTK_IS_LABEL (focused_widget)) {
2113 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2114 } else if (GTK_IS_EDITABLE (focused_widget)) {
2115 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2116 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2117 GtkTextBuffer *buffer;
2119 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2120 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2125 modest_ui_actions_on_undo (GtkAction *action,
2126 ModestWindow *window)
2128 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2129 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2131 g_return_if_reached ();
2136 modest_ui_actions_on_paste (GtkAction *action,
2137 ModestWindow *window)
2139 GtkWidget *focused_widget;
2141 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2142 if (GTK_IS_EDITABLE (focused_widget)) {
2143 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2144 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2145 GtkTextBuffer *buffer;
2146 GtkClipboard *clipboard;
2148 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2149 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2150 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2155 modest_ui_actions_on_select_all (GtkAction *action,
2156 ModestWindow *window)
2158 GtkWidget *focused_widget;
2160 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2161 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2162 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2163 } else if (GTK_IS_LABEL (focused_widget)) {
2164 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2165 } else if (GTK_IS_EDITABLE (focused_widget)) {
2166 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2167 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2168 GtkTextBuffer *buffer;
2169 GtkTextIter start, end;
2171 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2172 gtk_text_buffer_get_start_iter (buffer, &start);
2173 gtk_text_buffer_get_end_iter (buffer, &end);
2174 gtk_text_buffer_select_range (buffer, &start, &end);
2176 else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2177 (MODEST_IS_HEADER_VIEW (focused_widget))) {
2179 GtkTreeSelection *selection = NULL;
2181 /* Get header view */
2182 GtkWidget *header_view = focused_widget;
2183 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2184 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2185 MODEST_WIDGET_TYPE_HEADER_VIEW);
2187 /* Select all messages */
2188 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2189 gtk_tree_selection_select_all (selection);
2194 modest_ui_actions_on_mark_as_read (GtkAction *action,
2195 ModestWindow *window)
2197 g_return_if_fail (MODEST_IS_WINDOW(window));
2199 /* Mark each header as read */
2200 do_headers_action (window, headers_action_mark_as_read, NULL);
2204 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2205 ModestWindow *window)
2207 g_return_if_fail (MODEST_IS_WINDOW(window));
2209 /* Mark each header as read */
2210 do_headers_action (window, headers_action_mark_as_unread, NULL);
2214 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2215 GtkRadioAction *selected,
2216 ModestWindow *window)
2220 value = gtk_radio_action_get_current_value (selected);
2221 if (MODEST_IS_WINDOW (window)) {
2222 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2226 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2227 GtkRadioAction *selected,
2228 ModestWindow *window)
2230 TnyHeaderFlags flags;
2231 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2233 flags = gtk_radio_action_get_current_value (selected);
2234 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2237 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2238 GtkRadioAction *selected,
2239 ModestWindow *window)
2243 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2245 file_format = gtk_radio_action_get_current_value (selected);
2246 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2251 modest_ui_actions_on_zoom_plus (GtkAction *action,
2252 ModestWindow *window)
2254 g_return_if_fail (MODEST_IS_WINDOW (window));
2256 modest_window_zoom_plus (MODEST_WINDOW (window));
2260 modest_ui_actions_on_zoom_minus (GtkAction *action,
2261 ModestWindow *window)
2263 g_return_if_fail (MODEST_IS_WINDOW (window));
2265 modest_window_zoom_minus (MODEST_WINDOW (window));
2269 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2270 ModestWindow *window)
2272 ModestWindowMgr *mgr;
2273 gboolean fullscreen, active;
2274 g_return_if_fail (MODEST_IS_WINDOW (window));
2276 mgr = modest_runtime_get_window_mgr ();
2278 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2279 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2281 if (active != fullscreen) {
2282 modest_window_mgr_set_fullscreen_mode (mgr, active);
2283 gtk_window_present (GTK_WINDOW (window));
2288 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2289 ModestWindow *window)
2291 ModestWindowMgr *mgr;
2292 gboolean fullscreen;
2294 g_return_if_fail (MODEST_IS_WINDOW (window));
2296 mgr = modest_runtime_get_window_mgr ();
2297 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2298 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2300 gtk_window_present (GTK_WINDOW (window));
2304 * Used by modest_ui_actions_on_details to call do_headers_action
2307 headers_action_show_details (TnyHeader *header,
2308 ModestWindow *window,
2315 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2318 gtk_widget_show_all (dialog);
2319 gtk_dialog_run (GTK_DIALOG (dialog));
2321 gtk_widget_destroy (dialog);
2325 * Show the folder details in a ModestDetailsDialog widget
2328 show_folder_details (TnyFolder *folder,
2334 dialog = modest_details_dialog_new_with_folder (window, folder);
2337 gtk_widget_show_all (dialog);
2338 gtk_dialog_run (GTK_DIALOG (dialog));
2340 gtk_widget_destroy (dialog);
2344 * Show the header details in a ModestDetailsDialog widget
2347 modest_ui_actions_on_details (GtkAction *action,
2350 TnyList * headers_list;
2354 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2357 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2360 g_object_unref (msg);
2362 headers_list = get_selected_headers (win);
2366 iter = tny_list_create_iterator (headers_list);
2368 header = TNY_HEADER (tny_iterator_get_current (iter));
2369 headers_action_show_details (header, win, NULL);
2370 g_object_unref (header);
2372 g_object_unref (iter);
2373 g_object_unref (headers_list);
2375 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2376 GtkWidget *folder_view, *header_view;
2378 /* Check which widget has the focus */
2379 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2380 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2381 if (gtk_widget_is_focus (folder_view)) {
2384 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2386 /* Show only when it's a folder */
2387 if (!folder || !TNY_IS_FOLDER (folder))
2390 show_folder_details (folder, GTK_WINDOW (win));
2393 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2394 MODEST_WIDGET_TYPE_HEADER_VIEW);
2395 /* Show details of each header */
2396 do_headers_action (win, headers_action_show_details, header_view);
2402 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2403 ModestMsgEditWindow *window)
2405 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2407 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2411 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2412 ModestMsgEditWindow *window)
2414 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2416 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2420 modest_ui_actions_toggle_folders_view (GtkAction *action,
2421 ModestMainWindow *main_window)
2425 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2427 conf = modest_runtime_get_conf ();
2429 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2430 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2432 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2436 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2437 ModestWindow *window)
2439 gboolean active, fullscreen = FALSE;
2440 ModestWindowMgr *mgr;
2442 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2444 /* Check if we want to toggle the toolbar vuew in fullscreen
2446 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2447 "ViewShowToolbarFullScreen")) {
2451 /* Toggle toolbar */
2452 mgr = modest_runtime_get_window_mgr ();
2453 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2457 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2458 ModestMsgEditWindow *window)
2460 modest_msg_edit_window_select_font (window);
2464 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2465 const gchar *display_name,
2468 /* Do not change the application name if the widget has not
2469 the focus. This callback could be called even if the folder
2470 view has not the focus, because the handled signal could be
2471 emitted when the folder view is redrawn */
2472 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2474 gtk_window_set_title (window, display_name);
2476 gtk_window_set_title (window, " ");
2481 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2483 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2484 modest_msg_edit_window_select_contacts (window);
2488 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2490 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2491 modest_msg_edit_window_check_names (window);
2496 create_move_to_dialog (ModestWindow *win,
2497 GtkWidget *folder_view,
2498 GtkWidget **tree_view)
2500 GtkWidget *dialog, *scroll;
2502 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2504 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2506 GTK_RESPONSE_ACCEPT,
2508 GTK_RESPONSE_REJECT,
2511 /* Create scrolled window */
2512 scroll = gtk_scrolled_window_new (NULL, NULL);
2513 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2514 GTK_POLICY_AUTOMATIC,
2515 GTK_POLICY_AUTOMATIC);
2517 /* Create folder view */
2518 *tree_view = modest_folder_view_new (NULL);
2519 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2520 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2521 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2523 /* Add scroll to dialog */
2524 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2525 scroll, FALSE, FALSE, 0);
2527 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2533 * Returns TRUE if at least one of the headers of the list belongs to
2534 * a message that has been fully retrieved.
2537 has_retrieved_msgs (TnyList *list)
2540 gboolean found = FALSE;
2542 iter = tny_list_create_iterator (list);
2543 while (tny_iterator_is_done (iter) && !found) {
2545 TnyHeaderFlags flags;
2547 header = TNY_HEADER (tny_iterator_get_current (iter));
2548 flags = tny_header_get_flags (header);
2549 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2553 tny_iterator_next (iter);
2555 g_object_unref (iter);
2561 * Shows a confirmation dialog to the user when we're moving messages
2562 * from a remote server to the local storage. Returns the dialog
2563 * response. If it's other kind of movement the it always returns
2567 msgs_move_to_confirmation (GtkWindow *win,
2568 TnyFolder *dest_folder,
2571 gint response = GTK_RESPONSE_OK;
2573 /* If the destination is a local folder */
2574 if (modest_tny_folder_is_local_folder (dest_folder)) {
2575 TnyFolder *src_folder;
2579 /* Get source folder */
2580 iter = tny_list_create_iterator (headers);
2581 header = TNY_HEADER (tny_iterator_get_current (iter));
2582 src_folder = tny_header_get_folder (header);
2583 g_object_unref (header);
2584 g_object_unref (iter);
2586 /* If the source is a remote folder */
2587 if (!modest_tny_folder_is_local_folder (src_folder)) {
2588 const gchar *message;
2590 if (tny_list_get_length (headers) == 1)
2591 if (has_retrieved_msgs (headers))
2592 message = _("mcen_nc_move_retrieve");
2594 message = _("mcen_nc_move_header");
2596 if (has_retrieved_msgs (headers))
2597 message = _("mcen_nc_move_retrieves");
2599 message = _("mcen_nc_move_headers");
2601 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2602 (const gchar *) message);
2604 g_object_unref (src_folder);
2611 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2613 ModestMsgViewWindow *self = NULL;
2614 gboolean found = FALSE;
2616 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2617 self = MODEST_MSG_VIEW_WINDOW (object);
2619 found = modest_msg_view_window_select_first_message (self);
2620 g_return_if_fail (found);
2624 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2627 GObject *win = modest_mail_operation_get_source (mail_op);
2629 /* TODO: show error message */
2630 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2631 _("mail_in_ui_folder_move_target_error"));
2635 * UI handler for the "Move to" action when invoked from the
2639 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2640 ModestMainWindow *win)
2642 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2643 GtkWidget *header_view = NULL;
2645 TnyFolderStore *folder_store = NULL;
2646 ModestMailOperation *mail_op = NULL;
2648 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2650 /* Get the folder view */
2651 folder_view = modest_main_window_get_child_widget (win,
2652 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2654 /* Get header view */
2655 header_view = modest_main_window_get_child_widget (win,
2656 MODEST_WIDGET_TYPE_HEADER_VIEW);
2658 /* Create and run the dialog */
2659 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2660 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
2661 result = gtk_dialog_run (GTK_DIALOG(dialog));
2662 g_object_ref (tree_view);
2664 /* We do this to save an indentation level ;-) */
2665 if (result != GTK_RESPONSE_ACCEPT)
2668 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2670 if (TNY_IS_ACCOUNT (folder_store))
2673 /* Get folder or messages to transfer */
2674 if (gtk_widget_is_focus (folder_view)) {
2675 TnyFolderStore *src_folder;
2676 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2678 /* Clean folder on header view before moving it */
2679 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2681 if (TNY_IS_FOLDER (src_folder)) {
2683 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2685 modest_ui_actions_move_folder_error_handler,
2687 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2689 modest_mail_operation_xfer_folder (mail_op,
2690 TNY_FOLDER (src_folder),
2693 /* Unref mail operation */
2694 g_object_unref (G_OBJECT (mail_op));
2698 g_object_unref (G_OBJECT (src_folder));
2700 if (gtk_widget_is_focus (header_view)) {
2704 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2706 /* Ask for user confirmation */
2707 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2708 TNY_FOLDER (folder_store),
2711 /* Transfer messages */
2712 if (response == GTK_RESPONSE_OK) {
2713 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2714 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2717 modest_mail_operation_xfer_msgs (mail_op,
2719 TNY_FOLDER (folder_store),
2724 g_object_unref (G_OBJECT (mail_op));
2726 g_object_unref (headers);
2729 g_object_unref (folder_store);
2731 gtk_widget_destroy (dialog);
2736 * UI handler for the "Move to" action when invoked from the
2737 * ModestMsgViewWindow
2740 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2741 ModestMsgViewWindow *win)
2743 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2745 ModestMainWindow *main_window;
2749 /* Get the folder view */
2750 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2751 folder_view = modest_main_window_get_child_widget (main_window,
2752 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2754 /* Create and run the dialog */
2755 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2756 result = gtk_dialog_run (GTK_DIALOG(dialog));
2757 g_object_ref (tree_view);
2759 if (result == GTK_RESPONSE_ACCEPT) {
2760 TnyFolderStore *folder_store;
2763 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2765 /* Create header list */
2766 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2767 headers = tny_simple_list_new ();
2768 tny_list_prepend (headers, G_OBJECT (header));
2769 g_object_unref (header);
2771 /* Ask user for confirmation. MSG-NOT404 */
2772 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2773 TNY_FOLDER (folder_store),
2776 /* Transfer current msg */
2777 if (response == GTK_RESPONSE_OK) {
2778 ModestMailOperation *mail_op;
2780 /* Create mail op */
2781 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2782 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2785 /* Transfer messages */
2786 modest_mail_operation_xfer_msgs (mail_op,
2788 TNY_FOLDER (folder_store),
2790 tranasfer_msgs_from_viewer_cb,
2792 g_object_unref (G_OBJECT (mail_op));
2794 g_object_unref (headers);
2795 g_object_unref (folder_store);
2797 gtk_widget_destroy (dialog);
2801 modest_ui_actions_on_move_to (GtkAction *action,
2804 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2805 MODEST_IS_MSG_VIEW_WINDOW (win));
2807 if (MODEST_IS_MAIN_WINDOW (win))
2808 modest_ui_actions_on_main_window_move_to (action,
2809 MODEST_MAIN_WINDOW (win));
2811 modest_ui_actions_on_msg_view_window_move_to (action,
2812 MODEST_MSG_VIEW_WINDOW (win));
2816 * Calls #HeadersFunc for each header already selected in the main
2817 * window or the message currently being shown in the msg view window
2820 do_headers_action (ModestWindow *win,
2824 TnyList *headers_list;
2828 headers_list = get_selected_headers (win);
2832 /* Call the function for each header */
2833 iter = tny_list_create_iterator (headers_list);
2834 while (!tny_iterator_is_done (iter)) {
2837 header = TNY_HEADER (tny_iterator_get_current (iter));
2838 func (header, win, user_data);
2839 g_object_unref (header);
2840 tny_iterator_next (iter);
2842 g_object_unref (iter);
2843 g_object_unref (headers_list);
2847 modest_ui_actions_view_attachment (GtkAction *action,
2848 ModestWindow *window)
2850 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2851 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2853 /* not supported window for this action */
2854 g_return_if_reached ();
2859 modest_ui_actions_save_attachments (GtkAction *action,
2860 ModestWindow *window)
2862 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2863 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2865 /* not supported window for this action */
2866 g_return_if_reached ();
2871 modest_ui_actions_remove_attachments (GtkAction *action,
2872 ModestWindow *window)
2874 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2875 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2877 /* not supported window for this action */
2878 g_return_if_reached ();
2883 modest_ui_actions_on_settings (GtkAction *action,
2888 dialog = modest_platform_get_global_settings_dialog ();
2889 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2890 gtk_widget_show (dialog);
2892 gtk_dialog_run (GTK_DIALOG (dialog));
2894 gtk_widget_destroy (dialog);
2898 modest_ui_actions_on_help (GtkAction *action,
2901 const gchar *help_id = NULL;
2903 if (MODEST_IS_MAIN_WINDOW (win)) {
2904 const gchar *action_name;
2905 action_name = gtk_action_get_name (action);
2907 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2908 !strcmp (action_name, "HeaderViewCSMHelp")) {
2909 GtkWidget *folder_view;
2910 TnyFolderStore *folder_store;
2911 /* Get selected folder */
2912 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2913 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2914 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2916 /* Switch help_id */
2917 if (TNY_IS_FOLDER (folder_store)) {
2918 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2919 case TNY_FOLDER_TYPE_NORMAL:
2920 help_id = "applications_email_userfolder";
2922 case TNY_FOLDER_TYPE_INBOX:
2923 help_id = "applications_email_inbox";
2925 case TNY_FOLDER_TYPE_OUTBOX:
2926 help_id = "applications_email_outbox";
2928 case TNY_FOLDER_TYPE_SENT:
2929 help_id = "applications_email_sent";
2931 case TNY_FOLDER_TYPE_DRAFTS:
2932 help_id = "applications_email_drafts";
2934 case TNY_FOLDER_TYPE_ARCHIVE:
2935 help_id = "applications_email_archive";
2942 help_id = "applications_email_mainview";
2944 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2945 help_id = "applications_email_viewer";
2946 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2947 help_id = "applications_email_editor";
2949 modest_platform_show_help (GTK_WINDOW (win), help_id);
2953 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2954 ModestWindow *window)
2956 ModestMailOperation *mail_op;
2960 headers = get_selected_headers (window);
2964 /* Create mail operation */
2965 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2967 modest_ui_actions_get_msgs_full_error_handler,
2969 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2970 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2973 g_object_unref (headers);
2974 g_object_unref (mail_op);
2978 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2979 ModestWindow *window)
2981 g_return_if_fail (MODEST_IS_WINDOW (window));
2984 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2988 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2989 ModestWindow *window)
2991 g_return_if_fail (MODEST_IS_WINDOW (window));
2994 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2998 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
2999 ModestWindow *window)
3001 g_return_if_fail (MODEST_IS_WINDOW (window));
3004 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3008 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3009 ModestWindow *window)
3011 g_return_if_fail (MODEST_IS_WINDOW (window));
3014 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3018 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3019 ModestWindow *window)
3021 g_return_if_fail (MODEST_IS_WINDOW (window));
3024 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3028 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3030 g_return_if_fail (MODEST_IS_WINDOW (window));
3033 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3037 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3039 g_return_if_fail (MODEST_IS_WINDOW (window));
3041 modest_platform_show_search_messages (GTK_WINDOW (window));
3045 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3047 g_return_if_fail (MODEST_IS_WINDOW (win));
3048 modest_platform_show_addressbook (GTK_WINDOW (win));
3053 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3054 ModestWindow *window)
3056 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3058 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3062 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3063 ModestMailOperationState *state,
3066 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3068 /* Set send/receive operation finished */
3069 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3070 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));