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;
230 osso_display_state_t display_state;
232 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
233 MODEST_TYPE_MAIN_WINDOW, \
234 ModestMainWindowPrivate))
236 typedef struct _GetMsgAsyncHelper {
237 ModestMainWindowPrivate *main_window_private;
239 ModestTnyMsgReplyType reply_type;
240 ModestTnyMsgForwardType forward_type;
247 static GtkWindowClass *parent_class = NULL;
250 /* Private actions */
251 /* This is the context sensitive menu: */
252 static const GtkActionEntry modest_folder_view_action_entries [] = {
254 /* Folder View CSM actions */
255 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
256 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
257 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_paste)},
258 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
259 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_search_messages) },
260 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
263 static const GtkActionEntry modest_header_view_action_entries [] = {
265 /* Header View CSM actions */
266 { "HeaderViewCSMOpen", NULL, N_("mcen_me_inbox_open"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_open) },
267 { "HeaderViewCSMReply", NULL, N_("mcen_me_inbox_reply"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply) },
268 { "HeaderViewCSMReplyAll", NULL, N_("mcen_me_inbox_replytoall"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply_all) },
269 { "HeaderViewCSMForward", NULL, N_("mcen_me_inbox_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_forward) },
270 { "HeaderViewCSMCut", NULL, N_("mcen_me_inbox_cut"), "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
271 { "HeaderViewCSMCopy", NULL, N_("mcen_me_inbox_copy"), "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
272 { "HeaderViewCSMPaste", NULL, N_("mcen_me_inbox_paste"), "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
273 { "HeaderViewCSMDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_message) },
274 { "HeaderViewCSMCancelSending", NULL, N_("mcen_me_outbox_cancelsend"), NULL, NULL, G_CALLBACK (modest_ui_actions_cancel_send) },
275 { "HeaderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
278 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
279 { "ToggleFolders", MODEST_STOCK_SPLIT_VIEW, N_("mcen_me_inbox_hidefolders"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), TRUE },
282 /************************************************************************/
285 modest_main_window_get_type (void)
287 static GType my_type = 0;
289 static const GTypeInfo my_info = {
290 sizeof(ModestMainWindowClass),
291 NULL, /* base init */
292 NULL, /* base finalize */
293 (GClassInitFunc) modest_main_window_class_init,
294 NULL, /* class finalize */
295 NULL, /* class data */
296 sizeof(ModestMainWindow),
298 (GInstanceInitFunc) modest_main_window_init,
301 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
309 modest_main_window_class_init (ModestMainWindowClass *klass)
311 GObjectClass *gobject_class;
312 gobject_class = (GObjectClass*) klass;
313 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
315 parent_class = g_type_class_peek_parent (klass);
316 gobject_class->finalize = modest_main_window_finalize;
318 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
320 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
321 modest_window_class->save_state_func = save_state;
322 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
323 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
324 modest_window_class->disconnect_signals_func = modest_main_window_disconnect_signals;
328 modest_main_window_init (ModestMainWindow *obj)
330 ModestMainWindowPrivate *priv;
332 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
334 priv->queue_err_signals = NULL;
335 priv->msg_paned = NULL;
336 priv->main_paned = NULL;
337 priv->main_vbox = NULL;
338 priv->header_view = NULL;
339 priv->folder_view = NULL;
340 priv->contents_widget = NULL;
341 priv->accounts_popup = NULL;
342 priv->details_widget = NULL;
343 priv->empty_view = NULL;
344 priv->progress_widgets = NULL;
345 priv->progress_bar = NULL;
346 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
347 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
348 priv->contents_style = -1; /* invalid contents style. We need this to select it for the first time */
349 priv->merge_ids = NULL;
350 priv->optimized_view = FALSE;
351 priv->send_receive_in_progress = FALSE;
352 priv->progress_bar_timeout = 0;
353 priv->restore_paned_timeout = 0;
354 priv->sighandlers = NULL;
355 priv->updating_banner = NULL;
356 priv->updating_banner_timeout = 0;
357 priv->display_state = OSSO_DISPLAY_ON;
359 modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
361 "applications_email_mainview");
365 modest_main_window_finalize (GObject *obj)
367 ModestMainWindowPrivate *priv;
369 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
371 /* Sanity check: shouldn't be needed, the window mgr should
372 call this function before */
373 modest_main_window_disconnect_signals (MODEST_WINDOW (obj));
374 modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
376 g_slist_free (priv->progress_widgets);
378 g_byte_array_free (priv->merge_ids, TRUE);
380 if (priv->progress_bar_timeout > 0) {
381 g_source_remove (priv->progress_bar_timeout);
382 priv->progress_bar_timeout = 0;
385 if (priv->updating_banner_timeout > 0) {
386 g_source_remove (priv->updating_banner_timeout);
387 priv->updating_banner_timeout = 0;
390 if (priv->updating_banner) {
391 gtk_widget_destroy (priv->updating_banner);
392 priv->updating_banner = NULL;
395 if (priv->restore_paned_timeout > 0) {
396 g_source_remove (priv->restore_paned_timeout);
397 priv->restore_paned_timeout = 0;
400 G_OBJECT_CLASS(parent_class)->finalize (obj);
404 modest_main_window_get_child_widget (ModestMainWindow *self,
405 ModestMainWindowWidgetType widget_type)
407 ModestMainWindowPrivate *priv;
410 g_return_val_if_fail (self && MODEST_IS_MAIN_WINDOW(self), NULL);
411 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_MAIN_WINDOW_WIDGET_TYPE_NUM,
414 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
416 switch (widget_type) {
417 case MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW:
418 widget = (GtkWidget*)priv->header_view; break;
419 case MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW:
420 widget = (GtkWidget*)priv->folder_view; break;
425 return widget ? GTK_WIDGET(widget) : NULL;
429 restore_paned_timeout_handler (gpointer *data)
431 ModestMainWindow *main_window = MODEST_MAIN_WINDOW (data);
432 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
435 /* Timeouts are outside the main lock */
436 gdk_threads_enter ();
437 if (GTK_WIDGET_VISIBLE (main_window)) {
438 conf = modest_runtime_get_conf ();
439 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
440 MODEST_CONF_MAIN_PANED_KEY);
442 gdk_threads_leave ();
449 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
452 ModestMainWindowPrivate *priv;
454 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
456 conf = modest_runtime_get_conf ();
458 modest_widget_memory_restore (conf, G_OBJECT(self),
459 MODEST_CONF_MAIN_WINDOW_KEY);
461 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
462 MODEST_CONF_HEADER_VIEW_KEY);
464 if (do_folder_view_too)
465 modest_widget_memory_restore (conf, G_OBJECT(priv->folder_view),
466 MODEST_CONF_FOLDER_VIEW_KEY);
468 /* modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned), */
469 /* MODEST_CONF_MAIN_PANED_KEY); */
471 g_timeout_add (250, (GSourceFunc) restore_paned_timeout_handler, self);
473 /* We need to force a redraw here in order to get the right
474 position of the horizontal paned separator */
475 gtk_widget_show (GTK_WIDGET (self));
480 save_state (ModestWindow *window)
483 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
484 ModestMainWindowPrivate *priv;
486 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
487 conf = modest_runtime_get_conf ();
489 modest_widget_memory_save (conf,G_OBJECT(self),
490 MODEST_CONF_MAIN_WINDOW_KEY);
491 /* Only save main paned position if we're in split mode */
492 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SPLIT)
493 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
494 MODEST_CONF_MAIN_PANED_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 strcmp (modest_account_settings_get_display_name (a),
504 modest_account_settings_get_display_name (b));
507 /* We use this function to prevent the send&receive CSM to be shown
508 when there are less than two account */
510 tap_and_hold_query_cb (GtkWidget *widget, GdkEvent *event)
516 update_menus (ModestMainWindow* self)
518 GSList *account_names, *iter, *accounts;
519 ModestMainWindowPrivate *priv;
520 ModestWindowPrivate *parent_priv;
521 ModestAccountMgr *mgr;
522 gint i, num_accounts;
524 gchar *default_account;
525 const gchar *active_account_name;
526 GtkWidget *send_receive_button, *item;
527 GtkAction *send_receive_all = NULL;
530 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
531 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
533 /* Get enabled account IDs */
534 mgr = modest_runtime_get_account_mgr ();
535 account_names = modest_account_mgr_account_names (mgr, TRUE);
536 iter = account_names;
540 ModestAccountSettings *settings =
541 modest_account_mgr_load_account_settings (mgr, (gchar*) iter->data);
542 accounts = g_slist_prepend (accounts, settings);
546 modest_account_mgr_free_account_names (account_names);
547 account_names = NULL;
549 /* Order the list of accounts by its display name */
550 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
551 num_accounts = g_slist_length (accounts);
553 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
554 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
555 gtk_action_set_visible (send_receive_all, num_accounts > 0);
557 /* Delete old send&receive popup items. We can not just do a
558 menu_detach because it does not work well with
560 if (priv->accounts_popup)
561 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
562 (GtkCallback) gtk_widget_destroy, NULL);
564 /* Delete old entries in the View menu. Do not free groups, it
566 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
568 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
569 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
570 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
571 GTK_ACTION_GROUP (groups->data));
574 if (priv->merge_ids) {
575 for (i = 0; i < priv->merge_ids->len; i++)
576 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
577 g_byte_array_free (priv->merge_ids, TRUE);
579 /* We need to call this in order to ensure
580 that the new actions are added in the right
581 order (alphabetical) */
582 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
584 groups = g_list_next (groups);
586 priv->merge_ids = g_byte_array_sized_new (num_accounts);
588 /* Get send receive button */
589 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
590 "/ToolBar/ToolbarSendReceive");
592 /* Create the menu */
593 if (num_accounts > 1) {
594 if (!priv->accounts_popup)
595 priv->accounts_popup = gtk_menu_new ();
596 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
597 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
598 g_signal_connect (G_OBJECT (item),
600 G_CALLBACK (on_send_receive_csm_activated),
602 item = gtk_separator_menu_item_new ();
603 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
606 /* Create a new action group */
607 default_account = modest_account_mgr_get_default_account (mgr);
608 active_account_name = modest_window_get_active_account (MODEST_WINDOW (self));
610 if (!active_account_name)
611 modest_window_set_active_account (MODEST_WINDOW (self), default_account);
613 priv->view_additions_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
615 for (i = 0; i < num_accounts; i++) {
616 gchar *display_name = NULL;
617 const gchar *account_name;
618 ModestAccountSettings *settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
621 g_warning ("%s: BUG: account_data == NULL", __FUNCTION__);
624 account_name = modest_account_settings_get_account_name (settings);
626 if (default_account && account_name &&
627 !(strcmp (default_account, account_name) == 0)) {
628 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
629 modest_account_settings_get_display_name (settings));
631 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
632 modest_account_settings_get_display_name (settings));
635 /* Create action and add it to the action group. The
636 action name must be the account name, this way we
637 could know in the handlers the account to show */
638 if (settings && account_name) {
639 gchar* item_name, *refresh_action_name;
641 GtkAction *view_account_action, *refresh_account_action;
643 view_account_action = GTK_ACTION (gtk_radio_action_new (account_name,
644 display_name, NULL, NULL, 0));
645 gtk_action_group_add_action (priv->view_additions_group, view_account_action);
646 gtk_radio_action_set_group (GTK_RADIO_ACTION (view_account_action), radio_group);
647 radio_group = gtk_radio_action_get_group (GTK_RADIO_ACTION (view_account_action));
649 if (active_account_name) {
650 if (active_account_name && account_name &&
651 (strcmp (active_account_name, account_name) == 0)) {
652 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (view_account_action), TRUE);
656 /* Add ui from account data. We allow 2^9-1 account
657 changes in a single execution because we're
658 downcasting the guint to a guint8 in order to use a
659 GByteArray. It should be enough. */
660 item_name = g_strconcat (account_name, "Menu", NULL);
661 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
662 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
663 gtk_ui_manager_add_ui (parent_priv->ui_manager,
665 "/MenuBar/ViewMenu/ViewMenuAdditions",
668 GTK_UI_MANAGER_MENUITEM,
671 /* Connect the action signal "activate" */
672 g_signal_connect_after (G_OBJECT (view_account_action),
674 G_CALLBACK (on_show_account_action_toggled),
677 /* Create the items for the Tools->Send&Receive submenu */
678 refresh_action_name = g_strconcat ("SendReceive", account_name, NULL);
679 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
680 display_name, NULL, NULL);
681 gtk_action_group_add_action (priv->view_additions_group, refresh_account_action);
683 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
684 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
685 gtk_ui_manager_add_ui (parent_priv->ui_manager,
687 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
690 GTK_UI_MANAGER_MENUITEM,
692 g_free (refresh_action_name);
694 g_signal_connect_data (G_OBJECT (refresh_account_action),
696 G_CALLBACK (on_refresh_account_action_activated),
697 g_strdup (account_name),
698 (GClosureNotify) g_free,
701 /* Create item and add it to the send&receive
702 CSM. If there is only one account then
704 if (num_accounts > 1) {
705 GtkWidget *label = gtk_label_new(NULL);
706 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
707 if (default_account && (strcmp(account_name, default_account) == 0)) {
708 gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
709 gtk_label_set_markup (GTK_LABEL (label), escaped);
712 gtk_label_set_text (GTK_LABEL (label), display_name);
715 item = gtk_menu_item_new ();
716 gtk_container_add (GTK_CONTAINER (item), label);
718 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
719 g_signal_connect_data (G_OBJECT (item),
721 G_CALLBACK (on_send_receive_csm_activated),
722 g_strdup (account_name),
723 (GClosureNotify) g_free,
730 g_free (display_name);
733 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, priv->view_additions_group, 1);
735 /* We cannot do this in the loop above because this relies on the action
736 * group being inserted. This makes the default account appear in bold.
737 * I agree it is a rather ugly way, but I don't see another possibility. armin. */
738 for (i = 0; i < num_accounts; i++) {
739 gchar *item_name, *path;
741 ModestAccountSettings *settings;
742 const gchar *account_name;
745 settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
746 account_name = modest_account_settings_get_account_name (settings);
747 is_default = (account_name && default_account && !strcmp (account_name, default_account));
749 /* Get the item of the view menu */
750 item_name = g_strconcat (account_name, "Menu", NULL);
751 path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
752 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
756 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
757 if (GTK_IS_LABEL (child)) {
758 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
760 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
761 gtk_label_set_markup (GTK_LABEL (child), bold_name);
764 gtk_label_set_ellipsize (GTK_LABEL (child), PANGO_ELLIPSIZE_END);
768 /* Get the item of the tools menu */
769 path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", item_name, NULL);
770 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
774 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
775 if (GTK_IS_LABEL (child)) {
776 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
778 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
779 gtk_label_set_markup (GTK_LABEL (child), bold_name);
782 gtk_label_set_ellipsize (GTK_LABEL (child), PANGO_ELLIPSIZE_END);
787 g_object_unref (settings);
790 if (num_accounts > 1) {
791 /* Disconnect the tap-and-hold-query if it's connected */
792 if (modest_signal_mgr_is_connected (priv->sighandlers,
793 G_OBJECT (send_receive_button),
794 "tap-and-hold-query"))
795 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
796 G_OBJECT (send_receive_button),
797 "tap-and-hold-query");
799 /* Mandatory in order to view the menu contents */
800 gtk_widget_show_all (priv->accounts_popup);
802 /* Setup tap_and_hold just if was not done before*/
803 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
804 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
806 /* Connect the tap-and-hold-query in order not to show the CSM */
807 if (!modest_signal_mgr_is_connected (priv->sighandlers,
808 G_OBJECT (send_receive_button),
809 "tap-and-hold-query"))
810 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
811 G_OBJECT (send_receive_button),
812 "tap-and-hold-query",
813 G_CALLBACK (tap_and_hold_query_cb),
818 g_slist_free (accounts);
819 g_free (default_account);
822 /* Make sure that at least one account is viewed if there are any
823 * accounts, for instance when adding the first account: */
824 set_at_least_one_account_visible (self);
828 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
830 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
831 gtk_scrolled_window_add_with_viewport
832 (GTK_SCROLLED_WINDOW(win), widget);
834 gtk_container_add (GTK_CONTAINER(win),
845 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
847 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
849 GList *oerrsignals = priv->queue_err_signals;
850 while (oerrsignals) {
851 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
852 g_signal_handler_disconnect (esignal->queue, esignal->signal);
853 g_slice_free (QueueErrorSignal, esignal);
854 oerrsignals = g_list_next (oerrsignals);
856 g_list_free (priv->queue_err_signals);
857 priv->queue_err_signals = NULL;
862 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
864 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
867 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
871 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
873 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
875 /* Update visibility */
878 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
882 modest_main_window_disconnect_signals (ModestWindow *self)
884 ModestMainWindowPrivate *priv;
885 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
887 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
888 priv->sighandlers = NULL;
892 connect_signals (ModestMainWindow *self)
894 ModestWindowPrivate *parent_priv;
895 ModestMainWindowPrivate *priv;
898 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
899 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
904 modest_signal_mgr_connect (priv->sighandlers,
905 G_OBJECT(priv->folder_view), "key-press-event",
906 G_CALLBACK(on_inner_widgets_key_pressed), self);
908 modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view),
909 "folder_selection_changed",
910 G_CALLBACK (on_folder_selection_changed),
913 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view),
914 "folder-display-name-changed",
915 G_CALLBACK (modest_ui_actions_on_folder_display_name_changed),
918 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view),
920 G_CALLBACK (on_folder_view_focus_in),
923 /* Folder view CSM */
924 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
925 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
926 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
927 G_CALLBACK(_folder_view_csm_menu_activated),
931 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
932 G_CALLBACK(modest_ui_actions_on_header_selected), self);
934 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
935 G_CALLBACK(modest_ui_actions_on_header_activated), self);
937 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
938 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
940 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
941 G_CALLBACK(on_inner_widgets_key_pressed), self);
943 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
944 G_CALLBACK(on_msg_count_changed), self);
946 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
947 G_CALLBACK (on_header_view_focus_in), self);
949 modest_signal_mgr_connect (priv->sighandlers,
950 G_OBJECT (priv->header_view),
952 G_CALLBACK (on_updating_msg_list),
955 /* Header view CSM */
956 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
957 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
959 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
960 G_CALLBACK(_header_view_csm_menu_activated),
965 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
966 G_CALLBACK (modest_main_window_window_state_event),
969 /* Mail Operation Queue */
971 modest_signal_mgr_connect (priv->sighandlers,
972 G_OBJECT (modest_runtime_get_mail_operation_queue ()),
974 G_CALLBACK (on_queue_changed), self);
976 /* Track changes in the device name */
978 modest_signal_mgr_connect (priv->sighandlers,
979 G_OBJECT(modest_runtime_get_conf ()),
981 G_CALLBACK (on_configuration_key_changed),
984 /* Track account changes. We need to refresh the toolbar */
986 modest_signal_mgr_connect (priv->sighandlers,
987 G_OBJECT (modest_runtime_get_account_store ()),
989 G_CALLBACK (on_account_inserted),
992 modest_signal_mgr_connect (priv->sighandlers,
993 G_OBJECT (modest_runtime_get_account_store ()),
995 G_CALLBACK (on_account_removed),
998 /* We need to refresh the send & receive menu to change the bold
999 * account when the default account changes. */
1001 modest_signal_mgr_connect (priv->sighandlers,
1002 G_OBJECT (modest_runtime_get_account_mgr ()),
1003 "default_account_changed",
1004 G_CALLBACK (on_default_account_changed),
1009 modest_signal_mgr_connect (priv->sighandlers,
1010 G_OBJECT (modest_runtime_get_account_store ()),
1012 G_CALLBACK (on_account_changed),
1016 modest_signal_mgr_connect (priv->sighandlers,
1017 G_OBJECT (modest_runtime_get_account_store()),
1018 "password_requested",
1019 G_CALLBACK (modest_ui_actions_on_password_requested),
1024 on_hildon_program_is_topmost_notify(GObject *self,
1025 GParamSpec *propert_param,
1028 HildonProgram *app = HILDON_PROGRAM (self);
1030 /* Note that use of hildon_program_set_can_hibernate()
1031 * is generally referred to as "setting the killable flag",
1032 * though hibernation does not seem equal to death.
1035 if (hildon_program_get_is_topmost (app)) {
1036 /* Prevent hibernation when the progam comes to the foreground,
1037 * because hibernation should only happen when the application
1038 * is in the background: */
1039 hildon_program_set_can_hibernate (app, FALSE);
1041 /* Remove new mail visual notifications */
1042 modest_platform_remove_new_mail_notifications (TRUE);
1044 /* Allow hibernation if the program has gone to the background: */
1046 /* However, prevent hibernation while the settings are being changed: */
1047 const gboolean hibernation_prevented =
1048 modest_window_mgr_get_hibernation_is_prevented (
1049 modest_runtime_get_window_mgr ());
1051 if (hibernation_prevented)
1052 hildon_program_set_can_hibernate (app, FALSE);
1054 /* Allow hibernation, after saving the state: */
1055 modest_osso_save_state();
1056 hildon_program_set_can_hibernate (app, TRUE);
1062 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
1064 GtkWidget *folder_win = (GtkWidget *) user_data;
1065 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1067 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
1068 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
1070 gtk_widget_show (GTK_WIDGET (priv->folder_view));
1072 /* Connect signals */
1073 connect_signals (MODEST_MAIN_WINDOW (self));
1075 /* Set account store */
1076 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
1077 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1079 /* Load previous osso state, for instance if we are being restored from
1081 modest_osso_load_state ();
1083 /* Restore window & widget settings */
1084 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
1086 /* Check if accounts exist and show the account wizard if not */
1087 gboolean accounts_exist =
1088 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1090 if (!accounts_exist) {
1091 /* This is necessary to have the main window shown behind the dialog
1092 It's an ugly hack... jschmid */
1093 gtk_widget_show_all(GTK_WIDGET(self));
1094 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
1097 GtkAction *send_receive_all;
1098 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1099 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
1100 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1101 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1102 gtk_action_set_visible (send_receive_all, g_slist_length (accounts) > 0);
1103 modest_account_mgr_free_account_names (accounts);
1104 update_menus (MODEST_MAIN_WINDOW (self));
1109 osso_display_event_cb (osso_display_state_t state,
1112 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (data);
1114 priv->display_state = state;
1116 /* Stop blinking if the screen becomes on */
1117 if (priv->display_state == OSSO_DISPLAY_ON)
1118 modest_platform_remove_new_mail_notifications (TRUE);
1122 modest_main_window_new (void)
1124 ModestMainWindow *self = NULL;
1125 ModestMainWindowPrivate *priv = NULL;
1126 ModestWindowPrivate *parent_priv = NULL;
1127 GtkWidget *folder_win = NULL;
1128 ModestDimmingRulesGroup *menu_rules_group = NULL;
1129 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1130 GtkActionGroup *action_group = NULL;
1131 GError *error = NULL;
1133 ModestConf *conf = NULL;
1134 GtkAction *action = NULL;
1135 GdkPixbuf *window_icon;
1137 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
1138 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1139 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1141 parent_priv->ui_manager = gtk_ui_manager_new();
1142 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
1144 action_group = gtk_action_group_new ("ModestMainWindowActions");
1145 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1147 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1148 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1150 /* Add common actions */
1151 gtk_action_group_add_actions (action_group,
1152 modest_action_entries,
1153 G_N_ELEMENTS (modest_action_entries),
1156 gtk_action_group_add_actions (action_group,
1157 modest_folder_view_action_entries,
1158 G_N_ELEMENTS (modest_folder_view_action_entries),
1161 gtk_action_group_add_actions (action_group,
1162 modest_header_view_action_entries,
1163 G_N_ELEMENTS (modest_header_view_action_entries),
1166 gtk_action_group_add_toggle_actions (action_group,
1167 modest_toggle_action_entries,
1168 G_N_ELEMENTS (modest_toggle_action_entries),
1171 gtk_action_group_add_toggle_actions (action_group,
1172 modest_main_window_toggle_action_entries,
1173 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
1176 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
1177 g_object_unref (action_group);
1179 /* Load the UI definition */
1180 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
1181 MODEST_UIDIR "modest-main-window-ui.xml", &error);
1182 if (error != NULL) {
1183 g_warning ("Could not merge modest-ui.xml: %s", error->message);
1184 g_error_free (error);
1188 /* Add common dimming rules */
1189 modest_dimming_rules_group_add_rules (menu_rules_group,
1190 modest_main_window_menu_dimming_entries,
1191 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
1192 MODEST_WINDOW (self));
1193 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1194 modest_main_window_toolbar_dimming_entries,
1195 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
1196 MODEST_WINDOW (self));
1198 /* Insert dimming rules group for this window */
1199 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1200 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1201 g_object_unref (menu_rules_group);
1202 g_object_unref (toolbar_rules_group);
1204 /* Add accelerators */
1205 gtk_window_add_accel_group (GTK_WINDOW (self),
1206 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
1208 /* Menubar. Update the state of some toggles */
1209 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1210 conf = modest_runtime_get_conf ();
1211 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1212 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
1213 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1214 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR, NULL));
1215 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1216 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
1217 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1218 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
1219 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
1220 gtk_widget_show (parent_priv->menubar);
1222 /* Get device name */
1223 modest_maemo_utils_get_device_name ();
1227 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
1228 if (!priv->header_view)
1229 g_printerr ("modest: cannot instantiate header view\n");
1230 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
1231 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
1232 MODEST_CONF_HEADER_VIEW_KEY);
1234 /* Other style properties of header view */
1235 g_object_set (G_OBJECT (priv->header_view),
1236 "rules-hint", FALSE,
1238 /* gtk_widget_show (priv->header_view); */
1241 priv->empty_view = create_empty_view ();
1242 gtk_widget_show (priv->empty_view);
1244 /* Create scrolled windows */
1245 folder_win = gtk_scrolled_window_new (NULL, NULL);
1246 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
1247 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
1249 GTK_POLICY_AUTOMATIC);
1250 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
1252 GTK_POLICY_AUTOMATIC);
1253 /* gtk_widget_show (priv->contents_widget); */
1256 priv->main_paned = gtk_hpaned_new ();
1257 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
1258 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
1259 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
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->main_paned, 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 g_signal_connect (G_OBJECT(self), "show",
1275 G_CALLBACK (modest_main_window_on_show), folder_win);
1277 /* Set window icon */
1278 window_icon = modest_platform_get_icon (MODEST_APP_ICON, MODEST_ICON_SIZE_BIG);
1280 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
1281 g_object_unref (window_icon);
1284 /* Listen for changes in the screen, we don't want to show a
1285 led pattern when the display is on for example */
1286 osso_hw_set_display_event_cb (modest_maemo_utils_get_osso_context (),
1287 osso_display_event_cb,
1290 /* Dont't restore settings here,
1291 * because it requires a gtk_widget_show(),
1292 * and we don't want to do that until later,
1293 * so that the UI is not visible for non-menu D-Bus activation.
1296 return MODEST_WINDOW(self);
1300 modest_main_window_set_style (ModestMainWindow *self,
1301 ModestMainWindowStyle style)
1303 ModestMainWindowPrivate *priv;
1304 ModestWindowPrivate *parent_priv;
1308 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1310 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1311 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1313 /* no change -> nothing to do */
1314 if (priv->style == style)
1317 /* Get toggle button and update the state if needed. This will
1318 happen only when the set_style is not invoked from the UI,
1319 for example when it's called from widget memory */
1320 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1321 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
1322 if ((active && style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) ||
1323 (!active && style == MODEST_MAIN_WINDOW_STYLE_SPLIT)) {
1324 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1325 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !active);
1326 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1329 priv->style = style;
1331 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
1332 /* Remove main paned */
1333 g_object_ref (priv->main_paned);
1334 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1336 /* Reparent the contents widget to the main vbox */
1337 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
1340 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1341 /* Remove header view */
1342 g_object_ref (priv->contents_widget);
1343 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1345 /* Reparent the main paned */
1346 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1347 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1351 g_return_if_reached ();
1354 /* Let header view grab the focus if it's being shown */
1355 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1356 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1358 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1361 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1364 ModestMainWindowStyle
1365 modest_main_window_get_style (ModestMainWindow *self)
1367 ModestMainWindowPrivate *priv;
1369 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1371 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1376 toolbar_resize (ModestMainWindow *self)
1378 ModestMainWindowPrivate *priv = NULL;
1379 ModestWindowPrivate *parent_priv = NULL;
1381 gint static_button_size;
1382 ModestWindowMgr *mgr;
1384 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1385 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1386 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1388 mgr = modest_runtime_get_window_mgr ();
1389 static_button_size = modest_window_mgr_get_fullscreen_mode (mgr)?118:108;
1391 if (parent_priv->toolbar) {
1392 /* left size buttons */
1393 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNew");
1394 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1395 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1396 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1397 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply");
1398 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1399 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1400 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1401 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage");
1402 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1403 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1404 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1405 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1406 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1407 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1408 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1410 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1411 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1412 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1413 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1414 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1415 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1416 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1417 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1425 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1427 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1428 ModestWindowPrivate *parent_priv;
1429 ModestWindowMgr *mgr;
1430 gboolean is_fullscreen;
1431 GtkAction *fs_toggle_action;
1434 mgr = modest_runtime_get_window_mgr ();
1436 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1438 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1440 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1441 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1442 if (is_fullscreen != active) {
1443 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1446 toolbar_resize (MODEST_MAIN_WINDOW (widget));
1454 modest_main_window_show_toolbar (ModestWindow *self,
1455 gboolean show_toolbar)
1457 ModestMainWindowPrivate *priv = NULL;
1458 ModestWindowPrivate *parent_priv = NULL;
1459 GtkWidget *reply_button = NULL, *menu = NULL;
1460 GtkWidget *placeholder = NULL;
1462 const gchar *action_name;
1465 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1466 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1467 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1469 /* Set optimized view status */
1470 priv->optimized_view = !show_toolbar;
1472 if (!parent_priv->toolbar) {
1473 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1475 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1477 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1478 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1479 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1480 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1481 toolbar_resize (MODEST_MAIN_WINDOW (self));
1483 /* Add ProgressBar (Transfer toolbar) */
1484 priv->progress_bar = modest_progress_bar_widget_new ();
1485 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1486 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1487 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1488 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1489 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1491 /* Connect cancel 'clicked' signal to abort progress mode */
1492 g_signal_connect(priv->cancel_toolitem, "clicked",
1493 G_CALLBACK(cancel_progressbar),
1496 /* Add it to the observers list */
1497 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1500 hildon_window_add_toolbar (HILDON_WINDOW (self),
1501 GTK_TOOLBAR (parent_priv->toolbar));
1503 /* Set reply button tap and hold menu */
1504 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1505 "/ToolBar/ToolbarMessageReply");
1506 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1507 "/ToolbarReplyCSM");
1508 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1510 /* Set send & receive button tap and hold menu */
1511 update_menus (MODEST_MAIN_WINDOW (self));
1515 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1516 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1517 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1519 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1520 if (modest_main_window_transfer_mode_enabled (MODEST_MAIN_WINDOW(self)))
1521 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_TRANSFER);
1523 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1525 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1529 /* Update also the actions (to update the toggles in the
1530 menus), we have to do it manually because some other window
1531 of the same time could have changed it (remember that the
1532 toolbar fullscreen mode is shared by all the windows of the
1534 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
1535 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu";
1537 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu";
1539 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
1540 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
1545 on_account_inserted (TnyAccountStore *accoust_store,
1546 TnyAccount *account,
1549 /* Transport accounts and local ones (MMC and the Local
1550 folders account do now cause menu changes */
1551 if (TNY_IS_STORE_ACCOUNT (account) &&
1552 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1553 update_menus (MODEST_MAIN_WINDOW (user_data));
1557 on_default_account_changed (ModestAccountMgr* mgr,
1560 update_menus (MODEST_MAIN_WINDOW (user_data));
1564 on_account_removed (TnyAccountStore *accoust_store,
1565 TnyAccount *account,
1568 /* Transport accounts and local ones (MMC and the Local
1569 folders account do now cause menu changes */
1570 if (TNY_IS_STORE_ACCOUNT (account) &&
1571 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1572 update_menus (MODEST_MAIN_WINDOW (user_data));
1576 on_account_changed (TnyAccountStore *account_store,
1577 TnyAccount *account,
1580 ModestMainWindow *win = MODEST_MAIN_WINDOW (user_data);
1582 /* We need to refresh the details widget because it could have changed */
1583 if (modest_main_window_get_contents_style(win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS) {
1584 modest_main_window_set_contents_style (win, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1587 /* Update the menus as well, the account name could be
1588 changed. Transport accounts and local ones (MMC and the
1589 Local folders account do now cause menu changes */
1590 if (TNY_IS_STORE_ACCOUNT (account) &&
1591 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1592 update_menus (MODEST_MAIN_WINDOW (user_data));
1596 * This function manages the key events used to navigate between
1597 * header and folder views (when the window is in split view)
1600 * -------------------------------------------------
1601 * HeaderView GDK_Left Move focus to folder view
1602 * FolderView GDK_Right Move focus to header view
1604 * There is no need to scroll to selected row, the widgets will be the
1605 * responsibles of doing that (probably managing the focus-in event
1608 on_inner_widgets_key_pressed (GtkWidget *widget,
1612 ModestMainWindowPrivate *priv;
1614 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1616 /* Do nothing if we're in SIMPLE style */
1617 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1620 if (MODEST_IS_HEADER_VIEW (widget)) {
1621 if (event->keyval == GDK_Left)
1622 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1623 else if ((event->keyval == GDK_Return)||(event->keyval == GDK_KP_Enter)) {
1624 guint selected_headers = modest_header_view_count_selected_headers (MODEST_HEADER_VIEW (widget));
1625 if (selected_headers > 1) {
1626 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1630 } else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1631 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1637 set_alignment (GtkWidget *widget,
1640 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1641 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1645 create_empty_view (void)
1647 GtkLabel *label = NULL;
1648 GtkWidget *align = NULL;
1650 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1651 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1652 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1653 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1655 return GTK_WIDGET(align);
1659 * Free the returned string
1662 get_gray_color_markup (GtkWidget *styled_widget)
1664 gchar *gray_color_markup = NULL;
1665 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1666 /* Obtain the secondary text color. We need a realized widget, that's why
1667 we get styled_widget from outside */
1669 if (gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color))
1670 gray_color_markup = modest_text_utils_get_color_string (&color);
1671 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
1673 if (!gray_color_markup)
1674 gray_color_markup = g_strdup ("#BBBBBB");
1676 return gray_color_markup;
1680 * Free the returned string
1683 create_device_name_visual_string (const gchar *device_name,
1684 const gchar *gray_color_markup)
1688 /* We have to use "" to fill the %s of the translation. We can
1689 not just use the device name because the device name is
1690 shown in a different color, so it could not be included
1691 into the <span> tag */
1692 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), "");
1693 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1703 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1705 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1710 gchar *gray_color_markup;
1712 vbox = gtk_vbox_new (FALSE, 0);
1714 gray_color_markup = get_gray_color_markup (styled_widget);
1716 /* Account description: */
1717 if (modest_tny_account_is_virtual_local_folders (account)
1718 || (modest_tny_account_is_memory_card_account (account))) {
1720 /* Get device name */
1721 gchar *device_name = NULL;
1722 if (modest_tny_account_is_virtual_local_folders (account))
1723 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1724 MODEST_CONF_DEVICE_NAME, NULL);
1726 device_name = g_strdup (tny_account_get_name (account));
1728 label = create_device_name_visual_string ((const gchar *) device_name,
1729 (const gchar *) gray_color_markup);
1730 label_w = gtk_label_new (NULL);
1731 gtk_label_set_markup (GTK_LABEL (label_w), label);
1732 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1733 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1734 g_free (device_name);
1737 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1738 gtk_box_pack_start (GTK_BOX (vbox),
1739 gtk_label_new (tny_account_get_name (account)),
1742 /* Other accounts, such as IMAP and POP: */
1747 /* Put proto in uppercase */
1748 proto = g_string_new (tny_account_get_proto (account));
1749 proto = g_string_ascii_up (proto);
1751 /* note: mcen_fi_localroot_description is something like "%s account"
1752 * however, we should display "%s account: %s"... therefore, ugly tmp */
1753 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1754 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1755 gray_color_markup, tmp, tny_account_get_name (account));
1758 label_w = gtk_label_new (NULL);
1759 gtk_label_set_markup (GTK_LABEL (label_w), label);
1760 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1761 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1762 g_string_free (proto, TRUE);
1768 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1769 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1770 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1771 modest_tny_folder_store_get_message_count (folder_store));
1772 label_w = gtk_label_new (NULL);
1773 gtk_label_set_markup (GTK_LABEL (label_w), label);
1774 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1775 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1779 label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d",
1781 _("mcen_fi_rootfolder_folders"),
1782 modest_tny_folder_store_get_folder_count (folder_store));
1783 label_w = gtk_label_new (NULL);
1784 gtk_label_set_markup (GTK_LABEL (label_w), label);
1785 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1786 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1790 if (modest_tny_account_is_virtual_local_folders (account)
1791 || modest_tny_account_is_memory_card_account (account)) {
1793 gchar *size = modest_text_utils_get_display_size (
1794 modest_tny_folder_store_get_local_size (folder_store));
1796 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1797 gray_color_markup, _("mcen_fi_rootfolder_size"),
1801 label_w = gtk_label_new (NULL);
1802 gtk_label_set_markup (GTK_LABEL (label_w), label);
1803 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1804 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1806 } else if (TNY_IS_ACCOUNT(folder_store)) {
1807 TnyAccount *account = TNY_ACCOUNT(folder_store);
1809 time_t last_updated;
1810 const gchar *last_updated_string;
1811 /* Get last updated from configuration */
1812 last_updated = modest_account_mgr_get_last_updated (modest_runtime_get_account_mgr (),
1813 tny_account_get_id (account));
1815 if (last_updated > 0)
1816 last_updated_string = modest_text_utils_get_display_date(last_updated);
1818 last_updated_string = g_strdup (_("mcen_va_never"));
1820 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1821 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1822 label_w = gtk_label_new (NULL);
1823 gtk_label_set_markup (GTK_LABEL (label_w), label);
1824 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1825 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1829 g_free (gray_color_markup);
1832 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1838 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1840 ModestMainWindowPrivate *priv = NULL;
1842 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1844 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1846 return priv->send_receive_in_progress;
1850 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1852 GtkAction *action = NULL;
1853 GtkWidget *widget = NULL;
1854 ModestMainWindowPrivate *priv = NULL;
1856 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1857 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1859 priv->send_receive_in_progress = TRUE;
1861 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1862 gtk_action_set_sensitive (action, FALSE);
1863 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1864 /* gtk_action_set_sensitive (action, FALSE); */
1865 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1866 gtk_widget_set_sensitive (widget, FALSE);
1870 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1872 GtkAction *action = NULL;
1873 GtkWidget *widget = NULL;
1874 ModestMainWindowPrivate *priv = NULL;
1876 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1877 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1879 priv->send_receive_in_progress = FALSE;
1881 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1882 gtk_action_set_sensitive (action, TRUE);
1883 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1884 /* gtk_action_set_sensitive (action, TRUE); */
1885 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1886 gtk_widget_set_sensitive (widget, TRUE);
1891 on_msg_count_changed (ModestHeaderView *header_view,
1893 TnyFolderChange *change,
1894 ModestMainWindow *main_window)
1896 gboolean folder_empty = FALSE;
1897 gboolean all_marked_as_deleted = FALSE;
1898 ModestMainWindowPrivate *priv;
1900 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1901 g_return_if_fail (TNY_IS_FOLDER(folder));
1902 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
1904 if (change != NULL) {
1905 TnyFolderChangeChanged changed;
1907 changed = tny_folder_change_get_changed (change);
1908 /* If something changes */
1909 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1910 folder_empty = (((guint) tny_folder_change_get_new_all_count (change)) == 0);
1912 folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1914 /* Play a sound (if configured) and make the LED blink */
1915 if (changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS) {
1916 modest_platform_on_new_headers_received (NULL, FALSE);
1920 /* Check if all messages are marked to be deleted */
1921 all_marked_as_deleted = modest_header_view_is_empty (header_view);
1922 folder_empty = folder_empty || all_marked_as_deleted;
1924 /* Set contents style of headers view */
1926 modest_main_window_set_contents_style (main_window,
1927 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1928 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1930 modest_main_window_set_contents_style (main_window,
1931 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1937 modest_main_window_set_contents_style (ModestMainWindow *self,
1938 ModestMainWindowContentsStyle style)
1940 ModestMainWindowPrivate *priv;
1942 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1944 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1946 /* We allow to set the same content style than the previously
1947 set if there are details, because it could happen when we're
1948 selecting different accounts consecutively */
1949 if ((priv->contents_style == style) &&
1950 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1953 /* Remove previous child. Delete it if it was an account
1955 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1957 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1958 g_object_ref (content);
1959 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1960 g_object_ref (priv->empty_view);
1961 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
1964 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1967 priv->contents_style = style;
1969 switch (priv->contents_style) {
1970 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1971 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1972 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1975 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1977 /* if we're started without main win, there may not be a folder
1978 * view. this fixes a GLib-Critical */
1979 if (priv->folder_view) {
1980 TnyFolderStore *selected_folderstore =
1981 modest_folder_view_get_selected (priv->folder_view);
1982 if (TNY_IS_ACCOUNT (selected_folderstore)) {
1983 priv->details_widget = create_details_widget (GTK_WIDGET (self),
1984 TNY_ACCOUNT (selected_folderstore));
1986 wrap_in_scrolled_window (priv->contents_widget,
1987 priv->details_widget);
1989 g_object_unref (selected_folderstore);
1990 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1995 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
1996 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
1997 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2001 g_return_if_reached ();
2005 gtk_widget_show_all (priv->contents_widget);
2008 ModestMainWindowContentsStyle
2009 modest_main_window_get_contents_style (ModestMainWindow *self)
2011 ModestMainWindowPrivate *priv;
2013 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
2015 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2016 return priv->contents_style;
2021 on_configuration_key_changed (ModestConf* conf,
2023 ModestConfEvent event,
2024 ModestConfNotificationId id,
2025 ModestMainWindow *self)
2027 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2028 TnyAccount *account = NULL;
2030 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
2033 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
2036 if (priv->folder_view)
2037 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
2039 if (account && TNY_IS_ACCOUNT (account) &&
2040 strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID) == 0) {
2043 const gchar *device_name;
2044 gchar *new_text, *gray_color_markup;
2047 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
2048 label = GTK_LABEL (children->data);
2050 device_name = modest_conf_get_string (modest_runtime_get_conf(),
2051 MODEST_CONF_DEVICE_NAME, NULL);
2053 gray_color_markup = get_gray_color_markup (GTK_WIDGET (self));
2054 new_text = create_device_name_visual_string (device_name, gray_color_markup);
2056 gtk_label_set_markup (label, new_text);
2057 gtk_widget_show (GTK_WIDGET (label));
2059 g_free (gray_color_markup);
2061 g_list_free (children);
2063 g_object_unref (account);
2067 set_toolbar_transfer_mode (ModestMainWindow *self)
2069 ModestMainWindowPrivate *priv = NULL;
2071 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2073 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2075 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
2077 if (priv->progress_bar_timeout > 0) {
2078 g_source_remove (priv->progress_bar_timeout);
2079 priv->progress_bar_timeout = 0;
2086 set_toolbar_mode (ModestMainWindow *self,
2087 ModestToolBarModes mode)
2089 ModestWindowPrivate *parent_priv = NULL;
2090 ModestMainWindowPrivate *priv = NULL;
2091 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
2093 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2095 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2096 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2098 /* In case this was called before the toolbar exists: */
2099 if (!(parent_priv->toolbar))
2102 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
2104 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
2105 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
2106 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
2108 /* Sets current toolbar mode */
2109 priv->current_toolbar_mode = mode;
2111 /* Checks the dimming rules */
2112 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2114 /* Show and hide toolbar items */
2116 case TOOLBAR_MODE_NORMAL:
2118 gtk_action_set_visible (sort_action, TRUE);
2120 gtk_action_set_visible (refresh_action, TRUE);
2121 if (priv->progress_toolitem) {
2122 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
2123 gtk_widget_hide (priv->progress_toolitem);
2125 if (priv->progress_bar)
2126 gtk_widget_hide (priv->progress_bar);
2129 gtk_action_set_visible (cancel_action, FALSE);
2131 /* Hide toolbar if optimized view is enabled */
2132 if (priv->optimized_view)
2133 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
2135 case TOOLBAR_MODE_TRANSFER:
2137 gtk_action_set_visible (sort_action, FALSE);
2139 gtk_action_set_visible (refresh_action, FALSE);
2141 gtk_action_set_visible (cancel_action, TRUE);
2142 if (priv->progress_bar)
2143 gtk_widget_show (priv->progress_bar);
2144 if (priv->progress_toolitem) {
2145 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
2146 gtk_widget_show (priv->progress_toolitem);
2149 /* Show toolbar if it's hiden (optimized view ) */
2150 if (priv->optimized_view)
2151 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2154 g_return_if_reached ();
2159 modest_main_window_transfer_mode_enabled (ModestMainWindow *self)
2161 ModestMainWindowPrivate *priv;
2163 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2164 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2166 return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
2170 cancel_progressbar (GtkToolButton *toolbutton,
2171 ModestMainWindow *self)
2174 ModestMainWindowPrivate *priv;
2176 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2178 /* Get operation observers and cancel all the operations */
2179 tmp = priv->progress_widgets;
2181 modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2182 tmp=g_slist_next(tmp);
2187 observers_empty (ModestMainWindow *self)
2190 ModestMainWindowPrivate *priv;
2191 gboolean is_empty = TRUE;
2192 guint pending_ops = 0;
2194 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2195 tmp = priv->progress_widgets;
2197 /* Check all observers */
2198 while (tmp && is_empty) {
2199 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2200 is_empty = pending_ops == 0;
2202 tmp = g_slist_next(tmp);
2210 * Gets the toolbar mode needed for each mail operation. It stores in
2211 * @mode_changed if the toolbar mode has changed or not
2213 static ModestToolBarModes
2214 get_toolbar_mode_from_mail_operation (ModestMainWindow *self,
2215 ModestMailOperation *mail_op,
2216 gboolean *mode_changed)
2218 ModestToolBarModes mode;
2219 ModestMainWindowPrivate *priv;
2221 *mode_changed = FALSE;
2222 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2224 /* Get toolbar mode from operation id*/
2225 switch (modest_mail_operation_get_type_operation (mail_op)) {
2226 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
2227 case MODEST_MAIL_OPERATION_TYPE_OPEN:
2228 mode = TOOLBAR_MODE_TRANSFER;
2229 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
2230 *mode_changed = TRUE;
2233 mode = TOOLBAR_MODE_NORMAL;
2239 on_mail_operation_started (ModestMailOperation *mail_op,
2242 ModestMainWindow *self;
2243 ModestMailOperationTypeOperation op_type;
2244 ModestMainWindowPrivate *priv;
2245 ModestToolBarModes mode;
2247 gboolean mode_changed = FALSE;
2248 TnyAccount *account;
2250 self = MODEST_MAIN_WINDOW (user_data);
2251 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2253 /* Do not show progress for receiving operations if the
2254 account is the local account or the MMC one */
2255 op_type = modest_mail_operation_get_type_operation (mail_op);
2256 account = modest_mail_operation_get_account (mail_op);
2257 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2260 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2261 modest_tny_account_is_memory_card_account (account));
2262 g_object_unref (account);
2267 /* Get toolbar mode from operation id*/
2268 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2270 /* Add operation observers and change toolbar if neccessary*/
2271 tmp = priv->progress_widgets;
2272 if (mode == TOOLBAR_MODE_TRANSFER) {
2274 GObject *source = modest_mail_operation_get_source(mail_op);
2275 if (G_OBJECT (self) == source) {
2276 set_toolbar_transfer_mode(self);
2278 g_object_unref (source);
2282 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2284 tmp = g_slist_next (tmp);
2290 on_mail_operation_finished (ModestMailOperation *mail_op,
2293 ModestToolBarModes mode;
2294 ModestMailOperationTypeOperation op_type;
2296 ModestMainWindow *self;
2297 gboolean mode_changed;
2298 TnyAccount *account;
2299 ModestMainWindowPrivate *priv;
2301 self = MODEST_MAIN_WINDOW (user_data);
2302 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2304 /* The mail operation was not added to the progress objects if
2305 the account was the local account or the MMC one */
2306 op_type = modest_mail_operation_get_type_operation (mail_op);
2307 account = modest_mail_operation_get_account (mail_op);
2308 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2311 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2312 modest_tny_account_is_memory_card_account (account));
2313 g_object_unref (account);
2318 /* Get toolbar mode from operation id*/
2319 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2321 /* Change toolbar mode */
2322 tmp = priv->progress_widgets;
2323 if (mode == TOOLBAR_MODE_TRANSFER) {
2325 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2327 tmp = g_slist_next (tmp);
2330 /* If no more operations are being observed, NORMAL mode is enabled again */
2331 if (observers_empty (self)) {
2332 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
2338 on_queue_changed (ModestMailOperationQueue *queue,
2339 ModestMailOperation *mail_op,
2340 ModestMailOperationQueueNotification type,
2341 ModestMainWindow *self)
2343 ModestMainWindowPrivate *priv;
2345 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2347 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
2348 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2350 "operation-started",
2351 G_CALLBACK (on_mail_operation_started),
2353 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2355 "operation-finished",
2356 G_CALLBACK (on_mail_operation_finished),
2358 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
2359 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2361 "operation-started");
2362 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2364 "operation-finished");
2369 set_account_visible(ModestMainWindow *self, const gchar *acc_name)
2371 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2373 ModestAccountMgr *mgr;
2374 ModestAccountSettings *settings;
2375 ModestServerAccountSettings *store_settings = NULL;
2377 /* Get account data */
2378 mgr = modest_runtime_get_account_mgr ();
2379 settings = modest_account_mgr_load_account_settings (mgr, acc_name);
2381 store_settings = modest_account_settings_get_store_settings (settings);
2383 /* Set the new visible & active account */
2384 if (settings && (modest_server_account_settings_get_account_name (store_settings)!= NULL)) {
2385 const gchar *account_name;
2387 account_name = modest_account_settings_get_account_name (settings);
2389 modest_folder_view_set_account_id_of_visible_server_account
2391 modest_server_account_settings_get_account_name (store_settings));
2392 modest_window_set_active_account (MODEST_WINDOW (self), account_name);
2393 action = gtk_action_group_get_action (priv->view_additions_group, account_name);
2394 if (action != NULL) {
2395 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2396 modest_utils_toggle_action_set_active_block_notify (
2397 GTK_TOGGLE_ACTION (action),
2403 modest_folder_view_select_first_inbox_or_local (priv->folder_view);
2408 g_object_unref (store_settings);
2409 g_object_unref (settings);
2413 /* Make sure that at least one account is "viewed": */
2415 set_at_least_one_account_visible(ModestMainWindow *self)
2417 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2418 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2420 if (!(priv->folder_view)) {
2421 /* It is too early to do this. */
2425 const gchar *active_server_account_name =
2426 modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);
2428 if (!active_server_account_name ||
2429 !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
2431 gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
2432 gchar* default_modest_name = modest_account_mgr_get_default_account (account_mgr);
2433 if (default_modest_name) {
2434 set_account_visible (self, default_modest_name);
2435 } else if (first_modest_name) {
2436 set_account_visible (self, first_modest_name);
2438 g_free (first_modest_name);
2439 g_free (default_modest_name);
2444 on_show_account_action_toggled (GtkToggleAction *action,
2447 ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
2449 const gchar *acc_name = gtk_action_get_name (GTK_ACTION (action));
2450 if (gtk_toggle_action_get_active (action))
2451 set_account_visible (self, acc_name);
2455 refresh_account (const gchar *account_name)
2459 /* win must already exists here, obviously */
2460 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
2463 g_warning ("%s: BUG: no main window!", __FUNCTION__);
2467 /* If account_name == NULL, we must update all (option All) */
2469 modest_ui_actions_do_send_receive_all (win, FALSE);
2471 modest_ui_actions_do_send_receive (account_name, FALSE, win);
2476 on_refresh_account_action_activated (GtkAction *action,
2479 refresh_account ((const gchar*) user_data);
2483 on_send_receive_csm_activated (GtkMenuItem *item,
2486 refresh_account ((const gchar*) user_data);
2490 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2492 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2494 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2500 on_folder_view_focus_in (GtkWidget *widget, GdkEventFocus *event, gpointer userdata)
2502 ModestMainWindow *main_window = NULL;
2504 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2505 main_window = MODEST_MAIN_WINDOW (userdata);
2507 /* Update toolbar dimming state */
2508 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2514 on_header_view_focus_in (GtkWidget *widget,
2515 GdkEventFocus *event,
2518 ModestMainWindow *main_window = NULL;
2520 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2522 main_window = MODEST_MAIN_WINDOW (userdata);
2524 /* Update toolbar dimming state */
2525 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2531 on_folder_selection_changed (ModestFolderView *folder_view,
2532 TnyFolderStore *folder_store,
2534 ModestMainWindow *main_window)
2536 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2537 GtkAction *action = NULL;
2538 gboolean show_reply = TRUE;
2539 gboolean show_forward = TRUE;
2540 gboolean show_cancel_send = FALSE;
2541 gboolean show_clipboard = TRUE;
2542 gboolean show_delete = TRUE;
2545 if (TNY_IS_ACCOUNT (folder_store)) {
2546 show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2547 } else if (TNY_IS_FOLDER (folder_store)) {
2548 if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2549 TnyFolderType folder_type = modest_tny_folder_get_local_or_mmc_folder_type (
2550 TNY_FOLDER (folder_store));
2551 switch (folder_type) {
2552 case TNY_FOLDER_TYPE_DRAFTS:
2553 show_clipboard = show_delete = TRUE;
2554 show_reply = show_forward = show_cancel_send = FALSE;
2556 case TNY_FOLDER_TYPE_SENT:
2557 show_forward = show_clipboard = show_delete = TRUE;
2558 show_reply = show_cancel_send = FALSE;
2560 case TNY_FOLDER_TYPE_OUTBOX:
2561 show_clipboard = show_delete = show_cancel_send = TRUE;
2562 show_reply = show_forward = FALSE;
2564 case TNY_FOLDER_TYPE_INVALID:
2565 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
2568 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2569 show_cancel_send = FALSE;
2572 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2573 show_cancel_send = FALSE;
2578 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2579 gtk_action_set_visible (action, show_reply);
2580 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2581 gtk_action_set_visible (action, show_reply);
2582 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2583 gtk_action_set_visible (action, show_forward);
2584 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2585 gtk_action_set_visible (action, show_cancel_send);
2586 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2587 gtk_action_set_visible (action, show_delete);
2589 /* We finally call to the ui actions handler, after updating properly
2590 * the header view CSM */
2591 modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2595 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2596 GtkTreeModel *model,
2597 GtkTreeRowReference *row_reference,
2598 ModestMainWindow *self)
2600 ModestMainWindowPrivate *priv = NULL;
2601 GtkTreeModel *header_model = NULL;
2602 GtkTreePath *path = NULL;
2604 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
2605 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2606 g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2608 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2609 header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2611 /* Do nothing if we changed the folder in the main view */
2612 if (header_model != model)
2615 /* Select the message in the header view */
2616 path = gtk_tree_row_reference_get_path (row_reference);
2617 gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->header_view),
2619 gtk_tree_path_free (path);
2625 show_updating_banner (gpointer user_data)
2627 ModestMainWindowPrivate *priv = NULL;
2629 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2631 if (priv->updating_banner == NULL) {
2633 /* We're outside the main lock */
2634 gdk_threads_enter ();
2635 priv->updating_banner =
2636 modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2637 _CS ("ckdg_pb_updating"));
2638 gdk_threads_leave ();
2641 /* Remove timeout */
2642 priv->updating_banner_timeout = 0;
2647 * We use this function to show/hide a progress banner showing
2648 * "Updating" while the header view is being filled. We're not showing
2649 * it unless the update takes more than 2 seconds
2651 * If starting = TRUE then the refresh is starting, otherwise it means
2652 * that is has just finished
2655 on_updating_msg_list (ModestHeaderView *header_view,
2659 ModestMainWindowPrivate *priv = NULL;
2661 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2663 /* Remove old timeout */
2664 if (priv->updating_banner_timeout > 0) {
2665 g_source_remove (priv->updating_banner_timeout);
2666 priv->updating_banner_timeout = 0;
2669 /* Create a new timeout */
2671 priv->updating_banner_timeout =
2672 g_timeout_add (2000, show_updating_banner, user_data);
2674 /* Remove the banner if exists */
2675 if (priv->updating_banner) {
2676 gtk_widget_destroy (priv->updating_banner);
2677 priv->updating_banner = NULL;
2683 modest_main_window_screen_is_on (ModestMainWindow *self)
2685 ModestMainWindowPrivate *priv = NULL;
2687 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2689 return (priv->display_state == OSSO_DISPLAY_ON) ? TRUE : FALSE;