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))
709 gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
710 gtk_label_set_markup (GTK_LABEL (label), escaped);
715 gtk_label_set_text (GTK_LABEL (label), display_name);
718 item = gtk_menu_item_new ();
719 gtk_container_add (GTK_CONTAINER (item), label);
721 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
722 g_signal_connect_data (G_OBJECT (item),
724 G_CALLBACK (on_send_receive_csm_activated),
725 g_strdup (account_name),
726 (GClosureNotify) g_free,
733 g_free (display_name);
736 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, priv->view_additions_group, 1);
738 /* We cannot do this in the loop above because this relies on the action
739 * group being inserted. This makes the default account appear in bold.
740 * I agree it is a rather ugly way, but I don't see another possibility. armin. */
741 for (i = 0; i < num_accounts; i++) {
742 ModestAccountSettings *settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
743 const gchar *account_name;
745 account_name = modest_account_settings_get_account_name (settings);
747 if(account_name && default_account &&
748 strcmp (account_name, default_account) == 0) {
749 gchar *item_name = g_strconcat (account_name, "Menu", NULL);
751 gchar *path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
752 GtkWidget *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));
759 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
760 gtk_label_set_markup (GTK_LABEL (child), bold_name);
765 path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", item_name, NULL);
766 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
770 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
771 if (GTK_IS_LABEL (child)) {
772 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
773 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
774 gtk_label_set_markup (GTK_LABEL (child), bold_name);
782 g_object_unref (settings);
785 if (num_accounts > 1) {
786 /* Disconnect the tap-and-hold-query if it's connected */
787 if (modest_signal_mgr_is_connected (priv->sighandlers,
788 G_OBJECT (send_receive_button),
789 "tap-and-hold-query"))
790 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
791 G_OBJECT (send_receive_button),
792 "tap-and-hold-query");
794 /* Mandatory in order to view the menu contents */
795 gtk_widget_show_all (priv->accounts_popup);
797 /* Setup tap_and_hold just if was not done before*/
798 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
799 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
801 /* Connect the tap-and-hold-query in order not to show the CSM */
802 if (!modest_signal_mgr_is_connected (priv->sighandlers,
803 G_OBJECT (send_receive_button),
804 "tap-and-hold-query"))
805 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
806 G_OBJECT (send_receive_button),
807 "tap-and-hold-query",
808 G_CALLBACK (tap_and_hold_query_cb),
813 g_slist_free (accounts);
814 g_free (default_account);
817 /* Make sure that at least one account is viewed if there are any
818 * accounts, for instance when adding the first account: */
819 set_at_least_one_account_visible (self);
823 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
825 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
826 gtk_scrolled_window_add_with_viewport
827 (GTK_SCROLLED_WINDOW(win), widget);
829 gtk_container_add (GTK_CONTAINER(win),
840 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
842 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
844 GList *oerrsignals = priv->queue_err_signals;
845 while (oerrsignals) {
846 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
847 g_signal_handler_disconnect (esignal->queue, esignal->signal);
848 g_slice_free (QueueErrorSignal, esignal);
849 oerrsignals = g_list_next (oerrsignals);
851 g_list_free (priv->queue_err_signals);
852 priv->queue_err_signals = NULL;
857 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
859 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
862 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
866 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
868 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
870 /* Update visibility */
873 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
877 modest_main_window_disconnect_signals (ModestWindow *self)
879 ModestMainWindowPrivate *priv;
880 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
882 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
883 priv->sighandlers = NULL;
887 connect_signals (ModestMainWindow *self)
889 ModestWindowPrivate *parent_priv;
890 ModestMainWindowPrivate *priv;
893 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
894 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
899 modest_signal_mgr_connect (priv->sighandlers,
900 G_OBJECT(priv->folder_view), "key-press-event",
901 G_CALLBACK(on_inner_widgets_key_pressed), self);
903 modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view),
904 "folder_selection_changed",
905 G_CALLBACK (on_folder_selection_changed),
908 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view),
909 "folder-display-name-changed",
910 G_CALLBACK (modest_ui_actions_on_folder_display_name_changed),
913 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view),
915 G_CALLBACK (on_folder_view_focus_in),
918 /* Folder view CSM */
919 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
920 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
921 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
922 G_CALLBACK(_folder_view_csm_menu_activated),
926 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
927 G_CALLBACK(modest_ui_actions_on_header_selected), self);
929 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
930 G_CALLBACK(modest_ui_actions_on_header_activated), self);
932 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
933 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
935 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
936 G_CALLBACK(on_inner_widgets_key_pressed), self);
938 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
939 G_CALLBACK(on_msg_count_changed), self);
941 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
942 G_CALLBACK (on_header_view_focus_in), self);
944 modest_signal_mgr_connect (priv->sighandlers,
945 G_OBJECT (priv->header_view),
947 G_CALLBACK (on_updating_msg_list),
950 /* Header view CSM */
951 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
952 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
954 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
955 G_CALLBACK(_header_view_csm_menu_activated),
960 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
961 G_CALLBACK (modest_main_window_window_state_event),
964 /* Mail Operation Queue */
966 modest_signal_mgr_connect (priv->sighandlers,
967 G_OBJECT (modest_runtime_get_mail_operation_queue ()),
969 G_CALLBACK (on_queue_changed), self);
971 /* Track changes in the device name */
973 modest_signal_mgr_connect (priv->sighandlers,
974 G_OBJECT(modest_runtime_get_conf ()),
976 G_CALLBACK (on_configuration_key_changed),
979 /* Track account changes. We need to refresh the toolbar */
981 modest_signal_mgr_connect (priv->sighandlers,
982 G_OBJECT (modest_runtime_get_account_store ()),
984 G_CALLBACK (on_account_inserted),
987 modest_signal_mgr_connect (priv->sighandlers,
988 G_OBJECT (modest_runtime_get_account_store ()),
990 G_CALLBACK (on_account_removed),
993 /* We need to refresh the send & receive menu to change the bold
994 * account when the default account changes. */
996 modest_signal_mgr_connect (priv->sighandlers,
997 G_OBJECT (modest_runtime_get_account_mgr ()),
998 "default_account_changed",
999 G_CALLBACK (on_default_account_changed),
1004 modest_signal_mgr_connect (priv->sighandlers,
1005 G_OBJECT (modest_runtime_get_account_store ()),
1007 G_CALLBACK (on_account_changed),
1011 modest_signal_mgr_connect (priv->sighandlers,
1012 G_OBJECT (modest_runtime_get_account_store()),
1013 "password_requested",
1014 G_CALLBACK (modest_ui_actions_on_password_requested),
1019 on_hildon_program_is_topmost_notify(GObject *self,
1020 GParamSpec *propert_param,
1023 HildonProgram *app = HILDON_PROGRAM (self);
1025 /* Note that use of hildon_program_set_can_hibernate()
1026 * is generally referred to as "setting the killable flag",
1027 * though hibernation does not seem equal to death.
1030 if (hildon_program_get_is_topmost (app)) {
1031 /* Prevent hibernation when the progam comes to the foreground,
1032 * because hibernation should only happen when the application
1033 * is in the background: */
1034 hildon_program_set_can_hibernate (app, FALSE);
1036 /* Remove new mail visual notifications */
1037 modest_platform_remove_new_mail_notifications (TRUE);
1039 /* Allow hibernation if the program has gone to the background: */
1041 /* However, prevent hibernation while the settings are being changed: */
1042 const gboolean hibernation_prevented =
1043 modest_window_mgr_get_hibernation_is_prevented (
1044 modest_runtime_get_window_mgr ());
1046 if (hibernation_prevented)
1047 hildon_program_set_can_hibernate (app, FALSE);
1049 /* Allow hibernation, after saving the state: */
1050 modest_osso_save_state();
1051 hildon_program_set_can_hibernate (app, TRUE);
1057 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
1059 GtkWidget *folder_win = (GtkWidget *) user_data;
1060 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1062 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
1063 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
1065 gtk_widget_show (GTK_WIDGET (priv->folder_view));
1067 /* Connect signals */
1068 connect_signals (MODEST_MAIN_WINDOW (self));
1070 /* Set account store */
1071 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
1072 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1074 /* Load previous osso state, for instance if we are being restored from
1076 modest_osso_load_state ();
1078 /* Restore window & widget settings */
1079 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
1081 /* Check if accounts exist and show the account wizard if not */
1082 gboolean accounts_exist =
1083 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1085 if (!accounts_exist) {
1086 /* This is necessary to have the main window shown behind the dialog
1087 It's an ugly hack... jschmid */
1088 gtk_widget_show_all(GTK_WIDGET(self));
1089 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
1092 GtkAction *send_receive_all;
1093 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1094 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
1095 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1096 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1097 gtk_action_set_visible (send_receive_all, g_slist_length (accounts) > 0);
1098 modest_account_mgr_free_account_names (accounts);
1099 update_menus (MODEST_MAIN_WINDOW (self));
1104 osso_display_event_cb (osso_display_state_t state,
1107 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (data);
1109 priv->display_state = state;
1111 /* Stop blinking if the screen becomes on */
1112 if (priv->display_state == OSSO_DISPLAY_ON)
1113 modest_platform_remove_new_mail_notifications (TRUE);
1117 modest_main_window_new (void)
1119 ModestMainWindow *self = NULL;
1120 ModestMainWindowPrivate *priv = NULL;
1121 ModestWindowPrivate *parent_priv = NULL;
1122 GtkWidget *folder_win = NULL;
1123 ModestDimmingRulesGroup *menu_rules_group = NULL;
1124 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1125 GtkActionGroup *action_group = NULL;
1126 GError *error = NULL;
1128 ModestConf *conf = NULL;
1129 GtkAction *action = NULL;
1130 GdkPixbuf *window_icon;
1132 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
1133 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1134 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1136 parent_priv->ui_manager = gtk_ui_manager_new();
1137 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
1139 action_group = gtk_action_group_new ("ModestMainWindowActions");
1140 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1142 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1143 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1145 /* Add common actions */
1146 gtk_action_group_add_actions (action_group,
1147 modest_action_entries,
1148 G_N_ELEMENTS (modest_action_entries),
1151 gtk_action_group_add_actions (action_group,
1152 modest_folder_view_action_entries,
1153 G_N_ELEMENTS (modest_folder_view_action_entries),
1156 gtk_action_group_add_actions (action_group,
1157 modest_header_view_action_entries,
1158 G_N_ELEMENTS (modest_header_view_action_entries),
1161 gtk_action_group_add_toggle_actions (action_group,
1162 modest_toggle_action_entries,
1163 G_N_ELEMENTS (modest_toggle_action_entries),
1166 gtk_action_group_add_toggle_actions (action_group,
1167 modest_main_window_toggle_action_entries,
1168 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
1171 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
1172 g_object_unref (action_group);
1174 /* Load the UI definition */
1175 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
1176 MODEST_UIDIR "modest-main-window-ui.xml", &error);
1177 if (error != NULL) {
1178 g_warning ("Could not merge modest-ui.xml: %s", error->message);
1179 g_error_free (error);
1183 /* Add common dimming rules */
1184 modest_dimming_rules_group_add_rules (menu_rules_group,
1185 modest_main_window_menu_dimming_entries,
1186 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
1187 MODEST_WINDOW (self));
1188 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1189 modest_main_window_toolbar_dimming_entries,
1190 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
1191 MODEST_WINDOW (self));
1193 /* Insert dimming rules group for this window */
1194 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1195 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1196 g_object_unref (menu_rules_group);
1197 g_object_unref (toolbar_rules_group);
1199 /* Add accelerators */
1200 gtk_window_add_accel_group (GTK_WINDOW (self),
1201 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
1203 /* Menubar. Update the state of some toggles */
1204 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1205 conf = modest_runtime_get_conf ();
1206 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1207 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
1208 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1209 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR, NULL));
1210 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1211 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
1212 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1213 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
1214 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
1215 gtk_widget_show (parent_priv->menubar);
1217 /* Get device name */
1218 modest_maemo_utils_get_device_name ();
1222 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
1223 if (!priv->header_view)
1224 g_printerr ("modest: cannot instantiate header view\n");
1225 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
1226 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
1227 MODEST_CONF_HEADER_VIEW_KEY);
1229 /* Other style properties of header view */
1230 g_object_set (G_OBJECT (priv->header_view),
1231 "rules-hint", FALSE,
1233 /* gtk_widget_show (priv->header_view); */
1236 priv->empty_view = create_empty_view ();
1237 gtk_widget_show (priv->empty_view);
1239 /* Create scrolled windows */
1240 folder_win = gtk_scrolled_window_new (NULL, NULL);
1241 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
1242 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
1244 GTK_POLICY_AUTOMATIC);
1245 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
1247 GTK_POLICY_AUTOMATIC);
1248 /* gtk_widget_show (priv->contents_widget); */
1251 priv->main_paned = gtk_hpaned_new ();
1252 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
1253 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
1254 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
1256 /* putting it all together... */
1257 priv->main_vbox = gtk_vbox_new (FALSE, 6);
1258 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
1259 gtk_widget_show (priv->main_vbox);
1261 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
1263 app = hildon_program_get_instance ();
1264 hildon_program_add_window (app, HILDON_WINDOW (self));
1266 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
1267 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
1269 g_signal_connect (G_OBJECT(self), "show",
1270 G_CALLBACK (modest_main_window_on_show), folder_win);
1272 /* Set window icon */
1273 window_icon = modest_platform_get_icon (MODEST_APP_ICON, MODEST_ICON_SIZE_BIG);
1275 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
1276 g_object_unref (window_icon);
1279 /* Listen for changes in the screen, we don't want to show a
1280 led pattern when the display is on for example */
1281 osso_hw_set_display_event_cb (modest_maemo_utils_get_osso_context (),
1282 osso_display_event_cb,
1285 /* Dont't restore settings here,
1286 * because it requires a gtk_widget_show(),
1287 * and we don't want to do that until later,
1288 * so that the UI is not visible for non-menu D-Bus activation.
1291 return MODEST_WINDOW(self);
1295 modest_main_window_set_style (ModestMainWindow *self,
1296 ModestMainWindowStyle style)
1298 ModestMainWindowPrivate *priv;
1299 ModestWindowPrivate *parent_priv;
1303 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1305 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1306 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1308 /* no change -> nothing to do */
1309 if (priv->style == style)
1312 /* Get toggle button and update the state if needed. This will
1313 happen only when the set_style is not invoked from the UI,
1314 for example when it's called from widget memory */
1315 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1316 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
1317 if ((active && style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) ||
1318 (!active && style == MODEST_MAIN_WINDOW_STYLE_SPLIT)) {
1319 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1320 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !active);
1321 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1324 priv->style = style;
1326 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
1327 /* Remove main paned */
1328 g_object_ref (priv->main_paned);
1329 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1331 /* Reparent the contents widget to the main vbox */
1332 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
1335 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1336 /* Remove header view */
1337 g_object_ref (priv->contents_widget);
1338 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1340 /* Reparent the main paned */
1341 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1342 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1346 g_return_if_reached ();
1349 /* Let header view grab the focus if it's being shown */
1350 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1351 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1353 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1356 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1359 ModestMainWindowStyle
1360 modest_main_window_get_style (ModestMainWindow *self)
1362 ModestMainWindowPrivate *priv;
1364 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1366 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1371 toolbar_resize (ModestMainWindow *self)
1373 ModestMainWindowPrivate *priv = NULL;
1374 ModestWindowPrivate *parent_priv = NULL;
1376 gint static_button_size;
1377 ModestWindowMgr *mgr;
1379 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1380 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1381 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1383 mgr = modest_runtime_get_window_mgr ();
1384 static_button_size = modest_window_mgr_get_fullscreen_mode (mgr)?118:108;
1386 if (parent_priv->toolbar) {
1387 /* left size buttons */
1388 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNew");
1389 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1390 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1391 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1392 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply");
1393 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1394 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1395 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1396 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage");
1397 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1398 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1399 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1400 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1401 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1402 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1403 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1405 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1406 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1407 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1408 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1409 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1410 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1411 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1412 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1420 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1422 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1423 ModestWindowPrivate *parent_priv;
1424 ModestWindowMgr *mgr;
1425 gboolean is_fullscreen;
1426 GtkAction *fs_toggle_action;
1429 mgr = modest_runtime_get_window_mgr ();
1431 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1433 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1435 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1436 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1437 if (is_fullscreen != active) {
1438 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1441 toolbar_resize (MODEST_MAIN_WINDOW (widget));
1449 modest_main_window_show_toolbar (ModestWindow *self,
1450 gboolean show_toolbar)
1452 ModestMainWindowPrivate *priv = NULL;
1453 ModestWindowPrivate *parent_priv = NULL;
1454 GtkWidget *reply_button = NULL, *menu = NULL;
1455 GtkWidget *placeholder = NULL;
1457 const gchar *action_name;
1460 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1461 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1462 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1464 /* Set optimized view status */
1465 priv->optimized_view = !show_toolbar;
1467 if (!parent_priv->toolbar) {
1468 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1470 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1472 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1473 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1474 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1475 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1476 toolbar_resize (MODEST_MAIN_WINDOW (self));
1478 /* Add ProgressBar (Transfer toolbar) */
1479 priv->progress_bar = modest_progress_bar_widget_new ();
1480 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1481 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1482 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1483 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1484 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1486 /* Connect cancel 'clicked' signal to abort progress mode */
1487 g_signal_connect(priv->cancel_toolitem, "clicked",
1488 G_CALLBACK(cancel_progressbar),
1491 /* Add it to the observers list */
1492 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1495 hildon_window_add_toolbar (HILDON_WINDOW (self),
1496 GTK_TOOLBAR (parent_priv->toolbar));
1498 /* Set reply button tap and hold menu */
1499 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1500 "/ToolBar/ToolbarMessageReply");
1501 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1502 "/ToolbarReplyCSM");
1503 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1505 /* Set send & receive button tap and hold menu */
1506 update_menus (MODEST_MAIN_WINDOW (self));
1510 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1511 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1512 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1514 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1515 if (modest_main_window_transfer_mode_enabled (MODEST_MAIN_WINDOW(self)))
1516 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_TRANSFER);
1518 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1520 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1524 /* Update also the actions (to update the toggles in the
1525 menus), we have to do it manually because some other window
1526 of the same time could have changed it (remember that the
1527 toolbar fullscreen mode is shared by all the windows of the
1529 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
1530 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu";
1532 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu";
1534 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
1535 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
1540 on_account_inserted (TnyAccountStore *accoust_store,
1541 TnyAccount *account,
1544 /* Transport accounts and local ones (MMC and the Local
1545 folders account do now cause menu changes */
1546 if (TNY_IS_STORE_ACCOUNT (account) &&
1547 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1548 update_menus (MODEST_MAIN_WINDOW (user_data));
1552 on_default_account_changed (ModestAccountMgr* mgr,
1555 update_menus (MODEST_MAIN_WINDOW (user_data));
1559 on_account_removed (TnyAccountStore *accoust_store,
1560 TnyAccount *account,
1563 /* Transport accounts and local ones (MMC and the Local
1564 folders account do now cause menu changes */
1565 if (TNY_IS_STORE_ACCOUNT (account) &&
1566 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1567 update_menus (MODEST_MAIN_WINDOW (user_data));
1571 on_account_changed (TnyAccountStore *account_store,
1572 TnyAccount *account,
1575 ModestMainWindow *win = MODEST_MAIN_WINDOW (user_data);
1577 /* We need to refresh the details widget because it could have changed */
1578 if (modest_main_window_get_contents_style(win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS) {
1579 modest_main_window_set_contents_style (win, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1582 /* Update the menus as well, the account name could be
1583 changed. Transport accounts and local ones (MMC and the
1584 Local folders account do now cause menu changes */
1585 if (TNY_IS_STORE_ACCOUNT (account) &&
1586 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1587 update_menus (MODEST_MAIN_WINDOW (user_data));
1591 * This function manages the key events used to navigate between
1592 * header and folder views (when the window is in split view)
1595 * -------------------------------------------------
1596 * HeaderView GDK_Left Move focus to folder view
1597 * FolderView GDK_Right Move focus to header view
1599 * There is no need to scroll to selected row, the widgets will be the
1600 * responsibles of doing that (probably managing the focus-in event
1603 on_inner_widgets_key_pressed (GtkWidget *widget,
1607 ModestMainWindowPrivate *priv;
1609 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1611 /* Do nothing if we're in SIMPLE style */
1612 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1615 if (MODEST_IS_HEADER_VIEW (widget)) {
1616 if (event->keyval == GDK_Left)
1617 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1618 else if ((event->keyval == GDK_Return)||(event->keyval == GDK_KP_Enter)) {
1619 guint selected_headers = modest_header_view_count_selected_headers (MODEST_HEADER_VIEW (widget));
1620 if (selected_headers > 1) {
1621 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1625 } else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1626 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1632 set_alignment (GtkWidget *widget,
1635 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1636 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1640 create_empty_view (void)
1642 GtkLabel *label = NULL;
1643 GtkWidget *align = NULL;
1645 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1646 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1647 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1648 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1650 return GTK_WIDGET(align);
1654 * Free the returned string
1657 get_gray_color_markup (GtkWidget *styled_widget)
1659 gchar *gray_color_markup = NULL;
1660 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1661 /* Obtain the secondary text color. We need a realized widget, that's why
1662 we get styled_widget from outside */
1664 if (gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color))
1665 gray_color_markup = modest_text_utils_get_color_string (&color);
1666 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
1668 if (!gray_color_markup)
1669 gray_color_markup = g_strdup ("#BBBBBB");
1671 return gray_color_markup;
1675 * Free the returned string
1678 create_device_name_visual_string (const gchar *device_name,
1679 const gchar *gray_color_markup)
1683 /* We have to use "" to fill the %s of the translation. We can
1684 not just use the device name because the device name is
1685 shown in a different color, so it could not be included
1686 into the <span> tag */
1687 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), "");
1688 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1698 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1700 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1705 gchar *gray_color_markup;
1707 vbox = gtk_vbox_new (FALSE, 0);
1709 gray_color_markup = get_gray_color_markup (styled_widget);
1711 /* Account description: */
1712 if (modest_tny_account_is_virtual_local_folders (account)
1713 || (modest_tny_account_is_memory_card_account (account))) {
1715 /* Get device name */
1716 gchar *device_name = NULL;
1717 if (modest_tny_account_is_virtual_local_folders (account))
1718 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1719 MODEST_CONF_DEVICE_NAME, NULL);
1721 device_name = g_strdup (tny_account_get_name (account));
1723 label = create_device_name_visual_string ((const gchar *) device_name,
1724 (const gchar *) gray_color_markup);
1725 label_w = gtk_label_new (NULL);
1726 gtk_label_set_markup (GTK_LABEL (label_w), label);
1727 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1728 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1729 g_free (device_name);
1732 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1733 gtk_box_pack_start (GTK_BOX (vbox),
1734 gtk_label_new (tny_account_get_name (account)),
1737 /* Other accounts, such as IMAP and POP: */
1742 /* Put proto in uppercase */
1743 proto = g_string_new (tny_account_get_proto (account));
1744 proto = g_string_ascii_up (proto);
1746 /* note: mcen_fi_localroot_description is something like "%s account"
1747 * however, we should display "%s account: %s"... therefore, ugly tmp */
1748 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1749 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1750 gray_color_markup, tmp, tny_account_get_name (account));
1753 label_w = gtk_label_new (NULL);
1754 gtk_label_set_markup (GTK_LABEL (label_w), label);
1755 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1756 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1757 g_string_free (proto, TRUE);
1763 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1764 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1765 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1766 modest_tny_folder_store_get_message_count (folder_store));
1767 label_w = gtk_label_new (NULL);
1768 gtk_label_set_markup (GTK_LABEL (label_w), label);
1769 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1770 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1774 label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d",
1776 _("mcen_fi_rootfolder_folders"),
1777 modest_tny_folder_store_get_folder_count (folder_store));
1778 label_w = gtk_label_new (NULL);
1779 gtk_label_set_markup (GTK_LABEL (label_w), label);
1780 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1781 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1785 if (modest_tny_account_is_virtual_local_folders (account)
1786 || modest_tny_account_is_memory_card_account (account)) {
1788 gchar *size = modest_text_utils_get_display_size (
1789 modest_tny_folder_store_get_local_size (folder_store));
1791 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1792 gray_color_markup, _("mcen_fi_rootfolder_size"),
1796 label_w = gtk_label_new (NULL);
1797 gtk_label_set_markup (GTK_LABEL (label_w), label);
1798 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1799 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1801 } else if (TNY_IS_ACCOUNT(folder_store)) {
1802 TnyAccount *account = TNY_ACCOUNT(folder_store);
1804 time_t last_updated;
1805 const gchar *last_updated_string;
1806 /* Get last updated from configuration */
1807 last_updated = modest_account_mgr_get_last_updated (modest_runtime_get_account_mgr (),
1808 tny_account_get_id (account));
1810 if (last_updated > 0)
1811 last_updated_string = modest_text_utils_get_display_date(last_updated);
1813 last_updated_string = g_strdup (_("mcen_va_never"));
1815 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1816 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1817 label_w = gtk_label_new (NULL);
1818 gtk_label_set_markup (GTK_LABEL (label_w), label);
1819 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1820 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1824 g_free (gray_color_markup);
1827 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1833 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1835 ModestMainWindowPrivate *priv = NULL;
1837 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1839 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1841 return priv->send_receive_in_progress;
1845 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1847 GtkAction *action = NULL;
1848 GtkWidget *widget = NULL;
1849 ModestMainWindowPrivate *priv = NULL;
1851 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1852 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1854 priv->send_receive_in_progress = TRUE;
1856 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1857 gtk_action_set_sensitive (action, FALSE);
1858 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1859 /* gtk_action_set_sensitive (action, FALSE); */
1860 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1861 gtk_widget_set_sensitive (widget, FALSE);
1865 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1867 GtkAction *action = NULL;
1868 GtkWidget *widget = NULL;
1869 ModestMainWindowPrivate *priv = NULL;
1871 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1872 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1874 priv->send_receive_in_progress = FALSE;
1876 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1877 gtk_action_set_sensitive (action, TRUE);
1878 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1879 /* gtk_action_set_sensitive (action, TRUE); */
1880 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1881 gtk_widget_set_sensitive (widget, TRUE);
1886 on_msg_count_changed (ModestHeaderView *header_view,
1888 TnyFolderChange *change,
1889 ModestMainWindow *main_window)
1891 gboolean folder_empty = FALSE;
1892 gboolean all_marked_as_deleted = FALSE;
1893 ModestMainWindowPrivate *priv;
1895 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1896 g_return_if_fail (TNY_IS_FOLDER(folder));
1897 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
1899 if (change != NULL) {
1900 TnyFolderChangeChanged changed;
1902 changed = tny_folder_change_get_changed (change);
1903 /* If something changes */
1904 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1905 folder_empty = (((guint) tny_folder_change_get_new_all_count (change)) == 0);
1907 folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1909 /* Play a sound (if configured) and make the LED blink */
1910 if (changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS) {
1911 modest_platform_on_new_headers_received (NULL, FALSE);
1915 /* Check if all messages are marked to be deleted */
1916 all_marked_as_deleted = modest_header_view_is_empty (header_view);
1917 folder_empty = folder_empty || all_marked_as_deleted;
1919 /* Set contents style of headers view */
1921 modest_main_window_set_contents_style (main_window,
1922 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1923 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1925 modest_main_window_set_contents_style (main_window,
1926 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1932 modest_main_window_set_contents_style (ModestMainWindow *self,
1933 ModestMainWindowContentsStyle style)
1935 ModestMainWindowPrivate *priv;
1937 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1939 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1941 /* We allow to set the same content style than the previously
1942 set if there are details, because it could happen when we're
1943 selecting different accounts consecutively */
1944 if ((priv->contents_style == style) &&
1945 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1948 /* Remove previous child. Delete it if it was an account
1950 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1952 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1953 g_object_ref (content);
1954 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1955 g_object_ref (priv->empty_view);
1956 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
1959 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1962 priv->contents_style = style;
1964 switch (priv->contents_style) {
1965 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1966 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1967 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1970 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1972 /* if we're started without main win, there may not be a folder
1973 * view. this fixes a GLib-Critical */
1974 if (priv->folder_view) {
1975 TnyFolderStore *selected_folderstore =
1976 modest_folder_view_get_selected (priv->folder_view);
1977 if (TNY_IS_ACCOUNT (selected_folderstore)) {
1978 priv->details_widget = create_details_widget (GTK_WIDGET (self),
1979 TNY_ACCOUNT (selected_folderstore));
1981 wrap_in_scrolled_window (priv->contents_widget,
1982 priv->details_widget);
1984 g_object_unref (selected_folderstore);
1985 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1990 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
1991 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
1992 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1996 g_return_if_reached ();
2000 gtk_widget_show_all (priv->contents_widget);
2003 ModestMainWindowContentsStyle
2004 modest_main_window_get_contents_style (ModestMainWindow *self)
2006 ModestMainWindowPrivate *priv;
2008 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
2010 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2011 return priv->contents_style;
2016 on_configuration_key_changed (ModestConf* conf,
2018 ModestConfEvent event,
2019 ModestConfNotificationId id,
2020 ModestMainWindow *self)
2022 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2023 TnyAccount *account = NULL;
2025 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
2028 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
2031 if (priv->folder_view)
2032 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
2034 if (account && TNY_IS_ACCOUNT (account) &&
2035 strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID) == 0) {
2038 const gchar *device_name;
2039 gchar *new_text, *gray_color_markup;
2042 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
2043 label = GTK_LABEL (children->data);
2045 device_name = modest_conf_get_string (modest_runtime_get_conf(),
2046 MODEST_CONF_DEVICE_NAME, NULL);
2048 gray_color_markup = get_gray_color_markup (GTK_WIDGET (self));
2049 new_text = create_device_name_visual_string (device_name, gray_color_markup);
2051 gtk_label_set_markup (label, new_text);
2052 gtk_widget_show (GTK_WIDGET (label));
2054 g_free (gray_color_markup);
2056 g_list_free (children);
2058 g_object_unref (account);
2062 set_toolbar_transfer_mode (ModestMainWindow *self)
2064 ModestMainWindowPrivate *priv = NULL;
2066 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2068 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2070 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
2072 if (priv->progress_bar_timeout > 0) {
2073 g_source_remove (priv->progress_bar_timeout);
2074 priv->progress_bar_timeout = 0;
2081 set_toolbar_mode (ModestMainWindow *self,
2082 ModestToolBarModes mode)
2084 ModestWindowPrivate *parent_priv = NULL;
2085 ModestMainWindowPrivate *priv = NULL;
2086 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
2088 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2090 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2091 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2093 /* In case this was called before the toolbar exists: */
2094 if (!(parent_priv->toolbar))
2097 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
2099 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
2100 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
2101 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
2103 /* Sets current toolbar mode */
2104 priv->current_toolbar_mode = mode;
2106 /* Checks the dimming rules */
2107 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2109 /* Show and hide toolbar items */
2111 case TOOLBAR_MODE_NORMAL:
2113 gtk_action_set_visible (sort_action, TRUE);
2115 gtk_action_set_visible (refresh_action, TRUE);
2116 if (priv->progress_toolitem) {
2117 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
2118 gtk_widget_hide (priv->progress_toolitem);
2120 if (priv->progress_bar)
2121 gtk_widget_hide (priv->progress_bar);
2124 gtk_action_set_visible (cancel_action, FALSE);
2126 /* Hide toolbar if optimized view is enabled */
2127 if (priv->optimized_view)
2128 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
2130 case TOOLBAR_MODE_TRANSFER:
2132 gtk_action_set_visible (sort_action, FALSE);
2134 gtk_action_set_visible (refresh_action, FALSE);
2136 gtk_action_set_visible (cancel_action, TRUE);
2137 if (priv->progress_bar)
2138 gtk_widget_show (priv->progress_bar);
2139 if (priv->progress_toolitem) {
2140 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
2141 gtk_widget_show (priv->progress_toolitem);
2144 /* Show toolbar if it's hiden (optimized view ) */
2145 if (priv->optimized_view)
2146 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2149 g_return_if_reached ();
2154 modest_main_window_transfer_mode_enabled (ModestMainWindow *self)
2156 ModestMainWindowPrivate *priv;
2158 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2159 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2161 return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
2165 cancel_progressbar (GtkToolButton *toolbutton,
2166 ModestMainWindow *self)
2169 ModestMainWindowPrivate *priv;
2171 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2173 /* Get operation observers and cancel all the operations */
2174 tmp = priv->progress_widgets;
2176 modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2177 tmp=g_slist_next(tmp);
2182 observers_empty (ModestMainWindow *self)
2185 ModestMainWindowPrivate *priv;
2186 gboolean is_empty = TRUE;
2187 guint pending_ops = 0;
2189 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2190 tmp = priv->progress_widgets;
2192 /* Check all observers */
2193 while (tmp && is_empty) {
2194 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2195 is_empty = pending_ops == 0;
2197 tmp = g_slist_next(tmp);
2205 * Gets the toolbar mode needed for each mail operation. It stores in
2206 * @mode_changed if the toolbar mode has changed or not
2208 static ModestToolBarModes
2209 get_toolbar_mode_from_mail_operation (ModestMainWindow *self,
2210 ModestMailOperation *mail_op,
2211 gboolean *mode_changed)
2213 ModestToolBarModes mode;
2214 ModestMainWindowPrivate *priv;
2216 *mode_changed = FALSE;
2217 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2219 /* Get toolbar mode from operation id*/
2220 switch (modest_mail_operation_get_type_operation (mail_op)) {
2221 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
2222 case MODEST_MAIL_OPERATION_TYPE_OPEN:
2223 mode = TOOLBAR_MODE_TRANSFER;
2224 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
2225 *mode_changed = TRUE;
2228 mode = TOOLBAR_MODE_NORMAL;
2234 on_mail_operation_started (ModestMailOperation *mail_op,
2237 ModestMainWindow *self;
2238 ModestMailOperationTypeOperation op_type;
2239 ModestMainWindowPrivate *priv;
2240 ModestToolBarModes mode;
2242 gboolean mode_changed = FALSE;
2243 TnyAccount *account;
2245 self = MODEST_MAIN_WINDOW (user_data);
2246 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2248 /* Do not show progress for receiving operations if the
2249 account is the local account or the MMC one */
2250 op_type = modest_mail_operation_get_type_operation (mail_op);
2251 account = modest_mail_operation_get_account (mail_op);
2252 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2255 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2256 modest_tny_account_is_memory_card_account (account));
2257 g_object_unref (account);
2262 /* Get toolbar mode from operation id*/
2263 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2265 /* Add operation observers and change toolbar if neccessary*/
2266 tmp = priv->progress_widgets;
2267 if (mode == TOOLBAR_MODE_TRANSFER) {
2269 GObject *source = modest_mail_operation_get_source(mail_op);
2270 if (G_OBJECT (self) == source) {
2271 set_toolbar_transfer_mode(self);
2273 g_object_unref (source);
2277 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2279 tmp = g_slist_next (tmp);
2285 on_mail_operation_finished (ModestMailOperation *mail_op,
2288 ModestToolBarModes mode;
2289 ModestMailOperationTypeOperation op_type;
2291 ModestMainWindow *self;
2292 gboolean mode_changed;
2293 TnyAccount *account;
2294 ModestMainWindowPrivate *priv;
2296 self = MODEST_MAIN_WINDOW (user_data);
2297 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2299 /* The mail operation was not added to the progress objects if
2300 the account was the local account or the MMC one */
2301 op_type = modest_mail_operation_get_type_operation (mail_op);
2302 account = modest_mail_operation_get_account (mail_op);
2303 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2306 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2307 modest_tny_account_is_memory_card_account (account));
2308 g_object_unref (account);
2313 /* Get toolbar mode from operation id*/
2314 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2316 /* Change toolbar mode */
2317 tmp = priv->progress_widgets;
2318 if (mode == TOOLBAR_MODE_TRANSFER) {
2320 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2322 tmp = g_slist_next (tmp);
2325 /* If no more operations are being observed, NORMAL mode is enabled again */
2326 if (observers_empty (self)) {
2327 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
2333 on_queue_changed (ModestMailOperationQueue *queue,
2334 ModestMailOperation *mail_op,
2335 ModestMailOperationQueueNotification type,
2336 ModestMainWindow *self)
2338 ModestMainWindowPrivate *priv;
2340 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2342 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
2343 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2345 "operation-started",
2346 G_CALLBACK (on_mail_operation_started),
2348 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2350 "operation-finished",
2351 G_CALLBACK (on_mail_operation_finished),
2353 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
2354 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2356 "operation-started");
2357 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2359 "operation-finished");
2364 set_account_visible(ModestMainWindow *self, const gchar *acc_name)
2366 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2368 ModestAccountMgr *mgr;
2369 ModestAccountSettings *settings;
2370 ModestServerAccountSettings *store_settings = NULL;
2372 /* Get account data */
2373 mgr = modest_runtime_get_account_mgr ();
2374 settings = modest_account_mgr_load_account_settings (mgr, acc_name);
2376 store_settings = modest_account_settings_get_store_settings (settings);
2378 /* Set the new visible & active account */
2379 if (settings && (modest_server_account_settings_get_account_name (store_settings)!= NULL)) {
2380 const gchar *account_name;
2382 account_name = modest_account_settings_get_account_name (settings);
2384 modest_folder_view_set_account_id_of_visible_server_account
2386 modest_server_account_settings_get_account_name (store_settings));
2387 modest_window_set_active_account (MODEST_WINDOW (self), account_name);
2388 action = gtk_action_group_get_action (priv->view_additions_group, account_name);
2389 if (action != NULL) {
2390 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2391 modest_utils_toggle_action_set_active_block_notify (
2392 GTK_TOGGLE_ACTION (action),
2398 modest_folder_view_select_first_inbox_or_local (priv->folder_view);
2403 g_object_unref (store_settings);
2404 g_object_unref (settings);
2408 /* Make sure that at least one account is "viewed": */
2410 set_at_least_one_account_visible(ModestMainWindow *self)
2412 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2413 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2415 if (!(priv->folder_view)) {
2416 /* It is too early to do this. */
2420 const gchar *active_server_account_name =
2421 modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);
2423 if (!active_server_account_name ||
2424 !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
2426 gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
2427 gchar* default_modest_name = modest_account_mgr_get_default_account (account_mgr);
2428 if (default_modest_name) {
2429 set_account_visible (self, default_modest_name);
2430 } else if (first_modest_name) {
2431 set_account_visible (self, first_modest_name);
2433 g_free (first_modest_name);
2434 g_free (default_modest_name);
2439 on_show_account_action_toggled (GtkToggleAction *action,
2442 ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
2444 const gchar *acc_name = gtk_action_get_name (GTK_ACTION (action));
2445 if (gtk_toggle_action_get_active (action))
2446 set_account_visible (self, acc_name);
2450 refresh_account (const gchar *account_name)
2454 /* win must already exists here, obviously */
2455 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
2458 g_warning ("%s: BUG: no main window!", __FUNCTION__);
2462 /* If account_name == NULL, we must update all (option All) */
2464 modest_ui_actions_do_send_receive_all (win, FALSE);
2466 modest_ui_actions_do_send_receive (account_name, FALSE, win);
2471 on_refresh_account_action_activated (GtkAction *action,
2474 refresh_account ((const gchar*) user_data);
2478 on_send_receive_csm_activated (GtkMenuItem *item,
2481 refresh_account ((const gchar*) user_data);
2485 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2487 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2489 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2495 on_folder_view_focus_in (GtkWidget *widget, GdkEventFocus *event, gpointer userdata)
2497 ModestMainWindow *main_window = NULL;
2499 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2500 main_window = MODEST_MAIN_WINDOW (userdata);
2502 /* Update toolbar dimming state */
2503 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2509 on_header_view_focus_in (GtkWidget *widget,
2510 GdkEventFocus *event,
2513 ModestMainWindow *main_window = NULL;
2515 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2517 main_window = MODEST_MAIN_WINDOW (userdata);
2519 /* Update toolbar dimming state */
2520 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2526 on_folder_selection_changed (ModestFolderView *folder_view,
2527 TnyFolderStore *folder_store,
2529 ModestMainWindow *main_window)
2531 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2532 GtkAction *action = NULL;
2533 gboolean show_reply = TRUE;
2534 gboolean show_forward = TRUE;
2535 gboolean show_cancel_send = FALSE;
2536 gboolean show_clipboard = TRUE;
2537 gboolean show_delete = TRUE;
2540 if (TNY_IS_ACCOUNT (folder_store)) {
2541 show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2542 } else if (TNY_IS_FOLDER (folder_store)) {
2543 if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2544 TnyFolderType folder_type = modest_tny_folder_get_local_or_mmc_folder_type (
2545 TNY_FOLDER (folder_store));
2546 switch (folder_type) {
2547 case TNY_FOLDER_TYPE_DRAFTS:
2548 show_clipboard = show_delete = TRUE;
2549 show_reply = show_forward = show_cancel_send = FALSE;
2551 case TNY_FOLDER_TYPE_SENT:
2552 show_forward = show_clipboard = show_delete = TRUE;
2553 show_reply = show_cancel_send = FALSE;
2555 case TNY_FOLDER_TYPE_OUTBOX:
2556 show_clipboard = show_delete = show_cancel_send = TRUE;
2557 show_reply = show_forward = FALSE;
2559 case TNY_FOLDER_TYPE_INVALID:
2560 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
2563 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2564 show_cancel_send = FALSE;
2567 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2568 show_cancel_send = FALSE;
2573 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2574 gtk_action_set_visible (action, show_reply);
2575 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2576 gtk_action_set_visible (action, show_reply);
2577 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2578 gtk_action_set_visible (action, show_forward);
2579 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2580 gtk_action_set_visible (action, show_cancel_send);
2581 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2582 gtk_action_set_visible (action, show_delete);
2584 /* We finally call to the ui actions handler, after updating properly
2585 * the header view CSM */
2586 modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2590 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2591 GtkTreeModel *model,
2592 GtkTreeRowReference *row_reference,
2593 ModestMainWindow *self)
2595 ModestMainWindowPrivate *priv = NULL;
2596 GtkTreeModel *header_model = NULL;
2597 GtkTreePath *path = NULL;
2599 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
2600 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2601 g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2603 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2604 header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2606 /* Do nothing if we changed the folder in the main view */
2607 if (header_model != model)
2610 /* Select the message in the header view */
2611 path = gtk_tree_row_reference_get_path (row_reference);
2612 gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->header_view),
2614 gtk_tree_path_free (path);
2620 show_updating_banner (gpointer user_data)
2622 ModestMainWindowPrivate *priv = NULL;
2624 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2626 if (priv->updating_banner == NULL) {
2628 /* We're outside the main lock */
2629 gdk_threads_enter ();
2630 priv->updating_banner =
2631 modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2632 _CS ("ckdg_pb_updating"));
2633 gdk_threads_leave ();
2636 /* Remove timeout */
2637 priv->updating_banner_timeout = 0;
2642 * We use this function to show/hide a progress banner showing
2643 * "Updating" while the header view is being filled. We're not showing
2644 * it unless the update takes more than 2 seconds
2646 * If starting = TRUE then the refresh is starting, otherwise it means
2647 * that is has just finished
2650 on_updating_msg_list (ModestHeaderView *header_view,
2654 ModestMainWindowPrivate *priv = NULL;
2656 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2658 /* Remove old timeout */
2659 if (priv->updating_banner_timeout > 0) {
2660 g_source_remove (priv->updating_banner_timeout);
2661 priv->updating_banner_timeout = 0;
2664 /* Create a new timeout */
2666 priv->updating_banner_timeout =
2667 g_timeout_add (2000, show_updating_banner, user_data);
2669 /* Remove the banner if exists */
2670 if (priv->updating_banner) {
2671 gtk_widget_destroy (priv->updating_banner);
2672 priv->updating_banner = NULL;
2678 modest_main_window_screen_is_on (ModestMainWindow *self)
2680 ModestMainWindowPrivate *priv = NULL;
2682 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2684 return (priv->display_state == OSSO_DISPLAY_ON) ? TRUE : FALSE;