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"
51 #include "easysetup/modest-easysetup-wizard.h"
52 #include <modest-widget-memory.h>
53 #include <tny-error.h>
54 #include <tny-simple-list.h>
55 #include <tny-msg-view.h>
56 #include <tny-device.h>
59 typedef struct _GetMsgAsyncHelper {
66 typedef enum _ReplyForwardAction {
72 typedef struct _ReplyForwardHelper {
73 guint reply_forward_type;
74 ReplyForwardAction action;
79 static void reply_forward_func (gpointer data, gpointer user_data);
80 static void read_msg_func (gpointer data, gpointer user_data);
81 static void get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err,
83 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
84 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
88 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
91 const gchar *authors[] = {
92 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
95 about = gtk_about_dialog_new ();
96 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
97 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
98 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
99 _("Copyright (c) 2006, Nokia Corporation\n"
100 "All rights reserved."));
101 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
102 _("a modest e-mail client\n\n"
103 "design and implementation: Dirk-Jan C. Binnema\n"
104 "contributions from the fine people at KernelConcepts and Igalia\n"
105 "uses the tinymail email framework written by Philip van Hoof"));
106 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
107 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
109 gtk_dialog_run (GTK_DIALOG (about));
110 gtk_widget_destroy(about);
115 get_selected_headers (ModestWindow *win)
117 if (MODEST_IS_MAIN_WINDOW(win)) {
118 GtkWidget *header_view;
120 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
121 MODEST_WIDGET_TYPE_HEADER_VIEW);
122 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
124 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
125 /* for MsgViewWindows, we simply return a list with one element */
128 TnyList *list = NULL;
130 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
132 header = tny_msg_get_header (msg);
133 list = tny_simple_list_new ();
134 tny_list_prepend (list, G_OBJECT(header));
135 g_object_unref (G_OBJECT(header));
144 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
146 TnyList *header_list;
149 g_return_if_fail (MODEST_IS_WINDOW(win));
151 header_list = get_selected_headers (win);
154 iter = tny_list_create_iterator (header_list);
157 ModestMailOperation *mail_op;
159 header = TNY_HEADER (tny_iterator_get_current (iter));
160 /* TODO: thick grain mail operation involving
161 a list of objects. Composite pattern ??? */
162 /* TODO: add confirmation dialog */
163 mail_op = modest_mail_operation_new ();
164 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
167 /* Always delete. TODO: Move to trash still not supported */
168 modest_mail_operation_remove_msg (mail_op, header, FALSE);
171 g_object_unref (G_OBJECT (mail_op));
172 g_object_unref (G_OBJECT (header));
174 tny_iterator_next (iter);
176 } while (!tny_iterator_is_done (iter));
179 g_object_unref (G_OBJECT (iter));
185 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
187 /* FIXME: save size of main window */
188 /* save_sizes (main_window); */
189 gtk_widget_destroy (GTK_WIDGET (win));
193 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
195 GtkClipboard *clipboard = NULL;
196 gchar *selection = NULL;
198 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
199 selection = gtk_clipboard_wait_for_text (clipboard);
201 modest_address_book_add_address (selection);
206 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
208 /* GtkDialog *account_win; */
209 /* account_win = GTK_DIALOG(modest_account_view_window_new ()); */
212 /* gtk_dialog_run (account_win); */
213 //gtk_widget_destroy (GTK_WIDGET(account_win));
214 GtkWidget *dialog, *label;
216 /* Create the widgets */
218 dialog = gtk_dialog_new_with_buttons ("Message",
220 GTK_DIALOG_DESTROY_WITH_PARENT,
224 label = gtk_label_new ("Hello World!");
226 /* Ensure that the dialog box is destroyed when the user responds. */
228 g_signal_connect_swapped (dialog, "response",
229 G_CALLBACK (gtk_widget_destroy),
232 /* Add the label, and show everything we've added to the dialog. */
234 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
236 gtk_widget_show_all (dialog);
240 modest_ui_actions_on_new_account (GtkAction *action, ModestWindow *win)
242 /* This is currently only implemented for Maemo,
243 * because it requires a providers preset file which is not publically available.
245 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
246 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
247 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
248 gtk_dialog_run (GTK_DIALOG (wizard));
249 gtk_widget_destroy (GTK_WIDGET (wizard));
250 #endif MODEST_PLATFORM_MAEMO
254 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
256 ModestWindow *msg_win;
258 TnyFolder *folder = NULL;
259 gchar *account_name = NULL;
260 gchar *from_str = NULL;
264 account_name = g_strdup(modest_window_get_active_account (win));
266 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
268 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
270 TNY_ACCOUNT_TYPE_STORE);
272 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
276 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
278 msg = modest_tny_msg_new ("", from_str, "", "", "", "", NULL);
280 g_printerr ("modest: failed to create new msg\n");
284 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
286 g_printerr ("modest: failed to find Drafts folder\n");
290 tny_folder_add_msg (folder, msg, &err);
292 g_printerr ("modest: error adding msg to Drafts folder: %s",
298 msg_win = modest_msg_edit_window_new (msg, account_name);
300 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
302 gtk_widget_show_all (GTK_WIDGET (msg_win));
305 g_free (account_name);
308 g_object_unref (G_OBJECT(account));
310 g_object_unref (G_OBJECT(msg));
312 g_object_unref (G_OBJECT(folder));
317 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
319 modest_runtime_not_implemented (GTK_WINDOW(win)); /* FIXME */
325 reply_forward_func (gpointer data, gpointer user_data)
327 TnyMsg *msg, *new_msg;
328 GetMsgAsyncHelper *helper;
329 ReplyForwardHelper *rf_helper;
330 ModestWindow *msg_win;
331 ModestEditType edit_type;
334 TnyFolder *folder = NULL;
335 TnyAccount *account = NULL;
337 msg = TNY_MSG (data);
338 helper = (GetMsgAsyncHelper *) user_data;
339 rf_helper = (ReplyForwardHelper *) helper->user_data;
341 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
342 rf_helper->account_name);
343 /* Create reply mail */
344 switch (rf_helper->action) {
347 modest_tny_msg_create_reply_msg (msg, from,
348 rf_helper->reply_forward_type,
349 MODEST_TNY_MSG_REPLY_MODE_SENDER);
351 case ACTION_REPLY_TO_ALL:
353 modest_tny_msg_create_reply_msg (msg, from, rf_helper->reply_forward_type,
354 MODEST_TNY_MSG_REPLY_MODE_ALL);
355 edit_type = MODEST_EDIT_TYPE_REPLY;
359 modest_tny_msg_create_forward_msg (msg, from, rf_helper->reply_forward_type);
360 edit_type = MODEST_EDIT_TYPE_FORWARD;
363 g_return_if_reached ();
368 g_printerr ("modest: failed to create message\n");
372 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
373 rf_helper->account_name,
374 TNY_ACCOUNT_TYPE_STORE);
376 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
380 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
382 g_printerr ("modest: failed to find Drafts folder\n");
386 tny_folder_add_msg (folder, msg, &err);
388 g_printerr ("modest: error adding msg to Drafts folder: %s",
394 /* Show edit window */
395 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
396 gtk_widget_show_all (GTK_WIDGET (msg_win));
400 g_object_unref (G_OBJECT (new_msg));
402 g_object_unref (G_OBJECT (folder));
404 g_object_unref (G_OBJECT (account));
406 g_free (rf_helper->account_name);
407 g_slice_free (ReplyForwardHelper, rf_helper);
410 * Common code for the reply and forward actions
413 reply_forward (ReplyForwardAction action, ModestWindow *win)
415 TnyList *header_list;
416 guint reply_forward_type;
419 GetMsgAsyncHelper *helper;
420 ReplyForwardHelper *rf_helper;
422 g_return_if_fail (MODEST_IS_WINDOW(win));
424 header_list = get_selected_headers (win);
428 reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
429 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
431 /* We assume that we can only select messages of the
432 same folder and that we reply all of them from the
433 same account. In fact the interface currently only
434 allows single selection */
437 rf_helper = g_slice_new0 (ReplyForwardHelper);
438 rf_helper->reply_forward_type = reply_forward_type;
439 rf_helper->action = action;
441 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
442 if (!rf_helper->account_name)
443 rf_helper->account_name =
444 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
446 helper = g_slice_new0 (GetMsgAsyncHelper);
447 helper->window = win;
448 helper->func = reply_forward_func;
449 helper->iter = tny_list_create_iterator (header_list);
450 helper->user_data = rf_helper;
452 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
454 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
456 g_printerr ("modest: no message found\n");
459 reply_forward_func (msg, helper);
461 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
462 folder = tny_header_get_folder (header);
464 /* The callback will call it per each header */
465 tny_folder_get_msg_async (folder, header, get_msg_cb, helper);
466 g_object_unref (G_OBJECT (folder));
468 g_printerr ("modest: no folder for header\n");
471 g_object_unref (G_OBJECT (header));
477 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
479 g_return_if_fail (MODEST_IS_WINDOW(win));
481 reply_forward (ACTION_REPLY, win);
485 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
487 g_return_if_fail (MODEST_IS_WINDOW(win));
489 reply_forward (ACTION_FORWARD, win);
493 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
495 g_return_if_fail (MODEST_IS_WINDOW(win));
497 reply_forward (ACTION_REPLY_TO_ALL, win);
501 modest_ui_actions_on_next (GtkAction *action,
502 ModestMainWindow *main_window)
504 GtkWidget *header_view;
505 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
507 header_view = modest_main_window_get_child_widget (main_window,
508 MODEST_WIDGET_TYPE_HEADER_VIEW);
512 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
516 modest_ui_actions_on_prev (GtkAction *action,
517 ModestMainWindow *main_window)
519 GtkWidget *header_view;
520 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
522 header_view = modest_main_window_get_child_widget (main_window,
523 MODEST_WIDGET_TYPE_HEADER_VIEW);
527 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
532 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
535 TnyAccount *tny_account;
536 ModestTnySendQueue *send_queue;
537 ModestMailOperation *mail_op;
540 g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
542 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
544 g_printerr ("modest: cannot get account\n");
549 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
551 TNY_ACCOUNT_TYPE_TRANSPORT);
553 g_printerr ("modest: cannot get tny transport account for %s\n", account_name);
556 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account));
558 g_object_unref (G_OBJECT(tny_account));
559 g_printerr ("modest: cannot get send queue for %s\n", account_name);
562 //modest_tny_send_queue_flush (send_queue);
564 g_object_unref (G_OBJECT(send_queue));
565 g_object_unref (G_OBJECT(tny_account));
568 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
570 TNY_ACCOUNT_TYPE_STORE);
572 g_printerr ("modest: cannot get tny store account for %s\n", account_name);
576 /* Create the mail operation */
577 mail_op = modest_mail_operation_new ();
578 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
579 modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
582 g_object_unref (G_OBJECT (tny_account));
583 g_object_unref (G_OBJECT (mail_op));
589 modest_ui_actions_toggle_view (GtkAction *action, ModestMainWindow *main_window)
592 GtkWidget *header_view;
594 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
596 header_view = modest_main_window_get_child_widget (main_window,
597 MODEST_WIDGET_TYPE_HEADER_VIEW);
601 conf = modest_runtime_get_conf ();
603 /* what is saved/restored is depending on the style; thus; we save with
604 * old style, then update the style, and restore for this new style
606 modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view");
608 if (modest_header_view_get_style
609 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
610 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
611 MODEST_HEADER_VIEW_STYLE_TWOLINES);
613 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
614 MODEST_HEADER_VIEW_STYLE_DETAILS);
616 modest_widget_memory_restore (conf, G_OBJECT(header_view),
623 * Marks a message as read and passes it to the msg preview widget
626 read_msg_func (gpointer data, gpointer user_data)
630 GetMsgAsyncHelper *helper;
631 TnyHeaderFlags header_flags;
632 GtkWidget *msg_preview;
634 msg = TNY_MSG (data);
635 helper = (GetMsgAsyncHelper *) user_data;
637 msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window),
638 MODEST_WIDGET_TYPE_MSG_PREVIEW);
642 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
643 header_flags = tny_header_get_flags (header);
644 tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
645 g_object_unref (G_OBJECT (header));
647 /* Set message on msg view */
648 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg);
652 * This function is a generic handler for the tny_folder_get_msg_async
653 * call. It expects as user_data a #GetMsgAsyncHelper. This helper
654 * contains a user provided function that is called inside this
655 * method. This will allow us to use this callback in many different
656 * places. This callback performs the common actions for the
657 * get_msg_async call, more specific actions will be done by the user
661 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
663 GetMsgAsyncHelper *helper;
665 helper = (GetMsgAsyncHelper *) user_data;
667 if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
668 modest_ui_actions_on_item_not_found (NULL,
669 MODEST_ITEM_TYPE_MESSAGE,
674 /* Call user function */
675 helper->func (msg, user_data);
677 /* Process next element (if exists) */
678 tny_iterator_next (helper->iter);
679 if (tny_iterator_is_done (helper->iter)) {
681 headers = tny_iterator_get_list (helper->iter);
683 g_object_unref (G_OBJECT (headers));
684 g_object_unref (G_OBJECT (helper->iter));
685 g_slice_free (GetMsgAsyncHelper, helper);
688 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
689 tny_folder_get_msg_async (folder, header,
691 g_object_unref (G_OBJECT(header));
696 modest_ui_actions_on_header_selected (ModestHeaderView *folder_view,
698 ModestMainWindow *main_window)
700 GtkWidget *msg_preview;
702 GetMsgAsyncHelper *helper;
705 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
707 msg_preview = modest_main_window_get_child_widget(main_window,
708 MODEST_WIDGET_TYPE_MSG_PREVIEW);
712 /* when there's no header, clear the msgview */
714 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL);
718 folder = tny_header_get_folder (TNY_HEADER(header));
721 list = tny_simple_list_new ();
722 tny_list_prepend (list, G_OBJECT (header));
724 /* Fill helper data */
725 helper = g_slice_new0 (GetMsgAsyncHelper);
726 helper->window = MODEST_WINDOW (main_window);
727 helper->iter = tny_list_create_iterator (list);
728 helper->func = read_msg_func;
730 tny_folder_get_msg_async (TNY_FOLDER(folder),
735 g_object_unref (G_OBJECT (folder));
741 modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header,
742 ModestMainWindow *main_window)
745 TnyFolder *folder = NULL;
747 gchar *account = NULL;
749 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
754 folder = tny_header_get_folder (header);
756 g_printerr ("modest: cannot get folder for header\n");
760 /* FIXME: make async?; check error */
761 msg = tny_folder_get_msg (folder, header, NULL);
763 g_printerr ("modest: cannot get msg for header\n");
767 account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
769 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
771 win = modest_msg_view_window_new (msg, account);
772 gtk_window_set_transient_for (GTK_WINDOW (win),
773 GTK_WINDOW (main_window));
775 gtk_widget_show_all (GTK_WIDGET(win));
781 g_object_unref (G_OBJECT (folder));
783 g_object_unref (G_OBJECT (msg));
787 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
790 ModestMainWindow *main_window)
794 GtkWidget *header_view;
796 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
798 header_view = modest_main_window_get_child_widget(main_window,
799 MODEST_WIDGET_TYPE_HEADER_VIEW);
803 conf = modest_runtime_get_conf ();
805 if (!selected) { /* the folder was unselected; save it's settings */
806 modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view");
807 gtk_window_set_title (GTK_WINDOW(main_window), "Modest");
808 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
809 } else { /* the folder was selected */
810 if (folder) { /* folder may be NULL */
814 num = tny_folder_get_all_count (folder);
815 unread = tny_folder_get_unread_count (folder);
817 title = g_strdup_printf ("Modest: %s",
818 tny_folder_get_name (folder));
820 gtk_window_set_title (GTK_WINDOW(main_window), title);
823 txt = g_strdup_printf (_("%d %s, %d unread"),
824 num, num==1 ? _("item") : _("items"), unread);
825 //gtk_label_set_label (GTK_LABEL(folder_info_label), txt);
828 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), folder);
829 modest_widget_memory_restore (conf, G_OBJECT(header_view),
835 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
842 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
844 if (g_main_depth > 0)
845 gdk_threads_enter ();
846 online = tny_device_is_online (modest_runtime_get_device());
849 /* already online -- the item is simply not there... */
850 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
854 _("The %s you selected cannot be found"),
856 gtk_dialog_run (GTK_DIALOG(dialog));
858 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
866 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
867 "Do you want to get online?"), item);
868 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
869 gtk_label_new (txt), FALSE, FALSE, 0);
870 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
873 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
874 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
875 // tny_device_force_online (modest_runtime_get_device());
878 gtk_widget_destroy (dialog);
879 if (g_main_depth > 0)
880 gdk_threads_leave ();
884 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
887 g_message (__FUNCTION__);
892 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
895 g_message (__FUNCTION__);
899 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
902 g_message (__FUNCTION__);
907 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
908 const gchar *address,
911 g_message ("%s %s", __FUNCTION__, address);
915 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
917 TnyTransportAccount *transport_account;
918 ModestMailOperation *mail_operation;
920 gchar *account_name, *from;
921 ModestAccountMgr *account_mgr;
923 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
925 data = modest_msg_edit_window_get_msg_data (edit_window);
927 /* FIXME: Code added just for testing. The final version will
928 use the send queue provided by tinymail and some
930 account_mgr = modest_runtime_get_account_mgr();
931 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
933 account_name = modest_account_mgr_get_default_account (account_mgr);
935 g_printerr ("modest: no account found\n");
936 modest_msg_edit_window_free_msg_data (edit_window, data);
940 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
941 (modest_runtime_get_account_store(),
943 TNY_ACCOUNT_TYPE_TRANSPORT));
944 if (!transport_account) {
945 g_printerr ("modest: no transport account found for '%s'\n", account_name);
946 g_free (account_name);
947 modest_msg_edit_window_free_msg_data (edit_window, data);
950 from = modest_account_mgr_get_from_string (account_mgr, account_name);
952 /* Create the mail operation */
953 mail_operation = modest_mail_operation_new ();
954 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
956 modest_mail_operation_send_new_mail (mail_operation,
968 g_free (account_name);
969 g_object_unref (G_OBJECT (transport_account));
970 g_object_unref (G_OBJECT (mail_operation));
972 modest_msg_edit_window_free_msg_data (edit_window, data);
974 /* Save settings and close the window */
975 gtk_widget_destroy (GTK_WIDGET (edit_window));
979 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
980 ModestMsgEditWindow *window)
982 ModestMsgEditFormatState *format_state = NULL;
984 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
985 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
987 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
990 format_state = modest_msg_edit_window_get_format_state (window);
991 g_return_if_fail (format_state != NULL);
993 format_state->bold = gtk_toggle_action_get_active (action);
994 modest_msg_edit_window_set_format_state (window, format_state);
995 g_free (format_state);
1000 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1001 ModestMsgEditWindow *window)
1003 ModestMsgEditFormatState *format_state = NULL;
1005 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1006 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1008 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1011 format_state = modest_msg_edit_window_get_format_state (window);
1012 g_return_if_fail (format_state != NULL);
1014 format_state->italics = gtk_toggle_action_get_active (action);
1015 modest_msg_edit_window_set_format_state (window, format_state);
1016 g_free (format_state);
1021 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1022 ModestMsgEditWindow *window)
1024 ModestMsgEditFormatState *format_state = NULL;
1026 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1027 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1029 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1032 format_state = modest_msg_edit_window_get_format_state (window);
1033 g_return_if_fail (format_state != NULL);
1035 format_state->bullet = gtk_toggle_action_get_active (action);
1036 modest_msg_edit_window_set_format_state (window, format_state);
1037 g_free (format_state);
1042 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1043 GtkRadioAction *selected,
1044 ModestMsgEditWindow *window)
1046 ModestMsgEditFormatState *format_state = NULL;
1047 GtkJustification value;
1049 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1051 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1054 value = gtk_radio_action_get_current_value (selected);
1056 format_state = modest_msg_edit_window_get_format_state (window);
1057 g_return_if_fail (format_state != NULL);
1059 format_state->justification = value;
1060 modest_msg_edit_window_set_format_state (window, format_state);
1061 g_free (format_state);
1065 modest_ui_actions_on_select_editor_color (GtkAction *action,
1066 ModestMsgEditWindow *window)
1068 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1069 g_return_if_fail (GTK_IS_ACTION (action));
1071 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1074 modest_msg_edit_window_select_color (window);
1078 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1079 ModestMsgEditWindow *window)
1081 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1082 g_return_if_fail (GTK_IS_ACTION (action));
1084 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1087 modest_msg_edit_window_select_background_color (window);
1091 modest_ui_actions_on_insert_image (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_insert_image (window);
1104 * Shows a dialog with an entry that asks for some text. The returned
1105 * value must be freed by the caller. The dialog window title will be
1109 ask_for_folder_name (GtkWindow *parent_window,
1112 GtkWidget *dialog, *entry;
1113 gchar *folder_name = NULL;
1115 /* Ask for folder name */
1116 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1120 GTK_RESPONSE_REJECT,
1122 GTK_RESPONSE_ACCEPT,
1124 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1125 gtk_label_new(title),
1128 entry = gtk_entry_new_with_max_length (40);
1129 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1133 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1135 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1136 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1138 gtk_widget_destroy (dialog);
1144 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1146 TnyFolder *parent_folder;
1147 GtkWidget *folder_view;
1149 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1151 folder_view = modest_main_window_get_child_widget (main_window,
1152 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1156 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1158 if (parent_folder) {
1161 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1162 _("Please enter a name for the new folder"));
1164 if (folder_name != NULL && strlen (folder_name) > 0) {
1165 TnyFolder *new_folder;
1166 ModestMailOperation *mail_op;
1168 mail_op = modest_mail_operation_new ();
1169 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1172 new_folder = modest_mail_operation_create_folder (mail_op,
1173 TNY_FOLDER_STORE (parent_folder),
1174 (const gchar *) folder_name);
1176 g_object_unref (new_folder);
1177 g_object_unref (mail_op);
1178 g_free (folder_name);
1180 g_object_unref (parent_folder);
1185 modest_ui_actions_on_rename_folder (GtkAction *action,
1186 ModestMainWindow *main_window)
1189 GtkWidget *folder_view;
1191 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1193 folder_view = modest_main_window_get_child_widget (main_window,
1194 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1198 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1202 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1203 _("Please enter a new name for the folder"));
1205 if (folder_name != NULL && strlen (folder_name) > 0) {
1206 ModestMailOperation *mail_op;
1208 mail_op = modest_mail_operation_new ();
1209 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1212 modest_mail_operation_rename_folder (mail_op,
1214 (const gchar *) folder_name);
1216 g_object_unref (mail_op);
1217 g_free (folder_name);
1219 g_object_unref (folder);
1224 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1227 ModestMailOperation *mail_op;
1228 GtkWidget *folder_view;
1230 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1232 folder_view = modest_main_window_get_child_widget (main_window,
1233 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1237 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1239 mail_op = modest_mail_operation_new ();
1240 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1242 modest_mail_operation_remove_folder (mail_op, folder, move_to_trash);
1244 g_object_unref (G_OBJECT (mail_op));
1245 g_object_unref (G_OBJECT (folder));
1249 modest_ui_actions_on_delete_folder (GtkAction *action,
1250 ModestMainWindow *main_window)
1252 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1254 delete_folder (main_window, FALSE);
1258 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1260 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1262 delete_folder (main_window, TRUE);
1266 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1267 const gchar* account_name,
1271 ModestMainWindow *main_window)
1274 GtkWidget *dialog, *entry, *remember_pass_check;
1276 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1280 GTK_RESPONSE_REJECT,
1282 GTK_RESPONSE_ACCEPT,
1284 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1286 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1287 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1291 entry = gtk_entry_new_with_max_length (40);
1292 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1293 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1295 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1298 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1299 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1302 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1304 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1305 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1312 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1317 gtk_widget_destroy (dialog);
1321 modest_ui_actions_on_cut (GtkAction *action,
1322 ModestWindow *window)
1324 GtkWidget *focused_widget;
1326 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1327 if (GTK_IS_EDITABLE (focused_widget)) {
1328 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1329 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1330 GtkTextBuffer *buffer;
1331 GtkClipboard *clipboard;
1333 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1334 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1335 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1340 modest_ui_actions_on_copy (GtkAction *action,
1341 ModestWindow *window)
1343 GtkClipboard *clipboard;
1344 GtkWidget *focused_widget;
1346 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1347 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1348 if (GTK_IS_LABEL (focused_widget)) {
1349 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1350 } else if (GTK_IS_EDITABLE (focused_widget)) {
1351 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1352 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1353 GtkTextBuffer *buffer;
1355 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1356 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1361 modest_ui_actions_on_paste (GtkAction *action,
1362 ModestWindow *window)
1364 GtkWidget *focused_widget;
1366 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1367 if (GTK_IS_EDITABLE (focused_widget)) {
1368 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1369 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1370 GtkTextBuffer *buffer;
1371 GtkClipboard *clipboard;
1373 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1374 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1375 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1380 modest_ui_actions_on_select_all (GtkAction *action,
1381 ModestWindow *window)
1383 GtkWidget *focused_widget;
1385 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1386 if (GTK_IS_LABEL (focused_widget)) {
1387 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1388 } else if (GTK_IS_EDITABLE (focused_widget)) {
1389 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1390 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1391 GtkTextBuffer *buffer;
1392 GtkTextIter start, end;
1394 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1395 gtk_text_buffer_get_start_iter (buffer, &start);
1396 gtk_text_buffer_get_end_iter (buffer, &end);
1397 gtk_text_buffer_select_range (buffer, &start, &end);