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 /* This is the context sensitive menu: */
179 static const GtkActionEntry modest_folder_view_action_entries [] = {
181 /* Folder View CSM actions */
182 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
183 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
184 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, NULL },
185 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
186 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, NULL },
187 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, NULL },
191 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
192 { "ToolbarToggleView", MODEST_STOCK_SPLIT_VIEW, N_("gqn_toolb_rss_fldonoff"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), FALSE },
195 /************************************************************************/
198 modest_main_window_get_type (void)
200 static GType my_type = 0;
202 static const GTypeInfo my_info = {
203 sizeof(ModestMainWindowClass),
204 NULL, /* base init */
205 NULL, /* base finalize */
206 (GClassInitFunc) modest_main_window_class_init,
207 NULL, /* class finalize */
208 NULL, /* class data */
209 sizeof(ModestMainWindow),
211 (GInstanceInitFunc) modest_main_window_init,
214 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
222 modest_main_window_class_init (ModestMainWindowClass *klass)
224 GObjectClass *gobject_class;
225 gobject_class = (GObjectClass*) klass;
226 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
228 parent_class = g_type_class_peek_parent (klass);
229 gobject_class->finalize = modest_main_window_finalize;
231 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
233 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
234 modest_window_class->save_state_func = save_state;
238 modest_main_window_init (ModestMainWindow *obj)
240 ModestMainWindowPrivate *priv;
242 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
244 priv->msg_paned = NULL;
245 priv->main_paned = NULL;
246 priv->main_vbox = NULL;
247 priv->header_view = NULL;
248 priv->folder_view = NULL;
249 priv->contents_widget = NULL;
250 priv->accounts_popup = NULL;
251 priv->details_widget = NULL;
253 priv->progress_widgets = NULL;
254 priv->progress_bar = NULL;
255 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
257 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
258 priv->contents_style = MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS;
260 priv->merge_ids = NULL;
262 priv->optimized_view = FALSE;
263 priv->progress_bar_timeout = 0;
267 modest_main_window_finalize (GObject *obj)
269 ModestMainWindowPrivate *priv;
271 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
273 g_slist_free (priv->progress_widgets);
275 g_byte_array_free (priv->merge_ids, TRUE);
277 if (priv->progress_bar_timeout > 0) {
278 g_source_remove (priv->progress_bar_timeout);
279 priv->progress_bar_timeout = 0;
282 G_OBJECT_CLASS(parent_class)->finalize (obj);
286 modest_main_window_get_child_widget (ModestMainWindow *self,
287 ModestWidgetType widget_type)
289 ModestMainWindowPrivate *priv;
292 g_return_val_if_fail (self, NULL);
293 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_WIDGET_TYPE_NUM,
296 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
298 switch (widget_type) {
299 case MODEST_WIDGET_TYPE_HEADER_VIEW:
300 widget = (GtkWidget*)priv->header_view; break;
301 case MODEST_WIDGET_TYPE_FOLDER_VIEW:
302 widget = (GtkWidget*)priv->folder_view; break;
307 return widget ? GTK_WIDGET(widget) : NULL;
313 restore_settings (ModestMainWindow *self)
316 ModestMainWindowPrivate *priv;
318 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
320 conf = modest_runtime_get_conf ();
322 modest_widget_memory_restore (conf, G_OBJECT(self),
323 MODEST_CONF_MAIN_WINDOW_KEY);
324 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
325 MODEST_CONF_MAIN_PANED_KEY);
326 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
327 MODEST_CONF_HEADER_VIEW_KEY);
332 save_state (ModestWindow *window)
335 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
336 ModestMainWindowPrivate *priv;
338 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
339 conf = modest_runtime_get_conf ();
341 modest_widget_memory_save (conf,G_OBJECT(self),
342 MODEST_CONF_MAIN_WINDOW_KEY);
343 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
344 MODEST_CONF_MAIN_PANED_KEY);
345 modest_widget_memory_save (conf, G_OBJECT(priv->header_view),
346 MODEST_CONF_HEADER_VIEW_KEY);
350 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
352 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
353 gtk_scrolled_window_add_with_viewport
354 (GTK_SCROLLED_WINDOW(win), widget);
356 gtk_container_add (GTK_CONTAINER(win),
362 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self)
364 modest_window_save_state (MODEST_WINDOW(self));
370 on_connection_changed (TnyDevice *device, gboolean online, ModestMainWindow *self)
372 /* When going online, do the equivalent of pressing the send/receive button,
373 * as per the specification:
374 * (without the check for >0 accounts, though that is not specified): */
376 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (self));
383 connect_signals (ModestMainWindow *self)
385 ModestWindowPrivate *parent_priv;
386 ModestMainWindowPrivate *priv;
389 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
390 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
393 g_signal_connect (G_OBJECT(priv->folder_view), "key-press-event",
394 G_CALLBACK(on_inner_widgets_key_pressed), self);
395 g_signal_connect (G_OBJECT(priv->folder_view), "folder_selection_changed",
396 G_CALLBACK(modest_ui_actions_on_folder_selection_changed), self);
397 g_signal_connect (G_OBJECT(priv->folder_view), "folder-display-name-changed",
398 G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
400 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
401 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
404 /* g_signal_connect (G_OBJECT(priv->header_view), "status_update", */
405 /* G_CALLBACK(modest_ui_actions_on_header_status_update), self); */
406 g_signal_connect (G_OBJECT(priv->header_view), "header_selected",
407 G_CALLBACK(modest_ui_actions_on_header_selected), self);
408 g_signal_connect (G_OBJECT(priv->header_view), "header_activated",
409 G_CALLBACK(modest_ui_actions_on_header_activated), self);
410 g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
411 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
412 g_signal_connect (G_OBJECT(priv->header_view), "key-press-event",
413 G_CALLBACK(on_inner_widgets_key_pressed), self);
416 g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
417 g_signal_connect (G_OBJECT (self), "window-state-event",
418 G_CALLBACK (modest_main_window_window_state_event),
420 g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
422 /* Mail Operation Queue */
423 g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
425 G_CALLBACK (on_queue_changed),
428 /* Track changes in the device name */
429 g_signal_connect (G_OBJECT(modest_runtime_get_conf ()),
431 G_CALLBACK (on_configuration_key_changed),
434 /* Track account changes. We need to refresh the toolbar */
435 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
437 G_CALLBACK (on_account_update),
441 g_signal_connect (G_OBJECT (modest_runtime_get_account_store()), "password_requested",
442 G_CALLBACK (modest_ui_actions_on_password_requested), self);
445 g_signal_connect (G_OBJECT(modest_runtime_get_device()), "connection_changed",
446 G_CALLBACK(on_connection_changed), self);
449 /** Idle handler, to send/receive at startup .*/
451 sync_accounts_cb (ModestMainWindow *win)
453 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (win));
454 return FALSE; /* Do not call this idle handler again. */
457 static void on_hildon_program_is_topmost_notify(GObject *self,
458 GParamSpec *propert_param, gpointer user_data)
460 HildonProgram *app = HILDON_PROGRAM (self);
463 ModestWindow* self = MODEST_WINDOW(user_data);
466 /* Note that use of hildon_program_set_can_hibernate()
467 * is generally referred to as "setting the killable flag",
468 * though hibernation does not seem equal to death.
471 if (hildon_program_get_is_topmost (app)) {
472 /* Prevent hibernation when the progam comes to the foreground,
473 * because hibernation should only happen when the application
474 * is in the background: */
475 hildon_program_set_can_hibernate (app, FALSE);
477 /* Allow hibernation if the program has gone to the background: */
479 /* However, prevent hibernation while the settings are being changed: */
480 const gboolean hibernation_prevented =
481 modest_window_mgr_get_hibernation_is_prevented (
482 modest_runtime_get_window_mgr ());
484 if (hibernation_prevented)
485 hildon_program_set_can_hibernate (app, FALSE);
487 /* Allow hibernation, after saving the state: */
488 modest_osso_save_state();
489 hildon_program_set_can_hibernate (app, TRUE);
498 modest_main_window_new (void)
500 ModestMainWindow *self;
501 ModestMainWindowPrivate *priv;
502 ModestWindowPrivate *parent_priv;
503 GtkWidget *folder_win;
504 GtkActionGroup *action_group;
505 GError *error = NULL;
506 TnyFolderStoreQuery *query;
507 GdkPixbuf *window_icon;
511 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
512 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
513 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
515 parent_priv->ui_manager = gtk_ui_manager_new();
516 action_group = gtk_action_group_new ("ModestMainWindowActions");
517 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
519 /* Add common actions */
520 gtk_action_group_add_actions (action_group,
521 modest_action_entries,
522 G_N_ELEMENTS (modest_action_entries),
525 gtk_action_group_add_actions (action_group,
526 modest_folder_view_action_entries,
527 G_N_ELEMENTS (modest_folder_view_action_entries),
530 gtk_action_group_add_toggle_actions (action_group,
531 modest_toggle_action_entries,
532 G_N_ELEMENTS (modest_toggle_action_entries),
535 gtk_action_group_add_toggle_actions (action_group,
536 modest_main_window_toggle_action_entries,
537 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
540 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
541 g_object_unref (action_group);
543 /* Load the UI definition */
544 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
545 MODEST_UIDIR "modest-main-window-ui.xml", &error);
547 g_warning ("Could not merge modest-ui.xml: %s", error->message);
548 g_error_free (error);
552 /* Add accelerators */
553 gtk_window_add_accel_group (GTK_WINDOW (self),
554 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
556 /* Menubar. Update the state of some toggles */
557 parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
558 conf = modest_runtime_get_conf ();
559 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
560 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
561 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
562 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL));
563 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
564 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
565 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
566 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL));
567 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
569 /* Get device name */
570 modest_maemo_utils_get_device_name ();
573 query = tny_folder_store_query_new ();
574 tny_folder_store_query_add_item (query, NULL,
575 TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
576 priv->folder_view = MODEST_FOLDER_VIEW(modest_folder_view_new (query));
577 if (!priv->folder_view)
578 g_printerr ("modest: cannot instantiate folder view\n");
579 g_object_unref (G_OBJECT (query));
580 modest_folder_view_set_style (priv->folder_view,
581 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
585 MODEST_HEADER_VIEW(modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
586 if (!priv->header_view)
587 g_printerr ("modest: cannot instantiate header view\n");
588 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
590 /* Create scrolled windows */
591 folder_win = gtk_scrolled_window_new (NULL, NULL);
592 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
593 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
595 GTK_POLICY_AUTOMATIC);
596 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
598 GTK_POLICY_AUTOMATIC);
600 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
601 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view));
604 priv->main_paned = gtk_hpaned_new ();
605 gtk_paned_add1 (GTK_PANED(priv->main_paned), folder_win);
606 gtk_paned_add2 (GTK_PANED(priv->main_paned), priv->contents_widget);
607 gtk_widget_show (GTK_WIDGET(priv->header_view));
608 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
610 /* putting it all together... */
611 priv->main_vbox = gtk_vbox_new (FALSE, 6);
612 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
614 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
615 restore_settings (MODEST_MAIN_WINDOW(self));
617 /* Set window icon */
618 window_icon = modest_platform_get_icon (MODEST_APP_ICON);
619 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
621 /* Connect signals */
622 connect_signals (self);
624 /* Set account store */
625 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
626 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
628 /* do send & receive when we are idle */
629 g_idle_add ((GSourceFunc)sync_accounts_cb, self);
631 HildonProgram *app = hildon_program_get_instance ();
632 hildon_program_add_window (app, HILDON_WINDOW (self));
634 /* Register HildonProgram signal handlers: */
635 /* These are apparently deprecated, according to the
636 * "HildonApp/HildonAppView to HildonProgram/HildonWindow migration guide",
637 * though the API reference does not mention that:
639 g_signal_connect (G_OBJECT(app), "topmost_status_lose",
640 G_CALLBACK (on_hildon_program_save_state), self);
641 g_signal_connect (G_OBJECT(app), "topmost_status_acquire",
642 G_CALLBACK (on_hildon_program_status_acquire), self);
644 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
645 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
647 /* Load previous osso state, for instance if we are being restored from
649 modest_osso_load_state();
651 return MODEST_WINDOW(self);
655 modest_main_window_close_all (ModestMainWindow *self)
658 GtkResponseType response;
660 /* Create the confirmation dialog MSG-NOT308 */
661 note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
662 _("emev_nc_close_windows"),
663 _("mcen_bd_yes"), GTK_RESPONSE_YES,
664 _("mcen_bd_no"), GTK_RESPONSE_NO,
667 response = gtk_dialog_run (GTK_DIALOG (note));
668 gtk_widget_destroy (GTK_WIDGET (note));
670 if (response == GTK_RESPONSE_YES)
678 modest_main_window_set_style (ModestMainWindow *self,
679 ModestMainWindowStyle style)
681 ModestMainWindowPrivate *priv;
682 ModestWindowPrivate *parent_priv;
685 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
687 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
688 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
690 /* no change -> nothing to do */
691 if (priv->style == style)
694 /* Get toggle button */
695 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarToggleView");
700 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
701 /* Remove main paned */
702 g_object_ref (priv->main_paned);
703 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
705 /* Reparent the contents widget to the main vbox */
706 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
708 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
709 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
710 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
713 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
714 /* Remove header view */
715 g_object_ref (priv->contents_widget);
716 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
718 /* Reparent the main paned */
719 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
720 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
722 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
723 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
724 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
728 g_return_if_reached ();
731 /* Let header view grab the focus if it's being shown */
732 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
733 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
735 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
738 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
741 ModestMainWindowStyle
742 modest_main_window_get_style (ModestMainWindow *self)
744 ModestMainWindowPrivate *priv;
746 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
748 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
755 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
757 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
758 ModestWindowPrivate *parent_priv;
759 ModestWindowMgr *mgr;
760 gboolean is_fullscreen;
761 GtkAction *fs_toggle_action;
764 mgr = modest_runtime_get_window_mgr ();
766 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
768 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
770 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
771 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
772 if (is_fullscreen != active) {
773 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
782 set_homogeneous (GtkWidget *widget,
785 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
786 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
790 modest_main_window_show_toolbar (ModestWindow *self,
791 gboolean show_toolbar)
793 ModestMainWindowPrivate *priv = NULL;
794 ModestWindowPrivate *parent_priv = NULL;
795 GtkWidget *reply_button = NULL, *menu = NULL;
796 GtkWidget *placeholder = NULL;
799 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
800 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
801 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
803 /* Set optimized view status */
804 priv->optimized_view = !show_toolbar;
806 if (!parent_priv->toolbar) {
807 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
810 /* Set homogeneous toolbar */
811 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar),
812 set_homogeneous, NULL);
814 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
815 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
816 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
817 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
818 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
819 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
820 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
821 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
823 /* Add ProgressBar (Transfer toolbar) */
824 priv->progress_bar = modest_progress_bar_widget_new ();
825 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
826 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
827 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
828 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
829 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
831 /* Connect cancel 'clicked' signal to abort progress mode */
832 g_signal_connect(priv->cancel_toolitem, "clicked",
833 G_CALLBACK(cancel_progressbar),
836 /* Add it to the observers list */
837 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
840 hildon_window_add_toolbar (HILDON_WINDOW (self),
841 GTK_TOOLBAR (parent_priv->toolbar));
843 /* Set reply button tap and hold menu */
844 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
845 "/ToolBar/ToolbarMessageReply");
846 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
848 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
850 /* Set send & receive button tap and hold menu */
851 on_account_update (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
856 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
857 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
858 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
860 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
861 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
863 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
868 compare_display_names (ModestAccountData *a,
869 ModestAccountData *b)
871 return strcmp (a->display_name, b->display_name);
875 on_account_update (TnyAccountStore *account_store,
876 const gchar *account_name,
879 GSList *account_names, *iter, *accounts;
880 ModestMainWindow *self;
881 ModestMainWindowPrivate *priv;
882 ModestWindowPrivate *parent_priv;
883 ModestAccountMgr *mgr;
884 gint i, num_accounts;
885 GtkActionGroup *action_group;
887 gchar *default_account;
888 GtkWidget *send_receive_button, *item;
890 self = MODEST_MAIN_WINDOW (user_data);
891 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
892 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
894 /* Get enabled account IDs */
895 mgr = modest_runtime_get_account_mgr ();
896 account_names = modest_account_mgr_account_names (mgr, TRUE);
897 iter = account_names;
901 ModestAccountData *account_data =
902 modest_account_mgr_get_account_data (mgr, (gchar*) iter->data);
903 accounts = g_slist_prepend (accounts, account_data);
907 g_slist_free (account_names);
909 /* Order the list of accounts by its display name */
910 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
911 num_accounts = g_slist_length (accounts);
913 /* Delete old send&receive popup items. We can not just do a
914 menu_detach because it does not work well with
916 if (priv->accounts_popup)
917 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup), (GtkCallback) gtk_widget_destroy, NULL);
919 /* Delete old entries in the View menu. Do not free groups, it
921 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
923 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
924 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
925 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
926 GTK_ACTION_GROUP (groups->data));
929 if (priv->merge_ids) {
930 for (i = 0; i < priv->merge_ids->len; i++)
931 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
932 g_byte_array_free (priv->merge_ids, TRUE);
934 /* We need to call this in order to ensure
935 that the new actions are added in the right
936 order (alphabetical */
937 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
939 groups = g_list_next (groups);
941 priv->merge_ids = g_byte_array_sized_new (num_accounts);
943 /* Get send receive button */
944 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
945 "/ToolBar/ToolbarSendReceive");
947 /* Create the menu */
948 if (num_accounts > 1) {
949 if (!priv->accounts_popup)
950 priv->accounts_popup = gtk_menu_new ();
951 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
952 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
953 g_signal_connect (G_OBJECT (item),
955 G_CALLBACK (on_send_receive_csm_activated),
957 item = gtk_separator_menu_item_new ();
958 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
961 /* Create a new action group */
962 default_account = modest_account_mgr_get_default_account (mgr);
963 action_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
964 for (i = 0; i < num_accounts; i++) {
965 GtkAction *new_action = NULL;
966 gchar *display_name = NULL;
968 ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
970 /* Create display name. The default account is shown differently */
971 if (default_account && account_data->account_name &&
972 !(strcmp (default_account, account_data->account_name) == 0)) {
973 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
974 account_data->display_name);
977 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
978 account_data->display_name);
981 /* Create action and add it to the action group. The
982 action name must be the account name, this way we
983 could know in the handlers the account to show */
984 if(account_data->account_name) {
985 new_action = gtk_action_new (account_data->account_name, display_name, NULL, NULL);
986 gtk_action_group_add_action (action_group, new_action);
988 /* Add ui from account data. We allow 2^9-1 account
989 changes in a single execution because we're
990 downcasting the guint to a guint8 in order to use a
991 GByteArray, it should be enough */
992 gchar* item_name = g_strconcat (account_data->account_name, "Menu", NULL);
993 guint8 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
994 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
995 gtk_ui_manager_add_ui (parent_priv->ui_manager,
997 "/MenuBar/ViewMenu/ViewMenuAdditions",
999 account_data->account_name,
1000 GTK_UI_MANAGER_MENUITEM,
1003 /* Connect the action signal "activate" */
1004 g_signal_connect (G_OBJECT (new_action),
1006 G_CALLBACK (on_show_account_action_activated),
1009 /* Create item and add it to the send&receive CSM */
1010 /* TODO: Why is this sometimes NULL? murrayc */
1011 if (priv->accounts_popup) {
1012 item = gtk_menu_item_new_with_label (display_name);
1013 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1014 g_signal_connect_data (G_OBJECT (item),
1016 G_CALLBACK (on_send_receive_csm_activated),
1017 g_strdup (account_data->account_name),
1018 (GClosureNotify) g_free,
1026 g_free (display_name);
1027 modest_account_mgr_free_account_data (mgr, account_data);
1029 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 1);
1031 if (priv->accounts_popup) {
1032 /* Mandatory in order to view the menu contents */
1033 gtk_widget_show_all (priv->accounts_popup);
1035 /* Setup tap_and_hold just if was not done before*/
1036 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
1037 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
1041 g_slist_free (accounts);
1042 g_free (default_account);
1046 * This function manages the key events used to navigate between
1047 * header and folder views (when the window is in split view)
1050 * -------------------------------------------------
1051 * HeaderView GDK_Left Move focus to folder view
1052 * FolderView GDK_Right Move focus to header view
1054 * There is no need to scroll to selected row, the widgets will be the
1055 * responsibles of doing that (probably managing the focus-in event
1058 on_inner_widgets_key_pressed (GtkWidget *widget,
1062 ModestMainWindowPrivate *priv;
1064 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1066 /* Do nothing if we're in SIMPLE style */
1067 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1070 if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
1071 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1072 else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1073 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1079 set_alignment (GtkWidget *widget,
1082 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1083 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1087 create_details_widget (TnyAccount *account)
1092 vbox = gtk_vbox_new (FALSE, 0);
1094 /* Account description */
1095 if (!strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1098 /* Get device name */
1099 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1100 MODEST_CONF_DEVICE_NAME, NULL);
1102 label = g_strdup_printf ("%s: %s",
1103 _("mcen_fi_localroot_description"),
1105 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1106 g_free (device_name);
1108 } else if (!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1110 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("FIXME: MMC ?"), FALSE, FALSE, 0);
1114 /* Put proto in uppercase */
1115 proto = g_string_new (tny_account_get_proto (account));
1116 proto = g_string_ascii_up (proto);
1118 label = g_strdup_printf ("%s %s: %s",
1120 _("mcen_fi_remoteroot_account"),
1121 tny_account_get_name (account));
1122 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1123 g_string_free (proto, TRUE);
1128 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_messages"),
1129 modest_tny_account_get_message_count (account));
1130 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1134 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_folders"),
1135 modest_tny_account_get_folder_count (account));
1136 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1140 if (!strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1141 /* FIXME: format size */
1142 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_size"),
1143 modest_tny_account_get_local_size (account));
1144 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1146 } else if (!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1147 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("FIXME: MMC ?"), FALSE, FALSE, 0);
1149 time_t last_updated;
1150 gchar *last_updated_string;
1151 /* Get last updated from configuration */
1152 last_updated = modest_account_mgr_get_int (modest_runtime_get_account_mgr (),
1153 tny_account_get_id (account),
1154 MODEST_ACCOUNT_LAST_UPDATED,
1156 if (last_updated > 0)
1157 last_updated_string = modest_text_utils_get_display_date(last_updated);
1159 last_updated_string = g_strdup (_("FIXME: Never"));
1161 label = g_strdup_printf ("%s: %s", _("mcen_ti_lastupdated"), last_updated_string);
1162 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1163 g_free (last_updated_string);
1168 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1174 modest_main_window_set_contents_style (ModestMainWindow *self,
1175 ModestMainWindowContentsStyle style)
1177 ModestMainWindowPrivate *priv;
1179 TnyAccount *account;
1181 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1183 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1185 /* We allow to set the same content style than the previously
1186 set if there are details, because it could happen when we're
1187 selecting different accounts consecutively */
1188 if ((priv->contents_style == style) &&
1189 (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS))
1192 /* Remove previous child. Delete it if it was an account
1194 content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1195 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1196 g_object_ref (content);
1197 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1199 priv->contents_style = style;
1201 switch (priv->contents_style) {
1202 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1203 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1205 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1206 /* TODO: show here account details */
1207 account = TNY_ACCOUNT (modest_folder_view_get_selected (priv->folder_view));
1208 priv->details_widget = create_details_widget (account);
1210 wrap_in_scrolled_window (priv->contents_widget,
1211 priv->details_widget);
1214 g_return_if_reached ();
1218 gtk_widget_show_all (priv->contents_widget);
1222 on_configuration_key_changed (ModestConf* conf,
1224 ModestConfEvent event,
1225 ModestMainWindow *self)
1227 ModestMainWindowPrivate *priv;
1228 TnyAccount *account;
1230 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
1233 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1235 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1238 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
1239 if (TNY_IS_ACCOUNT (account) &&
1240 !strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1243 const gchar *device_name;
1247 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
1248 label = GTK_LABEL (children->data);
1250 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1251 MODEST_CONF_DEVICE_NAME, NULL);
1253 new_text = g_strdup_printf ("%s: %s",
1254 _("mcen_fi_localroot_description"),
1257 gtk_label_set_text (label, new_text);
1258 gtk_widget_show (GTK_WIDGET (label));
1261 g_list_free (children);
1266 set_toolbar_transfer_mode (ModestMainWindow *self)
1268 ModestMainWindowPrivate *priv = NULL;
1270 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1272 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1274 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
1276 if (priv->progress_bar_timeout > 0) {
1277 g_source_remove (priv->progress_bar_timeout);
1278 priv->progress_bar_timeout = 0;
1285 set_toolbar_mode (ModestMainWindow *self,
1286 ModestToolBarModes mode)
1288 ModestWindowPrivate *parent_priv = NULL;
1289 ModestMainWindowPrivate *priv = NULL;
1290 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
1292 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1294 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1295 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1297 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
1299 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1300 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1301 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1303 /* Sets current toolbar mode */
1304 priv->current_toolbar_mode = mode;
1306 /* Show and hide toolbar items */
1308 case TOOLBAR_MODE_NORMAL:
1310 gtk_action_set_visible (sort_action, TRUE);
1312 gtk_action_set_visible (refresh_action, TRUE);
1313 if (priv->progress_toolitem) {
1314 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1315 gtk_widget_hide (priv->progress_toolitem);
1317 if (priv->progress_bar)
1318 gtk_widget_hide (priv->progress_bar);
1321 gtk_action_set_visible (cancel_action, FALSE);
1323 /* Hide toolbar if optimized view is enabled */
1324 if (priv->optimized_view)
1325 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
1327 case TOOLBAR_MODE_TRANSFER:
1329 gtk_action_set_visible (sort_action, FALSE);
1331 gtk_action_set_visible (refresh_action, FALSE);
1333 gtk_action_set_visible (cancel_action, TRUE);
1334 if (priv->progress_toolitem) {
1335 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1336 gtk_widget_show (priv->progress_toolitem);
1338 if (priv->progress_bar)
1339 gtk_widget_show (priv->progress_bar);
1341 /* Show toolbar if it's hiden (optimized view ) */
1342 if (priv->optimized_view)
1343 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1346 g_return_if_reached ();
1351 cancel_progressbar (GtkToolButton *toolbutton,
1352 ModestMainWindow *self)
1355 ModestMainWindowPrivate *priv;
1357 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1359 /* Get operation observers and cancel its current operation */
1360 tmp = priv->progress_widgets;
1362 modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
1363 tmp=g_slist_next(tmp);
1368 observers_empty (ModestMainWindow *self)
1371 ModestMainWindowPrivate *priv;
1372 gboolean is_empty = TRUE;
1373 guint pending_ops = 0;
1375 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1376 tmp = priv->progress_widgets;
1378 /* Check all observers */
1379 while (tmp && is_empty) {
1380 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
1381 is_empty = pending_ops == 0;
1383 tmp = g_slist_next(tmp);
1390 on_queue_changed (ModestMailOperationQueue *queue,
1391 ModestMailOperation *mail_op,
1392 ModestMailOperationQueueNotification type,
1393 ModestMainWindow *self)
1395 ModestMainWindowPrivate *priv;
1396 ModestMailOperationId op_id;
1397 ModestToolBarModes mode;
1399 gboolean mode_changed = FALSE;
1400 ModestMailOperationStatus status;
1402 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1403 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1405 /* Get toolbar mode from operation id*/
1406 op_id = modest_mail_operation_get_id (mail_op);
1408 case MODEST_MAIL_OPERATION_ID_SEND:
1409 case MODEST_MAIL_OPERATION_ID_RECEIVE:
1410 mode = TOOLBAR_MODE_TRANSFER;
1411 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
1412 mode_changed = TRUE;
1415 mode = TOOLBAR_MODE_NORMAL;
1420 /* Add operation observers and change toolbar if neccessary*/
1421 tmp = priv->progress_widgets;
1423 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
1424 if (mode == TOOLBAR_MODE_TRANSFER) {
1426 set_toolbar_transfer_mode(self);
1428 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1430 tmp = g_slist_next (tmp);
1434 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
1435 /* If mail_op is mine, check errors */
1436 status = modest_mail_operation_get_status (mail_op);
1437 if (status != MODEST_MAIL_OPERATION_STATUS_SUCCESS)
1438 modest_mail_operation_execute_error_handler (mail_op);
1440 /* Change toolbar mode */
1441 if (mode == TOOLBAR_MODE_TRANSFER) {
1443 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1445 tmp = g_slist_next (tmp);
1448 /* If no more operations are being observed, NORMAL mode is enabled again */
1449 if (observers_empty (self)) {
1450 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
1461 on_show_account_action_activated (GtkAction *action,
1464 ModestAccountData *acc_data;
1465 ModestMainWindow *self;
1466 ModestMainWindowPrivate *priv;
1467 ModestAccountMgr *mgr;
1468 const gchar *acc_name;
1470 self = MODEST_MAIN_WINDOW (user_data);
1471 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1473 /* Get account data */
1474 acc_name = gtk_action_get_name (action);
1475 mgr = modest_runtime_get_account_mgr ();
1476 acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
1478 /* Set the new visible & active account */
1479 if (acc_data->store_account) {
1480 modest_folder_view_set_account_id_of_visible_server_account (priv->folder_view,
1481 acc_data->store_account->account_name);
1482 modest_window_set_active_account (MODEST_WINDOW (self), acc_data->account_name);
1486 modest_account_mgr_free_account_data (mgr, acc_data);
1490 on_send_receive_csm_activated (GtkMenuItem *item,
1495 win = MODEST_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
1497 /* If user_data == NULL, we must update all (CSM option All) */
1499 modest_ui_actions_do_send_receive_all (win);
1501 modest_ui_actions_do_send_receive ((const gchar *)user_data, win);