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>
36 #include <modest-runtime.h>
37 #include <modest-tny-msg.h>
38 #include <modest-tny-account.h>
39 #include <modest-address-book.h>
41 #include "modest-ui-actions.h"
43 #include "modest-tny-platform-factory.h"
45 #include <widgets/modest-main-window.h>
46 #include <widgets/modest-msg-view-window.h>
47 #include <widgets/modest-account-view-window.h>
49 #include "modest-account-mgr-helpers.h"
50 #include "modest-mail-operation.h"
52 #ifdef MODEST_HAVE_EASYSETUP
53 #include "easysetup/modest-easysetup-wizard.h"
54 #endif /*MODEST_HAVE_EASYSETUP*/
56 #include <modest-widget-memory.h>
57 #include <tny-error.h>
58 #include <tny-simple-list.h>
59 #include <tny-msg-view.h>
60 #include <tny-device.h>
63 typedef struct _GetMsgAsyncHelper {
70 typedef enum _ReplyForwardAction {
76 typedef struct _ReplyForwardHelper {
77 guint reply_forward_type;
78 ReplyForwardAction action;
83 static void reply_forward_func (gpointer data, gpointer user_data);
84 static void read_msg_func (gpointer data, gpointer user_data);
85 static void get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err,
87 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
88 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
92 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
95 const gchar *authors[] = {
96 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
99 about = gtk_about_dialog_new ();
100 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
101 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
102 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
103 _("Copyright (c) 2006, Nokia Corporation\n"
104 "All rights reserved."));
105 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
106 _("a modest e-mail client\n\n"
107 "design and implementation: Dirk-Jan C. Binnema\n"
108 "contributions from the fine people at KernelConcepts and Igalia\n"
109 "uses the tinymail email framework written by Philip van Hoof"));
110 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
111 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
113 gtk_dialog_run (GTK_DIALOG (about));
114 gtk_widget_destroy(about);
119 get_selected_headers (ModestWindow *win)
121 if (MODEST_IS_MAIN_WINDOW(win)) {
122 GtkWidget *header_view;
124 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
125 MODEST_WIDGET_TYPE_HEADER_VIEW);
126 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
128 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
129 /* for MsgViewWindows, we simply return a list with one element */
132 TnyList *list = NULL;
134 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
136 header = tny_msg_get_header (msg);
137 list = tny_simple_list_new ();
138 tny_list_prepend (list, G_OBJECT(header));
139 g_object_unref (G_OBJECT(header));
148 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
150 TnyList *header_list;
153 g_return_if_fail (MODEST_IS_WINDOW(win));
155 header_list = get_selected_headers (win);
158 iter = tny_list_create_iterator (header_list);
161 ModestMailOperation *mail_op;
163 header = TNY_HEADER (tny_iterator_get_current (iter));
164 /* TODO: thick grain mail operation involving
165 a list of objects. Composite pattern ??? */
166 /* TODO: add confirmation dialog */
167 mail_op = modest_mail_operation_new ();
168 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
171 /* Always delete. TODO: Move to trash still not supported */
172 modest_mail_operation_remove_msg (mail_op, header, FALSE);
175 g_object_unref (G_OBJECT (mail_op));
176 g_object_unref (G_OBJECT (header));
178 tny_iterator_next (iter);
180 } while (!tny_iterator_is_done (iter));
183 g_object_unref (G_OBJECT (iter));
189 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
191 /* FIXME: save size of main window */
192 /* save_sizes (main_window); */
193 gtk_widget_destroy (GTK_WIDGET (win));
197 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
199 GtkClipboard *clipboard = NULL;
200 gchar *selection = NULL;
202 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
203 selection = gtk_clipboard_wait_for_text (clipboard);
205 modest_address_book_add_address (selection);
210 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
212 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr());
214 gboolean accounts_exist = account_names != NULL;
215 g_slist_free (account_names);
217 /* This is currently only implemented for Maemo,
218 * because it requires a providers preset file which is not publically available.
220 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
221 /* To test, while modest_account_mgr_account_names() is broken: accounts_exist = TRUE; */
222 if (!accounts_exist) {
223 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
224 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
225 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
226 gtk_dialog_run (GTK_DIALOG (wizard));
227 gtk_widget_destroy (GTK_WIDGET (wizard));
231 /* Show the list of accounts: */
232 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
233 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
234 gtk_dialog_run (account_win);
235 gtk_widget_destroy (GTK_WIDGET(account_win));
238 GtkWidget *dialog, *label;
240 /* Create the widgets */
242 dialog = gtk_dialog_new_with_buttons ("Message",
244 GTK_DIALOG_DESTROY_WITH_PARENT,
248 label = gtk_label_new ("Hello World!");
250 /* Ensure that the dialog box is destroyed when the user responds. */
252 g_signal_connect_swapped (dialog, "response",
253 G_CALLBACK (gtk_widget_destroy),
256 /* Add the label, and show everything we've added to the dialog. */
258 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
260 gtk_widget_show_all (dialog);
261 #endif /* MODEST_PLATFORM_MAEMO */
265 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
267 ModestWindow *msg_win;
269 TnyFolder *folder = NULL;
270 gchar *account_name = NULL;
271 gchar *from_str = NULL;
274 ModestWindowMgr *mgr;
276 account_name = g_strdup(modest_window_get_active_account (win));
278 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
280 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
282 TNY_ACCOUNT_TYPE_STORE);
284 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
288 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
290 msg = modest_tny_msg_new ("", from_str, "", "", "", "", NULL);
292 g_printerr ("modest: failed to create new msg\n");
296 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
298 g_printerr ("modest: failed to find Drafts folder\n");
302 tny_folder_add_msg (folder, msg, &err);
304 g_printerr ("modest: error adding msg to Drafts folder: %s",
310 /* Create and register edit window */
311 msg_win = modest_msg_edit_window_new (msg, account_name);
312 mgr = modest_runtime_get_window_mgr ();
313 modest_window_mgr_register_window (mgr, msg_win);
316 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
318 gtk_widget_show_all (GTK_WIDGET (msg_win));
321 g_free (account_name);
324 g_object_unref (G_OBJECT(account));
326 g_object_unref (G_OBJECT(msg));
328 g_object_unref (G_OBJECT(folder));
333 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
335 modest_runtime_not_implemented (GTK_WINDOW(win)); /* FIXME */
341 reply_forward_func (gpointer data, gpointer user_data)
343 TnyMsg *msg, *new_msg;
344 GetMsgAsyncHelper *helper;
345 ReplyForwardHelper *rf_helper;
346 ModestWindow *msg_win;
347 ModestEditType edit_type;
350 TnyFolder *folder = NULL;
351 TnyAccount *account = NULL;
352 ModestWindowMgr *mgr;
354 msg = TNY_MSG (data);
355 helper = (GetMsgAsyncHelper *) user_data;
356 rf_helper = (ReplyForwardHelper *) helper->user_data;
358 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
359 rf_helper->account_name);
360 /* Create reply mail */
361 switch (rf_helper->action) {
364 modest_tny_msg_create_reply_msg (msg, from,
365 rf_helper->reply_forward_type,
366 MODEST_TNY_MSG_REPLY_MODE_SENDER);
368 case ACTION_REPLY_TO_ALL:
370 modest_tny_msg_create_reply_msg (msg, from, rf_helper->reply_forward_type,
371 MODEST_TNY_MSG_REPLY_MODE_ALL);
372 edit_type = MODEST_EDIT_TYPE_REPLY;
376 modest_tny_msg_create_forward_msg (msg, from, rf_helper->reply_forward_type);
377 edit_type = MODEST_EDIT_TYPE_FORWARD;
380 g_return_if_reached ();
385 g_printerr ("modest: failed to create message\n");
389 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
390 rf_helper->account_name,
391 TNY_ACCOUNT_TYPE_STORE);
393 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
397 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
399 g_printerr ("modest: failed to find Drafts folder\n");
403 tny_folder_add_msg (folder, msg, &err);
405 g_printerr ("modest: error adding msg to Drafts folder: %s",
411 /* Create and register the windows */
412 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
413 mgr = modest_runtime_get_window_mgr ();
414 modest_window_mgr_register_window (mgr, msg_win);
416 /* Show edit window */
417 gtk_widget_show_all (GTK_WIDGET (msg_win));
421 g_object_unref (G_OBJECT (new_msg));
423 g_object_unref (G_OBJECT (folder));
425 g_object_unref (G_OBJECT (account));
427 g_free (rf_helper->account_name);
428 g_slice_free (ReplyForwardHelper, rf_helper);
431 * Common code for the reply and forward actions
434 reply_forward (ReplyForwardAction action, ModestWindow *win)
436 TnyList *header_list;
437 guint reply_forward_type;
440 GetMsgAsyncHelper *helper;
441 ReplyForwardHelper *rf_helper;
443 g_return_if_fail (MODEST_IS_WINDOW(win));
445 header_list = get_selected_headers (win);
449 reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
450 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
452 /* We assume that we can only select messages of the
453 same folder and that we reply all of them from the
454 same account. In fact the interface currently only
455 allows single selection */
458 rf_helper = g_slice_new0 (ReplyForwardHelper);
459 rf_helper->reply_forward_type = reply_forward_type;
460 rf_helper->action = action;
462 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
463 if (!rf_helper->account_name)
464 rf_helper->account_name =
465 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
467 helper = g_slice_new0 (GetMsgAsyncHelper);
468 helper->window = win;
469 helper->func = reply_forward_func;
470 helper->iter = tny_list_create_iterator (header_list);
471 helper->user_data = rf_helper;
473 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
475 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
477 g_printerr ("modest: no message found\n");
480 reply_forward_func (msg, helper);
482 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
483 folder = tny_header_get_folder (header);
485 /* The callback will call it per each header */
486 tny_folder_get_msg_async (folder, header, get_msg_cb, helper);
487 g_object_unref (G_OBJECT (folder));
489 g_printerr ("modest: no folder for header\n");
492 g_object_unref (G_OBJECT (header));
498 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
500 g_return_if_fail (MODEST_IS_WINDOW(win));
502 reply_forward (ACTION_REPLY, win);
506 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
508 g_return_if_fail (MODEST_IS_WINDOW(win));
510 reply_forward (ACTION_FORWARD, win);
514 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
516 g_return_if_fail (MODEST_IS_WINDOW(win));
518 reply_forward (ACTION_REPLY_TO_ALL, win);
522 modest_ui_actions_on_next (GtkAction *action,
523 ModestMainWindow *main_window)
525 GtkWidget *header_view;
526 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
528 header_view = modest_main_window_get_child_widget (main_window,
529 MODEST_WIDGET_TYPE_HEADER_VIEW);
533 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
537 modest_ui_actions_on_prev (GtkAction *action,
538 ModestMainWindow *main_window)
540 GtkWidget *header_view;
541 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
543 header_view = modest_main_window_get_child_widget (main_window,
544 MODEST_WIDGET_TYPE_HEADER_VIEW);
548 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
553 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
556 TnyAccount *tny_account;
557 ModestTnySendQueue *send_queue;
558 ModestMailOperation *mail_op;
561 g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
563 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
565 g_printerr ("modest: cannot get account\n");
570 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
572 TNY_ACCOUNT_TYPE_TRANSPORT);
574 g_printerr ("modest: cannot get tny transport account for %s\n", account_name);
577 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account));
579 g_object_unref (G_OBJECT(tny_account));
580 g_printerr ("modest: cannot get send queue for %s\n", account_name);
583 //modest_tny_send_queue_flush (send_queue);
585 g_object_unref (G_OBJECT(send_queue));
586 g_object_unref (G_OBJECT(tny_account));
589 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
591 TNY_ACCOUNT_TYPE_STORE);
593 g_printerr ("modest: cannot get tny store account for %s\n", account_name);
597 /* Create the mail operation */
598 mail_op = modest_mail_operation_new ();
599 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
600 modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
603 g_object_unref (G_OBJECT (tny_account));
604 g_object_unref (G_OBJECT (mail_op));
610 modest_ui_actions_toggle_view (GtkAction *action, ModestMainWindow *main_window)
613 GtkWidget *header_view;
615 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
617 header_view = modest_main_window_get_child_widget (main_window,
618 MODEST_WIDGET_TYPE_HEADER_VIEW);
622 conf = modest_runtime_get_conf ();
624 /* what is saved/restored is depending on the style; thus; we save with
625 * old style, then update the style, and restore for this new style
627 modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view");
629 if (modest_header_view_get_style
630 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
631 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
632 MODEST_HEADER_VIEW_STYLE_TWOLINES);
634 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
635 MODEST_HEADER_VIEW_STYLE_DETAILS);
637 modest_widget_memory_restore (conf, G_OBJECT(header_view),
644 * Marks a message as read and passes it to the msg preview widget
647 read_msg_func (gpointer data, gpointer user_data)
651 GetMsgAsyncHelper *helper;
652 TnyHeaderFlags header_flags;
653 GtkWidget *msg_preview;
655 msg = TNY_MSG (data);
656 helper = (GetMsgAsyncHelper *) user_data;
658 msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window),
659 MODEST_WIDGET_TYPE_MSG_PREVIEW);
663 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
664 header_flags = tny_header_get_flags (header);
665 tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
666 g_object_unref (G_OBJECT (header));
668 /* Set message on msg view */
669 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg);
673 * This function is a generic handler for the tny_folder_get_msg_async
674 * call. It expects as user_data a #GetMsgAsyncHelper. This helper
675 * contains a user provided function that is called inside this
676 * method. This will allow us to use this callback in many different
677 * places. This callback performs the common actions for the
678 * get_msg_async call, more specific actions will be done by the user
682 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
684 GetMsgAsyncHelper *helper;
686 helper = (GetMsgAsyncHelper *) user_data;
688 if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
689 modest_ui_actions_on_item_not_found (NULL,
690 MODEST_ITEM_TYPE_MESSAGE,
695 /* Call user function */
696 helper->func (msg, user_data);
698 /* Process next element (if exists) */
699 tny_iterator_next (helper->iter);
700 if (tny_iterator_is_done (helper->iter)) {
702 headers = tny_iterator_get_list (helper->iter);
704 g_object_unref (G_OBJECT (headers));
705 g_object_unref (G_OBJECT (helper->iter));
706 g_slice_free (GetMsgAsyncHelper, helper);
709 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
710 tny_folder_get_msg_async (folder, header,
712 g_object_unref (G_OBJECT(header));
717 modest_ui_actions_on_header_selected (ModestHeaderView *folder_view,
719 ModestMainWindow *main_window)
721 GtkWidget *msg_preview;
723 GetMsgAsyncHelper *helper;
726 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
728 msg_preview = modest_main_window_get_child_widget(main_window,
729 MODEST_WIDGET_TYPE_MSG_PREVIEW);
733 /* when there's no header, clear the msgview */
735 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL);
739 folder = tny_header_get_folder (TNY_HEADER(header));
742 list = tny_simple_list_new ();
743 tny_list_prepend (list, G_OBJECT (header));
745 /* Fill helper data */
746 helper = g_slice_new0 (GetMsgAsyncHelper);
747 helper->window = MODEST_WINDOW (main_window);
748 helper->iter = tny_list_create_iterator (list);
749 helper->func = read_msg_func;
751 tny_folder_get_msg_async (TNY_FOLDER(folder),
756 g_object_unref (G_OBJECT (folder));
762 modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header,
763 ModestMainWindow *main_window)
766 TnyFolder *folder = NULL;
768 gchar *account = NULL;
769 ModestWindowMgr *mgr;
771 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
776 folder = tny_header_get_folder (header);
778 g_printerr ("modest: cannot get folder for header\n");
782 /* FIXME: make async?; check error */
783 msg = tny_folder_get_msg (folder, header, NULL);
785 g_printerr ("modest: cannot get msg for header\n");
789 account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
791 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
793 /* Create and register message view window */
794 win = modest_msg_view_window_new (msg, account);
795 mgr = modest_runtime_get_window_mgr ();
796 modest_window_mgr_register_window (mgr, win);
798 gtk_window_set_transient_for (GTK_WINDOW (win),
799 GTK_WINDOW (main_window));
801 gtk_widget_show_all (GTK_WIDGET(win));
807 g_object_unref (G_OBJECT (folder));
809 g_object_unref (G_OBJECT (msg));
813 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
816 ModestMainWindow *main_window)
820 GtkWidget *header_view;
822 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
824 header_view = modest_main_window_get_child_widget(main_window,
825 MODEST_WIDGET_TYPE_HEADER_VIEW);
829 conf = modest_runtime_get_conf ();
831 if (!selected) { /* the folder was unselected; save it's settings */
832 modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view");
833 gtk_window_set_title (GTK_WINDOW(main_window), "Modest");
834 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
835 } else { /* the folder was selected */
836 if (folder) { /* folder may be NULL */
840 num = tny_folder_get_all_count (folder);
841 unread = tny_folder_get_unread_count (folder);
843 title = g_strdup_printf ("Modest: %s",
844 tny_folder_get_name (folder));
846 gtk_window_set_title (GTK_WINDOW(main_window), title);
849 txt = g_strdup_printf (_("%d %s, %d unread"),
850 num, num==1 ? _("item") : _("items"), unread);
851 //gtk_label_set_label (GTK_LABEL(folder_info_label), txt);
854 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), folder);
855 modest_widget_memory_restore (conf, G_OBJECT(header_view),
861 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
868 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
870 if (g_main_depth > 0)
871 gdk_threads_enter ();
872 online = tny_device_is_online (modest_runtime_get_device());
875 /* already online -- the item is simply not there... */
876 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
880 _("The %s you selected cannot be found"),
882 gtk_dialog_run (GTK_DIALOG(dialog));
884 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
892 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
893 "Do you want to get online?"), item);
894 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
895 gtk_label_new (txt), FALSE, FALSE, 0);
896 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
899 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
900 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
901 // tny_device_force_online (modest_runtime_get_device());
904 gtk_widget_destroy (dialog);
905 if (g_main_depth > 0)
906 gdk_threads_leave ();
910 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
913 g_message (__FUNCTION__);
918 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
921 g_message (__FUNCTION__);
925 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
928 g_message (__FUNCTION__);
933 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
934 const gchar *address,
937 g_message ("%s %s", __FUNCTION__, address);
941 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
943 TnyTransportAccount *transport_account;
944 ModestMailOperation *mail_operation;
946 gchar *account_name, *from;
947 ModestAccountMgr *account_mgr;
949 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
951 data = modest_msg_edit_window_get_msg_data (edit_window);
953 /* FIXME: Code added just for testing. The final version will
954 use the send queue provided by tinymail and some
956 account_mgr = modest_runtime_get_account_mgr();
957 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
959 account_name = modest_account_mgr_get_default_account (account_mgr);
961 g_printerr ("modest: no account found\n");
962 modest_msg_edit_window_free_msg_data (edit_window, data);
966 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
967 (modest_runtime_get_account_store(),
969 TNY_ACCOUNT_TYPE_TRANSPORT));
970 if (!transport_account) {
971 g_printerr ("modest: no transport account found for '%s'\n", account_name);
972 g_free (account_name);
973 modest_msg_edit_window_free_msg_data (edit_window, data);
976 from = modest_account_mgr_get_from_string (account_mgr, account_name);
978 /* Create the mail operation */
979 mail_operation = modest_mail_operation_new ();
980 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
982 modest_mail_operation_send_new_mail (mail_operation,
994 g_free (account_name);
995 g_object_unref (G_OBJECT (transport_account));
996 g_object_unref (G_OBJECT (mail_operation));
998 modest_msg_edit_window_free_msg_data (edit_window, data);
1000 /* Save settings and close the window */
1001 gtk_widget_destroy (GTK_WIDGET (edit_window));
1005 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1006 ModestMsgEditWindow *window)
1008 ModestMsgEditFormatState *format_state = NULL;
1010 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1011 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1013 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1016 format_state = modest_msg_edit_window_get_format_state (window);
1017 g_return_if_fail (format_state != NULL);
1019 format_state->bold = gtk_toggle_action_get_active (action);
1020 modest_msg_edit_window_set_format_state (window, format_state);
1021 g_free (format_state);
1026 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1027 ModestMsgEditWindow *window)
1029 ModestMsgEditFormatState *format_state = NULL;
1031 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1032 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1034 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1037 format_state = modest_msg_edit_window_get_format_state (window);
1038 g_return_if_fail (format_state != NULL);
1040 format_state->italics = gtk_toggle_action_get_active (action);
1041 modest_msg_edit_window_set_format_state (window, format_state);
1042 g_free (format_state);
1047 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1048 ModestMsgEditWindow *window)
1050 ModestMsgEditFormatState *format_state = NULL;
1052 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1053 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1055 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1058 format_state = modest_msg_edit_window_get_format_state (window);
1059 g_return_if_fail (format_state != NULL);
1061 format_state->bullet = gtk_toggle_action_get_active (action);
1062 modest_msg_edit_window_set_format_state (window, format_state);
1063 g_free (format_state);
1068 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1069 GtkRadioAction *selected,
1070 ModestMsgEditWindow *window)
1072 ModestMsgEditFormatState *format_state = NULL;
1073 GtkJustification value;
1075 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1077 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1080 value = gtk_radio_action_get_current_value (selected);
1082 format_state = modest_msg_edit_window_get_format_state (window);
1083 g_return_if_fail (format_state != NULL);
1085 format_state->justification = value;
1086 modest_msg_edit_window_set_format_state (window, format_state);
1087 g_free (format_state);
1091 modest_ui_actions_on_select_editor_color (GtkAction *action,
1092 ModestMsgEditWindow *window)
1094 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1095 g_return_if_fail (GTK_IS_ACTION (action));
1097 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1100 modest_msg_edit_window_select_color (window);
1104 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1105 ModestMsgEditWindow *window)
1107 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1108 g_return_if_fail (GTK_IS_ACTION (action));
1110 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1113 modest_msg_edit_window_select_background_color (window);
1117 modest_ui_actions_on_insert_image (GtkAction *action,
1118 ModestMsgEditWindow *window)
1120 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1121 g_return_if_fail (GTK_IS_ACTION (action));
1123 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1126 modest_msg_edit_window_insert_image (window);
1130 * Shows a dialog with an entry that asks for some text. The returned
1131 * value must be freed by the caller. The dialog window title will be
1135 ask_for_folder_name (GtkWindow *parent_window,
1138 GtkWidget *dialog, *entry;
1139 gchar *folder_name = NULL;
1141 /* Ask for folder name */
1142 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1146 GTK_RESPONSE_REJECT,
1148 GTK_RESPONSE_ACCEPT,
1150 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1151 gtk_label_new(title),
1154 entry = gtk_entry_new_with_max_length (40);
1155 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1159 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1161 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1162 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1164 gtk_widget_destroy (dialog);
1170 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1172 TnyFolder *parent_folder;
1173 GtkWidget *folder_view;
1175 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1177 folder_view = modest_main_window_get_child_widget (main_window,
1178 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1182 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1184 if (parent_folder) {
1187 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1188 _("Please enter a name for the new folder"));
1190 if (folder_name != NULL && strlen (folder_name) > 0) {
1191 TnyFolder *new_folder;
1192 ModestMailOperation *mail_op;
1194 mail_op = modest_mail_operation_new ();
1195 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1198 new_folder = modest_mail_operation_create_folder (mail_op,
1199 TNY_FOLDER_STORE (parent_folder),
1200 (const gchar *) folder_name);
1202 g_object_unref (new_folder);
1203 g_object_unref (mail_op);
1204 g_free (folder_name);
1206 g_object_unref (parent_folder);
1211 modest_ui_actions_on_rename_folder (GtkAction *action,
1212 ModestMainWindow *main_window)
1215 GtkWidget *folder_view;
1217 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1219 folder_view = modest_main_window_get_child_widget (main_window,
1220 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1224 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1228 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1229 _("Please enter a new name for the folder"));
1231 if (folder_name != NULL && strlen (folder_name) > 0) {
1232 ModestMailOperation *mail_op;
1234 mail_op = modest_mail_operation_new ();
1235 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1238 modest_mail_operation_rename_folder (mail_op,
1240 (const gchar *) folder_name);
1242 g_object_unref (mail_op);
1243 g_free (folder_name);
1245 g_object_unref (folder);
1250 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1253 ModestMailOperation *mail_op;
1254 GtkWidget *folder_view;
1256 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1258 folder_view = modest_main_window_get_child_widget (main_window,
1259 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1263 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1265 mail_op = modest_mail_operation_new ();
1266 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1268 modest_mail_operation_remove_folder (mail_op, folder, move_to_trash);
1270 g_object_unref (G_OBJECT (mail_op));
1271 g_object_unref (G_OBJECT (folder));
1275 modest_ui_actions_on_delete_folder (GtkAction *action,
1276 ModestMainWindow *main_window)
1278 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1280 delete_folder (main_window, FALSE);
1284 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1286 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1288 delete_folder (main_window, TRUE);
1292 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1293 const gchar* account_name,
1297 ModestMainWindow *main_window)
1300 GtkWidget *dialog, *entry, *remember_pass_check;
1302 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1306 GTK_RESPONSE_REJECT,
1308 GTK_RESPONSE_ACCEPT,
1310 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1312 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1313 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1317 entry = gtk_entry_new_with_max_length (40);
1318 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1319 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1321 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1324 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1325 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1328 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1330 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1331 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1338 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1343 gtk_widget_destroy (dialog);
1347 modest_ui_actions_on_cut (GtkAction *action,
1348 ModestWindow *window)
1350 GtkWidget *focused_widget;
1352 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1353 if (GTK_IS_EDITABLE (focused_widget)) {
1354 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1355 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1356 GtkTextBuffer *buffer;
1357 GtkClipboard *clipboard;
1359 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1360 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1361 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1366 modest_ui_actions_on_copy (GtkAction *action,
1367 ModestWindow *window)
1369 GtkClipboard *clipboard;
1370 GtkWidget *focused_widget;
1372 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1373 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1374 if (GTK_IS_LABEL (focused_widget)) {
1375 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1376 } else if (GTK_IS_EDITABLE (focused_widget)) {
1377 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1378 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1379 GtkTextBuffer *buffer;
1381 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1382 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1387 modest_ui_actions_on_paste (GtkAction *action,
1388 ModestWindow *window)
1390 GtkWidget *focused_widget;
1392 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1393 if (GTK_IS_EDITABLE (focused_widget)) {
1394 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1395 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1396 GtkTextBuffer *buffer;
1397 GtkClipboard *clipboard;
1399 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1400 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1401 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1406 modest_ui_actions_on_select_all (GtkAction *action,
1407 ModestWindow *window)
1409 GtkWidget *focused_widget;
1411 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1412 if (GTK_IS_LABEL (focused_widget)) {
1413 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1414 } else if (GTK_IS_EDITABLE (focused_widget)) {
1415 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1416 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1417 GtkTextBuffer *buffer;
1418 GtkTextIter start, end;
1420 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1421 gtk_text_buffer_get_start_iter (buffer, &start);
1422 gtk_text_buffer_get_end_iter (buffer, &end);
1423 gtk_text_buffer_select_range (buffer, &start, &end);