1 /* Copyright (c) 2006, 2008 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>
35 #include <tny-iterator.h>
36 #include <tny-error.h>
37 #include "modest-hildon-includes.h"
38 #include "modest-defs.h"
40 #include "widgets/modest-header-view-priv.h"
41 #include "widgets/modest-main-window.h"
42 #include "widgets/modest-msg-edit-window.h"
43 #include "widgets/modest-account-view-window.h"
44 #include "modest-runtime.h"
45 #include "modest-account-mgr-helpers.h"
46 #include "modest-platform.h"
47 #include "modest-widget-memory.h"
48 #include "modest-window-priv.h"
49 #include "modest-main-window-ui.h"
50 #include "modest-main-window-ui-dimming.h"
51 #include "modest-account-mgr.h"
52 #include "modest-tny-account.h"
53 #include "modest-tny-folder.h"
54 #include "modest-conf.h"
55 #include <modest-utils.h>
56 #include <modest-maemo-utils.h>
57 #include "modest-tny-platform-factory.h"
58 #include "modest-tny-msg.h"
59 #include "modest-mail-operation.h"
60 #include "modest-icon-names.h"
61 #include "modest-progress-bar.h"
62 #include "modest-text-utils.h"
63 #include "modest-ui-dimming-manager.h"
64 #include "modest-osso-state-saving.h"
65 #include "modest-text-utils.h"
66 #include "modest-signal-mgr.h"
67 #include <tny-gtk-folder-store-tree-model.h>
68 #include <modest-accounts-window.h>
70 #define MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS "ModestMainWindowActionAdditions"
77 /* 'private'/'protected' functions */
78 static void modest_main_window_class_init (ModestMainWindowClass *klass);
79 static void modest_main_window_init (ModestMainWindow *obj);
80 static void modest_main_window_finalize (GObject *obj);
82 static gboolean modest_main_window_window_state_event (GtkWidget *widget,
83 GdkEventWindowState *event,
86 static void connect_signals (ModestMainWindow *self);
88 static void modest_main_window_disconnect_signals (ModestWindow *self);
90 static void restore_settings (ModestMainWindow *self,
91 gboolean do_folder_view_too);
93 static void save_state (ModestWindow *self);
95 static void update_menus (ModestMainWindow* self);
97 static void modest_main_window_show_toolbar (ModestWindow *window,
98 gboolean show_toolbar);
100 static void cancel_progressbar (GtkToolButton *toolbutton,
101 ModestMainWindow *self);
103 static void on_queue_changed (ModestMailOperationQueue *queue,
104 ModestMailOperation *mail_op,
105 ModestMailOperationQueueNotification type,
106 ModestMainWindow *self);
108 static gboolean on_zoom_minus_plus_not_implemented (ModestWindow *window);
110 static void on_account_inserted (TnyAccountStore *accoust_store,
114 static void on_account_removed (TnyAccountStore *accoust_store,
118 static void on_account_changed (TnyAccountStore *account_store,
122 static void on_default_account_changed (ModestAccountMgr* mgr,
125 static gboolean on_inner_widgets_key_pressed (GtkWidget *widget,
129 static void on_configuration_key_changed (ModestConf* conf,
131 ModestConfEvent event,
132 ModestConfNotificationId id,
133 ModestMainWindow *self);
135 static void set_toolbar_mode (ModestMainWindow *self,
136 ModestToolBarModes mode);
138 static gboolean set_toolbar_transfer_mode (ModestMainWindow *self);
140 static void on_show_account_action_toggled (GtkToggleAction *action,
143 static void on_refresh_account_action_activated (GtkAction *action,
146 static void on_send_receive_csm_activated (GtkMenuItem *item,
149 static void on_folder_view_row_activated (GtkTreeView *tree_view,
150 GtkTreePath *tree_path,
151 GtkTreeViewColumn *column,
153 static void on_msg_count_changed (ModestHeaderView *header_view,
155 TnyFolderChange *change,
156 ModestMainWindow *main_window);
158 static void modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self);
161 static GtkWidget * create_empty_view (void);
163 static gboolean on_folder_view_focus_in (GtkWidget *widget,
164 GdkEventFocus *event,
167 static gboolean on_header_view_focus_in (GtkWidget *widget,
168 GdkEventFocus *event,
171 static void on_folder_selection_changed (ModestFolderView *folder_view,
172 TnyFolderStore *folder_store,
174 ModestMainWindow *main_window);
176 static void set_at_least_one_account_visible(ModestMainWindow *self);
178 static void on_updating_msg_list (ModestHeaderView *header_view,
182 static gboolean show_opening_banner (gpointer user_data);
184 static void on_window_destroy (GtkObject *widget,
187 static void on_window_hide (GObject *gobject,
191 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
192 struct _ModestMainWindowPrivate {
193 GtkWidget *main_vbox;
194 GtkWidget *contents_widget;
195 GtkWidget *empty_view;
197 /* Progress observers */
198 GtkWidget *progress_bar;
199 GSList *progress_widgets;
202 GtkWidget *progress_toolitem;
203 GtkWidget *cancel_toolitem;
204 GtkWidget *sort_toolitem;
205 GtkWidget *refresh_toolitem;
206 ModestToolBarModes current_toolbar_mode;
208 /* Merge ids used to add/remove accounts to the ViewMenu*/
209 GByteArray *merge_ids;
210 GtkActionGroup *view_additions_group;
212 /* On-demand widgets */
213 GtkWidget *accounts_popup;
214 GtkWidget *details_widget;
216 /* Optimized view enabled */
217 gboolean optimized_view;
219 /* Optimized view enabled */
220 gboolean send_receive_in_progress;
222 ModestHeaderView *header_view;
223 ModestFolderView *folder_view;
225 ModestMainWindowStyle style;
226 ModestMainWindowContentsStyle contents_style;
227 gboolean wait_for_settings;
229 guint progress_bar_timeout;
231 /* Signal handler UIDs */
232 GList *queue_err_signals;
235 /* "Updating" banner for header view */
236 GtkWidget *updating_banner;
237 guint updating_banner_timeout;
239 /* "Opening" banner for header view */
240 GtkWidget *opening_banner;
241 guint opening_banner_timeout;
244 osso_display_state_t display_state;
246 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
247 MODEST_TYPE_MAIN_WINDOW, \
248 ModestMainWindowPrivate))
250 typedef struct _GetMsgAsyncHelper {
251 ModestMainWindowPrivate *main_window_private;
253 ModestTnyMsgReplyType reply_type;
254 ModestTnyMsgForwardType forward_type;
261 static GtkWindowClass *parent_class = NULL;
264 /* Private actions */
265 /* This is the context sensitive menu: */
266 static const GtkActionEntry modest_folder_view_action_entries [] = {
268 /* Folder View CSM actions */
269 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
270 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
271 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_paste)},
272 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
273 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_csm_help) },
276 static const GtkActionEntry modest_header_view_action_entries [] = {
278 /* Header View CSM actions */
279 { "HeaderViewCSMOpen", NULL, N_("mcen_me_inbox_open"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_open) },
280 { "HeaderViewCSMReply", NULL, N_("mcen_me_inbox_reply"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply) },
281 { "HeaderViewCSMReplyAll", NULL, N_("mcen_me_inbox_replytoall"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply_all) },
282 { "HeaderViewCSMForward", NULL, N_("mcen_me_inbox_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_forward) },
283 { "HeaderViewCSMCut", NULL, N_("mcen_me_inbox_cut"), "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
284 { "HeaderViewCSMCopy", NULL, N_("mcen_me_inbox_copy"), "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
285 { "HeaderViewCSMPaste", NULL, N_("mcen_me_inbox_paste"), "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
286 { "HeaderViewCSMDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_message) },
287 { "HeaderViewCSMCancelSending", NULL, N_("mcen_me_outbox_cancelsend"), NULL, NULL, G_CALLBACK (modest_ui_actions_cancel_send) },
288 { "HeaderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
291 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
292 { "ToggleFolders", MODEST_STOCK_SPLIT_VIEW, N_("mcen_me_inbox_hidefolders"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), TRUE },
295 /************************************************************************/
298 modest_main_window_get_type (void)
300 static GType my_type = 0;
302 static const GTypeInfo my_info = {
303 sizeof(ModestMainWindowClass),
304 NULL, /* base init */
305 NULL, /* base finalize */
306 (GClassInitFunc) modest_main_window_class_init,
307 NULL, /* class finalize */
308 NULL, /* class data */
309 sizeof(ModestMainWindow),
311 (GInstanceInitFunc) modest_main_window_init,
314 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
322 modest_main_window_class_init (ModestMainWindowClass *klass)
324 GObjectClass *gobject_class;
325 gobject_class = (GObjectClass*) klass;
326 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
328 parent_class = g_type_class_peek_parent (klass);
329 gobject_class->finalize = modest_main_window_finalize;
331 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
333 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
334 modest_window_class->save_state_func = save_state;
335 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
336 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
337 modest_window_class->disconnect_signals_func = modest_main_window_disconnect_signals;
341 modest_main_window_init (ModestMainWindow *obj)
343 ModestMainWindowPrivate *priv;
345 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
347 priv->queue_err_signals = NULL;
348 priv->main_vbox = NULL;
349 priv->header_view = NULL;
350 priv->folder_view = NULL;
351 priv->contents_widget = NULL;
352 priv->accounts_popup = NULL;
353 priv->details_widget = NULL;
354 priv->empty_view = NULL;
355 priv->progress_widgets = NULL;
356 priv->progress_bar = NULL;
357 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
358 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
359 priv->wait_for_settings = TRUE;
360 priv->contents_style = -1; /* invalid contents style. We need this to select it for the first time */
361 priv->merge_ids = NULL;
362 priv->optimized_view = FALSE;
363 priv->send_receive_in_progress = FALSE;
364 priv->progress_bar_timeout = 0;
365 priv->sighandlers = NULL;
366 priv->updating_banner = NULL;
367 priv->updating_banner_timeout = 0;
368 priv->opening_banner = NULL;
369 priv->opening_banner_timeout = 0;
370 priv->display_state = OSSO_DISPLAY_ON;
372 modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
374 "applications_email_mainview");
378 modest_main_window_finalize (GObject *obj)
380 ModestMainWindowPrivate *priv;
382 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
384 /* Sanity check: shouldn't be needed, the window mgr should
385 call this function before */
386 modest_main_window_disconnect_signals (MODEST_WINDOW (obj));
387 modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
389 if (priv->empty_view) {
390 g_object_unref (priv->empty_view);
391 priv->empty_view = NULL;
394 if (priv->header_view) {
395 g_object_unref (priv->header_view);
396 priv->header_view = NULL;
399 g_slist_free (priv->progress_widgets);
401 g_byte_array_free (priv->merge_ids, TRUE);
403 if (priv->progress_bar_timeout > 0) {
404 g_source_remove (priv->progress_bar_timeout);
405 priv->progress_bar_timeout = 0;
408 if (priv->updating_banner_timeout > 0) {
409 g_source_remove (priv->updating_banner_timeout);
410 priv->updating_banner_timeout = 0;
413 if (priv->updating_banner) {
414 gtk_widget_destroy (priv->updating_banner);
415 priv->updating_banner = NULL;
418 if (priv->opening_banner_timeout > 0) {
419 g_source_remove (priv->opening_banner_timeout);
420 priv->opening_banner_timeout = 0;
423 if (priv->opening_banner) {
424 gtk_widget_destroy (priv->opening_banner);
425 priv->opening_banner = NULL;
428 G_OBJECT_CLASS(parent_class)->finalize (obj);
432 modest_main_window_get_child_widget (ModestMainWindow *self,
433 ModestMainWindowWidgetType widget_type)
435 ModestMainWindowPrivate *priv;
438 g_return_val_if_fail (self && MODEST_IS_MAIN_WINDOW(self), NULL);
439 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_MAIN_WINDOW_WIDGET_TYPE_NUM,
442 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
444 switch (widget_type) {
445 case MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW:
446 widget = (GtkWidget*)priv->header_view; break;
447 case MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW:
448 widget = (GtkWidget*)priv->folder_view; break;
453 /* Note that the window could have been destroyed, and so
454 their children, but still have some references */
455 return (widget && GTK_IS_WIDGET(widget)) ? GTK_WIDGET(widget) : NULL;
460 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
463 ModestMainWindowPrivate *priv;
465 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
467 conf = modest_runtime_get_conf ();
469 modest_widget_memory_restore (conf, G_OBJECT(self),
470 MODEST_CONF_MAIN_WINDOW_KEY);
472 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
473 MODEST_CONF_HEADER_VIEW_KEY);
475 if (do_folder_view_too)
476 modest_widget_memory_restore (conf, G_OBJECT(priv->folder_view),
477 MODEST_CONF_FOLDER_VIEW_KEY);
479 gtk_widget_show (GTK_WIDGET (self));
484 save_state (ModestWindow *window)
487 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
488 ModestMainWindowPrivate *priv;
490 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
491 conf = modest_runtime_get_conf ();
493 modest_widget_memory_save (conf,G_OBJECT(self),
494 MODEST_CONF_MAIN_WINDOW_KEY);
495 modest_widget_memory_save (conf, G_OBJECT(priv->folder_view),
496 MODEST_CONF_FOLDER_VIEW_KEY);
500 compare_display_names (ModestAccountSettings *a,
501 ModestAccountSettings *b)
503 return g_utf8_collate (modest_account_settings_get_display_name (a),
504 modest_account_settings_get_display_name (b));
508 /* We use this function to prevent the send&receive CSM to be shown
509 when there are less than two account */
511 tap_and_hold_query_cb (GtkWidget *widget, GdkEvent *event)
517 update_menus (ModestMainWindow* self)
519 GSList *account_names, *iter, *accounts;
520 ModestMainWindowPrivate *priv;
521 ModestWindowPrivate *parent_priv;
522 ModestAccountMgr *mgr;
523 gint i, num_accounts;
525 gchar *default_account;
526 const gchar *active_account_name;
527 GtkWidget *send_receive_button, *item;
528 GtkAction *send_receive_all = NULL;
531 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
532 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
534 /* Get enabled account IDs */
535 mgr = modest_runtime_get_account_mgr ();
536 account_names = modest_account_mgr_account_names (mgr, TRUE);
537 iter = account_names;
541 ModestAccountSettings *settings =
542 modest_account_mgr_load_account_settings (mgr, (gchar*) iter->data);
543 accounts = g_slist_prepend (accounts, settings);
547 modest_account_mgr_free_account_names (account_names);
548 account_names = NULL;
550 /* Order the list of accounts by its display name */
551 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
552 num_accounts = g_slist_length (accounts);
554 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
555 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
556 gtk_action_set_visible (send_receive_all, num_accounts > 0);
558 /* Delete old send&receive popup items. We can not just do a
559 menu_detach because it does not work well with
561 if (priv->accounts_popup)
562 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
563 (GtkCallback) gtk_widget_destroy, NULL);
565 /* Delete old entries in the View menu. Do not free groups, it
567 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
569 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
570 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
571 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
572 GTK_ACTION_GROUP (groups->data));
575 if (priv->merge_ids) {
576 for (i = 0; i < priv->merge_ids->len; i++)
577 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
578 g_byte_array_free (priv->merge_ids, TRUE);
580 /* We need to call this in order to ensure
581 that the new actions are added in the right
582 order (alphabetical) */
583 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
585 groups = g_list_next (groups);
587 priv->merge_ids = g_byte_array_sized_new (num_accounts);
589 /* Get send receive button */
590 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
591 "/ToolBar/ToolbarSendReceive");
593 /* Create the menu */
594 if (num_accounts > 1) {
595 if (!priv->accounts_popup)
596 priv->accounts_popup = gtk_menu_new ();
597 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
598 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
599 g_signal_connect (G_OBJECT (item),
601 G_CALLBACK (on_send_receive_csm_activated),
603 item = gtk_separator_menu_item_new ();
604 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
607 /* Create a new action group */
608 default_account = modest_account_mgr_get_default_account (mgr);
609 active_account_name = modest_window_get_active_account (MODEST_WINDOW (self));
611 if (!active_account_name)
612 modest_window_set_active_account (MODEST_WINDOW (self), default_account);
614 priv->view_additions_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
616 for (i = 0; i < num_accounts; i++) {
617 gchar *display_name = NULL;
618 const gchar *account_name;
619 ModestAccountSettings *settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
622 g_warning ("%s: BUG: account_data == NULL", __FUNCTION__);
625 account_name = modest_account_settings_get_account_name (settings);
627 if (default_account && account_name &&
628 !(strcmp (default_account, account_name) == 0)) {
629 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
630 modest_account_settings_get_display_name (settings));
632 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
633 modest_account_settings_get_display_name (settings));
638 /* Create action and add it to the action group. The
639 action name must be the account name, this way we
640 could know in the handlers the account to show */
641 if (settings && account_name) {
642 gchar* item_name, *refresh_action_name;
644 GtkAction *view_account_action, *refresh_account_action;
645 gchar *escaped_display_name;
647 escaped_display_name = modest_text_utils_escape_mnemonics (display_name);
649 view_account_action = GTK_ACTION (gtk_radio_action_new (account_name,
650 escaped_display_name, NULL, NULL, 0));
651 g_free (escaped_display_name);
652 gtk_action_group_add_action (priv->view_additions_group, view_account_action);
653 gtk_radio_action_set_group (GTK_RADIO_ACTION (view_account_action), radio_group);
654 radio_group = gtk_radio_action_get_group (GTK_RADIO_ACTION (view_account_action));
656 if (active_account_name) {
657 if (active_account_name && account_name &&
658 (strcmp (active_account_name, account_name) == 0)) {
659 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (view_account_action), TRUE);
663 /* Add ui from account data. We allow 2^9-1 account
664 changes in a single execution because we're
665 downcasting the guint to a guint8 in order to use a
666 GByteArray. It should be enough :-) */
667 item_name = g_strconcat (account_name, "Menu", NULL);
668 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
669 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
670 gtk_ui_manager_add_ui (parent_priv->ui_manager,
672 "/MenuBar/ViewMenu/ViewMenuAdditions",
675 GTK_UI_MANAGER_MENUITEM,
678 /* Connect the action signal "activate" */
679 g_signal_connect_after (G_OBJECT (view_account_action),
681 G_CALLBACK (on_show_account_action_toggled),
684 /* Create the items for the Tools->Send&Receive submenu */
685 refresh_action_name = g_strconcat ("SendReceive", account_name, NULL);
686 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
687 display_name, NULL, NULL);
688 gtk_action_group_add_action (priv->view_additions_group, refresh_account_action);
690 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
691 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
692 gtk_ui_manager_add_ui (parent_priv->ui_manager,
694 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
697 GTK_UI_MANAGER_MENUITEM,
699 g_free (refresh_action_name);
701 g_signal_connect_data (G_OBJECT (refresh_account_action),
703 G_CALLBACK (on_refresh_account_action_activated),
704 g_strdup (account_name),
705 (GClosureNotify) g_free,
708 /* Create item and add it to the send&receive
709 CSM. If there is only one account then
711 if (num_accounts > 1) {
712 GtkWidget *label = gtk_label_new(NULL);
713 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
714 if (default_account && (strcmp(account_name, default_account) == 0)) {
715 gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
716 gtk_label_set_markup (GTK_LABEL (label), escaped);
719 gtk_label_set_text (GTK_LABEL (label), display_name);
722 item = gtk_menu_item_new ();
723 gtk_container_add (GTK_CONTAINER (item), label);
725 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup),
727 g_signal_connect_data (G_OBJECT (item),
729 G_CALLBACK (on_send_receive_csm_activated),
730 g_strdup (account_name),
731 (GClosureNotify) g_free,
738 g_free (display_name);
741 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, priv->view_additions_group, 1);
743 /* We cannot do this in the loop above because this relies on the action
744 * group being inserted. This makes the default account appear in bold.
745 * I agree it is a rather ugly way, but I don't see another possibility. armin. */
746 for (i = 0; i < num_accounts; i++) {
747 gchar *item_name, *path;
749 ModestAccountSettings *settings;
750 const gchar *account_name;
753 settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
754 account_name = modest_account_settings_get_account_name (settings);
755 is_default = (account_name && default_account && !strcmp (account_name, default_account));
757 /* Get the item of the view menu */
758 item_name = g_strconcat (account_name, "Menu", NULL);
759 path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
760 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
764 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
765 if (GTK_IS_LABEL (child)) {
766 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
768 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
769 gtk_label_set_markup (GTK_LABEL (child), bold_name);
772 gtk_label_set_ellipsize (GTK_LABEL (child), PANGO_ELLIPSIZE_END);
776 /* Get the item of the tools menu */
777 path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", item_name, NULL);
778 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
782 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
783 if (GTK_IS_LABEL (child)) {
784 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
786 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
787 gtk_label_set_markup (GTK_LABEL (child), bold_name);
790 gtk_label_set_ellipsize (GTK_LABEL (child), PANGO_ELLIPSIZE_END);
795 g_object_unref (settings);
798 if (num_accounts > 1) {
799 /* Disconnect the tap-and-hold-query if it's connected */
800 if (modest_signal_mgr_is_connected (priv->sighandlers,
801 G_OBJECT (send_receive_button),
802 "tap-and-hold-query"))
803 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
804 G_OBJECT (send_receive_button),
805 "tap-and-hold-query");
807 /* Mandatory in order to view the menu contents */
808 gtk_widget_show_all (priv->accounts_popup);
810 /* Setup tap_and_hold just if was not done before*/
811 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
812 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
814 /* Connect the tap-and-hold-query in order not to show the CSM */
815 if (!modest_signal_mgr_is_connected (priv->sighandlers,
816 G_OBJECT (send_receive_button),
817 "tap-and-hold-query"))
818 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
819 G_OBJECT (send_receive_button),
820 "tap-and-hold-query",
821 G_CALLBACK (tap_and_hold_query_cb),
826 g_slist_free (accounts);
827 g_free (default_account);
830 /* Make sure that at least one account is viewed if there are any
831 * accounts, for instance when adding the first account: */
832 set_at_least_one_account_visible (self);
836 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
838 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
839 gtk_scrolled_window_add_with_viewport
840 (GTK_SCROLLED_WINDOW(win), widget);
842 gtk_container_add (GTK_CONTAINER(win),
853 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
855 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
857 GList *oerrsignals = priv->queue_err_signals;
858 while (oerrsignals) {
859 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
860 g_signal_handler_disconnect (esignal->queue, esignal->signal);
861 g_slice_free (QueueErrorSignal, esignal);
862 oerrsignals = g_list_next (oerrsignals);
864 g_list_free (priv->queue_err_signals);
865 priv->queue_err_signals = NULL;
870 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
872 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
875 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
879 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
881 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
883 /* Update visibility */
886 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
890 modest_main_window_disconnect_signals (ModestWindow *self)
892 ModestMainWindowPrivate *priv;
893 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
895 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
896 priv->sighandlers = NULL;
900 connect_signals (ModestMainWindow *self)
902 ModestWindowPrivate *parent_priv;
903 ModestMainWindowPrivate *priv;
906 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
907 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
912 modest_signal_mgr_connect (priv->sighandlers,
913 G_OBJECT(priv->folder_view), "key-press-event",
914 G_CALLBACK(on_inner_widgets_key_pressed), self);
916 modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view),
917 "folder_selection_changed",
918 G_CALLBACK (on_folder_selection_changed),
921 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view),
922 "folder-display-name-changed",
923 G_CALLBACK (modest_ui_actions_on_folder_display_name_changed),
926 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view),
928 G_CALLBACK (on_folder_view_focus_in),
931 /* Folder view CSM */
932 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
933 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
934 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
935 G_CALLBACK(_folder_view_csm_menu_activated),
938 /* folder view row activated */
939 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "row-activated",
940 G_CALLBACK(on_folder_view_row_activated),
945 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
946 G_CALLBACK(modest_ui_actions_on_header_selected), self);
948 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
949 G_CALLBACK(modest_ui_actions_on_header_activated), self);
951 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
952 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
954 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
955 G_CALLBACK(on_inner_widgets_key_pressed), self);
957 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
958 G_CALLBACK(on_msg_count_changed), self);
960 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
961 G_CALLBACK (on_header_view_focus_in), self);
963 modest_signal_mgr_connect (priv->sighandlers,
964 G_OBJECT (priv->header_view),
966 G_CALLBACK (on_updating_msg_list),
969 /* Header view CSM */
970 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
971 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
973 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
974 G_CALLBACK(_header_view_csm_menu_activated),
979 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
980 G_CALLBACK (modest_main_window_window_state_event),
982 /* we don't register this in sighandlers, as it should be run after disconnecting all signals,
983 * in destroy stage */
984 g_signal_connect (G_OBJECT (self), "destroy", G_CALLBACK (on_window_destroy), NULL);
986 g_signal_connect (G_OBJECT (self), "notify::visible", G_CALLBACK (on_window_hide), NULL);
988 /* Mail Operation Queue */
990 modest_signal_mgr_connect (priv->sighandlers,
991 G_OBJECT (modest_runtime_get_mail_operation_queue ()),
993 G_CALLBACK (on_queue_changed), self);
995 /* Track changes in the device name */
997 modest_signal_mgr_connect (priv->sighandlers,
998 G_OBJECT(modest_runtime_get_conf ()),
1000 G_CALLBACK (on_configuration_key_changed),
1003 /* Track account changes. We need to refresh the toolbar */
1005 modest_signal_mgr_connect (priv->sighandlers,
1006 G_OBJECT (modest_runtime_get_account_store ()),
1008 G_CALLBACK (on_account_inserted),
1011 modest_signal_mgr_connect (priv->sighandlers,
1012 G_OBJECT (modest_runtime_get_account_store ()),
1014 G_CALLBACK (on_account_removed),
1017 /* We need to refresh the send & receive menu to change the bold
1018 * account when the default account changes. */
1020 modest_signal_mgr_connect (priv->sighandlers,
1021 G_OBJECT (modest_runtime_get_account_mgr ()),
1022 "default_account_changed",
1023 G_CALLBACK (on_default_account_changed),
1028 modest_signal_mgr_connect (priv->sighandlers,
1029 G_OBJECT (modest_runtime_get_account_store ()),
1031 G_CALLBACK (on_account_changed),
1036 on_hildon_program_is_topmost_notify(GObject *self,
1037 GParamSpec *propert_param,
1040 HildonProgram *app = HILDON_PROGRAM (self);
1042 /* Note that use of hildon_program_set_can_hibernate()
1043 * is generally referred to as "setting the killable flag",
1044 * though hibernation does not seem equal to death.
1047 if (hildon_program_get_is_topmost (app)) {
1048 /* Prevent hibernation when the progam comes to the foreground,
1049 * because hibernation should only happen when the application
1050 * is in the background: */
1051 hildon_program_set_can_hibernate (app, FALSE);
1053 /* Remove new mail visual notifications */
1054 modest_platform_remove_new_mail_notifications (TRUE);
1056 /* Allow hibernation if the program has gone to the background: */
1058 /* However, prevent hibernation while the settings are being changed: */
1059 const gboolean hibernation_prevented =
1060 modest_window_mgr_get_hibernation_is_prevented (
1061 modest_runtime_get_window_mgr ());
1063 if (hibernation_prevented)
1064 hildon_program_set_can_hibernate (app, FALSE);
1066 /* Allow hibernation, after saving the state: */
1067 modest_osso_save_state();
1068 hildon_program_set_can_hibernate (app, TRUE);
1079 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
1081 ShowHelper *helper = (ShowHelper *) user_data;
1082 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1084 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
1085 modest_main_window_set_contents_style (MODEST_MAIN_WINDOW (self),
1086 MODEST_MAIN_WINDOW_CONTENTS_STYLE_FOLDERS);
1087 gtk_tree_view_expand_all (GTK_TREE_VIEW (priv->folder_view));
1089 gtk_widget_show (GTK_WIDGET (priv->folder_view));
1091 /* Connect signals */
1092 connect_signals (MODEST_MAIN_WINDOW (self));
1094 /* Set account store */
1095 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
1096 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1098 /* Load previous osso state, for instance if we are being restored from
1100 modest_osso_load_state ();
1102 /* Restore window & widget settings */
1103 priv->wait_for_settings = TRUE;
1104 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
1105 priv->wait_for_settings = FALSE;
1107 /* Check if accounts exist and show the account wizard if not */
1108 gboolean accounts_exist =
1109 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1111 if (!accounts_exist) {
1112 /* This is necessary to have the main window shown behind the dialog
1113 It's an ugly hack... jschmid */
1114 gtk_widget_show_all(GTK_WIDGET(self));
1115 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
1117 update_menus (MODEST_MAIN_WINDOW (self));
1120 /* Never call this function again (NOTE that it could happen
1121 as we hide the main window instead of closing it while
1122 there are operations ongoing) and free the helper */
1123 g_signal_handler_disconnect (self, helper->handler_id);
1124 g_slice_free (ShowHelper, helper);
1128 osso_display_event_cb (osso_display_state_t state,
1131 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (data);
1133 priv->display_state = state;
1135 /* Stop blinking if the screen becomes on */
1136 if (priv->display_state == OSSO_DISPLAY_ON)
1137 modest_platform_remove_new_mail_notifications (TRUE);
1141 modest_main_window_new (void)
1143 ModestMainWindow *self = NULL;
1144 ModestMainWindowPrivate *priv = NULL;
1145 ModestWindowPrivate *parent_priv = NULL;
1146 ModestDimmingRulesGroup *menu_rules_group = NULL;
1147 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1148 GtkActionGroup *action_group = NULL;
1149 GError *error = NULL;
1151 GdkPixbuf *window_icon;
1154 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
1155 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1156 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1158 parent_priv->ui_manager = gtk_ui_manager_new();
1159 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
1161 action_group = gtk_action_group_new ("ModestMainWindowActions");
1162 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1164 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1165 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1167 /* Add common actions */
1168 gtk_action_group_add_actions (action_group,
1169 modest_action_entries,
1170 G_N_ELEMENTS (modest_action_entries),
1173 gtk_action_group_add_actions (action_group,
1174 modest_folder_view_action_entries,
1175 G_N_ELEMENTS (modest_folder_view_action_entries),
1178 gtk_action_group_add_actions (action_group,
1179 modest_header_view_action_entries,
1180 G_N_ELEMENTS (modest_header_view_action_entries),
1183 gtk_action_group_add_toggle_actions (action_group,
1184 modest_toggle_action_entries,
1185 G_N_ELEMENTS (modest_toggle_action_entries),
1188 gtk_action_group_add_toggle_actions (action_group,
1189 modest_main_window_toggle_action_entries,
1190 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
1193 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
1194 g_object_unref (action_group);
1196 /* Load the UI definition */
1197 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
1198 MODEST_UIDIR "modest-main-window-ui.xml", &error);
1199 if (error != NULL) {
1200 g_warning ("Could not merge modest-ui.xml: %s", error->message);
1201 g_error_free (error);
1205 /* Add common dimming rules */
1206 modest_dimming_rules_group_add_rules (menu_rules_group,
1207 modest_main_window_menu_dimming_entries,
1208 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
1209 MODEST_WINDOW (self));
1210 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1211 modest_main_window_toolbar_dimming_entries,
1212 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
1213 MODEST_WINDOW (self));
1215 /* Insert dimming rules group for this window */
1216 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1217 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1218 g_object_unref (menu_rules_group);
1219 g_object_unref (toolbar_rules_group);
1221 /* Add accelerators */
1222 gtk_window_add_accel_group (GTK_WINDOW (self),
1223 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
1225 /* Menubar. Update the state of some toggles */
1226 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1227 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
1228 gtk_widget_show (parent_priv->menubar);
1230 /* Get device name */
1231 modest_maemo_utils_get_device_name ();
1235 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
1236 g_object_ref (priv->header_view);
1237 if (!priv->header_view)
1238 g_printerr ("modest: cannot instantiate header view\n");
1239 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
1240 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
1241 MODEST_CONF_HEADER_VIEW_KEY);
1243 /* Other style properties of header view */
1244 g_object_set (G_OBJECT (priv->header_view),
1245 "rules-hint", FALSE,
1247 /* gtk_widget_show (priv->header_view); */
1250 priv->empty_view = create_empty_view ();
1251 gtk_widget_show (priv->empty_view);
1252 g_object_ref (priv->empty_view);
1254 /* Create scrolled windows */
1255 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
1256 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
1258 GTK_POLICY_AUTOMATIC);
1259 /* gtk_widget_show (priv->contents_widget); */
1261 /* putting it all together... */
1262 priv->main_vbox = gtk_vbox_new (FALSE, 6);
1263 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->contents_widget, TRUE, TRUE,0);
1264 gtk_widget_show (priv->main_vbox);
1266 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
1268 app = hildon_program_get_instance ();
1269 hildon_program_add_window (app, HILDON_WINDOW (self));
1271 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
1272 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
1274 /* Connect to "show" action. We delay the creation of some
1275 elements until that moment */
1276 helper = g_slice_new0 (ShowHelper);
1277 helper->handler_id = g_signal_connect (G_OBJECT(self), "show",
1278 G_CALLBACK (modest_main_window_on_show),
1281 /* Set window icon */
1282 window_icon = modest_platform_get_icon (MODEST_APP_ICON, MODEST_ICON_SIZE_BIG);
1284 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
1285 g_object_unref (window_icon);
1288 /* Listen for changes in the screen, we don't want to show a
1289 led pattern when the display is on for example */
1290 osso_hw_set_display_event_cb (modest_maemo_utils_get_osso_context (),
1291 osso_display_event_cb,
1294 /* Dont't restore settings here,
1295 * because it requires a gtk_widget_show(),
1296 * and we don't want to do that until later,
1297 * so that the UI is not visible for non-menu D-Bus activation.
1300 return MODEST_WINDOW(self);
1304 modest_main_window_set_style (ModestMainWindow *self,
1305 ModestMainWindowStyle style)
1307 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1309 /* We only provide simple style */
1313 ModestMainWindowStyle
1314 modest_main_window_get_style (ModestMainWindow *self)
1316 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1318 return MODEST_MAIN_WINDOW_STYLE_SIMPLE;
1322 toolbar_resize (ModestMainWindow *self)
1324 ModestMainWindowPrivate *priv = NULL;
1325 ModestWindowPrivate *parent_priv = NULL;
1327 gint static_button_size;
1328 ModestWindowMgr *mgr;
1330 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1331 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1332 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1334 mgr = modest_runtime_get_window_mgr ();
1335 static_button_size = modest_window_mgr_get_fullscreen_mode (mgr)?118:108;
1337 if (parent_priv->toolbar) {
1338 /* left size buttons */
1339 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNew");
1340 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1341 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1342 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1343 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply");
1344 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1345 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1346 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1347 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage");
1348 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1349 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1350 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1351 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1352 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1353 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1354 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1356 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1357 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1358 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1359 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1360 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1361 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1362 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1363 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1371 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1373 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1374 ModestWindowPrivate *parent_priv;
1375 ModestWindowMgr *mgr;
1376 gboolean is_fullscreen;
1377 GtkAction *fs_toggle_action;
1380 mgr = modest_runtime_get_window_mgr ();
1382 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1384 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1386 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1387 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1388 if (is_fullscreen != active) {
1389 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1392 toolbar_resize (MODEST_MAIN_WINDOW (widget));
1400 modest_main_window_show_toolbar (ModestWindow *self,
1401 gboolean show_toolbar)
1403 ModestMainWindowPrivate *priv = NULL;
1404 ModestWindowPrivate *parent_priv = NULL;
1405 GtkWidget *reply_button = NULL, *menu = NULL;
1406 GtkWidget *placeholder = NULL;
1409 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1410 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1411 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1413 /* Set optimized view status */
1414 priv->optimized_view = !show_toolbar;
1416 if (!parent_priv->toolbar) {
1417 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1419 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1421 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1422 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1423 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1424 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1425 toolbar_resize (MODEST_MAIN_WINDOW (self));
1427 /* Add ProgressBar (Transfer toolbar) */
1428 priv->progress_bar = modest_progress_bar_new ();
1429 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1430 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1431 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1432 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1433 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1435 /* Connect cancel 'clicked' signal to abort progress mode */
1436 g_signal_connect(priv->cancel_toolitem, "clicked",
1437 G_CALLBACK(cancel_progressbar),
1440 /* Add it to the observers list */
1441 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1444 hildon_window_add_toolbar (HILDON_WINDOW (self),
1445 GTK_TOOLBAR (parent_priv->toolbar));
1447 /* Set reply button tap and hold menu */
1448 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1449 "/ToolBar/ToolbarMessageReply");
1450 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1451 "/ToolbarReplyCSM");
1452 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1454 /* Set send & receive button tap and hold menu */
1455 update_menus (MODEST_MAIN_WINDOW (self));
1459 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1460 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1461 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1463 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1464 if (modest_main_window_transfer_mode_enabled (MODEST_MAIN_WINDOW(self)))
1465 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_TRANSFER);
1467 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1469 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1475 on_account_inserted (TnyAccountStore *accoust_store,
1476 TnyAccount *account,
1479 /* Transport accounts and local ones (MMC and the Local
1480 folders account do now cause menu changes */
1481 if (TNY_IS_STORE_ACCOUNT (account) &&
1482 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account))) {
1484 update_menus (MODEST_MAIN_WINDOW (user_data));
1489 on_default_account_changed (ModestAccountMgr* mgr,
1492 update_menus (MODEST_MAIN_WINDOW (user_data));
1496 on_account_removed (TnyAccountStore *accoust_store,
1497 TnyAccount *account,
1500 /* Transport accounts and local ones (MMC and the Local
1501 folders account do now cause menu changes */
1502 if (TNY_IS_STORE_ACCOUNT (account) &&
1503 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1504 update_menus (MODEST_MAIN_WINDOW (user_data));
1508 on_account_changed (TnyAccountStore *account_store,
1509 TnyAccount *account,
1512 ModestMainWindow *win = MODEST_MAIN_WINDOW (user_data);
1514 /* Transport accounts and local ones (MMC and the Local
1515 folders account do now cause menu changes */
1516 if (TNY_IS_STORE_ACCOUNT (account)) {
1517 /* Update the menus as well, name could change */
1518 if (modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1519 update_menus (MODEST_MAIN_WINDOW (win));
1524 * This function manages the key events used to navigate between
1525 * header and folder views (when the window is in split view)
1528 * -------------------------------------------------
1529 * HeaderView GDK_Left Move focus to folder view
1530 * FolderView GDK_Right Move focus to header view
1532 * There is no need to scroll to selected row, the widgets will be the
1533 * responsibles of doing that (probably managing the focus-in event
1536 on_inner_widgets_key_pressed (GtkWidget *widget,
1540 ModestMainWindowPrivate *priv;
1542 if (event->type == GDK_KEY_RELEASE)
1545 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1547 /* Do nothing if we're in SIMPLE style */
1548 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1551 if (MODEST_IS_HEADER_VIEW (widget)) {
1552 if (event->keyval == GDK_Left)
1553 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1554 else if ((event->keyval == GDK_Return)||(event->keyval == GDK_KP_Enter)) {
1555 guint selected_headers = modest_header_view_count_selected_headers (MODEST_HEADER_VIEW (widget));
1556 if (selected_headers > 1) {
1557 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1560 GtkTreePath * cursor_path;
1561 gtk_tree_view_get_cursor (GTK_TREE_VIEW (widget), &cursor_path, NULL);
1562 if (cursor_path == NULL) {
1563 GtkTreeSelection *selection;
1565 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget));
1566 list = gtk_tree_selection_get_selected_rows (selection, NULL);
1569 gtk_tree_view_set_cursor (GTK_TREE_VIEW (widget), (GtkTreePath *) list->data, NULL, FALSE);
1570 g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
1575 } else if (MODEST_IS_FOLDER_VIEW (widget) && (event->keyval == GDK_Right || event->keyval == GDK_Left)) {
1576 #if GTK_CHECK_VERSION(2, 8, 0) /* TODO: gtk_tree_view_get_visible_range() is only available in GTK+ 2.8 */
1577 GtkTreePath *selected_path = NULL;
1578 GtkTreePath *start_path = NULL;
1579 GtkTreePath *end_path = NULL;
1581 GtkTreeSelection *selection;
1583 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->header_view));
1584 selected = gtk_tree_selection_get_selected_rows (selection, NULL);
1585 if (selected != NULL) {
1586 selected_path = (GtkTreePath *) selected->data;
1587 if (gtk_tree_view_get_visible_range (GTK_TREE_VIEW (priv->header_view),
1591 if ((gtk_tree_path_compare (start_path, selected_path) != -1) ||
1592 (gtk_tree_path_compare (end_path, selected_path) != 1)) {
1594 /* Scroll to first path */
1595 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (priv->header_view),
1604 gtk_tree_path_free (start_path);
1606 gtk_tree_path_free (end_path);
1607 g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
1608 g_list_free (selected);
1610 #endif /* GTK_CHECK_VERSION */
1612 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1619 create_empty_view (void)
1621 GtkLabel *label = NULL;
1622 GtkWidget *align = NULL;
1624 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1625 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1626 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1627 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1629 return GTK_WIDGET(align);
1634 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1636 ModestMainWindowPrivate *priv = NULL;
1638 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1640 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1642 return priv->send_receive_in_progress;
1646 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1648 GtkAction *action = NULL;
1649 GtkWidget *widget = NULL;
1650 ModestMainWindowPrivate *priv = NULL;
1652 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1653 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1655 priv->send_receive_in_progress = TRUE;
1657 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1658 gtk_action_set_sensitive (action, FALSE);
1659 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1660 /* gtk_action_set_sensitive (action, FALSE); */
1661 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1662 gtk_widget_set_sensitive (widget, FALSE);
1666 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1668 GtkAction *action = NULL;
1669 GtkWidget *widget = NULL;
1670 ModestMainWindowPrivate *priv = NULL;
1672 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1673 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1675 priv->send_receive_in_progress = FALSE;
1677 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1678 gtk_action_set_sensitive (action, TRUE);
1679 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1680 /* gtk_action_set_sensitive (action, TRUE); */
1681 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1682 gtk_widget_set_sensitive (widget, TRUE);
1687 on_msg_count_changed (ModestHeaderView *header_view,
1689 TnyFolderChange *change,
1690 ModestMainWindow *main_window)
1692 gboolean refilter = FALSE;
1693 gboolean folder_empty = FALSE;
1694 gboolean all_marked_as_deleted = FALSE;
1695 ModestMainWindowPrivate *priv;
1697 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1698 g_return_if_fail (TNY_IS_FOLDER(folder));
1699 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
1701 if (change != NULL) {
1702 TnyFolderChangeChanged changed;
1704 changed = tny_folder_change_get_changed (change);
1705 /* If something changes */
1706 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1707 folder_empty = (((guint) tny_folder_change_get_new_all_count (change)) == 0);
1709 folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1711 /* Play a sound (if configured) and make the LED blink */
1712 if (changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS) {
1713 modest_platform_push_email_notification ();
1716 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_EXPUNGED_HEADERS)
1719 folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1722 /* Check if all messages are marked to be deleted */
1723 all_marked_as_deleted = modest_header_view_is_empty (header_view);
1724 folder_empty = folder_empty || all_marked_as_deleted;
1726 /* Set contents style of headers view */
1727 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY ||
1728 priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS) {
1730 modest_main_window_set_contents_style (main_window,
1731 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1732 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1734 modest_main_window_set_contents_style (main_window,
1735 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1740 modest_header_view_refilter (header_view);
1745 modest_main_window_set_contents_style (ModestMainWindow *self,
1746 ModestMainWindowContentsStyle style)
1748 ModestMainWindowPrivate *priv;
1750 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1752 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1754 /* We allow to set the same content style than the previously
1755 set if there are details, because it could happen when we're
1756 selecting different accounts consecutively */
1757 if ((priv->contents_style == style) &&
1758 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1761 /* Remove previous child. Delete it if it was an account
1763 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1765 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1766 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
1769 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1772 priv->contents_style = style;
1774 switch (priv->contents_style) {
1775 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_FOLDERS:
1776 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->folder_view));
1777 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1779 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1781 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1782 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1783 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1785 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1786 gtk_widget_show (GTK_WIDGET (priv->header_view));
1788 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1789 g_message ("This view is not supported in Fremantle style");
1791 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
1792 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
1793 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1795 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1796 gtk_widget_grab_focus (GTK_WIDGET (priv->empty_view));
1799 g_return_if_reached ();
1803 gtk_widget_show_all (priv->contents_widget);
1806 ModestMainWindowContentsStyle
1807 modest_main_window_get_contents_style (ModestMainWindow *self)
1809 ModestMainWindowPrivate *priv;
1811 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1813 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1814 return priv->contents_style;
1819 on_configuration_key_changed (ModestConf* conf,
1821 ModestConfEvent event,
1822 ModestConfNotificationId id,
1823 ModestMainWindow *self)
1825 /* TODO: remove this handler. Now we don't support details view,
1826 * so this must be removed */
1832 set_toolbar_transfer_mode (ModestMainWindow *self)
1834 ModestMainWindowPrivate *priv = NULL;
1836 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1838 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1840 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
1842 if (priv->progress_bar_timeout > 0) {
1843 g_source_remove (priv->progress_bar_timeout);
1844 priv->progress_bar_timeout = 0;
1851 set_toolbar_mode (ModestMainWindow *self,
1852 ModestToolBarModes mode)
1854 ModestWindowPrivate *parent_priv = NULL;
1855 ModestMainWindowPrivate *priv = NULL;
1856 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
1858 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1860 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1861 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1863 /* In case this was called before the toolbar exists: */
1864 if (!(parent_priv->toolbar))
1867 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
1869 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1870 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1871 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1873 /* Sets current toolbar mode */
1874 priv->current_toolbar_mode = mode;
1876 /* Checks the dimming rules */
1877 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
1878 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
1880 /* Show and hide toolbar items */
1882 case TOOLBAR_MODE_NORMAL:
1884 gtk_action_set_visible (sort_action, TRUE);
1886 gtk_action_set_visible (refresh_action, TRUE);
1887 if (priv->progress_toolitem) {
1888 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1889 gtk_widget_hide (priv->progress_toolitem);
1891 if (priv->progress_bar)
1892 gtk_widget_hide (priv->progress_bar);
1895 gtk_action_set_visible (cancel_action, FALSE);
1897 /* Hide toolbar if optimized view is enabled */
1898 if (priv->optimized_view)
1899 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
1901 case TOOLBAR_MODE_TRANSFER:
1903 gtk_action_set_visible (sort_action, FALSE);
1905 gtk_action_set_visible (refresh_action, FALSE);
1907 gtk_action_set_visible (cancel_action, TRUE);
1908 if (priv->progress_bar)
1909 gtk_widget_show (priv->progress_bar);
1910 if (priv->progress_toolitem) {
1911 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1912 gtk_widget_show (priv->progress_toolitem);
1915 /* Show toolbar if it's hiden (optimized view ) */
1916 if (priv->optimized_view)
1917 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1920 g_return_if_reached ();
1925 modest_main_window_transfer_mode_enabled (ModestMainWindow *self)
1927 ModestMainWindowPrivate *priv;
1929 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1930 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1932 return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
1936 cancel_progressbar (GtkToolButton *toolbutton,
1937 ModestMainWindow *self)
1940 ModestMainWindowPrivate *priv;
1942 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1944 /* Get operation observers and cancel all the operations */
1945 tmp = priv->progress_widgets;
1947 modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
1948 tmp=g_slist_next(tmp);
1953 observers_empty (ModestMainWindow *self)
1956 ModestMainWindowPrivate *priv;
1957 gboolean is_empty = TRUE;
1958 guint pending_ops = 0;
1960 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1961 tmp = priv->progress_widgets;
1963 /* Check all observers */
1964 while (tmp && is_empty) {
1965 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
1966 is_empty = pending_ops == 0;
1968 tmp = g_slist_next(tmp);
1976 * Gets the toolbar mode needed for each mail operation. It stores in
1977 * @mode_changed if the toolbar mode has changed or not
1979 static ModestToolBarModes
1980 get_toolbar_mode_from_mail_operation (ModestMainWindow *self,
1981 ModestMailOperation *mail_op,
1982 gboolean *mode_changed)
1984 ModestToolBarModes mode;
1985 ModestMainWindowPrivate *priv;
1987 *mode_changed = FALSE;
1988 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
1990 /* Get toolbar mode from operation id*/
1991 switch (modest_mail_operation_get_type_operation (mail_op)) {
1992 case MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE:
1993 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
1994 mode = TOOLBAR_MODE_TRANSFER;
1995 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
1996 *mode_changed = TRUE;
1999 mode = TOOLBAR_MODE_NORMAL;
2005 on_mail_operation_started (ModestMailOperation *mail_op,
2008 ModestMainWindow *self;
2009 ModestMailOperationTypeOperation op_type;
2010 ModestMainWindowPrivate *priv;
2011 ModestToolBarModes mode;
2013 gboolean mode_changed = FALSE;
2014 TnyAccount *account = NULL;
2016 self = MODEST_MAIN_WINDOW (user_data);
2017 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2019 /* Do not show progress for receiving operations if the
2020 account is the local account or the MMC one */
2021 op_type = modest_mail_operation_get_type_operation (mail_op);
2022 account = modest_mail_operation_get_account (mail_op);
2023 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_OPEN) {
2026 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2027 modest_tny_account_is_memory_card_account (account));
2029 g_object_unref (account);
2033 /* Show information banner. Remove old timeout */
2034 if (priv->opening_banner_timeout > 0) {
2035 g_source_remove (priv->opening_banner_timeout);
2036 priv->opening_banner_timeout = 0;
2038 /* Create a new timeout */
2039 priv->opening_banner_timeout =
2040 g_timeout_add (2000, show_opening_banner, self);
2043 /* Not every mail operation has account, noop does not */
2045 g_object_unref (account);
2047 /* Get toolbar mode from operation id*/
2048 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2050 /* Add operation observers and change toolbar if neccessary*/
2051 tmp = priv->progress_widgets;
2052 if (mode == TOOLBAR_MODE_TRANSFER) {
2054 GObject *source = modest_mail_operation_get_source(mail_op);
2055 if (G_OBJECT (self) == source) {
2056 set_toolbar_transfer_mode(self);
2058 g_object_unref (source);
2062 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2064 tmp = g_slist_next (tmp);
2068 /* Update the main menu as well, we need to explicitely do
2069 this in order to enable/disable accelerators */
2070 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
2074 on_mail_operation_finished (ModestMailOperation *mail_op,
2077 ModestToolBarModes mode;
2078 ModestMailOperationTypeOperation op_type;
2080 ModestMainWindow *self;
2081 gboolean mode_changed;
2082 TnyAccount *account = NULL;
2083 ModestMainWindowPrivate *priv;
2085 self = MODEST_MAIN_WINDOW (user_data);
2086 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2088 /* The mail operation was not added to the progress objects if
2089 the account was the local account or the MMC one */
2090 op_type = modest_mail_operation_get_type_operation (mail_op);
2091 account = modest_mail_operation_get_account (mail_op);
2092 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_OPEN) {
2095 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2096 modest_tny_account_is_memory_card_account (account));
2098 g_object_unref (account);
2102 /* Remove old timeout */
2103 if (priv->opening_banner_timeout > 0) {
2104 g_source_remove (priv->opening_banner_timeout);
2105 priv->opening_banner_timeout = 0;
2108 /* Remove the banner if exists */
2109 if (priv->opening_banner) {
2110 gtk_widget_destroy (priv->opening_banner);
2111 priv->opening_banner = NULL;
2115 /* Not every mail operation has account, noop does not */
2117 g_object_unref (account);
2119 /* Get toolbar mode from operation id*/
2120 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2122 /* Change toolbar mode */
2123 tmp = priv->progress_widgets;
2124 if (mode == TOOLBAR_MODE_TRANSFER) {
2126 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2128 tmp = g_slist_next (tmp);
2131 /* If no more operations are being observed, NORMAL mode is enabled again */
2132 if (observers_empty (self)) {
2133 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
2139 on_queue_changed (ModestMailOperationQueue *queue,
2140 ModestMailOperation *mail_op,
2141 ModestMailOperationQueueNotification type,
2142 ModestMainWindow *self)
2144 ModestMainWindowPrivate *priv;
2146 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2148 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
2149 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2151 "operation-started",
2152 G_CALLBACK (on_mail_operation_started),
2154 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2156 "operation-finished",
2157 G_CALLBACK (on_mail_operation_finished),
2159 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
2160 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2162 "operation-started");
2163 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2165 "operation-finished");
2170 set_account_visible(ModestMainWindow *self, const gchar *acc_name)
2172 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2174 ModestAccountMgr *mgr;
2175 ModestAccountSettings *settings;
2176 ModestServerAccountSettings *store_settings = NULL;
2178 /* GtkWidget *folder_window; */
2180 /* folder_window = GTK_WIDGET (modest_folder_window_new (NULL)); */
2181 /* modest_window_mgr_register_window (modest_runtime_get_window_mgr (), */
2182 /* MODEST_WINDOW (folder_window), */
2183 /* MODEST_WINDOW (self)); */
2184 /* gtk_widget_show (folder_window); */
2185 GtkWidget *accounts_window;
2187 accounts_window = GTK_WIDGET (modest_accounts_window_new ());
2188 modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
2189 MODEST_WINDOW (accounts_window),
2190 MODEST_WINDOW (self));
2191 gtk_widget_show (accounts_window);
2193 /* Get account data */
2194 mgr = modest_runtime_get_account_mgr ();
2195 settings = modest_account_mgr_load_account_settings (mgr, acc_name);
2197 store_settings = modest_account_settings_get_store_settings (settings);
2199 /* Set the new visible & active account */
2200 if (settings && (modest_server_account_settings_get_account_name (store_settings)!= NULL)) {
2201 const gchar *account_name;
2203 account_name = modest_account_settings_get_account_name (settings);
2205 modest_folder_view_set_account_id_of_visible_server_account
2207 modest_server_account_settings_get_account_name (store_settings));
2208 modest_folder_view_select_first_inbox_or_local (priv->folder_view);
2209 modest_window_set_active_account (MODEST_WINDOW (self), account_name);
2211 /* modest_folder_window_set_account (MODEST_FOLDER_WINDOW (folder_window), acc_name); */
2213 action = gtk_action_group_get_action (priv->view_additions_group, account_name);
2214 if (action != NULL) {
2215 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2216 modest_utils_toggle_action_set_active_block_notify (
2217 GTK_TOGGLE_ACTION (action),
2225 g_object_unref (store_settings);
2226 g_object_unref (settings);
2231 /* Make sure that at least one account is "viewed": */
2233 set_at_least_one_account_visible(ModestMainWindow *self)
2235 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2236 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2238 if (!(priv->folder_view)) {
2239 /* It is too early to do this. */
2243 const gchar *active_server_account_name =
2244 modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);
2246 if (!active_server_account_name ||
2247 !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
2249 gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
2250 gchar* default_modest_name = modest_account_mgr_get_default_account (account_mgr);
2251 if (default_modest_name) {
2252 set_account_visible (self, default_modest_name);
2253 } else if (first_modest_name) {
2254 set_account_visible (self, first_modest_name);
2256 g_free (first_modest_name);
2257 g_free (default_modest_name);
2262 on_show_account_action_toggled (GtkToggleAction *action,
2265 ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
2267 const gchar *acc_name = gtk_action_get_name (GTK_ACTION (action));
2268 if (gtk_toggle_action_get_active (action))
2269 set_account_visible (self, acc_name);
2273 refresh_account (const gchar *account_name)
2277 /* win must already exists here, obviously */
2278 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
2281 g_warning ("%s: BUG: no main window!", __FUNCTION__);
2285 /* If account_name == NULL, we must update all (option All) */
2287 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2289 modest_ui_actions_do_send_receive (account_name, TRUE, TRUE, TRUE, win);
2294 on_refresh_account_action_activated (GtkAction *action,
2297 refresh_account ((const gchar*) user_data);
2301 on_send_receive_csm_activated (GtkMenuItem *item,
2304 refresh_account ((const gchar*) user_data);
2308 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2310 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2312 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2318 on_folder_view_focus_in (GtkWidget *widget, GdkEventFocus *event, gpointer userdata)
2320 ModestMainWindow *main_window = NULL;
2322 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2323 main_window = MODEST_MAIN_WINDOW (userdata);
2325 /* Update toolbar dimming state */
2326 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2327 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2333 on_header_view_focus_in (GtkWidget *widget,
2334 GdkEventFocus *event,
2337 ModestMainWindow *main_window = NULL;
2339 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2341 main_window = MODEST_MAIN_WINDOW (userdata);
2343 /* Update toolbar dimming state */
2344 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2345 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2351 on_folder_selection_changed (ModestFolderView *folder_view,
2352 TnyFolderStore *folder_store,
2354 ModestMainWindow *main_window)
2356 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2357 GtkAction *action = NULL;
2358 gboolean show_reply = TRUE;
2359 gboolean show_forward = TRUE;
2360 gboolean show_cancel_send = FALSE;
2361 gboolean show_clipboard = TRUE;
2362 gboolean show_delete = TRUE;
2365 if (TNY_IS_ACCOUNT (folder_store)) {
2366 show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2367 } else if (TNY_IS_FOLDER (folder_store)) {
2368 if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2369 TnyFolderType folder_type = modest_tny_folder_get_local_or_mmc_folder_type (
2370 TNY_FOLDER (folder_store));
2371 switch (folder_type) {
2372 case TNY_FOLDER_TYPE_DRAFTS:
2373 show_clipboard = show_delete = TRUE;
2374 show_reply = show_forward = show_cancel_send = FALSE;
2376 case TNY_FOLDER_TYPE_SENT:
2377 show_forward = show_clipboard = show_delete = TRUE;
2378 show_reply = show_cancel_send = FALSE;
2380 case TNY_FOLDER_TYPE_OUTBOX:
2381 show_clipboard = show_delete = show_cancel_send = TRUE;
2382 show_reply = show_forward = FALSE;
2384 case TNY_FOLDER_TYPE_INVALID:
2385 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
2388 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2389 show_cancel_send = FALSE;
2392 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2393 show_cancel_send = FALSE;
2398 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2399 gtk_action_set_visible (action, show_reply);
2400 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2401 gtk_action_set_visible (action, show_reply);
2402 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2403 gtk_action_set_visible (action, show_forward);
2404 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2405 gtk_action_set_visible (action, show_cancel_send);
2406 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2407 gtk_action_set_visible (action, show_delete);
2412 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2413 GtkTreeModel *model,
2414 GtkTreeRowReference *row_reference,
2415 ModestMainWindow *self)
2417 ModestMainWindowPrivate *priv = NULL;
2418 GtkTreeModel *header_model = NULL;
2419 GtkTreePath *path = NULL;
2421 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
2422 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2423 g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2425 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2426 header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2428 /* Do nothing if we changed the folder in the main view */
2429 if (header_model != model)
2432 /* Select the message in the header view */
2433 path = gtk_tree_row_reference_get_path (row_reference);
2434 gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->header_view),
2436 gtk_tree_path_free (path);
2442 updating_banner_destroyed (gpointer data,
2443 GObject *where_the_object_was)
2445 ModestMainWindowPrivate *priv = NULL;
2447 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (data);
2449 priv->updating_banner = NULL;
2453 show_updating_banner (gpointer user_data)
2455 ModestMainWindowPrivate *priv = NULL;
2457 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2459 if (priv->updating_banner == NULL) {
2461 /* We're outside the main lock */
2462 gdk_threads_enter ();
2463 priv->updating_banner =
2464 modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2465 _CS ("ckdg_pb_updating"));
2467 /* We need this because banners in Maemo could be
2468 destroyed by dialogs so we need to properly update
2469 our reference to it */
2470 g_object_weak_ref (G_OBJECT (priv->updating_banner),
2471 updating_banner_destroyed,
2473 gdk_threads_leave ();
2476 /* Remove timeout */
2477 priv->updating_banner_timeout = 0;
2482 * We use this function to show/hide a progress banner showing
2483 * "Updating" while the header view is being filled. We're not showing
2484 * it unless the update takes more than 2 seconds
2486 * If starting = TRUE then the refresh is starting, otherwise it means
2487 * that is has just finished
2490 on_updating_msg_list (ModestHeaderView *header_view,
2494 ModestMainWindowPrivate *priv = NULL;
2496 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2498 /* Remove old timeout */
2499 if (priv->updating_banner_timeout > 0) {
2500 g_source_remove (priv->updating_banner_timeout);
2501 priv->updating_banner_timeout = 0;
2504 /* Create a new timeout */
2506 priv->updating_banner_timeout =
2507 g_timeout_add (2000, show_updating_banner, user_data);
2509 /* Remove the banner if exists */
2510 if (priv->updating_banner) {
2511 gtk_widget_destroy (priv->updating_banner);
2512 priv->updating_banner = NULL;
2517 static void on_folder_view_row_activated (GtkTreeView *tree_view,
2518 GtkTreePath *tree_path,
2519 GtkTreeViewColumn *column,
2522 GtkTreeModel *model;
2524 TnyFolderStore *folder_store = NULL;
2525 ModestMainWindow *self = (ModestMainWindow *) userdata;
2526 ModestMainWindowPrivate *priv = NULL;
2528 g_return_if_fail (MODEST_IS_MAIN_WINDOW(self));
2529 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2531 model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
2533 if (gtk_tree_model_get_iter (model, &iter, tree_path)) {
2534 gtk_tree_model_get (model, &iter,
2535 TNY_GTK_FOLDER_STORE_TREE_MODEL_INSTANCE_COLUMN, &folder_store,
2537 if (folder_store && TNY_IS_FOLDER (folder_store)) {
2538 modest_header_view_set_folder (MODEST_HEADER_VIEW (priv->header_view),
2539 TNY_FOLDER (folder_store), TRUE, MODEST_WINDOW (self),
2541 modest_main_window_set_contents_style (MODEST_MAIN_WINDOW (self),
2542 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2543 modest_widget_memory_restore (modest_runtime_get_conf (),
2544 G_OBJECT(priv->header_view),
2545 MODEST_CONF_HEADER_VIEW_KEY);
2546 on_msg_count_changed (MODEST_HEADER_VIEW (priv->header_view), TNY_FOLDER (folder_store), NULL, self);
2550 g_object_unref (folder_store);
2553 g_message ("FOLDER VIEW CELL ACTIVATED");
2558 modest_main_window_screen_is_on (ModestMainWindow *self)
2560 ModestMainWindowPrivate *priv = NULL;
2562 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(self), FALSE);
2564 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2566 return (priv->display_state == OSSO_DISPLAY_ON) ? TRUE : FALSE;
2570 remove_banners (ModestMainWindow *window)
2572 ModestMainWindowPrivate *priv;
2574 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (window);
2576 if (priv->opening_banner_timeout > 0) {
2577 g_source_remove (priv->opening_banner_timeout);
2578 priv->opening_banner_timeout = 0;
2581 if (priv->opening_banner != NULL) {
2582 gtk_widget_destroy (priv->opening_banner);
2583 priv->opening_banner = NULL;
2586 if (priv->updating_banner_timeout > 0) {
2587 g_source_remove (priv->updating_banner_timeout);
2588 priv->updating_banner_timeout = 0;
2591 if (priv->updating_banner != NULL) {
2592 gtk_widget_destroy (priv->updating_banner);
2593 priv->updating_banner = NULL;
2599 on_window_hide (GObject *gobject,
2603 g_return_if_fail (MODEST_IS_MAIN_WINDOW (gobject));
2605 if (!GTK_WIDGET_VISIBLE (gobject)) {
2606 TnyFolderStore *folder_store;
2607 ModestMainWindowPrivate *priv;
2609 /* Remove the currently shown banners */
2610 remove_banners (MODEST_MAIN_WINDOW (gobject));
2612 /* Force the folder view to sync the currently selected folder
2613 to save the read/unread status and to expunge messages */
2614 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (gobject);
2615 folder_store = modest_folder_view_get_selected (priv->folder_view);
2616 if (TNY_IS_FOLDER (folder_store)) {
2617 ModestMailOperation *mail_op;
2619 mail_op = modest_mail_operation_new (NULL);
2620 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2622 modest_mail_operation_sync_folder (mail_op, TNY_FOLDER (folder_store), FALSE);
2623 g_object_unref (mail_op);
2624 g_object_unref (folder_store);
2630 on_window_destroy (GtkObject *widget,
2633 g_return_if_fail (MODEST_IS_MAIN_WINDOW (widget));
2635 remove_banners (MODEST_MAIN_WINDOW (widget));
2639 opening_banner_destroyed (gpointer data,
2640 GObject *where_the_object_was)
2642 ModestMainWindowPrivate *priv = NULL;
2644 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (data);
2646 priv->opening_banner = NULL;
2650 show_opening_banner (gpointer user_data)
2652 ModestMainWindowPrivate *priv = NULL;
2654 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2656 if (priv->opening_banner == NULL) {
2658 /* We're outside the main lock */
2659 gdk_threads_enter ();
2660 priv->opening_banner =
2661 modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2662 _("mail_me_opening"));
2664 /* We need this because banners in Maemo could be
2665 destroyed by dialogs so we need to properly update
2666 our reference to it */
2667 g_object_weak_ref (G_OBJECT (priv->opening_banner),
2668 opening_banner_destroyed,
2671 /* We need this because banners in Maemo could be
2672 destroyed by dialogs so we need to properly update
2673 our reference to it */
2674 g_object_weak_ref (G_OBJECT (priv->updating_banner),
2675 updating_banner_destroyed,
2677 gdk_threads_leave ();
2680 /* Remove timeout */
2681 priv->opening_banner_timeout = 0;