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.
30 #include <glib/gi18n.h>
31 #include <gtk/gtktreeviewcolumn.h>
32 #include <tny-account-store-view.h>
33 #include <tny-simple-list.h>
34 #include "modest-hildon-includes.h"
35 #include "modest-defs.h"
38 #include "widgets/modest-main-window.h"
39 #include "widgets/modest-msg-edit-window.h"
40 #include "widgets/modest-account-view-window.h"
41 #include "modest-runtime.h"
42 #include "modest-account-mgr-helpers.h"
43 #include "modest-platform.h"
44 #include "modest-widget-memory.h"
45 #include "modest-window-priv.h"
46 #include "modest-main-window-ui.h"
47 #include "modest-account-mgr.h"
48 #include "modest-tny-account.h"
49 #include "modest-conf.h"
50 #include <modest-maemo-utils.h>
51 #include "modest-tny-platform-factory.h"
52 #include "modest-tny-msg.h"
53 #include "modest-mail-operation.h"
54 #include "modest-icon-names.h"
55 #include "modest-progress-bar-widget.h"
56 #include "modest-text-utils.h"
57 #include "maemo/modest-osso-state-saving.h"
59 #ifdef MODEST_HILDON_VERSION_0
60 #include <hildon-widgets/hildon-program.h>
62 #include <hildon/hildon-program.h>
63 #endif /*MODEST_HILDON_VERSION_0*/
65 #define MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS "ModestMainWindowActionAdditions"
67 /* 'private'/'protected' functions */
68 static void modest_main_window_class_init (ModestMainWindowClass *klass);
69 static void modest_main_window_init (ModestMainWindow *obj);
70 static void modest_main_window_finalize (GObject *obj);
71 static gboolean modest_main_window_window_state_event (GtkWidget *widget,
72 GdkEventWindowState *event,
75 static void connect_signals (ModestMainWindow *self);
77 static void restore_settings (ModestMainWindow *self);
78 static void save_state (ModestWindow *self);
80 static void modest_main_window_show_toolbar (ModestWindow *window,
81 gboolean show_toolbar);
83 static void cancel_progressbar (GtkToolButton *toolbutton,
84 ModestMainWindow *self);
86 static void on_queue_changed (ModestMailOperationQueue *queue,
87 ModestMailOperation *mail_op,
88 ModestMailOperationQueueNotification type,
89 ModestMainWindow *self);
91 static void on_account_update (TnyAccountStore *account_store,
92 const gchar *account_name,
95 static gboolean on_inner_widgets_key_pressed (GtkWidget *widget,
99 static void on_configuration_key_changed (ModestConf* conf,
101 ModestConfEvent event,
102 ModestMainWindow *self);
104 static void set_toolbar_mode (ModestMainWindow *self,
105 ModestToolBarModes mode);
107 static gboolean set_toolbar_transfer_mode (ModestMainWindow *self);
109 static void on_show_account_action_activated (GtkAction *action,
112 static void on_refresh_account_action_activated (GtkAction *action,
115 static void on_send_receive_csm_activated (GtkMenuItem *item,
117 /* list my signals */
125 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
126 struct _ModestMainWindowPrivate {
127 GtkWidget *msg_paned;
128 GtkWidget *main_paned;
129 GtkWidget *main_vbox;
130 GtkWidget *contents_widget;
132 /* Progress observers */
133 GtkWidget *progress_bar;
134 GSList *progress_widgets;
137 GtkWidget *progress_toolitem;
138 GtkWidget *cancel_toolitem;
139 GtkWidget *sort_toolitem;
140 GtkWidget *refresh_toolitem;
141 ModestToolBarModes current_toolbar_mode;
143 /* Merge ids used to add/remove accounts to the ViewMenu*/
144 GByteArray *merge_ids;
146 /* On-demand widgets */
147 GtkWidget *accounts_popup;
148 GtkWidget *details_widget;
150 /* Optimized view enabled */
151 gboolean optimized_view;
153 ModestHeaderView *header_view;
154 ModestFolderView *folder_view;
156 ModestMainWindowStyle style;
157 ModestMainWindowContentsStyle contents_style;
159 guint progress_bar_timeout;
162 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
163 MODEST_TYPE_MAIN_WINDOW, \
164 ModestMainWindowPrivate))
166 typedef struct _GetMsgAsyncHelper {
167 ModestMainWindowPrivate *main_window_private;
169 ModestTnyMsgReplyType reply_type;
170 ModestTnyMsgForwardType forward_type;
177 static GtkWindowClass *parent_class = NULL;
180 /* Private actions */
181 /* This is the context sensitive menu: */
182 static const GtkActionEntry modest_folder_view_action_entries [] = {
184 /* Folder View CSM actions */
185 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
186 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
187 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, NULL },
188 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
189 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, NULL },
190 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, NULL },
194 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
195 { "ToolbarToggleView", MODEST_STOCK_SPLIT_VIEW, N_("gqn_toolb_rss_fldonoff"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), FALSE },
198 /************************************************************************/
201 modest_main_window_get_type (void)
203 static GType my_type = 0;
205 static const GTypeInfo my_info = {
206 sizeof(ModestMainWindowClass),
207 NULL, /* base init */
208 NULL, /* base finalize */
209 (GClassInitFunc) modest_main_window_class_init,
210 NULL, /* class finalize */
211 NULL, /* class data */
212 sizeof(ModestMainWindow),
214 (GInstanceInitFunc) modest_main_window_init,
217 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
225 modest_main_window_class_init (ModestMainWindowClass *klass)
227 GObjectClass *gobject_class;
228 gobject_class = (GObjectClass*) klass;
229 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
231 parent_class = g_type_class_peek_parent (klass);
232 gobject_class->finalize = modest_main_window_finalize;
234 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
236 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
237 modest_window_class->save_state_func = save_state;
241 modest_main_window_init (ModestMainWindow *obj)
243 ModestMainWindowPrivate *priv;
245 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
247 priv->msg_paned = NULL;
248 priv->main_paned = NULL;
249 priv->main_vbox = NULL;
250 priv->header_view = NULL;
251 priv->folder_view = NULL;
252 priv->contents_widget = NULL;
253 priv->accounts_popup = NULL;
254 priv->details_widget = NULL;
256 priv->progress_widgets = NULL;
257 priv->progress_bar = NULL;
258 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
260 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
261 priv->contents_style = MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS;
263 priv->merge_ids = NULL;
265 priv->optimized_view = FALSE;
266 priv->progress_bar_timeout = 0;
270 modest_main_window_finalize (GObject *obj)
272 ModestMainWindowPrivate *priv;
274 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
276 g_slist_free (priv->progress_widgets);
278 g_byte_array_free (priv->merge_ids, TRUE);
280 if (priv->progress_bar_timeout > 0) {
281 g_source_remove (priv->progress_bar_timeout);
282 priv->progress_bar_timeout = 0;
285 G_OBJECT_CLASS(parent_class)->finalize (obj);
289 modest_main_window_get_child_widget (ModestMainWindow *self,
290 ModestWidgetType widget_type)
292 ModestMainWindowPrivate *priv;
295 g_return_val_if_fail (self, NULL);
296 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_WIDGET_TYPE_NUM,
299 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
301 switch (widget_type) {
302 case MODEST_WIDGET_TYPE_HEADER_VIEW:
303 widget = (GtkWidget*)priv->header_view; break;
304 case MODEST_WIDGET_TYPE_FOLDER_VIEW:
305 widget = (GtkWidget*)priv->folder_view; break;
310 return widget ? GTK_WIDGET(widget) : NULL;
316 restore_settings (ModestMainWindow *self)
319 ModestMainWindowPrivate *priv;
321 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
323 conf = modest_runtime_get_conf ();
325 modest_widget_memory_restore (conf, G_OBJECT(self),
326 MODEST_CONF_MAIN_WINDOW_KEY);
327 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
328 MODEST_CONF_MAIN_PANED_KEY);
329 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
330 MODEST_CONF_HEADER_VIEW_KEY);
335 save_state (ModestWindow *window)
338 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
339 ModestMainWindowPrivate *priv;
341 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
342 conf = modest_runtime_get_conf ();
344 modest_widget_memory_save (conf,G_OBJECT(self),
345 MODEST_CONF_MAIN_WINDOW_KEY);
346 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
347 MODEST_CONF_MAIN_PANED_KEY);
348 modest_widget_memory_save (conf, G_OBJECT(priv->header_view),
349 MODEST_CONF_HEADER_VIEW_KEY);
353 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
355 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
356 gtk_scrolled_window_add_with_viewport
357 (GTK_SCROLLED_WINDOW(win), widget);
359 gtk_container_add (GTK_CONTAINER(win),
365 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self)
367 modest_window_save_state (MODEST_WINDOW(self));
373 on_account_store_connecting_finished (TnyAccountStore *store, ModestMainWindow *self)
375 /* When going online, do the equivalent of pressing the send/receive button,
376 * as per the specification:
377 * (without the check for >0 accounts, though that is not specified): */
378 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (self));
384 connect_signals (ModestMainWindow *self)
386 ModestWindowPrivate *parent_priv;
387 ModestMainWindowPrivate *priv;
390 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
391 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
394 g_signal_connect (G_OBJECT(priv->folder_view), "key-press-event",
395 G_CALLBACK(on_inner_widgets_key_pressed), self);
396 g_signal_connect (G_OBJECT(priv->folder_view), "folder_selection_changed",
397 G_CALLBACK(modest_ui_actions_on_folder_selection_changed), self);
398 g_signal_connect (G_OBJECT(priv->folder_view), "folder-display-name-changed",
399 G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
401 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
402 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
405 /* g_signal_connect (G_OBJECT(priv->header_view), "status_update", */
406 /* G_CALLBACK(modest_ui_actions_on_header_status_update), self); */
407 g_signal_connect (G_OBJECT(priv->header_view), "header_selected",
408 G_CALLBACK(modest_ui_actions_on_header_selected), self);
409 g_signal_connect (G_OBJECT(priv->header_view), "header_activated",
410 G_CALLBACK(modest_ui_actions_on_header_activated), self);
411 g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
412 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
413 g_signal_connect (G_OBJECT(priv->header_view), "key-press-event",
414 G_CALLBACK(on_inner_widgets_key_pressed), self);
417 g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
418 g_signal_connect (G_OBJECT (self), "window-state-event",
419 G_CALLBACK (modest_main_window_window_state_event),
421 g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
423 /* Mail Operation Queue */
424 g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
426 G_CALLBACK (on_queue_changed),
429 /* Track changes in the device name */
430 g_signal_connect (G_OBJECT(modest_runtime_get_conf ()),
432 G_CALLBACK (on_configuration_key_changed),
435 /* Track account changes. We need to refresh the toolbar */
436 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
438 G_CALLBACK (on_account_update),
442 g_signal_connect (G_OBJECT (modest_runtime_get_account_store()), "password_requested",
443 G_CALLBACK (modest_ui_actions_on_password_requested), self);
446 g_signal_connect (G_OBJECT(modest_runtime_get_account_store()), "connecting-finished",
447 G_CALLBACK(on_account_store_connecting_finished), self);
451 /** Idle handler, to send/receive at startup .*/
453 sync_accounts_cb (ModestMainWindow *win)
455 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (win));
456 return FALSE; /* Do not call this idle handler again. */
460 static void on_hildon_program_is_topmost_notify(GObject *self,
461 GParamSpec *propert_param, gpointer user_data)
463 HildonProgram *app = HILDON_PROGRAM (self);
466 ModestWindow* self = MODEST_WINDOW(user_data);
469 /* Note that use of hildon_program_set_can_hibernate()
470 * is generally referred to as "setting the killable flag",
471 * though hibernation does not seem equal to death.
474 if (hildon_program_get_is_topmost (app)) {
475 /* Prevent hibernation when the progam comes to the foreground,
476 * because hibernation should only happen when the application
477 * is in the background: */
478 hildon_program_set_can_hibernate (app, FALSE);
480 /* Allow hibernation if the program has gone to the background: */
482 /* However, prevent hibernation while the settings are being changed: */
483 const gboolean hibernation_prevented =
484 modest_window_mgr_get_hibernation_is_prevented (
485 modest_runtime_get_window_mgr ());
487 if (hibernation_prevented)
488 hildon_program_set_can_hibernate (app, FALSE);
490 /* Allow hibernation, after saving the state: */
491 modest_osso_save_state();
492 hildon_program_set_can_hibernate (app, TRUE);
501 modest_main_window_new (void)
503 ModestMainWindow *self;
504 ModestMainWindowPrivate *priv;
505 ModestWindowPrivate *parent_priv;
506 GtkWidget *folder_win;
507 GtkActionGroup *action_group;
508 GError *error = NULL;
509 TnyFolderStoreQuery *query;
510 GdkPixbuf *window_icon;
514 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
515 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
516 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
518 parent_priv->ui_manager = gtk_ui_manager_new();
519 action_group = gtk_action_group_new ("ModestMainWindowActions");
520 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
522 /* Add common actions */
523 gtk_action_group_add_actions (action_group,
524 modest_action_entries,
525 G_N_ELEMENTS (modest_action_entries),
528 gtk_action_group_add_actions (action_group,
529 modest_folder_view_action_entries,
530 G_N_ELEMENTS (modest_folder_view_action_entries),
533 gtk_action_group_add_toggle_actions (action_group,
534 modest_toggle_action_entries,
535 G_N_ELEMENTS (modest_toggle_action_entries),
538 gtk_action_group_add_toggle_actions (action_group,
539 modest_main_window_toggle_action_entries,
540 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
543 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
544 g_object_unref (action_group);
546 /* Load the UI definition */
547 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
548 MODEST_UIDIR "modest-main-window-ui.xml", &error);
550 g_warning ("Could not merge modest-ui.xml: %s", error->message);
551 g_error_free (error);
555 /* Add accelerators */
556 gtk_window_add_accel_group (GTK_WINDOW (self),
557 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
559 /* Menubar. Update the state of some toggles */
560 parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
561 conf = modest_runtime_get_conf ();
562 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
563 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
564 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
565 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL));
566 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
567 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
568 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
569 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL));
570 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
572 /* Get device name */
573 modest_maemo_utils_get_device_name ();
576 query = tny_folder_store_query_new ();
577 tny_folder_store_query_add_item (query, NULL,
578 TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
579 priv->folder_view = MODEST_FOLDER_VIEW(modest_folder_view_new (query));
580 if (!priv->folder_view)
581 g_printerr ("modest: cannot instantiate folder view\n");
582 g_object_unref (G_OBJECT (query));
583 modest_folder_view_set_style (priv->folder_view,
584 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
588 MODEST_HEADER_VIEW(modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
589 if (!priv->header_view)
590 g_printerr ("modest: cannot instantiate header view\n");
591 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
593 /* Create scrolled windows */
594 folder_win = gtk_scrolled_window_new (NULL, NULL);
595 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
596 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
598 GTK_POLICY_AUTOMATIC);
599 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
601 GTK_POLICY_AUTOMATIC);
603 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
604 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view));
607 priv->main_paned = gtk_hpaned_new ();
608 gtk_paned_add1 (GTK_PANED(priv->main_paned), folder_win);
609 gtk_paned_add2 (GTK_PANED(priv->main_paned), priv->contents_widget);
610 gtk_widget_show (GTK_WIDGET(priv->header_view));
611 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
613 /* putting it all together... */
614 priv->main_vbox = gtk_vbox_new (FALSE, 6);
615 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
617 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
618 restore_settings (MODEST_MAIN_WINDOW(self));
620 /* Set window icon */
621 window_icon = modest_platform_get_icon (MODEST_APP_ICON);
622 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
624 /* Connect signals */
625 connect_signals (self);
627 /* Set account store */
628 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
629 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
631 /* Do send & receive when we are idle */
632 /* TODO: Enable this again. I have commented it out because,
633 * at least in scratchbox, this can cause us to start a second
634 * update (in response to a connection change) when we are already
635 * doing an update (started here, at startup). Tinymail doesn't like that.
638 /* g_idle_add ((GSourceFunc)sync_accounts_cb, self); */
640 HildonProgram *app = hildon_program_get_instance ();
641 hildon_program_add_window (app, HILDON_WINDOW (self));
643 /* Register HildonProgram signal handlers: */
644 /* These are apparently deprecated, according to the
645 * "HildonApp/HildonAppView to HildonProgram/HildonWindow migration guide",
646 * though the API reference does not mention that:
648 g_signal_connect (G_OBJECT(app), "topmost_status_lose",
649 G_CALLBACK (on_hildon_program_save_state), self);
650 g_signal_connect (G_OBJECT(app), "topmost_status_acquire",
651 G_CALLBACK (on_hildon_program_status_acquire), self);
653 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
654 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
656 /* Load previous osso state, for instance if we are being restored from
658 modest_osso_load_state();
660 return MODEST_WINDOW(self);
664 modest_main_window_close_all (ModestMainWindow *self)
667 GtkResponseType response;
669 /* Create the confirmation dialog MSG-NOT308 */
670 note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
671 _("emev_nc_close_windows"),
672 _("mcen_bd_yes"), GTK_RESPONSE_YES,
673 _("mcen_bd_no"), GTK_RESPONSE_NO,
676 response = gtk_dialog_run (GTK_DIALOG (note));
677 gtk_widget_destroy (GTK_WIDGET (note));
679 if (response == GTK_RESPONSE_YES)
687 modest_main_window_set_style (ModestMainWindow *self,
688 ModestMainWindowStyle style)
690 ModestMainWindowPrivate *priv;
691 ModestWindowPrivate *parent_priv;
694 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
696 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
697 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
699 /* no change -> nothing to do */
700 if (priv->style == style)
703 /* Get toggle button */
704 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarToggleView");
709 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
710 /* Remove main paned */
711 g_object_ref (priv->main_paned);
712 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
714 /* Reparent the contents widget to the main vbox */
715 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
717 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
718 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
719 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
722 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
723 /* Remove header view */
724 g_object_ref (priv->contents_widget);
725 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
727 /* Reparent the main paned */
728 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
729 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
731 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
732 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
733 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
737 g_return_if_reached ();
740 /* Let header view grab the focus if it's being shown */
741 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
742 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
744 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
747 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
750 ModestMainWindowStyle
751 modest_main_window_get_style (ModestMainWindow *self)
753 ModestMainWindowPrivate *priv;
755 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
757 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
764 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
766 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
767 ModestWindowPrivate *parent_priv;
768 ModestWindowMgr *mgr;
769 gboolean is_fullscreen;
770 GtkAction *fs_toggle_action;
773 mgr = modest_runtime_get_window_mgr ();
775 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
777 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
779 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
780 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
781 if (is_fullscreen != active) {
782 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
791 set_homogeneous (GtkWidget *widget,
794 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
795 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
799 modest_main_window_show_toolbar (ModestWindow *self,
800 gboolean show_toolbar)
802 ModestMainWindowPrivate *priv = NULL;
803 ModestWindowPrivate *parent_priv = NULL;
804 GtkWidget *reply_button = NULL, *menu = NULL;
805 GtkWidget *placeholder = NULL;
808 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
809 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
810 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
812 /* Set optimized view status */
813 priv->optimized_view = !show_toolbar;
815 if (!parent_priv->toolbar) {
816 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
819 /* Set homogeneous toolbar */
820 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar),
821 set_homogeneous, NULL);
823 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
824 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
825 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
826 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
827 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
828 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
829 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
830 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
832 /* Add ProgressBar (Transfer toolbar) */
833 priv->progress_bar = modest_progress_bar_widget_new ();
834 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
835 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
836 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
837 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
838 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
840 /* Connect cancel 'clicked' signal to abort progress mode */
841 g_signal_connect(priv->cancel_toolitem, "clicked",
842 G_CALLBACK(cancel_progressbar),
845 /* Add it to the observers list */
846 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
849 hildon_window_add_toolbar (HILDON_WINDOW (self),
850 GTK_TOOLBAR (parent_priv->toolbar));
852 /* Set reply button tap and hold menu */
853 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
854 "/ToolBar/ToolbarMessageReply");
855 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
857 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
859 /* Set send & receive button tap and hold menu */
860 on_account_update (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
865 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
866 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
867 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
869 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
870 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
872 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
877 compare_display_names (ModestAccountData *a,
878 ModestAccountData *b)
880 return strcmp (a->display_name, b->display_name);
884 on_account_update (TnyAccountStore *account_store,
885 const gchar *account_name,
888 GSList *account_names, *iter, *accounts;
889 ModestMainWindow *self;
890 ModestMainWindowPrivate *priv;
891 ModestWindowPrivate *parent_priv;
892 ModestAccountMgr *mgr;
893 gint i, num_accounts;
894 GtkActionGroup *action_group;
896 gchar *default_account;
897 GtkWidget *send_receive_button, *item;
899 self = MODEST_MAIN_WINDOW (user_data);
900 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
901 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
903 /* Get enabled account IDs */
904 mgr = modest_runtime_get_account_mgr ();
905 account_names = modest_account_mgr_account_names (mgr, TRUE);
906 iter = account_names;
910 ModestAccountData *account_data =
911 modest_account_mgr_get_account_data (mgr, (gchar*) iter->data);
912 accounts = g_slist_prepend (accounts, account_data);
916 g_slist_free (account_names);
918 /* Order the list of accounts by its display name */
919 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
920 num_accounts = g_slist_length (accounts);
922 /* Delete old send&receive popup items. We can not just do a
923 menu_detach because it does not work well with
925 if (priv->accounts_popup)
926 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
927 (GtkCallback) gtk_widget_destroy, NULL);
929 /* Delete old entries in the View menu. Do not free groups, it
931 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
933 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
934 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
935 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
936 GTK_ACTION_GROUP (groups->data));
939 if (priv->merge_ids) {
940 for (i = 0; i < priv->merge_ids->len; i++)
941 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
942 g_byte_array_free (priv->merge_ids, TRUE);
944 /* We need to call this in order to ensure
945 that the new actions are added in the right
946 order (alphabetical */
947 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
949 groups = g_list_next (groups);
951 priv->merge_ids = g_byte_array_sized_new (num_accounts);
953 /* Get send receive button */
954 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
955 "/ToolBar/ToolbarSendReceive");
957 /* Create the menu */
958 if (num_accounts > 1) {
959 if (!priv->accounts_popup)
960 priv->accounts_popup = gtk_menu_new ();
961 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
962 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
963 g_signal_connect (G_OBJECT (item),
965 G_CALLBACK (on_send_receive_csm_activated),
967 item = gtk_separator_menu_item_new ();
968 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
971 /* Create a new action group */
972 default_account = modest_account_mgr_get_default_account (mgr);
973 action_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
974 for (i = 0; i < num_accounts; i++) {
975 gchar *display_name = NULL;
977 ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
979 /* Create display name. The default account is shown differently */
980 if (default_account && account_data->account_name &&
981 !(strcmp (default_account, account_data->account_name) == 0)) {
982 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
983 account_data->display_name);
986 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
987 account_data->display_name);
990 /* Create action and add it to the action group. The
991 action name must be the account name, this way we
992 could know in the handlers the account to show */
993 if(account_data->account_name) {
994 gchar* item_name, *refresh_action_name;
996 GtkAction *view_account_action, *refresh_account_action;
998 view_account_action = gtk_action_new (account_data->account_name,
999 display_name, NULL, NULL);
1000 gtk_action_group_add_action (action_group, view_account_action);
1002 /* Add ui from account data. We allow 2^9-1 account
1003 changes in a single execution because we're
1004 downcasting the guint to a guint8 in order to use a
1005 GByteArray, it should be enough */
1006 item_name = g_strconcat (account_data->account_name, "Menu", NULL);
1007 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
1008 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
1009 gtk_ui_manager_add_ui (parent_priv->ui_manager,
1011 "/MenuBar/ViewMenu/ViewMenuAdditions",
1013 account_data->account_name,
1014 GTK_UI_MANAGER_MENUITEM,
1017 /* Connect the action signal "activate" */
1018 g_signal_connect (G_OBJECT (view_account_action),
1020 G_CALLBACK (on_show_account_action_activated),
1023 /* Create the items for the Tools->Send&Receive submenu */
1024 refresh_action_name = g_strconcat ("SendReceive", account_data->account_name, NULL);
1025 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
1026 display_name, NULL, NULL);
1027 gtk_action_group_add_action (action_group, refresh_account_action);
1029 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
1030 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
1031 gtk_ui_manager_add_ui (parent_priv->ui_manager,
1033 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
1035 refresh_action_name,
1036 GTK_UI_MANAGER_MENUITEM,
1038 g_free (refresh_action_name);
1040 g_signal_connect_data (G_OBJECT (refresh_account_action),
1042 G_CALLBACK (on_refresh_account_action_activated),
1043 g_strdup (account_data->account_name),
1044 (GClosureNotify) g_free,
1047 /* Create item and add it to the send&receive
1048 CSM. If there is only one account then
1050 if (priv->accounts_popup) {
1051 item = gtk_menu_item_new_with_label (display_name);
1052 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1053 g_signal_connect_data (G_OBJECT (item),
1055 G_CALLBACK (on_send_receive_csm_activated),
1056 g_strdup (account_data->account_name),
1057 (GClosureNotify) g_free,
1064 g_free (display_name);
1065 modest_account_mgr_free_account_data (mgr, account_data);
1067 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 1);
1069 if (priv->accounts_popup) {
1070 /* Mandatory in order to view the menu contents */
1071 gtk_widget_show_all (priv->accounts_popup);
1073 /* Setup tap_and_hold just if was not done before*/
1074 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
1075 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
1079 g_slist_free (accounts);
1080 g_free (default_account);
1084 * This function manages the key events used to navigate between
1085 * header and folder views (when the window is in split view)
1088 * -------------------------------------------------
1089 * HeaderView GDK_Left Move focus to folder view
1090 * FolderView GDK_Right Move focus to header view
1092 * There is no need to scroll to selected row, the widgets will be the
1093 * responsibles of doing that (probably managing the focus-in event
1096 on_inner_widgets_key_pressed (GtkWidget *widget,
1100 ModestMainWindowPrivate *priv;
1102 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1104 /* Do nothing if we're in SIMPLE style */
1105 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1108 if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
1109 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1110 else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1111 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1117 set_alignment (GtkWidget *widget,
1120 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1121 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1125 create_details_widget (TnyFolderStore *folder_store)
1130 vbox = gtk_vbox_new (FALSE, 0);
1132 /* Account description: */
1134 if (modest_tny_folder_store_is_virtual_local_folders (folder_store)) {
1135 /* Local folders: */
1137 /* Get device name */
1138 gchar *device_name = modest_conf_get_string (modest_runtime_get_conf(),
1139 MODEST_CONF_DEVICE_NAME, NULL);
1141 label = g_strdup_printf ("%s: %s",
1142 _("mcen_fi_localroot_description"),
1144 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1145 g_free (device_name);
1147 } else if (TNY_IS_ACCOUNT (folder_store)) {
1148 TnyAccount *account = TNY_ACCOUNT(folder_store);
1150 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1152 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("FIXME: MMC ?"), FALSE, FALSE, 0);
1154 /* Other accounts, such as IMAP and POP: */
1158 /* Put proto in uppercase */
1159 proto = g_string_new (tny_account_get_proto (account));
1160 proto = g_string_ascii_up (proto);
1162 label = g_strdup_printf ("%s %s: %s",
1164 _("mcen_fi_remoteroot_account"),
1165 tny_account_get_name (account));
1166 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1167 g_string_free (proto, TRUE);
1174 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_messages"),
1175 modest_tny_folder_store_get_message_count (folder_store));
1176 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1180 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_folders"),
1181 modest_tny_folder_store_get_folder_count (folder_store));
1182 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1186 if (modest_tny_folder_store_is_virtual_local_folders (folder_store)) {
1187 /* FIXME: format size */
1188 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_size"),
1189 modest_tny_folder_store_get_local_size (folder_store));
1190 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1192 } else if (TNY_IS_ACCOUNT(folder_store)) {
1193 TnyAccount *account = TNY_ACCOUNT(folder_store);
1195 if (!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1196 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("FIXME: MMC ?"), FALSE, FALSE, 0);
1198 time_t last_updated;
1199 gchar *last_updated_string;
1200 /* Get last updated from configuration */
1201 last_updated = modest_account_mgr_get_int (modest_runtime_get_account_mgr (),
1202 tny_account_get_id (account),
1203 MODEST_ACCOUNT_LAST_UPDATED,
1205 if (last_updated > 0)
1206 last_updated_string = modest_text_utils_get_display_date(last_updated);
1208 last_updated_string = g_strdup (_("FIXME: Never"));
1210 label = g_strdup_printf ("%s: %s", _("mcen_ti_lastupdated"), last_updated_string);
1211 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1212 g_free (last_updated_string);
1218 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1224 modest_main_window_set_contents_style (ModestMainWindow *self,
1225 ModestMainWindowContentsStyle style)
1227 ModestMainWindowPrivate *priv;
1229 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1231 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1233 /* We allow to set the same content style than the previously
1234 set if there are details, because it could happen when we're
1235 selecting different accounts consecutively */
1236 if ((priv->contents_style == style) &&
1237 (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS))
1240 /* Remove previous child. Delete it if it was an account
1242 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1244 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1245 g_object_ref (content);
1246 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1249 priv->contents_style = style;
1251 switch (priv->contents_style) {
1252 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1253 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1255 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1257 /* TODO: show here account details */
1258 TnyFolderStore *selected_folderstore =
1259 modest_folder_view_get_selected (priv->folder_view);
1261 priv->details_widget = create_details_widget (selected_folderstore);
1263 wrap_in_scrolled_window (priv->contents_widget,
1264 priv->details_widget);
1268 g_return_if_reached ();
1272 gtk_widget_show_all (priv->contents_widget);
1276 on_configuration_key_changed (ModestConf* conf,
1278 ModestConfEvent event,
1279 ModestMainWindow *self)
1281 ModestMainWindowPrivate *priv;
1282 TnyAccount *account;
1284 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
1287 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1289 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1292 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
1293 if (TNY_IS_ACCOUNT (account) &&
1294 !strcmp (tny_account_get_id (account), MODEST_ACTUAL_LOCAL_FOLDERS_ACCOUNT_ID)) {
1297 const gchar *device_name;
1301 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
1302 label = GTK_LABEL (children->data);
1304 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1305 MODEST_CONF_DEVICE_NAME, NULL);
1307 new_text = g_strdup_printf ("%s: %s",
1308 _("mcen_fi_localroot_description"),
1311 gtk_label_set_text (label, new_text);
1312 gtk_widget_show (GTK_WIDGET (label));
1315 g_list_free (children);
1320 set_toolbar_transfer_mode (ModestMainWindow *self)
1322 ModestMainWindowPrivate *priv = NULL;
1324 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1326 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1328 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
1330 if (priv->progress_bar_timeout > 0) {
1331 g_source_remove (priv->progress_bar_timeout);
1332 priv->progress_bar_timeout = 0;
1339 set_toolbar_mode (ModestMainWindow *self,
1340 ModestToolBarModes mode)
1342 ModestWindowPrivate *parent_priv = NULL;
1343 ModestMainWindowPrivate *priv = NULL;
1344 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
1346 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1348 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1349 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1351 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
1353 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1354 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1355 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1357 /* Sets current toolbar mode */
1358 priv->current_toolbar_mode = mode;
1360 /* Show and hide toolbar items */
1362 case TOOLBAR_MODE_NORMAL:
1364 gtk_action_set_visible (sort_action, TRUE);
1366 gtk_action_set_visible (refresh_action, TRUE);
1367 if (priv->progress_toolitem) {
1368 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1369 gtk_widget_hide (priv->progress_toolitem);
1371 if (priv->progress_bar)
1372 gtk_widget_hide (priv->progress_bar);
1375 gtk_action_set_visible (cancel_action, FALSE);
1377 /* Hide toolbar if optimized view is enabled */
1378 if (priv->optimized_view)
1379 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
1381 case TOOLBAR_MODE_TRANSFER:
1383 gtk_action_set_visible (sort_action, FALSE);
1385 gtk_action_set_visible (refresh_action, FALSE);
1387 gtk_action_set_visible (cancel_action, TRUE);
1388 if (priv->progress_toolitem) {
1389 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1390 gtk_widget_show (priv->progress_toolitem);
1392 if (priv->progress_bar)
1393 gtk_widget_show (priv->progress_bar);
1395 /* Show toolbar if it's hiden (optimized view ) */
1396 if (priv->optimized_view)
1397 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1400 g_return_if_reached ();
1405 cancel_progressbar (GtkToolButton *toolbutton,
1406 ModestMainWindow *self)
1409 ModestMainWindowPrivate *priv;
1411 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1413 /* Get operation observers and cancel its current operation */
1414 tmp = priv->progress_widgets;
1416 modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
1417 tmp=g_slist_next(tmp);
1422 observers_empty (ModestMainWindow *self)
1425 ModestMainWindowPrivate *priv;
1426 gboolean is_empty = TRUE;
1427 guint pending_ops = 0;
1429 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1430 tmp = priv->progress_widgets;
1432 /* Check all observers */
1433 while (tmp && is_empty) {
1434 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
1435 is_empty = pending_ops == 0;
1437 tmp = g_slist_next(tmp);
1444 on_queue_changed (ModestMailOperationQueue *queue,
1445 ModestMailOperation *mail_op,
1446 ModestMailOperationQueueNotification type,
1447 ModestMainWindow *self)
1449 ModestMainWindowPrivate *priv;
1450 ModestMailOperationId op_id;
1451 ModestToolBarModes mode;
1453 gboolean mode_changed = FALSE;
1454 ModestMailOperationStatus status;
1456 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1457 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1459 /* Get toolbar mode from operation id*/
1460 op_id = modest_mail_operation_get_id (mail_op);
1462 case MODEST_MAIL_OPERATION_ID_SEND:
1463 case MODEST_MAIL_OPERATION_ID_RECEIVE:
1464 mode = TOOLBAR_MODE_TRANSFER;
1465 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
1466 mode_changed = TRUE;
1469 mode = TOOLBAR_MODE_NORMAL;
1474 /* Add operation observers and change toolbar if neccessary*/
1475 tmp = priv->progress_widgets;
1477 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
1478 if (mode == TOOLBAR_MODE_TRANSFER) {
1480 set_toolbar_transfer_mode(self);
1482 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1484 tmp = g_slist_next (tmp);
1488 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
1489 /* If mail_op is mine, check errors */
1490 status = modest_mail_operation_get_status (mail_op);
1491 if (status != MODEST_MAIL_OPERATION_STATUS_SUCCESS)
1492 modest_mail_operation_execute_error_handler (mail_op);
1494 /* Change toolbar mode */
1495 if (mode == TOOLBAR_MODE_TRANSFER) {
1497 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1499 tmp = g_slist_next (tmp);
1502 /* If no more operations are being observed, NORMAL mode is enabled again */
1503 if (observers_empty (self)) {
1504 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
1515 on_show_account_action_activated (GtkAction *action,
1518 ModestAccountData *acc_data;
1519 ModestMainWindow *self;
1520 ModestMainWindowPrivate *priv;
1521 ModestAccountMgr *mgr;
1522 const gchar *acc_name;
1524 self = MODEST_MAIN_WINDOW (user_data);
1525 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1527 /* Get account data */
1528 acc_name = gtk_action_get_name (action);
1529 mgr = modest_runtime_get_account_mgr ();
1530 acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
1532 /* Set the new visible & active account */
1533 if (acc_data->store_account) {
1534 modest_folder_view_set_account_id_of_visible_server_account (priv->folder_view,
1535 acc_data->store_account->account_name);
1536 modest_window_set_active_account (MODEST_WINDOW (self), acc_data->account_name);
1540 modest_account_mgr_free_account_data (mgr, acc_data);
1544 refresh_account (const gchar *account_name)
1548 win = MODEST_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
1550 /* If account_name == NULL, we must update all (option All) */
1552 modest_ui_actions_do_send_receive_all (win);
1554 modest_ui_actions_do_send_receive (account_name, win);
1558 on_refresh_account_action_activated (GtkAction *action,
1561 refresh_account ((const gchar*) user_data);
1565 on_send_receive_csm_activated (GtkMenuItem *item,
1568 refresh_account ((const gchar*) user_data);