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_send_receive_csm_activated (GtkMenuItem *item,
114 /* list my signals */
122 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
123 struct _ModestMainWindowPrivate {
124 GtkWidget *msg_paned;
125 GtkWidget *main_paned;
126 GtkWidget *main_vbox;
127 GtkWidget *contents_widget;
129 /* Progress observers */
130 GtkWidget *progress_bar;
131 GSList *progress_widgets;
134 GtkWidget *progress_toolitem;
135 GtkWidget *cancel_toolitem;
136 GtkWidget *sort_toolitem;
137 GtkWidget *refresh_toolitem;
138 ModestToolBarModes current_toolbar_mode;
140 /* Merge ids used to add/remove accounts to the ViewMenu*/
141 GByteArray *merge_ids;
143 /* On-demand widgets */
144 GtkWidget *accounts_popup;
145 GtkWidget *details_widget;
147 /* Optimized view enabled */
148 gboolean optimized_view;
150 ModestHeaderView *header_view;
151 ModestFolderView *folder_view;
153 ModestMainWindowStyle style;
154 ModestMainWindowContentsStyle contents_style;
156 guint progress_bar_timeout;
159 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
160 MODEST_TYPE_MAIN_WINDOW, \
161 ModestMainWindowPrivate))
163 typedef struct _GetMsgAsyncHelper {
164 ModestMainWindowPrivate *main_window_private;
166 ModestTnyMsgReplyType reply_type;
167 ModestTnyMsgForwardType forward_type;
174 static GtkWindowClass *parent_class = NULL;
177 /* Private actions */
178 static const GtkActionEntry modest_folder_view_action_entries [] = {
180 /* Folder View CSM actions */
181 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
182 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
183 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, NULL },
184 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
185 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, NULL },
186 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, NULL },
190 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
191 { "ToolbarToggleView", MODEST_STOCK_SPLIT_VIEW, N_("gqn_toolb_rss_fldonoff"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), FALSE },
194 /************************************************************************/
197 modest_main_window_get_type (void)
199 static GType my_type = 0;
201 static const GTypeInfo my_info = {
202 sizeof(ModestMainWindowClass),
203 NULL, /* base init */
204 NULL, /* base finalize */
205 (GClassInitFunc) modest_main_window_class_init,
206 NULL, /* class finalize */
207 NULL, /* class data */
208 sizeof(ModestMainWindow),
210 (GInstanceInitFunc) modest_main_window_init,
213 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
221 modest_main_window_class_init (ModestMainWindowClass *klass)
223 GObjectClass *gobject_class;
224 gobject_class = (GObjectClass*) klass;
225 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
227 parent_class = g_type_class_peek_parent (klass);
228 gobject_class->finalize = modest_main_window_finalize;
230 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
232 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
233 modest_window_class->save_state_func = save_state;
237 modest_main_window_init (ModestMainWindow *obj)
239 ModestMainWindowPrivate *priv;
241 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
243 priv->msg_paned = NULL;
244 priv->main_paned = NULL;
245 priv->main_vbox = NULL;
246 priv->header_view = NULL;
247 priv->folder_view = NULL;
248 priv->contents_widget = NULL;
249 priv->accounts_popup = NULL;
250 priv->details_widget = NULL;
252 priv->progress_widgets = NULL;
253 priv->progress_bar = NULL;
254 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
256 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
257 priv->contents_style = MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS;
259 priv->merge_ids = NULL;
261 priv->optimized_view = FALSE;
262 priv->progress_bar_timeout = 0;
266 modest_main_window_finalize (GObject *obj)
268 ModestMainWindowPrivate *priv;
270 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
272 g_slist_free (priv->progress_widgets);
274 g_byte_array_free (priv->merge_ids, TRUE);
276 if (priv->progress_bar_timeout > 0) {
277 g_source_remove (priv->progress_bar_timeout);
278 priv->progress_bar_timeout = 0;
281 G_OBJECT_CLASS(parent_class)->finalize (obj);
285 modest_main_window_get_child_widget (ModestMainWindow *self,
286 ModestWidgetType widget_type)
288 ModestMainWindowPrivate *priv;
291 g_return_val_if_fail (self, NULL);
292 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_WIDGET_TYPE_NUM,
295 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
297 switch (widget_type) {
298 case MODEST_WIDGET_TYPE_HEADER_VIEW:
299 widget = (GtkWidget*)priv->header_view; break;
300 case MODEST_WIDGET_TYPE_FOLDER_VIEW:
301 widget = (GtkWidget*)priv->folder_view; break;
306 return widget ? GTK_WIDGET(widget) : NULL;
312 restore_settings (ModestMainWindow *self)
315 ModestMainWindowPrivate *priv;
317 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
319 conf = modest_runtime_get_conf ();
321 modest_widget_memory_restore (conf, G_OBJECT(self),
322 MODEST_CONF_MAIN_WINDOW_KEY);
323 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
324 MODEST_CONF_MAIN_PANED_KEY);
325 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
326 MODEST_CONF_HEADER_VIEW_KEY);
331 save_state (ModestWindow *window)
334 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
335 ModestMainWindowPrivate *priv;
337 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
338 conf = modest_runtime_get_conf ();
340 modest_widget_memory_save (conf,G_OBJECT(self),
341 MODEST_CONF_MAIN_WINDOW_KEY);
342 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
343 MODEST_CONF_MAIN_PANED_KEY);
344 modest_widget_memory_save (conf, G_OBJECT(priv->header_view),
345 MODEST_CONF_HEADER_VIEW_KEY);
349 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
351 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
352 gtk_scrolled_window_add_with_viewport
353 (GTK_SCROLLED_WINDOW(win), widget);
355 gtk_container_add (GTK_CONTAINER(win),
361 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self)
363 modest_window_save_state (MODEST_WINDOW(self));
369 on_connection_changed (TnyDevice *device, gboolean online, ModestMainWindow *self)
371 /* When going online, do the equivalent of pressing the send/receive button,
372 * as per the specification:
373 * (without the check for >0 accounts, though that is not specified): */
375 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (self));
382 connect_signals (ModestMainWindow *self)
384 ModestWindowPrivate *parent_priv;
385 ModestMainWindowPrivate *priv;
388 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
389 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
392 g_signal_connect (G_OBJECT(priv->folder_view), "key-press-event",
393 G_CALLBACK(on_inner_widgets_key_pressed), self);
394 g_signal_connect (G_OBJECT(priv->folder_view), "folder_selection_changed",
395 G_CALLBACK(modest_ui_actions_on_folder_selection_changed), self);
396 g_signal_connect (G_OBJECT(priv->folder_view), "folder-display-name-changed",
397 G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
399 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
400 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
403 /* g_signal_connect (G_OBJECT(priv->header_view), "status_update", */
404 /* G_CALLBACK(modest_ui_actions_on_header_status_update), self); */
405 g_signal_connect (G_OBJECT(priv->header_view), "header_selected",
406 G_CALLBACK(modest_ui_actions_on_header_selected), self);
407 g_signal_connect (G_OBJECT(priv->header_view), "header_activated",
408 G_CALLBACK(modest_ui_actions_on_header_activated), self);
409 g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
410 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
411 g_signal_connect (G_OBJECT(priv->header_view), "key-press-event",
412 G_CALLBACK(on_inner_widgets_key_pressed), self);
415 g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
416 g_signal_connect (G_OBJECT (self), "window-state-event",
417 G_CALLBACK (modest_main_window_window_state_event),
419 g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
421 /* Mail Operation Queue */
422 g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
424 G_CALLBACK (on_queue_changed),
427 /* Track changes in the device name */
428 g_signal_connect (G_OBJECT(modest_runtime_get_conf ()),
430 G_CALLBACK (on_configuration_key_changed),
433 /* Track account changes. We need to refresh the toolbar */
434 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
436 G_CALLBACK (on_account_update),
440 g_signal_connect (G_OBJECT (modest_runtime_get_account_store()), "password_requested",
441 G_CALLBACK (modest_ui_actions_on_password_requested), self);
444 g_signal_connect (G_OBJECT(modest_runtime_get_device()), "connection_changed",
445 G_CALLBACK(on_connection_changed), self);
448 /** Idle handler, to send/receive at startup .*/
450 sync_accounts_cb (ModestMainWindow *win)
452 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (win));
453 return FALSE; /* Do not call this idle handler again. */
456 static void on_hildon_program_is_topmost_notify(GObject *self,
457 GParamSpec *propert_param, gpointer user_data)
459 HildonProgram *app = HILDON_PROGRAM (self);
462 ModestWindow* self = MODEST_WINDOW(user_data);
465 /* Note that use of hildon_program_set_can_hibernate()
466 * is generally referred to as "setting the killable flag",
467 * though hibernation does not seem equal to death.
470 if (hildon_program_get_is_topmost (app)) {
471 /* Prevent hibernation when the progam comes to the foreground,
472 * because hibernation should only happen when the application
473 * is in the background: */
474 hildon_program_set_can_hibernate (app, FALSE);
476 /* Allow hibernation if the program has gone to the background: */
478 /* However, prevent hibernation while the settings are being changed: */
479 const gboolean hibernation_prevented =
480 modest_window_mgr_get_hibernation_is_prevented (
481 modest_runtime_get_window_mgr ());
483 if (hibernation_prevented)
484 hildon_program_set_can_hibernate (app, FALSE);
486 /* Allow hibernation, after saving the state: */
487 modest_osso_save_state();
488 hildon_program_set_can_hibernate (app, TRUE);
497 modest_main_window_new (void)
499 ModestMainWindow *self;
500 ModestMainWindowPrivate *priv;
501 ModestWindowPrivate *parent_priv;
502 GtkWidget *folder_win;
503 GtkActionGroup *action_group;
504 GError *error = NULL;
505 TnyFolderStoreQuery *query;
506 GdkPixbuf *window_icon;
510 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
511 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
512 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
514 parent_priv->ui_manager = gtk_ui_manager_new();
515 action_group = gtk_action_group_new ("ModestMainWindowActions");
516 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
518 /* Add common actions */
519 gtk_action_group_add_actions (action_group,
520 modest_action_entries,
521 G_N_ELEMENTS (modest_action_entries),
524 gtk_action_group_add_actions (action_group,
525 modest_folder_view_action_entries,
526 G_N_ELEMENTS (modest_folder_view_action_entries),
529 gtk_action_group_add_toggle_actions (action_group,
530 modest_toggle_action_entries,
531 G_N_ELEMENTS (modest_toggle_action_entries),
534 gtk_action_group_add_toggle_actions (action_group,
535 modest_main_window_toggle_action_entries,
536 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
539 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
540 g_object_unref (action_group);
542 /* Load the UI definition */
543 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
544 MODEST_UIDIR "modest-main-window-ui.xml", &error);
546 g_warning ("Could not merge modest-ui.xml: %s", error->message);
547 g_error_free (error);
551 /* Add accelerators */
552 gtk_window_add_accel_group (GTK_WINDOW (self),
553 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
555 /* Menubar. Update the state of some toggles */
556 parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
557 conf = modest_runtime_get_conf ();
558 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
559 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
560 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
561 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL));
562 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
563 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
564 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
565 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL));
566 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
568 /* Get device name */
569 modest_maemo_utils_get_device_name ();
572 query = tny_folder_store_query_new ();
573 tny_folder_store_query_add_item (query, NULL,
574 TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
575 priv->folder_view = MODEST_FOLDER_VIEW(modest_folder_view_new (query));
576 if (!priv->folder_view)
577 g_printerr ("modest: cannot instantiate folder view\n");
578 g_object_unref (G_OBJECT (query));
579 modest_folder_view_set_style (priv->folder_view,
580 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
584 MODEST_HEADER_VIEW(modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
585 if (!priv->header_view)
586 g_printerr ("modest: cannot instantiate header view\n");
587 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
589 /* Create scrolled windows */
590 folder_win = gtk_scrolled_window_new (NULL, NULL);
591 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
592 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
594 GTK_POLICY_AUTOMATIC);
595 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
597 GTK_POLICY_AUTOMATIC);
599 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
600 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view));
603 priv->main_paned = gtk_hpaned_new ();
604 gtk_paned_add1 (GTK_PANED(priv->main_paned), folder_win);
605 gtk_paned_add2 (GTK_PANED(priv->main_paned), priv->contents_widget);
606 gtk_widget_show (GTK_WIDGET(priv->header_view));
607 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
609 /* putting it all together... */
610 priv->main_vbox = gtk_vbox_new (FALSE, 6);
611 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
613 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
614 restore_settings (MODEST_MAIN_WINDOW(self));
616 /* Set window icon */
617 window_icon = modest_platform_get_icon (MODEST_APP_ICON);
618 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
620 /* Connect signals */
621 connect_signals (self);
623 /* Set account store */
624 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
625 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
627 /* do send & receive when we are idle */
628 g_idle_add ((GSourceFunc)sync_accounts_cb, self);
630 HildonProgram *app = hildon_program_get_instance ();
631 hildon_program_add_window (app, HILDON_WINDOW (self));
633 /* Register HildonProgram signal handlers: */
634 /* These are apparently deprecated, according to the
635 * "HildonApp/HildonAppView to HildonProgram/HildonWindow migration guide",
636 * though the API reference does not mention that:
638 g_signal_connect (G_OBJECT(app), "topmost_status_lose",
639 G_CALLBACK (on_hildon_program_save_state), self);
640 g_signal_connect (G_OBJECT(app), "topmost_status_acquire",
641 G_CALLBACK (on_hildon_program_status_acquire), self);
643 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
644 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
646 /* Load previous osso state, for instance if we are being restored from
648 modest_osso_load_state();
650 return MODEST_WINDOW(self);
654 modest_main_window_close_all (ModestMainWindow *self)
657 GtkResponseType response;
659 /* Create the confirmation dialog MSG-NOT308 */
660 note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
661 _("emev_nc_close_windows"),
662 _("mcen_bd_yes"), GTK_RESPONSE_YES,
663 _("mcen_bd_no"), GTK_RESPONSE_NO,
666 response = gtk_dialog_run (GTK_DIALOG (note));
667 gtk_widget_destroy (GTK_WIDGET (note));
669 if (response == GTK_RESPONSE_YES)
677 modest_main_window_set_style (ModestMainWindow *self,
678 ModestMainWindowStyle style)
680 ModestMainWindowPrivate *priv;
681 ModestWindowPrivate *parent_priv;
684 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
686 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
687 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
689 /* no change -> nothing to do */
690 if (priv->style == style)
693 /* Get toggle button */
694 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarToggleView");
699 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
700 /* Remove main paned */
701 g_object_ref (priv->main_paned);
702 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
704 /* Reparent the contents widget to the main vbox */
705 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
707 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
708 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
709 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
712 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
713 /* Remove header view */
714 g_object_ref (priv->contents_widget);
715 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
717 /* Reparent the main paned */
718 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
719 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
721 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
722 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
723 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
727 g_return_if_reached ();
730 /* Let header view grab the focus if it's being shown */
731 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
732 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
734 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
737 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
740 ModestMainWindowStyle
741 modest_main_window_get_style (ModestMainWindow *self)
743 ModestMainWindowPrivate *priv;
745 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
747 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
754 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
756 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
757 ModestWindowPrivate *parent_priv;
758 ModestWindowMgr *mgr;
759 gboolean is_fullscreen;
760 GtkAction *fs_toggle_action;
763 mgr = modest_runtime_get_window_mgr ();
765 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
767 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
769 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
770 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
771 if (is_fullscreen != active) {
772 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
781 set_homogeneous (GtkWidget *widget,
784 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
785 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
789 modest_main_window_show_toolbar (ModestWindow *self,
790 gboolean show_toolbar)
792 ModestMainWindowPrivate *priv = NULL;
793 ModestWindowPrivate *parent_priv = NULL;
794 GtkWidget *reply_button = NULL, *menu = NULL;
795 GtkWidget *placeholder = NULL;
798 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
799 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
800 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
802 /* Set optimized view status */
803 priv->optimized_view = !show_toolbar;
805 if (!parent_priv->toolbar) {
806 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
809 /* Set homogeneous toolbar */
810 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar),
811 set_homogeneous, NULL);
813 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
814 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
815 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
816 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
817 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
818 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
819 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
820 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
822 /* Add ProgressBar (Transfer toolbar) */
823 priv->progress_bar = modest_progress_bar_widget_new ();
824 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
825 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
826 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
827 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
828 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
830 /* Connect cancel 'clicked' signal to abort progress mode */
831 g_signal_connect(priv->cancel_toolitem, "clicked",
832 G_CALLBACK(cancel_progressbar),
835 /* Add it to the observers list */
836 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
839 hildon_window_add_toolbar (HILDON_WINDOW (self),
840 GTK_TOOLBAR (parent_priv->toolbar));
842 /* Set reply button tap and hold menu */
843 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
844 "/ToolBar/ToolbarMessageReply");
845 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
847 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
849 /* Set send & receive button tap and hold menu */
850 on_account_update (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
855 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
856 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
857 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
859 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
860 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
862 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
867 compare_display_names (ModestAccountData *a,
868 ModestAccountData *b)
870 return strcmp (a->display_name, b->display_name);
874 on_account_update (TnyAccountStore *account_store,
875 const gchar *account_name,
878 GSList *account_names, *iter, *accounts;
879 ModestMainWindow *self;
880 ModestMainWindowPrivate *priv;
881 ModestWindowPrivate *parent_priv;
882 ModestAccountMgr *mgr;
883 gint i, num_accounts;
884 GtkActionGroup *action_group;
886 gchar *default_account;
887 GtkWidget *send_receive_button, *item;
889 self = MODEST_MAIN_WINDOW (user_data);
890 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
891 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
893 /* Get enabled account IDs */
894 mgr = modest_runtime_get_account_mgr ();
895 account_names = modest_account_mgr_account_names (mgr, TRUE);
896 iter = account_names;
900 ModestAccountData *account_data =
901 modest_account_mgr_get_account_data (mgr, (gchar*) iter->data);
902 accounts = g_slist_prepend (accounts, account_data);
906 g_slist_free (account_names);
908 /* Order the list of accounts by its display name */
909 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
910 num_accounts = g_slist_length (accounts);
912 /* Delete old send&receive popup items. We can not just do a
913 menu_detach because it does not work well with
915 if (priv->accounts_popup)
916 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup), (GtkCallback) gtk_widget_destroy, NULL);
918 /* Delete old entries in the View menu. Do not free groups, it
920 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
922 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
923 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
924 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
925 GTK_ACTION_GROUP (groups->data));
928 if (priv->merge_ids) {
929 for (i = 0; i < priv->merge_ids->len; i++)
930 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
931 g_byte_array_free (priv->merge_ids, TRUE);
933 /* We need to call this in order to ensure
934 that the new actions are added in the right
935 order (alphabetical */
936 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
938 groups = g_list_next (groups);
940 priv->merge_ids = g_byte_array_sized_new (num_accounts);
942 /* Get send receive button */
943 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
944 "/ToolBar/ToolbarSendReceive");
946 /* Create the menu */
947 if (num_accounts > 1) {
948 if (!priv->accounts_popup)
949 priv->accounts_popup = gtk_menu_new ();
950 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
951 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
952 g_signal_connect (G_OBJECT (item),
954 G_CALLBACK (on_send_receive_csm_activated),
956 item = gtk_separator_menu_item_new ();
957 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
960 /* Create a new action group */
961 default_account = modest_account_mgr_get_default_account (mgr);
962 action_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
963 for (i = 0; i < num_accounts; i++) {
964 GtkAction *new_action = NULL;
965 gchar *display_name = NULL;
967 ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
969 /* Create display name. The default account is shown differently */
970 if (default_account && account_data->account_name &&
971 !(strcmp (default_account, account_data->account_name) == 0)) {
972 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
973 account_data->display_name);
976 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
977 account_data->display_name);
980 /* Create action and add it to the action group. The
981 action name must be the account name, this way we
982 could know in the handlers the account to show */
983 if(account_data->account_name) {
984 new_action = gtk_action_new (account_data->account_name, display_name, NULL, NULL);
985 gtk_action_group_add_action (action_group, new_action);
987 /* Add ui from account data. We allow 2^9-1 account
988 changes in a single execution because we're
989 downcasting the guint to a guint8 in order to use a
990 GByteArray, it should be enough */
991 gchar* item_name = g_strconcat (account_data->account_name, "Menu", NULL);
992 guint8 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
993 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
994 gtk_ui_manager_add_ui (parent_priv->ui_manager,
996 "/MenuBar/ViewMenu/ViewMenuAdditions",
998 account_data->account_name,
999 GTK_UI_MANAGER_MENUITEM,
1002 /* Connect the action signal "activate" */
1003 g_signal_connect (G_OBJECT (new_action),
1005 G_CALLBACK (on_show_account_action_activated),
1008 /* Create item and add it to the send&receive CSM */
1009 /* TODO: Why is this sometimes NULL? murrayc */
1010 if (priv->accounts_popup) {
1011 item = gtk_menu_item_new_with_label (display_name);
1012 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1013 g_signal_connect_data (G_OBJECT (item),
1015 G_CALLBACK (on_send_receive_csm_activated),
1016 g_strdup (account_data->account_name),
1017 (GClosureNotify) g_free,
1025 g_free (display_name);
1026 modest_account_mgr_free_account_data (mgr, account_data);
1028 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 1);
1030 if (priv->accounts_popup) {
1031 /* Mandatory in order to view the menu contents */
1032 gtk_widget_show_all (priv->accounts_popup);
1034 /* Setup tap_and_hold just if was not done before*/
1035 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
1036 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
1040 g_slist_free (accounts);
1041 g_free (default_account);
1045 * This function manages the key events used to navigate between
1046 * header and folder views (when the window is in split view)
1049 * -------------------------------------------------
1050 * HeaderView GDK_Left Move focus to folder view
1051 * FolderView GDK_Right Move focus to header view
1053 * There is no need to scroll to selected row, the widgets will be the
1054 * responsibles of doing that (probably managing the focus-in event
1057 on_inner_widgets_key_pressed (GtkWidget *widget,
1061 ModestMainWindowPrivate *priv;
1063 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1065 /* Do nothing if we're in SIMPLE style */
1066 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1069 if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
1070 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1071 else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1072 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1078 set_alignment (GtkWidget *widget,
1081 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1082 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1086 create_details_widget (TnyAccount *account)
1091 vbox = gtk_vbox_new (FALSE, 0);
1093 /* Account description */
1094 if (!strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1097 /* Get device name */
1098 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1099 MODEST_CONF_DEVICE_NAME, NULL);
1101 label = g_strdup_printf ("%s: %s",
1102 _("mcen_fi_localroot_description"),
1104 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1105 g_free (device_name);
1107 } else if (!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1109 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("FIXME: MMC ?"), FALSE, FALSE, 0);
1113 /* Put proto in uppercase */
1114 proto = g_string_new (tny_account_get_proto (account));
1115 proto = g_string_ascii_up (proto);
1117 label = g_strdup_printf ("%s %s: %s",
1119 _("mcen_fi_remoteroot_account"),
1120 tny_account_get_name (account));
1121 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1122 g_string_free (proto, TRUE);
1127 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_messages"),
1128 modest_tny_account_get_message_count (account));
1129 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1133 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_folders"),
1134 modest_tny_account_get_folder_count (account));
1135 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1139 if (!strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1140 /* FIXME: format size */
1141 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_size"),
1142 modest_tny_account_get_local_size (account));
1143 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1145 } else if (!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1146 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("FIXME: MMC ?"), FALSE, FALSE, 0);
1148 time_t last_updated;
1149 gchar *last_updated_string;
1150 /* Get last updated from configuration */
1151 last_updated = modest_account_mgr_get_int (modest_runtime_get_account_mgr (),
1152 tny_account_get_id (account),
1153 MODEST_ACCOUNT_LAST_UPDATED,
1155 if (last_updated > 0)
1156 last_updated_string = modest_text_utils_get_display_date(last_updated);
1158 last_updated_string = g_strdup (_("FIXME: Never"));
1160 label = g_strdup_printf ("%s: %s", _("mcen_ti_lastupdated"), last_updated_string);
1161 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1162 g_free (last_updated_string);
1167 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1173 modest_main_window_set_contents_style (ModestMainWindow *self,
1174 ModestMainWindowContentsStyle style)
1176 ModestMainWindowPrivate *priv;
1178 TnyAccount *account;
1180 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1182 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1184 /* We allow to set the same content style than the previously
1185 set if there are details, because it could happen when we're
1186 selecting different accounts consecutively */
1187 if ((priv->contents_style == style) &&
1188 (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS))
1191 /* Remove previous child. Delete it if it was an account
1193 content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1194 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1195 g_object_ref (content);
1196 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1198 priv->contents_style = style;
1200 switch (priv->contents_style) {
1201 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1202 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1204 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1205 /* TODO: show here account details */
1206 account = TNY_ACCOUNT (modest_folder_view_get_selected (priv->folder_view));
1207 priv->details_widget = create_details_widget (account);
1209 wrap_in_scrolled_window (priv->contents_widget,
1210 priv->details_widget);
1213 g_return_if_reached ();
1217 gtk_widget_show_all (priv->contents_widget);
1221 on_configuration_key_changed (ModestConf* conf,
1223 ModestConfEvent event,
1224 ModestMainWindow *self)
1226 ModestMainWindowPrivate *priv;
1227 TnyAccount *account;
1229 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
1232 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1234 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1237 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
1238 if (TNY_IS_ACCOUNT (account) &&
1239 !strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1242 const gchar *device_name;
1246 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
1247 label = GTK_LABEL (children->data);
1249 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1250 MODEST_CONF_DEVICE_NAME, NULL);
1252 new_text = g_strdup_printf ("%s: %s",
1253 _("mcen_fi_localroot_description"),
1256 gtk_label_set_text (label, new_text);
1257 gtk_widget_show (GTK_WIDGET (label));
1260 g_list_free (children);
1265 set_toolbar_transfer_mode (ModestMainWindow *self)
1267 ModestMainWindowPrivate *priv = NULL;
1269 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1271 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1273 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
1275 if (priv->progress_bar_timeout > 0) {
1276 g_source_remove (priv->progress_bar_timeout);
1277 priv->progress_bar_timeout = 0;
1284 set_toolbar_mode (ModestMainWindow *self,
1285 ModestToolBarModes mode)
1287 ModestWindowPrivate *parent_priv = NULL;
1288 ModestMainWindowPrivate *priv = NULL;
1289 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
1291 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1293 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1294 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1296 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
1298 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1299 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1300 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1302 /* Sets current toolbar mode */
1303 priv->current_toolbar_mode = mode;
1305 /* Show and hide toolbar items */
1307 case TOOLBAR_MODE_NORMAL:
1309 gtk_action_set_visible (sort_action, TRUE);
1311 gtk_action_set_visible (refresh_action, TRUE);
1312 if (priv->progress_toolitem) {
1313 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1314 gtk_widget_hide (priv->progress_toolitem);
1316 if (priv->progress_bar)
1317 gtk_widget_hide (priv->progress_bar);
1320 gtk_action_set_visible (cancel_action, FALSE);
1322 /* Hide toolbar if optimized view is enabled */
1323 if (priv->optimized_view)
1324 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
1326 case TOOLBAR_MODE_TRANSFER:
1328 gtk_action_set_visible (sort_action, FALSE);
1330 gtk_action_set_visible (refresh_action, FALSE);
1332 gtk_action_set_visible (cancel_action, TRUE);
1333 if (priv->progress_toolitem) {
1334 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1335 gtk_widget_show (priv->progress_toolitem);
1337 if (priv->progress_bar)
1338 gtk_widget_show (priv->progress_bar);
1340 /* Show toolbar if it's hiden (optimized view ) */
1341 if (priv->optimized_view)
1342 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1345 g_return_if_reached ();
1350 cancel_progressbar (GtkToolButton *toolbutton,
1351 ModestMainWindow *self)
1354 ModestMainWindowPrivate *priv;
1356 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1358 /* Get operation observers and cancel its current operation */
1359 tmp = priv->progress_widgets;
1361 modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
1362 tmp=g_slist_next(tmp);
1367 observers_empty (ModestMainWindow *self)
1370 ModestMainWindowPrivate *priv;
1371 gboolean is_empty = TRUE;
1372 guint pending_ops = 0;
1374 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1375 tmp = priv->progress_widgets;
1377 /* Check all observers */
1378 while (tmp && is_empty) {
1379 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
1380 is_empty = pending_ops == 0;
1382 tmp = g_slist_next(tmp);
1389 on_queue_changed (ModestMailOperationQueue *queue,
1390 ModestMailOperation *mail_op,
1391 ModestMailOperationQueueNotification type,
1392 ModestMainWindow *self)
1394 ModestMainWindowPrivate *priv;
1395 ModestMailOperationId op_id;
1396 ModestToolBarModes mode;
1398 gboolean mode_changed = FALSE;
1400 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1401 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1403 /* Get toolbar mode from operation id*/
1404 op_id = modest_mail_operation_get_id (mail_op);
1406 case MODEST_MAIL_OPERATION_ID_SEND:
1407 case MODEST_MAIL_OPERATION_ID_RECEIVE:
1408 mode = TOOLBAR_MODE_TRANSFER;
1409 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
1410 mode_changed = TRUE;
1413 mode = TOOLBAR_MODE_NORMAL;
1418 /* Add operation observers and change toolbar if neccessary*/
1419 tmp = priv->progress_widgets;
1421 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
1422 if (mode == TOOLBAR_MODE_TRANSFER) {
1424 set_toolbar_transfer_mode(self);
1426 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1428 tmp = g_slist_next (tmp);
1432 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
1433 if (mode == TOOLBAR_MODE_TRANSFER) {
1435 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1437 tmp = g_slist_next (tmp);
1440 /* If no more operations are being observed, NORMAL mode is enabled again */
1441 if (observers_empty (self)) {
1442 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
1451 on_show_account_action_activated (GtkAction *action,
1454 ModestAccountData *acc_data;
1455 ModestMainWindow *self;
1456 ModestMainWindowPrivate *priv;
1457 ModestAccountMgr *mgr;
1458 const gchar *acc_name;
1460 self = MODEST_MAIN_WINDOW (user_data);
1461 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1463 /* Get account data */
1464 acc_name = gtk_action_get_name (action);
1465 mgr = modest_runtime_get_account_mgr ();
1466 acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
1468 /* Set the new visible & active account */
1469 if (acc_data->store_account) {
1470 modest_folder_view_set_account_id_of_visible_server_account (priv->folder_view,
1471 acc_data->store_account->account_name);
1472 modest_window_set_active_account (MODEST_WINDOW (self), acc_data->account_name);
1476 modest_account_mgr_free_account_data (mgr, acc_data);
1480 on_send_receive_csm_activated (GtkMenuItem *item,
1485 win = MODEST_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
1487 /* If user_data == NULL, we must update all (CSM option All) */
1489 modest_ui_actions_do_send_receive_all (win);
1491 modest_ui_actions_do_send_receive ((const gchar *)user_data, win);