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>
35 #include <tny-iterator.h>
36 #include <tny-maemo-conic-device.h>
37 #include <tny-error.h>
38 #include "modest-hildon-includes.h"
39 #include "modest-defs.h"
41 #include "widgets/modest-header-view-priv.h"
42 #include "widgets/modest-main-window.h"
43 #include "widgets/modest-msg-edit-window.h"
44 #include "widgets/modest-account-view-window.h"
45 #include "modest-runtime.h"
46 #include "modest-account-mgr-helpers.h"
47 #include "modest-platform.h"
48 #include "modest-widget-memory.h"
49 #include "modest-window-priv.h"
50 #include "modest-main-window-ui.h"
51 #include "modest-main-window-ui-dimming.h"
52 #include "modest-account-mgr.h"
53 #include "modest-tny-account.h"
54 #include "modest-tny-folder.h"
55 #include "modest-conf.h"
56 #include <modest-utils.h>
57 #include <modest-maemo-utils.h>
58 #include "modest-tny-platform-factory.h"
59 #include "modest-tny-msg.h"
60 #include "modest-mail-operation.h"
61 #include "modest-icon-names.h"
62 #include "modest-progress-bar-widget.h"
63 #include "modest-text-utils.h"
64 #include "modest-ui-dimming-manager.h"
65 #include "maemo/modest-osso-state-saving.h"
66 #include "modest-text-utils.h"
67 #include "modest-signal-mgr.h"
69 #define MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS "ModestMainWindowActionAdditions"
76 /* 'private'/'protected' functions */
77 static void modest_main_window_class_init (ModestMainWindowClass *klass);
78 static void modest_main_window_init (ModestMainWindow *obj);
79 static void modest_main_window_finalize (GObject *obj);
81 static gboolean modest_main_window_window_state_event (GtkWidget *widget,
82 GdkEventWindowState *event,
85 static void connect_signals (ModestMainWindow *self);
87 static void modest_main_window_disconnect_signals (ModestWindow *self);
89 static void restore_settings (ModestMainWindow *self,
90 gboolean do_folder_view_too);
92 static void save_state (ModestWindow *self);
94 static void update_menus (ModestMainWindow* self);
96 static void modest_main_window_show_toolbar (ModestWindow *window,
97 gboolean show_toolbar);
99 static void cancel_progressbar (GtkToolButton *toolbutton,
100 ModestMainWindow *self);
102 static void on_queue_changed (ModestMailOperationQueue *queue,
103 ModestMailOperation *mail_op,
104 ModestMailOperationQueueNotification type,
105 ModestMainWindow *self);
107 static gboolean on_zoom_minus_plus_not_implemented (ModestWindow *window);
109 static void on_account_inserted (TnyAccountStore *accoust_store,
113 static void on_account_removed (TnyAccountStore *accoust_store,
117 static void on_account_changed (TnyAccountStore *account_store,
121 static void on_default_account_changed (ModestAccountMgr* mgr,
124 static gboolean on_inner_widgets_key_pressed (GtkWidget *widget,
128 static void on_configuration_key_changed (ModestConf* conf,
130 ModestConfEvent event,
131 ModestConfNotificationId id,
132 ModestMainWindow *self);
134 static void set_toolbar_mode (ModestMainWindow *self,
135 ModestToolBarModes mode);
137 static gboolean set_toolbar_transfer_mode (ModestMainWindow *self);
139 static void on_show_account_action_toggled (GtkToggleAction *action,
142 static void on_refresh_account_action_activated (GtkAction *action,
145 static void on_send_receive_csm_activated (GtkMenuItem *item,
148 static void on_msg_count_changed (ModestHeaderView *header_view,
150 TnyFolderChange *change,
151 ModestMainWindow *main_window);
153 static void modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self);
156 static GtkWidget * create_empty_view (void);
158 static gboolean on_folder_view_focus_in (GtkWidget *widget,
159 GdkEventFocus *event,
162 static gboolean on_header_view_focus_in (GtkWidget *widget,
163 GdkEventFocus *event,
166 static void on_folder_selection_changed (ModestFolderView *folder_view,
167 TnyFolderStore *folder_store,
169 ModestMainWindow *main_window);
171 static void set_at_least_one_account_visible(ModestMainWindow *self);
173 static void on_updating_msg_list (ModestHeaderView *header_view,
177 static gboolean restore_paned_timeout_handler (gpointer *data);
179 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
180 struct _ModestMainWindowPrivate {
181 GtkWidget *msg_paned;
182 GtkWidget *main_paned;
183 GtkWidget *main_vbox;
184 GtkWidget *contents_widget;
185 GtkWidget *empty_view;
187 /* Progress observers */
188 GtkWidget *progress_bar;
189 GSList *progress_widgets;
192 GtkWidget *progress_toolitem;
193 GtkWidget *cancel_toolitem;
194 GtkWidget *sort_toolitem;
195 GtkWidget *refresh_toolitem;
196 ModestToolBarModes current_toolbar_mode;
198 /* Merge ids used to add/remove accounts to the ViewMenu*/
199 GByteArray *merge_ids;
200 GtkActionGroup *view_additions_group;
202 /* On-demand widgets */
203 GtkWidget *accounts_popup;
204 GtkWidget *details_widget;
206 /* Optimized view enabled */
207 gboolean optimized_view;
209 /* Optimized view enabled */
210 gboolean send_receive_in_progress;
212 ModestHeaderView *header_view;
213 ModestFolderView *folder_view;
215 ModestMainWindowStyle style;
216 ModestMainWindowContentsStyle contents_style;
218 guint progress_bar_timeout;
219 guint restore_paned_timeout;
221 /* Signal handler UIDs */
222 GList *queue_err_signals;
225 /* "Updating" banner for header view */
226 GtkWidget *updating_banner;
227 guint updating_banner_timeout;
229 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
230 MODEST_TYPE_MAIN_WINDOW, \
231 ModestMainWindowPrivate))
233 typedef struct _GetMsgAsyncHelper {
234 ModestMainWindowPrivate *main_window_private;
236 ModestTnyMsgReplyType reply_type;
237 ModestTnyMsgForwardType forward_type;
244 static GtkWindowClass *parent_class = NULL;
247 /* Private actions */
248 /* This is the context sensitive menu: */
249 static const GtkActionEntry modest_folder_view_action_entries [] = {
251 /* Folder View CSM actions */
252 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
253 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
254 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_paste)},
255 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
256 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_search_messages) },
257 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
260 static const GtkActionEntry modest_header_view_action_entries [] = {
262 /* Header View CSM actions */
263 { "HeaderViewCSMOpen", NULL, N_("mcen_me_inbox_open"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_open) },
264 { "HeaderViewCSMReply", NULL, N_("mcen_me_inbox_reply"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply) },
265 { "HeaderViewCSMReplyAll", NULL, N_("mcen_me_inbox_replytoall"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply_all) },
266 { "HeaderViewCSMForward", NULL, N_("mcen_me_inbox_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_forward) },
267 { "HeaderViewCSMCut", NULL, N_("mcen_me_inbox_cut"), "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
268 { "HeaderViewCSMCopy", NULL, N_("mcen_me_inbox_copy"), "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
269 { "HeaderViewCSMPaste", NULL, N_("mcen_me_inbox_paste"), "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
270 { "HeaderViewCSMDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_message) },
271 { "HeaderViewCSMCancelSending", NULL, N_("mcen_me_outbox_cancelsend"), NULL, NULL, G_CALLBACK (modest_ui_actions_cancel_send) },
272 { "HeaderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
275 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
276 { "ToggleFolders", MODEST_STOCK_SPLIT_VIEW, N_("mcen_me_inbox_hidefolders"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), TRUE },
279 /************************************************************************/
282 modest_main_window_get_type (void)
284 static GType my_type = 0;
286 static const GTypeInfo my_info = {
287 sizeof(ModestMainWindowClass),
288 NULL, /* base init */
289 NULL, /* base finalize */
290 (GClassInitFunc) modest_main_window_class_init,
291 NULL, /* class finalize */
292 NULL, /* class data */
293 sizeof(ModestMainWindow),
295 (GInstanceInitFunc) modest_main_window_init,
298 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
306 modest_main_window_class_init (ModestMainWindowClass *klass)
308 GObjectClass *gobject_class;
309 gobject_class = (GObjectClass*) klass;
310 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
312 parent_class = g_type_class_peek_parent (klass);
313 gobject_class->finalize = modest_main_window_finalize;
315 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
317 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
318 modest_window_class->save_state_func = save_state;
319 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
320 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
321 modest_window_class->disconnect_signals_func = modest_main_window_disconnect_signals;
325 modest_main_window_init (ModestMainWindow *obj)
327 ModestMainWindowPrivate *priv;
329 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
331 priv->queue_err_signals = NULL;
332 priv->msg_paned = NULL;
333 priv->main_paned = NULL;
334 priv->main_vbox = NULL;
335 priv->header_view = NULL;
336 priv->folder_view = NULL;
337 priv->contents_widget = NULL;
338 priv->accounts_popup = NULL;
339 priv->details_widget = NULL;
340 priv->empty_view = NULL;
341 priv->progress_widgets = NULL;
342 priv->progress_bar = NULL;
343 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
344 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
345 priv->contents_style = -1; /* invalid contents style. We need this to select it for the first time */
346 priv->merge_ids = NULL;
347 priv->optimized_view = FALSE;
348 priv->send_receive_in_progress = FALSE;
349 priv->progress_bar_timeout = 0;
350 priv->restore_paned_timeout = 0;
351 priv->sighandlers = NULL;
352 priv->updating_banner = NULL;
353 priv->updating_banner_timeout = 0;
355 modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
357 "applications_email_mainview");
361 modest_main_window_finalize (GObject *obj)
363 ModestMainWindowPrivate *priv;
365 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
367 /* Sanity check: shouldn't be needed, the window mgr should
368 call this function before */
369 modest_main_window_disconnect_signals (MODEST_WINDOW (obj));
370 modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
372 g_slist_free (priv->progress_widgets);
374 g_byte_array_free (priv->merge_ids, TRUE);
376 if (priv->progress_bar_timeout > 0) {
377 g_source_remove (priv->progress_bar_timeout);
378 priv->progress_bar_timeout = 0;
381 if (priv->updating_banner_timeout > 0) {
382 g_source_remove (priv->updating_banner_timeout);
383 priv->updating_banner_timeout = 0;
386 if (priv->updating_banner) {
387 gtk_widget_destroy (priv->updating_banner);
388 priv->updating_banner = NULL;
391 if (priv->restore_paned_timeout > 0) {
392 g_source_remove (priv->restore_paned_timeout);
393 priv->restore_paned_timeout = 0;
396 G_OBJECT_CLASS(parent_class)->finalize (obj);
400 modest_main_window_get_child_widget (ModestMainWindow *self,
401 ModestMainWindowWidgetType widget_type)
403 ModestMainWindowPrivate *priv;
406 g_return_val_if_fail (self, NULL);
407 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_MAIN_WINDOW_WIDGET_TYPE_NUM,
410 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
412 switch (widget_type) {
413 case MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW:
414 widget = (GtkWidget*)priv->header_view; break;
415 case MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW:
416 widget = (GtkWidget*)priv->folder_view; break;
421 return widget ? GTK_WIDGET(widget) : NULL;
425 restore_paned_timeout_handler (gpointer *data)
427 ModestMainWindow *main_window = MODEST_MAIN_WINDOW (data);
428 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
431 /* Timeouts are outside the main lock */
432 gdk_threads_enter ();
433 if (GTK_WIDGET_VISIBLE (main_window)) {
434 conf = modest_runtime_get_conf ();
435 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
436 MODEST_CONF_MAIN_PANED_KEY);
438 gdk_threads_leave ();
445 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
448 ModestMainWindowPrivate *priv;
450 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
452 conf = modest_runtime_get_conf ();
454 modest_widget_memory_restore (conf, G_OBJECT(self),
455 MODEST_CONF_MAIN_WINDOW_KEY);
457 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
458 MODEST_CONF_HEADER_VIEW_KEY);
460 if (do_folder_view_too)
461 modest_widget_memory_restore (conf, G_OBJECT(priv->folder_view),
462 MODEST_CONF_FOLDER_VIEW_KEY);
464 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
465 MODEST_CONF_MAIN_PANED_KEY);
467 g_timeout_add (500, (GSourceFunc) restore_paned_timeout_handler, self);
469 /* We need to force a redraw here in order to get the right
470 position of the horizontal paned separator */
471 gtk_widget_show (GTK_WIDGET (self));
476 save_state (ModestWindow *window)
479 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
480 ModestMainWindowPrivate *priv;
482 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
483 conf = modest_runtime_get_conf ();
485 modest_widget_memory_save (conf,G_OBJECT(self),
486 MODEST_CONF_MAIN_WINDOW_KEY);
487 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
488 MODEST_CONF_MAIN_PANED_KEY);
489 // modest_widget_memory_save (conf, G_OBJECT(priv->header_view),
490 // MODEST_CONF_HEADER_VIEW_KEY);
491 modest_widget_memory_save (conf, G_OBJECT(priv->folder_view),
492 MODEST_CONF_FOLDER_VIEW_KEY);
496 compare_display_names (ModestAccountSettings *a,
497 ModestAccountSettings *b)
499 return strcmp (modest_account_settings_get_display_name (a),
500 modest_account_settings_get_display_name (b));
504 update_menus (ModestMainWindow* self)
506 GSList *account_names, *iter, *accounts;
507 ModestMainWindowPrivate *priv;
508 ModestWindowPrivate *parent_priv;
509 ModestAccountMgr *mgr;
510 gint i, num_accounts;
512 gchar *default_account;
513 const gchar *active_account_name;
514 GtkWidget *send_receive_button, *item;
515 GtkAction *send_receive_all = NULL;
518 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
519 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
521 /* Get enabled account IDs */
522 mgr = modest_runtime_get_account_mgr ();
523 account_names = modest_account_mgr_account_names (mgr, TRUE);
524 iter = account_names;
528 ModestAccountSettings *settings =
529 modest_account_mgr_load_account_settings (mgr, (gchar*) iter->data);
530 accounts = g_slist_prepend (accounts, settings);
534 modest_account_mgr_free_account_names (account_names);
535 account_names = NULL;
537 /* Order the list of accounts by its display name */
538 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
539 num_accounts = g_slist_length (accounts);
541 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
542 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
543 gtk_action_set_visible (send_receive_all, num_accounts > 0);
545 /* Delete old send&receive popup items. We can not just do a
546 menu_detach because it does not work well with
548 if (priv->accounts_popup)
549 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
550 (GtkCallback) gtk_widget_destroy, NULL);
552 /* Delete old entries in the View menu. Do not free groups, it
554 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
556 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
557 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
558 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
559 GTK_ACTION_GROUP (groups->data));
562 if (priv->merge_ids) {
563 for (i = 0; i < priv->merge_ids->len; i++)
564 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
565 g_byte_array_free (priv->merge_ids, TRUE);
567 /* We need to call this in order to ensure
568 that the new actions are added in the right
569 order (alphabetical) */
570 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
572 groups = g_list_next (groups);
574 priv->merge_ids = g_byte_array_sized_new (num_accounts);
576 /* Get send receive button */
577 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
578 "/ToolBar/ToolbarSendReceive");
580 /* Create the menu */
581 if (num_accounts > 1) {
582 if (!priv->accounts_popup)
583 priv->accounts_popup = gtk_menu_new ();
584 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
585 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
586 g_signal_connect (G_OBJECT (item),
588 G_CALLBACK (on_send_receive_csm_activated),
590 item = gtk_separator_menu_item_new ();
591 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
594 /* Create a new action group */
595 default_account = modest_account_mgr_get_default_account (mgr);
596 active_account_name = modest_window_get_active_account (MODEST_WINDOW (self));
598 if (!active_account_name)
599 modest_window_set_active_account (MODEST_WINDOW (self), default_account);
601 priv->view_additions_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
603 for (i = 0; i < num_accounts; i++) {
604 gchar *display_name = NULL;
605 const gchar *account_name;
606 ModestAccountSettings *settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
609 g_warning ("%s: BUG: account_data == NULL", __FUNCTION__);
612 account_name = modest_account_settings_get_account_name (settings);
614 if (default_account && account_name &&
615 !(strcmp (default_account, account_name) == 0)) {
616 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
617 modest_account_settings_get_display_name (settings));
619 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
620 modest_account_settings_get_display_name (settings));
623 /* Create action and add it to the action group. The
624 action name must be the account name, this way we
625 could know in the handlers the account to show */
626 if (settings && account_name) {
627 gchar* item_name, *refresh_action_name;
629 GtkAction *view_account_action, *refresh_account_action;
631 view_account_action = GTK_ACTION (gtk_radio_action_new (account_name,
632 display_name, NULL, NULL, 0));
633 gtk_action_group_add_action (priv->view_additions_group, view_account_action);
634 gtk_radio_action_set_group (GTK_RADIO_ACTION (view_account_action), radio_group);
635 radio_group = gtk_radio_action_get_group (GTK_RADIO_ACTION (view_account_action));
637 if (active_account_name) {
638 if (active_account_name && account_name &&
639 (strcmp (active_account_name, account_name) == 0)) {
640 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (view_account_action), TRUE);
644 /* Add ui from account data. We allow 2^9-1 account
645 changes in a single execution because we're
646 downcasting the guint to a guint8 in order to use a
647 GByteArray. It should be enough. */
648 item_name = g_strconcat (account_name, "Menu", NULL);
649 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
650 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
651 gtk_ui_manager_add_ui (parent_priv->ui_manager,
653 "/MenuBar/ViewMenu/ViewMenuAdditions",
656 GTK_UI_MANAGER_MENUITEM,
659 /* Connect the action signal "activate" */
660 g_signal_connect_after (G_OBJECT (view_account_action),
662 G_CALLBACK (on_show_account_action_toggled),
665 /* Create the items for the Tools->Send&Receive submenu */
666 refresh_action_name = g_strconcat ("SendReceive", account_name, NULL);
667 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
668 display_name, NULL, NULL);
669 gtk_action_group_add_action (priv->view_additions_group, refresh_account_action);
671 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
672 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
673 gtk_ui_manager_add_ui (parent_priv->ui_manager,
675 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
678 GTK_UI_MANAGER_MENUITEM,
680 g_free (refresh_action_name);
682 g_signal_connect_data (G_OBJECT (refresh_account_action),
684 G_CALLBACK (on_refresh_account_action_activated),
685 g_strdup (account_name),
686 (GClosureNotify) g_free,
689 /* Create item and add it to the send&receive
690 CSM. If there is only one account then
692 if (priv->accounts_popup) {
693 GtkWidget *label = gtk_label_new(NULL);
694 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
695 if (default_account && (strcmp(account_name, default_account) == 0))
697 gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
698 gtk_label_set_markup (GTK_LABEL (label), escaped);
703 gtk_label_set_text (GTK_LABEL (label), display_name);
706 item = gtk_menu_item_new ();
707 gtk_container_add (GTK_CONTAINER (item), label);
709 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
710 g_signal_connect_data (G_OBJECT (item),
712 G_CALLBACK (on_send_receive_csm_activated),
713 g_strdup (account_name),
714 (GClosureNotify) g_free,
721 g_free (display_name);
724 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, priv->view_additions_group, 1);
726 /* We cannot do this in the loop above because this relies on the action
727 * group being inserted. This makes the default account appear in bold.
728 * I agree it is a rather ugly way, but I don't see another possibility. armin. */
729 for (i = 0; i < num_accounts; i++) {
730 ModestAccountSettings *settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
731 const gchar *account_name;
733 account_name = modest_account_settings_get_account_name (settings);
735 if(account_name && default_account &&
736 strcmp (account_name, default_account) == 0) {
737 gchar *item_name = g_strconcat (account_name, "Menu", NULL);
739 gchar *path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
740 GtkWidget *item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
744 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
745 if (GTK_IS_LABEL (child)) {
746 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
747 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
748 gtk_label_set_markup (GTK_LABEL (child), bold_name);
753 path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", item_name, NULL);
754 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
758 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
759 if (GTK_IS_LABEL (child)) {
760 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
761 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
762 gtk_label_set_markup (GTK_LABEL (child), bold_name);
770 g_object_unref (settings);
773 if (priv->accounts_popup) {
774 /* Mandatory in order to view the menu contents */
775 gtk_widget_show_all (priv->accounts_popup);
777 /* Setup tap_and_hold just if was not done before*/
778 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
779 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
783 g_slist_free (accounts);
784 g_free (default_account);
787 /* Make sure that at least one account is viewed if there are any
788 * accounts, for instance when adding the first account: */
789 set_at_least_one_account_visible (self);
793 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
795 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
796 gtk_scrolled_window_add_with_viewport
797 (GTK_SCROLLED_WINDOW(win), widget);
799 gtk_container_add (GTK_CONTAINER(win),
810 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
812 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
814 GList *oerrsignals = priv->queue_err_signals;
815 while (oerrsignals) {
816 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
817 g_signal_handler_disconnect (esignal->queue, esignal->signal);
818 g_slice_free (QueueErrorSignal, esignal);
819 oerrsignals = g_list_next (oerrsignals);
821 g_list_free (priv->queue_err_signals);
822 priv->queue_err_signals = NULL;
827 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
829 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
832 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
836 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
838 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
840 /* Update visibility */
843 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
847 modest_main_window_disconnect_signals (ModestWindow *self)
849 ModestMainWindowPrivate *priv;
850 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
852 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
853 priv->sighandlers = NULL;
857 connect_signals (ModestMainWindow *self)
859 ModestWindowPrivate *parent_priv;
860 ModestMainWindowPrivate *priv;
863 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
864 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
869 modest_signal_mgr_connect (priv->sighandlers,
870 G_OBJECT(priv->folder_view), "key-press-event",
871 G_CALLBACK(on_inner_widgets_key_pressed), self);
873 modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view),
874 "folder_selection_changed",
875 G_CALLBACK (on_folder_selection_changed),
878 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view),
879 "folder-display-name-changed",
880 G_CALLBACK (modest_ui_actions_on_folder_display_name_changed),
883 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view),
885 G_CALLBACK (on_folder_view_focus_in),
888 /* Folder view CSM */
889 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
890 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
891 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
892 G_CALLBACK(_folder_view_csm_menu_activated),
896 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
897 G_CALLBACK(modest_ui_actions_on_header_selected), self);
899 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
900 G_CALLBACK(modest_ui_actions_on_header_activated), self);
902 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
903 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
905 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
906 G_CALLBACK(on_inner_widgets_key_pressed), self);
908 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
909 G_CALLBACK(on_msg_count_changed), self);
911 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
912 G_CALLBACK (on_header_view_focus_in), self);
914 modest_signal_mgr_connect (priv->sighandlers,
915 G_OBJECT (priv->header_view),
917 G_CALLBACK (on_updating_msg_list),
920 /* Header view CSM */
921 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
922 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
924 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
925 G_CALLBACK(_header_view_csm_menu_activated),
930 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
931 G_CALLBACK (modest_main_window_window_state_event),
934 /* Mail Operation Queue */
936 modest_signal_mgr_connect (priv->sighandlers,
937 G_OBJECT (modest_runtime_get_mail_operation_queue ()),
939 G_CALLBACK (on_queue_changed), self);
941 /* Track changes in the device name */
943 modest_signal_mgr_connect (priv->sighandlers,
944 G_OBJECT(modest_runtime_get_conf ()),
946 G_CALLBACK (on_configuration_key_changed),
949 /* Track account changes. We need to refresh the toolbar */
951 modest_signal_mgr_connect (priv->sighandlers,
952 G_OBJECT (modest_runtime_get_account_store ()),
954 G_CALLBACK (on_account_inserted),
957 modest_signal_mgr_connect (priv->sighandlers,
958 G_OBJECT (modest_runtime_get_account_store ()),
960 G_CALLBACK (on_account_removed),
963 /* We need to refresh the send & receive menu to change the bold
964 * account when the default account changes. */
966 modest_signal_mgr_connect (priv->sighandlers,
967 G_OBJECT (modest_runtime_get_account_mgr ()),
968 "default_account_changed",
969 G_CALLBACK (on_default_account_changed),
974 modest_signal_mgr_connect (priv->sighandlers,
975 G_OBJECT (modest_runtime_get_account_store ()),
977 G_CALLBACK (on_account_changed),
981 modest_signal_mgr_connect (priv->sighandlers,
982 G_OBJECT (modest_runtime_get_account_store()),
983 "password_requested",
984 G_CALLBACK (modest_ui_actions_on_password_requested),
989 /** Idle handler, to send/receive at startup .*/
991 sync_accounts_cb (ModestMainWindow *win)
993 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (win));
994 return FALSE; /* Do not call this idle handler again. */
999 on_hildon_program_is_topmost_notify(GObject *self,
1000 GParamSpec *propert_param, gpointer user_data)
1002 HildonProgram *app = HILDON_PROGRAM (self);
1005 ModestWindow* self = MODEST_WINDOW(user_data);
1008 /* Note that use of hildon_program_set_can_hibernate()
1009 * is generally referred to as "setting the killable flag",
1010 * though hibernation does not seem equal to death.
1013 if (hildon_program_get_is_topmost (app)) {
1014 /* Prevent hibernation when the progam comes to the foreground,
1015 * because hibernation should only happen when the application
1016 * is in the background: */
1017 hildon_program_set_can_hibernate (app, FALSE);
1019 /* Allow hibernation if the program has gone to the background: */
1021 /* However, prevent hibernation while the settings are being changed: */
1022 const gboolean hibernation_prevented =
1023 modest_window_mgr_get_hibernation_is_prevented (
1024 modest_runtime_get_window_mgr ());
1026 if (hibernation_prevented)
1027 hildon_program_set_can_hibernate (app, FALSE);
1029 /* Allow hibernation, after saving the state: */
1030 modest_osso_save_state();
1031 hildon_program_set_can_hibernate (app, TRUE);
1038 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
1040 GtkWidget *folder_win = (GtkWidget *) user_data;
1041 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1043 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
1044 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
1046 gtk_widget_show (GTK_WIDGET (priv->folder_view));
1048 /* Connect signals */
1049 connect_signals (MODEST_MAIN_WINDOW (self));
1051 /* Set account store */
1052 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
1053 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1055 /* Load previous osso state, for instance if we are being restored from
1057 modest_osso_load_state ();
1059 /* Restore window & widget settings */
1060 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
1062 /* Check if accounts exist and show the account wizard if not */
1063 gboolean accounts_exist =
1064 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1066 if (!accounts_exist) {
1067 /* This is necessary to have the main window shown behind the dialog
1068 It's an ugly hack... jschmid */
1069 gtk_widget_show_all(GTK_WIDGET(self));
1070 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
1073 GtkAction *send_receive_all;
1074 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1075 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
1076 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1077 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1078 gtk_action_set_visible (send_receive_all, g_slist_length (accounts) > 0);
1079 modest_account_mgr_free_account_names (accounts);
1080 update_menus (MODEST_MAIN_WINDOW (self));
1085 modest_main_window_new (void)
1087 ModestMainWindow *self = NULL;
1088 ModestMainWindowPrivate *priv = NULL;
1089 ModestWindowPrivate *parent_priv = NULL;
1090 GtkWidget *folder_win = NULL;
1091 ModestDimmingRulesGroup *menu_rules_group = NULL;
1092 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1093 GtkActionGroup *action_group = NULL;
1094 GError *error = NULL;
1096 ModestConf *conf = NULL;
1097 GtkAction *action = NULL;
1098 GdkPixbuf *window_icon;
1100 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
1101 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1102 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1104 parent_priv->ui_manager = gtk_ui_manager_new();
1105 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
1107 action_group = gtk_action_group_new ("ModestMainWindowActions");
1108 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1110 menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules", FALSE);
1111 toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules", TRUE);
1113 /* Add common actions */
1114 gtk_action_group_add_actions (action_group,
1115 modest_action_entries,
1116 G_N_ELEMENTS (modest_action_entries),
1119 gtk_action_group_add_actions (action_group,
1120 modest_folder_view_action_entries,
1121 G_N_ELEMENTS (modest_folder_view_action_entries),
1124 gtk_action_group_add_actions (action_group,
1125 modest_header_view_action_entries,
1126 G_N_ELEMENTS (modest_header_view_action_entries),
1129 gtk_action_group_add_toggle_actions (action_group,
1130 modest_toggle_action_entries,
1131 G_N_ELEMENTS (modest_toggle_action_entries),
1134 gtk_action_group_add_toggle_actions (action_group,
1135 modest_main_window_toggle_action_entries,
1136 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
1139 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
1140 g_object_unref (action_group);
1142 /* Load the UI definition */
1143 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
1144 MODEST_UIDIR "modest-main-window-ui.xml", &error);
1145 if (error != NULL) {
1146 g_warning ("Could not merge modest-ui.xml: %s", error->message);
1147 g_error_free (error);
1151 /* Add common dimming rules */
1152 modest_dimming_rules_group_add_rules (menu_rules_group,
1153 modest_main_window_menu_dimming_entries,
1154 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
1155 MODEST_WINDOW (self));
1156 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1157 modest_main_window_toolbar_dimming_entries,
1158 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
1159 MODEST_WINDOW (self));
1161 /* Insert dimming rules group for this window */
1162 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1163 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1164 g_object_unref (menu_rules_group);
1165 g_object_unref (toolbar_rules_group);
1167 /* Add accelerators */
1168 gtk_window_add_accel_group (GTK_WINDOW (self),
1169 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
1171 /* Menubar. Update the state of some toggles */
1172 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1173 conf = modest_runtime_get_conf ();
1174 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1175 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
1176 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1177 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR, NULL));
1178 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1179 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
1180 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1181 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
1182 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
1183 gtk_widget_show (parent_priv->menubar);
1185 /* Get device name */
1186 modest_maemo_utils_get_device_name ();
1190 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
1191 if (!priv->header_view)
1192 g_printerr ("modest: cannot instantiate header view\n");
1193 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
1194 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
1195 MODEST_CONF_HEADER_VIEW_KEY);
1197 /* Other style properties of header view */
1198 g_object_set (G_OBJECT (priv->header_view),
1199 "rules-hint", FALSE,
1201 /* gtk_widget_show (priv->header_view); */
1204 priv->empty_view = create_empty_view ();
1205 gtk_widget_show (priv->empty_view);
1207 /* Create scrolled windows */
1208 folder_win = gtk_scrolled_window_new (NULL, NULL);
1209 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
1210 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
1212 GTK_POLICY_AUTOMATIC);
1213 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
1215 GTK_POLICY_AUTOMATIC);
1216 /* gtk_widget_show (priv->contents_widget); */
1219 priv->main_paned = gtk_hpaned_new ();
1220 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
1221 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
1222 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
1224 /* putting it all together... */
1225 priv->main_vbox = gtk_vbox_new (FALSE, 6);
1226 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
1227 gtk_widget_show (priv->main_vbox);
1229 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
1231 app = hildon_program_get_instance ();
1232 hildon_program_add_window (app, HILDON_WINDOW (self));
1234 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
1235 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
1237 g_signal_connect (G_OBJECT(self), "show",
1238 G_CALLBACK (modest_main_window_on_show), folder_win);
1240 /* Set window icon */
1241 window_icon = modest_platform_get_icon (MODEST_APP_ICON, MODEST_ICON_SIZE_BIG);
1243 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
1244 g_object_unref (window_icon);
1247 /* Dont't restore settings here,
1248 * because it requires a gtk_widget_show(),
1249 * and we don't want to do that until later,
1250 * so that the UI is not visible for non-menu D-Bus activation.
1252 /* restore_settings (MODEST_MAIN_WINDOW(self), FALSE); */
1254 return MODEST_WINDOW(self);
1258 modest_main_window_set_style (ModestMainWindow *self,
1259 ModestMainWindowStyle style)
1261 ModestMainWindowPrivate *priv;
1262 ModestWindowPrivate *parent_priv;
1266 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1268 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1269 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1271 /* no change -> nothing to do */
1272 if (priv->style == style)
1275 /* Get toggle button and update the state if needed. This will
1276 happen only when the set_style is not invoked from the UI,
1277 for example when it's called from widget memory */
1278 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1279 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
1280 if ((active && style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) ||
1281 (!active && style == MODEST_MAIN_WINDOW_STYLE_SPLIT)) {
1282 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1283 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !active);
1284 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1287 priv->style = style;
1289 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
1290 /* Remove main paned */
1291 g_object_ref (priv->main_paned);
1292 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1294 /* Reparent the contents widget to the main vbox */
1295 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
1298 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1299 /* Remove header view */
1300 g_object_ref (priv->contents_widget);
1301 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1303 /* Reparent the main paned */
1304 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1305 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1309 g_return_if_reached ();
1312 /* Let header view grab the focus if it's being shown */
1313 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1314 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1316 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1319 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1322 ModestMainWindowStyle
1323 modest_main_window_get_style (ModestMainWindow *self)
1325 ModestMainWindowPrivate *priv;
1327 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1329 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1334 toolbar_resize (ModestMainWindow *self)
1336 ModestMainWindowPrivate *priv = NULL;
1337 ModestWindowPrivate *parent_priv = NULL;
1339 gint static_button_size;
1340 ModestWindowMgr *mgr;
1342 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1343 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1344 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1346 mgr = modest_runtime_get_window_mgr ();
1347 static_button_size = modest_window_mgr_get_fullscreen_mode (mgr)?118:108;
1349 if (parent_priv->toolbar) {
1350 /* left size buttons */
1351 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNew");
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);
1355 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply");
1356 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1357 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1358 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1359 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage");
1360 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1361 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1362 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1363 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1364 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1365 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1366 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1368 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1369 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1370 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1371 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1372 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1373 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1374 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1375 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1383 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1385 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1386 ModestWindowPrivate *parent_priv;
1387 ModestWindowMgr *mgr;
1388 gboolean is_fullscreen;
1389 GtkAction *fs_toggle_action;
1392 mgr = modest_runtime_get_window_mgr ();
1394 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1396 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1398 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1399 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1400 if (is_fullscreen != active) {
1401 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1404 toolbar_resize (MODEST_MAIN_WINDOW (widget));
1412 modest_main_window_show_toolbar (ModestWindow *self,
1413 gboolean show_toolbar)
1415 ModestMainWindowPrivate *priv = NULL;
1416 ModestWindowPrivate *parent_priv = NULL;
1417 GtkWidget *reply_button = NULL, *menu = NULL;
1418 GtkWidget *placeholder = NULL;
1420 const gchar *action_name;
1423 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1424 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1425 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1427 /* Set optimized view status */
1428 priv->optimized_view = !show_toolbar;
1430 if (!parent_priv->toolbar) {
1431 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1433 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1435 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1436 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1437 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1438 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1439 toolbar_resize (MODEST_MAIN_WINDOW (self));
1441 /* Add ProgressBar (Transfer toolbar) */
1442 priv->progress_bar = modest_progress_bar_widget_new ();
1443 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1444 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1445 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1446 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1447 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1449 /* Connect cancel 'clicked' signal to abort progress mode */
1450 g_signal_connect(priv->cancel_toolitem, "clicked",
1451 G_CALLBACK(cancel_progressbar),
1454 /* Add it to the observers list */
1455 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1458 hildon_window_add_toolbar (HILDON_WINDOW (self),
1459 GTK_TOOLBAR (parent_priv->toolbar));
1461 /* Set reply button tap and hold menu */
1462 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1463 "/ToolBar/ToolbarMessageReply");
1464 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1465 "/ToolbarReplyCSM");
1466 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1468 /* Set send & receive button tap and hold menu */
1469 update_menus (MODEST_MAIN_WINDOW (self));
1473 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1474 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1475 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1477 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1478 if (modest_main_window_transfer_mode_enabled (MODEST_MAIN_WINDOW(self)))
1479 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_TRANSFER);
1481 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1483 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1487 /* Update also the actions (to update the toggles in the
1488 menus), we have to do it manually because some other window
1489 of the same time could have changed it (remember that the
1490 toolbar fullscreen mode is shared by all the windows of the
1492 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
1493 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu";
1495 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu";
1497 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
1498 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
1503 on_account_inserted (TnyAccountStore *accoust_store,
1504 TnyAccount *account,
1507 update_menus (MODEST_MAIN_WINDOW (user_data));
1511 on_default_account_changed (ModestAccountMgr* mgr,
1514 update_menus (MODEST_MAIN_WINDOW (user_data));
1518 on_account_removed (TnyAccountStore *accoust_store,
1519 TnyAccount *account,
1522 update_menus (MODEST_MAIN_WINDOW (user_data));
1526 on_account_changed (TnyAccountStore *account_store,
1527 TnyAccount *account,
1530 ModestMainWindow *win = MODEST_MAIN_WINDOW (user_data);
1532 /* We need to refresh the details widget because it could have changed */
1533 if (modest_main_window_get_contents_style(win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS) {
1534 modest_main_window_set_contents_style (win, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1537 /* Update the menus as well, the account name could be changed */
1538 update_menus (MODEST_MAIN_WINDOW (user_data));
1542 * This function manages the key events used to navigate between
1543 * header and folder views (when the window is in split view)
1546 * -------------------------------------------------
1547 * HeaderView GDK_Left Move focus to folder view
1548 * FolderView GDK_Right Move focus to header view
1550 * There is no need to scroll to selected row, the widgets will be the
1551 * responsibles of doing that (probably managing the focus-in event
1554 on_inner_widgets_key_pressed (GtkWidget *widget,
1558 ModestMainWindowPrivate *priv;
1560 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1562 /* Do nothing if we're in SIMPLE style */
1563 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1566 if (MODEST_IS_HEADER_VIEW (widget)) {
1567 if (event->keyval == GDK_Left)
1568 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1569 else if ((event->keyval == GDK_Return)||(event->keyval == GDK_KP_Enter)) {
1570 guint selected_headers = modest_header_view_count_selected_headers (MODEST_HEADER_VIEW (widget));
1571 if (selected_headers > 1) {
1572 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1576 } else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1577 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1583 set_alignment (GtkWidget *widget,
1586 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1587 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1591 create_empty_view (void)
1593 GtkLabel *label = NULL;
1594 GtkWidget *align = NULL;
1596 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1597 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1598 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1599 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1601 return GTK_WIDGET(align);
1605 * Free the returned string
1608 get_gray_color_markup (GtkWidget *styled_widget)
1610 gchar *gray_color_markup = NULL;
1611 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1612 /* Obtain the secondary text color. We need a realized widget, that's why
1613 we get styled_widget from outside */
1615 if (gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color))
1616 gray_color_markup = modest_text_utils_get_color_string (&color);
1617 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
1619 if (!gray_color_markup)
1620 gray_color_markup = g_strdup ("#BBBBBB");
1622 return gray_color_markup;
1626 * Free the returned string
1629 create_device_name_visual_string (const gchar *device_name,
1630 const gchar *gray_color_markup)
1634 /* We have to use "" to fill the %s of the translation. We can
1635 not just use the device name because the device name is
1636 shown in a different color, so it could not be included
1637 into the <span> tag */
1638 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), "");
1639 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1649 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1651 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1656 gchar *gray_color_markup;
1658 vbox = gtk_vbox_new (FALSE, 0);
1660 gray_color_markup = get_gray_color_markup (styled_widget);
1662 /* Account description: */
1663 if (modest_tny_account_is_virtual_local_folders (account)
1664 || (modest_tny_account_is_memory_card_account (account))) {
1666 /* Get device name */
1667 gchar *device_name = NULL;
1668 if (modest_tny_account_is_virtual_local_folders (account))
1669 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1670 MODEST_CONF_DEVICE_NAME, NULL);
1672 device_name = g_strdup (tny_account_get_name (account));
1674 label = create_device_name_visual_string ((const gchar *) device_name,
1675 (const gchar *) gray_color_markup);
1676 label_w = gtk_label_new (NULL);
1677 gtk_label_set_markup (GTK_LABEL (label_w), label);
1678 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1679 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1680 g_free (device_name);
1683 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1684 gtk_box_pack_start (GTK_BOX (vbox),
1685 gtk_label_new (tny_account_get_name (account)),
1688 /* Other accounts, such as IMAP and POP: */
1693 /* Put proto in uppercase */
1694 proto = g_string_new (tny_account_get_proto (account));
1695 proto = g_string_ascii_up (proto);
1697 /* note: mcen_fi_localroot_description is something like "%s account"
1698 * however, we should display "%s account: %s"... therefore, ugly tmp */
1699 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1700 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1701 gray_color_markup, tmp, tny_account_get_name (account));
1704 label_w = gtk_label_new (NULL);
1705 gtk_label_set_markup (GTK_LABEL (label_w), label);
1706 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1707 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1708 g_string_free (proto, TRUE);
1714 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1715 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1716 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1717 modest_tny_folder_store_get_message_count (folder_store));
1718 label_w = gtk_label_new (NULL);
1719 gtk_label_set_markup (GTK_LABEL (label_w), label);
1720 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1721 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1725 label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d",
1727 _("mcen_fi_rootfolder_folders"),
1728 modest_tny_folder_store_get_folder_count (folder_store));
1729 label_w = gtk_label_new (NULL);
1730 gtk_label_set_markup (GTK_LABEL (label_w), label);
1731 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1732 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1736 if (modest_tny_account_is_virtual_local_folders (account)
1737 || modest_tny_account_is_memory_card_account (account)) {
1739 gchar *size = modest_text_utils_get_display_size (
1740 modest_tny_folder_store_get_local_size (folder_store));
1742 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1743 gray_color_markup, _("mcen_fi_rootfolder_size"),
1747 label_w = gtk_label_new (NULL);
1748 gtk_label_set_markup (GTK_LABEL (label_w), label);
1749 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1750 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1752 } else if (TNY_IS_ACCOUNT(folder_store)) {
1753 TnyAccount *account = TNY_ACCOUNT(folder_store);
1755 time_t last_updated;
1756 const gchar *last_updated_string;
1757 /* Get last updated from configuration */
1758 last_updated = modest_account_mgr_get_last_updated (modest_runtime_get_account_mgr (),
1759 tny_account_get_id (account));
1761 if (last_updated > 0)
1762 last_updated_string = modest_text_utils_get_display_date(last_updated);
1764 last_updated_string = g_strdup (_("mcen_va_never"));
1766 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1767 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1768 label_w = gtk_label_new (NULL);
1769 gtk_label_set_markup (GTK_LABEL (label_w), label);
1770 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1771 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1775 g_free (gray_color_markup);
1778 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1784 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1786 ModestMainWindowPrivate *priv = NULL;
1788 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1790 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1792 return priv->send_receive_in_progress;
1796 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1798 GtkAction *action = NULL;
1799 GtkWidget *widget = NULL;
1800 ModestMainWindowPrivate *priv = NULL;
1802 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1803 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1805 priv->send_receive_in_progress = TRUE;
1807 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1808 gtk_action_set_sensitive (action, FALSE);
1809 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1810 /* gtk_action_set_sensitive (action, FALSE); */
1811 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1812 gtk_widget_set_sensitive (widget, FALSE);
1816 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1818 GtkAction *action = NULL;
1819 GtkWidget *widget = NULL;
1820 ModestMainWindowPrivate *priv = NULL;
1822 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1823 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1825 priv->send_receive_in_progress = FALSE;
1827 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1828 gtk_action_set_sensitive (action, TRUE);
1829 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1830 /* gtk_action_set_sensitive (action, TRUE); */
1831 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1832 gtk_widget_set_sensitive (widget, TRUE);
1837 on_msg_count_changed (ModestHeaderView *header_view,
1839 TnyFolderChange *change,
1840 ModestMainWindow *main_window)
1842 gboolean folder_empty = FALSE;
1843 gboolean all_marked_as_deleted = FALSE;
1844 TnyFolderChangeChanged changed;
1845 ModestMainWindowPrivate *priv;
1847 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1848 g_return_if_fail (TNY_IS_FOLDER(folder));
1849 g_return_if_fail (TNY_IS_FOLDER_CHANGE(change));
1850 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
1852 changed = tny_folder_change_get_changed (change);
1854 /* If something changes */
1855 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1856 folder_empty = (tny_folder_change_get_new_all_count (change) == 0);
1858 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1860 /* Check header removed (hide marked as DELETED headers) */
1861 if (changed & TNY_FOLDER_CHANGE_CHANGED_EXPUNGED_HEADERS) {
1862 modest_header_view_refilter (MODEST_HEADER_VIEW(priv->header_view));
1865 /* Check if all messages are marked to be deleted */
1866 all_marked_as_deleted = modest_header_view_is_empty (header_view);
1867 folder_empty = folder_empty || all_marked_as_deleted ;
1869 /* Set contents style of headers view */
1871 modest_main_window_set_contents_style (main_window,
1872 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1873 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1876 modest_main_window_set_contents_style (main_window,
1877 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1883 modest_main_window_set_contents_style (ModestMainWindow *self,
1884 ModestMainWindowContentsStyle style)
1886 ModestMainWindowPrivate *priv;
1888 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1890 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1892 /* We allow to set the same content style than the previously
1893 set if there are details, because it could happen when we're
1894 selecting different accounts consecutively */
1895 if ((priv->contents_style == style) &&
1896 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1899 /* Remove previous child. Delete it if it was an account
1901 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1903 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1904 g_object_ref (content);
1905 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1906 g_object_ref (priv->empty_view);
1907 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
1910 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1913 priv->contents_style = style;
1915 switch (priv->contents_style) {
1916 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1917 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1918 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1921 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1923 /* if we're started without main win, there may not be a folder
1924 * view. this fixes a GLib-Critical */
1925 if (priv->folder_view) {
1926 TnyFolderStore *selected_folderstore =
1927 modest_folder_view_get_selected (priv->folder_view);
1928 if (TNY_IS_ACCOUNT (selected_folderstore)) {
1929 priv->details_widget = create_details_widget (GTK_WIDGET (self),
1930 TNY_ACCOUNT (selected_folderstore));
1932 wrap_in_scrolled_window (priv->contents_widget,
1933 priv->details_widget);
1935 g_object_unref (selected_folderstore);
1936 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1941 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
1942 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
1943 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1947 g_return_if_reached ();
1951 gtk_widget_show_all (priv->contents_widget);
1954 ModestMainWindowContentsStyle
1955 modest_main_window_get_contents_style (ModestMainWindow *self)
1957 ModestMainWindowPrivate *priv;
1959 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1961 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1962 return priv->contents_style;
1967 on_configuration_key_changed (ModestConf* conf,
1969 ModestConfEvent event,
1970 ModestConfNotificationId id,
1971 ModestMainWindow *self)
1973 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1974 TnyAccount *account = NULL;
1976 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
1979 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1982 if (priv->folder_view)
1983 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
1985 if (account && TNY_IS_ACCOUNT (account) &&
1986 strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID) == 0) {
1989 const gchar *device_name;
1990 gchar *new_text, *gray_color_markup;
1993 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
1994 label = GTK_LABEL (children->data);
1996 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1997 MODEST_CONF_DEVICE_NAME, NULL);
1999 gray_color_markup = get_gray_color_markup (GTK_WIDGET (self));
2000 new_text = create_device_name_visual_string (device_name, gray_color_markup);
2002 gtk_label_set_markup (label, new_text);
2003 gtk_widget_show (GTK_WIDGET (label));
2005 g_free (gray_color_markup);
2007 g_list_free (children);
2009 g_object_unref (account);
2013 set_toolbar_transfer_mode (ModestMainWindow *self)
2015 ModestMainWindowPrivate *priv = NULL;
2017 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2019 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2021 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
2023 if (priv->progress_bar_timeout > 0) {
2024 g_source_remove (priv->progress_bar_timeout);
2025 priv->progress_bar_timeout = 0;
2032 set_toolbar_mode (ModestMainWindow *self,
2033 ModestToolBarModes mode)
2035 ModestWindowPrivate *parent_priv = NULL;
2036 ModestMainWindowPrivate *priv = NULL;
2037 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
2039 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2041 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2042 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2044 /* In case this was called before the toolbar exists: */
2045 if (!(parent_priv->toolbar))
2048 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
2050 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
2051 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
2052 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
2054 /* Sets current toolbar mode */
2055 priv->current_toolbar_mode = mode;
2057 /* Checks the dimming rules */
2058 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2060 /* Show and hide toolbar items */
2062 case TOOLBAR_MODE_NORMAL:
2064 gtk_action_set_visible (sort_action, TRUE);
2066 gtk_action_set_visible (refresh_action, TRUE);
2067 if (priv->progress_toolitem) {
2068 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
2069 gtk_widget_hide (priv->progress_toolitem);
2071 if (priv->progress_bar)
2072 gtk_widget_hide (priv->progress_bar);
2075 gtk_action_set_visible (cancel_action, FALSE);
2077 /* Hide toolbar if optimized view is enabled */
2078 if (priv->optimized_view)
2079 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
2081 case TOOLBAR_MODE_TRANSFER:
2083 gtk_action_set_visible (sort_action, FALSE);
2085 gtk_action_set_visible (refresh_action, FALSE);
2087 gtk_action_set_visible (cancel_action, TRUE);
2088 if (priv->progress_bar)
2089 gtk_widget_show (priv->progress_bar);
2090 if (priv->progress_toolitem) {
2091 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
2092 gtk_widget_show (priv->progress_toolitem);
2095 /* Show toolbar if it's hiden (optimized view ) */
2096 if (priv->optimized_view)
2097 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2100 g_return_if_reached ();
2105 modest_main_window_transfer_mode_enabled (ModestMainWindow *self)
2107 ModestMainWindowPrivate *priv;
2109 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2110 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2112 return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
2116 cancel_progressbar (GtkToolButton *toolbutton,
2117 ModestMainWindow *self)
2120 ModestMainWindowPrivate *priv;
2122 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2124 /* Get operation observers and cancel all the operations */
2125 tmp = priv->progress_widgets;
2127 modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2128 tmp=g_slist_next(tmp);
2133 observers_empty (ModestMainWindow *self)
2136 ModestMainWindowPrivate *priv;
2137 gboolean is_empty = TRUE;
2138 guint pending_ops = 0;
2140 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2141 tmp = priv->progress_widgets;
2143 /* Check all observers */
2144 while (tmp && is_empty) {
2145 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2146 is_empty = pending_ops == 0;
2148 tmp = g_slist_next(tmp);
2156 * Gets the toolbar mode needed for each mail operation. It stores in
2157 * @mode_changed if the toolbar mode has changed or not
2159 static ModestToolBarModes
2160 get_toolbar_mode_from_mail_operation (ModestMainWindow *self,
2161 ModestMailOperation *mail_op,
2162 gboolean *mode_changed)
2164 ModestToolBarModes mode;
2165 ModestMainWindowPrivate *priv;
2167 *mode_changed = FALSE;
2168 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2170 /* Get toolbar mode from operation id*/
2171 switch (modest_mail_operation_get_type_operation (mail_op)) {
2172 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
2173 case MODEST_MAIL_OPERATION_TYPE_OPEN:
2174 mode = TOOLBAR_MODE_TRANSFER;
2175 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
2176 *mode_changed = TRUE;
2179 mode = TOOLBAR_MODE_NORMAL;
2185 on_mail_operation_started (ModestMailOperation *mail_op,
2188 ModestMainWindow *self;
2189 ModestMailOperationTypeOperation op_type;
2190 ModestMainWindowPrivate *priv;
2191 ModestToolBarModes mode;
2193 gboolean mode_changed = FALSE;
2194 TnyAccount *account;
2196 self = MODEST_MAIN_WINDOW (user_data);
2197 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2199 /* Do not show progress for receiving operations if the
2200 account is the local account or the MMC one */
2201 op_type = modest_mail_operation_get_type_operation (mail_op);
2202 account = modest_mail_operation_get_account (mail_op);
2203 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2206 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2207 modest_tny_account_is_memory_card_account (account));
2208 g_object_unref (account);
2213 /* Get toolbar mode from operation id*/
2214 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2216 /* Add operation observers and change toolbar if neccessary*/
2217 tmp = priv->progress_widgets;
2218 if (mode == TOOLBAR_MODE_TRANSFER) {
2220 GObject *source = modest_mail_operation_get_source(mail_op);
2221 if (G_OBJECT (self) == source) {
2222 set_toolbar_transfer_mode(self);
2224 g_object_unref (source);
2228 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2230 tmp = g_slist_next (tmp);
2236 on_mail_operation_finished (ModestMailOperation *mail_op,
2239 ModestToolBarModes mode;
2240 ModestMailOperationTypeOperation op_type;
2242 ModestMainWindow *self;
2243 gboolean mode_changed;
2244 TnyAccount *account;
2245 ModestMainWindowPrivate *priv;
2247 self = MODEST_MAIN_WINDOW (user_data);
2248 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2250 /* The mail operation was not added to the progress objects if
2251 the account was the local account or the MMC one */
2252 op_type = modest_mail_operation_get_type_operation (mail_op);
2253 account = modest_mail_operation_get_account (mail_op);
2254 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2257 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2258 modest_tny_account_is_memory_card_account (account));
2259 g_object_unref (account);
2264 /* Get toolbar mode from operation id*/
2265 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2267 /* Change toolbar mode */
2268 tmp = priv->progress_widgets;
2269 if (mode == TOOLBAR_MODE_TRANSFER) {
2271 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2273 tmp = g_slist_next (tmp);
2276 /* If no more operations are being observed, NORMAL mode is enabled again */
2277 if (observers_empty (self)) {
2278 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
2284 on_queue_changed (ModestMailOperationQueue *queue,
2285 ModestMailOperation *mail_op,
2286 ModestMailOperationQueueNotification type,
2287 ModestMainWindow *self)
2289 ModestMainWindowPrivate *priv;
2291 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2293 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
2294 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2296 "operation-started",
2297 G_CALLBACK (on_mail_operation_started),
2299 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2301 "operation-finished",
2302 G_CALLBACK (on_mail_operation_finished),
2304 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
2305 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2307 "operation-started");
2308 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2310 "operation-finished");
2315 set_account_visible(ModestMainWindow *self, const gchar *acc_name)
2317 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2319 ModestAccountMgr *mgr;
2320 ModestAccountSettings *settings;
2321 ModestServerAccountSettings *store_settings = NULL;
2323 /* Get account data */
2324 mgr = modest_runtime_get_account_mgr ();
2325 settings = modest_account_mgr_load_account_settings (mgr, acc_name);
2327 store_settings = modest_account_settings_get_store_settings (settings);
2329 /* Set the new visible & active account */
2330 if (settings && (modest_server_account_settings_get_account_name (store_settings)!= NULL)) {
2331 const gchar *account_name;
2333 account_name = modest_account_settings_get_account_name (settings);
2335 modest_folder_view_set_account_id_of_visible_server_account
2337 modest_server_account_settings_get_account_name (store_settings));
2338 modest_window_set_active_account (MODEST_WINDOW (self), account_name);
2339 action = gtk_action_group_get_action (priv->view_additions_group, account_name);
2340 if (action != NULL) {
2341 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2342 modest_utils_toggle_action_set_active_block_notify (
2343 GTK_TOGGLE_ACTION (action),
2349 modest_folder_view_select_first_inbox_or_local (priv->folder_view);
2354 g_object_unref (store_settings);
2355 g_object_unref (settings);
2359 /* Make sure that at least one account is "viewed": */
2361 set_at_least_one_account_visible(ModestMainWindow *self)
2363 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2364 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2366 if (!(priv->folder_view)) {
2367 /* It is too early to do this. */
2371 const gchar *active_server_account_name =
2372 modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);
2374 if (!active_server_account_name ||
2375 !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
2377 gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
2378 gchar* default_modest_name = modest_account_mgr_get_default_account (account_mgr);
2379 if (default_modest_name) {
2380 set_account_visible (self, default_modest_name);
2381 } else if (first_modest_name) {
2382 set_account_visible (self, first_modest_name);
2384 g_free (first_modest_name);
2385 g_free (default_modest_name);
2390 on_show_account_action_toggled (GtkToggleAction *action,
2393 ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
2395 const gchar *acc_name = gtk_action_get_name (GTK_ACTION (action));
2396 if (gtk_toggle_action_get_active (action))
2397 set_account_visible (self, acc_name);
2401 refresh_account (const gchar *account_name)
2405 /* win must already exists here, obviously */
2406 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
2409 g_warning ("%s: BUG: no main window!", __FUNCTION__);
2413 /* If account_name == NULL, we must update all (option All) */
2415 modest_ui_actions_do_send_receive_all (win);
2417 modest_ui_actions_do_send_receive (account_name, win);
2422 on_refresh_account_action_activated (GtkAction *action,
2425 refresh_account ((const gchar*) user_data);
2429 on_send_receive_csm_activated (GtkMenuItem *item,
2432 refresh_account ((const gchar*) user_data);
2436 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2438 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2440 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2446 on_folder_view_focus_in (GtkWidget *widget, GdkEventFocus *event, gpointer userdata)
2448 ModestMainWindow *main_window = NULL;
2450 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2451 main_window = MODEST_MAIN_WINDOW (userdata);
2453 /* Update toolbar dimming state */
2454 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2460 on_header_view_focus_in (GtkWidget *widget,
2461 GdkEventFocus *event,
2464 ModestMainWindow *main_window = NULL;
2466 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2468 main_window = MODEST_MAIN_WINDOW (userdata);
2470 /* Update toolbar dimming state */
2471 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2477 on_folder_selection_changed (ModestFolderView *folder_view,
2478 TnyFolderStore *folder_store,
2480 ModestMainWindow *main_window)
2482 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2483 GtkAction *action = NULL;
2484 gboolean show_reply = TRUE;
2485 gboolean show_forward = TRUE;
2486 gboolean show_cancel_send = FALSE;
2487 gboolean show_clipboard = TRUE;
2488 gboolean show_delete = TRUE;
2491 if (TNY_IS_ACCOUNT (folder_store)) {
2492 show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2493 } else if (TNY_IS_FOLDER (folder_store)) {
2494 if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2495 TnyFolderType folder_type = modest_tny_folder_get_local_or_mmc_folder_type (
2496 TNY_FOLDER (folder_store));
2497 switch (folder_type) {
2498 case TNY_FOLDER_TYPE_DRAFTS:
2499 show_clipboard = show_delete = TRUE;
2500 show_reply = show_forward = show_cancel_send = FALSE;
2502 case TNY_FOLDER_TYPE_SENT:
2503 show_forward = show_clipboard = show_delete = TRUE;
2504 show_reply = show_cancel_send = FALSE;
2506 case TNY_FOLDER_TYPE_OUTBOX:
2507 show_clipboard = show_delete = show_cancel_send = TRUE;
2508 show_reply = show_forward = FALSE;
2510 case TNY_FOLDER_TYPE_INVALID:
2511 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
2514 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2515 show_cancel_send = FALSE;
2518 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2519 show_cancel_send = FALSE;
2524 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2525 gtk_action_set_visible (action, show_reply);
2526 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2527 gtk_action_set_visible (action, show_reply);
2528 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2529 gtk_action_set_visible (action, show_forward);
2530 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2531 gtk_action_set_visible (action, show_cancel_send);
2532 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2533 gtk_action_set_visible (action, show_delete);
2535 /* We finally call to the ui actions handler, after updating properly
2536 * the header view CSM */
2537 modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2541 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2542 GtkTreeModel *model,
2543 GtkTreeRowReference *row_reference,
2544 ModestMainWindow *self)
2546 ModestMainWindowPrivate *priv = NULL;
2547 GtkTreeModel *header_model = NULL;
2548 GtkTreePath *path = NULL;
2550 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
2551 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2552 g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2554 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2555 header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2557 /* Do nothing if we changed the folder in the main view */
2558 if (header_model != model)
2561 /* Select the message in the header view */
2562 path = gtk_tree_row_reference_get_path (row_reference);
2563 gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->header_view),
2565 gtk_tree_path_free (path);
2571 show_updating_banner (gpointer user_data)
2573 ModestMainWindowPrivate *priv = NULL;
2575 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2577 if (priv->updating_banner == NULL) {
2579 /* We're outside the main lock */
2580 gdk_threads_enter ();
2581 priv->updating_banner =
2582 modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2583 _CS ("ckdg_pb_updating"));
2584 gdk_threads_leave ();
2587 /* Remove timeout */
2588 priv->updating_banner_timeout = 0;
2593 * We use this function to show/hide a progress banner showing
2594 * "Updating" while the header view is being filled. We're not showing
2595 * it unless the update takes more than 2 seconds
2597 * If starting = TRUE then the refresh is starting, otherwise it means
2598 * that is has just finished
2601 on_updating_msg_list (ModestHeaderView *header_view,
2605 ModestMainWindowPrivate *priv = NULL;
2607 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2609 /* Remove old timeout */
2610 if (priv->updating_banner_timeout > 0) {
2611 g_source_remove (priv->updating_banner_timeout);
2612 priv->updating_banner_timeout = 0;
2615 /* Create a new timeout */
2617 priv->updating_banner_timeout =
2618 g_timeout_add (2000, show_updating_banner, user_data);
2620 /* Remove the banner if exists */
2621 if (priv->updating_banner) {
2622 gtk_widget_destroy (priv->updating_banner);
2623 priv->updating_banner = NULL;