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 "maemo/modest-osso-state-saving.h"
58 #ifdef MODEST_HILDON_VERSION_0
59 #include <hildon-widgets/hildon-program.h>
61 #include <hildon/hildon-program.h>
62 #endif /*MODEST_HILDON_VERSION_0*/
64 #define MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS "ModestMainWindowActionAdditions"
66 /* 'private'/'protected' functions */
67 static void modest_main_window_class_init (ModestMainWindowClass *klass);
68 static void modest_main_window_init (ModestMainWindow *obj);
69 static void modest_main_window_finalize (GObject *obj);
70 static gboolean modest_main_window_window_state_event (GtkWidget *widget,
71 GdkEventWindowState *event,
74 static void connect_signals (ModestMainWindow *self);
76 static void restore_settings (ModestMainWindow *self);
77 static void save_state (ModestWindow *self);
79 static void modest_main_window_show_toolbar (ModestWindow *window,
80 gboolean show_toolbar);
82 static void cancel_progressbar (GtkToolButton *toolbutton,
83 ModestMainWindow *self);
85 static void on_queue_changed (ModestMailOperationQueue *queue,
86 ModestMailOperation *mail_op,
87 ModestMailOperationQueueNotification type,
88 ModestMainWindow *self);
90 static void on_account_update (TnyAccountStore *account_store,
94 static gboolean on_inner_widgets_key_pressed (GtkWidget *widget,
98 static void on_configuration_key_changed (ModestConf* conf,
100 ModestConfEvent event,
101 ModestMainWindow *self);
103 static void set_toolbar_mode (ModestMainWindow *self,
104 ModestToolBarModes mode);
106 static void on_show_account_action_activated (GtkAction *action,
109 static void on_send_receive_csm_activated (GtkMenuItem *item,
111 /* list my signals */
119 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
120 struct _ModestMainWindowPrivate {
121 GtkWidget *msg_paned;
122 GtkWidget *main_paned;
123 GtkWidget *main_vbox;
124 GtkWidget *contents_widget;
126 /* Progress observers */
127 GtkWidget *progress_bar;
128 GSList *progress_widgets;
131 GtkWidget *progress_toolitem;
132 GtkWidget *cancel_toolitem;
133 GtkWidget *sort_toolitem;
134 GtkWidget *refresh_toolitem;
135 ModestToolBarModes current_toolbar_mode;
137 /* Merge ids used to add/remove accounts to the ViewMenu*/
138 GByteArray *merge_ids;
140 /* On-demand widgets */
141 GtkWidget *accounts_popup;
142 GtkWidget *details_widget;
144 /* Optimized view enabled */
145 gboolean optimized_view;
147 ModestHeaderView *header_view;
148 ModestFolderView *folder_view;
150 ModestMainWindowStyle style;
151 ModestMainWindowContentsStyle contents_style;
153 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
154 MODEST_TYPE_MAIN_WINDOW, \
155 ModestMainWindowPrivate))
157 typedef struct _GetMsgAsyncHelper {
158 ModestMainWindowPrivate *main_window_private;
160 ModestTnyMsgReplyType reply_type;
161 ModestTnyMsgForwardType forward_type;
168 static GtkWindowClass *parent_class = NULL;
171 /* Private actions */
172 static const GtkActionEntry modest_folder_view_action_entries [] = {
174 /* Folder View CSM actions */
175 { "FolderViewCSMNewFolder", NULL, N_("FIXME: New Folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
176 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
177 { "FolderViewCSMPasteMsgs", NULL, N_("FIXME: Paste"), NULL, NULL, NULL },
178 { "FolderViewCSMDeleteFolder", NULL, N_("FIXME: Delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
179 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, NULL },
180 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, NULL },
184 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
185 { "ToolbarToggleView", MODEST_STOCK_SPLIT_VIEW, N_("gqn_toolb_rss_fldonoff"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), FALSE },
188 /************************************************************************/
191 modest_main_window_get_type (void)
193 static GType my_type = 0;
195 static const GTypeInfo my_info = {
196 sizeof(ModestMainWindowClass),
197 NULL, /* base init */
198 NULL, /* base finalize */
199 (GClassInitFunc) modest_main_window_class_init,
200 NULL, /* class finalize */
201 NULL, /* class data */
202 sizeof(ModestMainWindow),
204 (GInstanceInitFunc) modest_main_window_init,
207 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
215 modest_main_window_class_init (ModestMainWindowClass *klass)
217 GObjectClass *gobject_class;
218 gobject_class = (GObjectClass*) klass;
219 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
221 parent_class = g_type_class_peek_parent (klass);
222 gobject_class->finalize = modest_main_window_finalize;
224 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
226 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
227 modest_window_class->save_state_func = save_state;
231 modest_main_window_init (ModestMainWindow *obj)
233 ModestMainWindowPrivate *priv;
235 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
237 priv->msg_paned = NULL;
238 priv->main_paned = NULL;
239 priv->main_vbox = NULL;
240 priv->header_view = NULL;
241 priv->folder_view = NULL;
242 priv->contents_widget = NULL;
243 priv->accounts_popup = NULL;
244 priv->details_widget = NULL;
246 priv->optimized_view = FALSE;
248 priv->progress_widgets = NULL;
249 priv->progress_bar = NULL;
250 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
252 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
253 priv->contents_style = MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS;
255 priv->merge_ids = NULL;
259 modest_main_window_finalize (GObject *obj)
261 ModestMainWindowPrivate *priv;
263 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
265 g_slist_free (priv->progress_widgets);
267 g_byte_array_free (priv->merge_ids, TRUE);
269 G_OBJECT_CLASS(parent_class)->finalize (obj);
273 modest_main_window_get_child_widget (ModestMainWindow *self,
274 ModestWidgetType widget_type)
276 ModestMainWindowPrivate *priv;
279 g_return_val_if_fail (self, NULL);
280 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_WIDGET_TYPE_NUM,
283 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
285 switch (widget_type) {
286 case MODEST_WIDGET_TYPE_HEADER_VIEW:
287 widget = (GtkWidget*)priv->header_view; break;
288 case MODEST_WIDGET_TYPE_FOLDER_VIEW:
289 widget = (GtkWidget*)priv->folder_view; break;
294 return widget ? GTK_WIDGET(widget) : NULL;
300 restore_settings (ModestMainWindow *self)
303 ModestMainWindowPrivate *priv;
305 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
307 conf = modest_runtime_get_conf ();
309 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
310 MODEST_CONF_MAIN_PANED_KEY);
311 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
312 MODEST_CONF_HEADER_VIEW_KEY);
313 modest_widget_memory_restore (conf, G_OBJECT(self),
314 MODEST_CONF_MAIN_WINDOW_KEY);
319 save_state (ModestWindow *window)
322 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
323 ModestMainWindowPrivate *priv;
325 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
326 conf = modest_runtime_get_conf ();
328 modest_widget_memory_save (conf,G_OBJECT(self),
329 MODEST_CONF_MAIN_WINDOW_KEY);
330 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
331 MODEST_CONF_MAIN_PANED_KEY);
332 modest_widget_memory_save (conf, G_OBJECT(priv->header_view),
333 MODEST_CONF_HEADER_VIEW_KEY);
337 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
339 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
340 gtk_scrolled_window_add_with_viewport
341 (GTK_SCROLLED_WINDOW(win), widget);
343 gtk_container_add (GTK_CONTAINER(win),
349 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self)
351 modest_window_save_state (MODEST_WINDOW(self));
357 on_connection_changed (TnyDevice *device, gboolean online, ModestMainWindow *self)
359 /* When going online, do the equivalent of pressing the send/receive button,
360 * as per the specification:
361 * (without the check for >0 accounts, though that is not specified): */
363 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (self));
370 connect_signals (ModestMainWindow *self)
372 ModestWindowPrivate *parent_priv;
373 ModestMainWindowPrivate *priv;
376 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
377 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
380 g_signal_connect (G_OBJECT(priv->folder_view), "key-press-event",
381 G_CALLBACK(on_inner_widgets_key_pressed), self);
382 g_signal_connect (G_OBJECT(priv->folder_view), "folder_selection_changed",
383 G_CALLBACK(modest_ui_actions_on_folder_selection_changed), self);
384 g_signal_connect (G_OBJECT(priv->folder_view), "folder-display-name-changed",
385 G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
387 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
388 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
391 /* g_signal_connect (G_OBJECT(priv->header_view), "status_update", */
392 /* G_CALLBACK(modest_ui_actions_on_header_status_update), self); */
393 g_signal_connect (G_OBJECT(priv->header_view), "header_selected",
394 G_CALLBACK(modest_ui_actions_on_header_selected), self);
395 g_signal_connect (G_OBJECT(priv->header_view), "header_activated",
396 G_CALLBACK(modest_ui_actions_on_header_activated), self);
397 g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
398 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
399 g_signal_connect (G_OBJECT(priv->header_view), "key-press-event",
400 G_CALLBACK(on_inner_widgets_key_pressed), self);
403 g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
404 g_signal_connect (G_OBJECT (self), "window-state-event",
405 G_CALLBACK (modest_main_window_window_state_event),
407 g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
409 /* Mail Operation Queue */
410 g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
412 G_CALLBACK (on_queue_changed),
415 /* Track changes in the device name */
416 g_signal_connect (G_OBJECT(modest_runtime_get_conf ()),
418 G_CALLBACK (on_configuration_key_changed),
421 /* Track account changes. We need to refresh the toolbar */
422 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
424 G_CALLBACK (on_account_update),
428 g_signal_connect (G_OBJECT (modest_runtime_get_account_store()), "password_requested",
429 G_CALLBACK (modest_ui_actions_on_password_requested), self);
432 g_signal_connect (G_OBJECT(modest_runtime_get_device()), "connection_changed",
433 G_CALLBACK(on_connection_changed), self);
436 /** Idle handler, to send/receive at startup .*/
438 sync_accounts_cb (ModestMainWindow *win)
440 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (win));
441 return FALSE; /* Do not call this idle handler again. */
444 static void on_hildon_program_is_topmost_notify(GObject *self,
445 GParamSpec *propert_param, gpointer user_data)
447 HildonProgram *app = HILDON_PROGRAM (self);
450 ModestWindow* self = MODEST_WINDOW(user_data);
453 /* Note that use of hildon_program_set_can_hibernate()
454 * is generally referred to as "setting the killable flag",
455 * though hibernation does not seem equal to death.
458 if (hildon_program_get_is_topmost (app)) {
459 /* Prevent hibernation when the progam comes to the foreground,
460 * because hibernation should only happen when the application
461 * is in the background: */
462 hildon_program_set_can_hibernate (app, FALSE);
464 /* Allow hibernation if the program has gone to the background: */
466 /* However, prevent hibernation while the settings are being changed: */
467 const gboolean hibernation_prevented =
468 modest_window_mgr_get_hibernation_is_prevented (
469 modest_runtime_get_window_mgr ());
471 if (hibernation_prevented)
472 hildon_program_set_can_hibernate (app, FALSE);
474 /* Allow hibernation, after saving the state: */
475 modest_osso_save_state();
476 hildon_program_set_can_hibernate (app, TRUE);
485 modest_main_window_new (void)
487 ModestMainWindow *self;
488 ModestMainWindowPrivate *priv;
489 ModestWindowPrivate *parent_priv;
490 GtkWidget *folder_win;
491 GtkActionGroup *action_group;
492 GError *error = NULL;
493 TnyFolderStoreQuery *query;
494 GdkPixbuf *window_icon;
498 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
499 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
500 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
502 parent_priv->ui_manager = gtk_ui_manager_new();
503 action_group = gtk_action_group_new ("ModestMainWindowActions");
504 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
506 /* Add common actions */
507 gtk_action_group_add_actions (action_group,
508 modest_action_entries,
509 G_N_ELEMENTS (modest_action_entries),
512 gtk_action_group_add_actions (action_group,
513 modest_folder_view_action_entries,
514 G_N_ELEMENTS (modest_folder_view_action_entries),
517 gtk_action_group_add_toggle_actions (action_group,
518 modest_toggle_action_entries,
519 G_N_ELEMENTS (modest_toggle_action_entries),
522 gtk_action_group_add_toggle_actions (action_group,
523 modest_main_window_toggle_action_entries,
524 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
527 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
528 g_object_unref (action_group);
530 /* Load the UI definition */
531 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
532 MODEST_UIDIR "modest-main-window-ui.xml", &error);
534 g_warning ("Could not merge modest-ui.xml: %s", error->message);
535 g_error_free (error);
539 /* Add accelerators */
540 gtk_window_add_accel_group (GTK_WINDOW (self),
541 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
543 /* Menubar. Update the state of some toggles */
544 parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
545 conf = modest_runtime_get_conf ();
546 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
547 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
548 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
549 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL));
550 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
551 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
552 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
553 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL));
554 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
556 /* Get device name */
557 modest_maemo_utils_get_device_name ();
560 query = tny_folder_store_query_new ();
561 tny_folder_store_query_add_item (query, NULL,
562 TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
563 priv->folder_view = MODEST_FOLDER_VIEW(modest_folder_view_new (query));
564 if (!priv->folder_view)
565 g_printerr ("modest: cannot instantiate folder view\n");
566 g_object_unref (G_OBJECT (query));
567 modest_folder_view_set_style (priv->folder_view,
568 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
572 MODEST_HEADER_VIEW(modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
573 if (!priv->header_view)
574 g_printerr ("modest: cannot instantiate header view\n");
575 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
577 /* Create scrolled windows */
578 folder_win = gtk_scrolled_window_new (NULL, NULL);
579 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
580 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
582 GTK_POLICY_AUTOMATIC);
583 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
585 GTK_POLICY_AUTOMATIC);
587 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
588 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view));
591 priv->main_paned = gtk_hpaned_new ();
592 gtk_paned_add1 (GTK_PANED(priv->main_paned), folder_win);
593 gtk_paned_add2 (GTK_PANED(priv->main_paned), priv->contents_widget);
594 gtk_widget_show (GTK_WIDGET(priv->header_view));
595 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
597 /* putting it all together... */
598 priv->main_vbox = gtk_vbox_new (FALSE, 6);
599 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
601 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
602 restore_settings (MODEST_MAIN_WINDOW(self));
604 /* Set window icon */
605 window_icon = modest_platform_get_icon (MODEST_APP_ICON);
606 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
608 /* Connect signals */
609 connect_signals (self);
611 /* Set account store */
612 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
613 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
615 /* do send & receive when we are idle */
616 g_idle_add ((GSourceFunc)sync_accounts_cb, self);
618 HildonProgram *app = hildon_program_get_instance ();
619 hildon_program_add_window (app, HILDON_WINDOW (self));
621 /* Register HildonProgram signal handlers: */
622 /* These are apparently deprecated, according to the
623 * "HildonApp/HildonAppView to HildonProgram/HildonWindow migration guide",
624 * though the API reference does not mention that:
626 g_signal_connect (G_OBJECT(app), "topmost_status_lose",
627 G_CALLBACK (on_hildon_program_save_state), self);
628 g_signal_connect (G_OBJECT(app), "topmost_status_acquire",
629 G_CALLBACK (on_hildon_program_status_acquire), self);
631 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
632 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
634 /* Load previous osso state, for instance if we are being restored from
636 modest_osso_load_state();
638 return MODEST_WINDOW(self);
642 modest_main_window_close_all (ModestMainWindow *self)
645 GtkResponseType response;
647 /* Create the confirmation dialog MSG-NOT308 */
648 note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
649 _("emev_nc_close_windows"),
650 _("mcen_bd_yes"), GTK_RESPONSE_YES,
651 _("mcen_bd_no"), GTK_RESPONSE_NO,
654 response = gtk_dialog_run (GTK_DIALOG (note));
655 gtk_widget_destroy (GTK_WIDGET (note));
657 if (response == GTK_RESPONSE_YES)
665 modest_main_window_set_style (ModestMainWindow *self,
666 ModestMainWindowStyle style)
668 ModestMainWindowPrivate *priv;
669 ModestWindowPrivate *parent_priv;
672 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
674 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
675 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
677 /* no change -> nothing to do */
678 if (priv->style == style)
681 /* Get toggle button */
682 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarToggleView");
687 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
688 /* Remove main paned */
689 g_object_ref (priv->main_paned);
690 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
692 /* Reparent the contents widget to the main vbox */
693 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
695 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
696 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
697 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
700 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
701 /* Remove header view */
702 g_object_ref (priv->contents_widget);
703 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
705 /* Reparent the main paned */
706 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
707 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
709 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
710 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
711 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
715 g_return_if_reached ();
718 /* Let header view grab the focus if it's being shown */
719 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
720 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
722 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
725 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
728 ModestMainWindowStyle
729 modest_main_window_get_style (ModestMainWindow *self)
731 ModestMainWindowPrivate *priv;
733 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
735 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
742 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
744 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
745 ModestWindowPrivate *parent_priv;
746 ModestWindowMgr *mgr;
747 gboolean is_fullscreen;
748 GtkAction *fs_toggle_action;
751 mgr = modest_runtime_get_window_mgr ();
753 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
755 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
757 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
758 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
759 if (is_fullscreen != active) {
760 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
769 set_homogeneous (GtkWidget *widget,
772 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
773 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
777 modest_main_window_show_toolbar (ModestWindow *self,
778 gboolean show_toolbar)
780 ModestMainWindowPrivate *priv = NULL;
781 ModestWindowPrivate *parent_priv = NULL;
782 GtkWidget *reply_button = NULL, *menu = NULL;
783 GtkWidget *placeholder = NULL;
786 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
787 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
788 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
790 /* Set optimized view status */
791 priv->optimized_view = !show_toolbar;
793 if (!parent_priv->toolbar) {
794 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
797 /* Set homogeneous toolbar */
798 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar),
799 set_homogeneous, NULL);
801 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
802 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
803 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
804 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
805 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
806 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
807 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
808 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
810 /* Add ProgressBar (Transfer toolbar) */
811 priv->progress_bar = modest_progress_bar_widget_new ();
812 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
813 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
814 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
815 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
816 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
818 /* Connect cancel 'clicked' signal to abort progress mode */
819 g_signal_connect(priv->cancel_toolitem, "clicked",
820 G_CALLBACK(cancel_progressbar),
823 /* Add it to the observers list */
824 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
827 hildon_window_add_toolbar (HILDON_WINDOW (self),
828 GTK_TOOLBAR (parent_priv->toolbar));
830 /* Set reply button tap and hold menu */
831 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
832 "/ToolBar/ToolbarMessageReply");
833 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
835 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
837 /* Set send & receive button tap and hold menu */
838 on_account_update (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
843 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
844 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
845 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
847 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
848 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
850 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
855 compare_display_names (ModestAccountData *a,
856 ModestAccountData *b)
858 return strcmp (a->display_name, b->display_name);
862 on_account_update (TnyAccountStore *account_store,
866 GSList *account_names, *iter, *accounts;
867 ModestMainWindow *self;
868 ModestMainWindowPrivate *priv;
869 ModestWindowPrivate *parent_priv;
870 ModestAccountMgr *mgr;
871 gint i, num_accounts;
872 ModestAccountData *account_data;
873 GtkActionGroup *action_group;
875 gchar *default_account;
876 GtkWidget *send_receive_button, *item;
878 self = MODEST_MAIN_WINDOW (user_data);
879 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
880 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
882 /* Get enabled account IDs */
883 mgr = modest_runtime_get_account_mgr ();
884 account_names = modest_account_mgr_account_names (mgr, TRUE);
885 iter = account_names;
889 account_data = modest_account_mgr_get_account_data (mgr, (gchar*) iter->data);
890 accounts = g_slist_prepend (accounts, account_data);
894 g_slist_free (account_names);
896 /* Order the list of accounts by its display name */
897 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
898 num_accounts = g_slist_length (accounts);
900 /* Delete old send&receive popup items. We can not just do a
901 menu_detach because it does not work well with
903 if (priv->accounts_popup)
904 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup), (GtkCallback) gtk_widget_destroy, NULL);
906 /* Delete old entries in the View menu. Do not free groups, it
908 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
910 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
911 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
912 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
913 GTK_ACTION_GROUP (groups->data));
916 if (priv->merge_ids) {
917 for (i = 0; i < priv->merge_ids->len; i++)
918 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
919 g_byte_array_free (priv->merge_ids, TRUE);
921 /* We need to call this in order to ensure
922 that the new actions are added in the right
923 order (alphabetical */
924 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
926 groups = g_list_next (groups);
928 priv->merge_ids = g_byte_array_sized_new (num_accounts);
930 /* Get send receive button */
931 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
932 "/ToolBar/ToolbarSendReceive");
934 /* Create the menu */
935 if (num_accounts > 1) {
936 if (!priv->accounts_popup)
937 priv->accounts_popup = gtk_menu_new ();
938 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
939 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
940 g_signal_connect (G_OBJECT (item),
942 G_CALLBACK (on_send_receive_csm_activated),
944 item = gtk_separator_menu_item_new ();
945 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
948 /* Create a new action group */
949 default_account = modest_account_mgr_get_default_account (mgr);
950 action_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
951 for (i = 0; i < num_accounts; i++) {
952 GtkAction *new_action;
953 gchar* item_name, *display_name;
956 account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
958 /* Create display name. The default account is shown differently */
959 if (default_account && !(strcmp (default_account, account_data->account_name) == 0))
960 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
961 account_data->display_name);
963 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
964 account_data->display_name);
966 /* Create action and add it to the action group. The
967 action name must be the account name, this way we
968 could know in the handlers the account to show */
969 new_action = gtk_action_new (account_data->account_name, display_name, NULL, NULL);
970 gtk_action_group_add_action (action_group, new_action);
972 /* Add ui from account data. We allow 2^9-1 account
973 changes in a single execution because we're
974 downcasting the guint to a guint8 in order to use a
975 GByteArray, it should be enough */
976 item_name = g_strconcat (account_data->account_name, "Menu");
977 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
978 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
979 gtk_ui_manager_add_ui (parent_priv->ui_manager,
981 "/MenuBar/ViewMenu/ViewMenuAdditions",
983 account_data->account_name,
984 GTK_UI_MANAGER_MENUITEM,
987 /* Connect the action signal "activate" */
988 g_signal_connect (G_OBJECT (new_action),
990 G_CALLBACK (on_show_account_action_activated),
993 /* Create item and add it to the send&receive CSM */
994 item = gtk_menu_item_new_with_label (display_name);
995 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
996 g_signal_connect_data (G_OBJECT (item),
998 G_CALLBACK (on_send_receive_csm_activated),
999 g_strdup (account_data->account_name),
1000 (GClosureNotify) g_free,
1004 g_free (display_name);
1006 modest_account_mgr_free_account_data (mgr, account_data);
1008 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 1);
1010 if (priv->accounts_popup) {
1011 /* Mandatory in order to view the menu contents */
1012 gtk_widget_show_all (priv->accounts_popup);
1014 /* Setup tap_and_hold just if was not done before*/
1015 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
1016 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
1020 g_slist_free (accounts);
1021 g_free (default_account);
1025 * This function manages the key events used to navigate between
1026 * header and folder views (when the window is in split view)
1029 * -------------------------------------------------
1030 * HeaderView GDK_Left Move focus to folder view
1031 * FolderView GDK_Right Move focus to header view
1033 * There is no need to scroll to selected row, the widgets will be the
1034 * responsibles of doing that (probably managing the focus-in event
1037 on_inner_widgets_key_pressed (GtkWidget *widget,
1041 ModestMainWindowPrivate *priv;
1043 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1045 /* Do nothing if we're in SIMPLE style */
1046 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1049 if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
1050 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1051 else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1052 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1058 set_alignment (GtkWidget *widget,
1061 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1062 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1066 create_details_widget (TnyAccount *account)
1071 vbox = gtk_vbox_new (FALSE, 0);
1073 /* Account description */
1074 if (!strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1077 /* Get device name */
1078 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1079 MODEST_CONF_DEVICE_NAME, NULL);
1081 label = g_strdup_printf ("%s: %s",
1082 _("mcen_fi_localroot_description"),
1084 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1085 g_free (device_name);
1087 } else if (!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1089 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("FIXME: MMC ?"), FALSE, FALSE, 0);
1093 /* Put proto in uppercase */
1094 proto = g_string_new (tny_account_get_proto (account));
1095 proto = g_string_ascii_up (proto);
1097 label = g_strdup_printf ("%s %s: %s",
1099 _("mcen_fi_remoteroot_account"),
1100 tny_account_get_name (account));
1101 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1102 g_string_free (proto, TRUE);
1107 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_messages"),
1108 modest_tny_account_get_message_count (account));
1109 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1113 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_folders"),
1114 modest_tny_account_get_folder_count (account));
1115 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1119 if (!strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1120 /* FIXME: format size */
1121 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_size"),
1122 modest_tny_account_get_local_size (account));
1123 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1125 } else if (!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1126 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("FIXME: MMC ?"), FALSE, FALSE, 0);
1128 label = g_strdup_printf ("%s: %s", _("mcen_ti_lastupdated"), "08/08/08");
1129 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1134 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1140 modest_main_window_set_contents_style (ModestMainWindow *self,
1141 ModestMainWindowContentsStyle style)
1143 ModestMainWindowPrivate *priv;
1145 TnyAccount *account;
1147 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1149 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1151 /* We allow to set the same content style than the previously
1152 set if there are details, because it could happen when we're
1153 selecting different accounts consecutively */
1154 if ((priv->contents_style == style) &&
1155 (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS))
1158 /* Remove previous child. Delete it if it was an account
1160 content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1161 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1162 g_object_ref (content);
1163 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1165 priv->contents_style = style;
1167 switch (priv->contents_style) {
1168 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1169 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1171 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1172 /* TODO: show here account details */
1173 account = TNY_ACCOUNT (modest_folder_view_get_selected (priv->folder_view));
1174 priv->details_widget = create_details_widget (account);
1176 wrap_in_scrolled_window (priv->contents_widget,
1177 priv->details_widget);
1180 g_return_if_reached ();
1184 gtk_widget_show_all (priv->contents_widget);
1188 on_configuration_key_changed (ModestConf* conf,
1190 ModestConfEvent event,
1191 ModestMainWindow *self)
1193 ModestMainWindowPrivate *priv;
1194 TnyAccount *account;
1196 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
1199 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1201 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1204 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
1205 if (TNY_IS_ACCOUNT (account) &&
1206 !strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1209 const gchar *device_name;
1213 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
1214 label = GTK_LABEL (children->data);
1216 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1217 MODEST_CONF_DEVICE_NAME, NULL);
1219 new_text = g_strdup_printf ("%s: %s",
1220 _("mcen_fi_localroot_description"),
1223 gtk_label_set_text (label, new_text);
1224 gtk_widget_show (GTK_WIDGET (label));
1227 g_list_free (children);
1232 set_toolbar_mode (ModestMainWindow *self,
1233 ModestToolBarModes mode)
1235 ModestWindowPrivate *parent_priv = NULL;
1236 ModestMainWindowPrivate *priv = NULL;
1237 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
1239 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1241 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1242 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1244 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
1246 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1247 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1248 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1250 /* Sets current toolbar mode */
1251 priv->current_toolbar_mode = mode;
1253 /* Show and hide toolbar items */
1255 case TOOLBAR_MODE_NORMAL:
1257 gtk_action_set_visible (sort_action, TRUE);
1259 gtk_action_set_visible (refresh_action, TRUE);
1260 if (priv->progress_toolitem) {
1261 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1262 gtk_widget_hide (priv->progress_toolitem);
1264 if (priv->progress_bar)
1265 gtk_widget_hide (priv->progress_bar);
1268 gtk_action_set_visible (cancel_action, FALSE);
1270 /* Hide toolbar if optimized view is enabled */
1271 if (priv->optimized_view)
1272 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
1274 case TOOLBAR_MODE_TRANSFER:
1276 gtk_action_set_visible (sort_action, FALSE);
1278 gtk_action_set_visible (refresh_action, FALSE);
1280 gtk_action_set_visible (cancel_action, TRUE);
1281 if (priv->progress_toolitem) {
1282 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1283 gtk_widget_show (priv->progress_toolitem);
1285 if (priv->progress_bar)
1286 gtk_widget_show (priv->progress_bar);
1288 /* Show toolbar if it's hiden (optimized view ) */
1289 if (priv->optimized_view)
1290 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1293 g_return_if_reached ();
1298 cancel_progressbar (GtkToolButton *toolbutton,
1299 ModestMainWindow *self)
1302 ModestMainWindowPrivate *priv;
1304 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1306 /* Get operation observers and cancel its current operation */
1307 tmp = priv->progress_widgets;
1309 modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
1310 tmp=g_slist_next(tmp);
1315 observers_empty (ModestMainWindow *self)
1318 ModestMainWindowPrivate *priv;
1319 gboolean is_empty = TRUE;
1320 guint pending_ops = 0;
1322 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1323 tmp = priv->progress_widgets;
1325 /* Check all observers */
1326 while (tmp && is_empty) {
1327 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
1328 is_empty = pending_ops == 0;
1330 tmp = g_slist_next(tmp);
1337 on_queue_changed (ModestMailOperationQueue *queue,
1338 ModestMailOperation *mail_op,
1339 ModestMailOperationQueueNotification type,
1340 ModestMainWindow *self)
1342 ModestMainWindowPrivate *priv;
1343 ModestMailOperationId op_id;
1344 ModestToolBarModes mode;
1346 gboolean mode_changed = FALSE;
1348 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1349 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1351 /* Get toolbar mode from operation id*/
1352 op_id = modest_mail_operation_get_id (mail_op);
1354 case MODEST_MAIL_OPERATION_ID_SEND:
1355 case MODEST_MAIL_OPERATION_ID_RECEIVE:
1356 mode = TOOLBAR_MODE_TRANSFER;
1357 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
1358 mode_changed = TRUE;
1361 mode = TOOLBAR_MODE_NORMAL;
1366 /* Add operation observers and change toolbar if neccessary*/
1367 tmp = priv->progress_widgets;
1369 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
1371 set_toolbar_mode (self, mode);
1372 if (mode == TOOLBAR_MODE_TRANSFER) {
1374 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1376 tmp = g_slist_next (tmp);
1380 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
1381 if (mode == TOOLBAR_MODE_TRANSFER) {
1384 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1386 tmp = g_slist_next (tmp);
1389 /* If no more operations are being observed, NORMAL mode is enabled again */
1390 if (observers_empty (self))
1391 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
1398 on_show_account_action_activated (GtkAction *action,
1401 ModestAccountData *acc_data;
1402 ModestMainWindow *self;
1403 ModestMainWindowPrivate *priv;
1404 ModestAccountMgr *mgr;
1405 const gchar *acc_name;
1407 self = MODEST_MAIN_WINDOW (user_data);
1408 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1410 /* Get account data */
1411 acc_name = gtk_action_get_name (action);
1412 mgr = modest_runtime_get_account_mgr ();
1413 acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
1415 /* Set the new visible & active account */
1416 if (acc_data->store_account) {
1417 modest_folder_view_set_account_id_of_visible_server_account (priv->folder_view,
1418 acc_data->store_account->account_name);
1422 modest_account_mgr_free_account_data (mgr, acc_data);
1426 on_send_receive_csm_activated (GtkMenuItem *item,
1431 win = MODEST_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
1433 /* If user_data == NULL, we must update all (CSM option All) */
1435 modest_ui_actions_do_send_receive_all (win);
1437 modest_ui_actions_do_send_receive ((const gchar *)user_data, win);