1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include "modest-ui-priv.h"
36 #include "modest-ui.h"
37 #include "modest-ui-actions.h"
38 #include "modest-icon-names.h"
39 #include "modest-tny-platform-factory.h"
40 #include "modest-account-view-window.h"
41 #include "modest-main-window.h"
42 #include <tny-error.h>
43 #include <tny-simple-list.h>
45 #define MODEST_UI_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
49 typedef struct _GetMsgAsyncHelper {
50 ModestMainWindow *main_window;
56 typedef enum _ReplyForwardAction {
62 typedef struct _ReplyForwardHelper {
63 guint reply_forward_type;
64 ReplyForwardAction action;
69 static GObjectClass *parent_class = NULL;
71 /* 'private'/'protected' functions */
72 static void modest_ui_class_init (ModestUIClass *klass);
73 static void modest_ui_init (ModestUI *obj);
74 static void modest_ui_finalize (GObject *obj);
76 static void register_stock_icons ();
77 static void connect_signals (ModestUI *self);
78 /* static GtkUIManager *create_ui_manager (); */
80 static void reply_forward_func (gpointer data, gpointer user_data);
81 static void read_msg_func (gpointer data, gpointer user_data);
82 static void get_msg_cb (TnyFolder *folder,
87 static void reply_forward (GtkWidget *widget,
88 ReplyForwardAction action,
89 ModestMainWindow *main_window);
91 static void _modest_ui_actions_on_password_requested (ModestTnyAccountStore *account_store,
92 const gchar* account_name,
96 ModestMainWindow *main_window);
99 modest_ui_get_type (void)
101 static GType my_type = 0;
103 static const GTypeInfo my_info = {
104 sizeof(ModestUIClass),
105 NULL, /* base init */
106 NULL, /* base finalize */
107 (GClassInitFunc) modest_ui_class_init,
108 NULL, /* class finalize */
109 NULL, /* class data */
112 (GInstanceInitFunc) modest_ui_init,
115 my_type = g_type_register_static (G_TYPE_OBJECT,
124 modest_ui_class_init (ModestUIClass *klass)
126 GObjectClass *gobject_class;
127 gobject_class = (GObjectClass*) klass;
129 parent_class = g_type_class_peek_parent (klass);
130 gobject_class->finalize = modest_ui_finalize;
132 g_type_class_add_private (gobject_class, sizeof(ModestUIPrivate));
138 modest_ui_init (ModestUI *obj)
140 ModestUIPrivate *priv;
142 priv = MODEST_UI_GET_PRIVATE(obj);
144 priv->widget_factory = NULL;
145 priv->main_window = NULL;
146 priv->account_store = NULL;
151 modest_ui_finalize (GObject *obj)
154 ModestUIPrivate *priv = MODEST_UI_GET_PRIVATE(obj);
156 if (priv->widget_factory) {
157 g_object_unref (G_OBJECT(priv->widget_factory));
158 priv->widget_factory = NULL;
161 if (priv->ui_manager) {
162 g_object_unref (G_OBJECT(priv->ui_manager));
163 priv->ui_manager = NULL;
166 G_OBJECT_CLASS(parent_class)->finalize (obj);
171 modest_ui_new (TnyAccountStore *account_store)
174 ModestUIPrivate *priv;
175 TnyPlatformFactory *fact;
176 ModestAccountMgr *account_mgr;
178 obj = g_object_new(MODEST_TYPE_UI, NULL);
179 priv = MODEST_UI_GET_PRIVATE(obj);
181 /* Get the platform-dependent instances */
182 fact = modest_tny_platform_factory_get_instance ();
184 priv->account_store = account_store;
186 account_mgr = modest_tny_platform_factory_get_modest_account_mgr_instance (fact);
188 g_printerr ("modest: could not create ModestAccountMgr instance\n");
189 g_object_unref (obj);
193 priv->widget_factory = modest_widget_factory_new ();
194 if (!priv->widget_factory) {
195 g_printerr ("modest: could not initialize widget factory\n");
199 /* Register our own icons as stock icons in order to
200 use them with the UI manager */
201 register_stock_icons ();
203 return MODEST_UI(obj);
207 on_main_window_destroy (GtkObject *widget, ModestUI *self)
209 /* FIXME: check if there any viewer/editing windows opened */
216 modest_ui_main_window (ModestUI *self)
218 ModestUIPrivate *priv;
220 g_return_val_if_fail (self, NULL);
221 priv = MODEST_UI_GET_PRIVATE(self);
223 if (!priv->main_window) {
225 /* Create main window */
226 priv->main_window = modest_main_window_new (priv->widget_factory,
227 priv->account_store);
229 connect_signals (self);
232 if (!priv->main_window)
233 g_printerr ("modest: could not create main window\n");
235 return priv->main_window;
239 modest_ui_edit_window (ModestUI *self, ModestEditType edit_type)
241 ModestUIPrivate *priv;
242 ModestWindow *edit_window;
244 g_return_val_if_fail (self, NULL);
245 priv = MODEST_UI_GET_PRIVATE(self);
248 edit_window = modest_edit_msg_window_new (priv->widget_factory,
252 /* Connect Edit Window signals */
253 /* connect_edit_window_signals (self); */
259 * This function registers our custom toolbar icons, so they can be
260 * themed. The idea of this function was taken from the gtk-demo
263 register_stock_icons ()
265 static gboolean registered = FALSE;
269 GtkIconFactory *factory;
273 static GtkStockItem items[] = {
274 { MODEST_STOCK_MAIL_SEND, "send mail", 0, 0, NULL },
275 { MODEST_STOCK_NEW_MAIL, "new mail", 0, 0, NULL },
276 { MODEST_STOCK_SEND_RECEIVE, "send receive", 0, 0, NULL },
277 { MODEST_STOCK_REPLY, "reply", 0, 0, NULL },
278 { MODEST_STOCK_REPLY_ALL, "reply all", 0, 0, NULL },
279 { MODEST_STOCK_FORWARD, "forward", 0, 0, NULL },
280 { MODEST_STOCK_DELETE, "delete", 0, 0, NULL },
281 { MODEST_STOCK_NEXT, "next", 0, 0, NULL },
282 { MODEST_STOCK_PREV, "prev", 0, 0, NULL },
283 { MODEST_STOCK_STOP, "stop", 0, 0, NULL }
286 static gchar *items_names [] = {
287 MODEST_TOOLBAR_ICON_MAIL_SEND,
288 MODEST_TOOLBAR_ICON_NEW_MAIL,
289 MODEST_TOOLBAR_ICON_SEND_RECEIVE,
290 MODEST_TOOLBAR_ICON_REPLY,
291 MODEST_TOOLBAR_ICON_REPLY_ALL,
292 MODEST_TOOLBAR_ICON_FORWARD,
293 MODEST_TOOLBAR_ICON_DELETE,
294 MODEST_TOOLBAR_ICON_NEXT,
295 MODEST_TOOLBAR_ICON_PREV,
296 MODEST_TOOLBAR_ICON_STOP
301 /* Register our stock items */
302 gtk_stock_add (items, G_N_ELEMENTS (items));
304 /* Add our custom icon factory to the list of defaults */
305 factory = gtk_icon_factory_new ();
306 gtk_icon_factory_add_default (factory);
308 /* Register icons to accompany stock items */
309 for (i = 0; i < G_N_ELEMENTS (items); i++) {
311 pixbuf = gdk_pixbuf_new_from_file (items_names[i], NULL);
313 if (pixbuf != NULL) {
314 GtkIconSet *icon_set;
315 GdkPixbuf *transparent;
317 transparent = gdk_pixbuf_add_alpha (pixbuf, TRUE, 0xff, 0xff, 0xff);
319 icon_set = gtk_icon_set_new_from_pixbuf (transparent);
320 gtk_icon_factory_add (factory, items[i].stock_id, icon_set);
321 gtk_icon_set_unref (icon_set);
322 g_object_unref (pixbuf);
323 g_object_unref (transparent);
326 g_warning ("failed to load %s icon", items_names[i]);
328 /* Drop our reference to the factory, GTK will hold a reference. */
329 g_object_unref (factory);
333 /* FIXME: uninit these as well */
335 connect_signals (ModestUI *self)
338 ModestUIPrivate *priv;
339 ModestFolderView *folder_view;
340 ModestHeaderView *header_view;
341 ModestMsgView *msg_view;
344 priv = MODEST_UI_GET_PRIVATE(self);
346 folder_view = modest_widget_factory_get_folder_view (priv->widget_factory);
347 header_view = modest_widget_factory_get_header_view (priv->widget_factory);
348 msg_view = modest_widget_factory_get_msg_preview (priv->widget_factory);
349 toggle = modest_widget_factory_get_online_toggle (priv->widget_factory);
350 device = tny_account_store_get_device (priv->account_store);
353 g_signal_connect (G_OBJECT(folder_view), "folder_selection_changed",
354 G_CALLBACK(_modest_ui_actions_on_folder_selection_changed),
356 /* g_signal_connect (G_OBJECT(folder_view), "key-press-event", */
357 /* G_CALLBACK(on_folder_key_press_event), priv->widget_factory); */
360 g_signal_connect (G_OBJECT(header_view), "status_update",
361 G_CALLBACK(_modest_ui_actions_on_header_status_update),
363 g_signal_connect (G_OBJECT(header_view), "header_selected",
364 G_CALLBACK(_modest_ui_actions_on_header_selected),
366 g_signal_connect (G_OBJECT(header_view), "item_not_found",
367 G_CALLBACK(_modest_ui_actions_on_item_not_found),
372 g_signal_connect (G_OBJECT(msg_view), "link_clicked",
373 G_CALLBACK(_modest_ui_actions_on_msg_link_clicked),
375 g_signal_connect (G_OBJECT(msg_view), "link_hover",
376 G_CALLBACK(_modest_ui_actions_on_msg_link_hover),
378 g_signal_connect (G_OBJECT(msg_view), "attachment_clicked",
379 G_CALLBACK(_modest_ui_actions_on_msg_attachment_clicked),
383 g_signal_connect (G_OBJECT(device), "connection_changed",
384 G_CALLBACK(_modest_ui_actions_on_connection_changed),
386 g_signal_connect (G_OBJECT(toggle), "toggled",
387 G_CALLBACK(_modest_ui_actions_on_online_toggle_toggled),
391 g_signal_connect (G_OBJECT (priv->account_store),
392 "password_requested",
393 G_CALLBACK(_modest_ui_actions_on_password_requested),
397 g_signal_connect (G_OBJECT(priv->main_window),
399 G_CALLBACK(on_main_window_destroy),
403 /* Init toggle in correct state */
404 _modest_ui_actions_on_connection_changed (device,
405 tny_device_is_online (device),
406 MODEST_MAIN_WINDOW (priv->main_window));
410 /* ***************************************************************** */
411 /* M O D E S T U I A C T I O N S */
412 /* ***************************************************************** */
414 _modest_ui_actions_on_about (GtkWidget *widget,
415 ModestMainWindow *main_window)
418 const gchar *authors[] = {
419 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
422 about = gtk_about_dialog_new ();
423 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
424 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
425 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
426 _("Copyright (c) 2006, Nokia Corporation\n"
427 "All rights reserved."));
428 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
429 _("a modest e-mail client\n\n"
430 "design and implementation: Dirk-Jan C. Binnema\n"
431 "contributions from the fine people at KernelConcepts and Igalia\n"
432 "uses the tinymail email framework written by Philip van Hoof"));
433 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
434 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
436 gtk_dialog_run (GTK_DIALOG (about));
437 gtk_widget_destroy(about);
441 _modest_ui_actions_on_delete (GtkWidget *widget,
442 ModestMainWindow *main_window)
444 ModestWidgetFactory *widget_factory;
445 ModestHeaderView *header_view;
446 TnyList *header_list;
450 widget_factory = modest_main_window_get_widget_factory (main_window);
451 header_view = modest_widget_factory_get_header_view (widget_factory);
452 header_list = modest_header_view_get_selected_headers (header_view);
453 g_object_unref (G_OBJECT(widget_factory));
456 iter = tny_list_create_iterator (header_list);
457 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
458 if (GTK_IS_TREE_MODEL_SORT (model))
459 model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (model));
462 ModestMailOperation *mail_op;
464 header = TNY_HEADER (tny_iterator_get_current (iter));
465 /* TODO: thick grain mail operation involving
466 a list of objects. Composite pattern ??? */
467 mail_op = modest_mail_operation_new ();
469 /* TODO: add confirmation dialog */
472 modest_mail_operation_remove_msg (mail_op, header, TRUE);
474 /* Remove from tree model */
475 if (modest_mail_operation_get_status (mail_op) ==
476 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
477 tny_list_remove (TNY_LIST (model), G_OBJECT (header));
479 /* TODO: error handling management */
481 error = modest_mail_operation_get_error (mail_op);
482 g_warning (error->message);
485 g_object_unref (G_OBJECT (mail_op));
486 g_object_unref (header);
487 tny_iterator_next (iter);
489 } while (!tny_iterator_is_done (iter));
494 _modest_ui_actions_on_quit (GtkWidget *widget,
495 ModestMainWindow *main_window)
497 /* FIXME: save size of main window */
498 /* save_sizes (main_window); */
499 gtk_widget_destroy (GTK_WIDGET (main_window));
503 _modest_ui_actions_on_accounts (GtkWidget *widget,
504 ModestMainWindow *main_window)
506 GtkWidget *account_win;
507 ModestWidgetFactory *widget_factory;
509 widget_factory = modest_main_window_get_widget_factory (main_window);
510 account_win = modest_account_view_window_new (widget_factory);
511 g_object_unref (G_OBJECT(widget_factory));
513 gtk_window_set_transient_for (GTK_WINDOW (account_win),
514 GTK_WINDOW (main_window));
516 gtk_widget_show (account_win);
520 _modest_ui_actions_on_new_msg (GtkWidget *widget,
521 ModestMainWindow *main_window)
523 ModestWindow *msg_win;
524 ModestWidgetFactory *widget_factory;
525 TnyAccountStore *account_store;
527 widget_factory = modest_main_window_get_widget_factory (main_window);
528 account_store = modest_main_window_get_account_store (main_window);
529 msg_win = modest_edit_msg_window_new (widget_factory,
531 MODEST_EDIT_TYPE_NEW);
532 g_object_unref (G_OBJECT (widget_factory));
533 g_object_unref (G_OBJECT (account_store));
535 gtk_widget_show (GTK_WIDGET (msg_win));
539 reply_forward_func (gpointer data, gpointer user_data)
541 ModestWidgetFactory *widget_factory;
542 TnyHeader *new_header;
543 TnyMsg *msg, *new_msg;
544 TnyAccountStore *account_store;
545 GetMsgAsyncHelper *helper;
546 ReplyForwardHelper *rf_helper;
548 ModestEditType edit_type;
550 msg = TNY_MSG (data);
551 helper = (GetMsgAsyncHelper *) user_data;
552 rf_helper = (ReplyForwardHelper *) helper->user_data;
554 /* Create reply mail */
555 switch (rf_helper->action) {
558 modest_mail_operation_create_reply_mail (msg,
560 rf_helper->reply_forward_type,
561 MODEST_MAIL_OPERATION_REPLY_MODE_SENDER);
562 case ACTION_REPLY_TO_ALL:
564 modest_mail_operation_create_reply_mail (msg, rf_helper->from, rf_helper->reply_forward_type,
565 MODEST_MAIL_OPERATION_REPLY_MODE_ALL);
566 edit_type = MODEST_EDIT_TYPE_REPLY;
570 modest_mail_operation_create_forward_mail (msg, rf_helper->from, rf_helper->reply_forward_type);
571 edit_type = MODEST_EDIT_TYPE_FORWARD;
576 new_header = tny_msg_get_header (new_msg);
577 tny_header_set_from (new_header, rf_helper->from);
578 g_object_unref (G_OBJECT (new_header));
580 /* Show edit window */
581 widget_factory = modest_main_window_get_widget_factory (helper->main_window);
582 account_store = modest_main_window_get_account_store (helper->main_window);
583 msg_win = modest_edit_msg_window_new (widget_factory,
585 MODEST_EDIT_TYPE_NEW);
586 g_object_unref (G_OBJECT (widget_factory));
587 g_object_unref (G_OBJECT (account_store));
588 modest_edit_msg_window_set_msg (MODEST_EDIT_MSG_WINDOW (msg_win),
590 gtk_widget_show (GTK_WIDGET (msg_win));
593 g_object_unref (G_OBJECT (new_msg));
594 g_free (rf_helper->from);
595 g_slice_free (ReplyForwardHelper, rf_helper);
599 * Common code for the reply and forward actions
602 reply_forward (GtkWidget *widget,
603 ReplyForwardAction action,
604 ModestMainWindow *main_window)
606 ModestHeaderView *header_view;
607 ModestWidgetFactory *widget_factory;
608 TnyList *header_list;
609 guint reply_forward_type;
611 TnyPlatformFactory *plat_factory;
615 ModestFolderView *folder_view;
616 GetMsgAsyncHelper *helper;
617 ReplyForwardHelper *rf_helper;
620 plat_factory = modest_tny_platform_factory_get_instance ();
621 conf = modest_tny_platform_factory_get_modest_conf_instance (plat_factory);
623 /* Get reply or forward type */
624 key = g_strdup_printf ("%s/%s", MODEST_CONF_NAMESPACE,
625 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE);
626 reply_forward_type = modest_conf_get_int (conf, key, NULL);
629 /* Get the list of headers */
630 widget_factory = modest_main_window_get_widget_factory (main_window);
631 header_view = modest_widget_factory_get_header_view (widget_factory);
632 header_list = modest_header_view_get_selected_headers (header_view);
633 g_object_unref (G_OBJECT(widget_factory));
638 /* We assume that we can only select messages of the
639 same folder and that we reply all of them from the
640 same account. In fact the interface currently only
641 allows single selection */
643 /* TODO: get the from string from account */
644 from = g_strdup ("Invalid");
647 rf_helper = g_slice_new0 (ReplyForwardHelper);
648 rf_helper->reply_forward_type = reply_forward_type;
649 rf_helper->action = action;
650 rf_helper->from = from;
652 helper = g_slice_new0 (GetMsgAsyncHelper);
653 helper->main_window = main_window;
654 helper->func = reply_forward_func;
655 helper->iter = tny_list_create_iterator (header_list);
656 helper->user_data = rf_helper;
658 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
659 folder = tny_header_get_folder (header);
661 /* The callback will call it per each header */
662 tny_folder_get_msg_async (folder, header, get_msg_cb, helper);
665 g_object_unref (G_OBJECT (folder));
669 _modest_ui_actions_on_reply (GtkWidget *widget,
670 ModestMainWindow *main_window)
672 reply_forward (widget, ACTION_REPLY, main_window);
676 _modest_ui_actions_on_forward (GtkWidget *widget,
677 ModestMainWindow *main_window)
679 reply_forward (widget, ACTION_FORWARD, main_window);
683 _modest_ui_actions_on_reply_all (GtkWidget *widget,
684 ModestMainWindow *main_window)
686 reply_forward (widget, ACTION_REPLY_TO_ALL, main_window);
690 _modest_ui_actions_on_next (GtkWidget *widget,
691 ModestMainWindow *main_window)
693 ModestHeaderView *header_view;
694 ModestWidgetFactory *widget_factory;
696 widget_factory = modest_main_window_get_widget_factory (main_window);
697 header_view = modest_widget_factory_get_header_view (widget_factory);
698 g_object_unref (G_OBJECT(widget_factory));
700 modest_header_view_select_next (header_view);
705 * Marks a message as read and passes it to the msg preview widget
708 read_msg_func (gpointer data, gpointer user_data)
710 ModestMsgView *msg_view;
711 ModestWidgetFactory *widget_factory;
714 GetMsgAsyncHelper *helper;
715 TnyHeaderFlags header_flags;
717 msg = TNY_MSG (data);
718 helper = (GetMsgAsyncHelper *) user_data;
720 /* mark message as seen; _set_flags crashes, bug in tinymail? */
721 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
722 header_flags = tny_header_get_flags (header);
723 tny_header_set_flags (header, header_flags | TNY_HEADER_FLAG_SEEN);
724 g_object_unref (G_OBJECT (header));
726 /* Set message on msg view */
727 widget_factory = modest_main_window_get_widget_factory (helper->main_window);
728 msg_view = modest_widget_factory_get_msg_preview (widget_factory);
729 g_object_unref (G_OBJECT(widget_factory));
730 modest_msg_view_set_message (msg_view, msg);
734 * This function is a generic handler for the tny_folder_get_msg_async
735 * call. It expects as user_data a #GetMsgAsyncHelper. This helper
736 * contains a user provided function that is called inside this
737 * method. This will allow us to use this callback in many different
738 * places. This callback performs the common actions for the
739 * get_msg_async call, more specific actions will be done by the user
743 get_msg_cb (TnyFolder *folder, TnyMsg *msg, GError **err, gpointer user_data)
745 GetMsgAsyncHelper *helper;
747 helper = (GetMsgAsyncHelper *) user_data;
749 if (*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) {
750 ModestHeaderView *header_view;
751 ModestWidgetFactory *widget_factory;
753 widget_factory = modest_main_window_get_widget_factory (helper->main_window);
754 header_view = modest_widget_factory_get_header_view (widget_factory);
755 g_object_unref (G_OBJECT (widget_factory));
756 _modest_ui_actions_on_item_not_found (header_view,
757 MODEST_ITEM_TYPE_MESSAGE,
758 helper->main_window);
765 /* Call user function */
766 helper->func (msg, user_data);
768 /* Process next element (if exists) */
769 tny_iterator_next (helper->iter);
770 if (tny_iterator_is_done (helper->iter)) {
772 headers = tny_iterator_get_list (helper->iter);
774 g_object_unref (G_OBJECT (headers));
775 g_object_unref (G_OBJECT (helper->iter));
776 g_slice_free (GetMsgAsyncHelper, helper);
778 tny_folder_get_msg_async (folder,
779 TNY_HEADER (tny_iterator_get_current (helper->iter)),
784 _modest_ui_actions_on_header_selected (ModestHeaderView *folder_view,
786 ModestMainWindow *main_window)
789 GetMsgAsyncHelper *helper;
796 folder = tny_header_get_folder (TNY_HEADER(header));
799 list = tny_simple_list_new ();
800 tny_list_prepend (list, G_OBJECT (header));
802 /* Fill helper data */
803 helper = g_slice_new0 (GetMsgAsyncHelper);
804 helper->main_window = main_window;
805 helper->iter = tny_list_create_iterator (list);
806 helper->func = read_msg_func;
808 tny_folder_get_msg_async (TNY_FOLDER(folder),
814 g_object_unref (G_OBJECT (folder));
818 _modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
821 ModestMainWindow *main_window)
823 GtkLabel *folder_info_label;
824 TnyPlatformFactory *factory;
827 ModestHeaderView *header_view;
828 ModestWidgetFactory *widget_factory;
830 widget_factory = modest_main_window_get_widget_factory (main_window);
832 GTK_LABEL (modest_widget_factory_get_folder_info_label (widget_factory));
835 gtk_label_set_label (GTK_LABEL(folder_info_label), "");
839 factory = modest_tny_platform_factory_get_instance ();
840 header_view = modest_widget_factory_get_header_view (widget_factory);
841 conf = modest_tny_platform_factory_get_modest_conf_instance (factory);
842 g_object_unref (G_OBJECT (widget_factory));
844 if (!selected) { /* the folder was unselected; save it's settings */
845 modest_widget_memory_save (conf, G_OBJECT (header_view),
847 } else { /* the folder was selected */
849 num = tny_folder_get_all_count (folder);
850 unread = tny_folder_get_unread_count (folder);
852 txt = g_strdup_printf (_("%d %s, %d unread"),
853 num, num==1 ? _("item") : _("items"), unread);
854 gtk_label_set_label (GTK_LABEL(folder_info_label), txt);
857 modest_header_view_set_folder (header_view, folder);
858 modest_widget_memory_restore (conf, G_OBJECT(header_view),
864 _modest_ui_actions_on_password_requested (ModestTnyAccountStore *account_store,
865 const gchar* account_name,
869 ModestMainWindow *main_window)
872 GtkWidget *dialog, *entry, *remember_pass_check;
874 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
875 GTK_WINDOW (main_window),
883 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
884 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
888 entry = gtk_entry_new_with_max_length (40);
889 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
890 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
892 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
895 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
896 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
899 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
901 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
902 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
909 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
914 gtk_widget_destroy (dialog);
916 while (gtk_events_pending ())
917 gtk_main_iteration ();
920 /****************************************************/
922 * below some stuff to clearup statusbar messages after 1,5 seconds....
925 GtkWidget *status_bar;
926 GtkWidget *progress_bar;
931 on_statusbar_remove_msg (StatusRemoveData *data)
933 /* we need to test types, as this callback maybe called after the
934 * widgets have been destroyed
936 if (GTK_IS_STATUSBAR(data->status_bar))
937 gtk_statusbar_remove (GTK_STATUSBAR(data->status_bar),
939 if (GTK_IS_PROGRESS_BAR(data->progress_bar))
940 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(data->progress_bar),
947 statusbar_push (ModestWidgetFactory *factory, guint context_id, const gchar *msg)
950 StatusRemoveData *data;
951 GtkWidget *status_bar, *progress_bar;
956 progress_bar = modest_widget_factory_get_progress_bar (factory);
957 status_bar = modest_widget_factory_get_status_bar (factory);
959 id = gtk_statusbar_push (GTK_STATUSBAR(status_bar), 0, msg);
961 data = g_new (StatusRemoveData, 1);
962 data->status_bar = status_bar;
963 data->progress_bar = progress_bar;
966 g_timeout_add (1500, (GSourceFunc)on_statusbar_remove_msg, data);
968 /****************************************************************************/
971 _modest_ui_actions_on_connection_changed (TnyDevice *device,
973 ModestMainWindow *main_window)
975 GtkWidget *online_toggle;
976 ModestHeaderView *header_view;
977 ModestWidgetFactory *widget_factory;
979 widget_factory = modest_main_window_get_widget_factory (main_window);
980 header_view = modest_widget_factory_get_header_view (widget_factory);
981 online_toggle = modest_widget_factory_get_online_toggle (widget_factory);
983 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(online_toggle),
985 gtk_button_set_label (GTK_BUTTON(online_toggle),
986 online ? _("Online") : _("Offline"));
988 statusbar_push (widget_factory, 0,
989 online ? _("Modest went online") : _("Modest went offline"));
990 g_object_unref (G_OBJECT (widget_factory));
992 /* If Modest has became online and the header view has a
993 header selected then show it */
995 GtkTreeSelection *selected;
997 selected = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
998 _modest_header_view_change_selection (selected, header_view);
1003 _modest_ui_actions_on_online_toggle_toggled (GtkToggleButton *toggle,
1004 ModestMainWindow *main_window)
1008 TnyPlatformFactory *factory;
1009 TnyAccountStore *account_store;
1011 /* Get device. Do not ask the platform factory for it, because
1012 it returns always a new one */
1013 factory = modest_tny_platform_factory_get_instance ();
1014 account_store = tny_platform_factory_new_account_store (factory);
1015 device = tny_account_store_get_device (account_store);
1017 online = gtk_toggle_button_get_active (toggle);
1020 tny_device_force_online (device);
1022 tny_device_force_offline (device);
1026 _modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,
1027 ModestItemType type,
1028 ModestMainWindow *main_window)
1034 TnyPlatformFactory *factory;
1035 TnyAccountStore *account_store;
1037 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1039 /* Get device. Do not ask the platform factory for it, because
1040 it returns always a new one */
1041 factory = modest_tny_platform_factory_get_instance ();
1042 account_store = tny_platform_factory_new_account_store (factory);
1043 device = tny_account_store_get_device (account_store);
1045 gdk_threads_enter ();
1046 online = tny_device_is_online (device);
1049 /* already online -- the item is simply not there... */
1050 dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
1052 GTK_MESSAGE_WARNING,
1054 _("The %s you selected cannot be found"),
1056 gtk_dialog_run (GTK_DIALOG(dialog));
1059 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1060 GTK_WINDOW (main_window),
1063 GTK_RESPONSE_REJECT,
1065 GTK_RESPONSE_ACCEPT,
1068 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1069 "Do you want to get online?"), item);
1070 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1071 gtk_label_new (txt), FALSE, FALSE, 0);
1072 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1075 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1076 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1077 tny_device_force_online (device);
1080 gtk_widget_destroy (dialog);
1081 gdk_threads_leave ();
1085 _modest_ui_actions_on_header_status_update (ModestHeaderView *header_view,
1089 ModestMainWindow *main_window)
1091 GtkWidget *progress_bar;
1092 ModestWidgetFactory *widget_factory;
1094 widget_factory = modest_main_window_get_widget_factory (main_window);
1095 progress_bar = modest_widget_factory_get_progress_bar (widget_factory);
1098 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress_bar),
1099 (gdouble)num/(gdouble)total);
1101 gtk_progress_bar_pulse (GTK_PROGRESS_BAR(progress_bar));
1103 statusbar_push (widget_factory, 0, msg);
1106 g_object_unref (G_OBJECT (widget_factory));
1111 _modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview,
1113 ModestMainWindow *main_window)
1115 ModestWidgetFactory *widget_factory;
1117 widget_factory = modest_main_window_get_widget_factory (main_window);
1118 statusbar_push (widget_factory, 0, link);
1119 g_object_unref (G_OBJECT (widget_factory));
1121 /* TODO: do something */
1126 _modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview,
1128 ModestMainWindow *main_window)
1131 ModestWidgetFactory *widget_factory;
1133 msg = g_strdup_printf (_("Opening %s..."), link);
1134 widget_factory = modest_main_window_get_widget_factory (main_window);
1135 statusbar_push (widget_factory, 0, msg);
1137 g_object_unref (G_OBJECT (widget_factory));
1141 /* TODO: do something */
1145 _modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview,
1147 ModestMainWindow *main_window)
1150 ModestWidgetFactory *widget_factory;
1152 msg = g_strdup_printf (_("Opening attachment %d..."), index);
1153 widget_factory = modest_main_window_get_widget_factory (main_window);
1154 statusbar_push (widget_factory, 0, msg);
1157 g_object_unref (G_OBJECT (widget_factory));
1158 /* TODO: do something */
1162 _modest_ui_actions_on_send (GtkWidget *widget,
1163 ModestEditMsgWindow *edit_window)
1165 TnyTransportAccount *transport_account;
1166 ModestMailOperation *mail_operation;
1169 data = modest_edit_msg_window_get_msg_data (edit_window);
1171 /* FIXME: Code added just for testing. The final version will
1172 use the send queue provided by tinymail and some
1177 TnyAccountStore *account_store;
1179 accounts = TNY_LIST(tny_simple_list_new ());
1180 account_store = modest_edit_msg_window_get_account_store (edit_window);
1181 tny_account_store_get_accounts (account_store, accounts,
1182 TNY_ACCOUNT_STORE_TRANSPORT_ACCOUNTS);
1183 g_object_unref (G_OBJECT (account_store));
1185 iter = tny_list_create_iterator(accounts);
1186 tny_iterator_first (iter);
1187 if (tny_iterator_is_done (iter)) {
1188 /* FIXME: Add error handling through mail operation */
1189 g_printerr("modest: no transport accounts defined\n");
1190 modest_edit_msg_window_free_msg_data (edit_window, data);
1193 transport_account = TNY_TRANSPORT_ACCOUNT (tny_iterator_get_current(iter));
1194 g_object_ref (transport_account);
1196 tny_list_foreach (accounts, (GFunc) g_object_unref, NULL);
1197 g_object_unref (G_OBJECT (accounts));
1198 g_object_unref (G_OBJECT (iter));
1201 mail_operation = modest_mail_operation_new ();
1203 modest_mail_operation_send_new_mail (mail_operation,
1213 g_object_unref (G_OBJECT (mail_operation));
1214 g_object_unref (G_OBJECT (transport_account));
1215 modest_edit_msg_window_free_msg_data (edit_window, data);
1217 /* Save settings and close the window */
1218 /* save_settings (edit_window) */
1219 gtk_widget_destroy (GTK_WIDGET (edit_window));