1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
48 #ifdef MODEST_PLATFORM_MAEMO
49 #include "maemo/modest-osso-state-saving.h"
50 #endif /* MODEST_PLATFORM_MAEMO */
52 #include "widgets/modest-ui-constants.h"
53 #include <widgets/modest-main-window.h>
54 #include <widgets/modest-msg-view-window.h>
55 #include <widgets/modest-account-view-window.h>
56 #include <widgets/modest-details-dialog.h>
57 #include <widgets/modest-attachments-view.h>
58 #include "widgets/modest-global-settings-dialog.h"
59 #include "modest-connection-specific-smtp-window.h"
60 #include "modest-account-mgr-helpers.h"
61 #include "modest-mail-operation.h"
62 #include "modest-text-utils.h"
64 #ifdef MODEST_HAVE_EASYSETUP
65 #include "easysetup/modest-easysetup-wizard.h"
66 #endif /* MODEST_HAVE_EASYSETUP */
68 #include <modest-widget-memory.h>
69 #include <tny-error.h>
70 #include <tny-simple-list.h>
71 #include <tny-msg-view.h>
72 #include <tny-device.h>
73 #include <tny-merge-folder.h>
75 typedef struct _GetMsgAsyncHelper {
77 ModestMailOperation *mail_op;
84 typedef enum _ReplyForwardAction {
90 typedef struct _ReplyForwardHelper {
91 guint reply_forward_type;
92 ReplyForwardAction action;
94 GtkWidget *parent_window;
98 * The do_headers_action uses this kind of functions to perform some
99 * action to each member of a list of headers
101 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
104 do_headers_action (ModestWindow *win,
109 static void open_msg_cb (ModestMailOperation *mail_op,
114 static void reply_forward_cb (ModestMailOperation *mail_op,
119 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
121 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
124 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
125 ModestMailOperationState *state,
131 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
134 const gchar *authors[] = {
135 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
138 about = gtk_about_dialog_new ();
139 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
140 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
141 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
142 _("Copyright (c) 2006, Nokia Corporation\n"
143 "All rights reserved."));
144 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
145 _("a modest e-mail client\n\n"
146 "design and implementation: Dirk-Jan C. Binnema\n"
147 "contributions from the fine people at KC and Ig\n"
148 "uses the tinymail email framework written by Philip van Hoof"));
149 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
150 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
152 gtk_dialog_run (GTK_DIALOG (about));
153 gtk_widget_destroy(about);
157 * Gets the list of currently selected messages. If the win is the
158 * main window, then it returns a newly allocated list of the headers
159 * selected in the header view. If win is the msg view window, then
160 * the value returned is a list with just a single header.
162 * The caller of this funcion must free the list.
165 get_selected_headers (ModestWindow *win)
167 if (MODEST_IS_MAIN_WINDOW(win)) {
168 GtkWidget *header_view;
170 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
171 MODEST_WIDGET_TYPE_HEADER_VIEW);
172 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
174 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
175 /* for MsgViewWindows, we simply return a list with one element */
177 TnyList *list = NULL;
179 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
180 if (header != NULL) {
181 list = tny_simple_list_new ();
182 tny_list_prepend (list, G_OBJECT(header));
183 g_object_unref (G_OBJECT(header));
193 headers_action_mark_as_read (TnyHeader *header,
197 TnyHeaderFlags flags;
199 g_return_if_fail (TNY_IS_HEADER(header));
201 flags = tny_header_get_flags (header);
202 if (flags & TNY_HEADER_FLAG_SEEN) return;
203 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
207 headers_action_mark_as_unread (TnyHeader *header,
211 TnyHeaderFlags flags;
213 g_return_if_fail (TNY_IS_HEADER(header));
215 flags = tny_header_get_flags (header);
216 if (flags & TNY_HEADER_FLAG_SEEN) {
217 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
223 headers_action_delete (TnyHeader *header,
227 ModestMailOperation *mail_op = NULL;
229 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
230 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
233 /* Always delete. TODO: Move to trash still not supported */
234 modest_mail_operation_remove_msg (mail_op, header, FALSE);
235 g_object_unref (G_OBJECT (mail_op));
239 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
241 TnyList *header_list = NULL;
242 TnyIterator *iter = NULL;
243 TnyHeader *header = NULL;
244 gchar *message = NULL;
248 ModestWindowMgr *mgr;
250 g_return_if_fail (MODEST_IS_WINDOW(win));
252 header_list = get_selected_headers (win);
253 if (!header_list) return;
255 /* Check if any of the headers is already opened */
256 iter = tny_list_create_iterator (header_list);
258 mgr = modest_runtime_get_window_mgr ();
259 while (!tny_iterator_is_done (iter) && !found) {
260 header = TNY_HEADER (tny_iterator_get_current (iter));
261 if (modest_window_mgr_find_window_by_header (mgr, header))
263 g_object_unref (header);
264 tny_iterator_next (iter);
266 g_object_unref (iter);
271 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
272 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
274 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
278 g_object_unref (header_list);
283 if (tny_list_get_length(header_list) > 1)
284 message = g_strdup(_("emev_nc_delete_messages"));
286 iter = tny_list_create_iterator (header_list);
287 header = TNY_HEADER (tny_iterator_get_current (iter));
288 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
289 message = g_strdup_printf(_("emev_nc_delete_message"), desc);
290 g_object_unref (header);
291 g_object_unref (iter);
294 /* Confirmation dialog */
295 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
299 if (response == GTK_RESPONSE_OK) {
300 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
302 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
306 /* Remove each header */
307 do_headers_action (win, headers_action_delete, NULL);
309 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
310 gtk_widget_destroy (GTK_WIDGET(win));
317 g_object_unref (header_list);
322 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
324 #ifdef MODEST_PLATFORM_MAEMO
325 modest_osso_save_state();
326 #endif /* MODEST_PLATFORM_MAEMO */
332 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
334 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
335 gtk_widget_destroy (GTK_WIDGET (win));
336 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
338 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
339 } else if (MODEST_IS_WINDOW (win)) {
340 gtk_widget_destroy (GTK_WIDGET (win));
342 g_return_if_reached ();
347 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
349 GtkClipboard *clipboard = NULL;
350 gchar *selection = NULL;
352 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
353 selection = gtk_clipboard_wait_for_text (clipboard);
355 /* Question: why is the clipboard being used here?
356 * It doesn't really make a lot of sense. */
360 modest_address_book_add_address (selection);
366 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
368 /* This is currently only implemented for Maemo,
369 * because it requires a providers preset file which is not publically available.
371 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
372 gboolean accounts_exist = modest_account_mgr_has_accounts(
373 modest_runtime_get_account_mgr(), TRUE);
375 if (!accounts_exist) {
376 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
377 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
378 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
379 gtk_dialog_run (GTK_DIALOG (wizard));
380 gtk_widget_destroy (GTK_WIDGET (wizard));
382 /* Show the list of accounts: */
383 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
384 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
385 gtk_dialog_run (account_win);
386 gtk_widget_destroy (GTK_WIDGET(account_win));
389 GtkWidget *dialog, *label;
391 /* Create the widgets */
393 dialog = gtk_dialog_new_with_buttons ("Message",
395 GTK_DIALOG_DESTROY_WITH_PARENT,
399 label = gtk_label_new ("Hello World!");
401 /* Ensure that the dialog box is destroyed when the user responds. */
403 g_signal_connect_swapped (dialog, "response",
404 G_CALLBACK (gtk_widget_destroy),
407 /* Add the label, and show everything we've added to the dialog. */
409 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
411 gtk_widget_show_all (dialog);
412 #endif /* MODEST_PLATFORM_MAEMO */
416 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
418 ModestWindow *main_window = MODEST_WINDOW (user_data);
420 /* Save any changes. */
421 modest_connection_specific_smtp_window_save_server_accounts (
422 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
423 modest_window_get_active_account (main_window));
424 gtk_widget_destroy (GTK_WIDGET (window));
428 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
430 /* This is currently only implemented for Maemo,
431 * because it requires an API (libconic) to detect different connection
434 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
436 /* Create the window if necessary: */
437 const gchar *active_account_name = modest_window_get_active_account (win);
439 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
440 * or show the default account?
441 * If we show the default account then the account name should be shown in
442 * the window when we show it. */
443 if (!active_account_name) {
444 g_warning ("%s: No account is active.", __FUNCTION__);
448 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
449 modest_connection_specific_smtp_window_fill_with_connections (
450 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
451 modest_runtime_get_account_mgr(),
452 active_account_name);
454 /* Show the window: */
455 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
456 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
457 gtk_widget_show (specific_window);
459 /* Save changes when the window is hidden: */
460 g_signal_connect (specific_window, "hide",
461 G_CALLBACK (on_smtp_servers_window_hide), win);
462 #endif /* MODEST_PLATFORM_MAEMO */
466 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
468 ModestWindow *msg_win;
470 TnyFolder *folder = NULL;
471 gchar *account_name = NULL;
472 gchar *from_str = NULL;
473 /* GError *err = NULL; */
474 TnyAccount *account = NULL;
475 ModestWindowMgr *mgr;
476 gchar *signature = NULL, *blank_and_signature = NULL;
478 account_name = g_strdup(modest_window_get_active_account (win));
480 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
482 g_printerr ("modest: no account found\n");
486 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
488 TNY_ACCOUNT_TYPE_STORE);
490 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
494 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
496 g_printerr ("modest: failed get from string for '%s'\n", account_name);
500 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
501 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
502 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
503 MODEST_ACCOUNT_SIGNATURE, FALSE);
504 blank_and_signature = g_strconcat ("\n", signature, NULL);
507 blank_and_signature = g_strdup ("");
510 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
512 g_printerr ("modest: failed to create new msg\n");
516 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
518 g_printerr ("modest: failed to find Drafts folder\n");
522 /* tny_folder_add_msg (folder, msg, &err); */
524 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
526 /* g_error_free (err); */
530 /* Create and register edit window */
531 /* This is destroyed by TOOD. */
532 msg_win = modest_msg_edit_window_new (msg, account_name);
533 mgr = modest_runtime_get_window_mgr ();
534 modest_window_mgr_register_window (mgr, msg_win);
537 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
539 gtk_widget_show_all (GTK_WIDGET (msg_win));
542 g_free (account_name);
544 g_free (blank_and_signature);
546 g_object_unref (G_OBJECT(account));
548 g_object_unref (G_OBJECT(msg));
550 g_object_unref (G_OBJECT(folder));
554 open_msg_cb (ModestMailOperation *mail_op,
559 ModestWindowMgr *mgr = NULL;
560 ModestWindow *parent_win = NULL;
561 ModestWindow *win = NULL;
562 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
563 gchar *account = NULL;
566 /* TODO: Show an error? (review the specs) */
570 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
571 folder = tny_header_get_folder (header);
573 /* Mark header as read */
574 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
577 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
579 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
581 /* Gets folder type (OUTBOX headers will be opened in edit window */
582 if (modest_tny_folder_is_local_folder (folder))
583 folder_type = modest_tny_folder_get_local_folder_type (folder);
585 /* If the header is in the drafts folder then open the editor,
586 else the message view window */
587 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
588 win = modest_msg_edit_window_new (msg, account);
590 gchar *uid = modest_tny_folder_get_header_unique_id (header);
592 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
593 GtkWidget *header_view;
594 GtkTreeSelection *sel;
595 GList *sel_list = NULL;
598 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
599 MODEST_WIDGET_TYPE_HEADER_VIEW);
601 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
602 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
604 if (sel_list != NULL) {
605 GtkTreeRowReference *row_reference;
607 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
608 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
609 g_list_free (sel_list);
611 win = modest_msg_view_window_new_with_header_model (msg,
616 gtk_tree_row_reference_free (row_reference);
618 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
621 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
626 /* Register and show new window */
628 mgr = modest_runtime_get_window_mgr ();
629 modest_window_mgr_register_window (mgr, win);
630 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
631 gtk_widget_show_all (GTK_WIDGET(win));
636 g_object_unref (msg);
637 g_object_unref (folder);
638 g_object_unref (header);
642 * This function is the error handler of the
643 * modest_mail_operation_get_msgs_full operation
646 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
651 error = modest_mail_operation_get_error (mail_op);
652 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
653 GObject *win = modest_mail_operation_get_source (mail_op);
655 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
661 * This function is used by both modest_ui_actions_on_open and
662 * modest_ui_actions_on_header_activated. This way we always do the
663 * same when trying to open messages.
666 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
668 ModestWindowMgr *mgr;
670 ModestMailOperation *mail_op;
672 /* Look if we already have a message view for each header. If
673 true, then remove the header from the list of headers to
675 mgr = modest_runtime_get_window_mgr ();
676 iter = tny_list_create_iterator (headers);
677 while (!tny_iterator_is_done (iter)) {
678 ModestWindow *window;
681 header = TNY_HEADER (tny_iterator_get_current (iter));
682 window = modest_window_mgr_find_window_by_header (mgr, header);
684 /* Do not open again the message and present
685 the window to the user */
686 tny_list_remove (headers, G_OBJECT (header));
687 gtk_window_present (GTK_WINDOW (window));
690 g_object_unref (header);
691 tny_iterator_next (iter);
694 /* Open each message */
695 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
697 modest_ui_actions_get_msgs_full_error_handler,
699 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
700 modest_mail_operation_get_msgs_full (mail_op,
707 g_object_unref(mail_op);
711 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
716 headers = get_selected_headers (win);
721 _modest_ui_actions_open (headers, win);
723 g_object_unref(headers);
728 free_reply_forward_helper (gpointer data)
730 ReplyForwardHelper *helper;
732 helper = (ReplyForwardHelper *) data;
733 g_free (helper->account_name);
734 g_slice_free (ReplyForwardHelper, helper);
738 reply_forward_cb (ModestMailOperation *mail_op,
744 ReplyForwardHelper *rf_helper;
745 ModestWindow *msg_win;
746 ModestEditType edit_type;
748 TnyAccount *account = NULL;
749 ModestWindowMgr *mgr;
750 gchar *signature = NULL;
752 g_return_if_fail (user_data != NULL);
753 rf_helper = (ReplyForwardHelper *) user_data;
755 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
756 rf_helper->account_name);
757 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
758 rf_helper->account_name,
759 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
760 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
761 rf_helper->account_name,
762 MODEST_ACCOUNT_SIGNATURE, FALSE);
765 /* Create reply mail */
766 switch (rf_helper->action) {
769 modest_tny_msg_create_reply_msg (msg, from, signature,
770 rf_helper->reply_forward_type,
771 MODEST_TNY_MSG_REPLY_MODE_SENDER);
773 case ACTION_REPLY_TO_ALL:
775 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
776 MODEST_TNY_MSG_REPLY_MODE_ALL);
777 edit_type = MODEST_EDIT_TYPE_REPLY;
781 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
782 edit_type = MODEST_EDIT_TYPE_FORWARD;
785 g_return_if_reached ();
792 g_printerr ("modest: failed to create message\n");
796 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
797 rf_helper->account_name,
798 TNY_ACCOUNT_TYPE_STORE);
800 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
804 /* Create and register the windows */
805 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
806 mgr = modest_runtime_get_window_mgr ();
807 modest_window_mgr_register_window (mgr, msg_win);
809 if (rf_helper->parent_window != NULL) {
812 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
813 modest_window_set_zoom (msg_win, parent_zoom);
816 /* Show edit window */
817 gtk_widget_show_all (GTK_WIDGET (msg_win));
821 g_object_unref (G_OBJECT (new_msg));
823 g_object_unref (G_OBJECT (account));
824 g_object_unref (msg);
825 g_object_unref (header);
829 * Checks a list of headers. If any of them are not currently
830 * downloaded (CACHED) then it asks the user for permission to
833 * Returns FALSE if the user does not want to download the
834 * messages. Returns TRUE if the user allowed the download or if all
835 * of them are currently downloaded
838 download_uncached_messages (TnyList *header_list, GtkWindow *win)
841 gboolean found, retval;
843 iter = tny_list_create_iterator (header_list);
845 while (!tny_iterator_is_done (iter) && !found) {
847 TnyHeaderFlags flags;
849 header = TNY_HEADER (tny_iterator_get_current (iter));
850 flags = tny_header_get_flags (header);
851 /* TODO: is this the right flag?, it seems that some
852 headers that have been previously downloaded do not
854 found = !(flags & TNY_HEADER_FLAG_CACHED);
855 g_object_unref (header);
856 tny_iterator_next (iter);
858 g_object_unref (iter);
860 /* Ask for user permission to download the messages */
863 GtkResponseType response;
865 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
866 _("mcen_nc_get_multi_msg_txt"));
867 if (response == GTK_RESPONSE_CANCEL)
875 * Common code for the reply and forward actions
878 reply_forward (ReplyForwardAction action, ModestWindow *win)
880 ModestMailOperation *mail_op = NULL;
881 TnyList *header_list = NULL;
882 ReplyForwardHelper *rf_helper = NULL;
883 guint reply_forward_type;
884 gboolean continue_download;
886 g_return_if_fail (MODEST_IS_WINDOW(win));
888 header_list = get_selected_headers (win);
892 /* Check that the messages have been previously downloaded */
893 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
894 if (!continue_download) {
895 g_object_unref (header_list);
900 modest_conf_get_int (modest_runtime_get_conf (),
901 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
903 /* We assume that we can only select messages of the
904 same folder and that we reply all of them from the
905 same account. In fact the interface currently only
906 allows single selection */
909 rf_helper = g_slice_new0 (ReplyForwardHelper);
910 rf_helper->reply_forward_type = reply_forward_type;
911 rf_helper->action = action;
912 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
913 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
914 rf_helper->parent_window = GTK_WIDGET (win);
915 if (!rf_helper->account_name)
916 rf_helper->account_name =
917 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
919 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
922 /* Get header and message. Do not free them here, the
923 reply_forward_cb must do it */
924 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
925 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
926 if (!msg || !header) {
928 g_object_unref (msg);
930 g_object_unref (header);
931 g_printerr ("modest: no message found\n");
934 reply_forward_cb (NULL, header, msg, rf_helper);
936 /* Retrieve messages */
937 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
939 modest_ui_actions_get_msgs_full_error_handler,
941 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
942 modest_mail_operation_get_msgs_full (mail_op,
946 free_reply_forward_helper);
949 g_object_unref(mail_op);
953 g_object_unref (header_list);
957 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
959 g_return_if_fail (MODEST_IS_WINDOW(win));
961 reply_forward (ACTION_REPLY, win);
965 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
967 g_return_if_fail (MODEST_IS_WINDOW(win));
969 reply_forward (ACTION_FORWARD, win);
973 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
975 g_return_if_fail (MODEST_IS_WINDOW(win));
977 reply_forward (ACTION_REPLY_TO_ALL, win);
981 modest_ui_actions_on_next (GtkAction *action,
982 ModestWindow *window)
984 if (MODEST_IS_MAIN_WINDOW (window)) {
985 GtkWidget *header_view;
987 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
988 MODEST_WIDGET_TYPE_HEADER_VIEW);
992 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
993 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
994 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
996 g_return_if_reached ();
1001 modest_ui_actions_on_prev (GtkAction *action,
1002 ModestWindow *window)
1004 g_return_if_fail (MODEST_IS_WINDOW(window));
1006 if (MODEST_IS_MAIN_WINDOW (window)) {
1007 GtkWidget *header_view;
1008 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1009 MODEST_WIDGET_TYPE_HEADER_VIEW);
1013 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1014 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1015 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1017 g_return_if_reached ();
1022 modest_ui_actions_on_sort (GtkAction *action,
1023 ModestWindow *window)
1025 g_return_if_fail (MODEST_IS_WINDOW(window));
1027 if (MODEST_IS_MAIN_WINDOW (window)) {
1028 GtkWidget *header_view;
1029 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1030 MODEST_WIDGET_TYPE_HEADER_VIEW);
1034 /* Show sorting dialog */
1035 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1040 * This function performs the send & receive required actions. The
1041 * window is used to create the mail operation. Typically it should
1042 * always be the main window, but we pass it as argument in order to
1046 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1048 gchar *acc_name = NULL;
1049 ModestMailOperation *mail_op;
1051 /* If no account name was provided then get the current account, and if
1052 there is no current account then pick the default one: */
1053 if (!account_name) {
1054 acc_name = g_strdup (modest_window_get_active_account(win));
1056 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1058 g_printerr ("modest: cannot get default account\n");
1062 acc_name = g_strdup (account_name);
1065 /* Set send/receive operation in progress */
1066 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1068 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1069 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1070 G_CALLBACK (_on_send_receive_progress_changed),
1073 /* Send & receive. */
1074 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1075 /* Receive and then send. The operation is tagged initially as
1076 a receive operation because the account update performs a
1077 receive and then a send. The operation changes its type
1078 internally, so the progress objects will receive the proper
1079 progress information */
1080 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1081 modest_mail_operation_update_account (mail_op, acc_name);
1082 g_object_unref (G_OBJECT (mail_op));
1089 * Refreshes all accounts. This function will be used by automatic
1093 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1095 GSList *account_names, *iter;
1097 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1100 iter = account_names;
1102 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1103 iter = g_slist_next (iter);
1106 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1107 g_slist_free (account_names);
1111 * Handler of the click on Send&Receive button in the main toolbar
1114 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1116 /* Check if accounts exist */
1117 gboolean accounts_exist =
1118 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1120 /* If not, allow the user to create an account before trying to send/receive. */
1121 if (!accounts_exist)
1122 modest_ui_actions_on_accounts (NULL, win);
1124 /* Refresh the active account */
1125 modest_ui_actions_do_send_receive (NULL, win);
1130 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1133 GtkWidget *header_view;
1135 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1137 header_view = modest_main_window_get_child_widget (main_window,
1138 MODEST_WIDGET_TYPE_HEADER_VIEW);
1142 conf = modest_runtime_get_conf ();
1144 /* what is saved/restored is depending on the style; thus; we save with
1145 * old style, then update the style, and restore for this new style
1147 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1149 if (modest_header_view_get_style
1150 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1151 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1152 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1154 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1155 MODEST_HEADER_VIEW_STYLE_DETAILS);
1157 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1158 MODEST_CONF_HEADER_VIEW_KEY);
1163 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1165 ModestMainWindow *main_window)
1167 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1168 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1170 /* If no header has been selected then exit */
1174 /* Update Main window title */
1175 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1176 const gchar *subject = tny_header_get_subject (header);
1177 if (subject && strlen(subject) > 0)
1178 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1180 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1183 /* Update toolbar dimming state */
1184 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1188 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1190 ModestMainWindow *main_window)
1194 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1199 headers = tny_simple_list_new ();
1200 tny_list_prepend (headers, G_OBJECT (header));
1202 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1204 g_object_unref (headers);
1208 set_active_account_from_tny_account (TnyAccount *account,
1209 ModestWindow *window)
1211 const gchar *server_acc_name = tny_account_get_id (account);
1213 /* We need the TnyAccount provided by the
1214 account store because that is the one that
1215 knows the name of the Modest account */
1216 TnyAccount *modest_server_account = modest_server_account =
1217 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1220 const gchar *modest_acc_name =
1221 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1222 modest_window_set_active_account (window, modest_acc_name);
1223 g_object_unref (modest_server_account);
1227 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1228 TnyFolderStore *folder_store,
1230 ModestMainWindow *main_window)
1233 GtkWidget *header_view;
1234 gboolean folder_empty = FALSE;
1236 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1238 header_view = modest_main_window_get_child_widget(main_window,
1239 MODEST_WIDGET_TYPE_HEADER_VIEW);
1243 conf = modest_runtime_get_conf ();
1245 if (TNY_IS_ACCOUNT (folder_store)) {
1246 /* Update active account */
1247 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1248 /* Show account details */
1249 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1251 if (TNY_IS_FOLDER (folder_store) && selected) {
1253 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1254 /* Update the active account */
1255 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1256 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1257 g_object_unref (account);
1261 /* Set folder on header view */
1262 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1263 TNY_FOLDER (folder_store));
1265 /* Set main view style */
1266 folder_empty = tny_folder_get_all_count (TNY_FOLDER (folder_store)) == 0;
1268 modest_main_window_set_contents_style (main_window,
1269 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1272 modest_main_window_set_contents_style (main_window,
1273 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1274 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1275 MODEST_CONF_HEADER_VIEW_KEY);
1278 /* Update the active account */
1279 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1280 /* Do not show folder */
1281 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1282 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1286 /* Update toolbar dimming state */
1287 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1291 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1298 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1300 if (g_main_depth > 0)
1301 gdk_threads_enter ();
1302 online = tny_device_is_online (modest_runtime_get_device());
1305 /* already online -- the item is simply not there... */
1306 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1308 GTK_MESSAGE_WARNING,
1310 _("The %s you selected cannot be found"),
1312 gtk_dialog_run (GTK_DIALOG(dialog));
1314 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1318 GTK_RESPONSE_REJECT,
1320 GTK_RESPONSE_ACCEPT,
1322 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1323 "Do you want to get online?"), item);
1324 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1325 gtk_label_new (txt), FALSE, FALSE, 0);
1326 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1329 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1330 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1331 // modest_platform_connect_and_wait ();;
1334 gtk_widget_destroy (dialog);
1335 if (g_main_depth > 0)
1336 gdk_threads_leave ();
1340 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1343 /* g_message ("%s %s", __FUNCTION__, link); */
1348 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1351 modest_platform_activate_uri (link);
1355 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1358 modest_platform_show_uri_popup (link);
1362 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1365 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1369 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1370 const gchar *address,
1373 /* g_message ("%s %s", __FUNCTION__, address); */
1377 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1379 TnyTransportAccount *transport_account;
1380 ModestMailOperation *mail_operation;
1382 gchar *account_name, *from;
1383 ModestAccountMgr *account_mgr;
1385 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1387 data = modest_msg_edit_window_get_msg_data (edit_window);
1389 account_mgr = modest_runtime_get_account_mgr();
1390 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1392 account_name = modest_account_mgr_get_default_account (account_mgr);
1393 if (!account_name) {
1394 g_printerr ("modest: no account found\n");
1395 modest_msg_edit_window_free_msg_data (edit_window, data);
1399 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1400 account_name = g_strdup (data->account_name);
1404 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1405 (modest_runtime_get_account_store(),
1407 TNY_ACCOUNT_TYPE_TRANSPORT));
1408 if (!transport_account) {
1409 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1410 g_free (account_name);
1411 modest_msg_edit_window_free_msg_data (edit_window, data);
1414 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1416 /* Create the mail operation */
1417 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1418 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1420 modest_mail_operation_save_to_drafts (mail_operation,
1431 data->priority_flags);
1434 g_free (account_name);
1435 g_object_unref (G_OBJECT (transport_account));
1436 g_object_unref (G_OBJECT (mail_operation));
1438 modest_msg_edit_window_free_msg_data (edit_window, data);
1440 /* Save settings and close the window */
1441 gtk_widget_destroy (GTK_WIDGET (edit_window));
1444 /* For instance, when clicking the Send toolbar button when editing a message: */
1446 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1448 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1450 if (!modest_msg_edit_window_check_names (edit_window))
1453 /* FIXME: Code added just for testing. The final version will
1454 use the send queue provided by tinymail and some
1456 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1457 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1459 account_name = modest_account_mgr_get_default_account (account_mgr);
1461 if (!account_name) {
1462 g_printerr ("modest: no account found\n");
1466 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1468 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1469 account_name = g_strdup (data->account_name);
1472 /* Get the currently-active transport account for this modest account: */
1473 TnyTransportAccount *transport_account =
1474 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1475 (modest_runtime_get_account_store(),
1477 if (!transport_account) {
1478 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1479 g_free (account_name);
1480 modest_msg_edit_window_free_msg_data (edit_window, data);
1484 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1486 /* mail content checks and dialogs */
1487 if (data->subject == NULL || data->subject[0] == '\0') {
1488 GtkResponseType response;
1489 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1490 _("mcen_nc_subject_is_empty_send"));
1491 if (response == GTK_RESPONSE_CANCEL) {
1492 g_free (account_name);
1497 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1498 GtkResponseType response;
1499 gchar *note_message;
1500 gchar *note_subject = data->subject;
1501 if (note_subject == NULL || note_subject[0] == '\0')
1502 note_subject = _("mail_va_no_subject");
1503 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1504 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1506 g_free (note_message);
1507 if (response == GTK_RESPONSE_CANCEL) {
1508 g_free (account_name);
1513 /* Create the mail operation */
1514 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1515 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1517 modest_mail_operation_send_new_mail (mail_operation,
1528 data->priority_flags);
1532 g_free (account_name);
1533 g_object_unref (G_OBJECT (transport_account));
1534 g_object_unref (G_OBJECT (mail_operation));
1536 modest_msg_edit_window_free_msg_data (edit_window, data);
1538 /* Save settings and close the window: */
1539 gtk_widget_destroy (GTK_WIDGET (edit_window));
1543 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1544 ModestMsgEditWindow *window)
1546 ModestMsgEditFormatState *format_state = NULL;
1548 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1549 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1551 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1554 format_state = modest_msg_edit_window_get_format_state (window);
1555 g_return_if_fail (format_state != NULL);
1557 format_state->bold = gtk_toggle_action_get_active (action);
1558 modest_msg_edit_window_set_format_state (window, format_state);
1559 g_free (format_state);
1564 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1565 ModestMsgEditWindow *window)
1567 ModestMsgEditFormatState *format_state = NULL;
1569 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1570 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1572 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1575 format_state = modest_msg_edit_window_get_format_state (window);
1576 g_return_if_fail (format_state != NULL);
1578 format_state->italics = gtk_toggle_action_get_active (action);
1579 modest_msg_edit_window_set_format_state (window, format_state);
1580 g_free (format_state);
1585 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1586 ModestMsgEditWindow *window)
1588 ModestMsgEditFormatState *format_state = NULL;
1590 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1591 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1593 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1596 format_state = modest_msg_edit_window_get_format_state (window);
1597 g_return_if_fail (format_state != NULL);
1599 format_state->bullet = gtk_toggle_action_get_active (action);
1600 modest_msg_edit_window_set_format_state (window, format_state);
1601 g_free (format_state);
1606 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1607 GtkRadioAction *selected,
1608 ModestMsgEditWindow *window)
1610 ModestMsgEditFormatState *format_state = NULL;
1611 GtkJustification value;
1613 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1615 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1618 value = gtk_radio_action_get_current_value (selected);
1620 format_state = modest_msg_edit_window_get_format_state (window);
1621 g_return_if_fail (format_state != NULL);
1623 format_state->justification = value;
1624 modest_msg_edit_window_set_format_state (window, format_state);
1625 g_free (format_state);
1629 modest_ui_actions_on_select_editor_color (GtkAction *action,
1630 ModestMsgEditWindow *window)
1632 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1633 g_return_if_fail (GTK_IS_ACTION (action));
1635 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1638 modest_msg_edit_window_select_color (window);
1642 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1643 ModestMsgEditWindow *window)
1645 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1646 g_return_if_fail (GTK_IS_ACTION (action));
1648 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1651 modest_msg_edit_window_select_background_color (window);
1655 modest_ui_actions_on_insert_image (GtkAction *action,
1656 ModestMsgEditWindow *window)
1658 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1659 g_return_if_fail (GTK_IS_ACTION (action));
1661 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1664 modest_msg_edit_window_insert_image (window);
1668 modest_ui_actions_on_attach_file (GtkAction *action,
1669 ModestMsgEditWindow *window)
1671 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1672 g_return_if_fail (GTK_IS_ACTION (action));
1674 modest_msg_edit_window_attach_file (window);
1678 modest_ui_actions_on_remove_attachments (GtkAction *action,
1679 ModestMsgEditWindow *window)
1681 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1682 g_return_if_fail (GTK_IS_ACTION (action));
1684 modest_msg_edit_window_remove_attachments (window, NULL);
1688 * Shows a dialog with an entry that asks for some text. The returned
1689 * value must be freed by the caller. The dialog window title will be
1693 ask_for_folder_name (GtkWindow *parent_window,
1696 GtkWidget *dialog, *entry;
1697 gchar *folder_name = NULL;
1699 /* Ask for folder name */
1700 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1704 GTK_RESPONSE_REJECT,
1706 GTK_RESPONSE_ACCEPT,
1708 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1709 gtk_label_new(title),
1712 entry = gtk_entry_new_with_max_length (40);
1713 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1717 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1719 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1720 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1722 gtk_widget_destroy (dialog);
1728 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1730 TnyFolderStore *parent_folder;
1731 GtkWidget *folder_view;
1733 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1735 folder_view = modest_main_window_get_child_widget (main_window,
1736 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1740 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1742 if (parent_folder) {
1743 gboolean finished = FALSE;
1745 gchar *folder_name = NULL, *suggested_name = NULL;
1747 /* Run the new folder dialog */
1749 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1754 if (result == GTK_RESPONSE_REJECT) {
1757 ModestMailOperation *mail_op;
1758 TnyFolder *new_folder = NULL;
1760 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1761 G_OBJECT(main_window));
1762 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1764 new_folder = modest_mail_operation_create_folder (mail_op,
1766 (const gchar *) folder_name);
1768 g_object_unref (new_folder);
1771 g_object_unref (mail_op);
1773 g_free (folder_name);
1777 g_object_unref (parent_folder);
1782 modest_ui_actions_on_rename_folder (GtkAction *action,
1783 ModestMainWindow *main_window)
1785 TnyFolderStore *folder;
1786 GtkWidget *folder_view;
1787 GtkWidget *header_view;
1789 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1791 folder_view = modest_main_window_get_child_widget (main_window,
1792 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1796 header_view = modest_main_window_get_child_widget (main_window,
1797 MODEST_WIDGET_TYPE_HEADER_VIEW);
1802 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1804 if (folder && TNY_IS_FOLDER (folder)) {
1806 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1807 _("Please enter a new name for the folder"));
1809 if (folder_name != NULL && strlen (folder_name) > 0) {
1810 ModestMailOperation *mail_op;
1812 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1813 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1816 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1818 modest_mail_operation_rename_folder (mail_op,
1819 TNY_FOLDER (folder),
1820 (const gchar *) folder_name);
1822 g_object_unref (mail_op);
1823 g_free (folder_name);
1825 g_object_unref (folder);
1830 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1833 GObject *win = modest_mail_operation_get_source (mail_op);
1835 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1836 _("mail_in_ui_folder_delete_error"));
1840 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1842 TnyFolderStore *folder;
1843 GtkWidget *folder_view;
1847 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1849 folder_view = modest_main_window_get_child_widget (main_window,
1850 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1854 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1856 /* Show an error if it's an account */
1857 if (!TNY_IS_FOLDER (folder)) {
1858 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1859 _("mail_in_ui_folder_delete_error"));
1864 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1865 tny_folder_get_name (TNY_FOLDER (folder)));
1866 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1867 (const gchar *) message);
1870 if (response == GTK_RESPONSE_OK) {
1871 ModestMailOperation *mail_op =
1872 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1873 G_OBJECT(main_window),
1874 modest_ui_actions_delete_folder_error_handler,
1877 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1879 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1880 g_object_unref (G_OBJECT (mail_op));
1883 g_object_unref (G_OBJECT (folder));
1887 modest_ui_actions_on_delete_folder (GtkAction *action,
1888 ModestMainWindow *main_window)
1890 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1892 delete_folder (main_window, FALSE);
1896 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1898 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1900 delete_folder (main_window, TRUE);
1904 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1905 const gchar* server_account_name,
1910 ModestMainWindow *main_window)
1912 g_return_if_fail(server_account_name);
1913 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1915 /* Initalize output parameters: */
1922 #ifdef MODEST_PLATFORM_MAEMO
1923 /* Maemo uses a different (awkward) button order,
1924 * It should probably just use gtk_alternative_dialog_button_order ().
1926 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1930 GTK_RESPONSE_ACCEPT,
1932 GTK_RESPONSE_REJECT,
1935 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1939 GTK_RESPONSE_REJECT,
1941 GTK_RESPONSE_ACCEPT,
1943 #endif /* MODEST_PLATFORM_MAEMO */
1945 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1947 gchar *server_name = modest_server_account_get_hostname (
1948 modest_runtime_get_account_mgr(), server_account_name);
1949 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
1950 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
1955 /* This causes a warning because the logical ID has no %s in it,
1956 * though the translation does, but there is not much we can do about that: */
1957 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1958 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1961 g_free (server_name);
1965 gchar *initial_username = modest_server_account_get_username (
1966 modest_runtime_get_account_mgr(), server_account_name);
1968 GtkWidget *entry_username = gtk_entry_new ();
1969 if (initial_username)
1970 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1971 /* Dim this if a connection has ever succeeded with this username,
1972 * as per the UI spec: */
1973 const gboolean username_known =
1974 modest_server_account_get_username_has_succeeded(
1975 modest_runtime_get_account_mgr(), server_account_name);
1976 gtk_widget_set_sensitive (entry_username, !username_known);
1978 #ifdef MODEST_PLATFORM_MAEMO
1979 /* Auto-capitalization is the default, so let's turn it off: */
1980 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1982 /* Create a size group to be used by all captions.
1983 * Note that HildonCaption does not create a default size group if we do not specify one.
1984 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1985 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1987 GtkWidget *caption = hildon_caption_new (sizegroup,
1988 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1989 gtk_widget_show (entry_username);
1990 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1991 FALSE, FALSE, MODEST_MARGIN_HALF);
1992 gtk_widget_show (caption);
1994 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1996 #endif /* MODEST_PLATFORM_MAEMO */
1999 GtkWidget *entry_password = gtk_entry_new ();
2000 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2001 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2003 #ifdef MODEST_PLATFORM_MAEMO
2004 /* Auto-capitalization is the default, so let's turn it off: */
2005 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2006 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2008 caption = hildon_caption_new (sizegroup,
2009 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2010 gtk_widget_show (entry_password);
2011 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2012 FALSE, FALSE, MODEST_MARGIN_HALF);
2013 gtk_widget_show (caption);
2014 g_object_unref (sizegroup);
2016 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2018 #endif /* MODEST_PLATFORM_MAEMO */
2020 /* This is not in the Maemo UI spec:
2021 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2022 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2026 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2028 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2030 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2032 modest_server_account_set_username (
2033 modest_runtime_get_account_mgr(), server_account_name,
2036 const gboolean username_was_changed =
2037 (strcmp (*username, initial_username) != 0);
2038 if (username_was_changed) {
2039 /* To actually use a changed username,
2040 * we must reset the connection, according to pvanhoof.
2041 * This _might_ be a sensible way to do that: */
2042 TnyDevice *device = modest_runtime_get_device();
2043 tny_device_force_offline (device);
2044 tny_device_force_online (device);
2049 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2051 /* We do not save the password in the configuration,
2052 * because this function is only called for passwords that should
2053 * not be remembered:
2054 modest_server_account_set_password (
2055 modest_runtime_get_account_mgr(), server_account_name,
2074 /* This is not in the Maemo UI spec:
2075 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2081 gtk_widget_destroy (dialog);
2083 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2087 modest_ui_actions_on_cut (GtkAction *action,
2088 ModestWindow *window)
2090 GtkWidget *focused_widget;
2092 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2093 if (GTK_IS_EDITABLE (focused_widget)) {
2094 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2095 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2096 GtkTextBuffer *buffer;
2097 GtkClipboard *clipboard;
2099 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2100 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2101 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2106 modest_ui_actions_on_copy (GtkAction *action,
2107 ModestWindow *window)
2109 GtkClipboard *clipboard;
2110 GtkWidget *focused_widget;
2112 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2113 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2114 if (GTK_IS_LABEL (focused_widget)) {
2115 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2116 } else if (GTK_IS_EDITABLE (focused_widget)) {
2117 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2118 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2119 GtkTextBuffer *buffer;
2121 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2122 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2127 modest_ui_actions_on_undo (GtkAction *action,
2128 ModestWindow *window)
2130 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2131 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2133 g_return_if_reached ();
2138 modest_ui_actions_on_paste (GtkAction *action,
2139 ModestWindow *window)
2141 GtkWidget *focused_widget;
2143 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2144 if (GTK_IS_EDITABLE (focused_widget)) {
2145 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2146 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2147 GtkTextBuffer *buffer;
2148 GtkClipboard *clipboard;
2150 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2151 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2152 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2157 modest_ui_actions_on_select_all (GtkAction *action,
2158 ModestWindow *window)
2160 GtkWidget *focused_widget;
2162 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2163 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2164 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2165 } else if (GTK_IS_LABEL (focused_widget)) {
2166 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2167 } else if (GTK_IS_EDITABLE (focused_widget)) {
2168 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2169 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2170 GtkTextBuffer *buffer;
2171 GtkTextIter start, end;
2173 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2174 gtk_text_buffer_get_start_iter (buffer, &start);
2175 gtk_text_buffer_get_end_iter (buffer, &end);
2176 gtk_text_buffer_select_range (buffer, &start, &end);
2178 else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2179 (MODEST_IS_HEADER_VIEW (focused_widget))) {
2181 GtkTreeSelection *selection = NULL;
2183 /* Get header view */
2184 GtkWidget *header_view = focused_widget;
2185 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2186 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2187 MODEST_WIDGET_TYPE_HEADER_VIEW);
2189 /* Select all messages */
2190 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2191 gtk_tree_selection_select_all (selection);
2196 modest_ui_actions_on_mark_as_read (GtkAction *action,
2197 ModestWindow *window)
2199 g_return_if_fail (MODEST_IS_WINDOW(window));
2201 /* Mark each header as read */
2202 do_headers_action (window, headers_action_mark_as_read, NULL);
2206 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2207 ModestWindow *window)
2209 g_return_if_fail (MODEST_IS_WINDOW(window));
2211 /* Mark each header as read */
2212 do_headers_action (window, headers_action_mark_as_unread, NULL);
2216 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2217 GtkRadioAction *selected,
2218 ModestWindow *window)
2222 value = gtk_radio_action_get_current_value (selected);
2223 if (MODEST_IS_WINDOW (window)) {
2224 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2228 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2229 GtkRadioAction *selected,
2230 ModestWindow *window)
2232 TnyHeaderFlags flags;
2233 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2235 flags = gtk_radio_action_get_current_value (selected);
2236 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2239 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2240 GtkRadioAction *selected,
2241 ModestWindow *window)
2245 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2247 file_format = gtk_radio_action_get_current_value (selected);
2248 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2253 modest_ui_actions_on_zoom_plus (GtkAction *action,
2254 ModestWindow *window)
2256 g_return_if_fail (MODEST_IS_WINDOW (window));
2258 modest_window_zoom_plus (MODEST_WINDOW (window));
2262 modest_ui_actions_on_zoom_minus (GtkAction *action,
2263 ModestWindow *window)
2265 g_return_if_fail (MODEST_IS_WINDOW (window));
2267 modest_window_zoom_minus (MODEST_WINDOW (window));
2271 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2272 ModestWindow *window)
2274 ModestWindowMgr *mgr;
2275 gboolean fullscreen, active;
2276 g_return_if_fail (MODEST_IS_WINDOW (window));
2278 mgr = modest_runtime_get_window_mgr ();
2280 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2281 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2283 if (active != fullscreen) {
2284 modest_window_mgr_set_fullscreen_mode (mgr, active);
2285 gtk_window_present (GTK_WINDOW (window));
2290 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2291 ModestWindow *window)
2293 ModestWindowMgr *mgr;
2294 gboolean fullscreen;
2296 g_return_if_fail (MODEST_IS_WINDOW (window));
2298 mgr = modest_runtime_get_window_mgr ();
2299 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2300 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2302 gtk_window_present (GTK_WINDOW (window));
2306 * Used by modest_ui_actions_on_details to call do_headers_action
2309 headers_action_show_details (TnyHeader *header,
2310 ModestWindow *window,
2317 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2320 gtk_widget_show_all (dialog);
2321 gtk_dialog_run (GTK_DIALOG (dialog));
2323 gtk_widget_destroy (dialog);
2327 * Show the folder details in a ModestDetailsDialog widget
2330 show_folder_details (TnyFolder *folder,
2336 dialog = modest_details_dialog_new_with_folder (window, folder);
2339 gtk_widget_show_all (dialog);
2340 gtk_dialog_run (GTK_DIALOG (dialog));
2342 gtk_widget_destroy (dialog);
2346 * Show the header details in a ModestDetailsDialog widget
2349 modest_ui_actions_on_details (GtkAction *action,
2352 TnyList * headers_list;
2356 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2359 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2362 g_object_unref (msg);
2364 headers_list = get_selected_headers (win);
2368 iter = tny_list_create_iterator (headers_list);
2370 header = TNY_HEADER (tny_iterator_get_current (iter));
2371 headers_action_show_details (header, win, NULL);
2372 g_object_unref (header);
2374 g_object_unref (iter);
2375 g_object_unref (headers_list);
2377 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2378 GtkWidget *folder_view, *header_view;
2380 /* Check which widget has the focus */
2381 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2382 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2383 if (gtk_widget_is_focus (folder_view)) {
2386 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2388 /* Show only when it's a folder */
2389 if (!folder || !TNY_IS_FOLDER (folder))
2392 show_folder_details (folder, GTK_WINDOW (win));
2395 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2396 MODEST_WIDGET_TYPE_HEADER_VIEW);
2397 /* Show details of each header */
2398 do_headers_action (win, headers_action_show_details, header_view);
2404 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2405 ModestMsgEditWindow *window)
2407 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2409 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2413 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2414 ModestMsgEditWindow *window)
2416 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2418 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2422 modest_ui_actions_toggle_folders_view (GtkAction *action,
2423 ModestMainWindow *main_window)
2427 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2429 conf = modest_runtime_get_conf ();
2431 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2432 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2434 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2438 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2439 ModestWindow *window)
2441 gboolean active, fullscreen = FALSE;
2442 ModestWindowMgr *mgr;
2444 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2446 /* Check if we want to toggle the toolbar vuew in fullscreen
2448 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2449 "ViewShowToolbarFullScreen")) {
2453 /* Toggle toolbar */
2454 mgr = modest_runtime_get_window_mgr ();
2455 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2459 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2460 ModestMsgEditWindow *window)
2462 modest_msg_edit_window_select_font (window);
2466 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2467 const gchar *display_name,
2470 /* Do not change the application name if the widget has not
2471 the focus. This callback could be called even if the folder
2472 view has not the focus, because the handled signal could be
2473 emitted when the folder view is redrawn */
2474 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2476 gtk_window_set_title (window, display_name);
2478 gtk_window_set_title (window, " ");
2483 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2485 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2486 modest_msg_edit_window_select_contacts (window);
2490 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2492 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2493 modest_msg_edit_window_check_names (window);
2498 create_move_to_dialog (ModestWindow *win,
2499 GtkWidget *folder_view,
2500 GtkWidget **tree_view)
2502 GtkWidget *dialog, *scroll;
2504 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2506 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2508 GTK_RESPONSE_ACCEPT,
2510 GTK_RESPONSE_REJECT,
2513 /* Create scrolled window */
2514 scroll = gtk_scrolled_window_new (NULL, NULL);
2515 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2516 GTK_POLICY_AUTOMATIC,
2517 GTK_POLICY_AUTOMATIC);
2519 /* Create folder view */
2520 *tree_view = modest_folder_view_new (NULL);
2521 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2522 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2523 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2525 /* Add scroll to dialog */
2526 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2527 scroll, FALSE, FALSE, 0);
2529 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2535 * Returns TRUE if at least one of the headers of the list belongs to
2536 * a message that has been fully retrieved.
2539 has_retrieved_msgs (TnyList *list)
2542 gboolean found = FALSE;
2544 iter = tny_list_create_iterator (list);
2545 while (tny_iterator_is_done (iter) && !found) {
2547 TnyHeaderFlags flags;
2549 header = TNY_HEADER (tny_iterator_get_current (iter));
2550 flags = tny_header_get_flags (header);
2551 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2555 tny_iterator_next (iter);
2557 g_object_unref (iter);
2563 * Shows a confirmation dialog to the user when we're moving messages
2564 * from a remote server to the local storage. Returns the dialog
2565 * response. If it's other kind of movement the it always returns
2569 msgs_move_to_confirmation (GtkWindow *win,
2570 TnyFolder *dest_folder,
2573 gint response = GTK_RESPONSE_OK;
2575 /* If the destination is a local folder */
2576 if (modest_tny_folder_is_local_folder (dest_folder)) {
2577 TnyFolder *src_folder;
2581 /* Get source folder */
2582 iter = tny_list_create_iterator (headers);
2583 header = TNY_HEADER (tny_iterator_get_current (iter));
2584 src_folder = tny_header_get_folder (header);
2585 g_object_unref (header);
2586 g_object_unref (iter);
2588 /* If the source is a remote folder */
2589 if (!modest_tny_folder_is_local_folder (src_folder)) {
2590 const gchar *message;
2592 if (tny_list_get_length (headers) == 1)
2593 if (has_retrieved_msgs (headers))
2594 message = _("mcen_nc_move_retrieve");
2596 message = _("mcen_nc_move_header");
2598 if (has_retrieved_msgs (headers))
2599 message = _("mcen_nc_move_retrieves");
2601 message = _("mcen_nc_move_headers");
2603 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2604 (const gchar *) message);
2606 g_object_unref (src_folder);
2613 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2615 ModestMsgViewWindow *self = NULL;
2616 gboolean found = FALSE;
2618 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2619 self = MODEST_MSG_VIEW_WINDOW (object);
2621 found = modest_msg_view_window_select_first_message (self);
2622 g_return_if_fail (found);
2626 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2629 GObject *win = modest_mail_operation_get_source (mail_op);
2631 /* TODO: show error message */
2632 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2633 _("mail_in_ui_folder_move_target_error"));
2637 * UI handler for the "Move to" action when invoked from the
2641 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2642 ModestMainWindow *win)
2644 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2645 GtkWidget *header_view = NULL;
2647 TnyFolderStore *folder_store = NULL;
2648 ModestMailOperation *mail_op = NULL;
2650 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2652 /* Get the folder view */
2653 folder_view = modest_main_window_get_child_widget (win,
2654 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2656 /* Get header view */
2657 header_view = modest_main_window_get_child_widget (win,
2658 MODEST_WIDGET_TYPE_HEADER_VIEW);
2660 /* Create and run the dialog */
2661 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2662 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
2663 result = gtk_dialog_run (GTK_DIALOG(dialog));
2664 g_object_ref (tree_view);
2666 /* We do this to save an indentation level ;-) */
2667 if (result != GTK_RESPONSE_ACCEPT)
2670 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2672 if (TNY_IS_ACCOUNT (folder_store))
2675 /* Get folder or messages to transfer */
2676 if (gtk_widget_is_focus (folder_view)) {
2677 TnyFolderStore *src_folder;
2678 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2680 /* Clean folder on header view before moving it */
2681 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2683 if (TNY_IS_FOLDER (src_folder)) {
2685 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2687 modest_ui_actions_move_folder_error_handler,
2689 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2691 modest_mail_operation_xfer_folder (mail_op,
2692 TNY_FOLDER (src_folder),
2695 /* Unref mail operation */
2696 g_object_unref (G_OBJECT (mail_op));
2700 g_object_unref (G_OBJECT (src_folder));
2702 if (gtk_widget_is_focus (header_view)) {
2706 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2708 /* Ask for user confirmation */
2709 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2710 TNY_FOLDER (folder_store),
2713 /* Transfer messages */
2714 if (response == GTK_RESPONSE_OK) {
2715 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2716 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2719 modest_mail_operation_xfer_msgs (mail_op,
2721 TNY_FOLDER (folder_store),
2726 g_object_unref (G_OBJECT (mail_op));
2728 g_object_unref (headers);
2731 g_object_unref (folder_store);
2733 gtk_widget_destroy (dialog);
2738 * UI handler for the "Move to" action when invoked from the
2739 * ModestMsgViewWindow
2742 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2743 ModestMsgViewWindow *win)
2745 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2747 ModestMainWindow *main_window;
2751 /* Get the folder view */
2752 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2753 folder_view = modest_main_window_get_child_widget (main_window,
2754 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2756 /* Create and run the dialog */
2757 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2758 result = gtk_dialog_run (GTK_DIALOG(dialog));
2759 g_object_ref (tree_view);
2761 if (result == GTK_RESPONSE_ACCEPT) {
2762 TnyFolderStore *folder_store;
2765 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2767 /* Create header list */
2768 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2769 headers = tny_simple_list_new ();
2770 tny_list_prepend (headers, G_OBJECT (header));
2771 g_object_unref (header);
2773 /* Ask user for confirmation. MSG-NOT404 */
2774 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2775 TNY_FOLDER (folder_store),
2778 /* Transfer current msg */
2779 if (response == GTK_RESPONSE_OK) {
2780 ModestMailOperation *mail_op;
2782 /* Create mail op */
2783 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2784 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2787 /* Transfer messages */
2788 modest_mail_operation_xfer_msgs (mail_op,
2790 TNY_FOLDER (folder_store),
2792 tranasfer_msgs_from_viewer_cb,
2794 g_object_unref (G_OBJECT (mail_op));
2796 g_object_unref (headers);
2797 g_object_unref (folder_store);
2799 gtk_widget_destroy (dialog);
2803 modest_ui_actions_on_move_to (GtkAction *action,
2806 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2807 MODEST_IS_MSG_VIEW_WINDOW (win));
2809 if (MODEST_IS_MAIN_WINDOW (win))
2810 modest_ui_actions_on_main_window_move_to (action,
2811 MODEST_MAIN_WINDOW (win));
2813 modest_ui_actions_on_msg_view_window_move_to (action,
2814 MODEST_MSG_VIEW_WINDOW (win));
2818 * Calls #HeadersFunc for each header already selected in the main
2819 * window or the message currently being shown in the msg view window
2822 do_headers_action (ModestWindow *win,
2826 TnyList *headers_list;
2830 headers_list = get_selected_headers (win);
2834 /* Call the function for each header */
2835 iter = tny_list_create_iterator (headers_list);
2836 while (!tny_iterator_is_done (iter)) {
2839 header = TNY_HEADER (tny_iterator_get_current (iter));
2840 func (header, win, user_data);
2841 g_object_unref (header);
2842 tny_iterator_next (iter);
2844 g_object_unref (iter);
2845 g_object_unref (headers_list);
2849 modest_ui_actions_view_attachment (GtkAction *action,
2850 ModestWindow *window)
2852 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2853 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2855 /* not supported window for this action */
2856 g_return_if_reached ();
2861 modest_ui_actions_save_attachments (GtkAction *action,
2862 ModestWindow *window)
2864 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2865 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2867 /* not supported window for this action */
2868 g_return_if_reached ();
2873 modest_ui_actions_remove_attachments (GtkAction *action,
2874 ModestWindow *window)
2876 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2877 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2879 /* not supported window for this action */
2880 g_return_if_reached ();
2885 modest_ui_actions_on_settings (GtkAction *action,
2890 dialog = modest_platform_get_global_settings_dialog ();
2891 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2892 gtk_widget_show (dialog);
2894 gtk_dialog_run (GTK_DIALOG (dialog));
2896 gtk_widget_destroy (dialog);
2900 modest_ui_actions_on_help (GtkAction *action,
2903 const gchar *help_id = NULL;
2905 if (MODEST_IS_MAIN_WINDOW (win)) {
2906 const gchar *action_name;
2907 action_name = gtk_action_get_name (action);
2909 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2910 !strcmp (action_name, "HeaderViewCSMHelp")) {
2911 GtkWidget *folder_view;
2912 TnyFolderStore *folder_store;
2913 /* Get selected folder */
2914 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2915 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2916 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2918 /* Switch help_id */
2919 if (TNY_IS_FOLDER (folder_store)) {
2920 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2921 case TNY_FOLDER_TYPE_NORMAL:
2922 help_id = "applications_email_userfolder";
2924 case TNY_FOLDER_TYPE_INBOX:
2925 help_id = "applications_email_inbox";
2927 case TNY_FOLDER_TYPE_OUTBOX:
2928 help_id = "applications_email_outbox";
2930 case TNY_FOLDER_TYPE_SENT:
2931 help_id = "applications_email_sent";
2933 case TNY_FOLDER_TYPE_DRAFTS:
2934 help_id = "applications_email_drafts";
2936 case TNY_FOLDER_TYPE_ARCHIVE:
2937 help_id = "applications_email_archive";
2944 help_id = "applications_email_mainview";
2946 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2947 help_id = "applications_email_viewer";
2948 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2949 help_id = "applications_email_editor";
2951 modest_platform_show_help (GTK_WINDOW (win), help_id);
2955 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2956 ModestWindow *window)
2958 ModestMailOperation *mail_op;
2962 headers = get_selected_headers (window);
2966 /* Create mail operation */
2967 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2969 modest_ui_actions_get_msgs_full_error_handler,
2971 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2972 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2975 g_object_unref (headers);
2976 g_object_unref (mail_op);
2980 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2981 ModestWindow *window)
2983 g_return_if_fail (MODEST_IS_WINDOW (window));
2986 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
2990 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
2991 ModestWindow *window)
2993 g_return_if_fail (MODEST_IS_WINDOW (window));
2996 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3000 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3001 ModestWindow *window)
3003 g_return_if_fail (MODEST_IS_WINDOW (window));
3006 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3010 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3011 ModestWindow *window)
3013 g_return_if_fail (MODEST_IS_WINDOW (window));
3016 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3020 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3021 ModestWindow *window)
3023 g_return_if_fail (MODEST_IS_WINDOW (window));
3026 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3030 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3032 g_return_if_fail (MODEST_IS_WINDOW (window));
3035 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3039 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3041 g_return_if_fail (MODEST_IS_WINDOW (window));
3043 modest_platform_show_search_messages (GTK_WINDOW (window));
3047 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3049 g_return_if_fail (MODEST_IS_WINDOW (win));
3050 modest_platform_show_addressbook (GTK_WINDOW (win));
3055 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3056 ModestWindow *window)
3058 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3060 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3064 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3065 ModestMailOperationState *state,
3068 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3070 /* Set send/receive operation finished */
3071 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3072 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));