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 /* list my signals */
117 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
118 struct _ModestMainWindowPrivate {
119 GtkWidget *msg_paned;
120 GtkWidget *main_paned;
121 GtkWidget *main_vbox;
122 GtkWidget *contents_widget;
124 /* Progress observers */
125 GtkWidget *progress_bar;
126 GSList *progress_widgets;
129 GtkWidget *progress_toolitem;
130 GtkWidget *cancel_toolitem;
131 GtkWidget *sort_toolitem;
132 GtkWidget *refresh_toolitem;
133 ModestToolBarModes current_toolbar_mode;
135 /* Merge ids used to add/remove accounts to the ViewMenu*/
136 GByteArray *merge_ids;
138 /* On-demand widgets */
139 GtkWidget *accounts_popup;
140 GtkWidget *details_widget;
142 /* Optimized view enabled */
143 gboolean optimized_view;
145 ModestHeaderView *header_view;
146 ModestFolderView *folder_view;
148 ModestMainWindowStyle style;
149 ModestMainWindowContentsStyle contents_style;
151 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
152 MODEST_TYPE_MAIN_WINDOW, \
153 ModestMainWindowPrivate))
155 typedef struct _GetMsgAsyncHelper {
156 ModestMainWindowPrivate *main_window_private;
158 ModestTnyMsgReplyType reply_type;
159 ModestTnyMsgForwardType forward_type;
166 static GtkWindowClass *parent_class = NULL;
169 /* Private actions */
170 static const GtkActionEntry modest_folder_view_action_entries [] = {
172 /* Folder View CSM actions */
173 { "FolderViewCSMNewFolder", NULL, N_("FIXME: New Folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
174 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
175 { "FolderViewCSMPasteMsgs", NULL, N_("FIXME: Paste"), NULL, NULL, NULL },
176 { "FolderViewCSMDeleteFolder", NULL, N_("FIXME: Delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
177 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, NULL },
178 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, NULL },
182 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
183 { "ToolbarToggleView", MODEST_STOCK_SPLIT_VIEW, N_("gqn_toolb_rss_fldonoff"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), FALSE },
186 /************************************************************************/
189 modest_main_window_get_type (void)
191 static GType my_type = 0;
193 static const GTypeInfo my_info = {
194 sizeof(ModestMainWindowClass),
195 NULL, /* base init */
196 NULL, /* base finalize */
197 (GClassInitFunc) modest_main_window_class_init,
198 NULL, /* class finalize */
199 NULL, /* class data */
200 sizeof(ModestMainWindow),
202 (GInstanceInitFunc) modest_main_window_init,
205 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
213 modest_main_window_class_init (ModestMainWindowClass *klass)
215 GObjectClass *gobject_class;
216 gobject_class = (GObjectClass*) klass;
217 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
219 parent_class = g_type_class_peek_parent (klass);
220 gobject_class->finalize = modest_main_window_finalize;
222 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
224 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
225 modest_window_class->save_state_func = save_state;
229 modest_main_window_init (ModestMainWindow *obj)
231 ModestMainWindowPrivate *priv;
233 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
235 priv->msg_paned = NULL;
236 priv->main_paned = NULL;
237 priv->main_vbox = NULL;
238 priv->header_view = NULL;
239 priv->folder_view = NULL;
240 priv->contents_widget = NULL;
241 priv->accounts_popup = NULL;
242 priv->details_widget = NULL;
244 priv->optimized_view = FALSE;
246 priv->progress_widgets = NULL;
247 priv->progress_bar = NULL;
248 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
250 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
251 priv->contents_style = MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS;
253 priv->merge_ids = NULL;
257 modest_main_window_finalize (GObject *obj)
259 ModestMainWindowPrivate *priv;
261 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
263 g_slist_free (priv->progress_widgets);
265 g_byte_array_free (priv->merge_ids, TRUE);
267 G_OBJECT_CLASS(parent_class)->finalize (obj);
271 modest_main_window_get_child_widget (ModestMainWindow *self,
272 ModestWidgetType widget_type)
274 ModestMainWindowPrivate *priv;
277 g_return_val_if_fail (self, NULL);
278 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_WIDGET_TYPE_NUM,
281 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
283 switch (widget_type) {
284 case MODEST_WIDGET_TYPE_HEADER_VIEW:
285 widget = (GtkWidget*)priv->header_view; break;
286 case MODEST_WIDGET_TYPE_FOLDER_VIEW:
287 widget = (GtkWidget*)priv->folder_view; break;
292 return widget ? GTK_WIDGET(widget) : NULL;
298 restore_settings (ModestMainWindow *self)
301 ModestMainWindowPrivate *priv;
303 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
305 conf = modest_runtime_get_conf ();
307 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
308 MODEST_CONF_MAIN_PANED_KEY);
309 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
310 MODEST_CONF_HEADER_VIEW_KEY);
311 modest_widget_memory_restore (conf, G_OBJECT(self),
312 MODEST_CONF_MAIN_WINDOW_KEY);
317 save_state (ModestWindow *window)
320 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
321 ModestMainWindowPrivate *priv;
323 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
324 conf = modest_runtime_get_conf ();
326 modest_widget_memory_save (conf,G_OBJECT(self),
327 MODEST_CONF_MAIN_WINDOW_KEY);
328 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
329 MODEST_CONF_MAIN_PANED_KEY);
330 modest_widget_memory_save (conf, G_OBJECT(priv->header_view),
331 MODEST_CONF_HEADER_VIEW_KEY);
335 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
337 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
338 gtk_scrolled_window_add_with_viewport
339 (GTK_SCROLLED_WINDOW(win), widget);
341 gtk_container_add (GTK_CONTAINER(win),
347 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self)
349 modest_window_save_state (MODEST_WINDOW(self));
355 on_connection_changed (TnyDevice *device, gboolean online, ModestMainWindow *self)
357 /* When going online, do the equivalent of pressing the send/receive button,
358 * as per the specification:
359 * (without the check for >0 accounts, though that is not specified): */
361 do_send_receive (MODEST_WINDOW (self));
368 connect_signals (ModestMainWindow *self)
370 ModestWindowPrivate *parent_priv;
371 ModestMainWindowPrivate *priv;
374 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
375 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
378 g_signal_connect (G_OBJECT(priv->folder_view), "key-press-event",
379 G_CALLBACK(on_inner_widgets_key_pressed), self);
380 g_signal_connect (G_OBJECT(priv->folder_view), "folder_selection_changed",
381 G_CALLBACK(modest_ui_actions_on_folder_selection_changed), self);
382 g_signal_connect (G_OBJECT(priv->folder_view), "folder-display-name-changed",
383 G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
385 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
386 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
389 /* g_signal_connect (G_OBJECT(priv->header_view), "status_update", */
390 /* G_CALLBACK(modest_ui_actions_on_header_status_update), self); */
391 g_signal_connect (G_OBJECT(priv->header_view), "header_selected",
392 G_CALLBACK(modest_ui_actions_on_header_selected), self);
393 g_signal_connect (G_OBJECT(priv->header_view), "header_activated",
394 G_CALLBACK(modest_ui_actions_on_header_activated), self);
395 g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
396 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
397 g_signal_connect (G_OBJECT(priv->header_view), "key-press-event",
398 G_CALLBACK(on_inner_widgets_key_pressed), self);
401 g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
402 g_signal_connect (G_OBJECT (self), "window-state-event",
403 G_CALLBACK (modest_main_window_window_state_event),
405 g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
407 /* Mail Operation Queue */
408 g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
410 G_CALLBACK (on_queue_changed),
413 /* Track changes in the device name */
414 g_signal_connect (G_OBJECT(modest_runtime_get_conf ()),
416 G_CALLBACK (on_configuration_key_changed),
419 /* Track account changes. We need to refresh the toolbar */
420 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
422 G_CALLBACK (on_account_update),
426 g_signal_connect (G_OBJECT (modest_runtime_get_account_store()), "password_requested",
427 G_CALLBACK (modest_ui_actions_on_password_requested), self);
430 g_signal_connect (G_OBJECT(modest_runtime_get_device()), "connection_changed",
431 G_CALLBACK(on_connection_changed), self);
434 /** Idle handler, to send/receive at startup .*/
436 sync_accounts_cb (ModestMainWindow *win)
438 do_send_receive (MODEST_WINDOW(win));
439 return FALSE; /* Do not call this idle handler again. */
442 static void on_hildon_program_is_topmost_notify(GObject *self,
443 GParamSpec *propert_param, gpointer user_data)
445 HildonProgram *app = HILDON_PROGRAM (self);
448 ModestWindow* self = MODEST_WINDOW(user_data);
451 /* Note that use of hildon_program_set_can_hibernate()
452 * is generally referred to as "setting the killable flag",
453 * though hibernation does not seem equal to death.
456 if (hildon_program_get_is_topmost (app)) {
457 /* Prevent hibernation when the progam comes to the foreground,
458 * because hibernation should only happen when the application
459 * is in the background: */
460 hildon_program_set_can_hibernate (app, FALSE);
462 /* Allow hibernation if the program has gone to the background: */
464 /* However, prevent hibernation while the settings are being changed: */
465 const gboolean hibernation_prevented =
466 modest_window_mgr_get_hibernation_is_prevented (
467 modest_runtime_get_window_mgr ());
469 if (hibernation_prevented)
470 hildon_program_set_can_hibernate (app, FALSE);
472 /* Allow hibernation, after saving the state: */
473 modest_osso_save_state();
474 hildon_program_set_can_hibernate (app, TRUE);
483 modest_main_window_new (void)
485 ModestMainWindow *self;
486 ModestMainWindowPrivate *priv;
487 ModestWindowPrivate *parent_priv;
488 GtkWidget *folder_win;
489 GtkActionGroup *action_group;
490 GError *error = NULL;
491 TnyFolderStoreQuery *query;
492 GdkPixbuf *window_icon;
496 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
497 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
498 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
500 parent_priv->ui_manager = gtk_ui_manager_new();
501 action_group = gtk_action_group_new ("ModestMainWindowActions");
502 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
504 /* Add common actions */
505 gtk_action_group_add_actions (action_group,
506 modest_action_entries,
507 G_N_ELEMENTS (modest_action_entries),
510 gtk_action_group_add_actions (action_group,
511 modest_folder_view_action_entries,
512 G_N_ELEMENTS (modest_folder_view_action_entries),
515 gtk_action_group_add_toggle_actions (action_group,
516 modest_toggle_action_entries,
517 G_N_ELEMENTS (modest_toggle_action_entries),
520 gtk_action_group_add_toggle_actions (action_group,
521 modest_main_window_toggle_action_entries,
522 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
525 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
526 g_object_unref (action_group);
528 /* Load the UI definition */
529 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
530 MODEST_UIDIR "modest-main-window-ui.xml", &error);
532 g_warning ("Could not merge modest-ui.xml: %s", error->message);
533 g_error_free (error);
537 /* Add accelerators */
538 gtk_window_add_accel_group (GTK_WINDOW (self),
539 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
541 /* Menubar. Update the state of some toggles */
542 parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
543 conf = modest_runtime_get_conf ();
544 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
545 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
546 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
547 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL));
548 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
549 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
550 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
551 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL));
552 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
555 query = tny_folder_store_query_new ();
556 tny_folder_store_query_add_item (query, NULL,
557 TNY_FOLDER_STORE_QUERY_OPTION_SUBSCRIBED);
558 priv->folder_view = MODEST_FOLDER_VIEW(modest_folder_view_new (query));
559 if (!priv->folder_view)
560 g_printerr ("modest: cannot instantiate folder view\n");
561 g_object_unref (G_OBJECT (query));
562 modest_folder_view_set_style (priv->folder_view,
563 MODEST_FOLDER_VIEW_STYLE_SHOW_ONE);
565 /* Get device name */
566 modest_maemo_utils_get_device_name ();
570 MODEST_HEADER_VIEW(modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
571 if (!priv->header_view)
572 g_printerr ("modest: cannot instantiate header view\n");
573 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
575 /* Create scrolled windows */
576 folder_win = gtk_scrolled_window_new (NULL, NULL);
577 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
578 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
580 GTK_POLICY_AUTOMATIC);
581 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
583 GTK_POLICY_AUTOMATIC);
585 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
586 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view));
589 priv->main_paned = gtk_hpaned_new ();
590 gtk_paned_add1 (GTK_PANED(priv->main_paned), folder_win);
591 gtk_paned_add2 (GTK_PANED(priv->main_paned), priv->contents_widget);
592 gtk_widget_show (GTK_WIDGET(priv->header_view));
593 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
595 /* putting it all together... */
596 priv->main_vbox = gtk_vbox_new (FALSE, 6);
597 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
599 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
600 restore_settings (MODEST_MAIN_WINDOW(self));
602 /* Set window icon */
603 window_icon = modest_platform_get_icon (MODEST_APP_ICON);
604 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
606 /* Connect signals */
607 connect_signals (self);
609 /* Set account store */
610 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
611 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
613 /* do send & receive when we are idle */
614 g_idle_add ((GSourceFunc)sync_accounts_cb, self);
617 HildonProgram *app = hildon_program_get_instance ();
618 hildon_program_add_window (app, HILDON_WINDOW (self));
620 /* Register HildonProgram signal handlers: */
621 /* These are apparently deprecated, according to the
622 * "HildonApp/HildonAppView to HildonProgram/HildonWindow migration guide",
623 * though the API reference does not mention that:
625 g_signal_connect (G_OBJECT(app), "topmost_status_lose",
626 G_CALLBACK (on_hildon_program_save_state), self);
627 g_signal_connect (G_OBJECT(app), "topmost_status_acquire",
628 G_CALLBACK (on_hildon_program_status_acquire), self);
630 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
631 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
633 /* Load previous osso state, for instance if we are being restored from
635 modest_osso_load_state();
637 return MODEST_WINDOW(self);
641 modest_main_window_close_all (ModestMainWindow *self)
644 GtkResponseType response;
646 /* Create the confirmation dialog MSG-NOT308 */
647 note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
648 _("emev_nc_close_windows"),
649 _("mcen_bd_yes"), GTK_RESPONSE_YES,
650 _("mcen_bd_no"), GTK_RESPONSE_NO,
653 response = gtk_dialog_run (GTK_DIALOG (note));
654 gtk_widget_destroy (GTK_WIDGET (note));
656 if (response == GTK_RESPONSE_YES)
664 modest_main_window_set_style (ModestMainWindow *self,
665 ModestMainWindowStyle style)
667 ModestMainWindowPrivate *priv;
668 ModestWindowPrivate *parent_priv;
671 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
673 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
674 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
676 /* no change -> nothing to do */
677 if (priv->style == style)
680 /* Get toggle button */
681 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarToggleView");
686 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
687 /* Remove main paned */
688 g_object_ref (priv->main_paned);
689 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
691 /* Reparent the contents widget to the main vbox */
692 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
694 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
695 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
696 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
699 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
700 /* Remove header view */
701 g_object_ref (priv->contents_widget);
702 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
704 /* Reparent the main paned */
705 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
706 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
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), FALSE);
710 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
714 g_return_if_reached ();
717 /* Let header view grab the focus if it's being shown */
718 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
719 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
721 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
724 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
727 ModestMainWindowStyle
728 modest_main_window_get_style (ModestMainWindow *self)
730 ModestMainWindowPrivate *priv;
732 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
734 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
741 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
743 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
744 ModestWindowPrivate *parent_priv;
745 ModestWindowMgr *mgr;
746 gboolean is_fullscreen;
747 GtkAction *fs_toggle_action;
750 mgr = modest_runtime_get_window_mgr ();
752 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
754 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
756 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
757 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
758 if (is_fullscreen != active) {
759 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
768 set_homogeneous (GtkWidget *widget,
771 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
772 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
776 modest_main_window_show_toolbar (ModestWindow *self,
777 gboolean show_toolbar)
779 ModestMainWindowPrivate *priv = NULL;
780 ModestWindowPrivate *parent_priv = NULL;
781 GtkWidget *reply_button = NULL, *menu = NULL;
782 GtkWidget *placeholder = NULL;
785 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
786 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
787 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
789 /* Set optimized view status */
790 priv->optimized_view = !show_toolbar;
792 if (!parent_priv->toolbar) {
793 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
796 /* Set homogeneous toolbar */
797 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar),
798 set_homogeneous, NULL);
800 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
801 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
802 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
803 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
804 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
805 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
806 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
807 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
809 /* Add ProgressBar (Transfer toolbar) */
810 priv->progress_bar = modest_progress_bar_widget_new ();
811 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
812 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
813 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
814 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
815 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
817 /* Connect cancel 'clicked' signal to abort progress mode */
818 g_signal_connect(priv->cancel_toolitem, "clicked",
819 G_CALLBACK(cancel_progressbar),
822 /* Add it to the observers list */
823 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
826 hildon_window_add_toolbar (HILDON_WINDOW (self),
827 GTK_TOOLBAR (parent_priv->toolbar));
829 /* Set reply button tap and hold menu */
830 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
831 "/ToolBar/ToolbarMessageReply");
832 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
834 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
836 /* Set send & receive button tap and hold menu */
837 on_account_update (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
842 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
843 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
844 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
846 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
847 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
849 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
854 compare_display_names (ModestAccountData *a,
855 ModestAccountData *b)
857 return strcmp (a->display_name, b->display_name);
861 * TODO: modify the menu dynamically. Add handlers to each item of the
865 on_account_update (TnyAccountStore *account_store,
869 GSList *account_names, *iter, *accounts;
870 ModestMainWindow *self;
871 ModestMainWindowPrivate *priv;
872 ModestWindowPrivate *parent_priv;
873 ModestAccountMgr *mgr;
874 gint i, num_accounts;
875 ModestAccountData *account_data;
876 GtkActionGroup *action_group;
878 gchar *default_account;
879 GtkWidget *send_receive_button, *item;
881 self = MODEST_MAIN_WINDOW (user_data);
882 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
883 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
885 /* Get enabled account IDs */
886 mgr = modest_runtime_get_account_mgr ();
887 account_names = modest_account_mgr_account_names (mgr, TRUE);
888 iter = account_names;
892 account_data = modest_account_mgr_get_account_data (mgr, (gchar*) iter->data);
893 accounts = g_slist_prepend (accounts, account_data);
897 g_slist_free (account_names);
899 /* Order the list of accounts by its display name */
900 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
901 num_accounts = g_slist_length (accounts);
903 /* Delete old send&receive popup items. We can not just do a
904 menu_detach because it does not work well with
906 if (priv->accounts_popup)
907 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup), (GtkCallback) gtk_widget_destroy, NULL);
909 /* Delete old entries in the View menu. Do not free groups, it
911 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
913 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
914 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
915 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
916 GTK_ACTION_GROUP (groups->data));
919 if (priv->merge_ids) {
920 for (i = 0; i < priv->merge_ids->len; i++)
921 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
922 g_byte_array_free (priv->merge_ids, TRUE);
924 /* We need to call this in order to ensure
925 that the new actions are added in the right
926 order (alphabetical */
927 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
929 groups = g_list_next (groups);
931 priv->merge_ids = g_byte_array_sized_new (num_accounts);
933 /* Get send receive button */
934 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
935 "/ToolBar/ToolbarSendReceive");
937 /* Create the menu */
938 if (num_accounts > 1) {
939 if (!priv->accounts_popup)
940 priv->accounts_popup = gtk_menu_new ();
941 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
942 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
943 item = gtk_separator_menu_item_new ();
944 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
947 /* Create a new action group */
948 default_account = modest_account_mgr_get_default_account (mgr);
949 action_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
950 for (i = 0; i < num_accounts; i++) {
951 GtkAction *new_action;
952 gchar* item_name, *display_name;
955 account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
957 /* Create display name. The default account is shown differently */
958 if (default_account && !(strcmp (default_account, account_data->account_name) == 0))
959 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
960 account_data->display_name);
962 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
963 account_data->display_name);
965 /* Create action and add it to the action group. The
966 action name must be the account name, this way we
967 could know in the handlers the account to show */
968 new_action = gtk_action_new (account_data->account_name, display_name, NULL, NULL);
969 gtk_action_group_add_action (action_group, new_action);
971 /* Add ui from account data. We allow 2^9-1 account
972 changes in a single execution because we're
973 downcasting the guint to a guint8 in order to use a
974 GByteArray, it should be enough */
975 item_name = g_strconcat (account_data->account_name, "Menu");
976 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
977 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
978 gtk_ui_manager_add_ui (parent_priv->ui_manager,
980 "/MenuBar/ViewMenu/ViewMenuAdditions",
982 account_data->account_name,
983 GTK_UI_MANAGER_MENUITEM,
986 /* Connect the action signal "activate" */
987 g_signal_connect (G_OBJECT (new_action),
989 G_CALLBACK (on_show_account_action_activated),
992 /* Create item and add it to the send&receive CSM */
993 item = gtk_menu_item_new_with_label (display_name);
994 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
997 g_free (display_name);
999 modest_account_mgr_free_account_data (mgr, account_data);
1001 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 1);
1003 if (priv->accounts_popup) {
1004 /* Mandatory in order to view the menu contents */
1005 gtk_widget_show_all (priv->accounts_popup);
1007 /* Setup tap_and_hold just if was not done before*/
1008 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
1009 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
1013 g_slist_free (accounts);
1014 g_free (default_account);
1018 * This function manages the key events used to navigate between
1019 * header and folder views (when the window is in split view)
1022 * -------------------------------------------------
1023 * HeaderView GDK_Left Move focus to folder view
1024 * FolderView GDK_Right Move focus to header view
1026 * There is no need to scroll to selected row, the widgets will be the
1027 * responsibles of doing that (probably managing the focus-in event
1030 on_inner_widgets_key_pressed (GtkWidget *widget,
1034 ModestMainWindowPrivate *priv;
1036 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1038 /* Do nothing if we're in SIMPLE style */
1039 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1042 if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
1043 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1044 else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1045 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1051 set_alignment (GtkWidget *widget,
1054 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1055 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1059 create_details_widget (TnyAccount *account)
1064 vbox = gtk_vbox_new (FALSE, 0);
1066 /* Account description */
1067 if (!strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1070 /* Get device name */
1071 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1072 MODEST_CONF_DEVICE_NAME, NULL);
1074 label = g_strdup_printf ("%s: %s",
1075 _("mcen_fi_localroot_description"),
1077 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1078 g_free (device_name);
1080 } else if (!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1082 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("FIXME: MMC ?"), FALSE, FALSE, 0);
1086 /* Put proto in uppercase */
1087 proto = g_string_new (tny_account_get_proto (account));
1088 proto = g_string_ascii_up (proto);
1090 label = g_strdup_printf ("%s %s: %s",
1092 _("mcen_fi_remoteroot_account"),
1093 tny_account_get_name (account));
1094 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1095 g_string_free (proto, TRUE);
1100 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_messages"),
1101 modest_tny_account_get_message_count (account));
1102 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1106 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_folders"),
1107 modest_tny_account_get_folder_count (account));
1108 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1112 if (!strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1113 /* FIXME: format size */
1114 label = g_strdup_printf ("%s: %d", _("mcen_fi_rootfolder_size"),
1115 modest_tny_account_get_local_size (account));
1116 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1118 } else if (!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1119 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new ("FIXME: MMC ?"), FALSE, FALSE, 0);
1121 label = g_strdup_printf ("%s: %s", _("mcen_ti_lastupdated"), "08/08/08");
1122 gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (label), FALSE, FALSE, 0);
1127 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1133 modest_main_window_set_contents_style (ModestMainWindow *self,
1134 ModestMainWindowContentsStyle style)
1136 ModestMainWindowPrivate *priv;
1138 TnyAccount *account;
1140 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1142 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1144 /* We allow to set the same content style than the previously
1145 set if there are details, because it could happen when we're
1146 selecting different accounts consecutively */
1147 if ((priv->contents_style == style) &&
1148 (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS))
1151 /* Remove previous child. Delete it if it was an account
1153 content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1154 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1155 g_object_ref (content);
1156 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1158 priv->contents_style = style;
1160 switch (priv->contents_style) {
1161 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1162 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1164 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1165 /* TODO: show here account details */
1166 account = TNY_ACCOUNT (modest_folder_view_get_selected (priv->folder_view));
1167 priv->details_widget = create_details_widget (account);
1169 wrap_in_scrolled_window (priv->contents_widget,
1170 priv->details_widget);
1173 g_return_if_reached ();
1177 gtk_widget_show_all (priv->contents_widget);
1181 on_configuration_key_changed (ModestConf* conf,
1183 ModestConfEvent event,
1184 ModestMainWindow *self)
1186 ModestMainWindowPrivate *priv;
1187 TnyAccount *account;
1189 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
1192 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1194 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1197 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
1198 if (TNY_IS_ACCOUNT (account) &&
1199 !strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1202 const gchar *device_name;
1206 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
1207 label = GTK_LABEL (children->data);
1209 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1210 MODEST_CONF_DEVICE_NAME, NULL);
1212 new_text = g_strdup_printf ("%s: %s",
1213 _("mcen_fi_localroot_description"),
1216 gtk_label_set_text (label, new_text);
1217 gtk_widget_show (GTK_WIDGET (label));
1220 g_list_free (children);
1225 set_toolbar_mode (ModestMainWindow *self,
1226 ModestToolBarModes mode)
1228 ModestWindowPrivate *parent_priv = NULL;
1229 ModestMainWindowPrivate *priv = NULL;
1230 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
1232 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1234 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1235 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1237 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
1239 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1240 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1241 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1243 /* Sets current toolbar mode */
1244 priv->current_toolbar_mode = mode;
1246 /* Show and hide toolbar items */
1248 case TOOLBAR_MODE_NORMAL:
1250 gtk_action_set_visible (sort_action, TRUE);
1252 gtk_action_set_visible (refresh_action, TRUE);
1253 if (priv->progress_toolitem) {
1254 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1255 gtk_widget_hide (priv->progress_toolitem);
1257 if (priv->progress_bar)
1258 gtk_widget_hide (priv->progress_bar);
1261 gtk_action_set_visible (cancel_action, FALSE);
1263 /* Hide toolbar if optimized view is enabled */
1264 if (priv->optimized_view)
1265 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
1267 case TOOLBAR_MODE_TRANSFER:
1269 gtk_action_set_visible (sort_action, FALSE);
1271 gtk_action_set_visible (refresh_action, FALSE);
1273 gtk_action_set_visible (cancel_action, TRUE);
1274 if (priv->progress_toolitem) {
1275 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1276 gtk_widget_show (priv->progress_toolitem);
1278 if (priv->progress_bar)
1279 gtk_widget_show (priv->progress_bar);
1281 /* Show toolbar if it's hiden (optimized view ) */
1282 if (priv->optimized_view)
1283 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1286 g_return_if_reached ();
1291 cancel_progressbar (GtkToolButton *toolbutton,
1292 ModestMainWindow *self)
1295 ModestMainWindowPrivate *priv;
1297 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1299 /* Get operation observers and cancel its current operation */
1300 tmp = priv->progress_widgets;
1302 modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
1303 tmp=g_slist_next(tmp);
1308 observers_empty (ModestMainWindow *self)
1311 ModestMainWindowPrivate *priv;
1312 gboolean is_empty = TRUE;
1313 guint pending_ops = 0;
1315 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1316 tmp = priv->progress_widgets;
1318 /* Check all observers */
1319 while (tmp && is_empty) {
1320 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
1321 is_empty = pending_ops == 0;
1323 tmp = g_slist_next(tmp);
1330 on_queue_changed (ModestMailOperationQueue *queue,
1331 ModestMailOperation *mail_op,
1332 ModestMailOperationQueueNotification type,
1333 ModestMainWindow *self)
1335 ModestMainWindowPrivate *priv;
1336 ModestMailOperationId op_id;
1337 ModestToolBarModes mode;
1339 gboolean mode_changed = FALSE;
1341 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1342 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1344 /* Get toolbar mode from operation id*/
1345 op_id = modest_mail_operation_get_id (mail_op);
1347 case MODEST_MAIL_OPERATION_ID_SEND:
1348 case MODEST_MAIL_OPERATION_ID_RECEIVE:
1349 mode = TOOLBAR_MODE_TRANSFER;
1350 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
1351 mode_changed = TRUE;
1354 mode = TOOLBAR_MODE_NORMAL;
1359 /* Add operation observers and change toolbar if neccessary*/
1360 tmp = priv->progress_widgets;
1362 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
1364 set_toolbar_mode (self, mode);
1365 if (mode == TOOLBAR_MODE_TRANSFER) {
1367 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1369 tmp = g_slist_next (tmp);
1373 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
1374 if (mode == TOOLBAR_MODE_TRANSFER) {
1376 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1378 tmp = g_slist_next (tmp);
1381 /* If no more operations are being observed, NORMAL mode is enabled again */
1382 if (observers_empty (self))
1383 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
1390 on_show_account_action_activated (GtkAction *action,
1393 ModestAccountData *acc_data;
1394 ModestMainWindow *self;
1395 ModestMainWindowPrivate *priv;
1396 ModestAccountMgr *mgr;
1398 self = MODEST_MAIN_WINDOW (user_data);
1399 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1401 /* Get account data */
1402 mgr = modest_runtime_get_account_mgr ();
1403 acc_data = modest_account_mgr_get_account_data (mgr, gtk_action_get_name (action));
1405 /* Set the new visible account */
1406 if (acc_data->store_account)
1407 modest_folder_view_set_account_id_of_visible_server_account (priv->folder_view,
1408 acc_data->store_account->account_name);
1411 modest_account_mgr_free_account_data (mgr, acc_data);