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 /* This is currently only implemented for Maemo,
209 * because it requires a providers preset file which is not publically available.
211 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
212 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
213 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
214 gtk_dialog_run (account_win);
215 gtk_widget_destroy (GTK_WIDGET(account_win));
217 GtkWidget *dialog, *label;
219 /* Create the widgets */
221 dialog = gtk_dialog_new_with_buttons ("Message",
223 GTK_DIALOG_DESTROY_WITH_PARENT,
227 label = gtk_label_new ("Hello World!");
229 /* Ensure that the dialog box is destroyed when the user responds. */
231 g_signal_connect_swapped (dialog, "response",
232 G_CALLBACK (gtk_widget_destroy),
235 /* Add the label, and show everything we've added to the dialog. */
237 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
239 gtk_widget_show_all (dialog);
240 #endif /* MODEST_PLATFORM_MAEMO */
244 modest_ui_actions_on_new_account (GtkAction *action, ModestWindow *win)
246 /* This is currently only implemented for Maemo,
247 * because it requires a providers preset file which is not publically available.
249 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
250 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
251 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
252 gtk_dialog_run (GTK_DIALOG (wizard));
253 gtk_widget_destroy (GTK_WIDGET (wizard));
254 #endif /* MODEST_PLATFORM_MAEMO */
258 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
260 ModestWindow *msg_win;
262 TnyFolder *folder = NULL;
263 gchar *account_name = NULL;
264 gchar *from_str = NULL;
268 account_name = g_strdup(modest_window_get_active_account (win));
270 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
272 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
274 TNY_ACCOUNT_TYPE_STORE);
276 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
280 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
282 msg = modest_tny_msg_new ("", from_str, "", "", "", "", NULL);
284 g_printerr ("modest: failed to create new msg\n");
288 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
290 g_printerr ("modest: failed to find Drafts folder\n");
294 tny_folder_add_msg (folder, msg, &err);
296 g_printerr ("modest: error adding msg to Drafts folder: %s",
302 msg_win = modest_msg_edit_window_new (msg, account_name);
304 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
306 gtk_widget_show_all (GTK_WIDGET (msg_win));
309 g_free (account_name);
312 g_object_unref (G_OBJECT(account));
314 g_object_unref (G_OBJECT(msg));
316 g_object_unref (G_OBJECT(folder));
321 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
323 modest_runtime_not_implemented (GTK_WINDOW(win)); /* FIXME */
329 reply_forward_func (gpointer data, gpointer user_data)
331 TnyMsg *msg, *new_msg;
332 GetMsgAsyncHelper *helper;
333 ReplyForwardHelper *rf_helper;
334 ModestWindow *msg_win;
335 ModestEditType edit_type;
338 TnyFolder *folder = NULL;
339 TnyAccount *account = NULL;
341 msg = TNY_MSG (data);
342 helper = (GetMsgAsyncHelper *) user_data;
343 rf_helper = (ReplyForwardHelper *) helper->user_data;
345 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
346 rf_helper->account_name);
347 /* Create reply mail */
348 switch (rf_helper->action) {
351 modest_tny_msg_create_reply_msg (msg, from,
352 rf_helper->reply_forward_type,
353 MODEST_TNY_MSG_REPLY_MODE_SENDER);
355 case ACTION_REPLY_TO_ALL:
357 modest_tny_msg_create_reply_msg (msg, from, rf_helper->reply_forward_type,
358 MODEST_TNY_MSG_REPLY_MODE_ALL);
359 edit_type = MODEST_EDIT_TYPE_REPLY;
363 modest_tny_msg_create_forward_msg (msg, from, rf_helper->reply_forward_type);
364 edit_type = MODEST_EDIT_TYPE_FORWARD;
367 g_return_if_reached ();
372 g_printerr ("modest: failed to create message\n");
376 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
377 rf_helper->account_name,
378 TNY_ACCOUNT_TYPE_STORE);
380 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
384 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
386 g_printerr ("modest: failed to find Drafts folder\n");
390 tny_folder_add_msg (folder, msg, &err);
392 g_printerr ("modest: error adding msg to Drafts folder: %s",
398 /* Show edit window */
399 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
400 gtk_widget_show_all (GTK_WIDGET (msg_win));
404 g_object_unref (G_OBJECT (new_msg));
406 g_object_unref (G_OBJECT (folder));
408 g_object_unref (G_OBJECT (account));
410 g_free (rf_helper->account_name);
411 g_slice_free (ReplyForwardHelper, rf_helper);
414 * Common code for the reply and forward actions
417 reply_forward (ReplyForwardAction action, ModestWindow *win)
419 TnyList *header_list;
420 guint reply_forward_type;
423 GetMsgAsyncHelper *helper;
424 ReplyForwardHelper *rf_helper;
426 g_return_if_fail (MODEST_IS_WINDOW(win));
428 header_list = get_selected_headers (win);
432 reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
433 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
435 /* We assume that we can only select messages of the
436 same folder and that we reply all of them from the
437 same account. In fact the interface currently only
438 allows single selection */
441 rf_helper = g_slice_new0 (ReplyForwardHelper);
442 rf_helper->reply_forward_type = reply_forward_type;
443 rf_helper->action = action;
445 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
446 if (!rf_helper->account_name)
447 rf_helper->account_name =
448 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
450 helper = g_slice_new0 (GetMsgAsyncHelper);
451 helper->window = win;
452 helper->func = reply_forward_func;
453 helper->iter = tny_list_create_iterator (header_list);
454 helper->user_data = rf_helper;
456 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
458 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
460 g_printerr ("modest: no message found\n");
463 reply_forward_func (msg, helper);
465 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
466 folder = tny_header_get_folder (header);
468 /* The callback will call it per each header */
469 tny_folder_get_msg_async (folder, header, get_msg_cb, helper);
470 g_object_unref (G_OBJECT (folder));
472 g_printerr ("modest: no folder for header\n");
475 g_object_unref (G_OBJECT (header));
481 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
483 g_return_if_fail (MODEST_IS_WINDOW(win));
485 reply_forward (ACTION_REPLY, win);
489 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
491 g_return_if_fail (MODEST_IS_WINDOW(win));
493 reply_forward (ACTION_FORWARD, win);
497 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
499 g_return_if_fail (MODEST_IS_WINDOW(win));
501 reply_forward (ACTION_REPLY_TO_ALL, win);
505 modest_ui_actions_on_next (GtkAction *action,
506 ModestMainWindow *main_window)
508 GtkWidget *header_view;
509 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
511 header_view = modest_main_window_get_child_widget (main_window,
512 MODEST_WIDGET_TYPE_HEADER_VIEW);
516 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
520 modest_ui_actions_on_prev (GtkAction *action,
521 ModestMainWindow *main_window)
523 GtkWidget *header_view;
524 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
526 header_view = modest_main_window_get_child_widget (main_window,
527 MODEST_WIDGET_TYPE_HEADER_VIEW);
531 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
536 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
539 TnyAccount *tny_account;
540 ModestTnySendQueue *send_queue;
541 ModestMailOperation *mail_op;
544 g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
546 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
548 g_printerr ("modest: cannot get account\n");
553 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
555 TNY_ACCOUNT_TYPE_TRANSPORT);
557 g_printerr ("modest: cannot get tny transport account for %s\n", account_name);
560 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account));
562 g_object_unref (G_OBJECT(tny_account));
563 g_printerr ("modest: cannot get send queue for %s\n", account_name);
566 //modest_tny_send_queue_flush (send_queue);
568 g_object_unref (G_OBJECT(send_queue));
569 g_object_unref (G_OBJECT(tny_account));
572 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
574 TNY_ACCOUNT_TYPE_STORE);
576 g_printerr ("modest: cannot get tny store account for %s\n", account_name);
580 /* Create the mail operation */
581 mail_op = modest_mail_operation_new ();
582 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
583 modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
586 g_object_unref (G_OBJECT (tny_account));
587 g_object_unref (G_OBJECT (mail_op));
593 modest_ui_actions_toggle_view (GtkAction *action, ModestMainWindow *main_window)
596 GtkWidget *header_view;
598 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
600 header_view = modest_main_window_get_child_widget (main_window,
601 MODEST_WIDGET_TYPE_HEADER_VIEW);
605 conf = modest_runtime_get_conf ();
607 /* what is saved/restored is depending on the style; thus; we save with
608 * old style, then update the style, and restore for this new style
610 modest_widget_memory_save (conf, G_OBJECT(header_view), "header-view");
612 if (modest_header_view_get_style
613 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
614 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
615 MODEST_HEADER_VIEW_STYLE_TWOLINES);
617 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
618 MODEST_HEADER_VIEW_STYLE_DETAILS);
620 modest_widget_memory_restore (conf, G_OBJECT(header_view),
627 * Marks a message as read and passes it to the msg preview widget
630 read_msg_func (gpointer data, gpointer user_data)
634 GetMsgAsyncHelper *helper;
635 TnyHeaderFlags header_flags;
636 GtkWidget *msg_preview;
638 msg = TNY_MSG (data);
639 helper = (GetMsgAsyncHelper *) user_data;
641 msg_preview = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (helper->window),
642 MODEST_WIDGET_TYPE_MSG_PREVIEW);
646 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
647 header_flags = tny_header_get_flags (header);
648 tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
649 g_object_unref (G_OBJECT (header));
651 /* Set message on msg view */
652 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), msg);
656 * This function is a generic handler for the tny_folder_get_msg_async
657 * call. It expects as user_data a #GetMsgAsyncHelper. This helper
658 * contains a user provided function that is called inside this
659 * method. This will allow us to use this callback in many different
660 * places. This callback performs the common actions for the
661 * get_msg_async call, more specific actions will be done by the user
665 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
667 GetMsgAsyncHelper *helper;
669 helper = (GetMsgAsyncHelper *) user_data;
671 if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
672 modest_ui_actions_on_item_not_found (NULL,
673 MODEST_ITEM_TYPE_MESSAGE,
678 /* Call user function */
679 helper->func (msg, user_data);
681 /* Process next element (if exists) */
682 tny_iterator_next (helper->iter);
683 if (tny_iterator_is_done (helper->iter)) {
685 headers = tny_iterator_get_list (helper->iter);
687 g_object_unref (G_OBJECT (headers));
688 g_object_unref (G_OBJECT (helper->iter));
689 g_slice_free (GetMsgAsyncHelper, helper);
692 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
693 tny_folder_get_msg_async (folder, header,
695 g_object_unref (G_OBJECT(header));
700 modest_ui_actions_on_header_selected (ModestHeaderView *folder_view,
702 ModestMainWindow *main_window)
704 GtkWidget *msg_preview;
706 GetMsgAsyncHelper *helper;
709 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
711 msg_preview = modest_main_window_get_child_widget(main_window,
712 MODEST_WIDGET_TYPE_MSG_PREVIEW);
716 /* when there's no header, clear the msgview */
718 modest_msg_view_set_message (MODEST_MSG_VIEW(msg_preview), NULL);
722 folder = tny_header_get_folder (TNY_HEADER(header));
725 list = tny_simple_list_new ();
726 tny_list_prepend (list, G_OBJECT (header));
728 /* Fill helper data */
729 helper = g_slice_new0 (GetMsgAsyncHelper);
730 helper->window = MODEST_WINDOW (main_window);
731 helper->iter = tny_list_create_iterator (list);
732 helper->func = read_msg_func;
734 tny_folder_get_msg_async (TNY_FOLDER(folder),
739 g_object_unref (G_OBJECT (folder));
745 modest_ui_actions_on_header_activated (ModestHeaderView *folder_view, TnyHeader *header,
746 ModestMainWindow *main_window)
749 TnyFolder *folder = NULL;
751 gchar *account = NULL;
753 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
758 folder = tny_header_get_folder (header);
760 g_printerr ("modest: cannot get folder for header\n");
764 /* FIXME: make async?; check error */
765 msg = tny_folder_get_msg (folder, header, NULL);
767 g_printerr ("modest: cannot get msg for header\n");
771 account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
773 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
775 win = modest_msg_view_window_new (msg, account);
776 gtk_window_set_transient_for (GTK_WINDOW (win),
777 GTK_WINDOW (main_window));
779 gtk_widget_show_all (GTK_WIDGET(win));
785 g_object_unref (G_OBJECT (folder));
787 g_object_unref (G_OBJECT (msg));
791 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
794 ModestMainWindow *main_window)
798 GtkWidget *header_view;
800 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
802 header_view = modest_main_window_get_child_widget(main_window,
803 MODEST_WIDGET_TYPE_HEADER_VIEW);
807 conf = modest_runtime_get_conf ();
809 if (!selected) { /* the folder was unselected; save it's settings */
810 modest_widget_memory_save (conf, G_OBJECT (header_view), "header-view");
811 gtk_window_set_title (GTK_WINDOW(main_window), "Modest");
812 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
813 } else { /* the folder was selected */
814 if (folder) { /* folder may be NULL */
818 num = tny_folder_get_all_count (folder);
819 unread = tny_folder_get_unread_count (folder);
821 title = g_strdup_printf ("Modest: %s",
822 tny_folder_get_name (folder));
824 gtk_window_set_title (GTK_WINDOW(main_window), title);
827 txt = g_strdup_printf (_("%d %s, %d unread"),
828 num, num==1 ? _("item") : _("items"), unread);
829 //gtk_label_set_label (GTK_LABEL(folder_info_label), txt);
832 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), folder);
833 modest_widget_memory_restore (conf, G_OBJECT(header_view),
839 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
846 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
848 if (g_main_depth > 0)
849 gdk_threads_enter ();
850 online = tny_device_is_online (modest_runtime_get_device());
853 /* already online -- the item is simply not there... */
854 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
858 _("The %s you selected cannot be found"),
860 gtk_dialog_run (GTK_DIALOG(dialog));
862 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
870 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
871 "Do you want to get online?"), item);
872 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
873 gtk_label_new (txt), FALSE, FALSE, 0);
874 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
877 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
878 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
879 // tny_device_force_online (modest_runtime_get_device());
882 gtk_widget_destroy (dialog);
883 if (g_main_depth > 0)
884 gdk_threads_leave ();
888 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
891 g_message (__FUNCTION__);
896 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
899 g_message (__FUNCTION__);
903 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
906 g_message (__FUNCTION__);
911 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
912 const gchar *address,
915 g_message ("%s %s", __FUNCTION__, address);
919 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
921 TnyTransportAccount *transport_account;
922 ModestMailOperation *mail_operation;
924 gchar *account_name, *from;
925 ModestAccountMgr *account_mgr;
927 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
929 data = modest_msg_edit_window_get_msg_data (edit_window);
931 /* FIXME: Code added just for testing. The final version will
932 use the send queue provided by tinymail and some
934 account_mgr = modest_runtime_get_account_mgr();
935 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
937 account_name = modest_account_mgr_get_default_account (account_mgr);
939 g_printerr ("modest: no account found\n");
940 modest_msg_edit_window_free_msg_data (edit_window, data);
944 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
945 (modest_runtime_get_account_store(),
947 TNY_ACCOUNT_TYPE_TRANSPORT));
948 if (!transport_account) {
949 g_printerr ("modest: no transport account found for '%s'\n", account_name);
950 g_free (account_name);
951 modest_msg_edit_window_free_msg_data (edit_window, data);
954 from = modest_account_mgr_get_from_string (account_mgr, account_name);
956 /* Create the mail operation */
957 mail_operation = modest_mail_operation_new ();
958 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
960 modest_mail_operation_send_new_mail (mail_operation,
972 g_free (account_name);
973 g_object_unref (G_OBJECT (transport_account));
974 g_object_unref (G_OBJECT (mail_operation));
976 modest_msg_edit_window_free_msg_data (edit_window, data);
978 /* Save settings and close the window */
979 gtk_widget_destroy (GTK_WIDGET (edit_window));
983 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
984 ModestMsgEditWindow *window)
986 ModestMsgEditFormatState *format_state = NULL;
988 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
989 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
991 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
994 format_state = modest_msg_edit_window_get_format_state (window);
995 g_return_if_fail (format_state != NULL);
997 format_state->bold = gtk_toggle_action_get_active (action);
998 modest_msg_edit_window_set_format_state (window, format_state);
999 g_free (format_state);
1004 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1005 ModestMsgEditWindow *window)
1007 ModestMsgEditFormatState *format_state = NULL;
1009 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1010 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1012 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1015 format_state = modest_msg_edit_window_get_format_state (window);
1016 g_return_if_fail (format_state != NULL);
1018 format_state->italics = gtk_toggle_action_get_active (action);
1019 modest_msg_edit_window_set_format_state (window, format_state);
1020 g_free (format_state);
1025 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1026 ModestMsgEditWindow *window)
1028 ModestMsgEditFormatState *format_state = NULL;
1030 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1031 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1033 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1036 format_state = modest_msg_edit_window_get_format_state (window);
1037 g_return_if_fail (format_state != NULL);
1039 format_state->bullet = gtk_toggle_action_get_active (action);
1040 modest_msg_edit_window_set_format_state (window, format_state);
1041 g_free (format_state);
1046 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1047 GtkRadioAction *selected,
1048 ModestMsgEditWindow *window)
1050 ModestMsgEditFormatState *format_state = NULL;
1051 GtkJustification value;
1053 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1055 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1058 value = gtk_radio_action_get_current_value (selected);
1060 format_state = modest_msg_edit_window_get_format_state (window);
1061 g_return_if_fail (format_state != NULL);
1063 format_state->justification = value;
1064 modest_msg_edit_window_set_format_state (window, format_state);
1065 g_free (format_state);
1069 modest_ui_actions_on_select_editor_color (GtkAction *action,
1070 ModestMsgEditWindow *window)
1072 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1073 g_return_if_fail (GTK_IS_ACTION (action));
1075 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1078 modest_msg_edit_window_select_color (window);
1082 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1083 ModestMsgEditWindow *window)
1085 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1086 g_return_if_fail (GTK_IS_ACTION (action));
1088 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1091 modest_msg_edit_window_select_background_color (window);
1095 modest_ui_actions_on_insert_image (GtkAction *action,
1096 ModestMsgEditWindow *window)
1098 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1099 g_return_if_fail (GTK_IS_ACTION (action));
1101 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1104 modest_msg_edit_window_insert_image (window);
1108 * Shows a dialog with an entry that asks for some text. The returned
1109 * value must be freed by the caller. The dialog window title will be
1113 ask_for_folder_name (GtkWindow *parent_window,
1116 GtkWidget *dialog, *entry;
1117 gchar *folder_name = NULL;
1119 /* Ask for folder name */
1120 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1124 GTK_RESPONSE_REJECT,
1126 GTK_RESPONSE_ACCEPT,
1128 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1129 gtk_label_new(title),
1132 entry = gtk_entry_new_with_max_length (40);
1133 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1137 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1139 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1140 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1142 gtk_widget_destroy (dialog);
1148 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1150 TnyFolder *parent_folder;
1151 GtkWidget *folder_view;
1153 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1155 folder_view = modest_main_window_get_child_widget (main_window,
1156 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1160 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1162 if (parent_folder) {
1165 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1166 _("Please enter a name for the new folder"));
1168 if (folder_name != NULL && strlen (folder_name) > 0) {
1169 TnyFolder *new_folder;
1170 ModestMailOperation *mail_op;
1172 mail_op = modest_mail_operation_new ();
1173 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1176 new_folder = modest_mail_operation_create_folder (mail_op,
1177 TNY_FOLDER_STORE (parent_folder),
1178 (const gchar *) folder_name);
1180 g_object_unref (new_folder);
1181 g_object_unref (mail_op);
1182 g_free (folder_name);
1184 g_object_unref (parent_folder);
1189 modest_ui_actions_on_rename_folder (GtkAction *action,
1190 ModestMainWindow *main_window)
1193 GtkWidget *folder_view;
1195 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1197 folder_view = modest_main_window_get_child_widget (main_window,
1198 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1202 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1206 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1207 _("Please enter a new name for the folder"));
1209 if (folder_name != NULL && strlen (folder_name) > 0) {
1210 ModestMailOperation *mail_op;
1212 mail_op = modest_mail_operation_new ();
1213 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1216 modest_mail_operation_rename_folder (mail_op,
1218 (const gchar *) folder_name);
1220 g_object_unref (mail_op);
1221 g_free (folder_name);
1223 g_object_unref (folder);
1228 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1231 ModestMailOperation *mail_op;
1232 GtkWidget *folder_view;
1234 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1236 folder_view = modest_main_window_get_child_widget (main_window,
1237 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1241 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1243 mail_op = modest_mail_operation_new ();
1244 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1246 modest_mail_operation_remove_folder (mail_op, folder, move_to_trash);
1248 g_object_unref (G_OBJECT (mail_op));
1249 g_object_unref (G_OBJECT (folder));
1253 modest_ui_actions_on_delete_folder (GtkAction *action,
1254 ModestMainWindow *main_window)
1256 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1258 delete_folder (main_window, FALSE);
1262 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1264 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1266 delete_folder (main_window, TRUE);
1270 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1271 const gchar* account_name,
1275 ModestMainWindow *main_window)
1278 GtkWidget *dialog, *entry, *remember_pass_check;
1280 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1284 GTK_RESPONSE_REJECT,
1286 GTK_RESPONSE_ACCEPT,
1288 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1290 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1291 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1295 entry = gtk_entry_new_with_max_length (40);
1296 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1297 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1299 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1302 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1303 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1306 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1308 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1309 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1316 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1321 gtk_widget_destroy (dialog);
1325 modest_ui_actions_on_cut (GtkAction *action,
1326 ModestWindow *window)
1328 GtkWidget *focused_widget;
1330 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1331 if (GTK_IS_EDITABLE (focused_widget)) {
1332 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1333 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1334 GtkTextBuffer *buffer;
1335 GtkClipboard *clipboard;
1337 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1338 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1339 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1344 modest_ui_actions_on_copy (GtkAction *action,
1345 ModestWindow *window)
1347 GtkClipboard *clipboard;
1348 GtkWidget *focused_widget;
1350 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1351 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1352 if (GTK_IS_LABEL (focused_widget)) {
1353 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1354 } else if (GTK_IS_EDITABLE (focused_widget)) {
1355 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1356 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1357 GtkTextBuffer *buffer;
1359 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1360 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1365 modest_ui_actions_on_paste (GtkAction *action,
1366 ModestWindow *window)
1368 GtkWidget *focused_widget;
1370 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1371 if (GTK_IS_EDITABLE (focused_widget)) {
1372 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1373 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1374 GtkTextBuffer *buffer;
1375 GtkClipboard *clipboard;
1377 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1378 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1379 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1384 modest_ui_actions_on_select_all (GtkAction *action,
1385 ModestWindow *window)
1387 GtkWidget *focused_widget;
1389 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1390 if (GTK_IS_LABEL (focused_widget)) {
1391 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1392 } else if (GTK_IS_EDITABLE (focused_widget)) {
1393 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1394 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1395 GtkTextBuffer *buffer;
1396 GtkTextIter start, end;
1398 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1399 gtk_text_buffer_get_start_iter (buffer, &start);
1400 gtk_text_buffer_get_end_iter (buffer, &end);
1401 gtk_text_buffer_select_range (buffer, &start, &end);