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 (500, (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 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
492 MODEST_CONF_MAIN_PANED_KEY);
493 // modest_widget_memory_save (conf, G_OBJECT(priv->header_view),
494 // MODEST_CONF_HEADER_VIEW_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));
508 update_menus (ModestMainWindow* self)
510 GSList *account_names, *iter, *accounts;
511 ModestMainWindowPrivate *priv;
512 ModestWindowPrivate *parent_priv;
513 ModestAccountMgr *mgr;
514 gint i, num_accounts;
516 gchar *default_account;
517 const gchar *active_account_name;
518 GtkWidget *send_receive_button, *item;
519 GtkAction *send_receive_all = NULL;
522 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
523 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
525 /* Get enabled account IDs */
526 mgr = modest_runtime_get_account_mgr ();
527 account_names = modest_account_mgr_account_names (mgr, TRUE);
528 iter = account_names;
532 ModestAccountSettings *settings =
533 modest_account_mgr_load_account_settings (mgr, (gchar*) iter->data);
534 accounts = g_slist_prepend (accounts, settings);
538 modest_account_mgr_free_account_names (account_names);
539 account_names = NULL;
541 /* Order the list of accounts by its display name */
542 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
543 num_accounts = g_slist_length (accounts);
545 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
546 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
547 gtk_action_set_visible (send_receive_all, num_accounts > 0);
549 /* Delete old send&receive popup items. We can not just do a
550 menu_detach because it does not work well with
552 if (priv->accounts_popup)
553 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
554 (GtkCallback) gtk_widget_destroy, NULL);
556 /* Delete old entries in the View menu. Do not free groups, it
558 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
560 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
561 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
562 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
563 GTK_ACTION_GROUP (groups->data));
566 if (priv->merge_ids) {
567 for (i = 0; i < priv->merge_ids->len; i++)
568 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
569 g_byte_array_free (priv->merge_ids, TRUE);
571 /* We need to call this in order to ensure
572 that the new actions are added in the right
573 order (alphabetical) */
574 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
576 groups = g_list_next (groups);
578 priv->merge_ids = g_byte_array_sized_new (num_accounts);
580 /* Get send receive button */
581 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
582 "/ToolBar/ToolbarSendReceive");
584 /* Create the menu */
585 if (num_accounts > 1) {
586 if (!priv->accounts_popup)
587 priv->accounts_popup = gtk_menu_new ();
588 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
589 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
590 g_signal_connect (G_OBJECT (item),
592 G_CALLBACK (on_send_receive_csm_activated),
594 item = gtk_separator_menu_item_new ();
595 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
598 /* Create a new action group */
599 default_account = modest_account_mgr_get_default_account (mgr);
600 active_account_name = modest_window_get_active_account (MODEST_WINDOW (self));
602 if (!active_account_name)
603 modest_window_set_active_account (MODEST_WINDOW (self), default_account);
605 priv->view_additions_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
607 for (i = 0; i < num_accounts; i++) {
608 gchar *display_name = NULL;
609 const gchar *account_name;
610 ModestAccountSettings *settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
613 g_warning ("%s: BUG: account_data == NULL", __FUNCTION__);
616 account_name = modest_account_settings_get_account_name (settings);
618 if (default_account && account_name &&
619 !(strcmp (default_account, account_name) == 0)) {
620 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
621 modest_account_settings_get_display_name (settings));
623 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
624 modest_account_settings_get_display_name (settings));
627 /* Create action and add it to the action group. The
628 action name must be the account name, this way we
629 could know in the handlers the account to show */
630 if (settings && account_name) {
631 gchar* item_name, *refresh_action_name;
633 GtkAction *view_account_action, *refresh_account_action;
635 view_account_action = GTK_ACTION (gtk_radio_action_new (account_name,
636 display_name, NULL, NULL, 0));
637 gtk_action_group_add_action (priv->view_additions_group, view_account_action);
638 gtk_radio_action_set_group (GTK_RADIO_ACTION (view_account_action), radio_group);
639 radio_group = gtk_radio_action_get_group (GTK_RADIO_ACTION (view_account_action));
641 if (active_account_name) {
642 if (active_account_name && account_name &&
643 (strcmp (active_account_name, account_name) == 0)) {
644 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (view_account_action), TRUE);
648 /* Add ui from account data. We allow 2^9-1 account
649 changes in a single execution because we're
650 downcasting the guint to a guint8 in order to use a
651 GByteArray. It should be enough. */
652 item_name = g_strconcat (account_name, "Menu", NULL);
653 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
654 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
655 gtk_ui_manager_add_ui (parent_priv->ui_manager,
657 "/MenuBar/ViewMenu/ViewMenuAdditions",
660 GTK_UI_MANAGER_MENUITEM,
663 /* Connect the action signal "activate" */
664 g_signal_connect_after (G_OBJECT (view_account_action),
666 G_CALLBACK (on_show_account_action_toggled),
669 /* Create the items for the Tools->Send&Receive submenu */
670 refresh_action_name = g_strconcat ("SendReceive", account_name, NULL);
671 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
672 display_name, NULL, NULL);
673 gtk_action_group_add_action (priv->view_additions_group, refresh_account_action);
675 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
676 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
677 gtk_ui_manager_add_ui (parent_priv->ui_manager,
679 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
682 GTK_UI_MANAGER_MENUITEM,
684 g_free (refresh_action_name);
686 g_signal_connect_data (G_OBJECT (refresh_account_action),
688 G_CALLBACK (on_refresh_account_action_activated),
689 g_strdup (account_name),
690 (GClosureNotify) g_free,
693 /* Create item and add it to the send&receive
694 CSM. If there is only one account then
696 if (priv->accounts_popup) {
697 GtkWidget *label = gtk_label_new(NULL);
698 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
699 if (default_account && (strcmp(account_name, default_account) == 0))
701 gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
702 gtk_label_set_markup (GTK_LABEL (label), escaped);
707 gtk_label_set_text (GTK_LABEL (label), display_name);
710 item = gtk_menu_item_new ();
711 gtk_container_add (GTK_CONTAINER (item), label);
713 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
714 g_signal_connect_data (G_OBJECT (item),
716 G_CALLBACK (on_send_receive_csm_activated),
717 g_strdup (account_name),
718 (GClosureNotify) g_free,
725 g_free (display_name);
728 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, priv->view_additions_group, 1);
730 /* We cannot do this in the loop above because this relies on the action
731 * group being inserted. This makes the default account appear in bold.
732 * I agree it is a rather ugly way, but I don't see another possibility. armin. */
733 for (i = 0; i < num_accounts; i++) {
734 ModestAccountSettings *settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
735 const gchar *account_name;
737 account_name = modest_account_settings_get_account_name (settings);
739 if(account_name && default_account &&
740 strcmp (account_name, default_account) == 0) {
741 gchar *item_name = g_strconcat (account_name, "Menu", NULL);
743 gchar *path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
744 GtkWidget *item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
748 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
749 if (GTK_IS_LABEL (child)) {
750 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
751 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
752 gtk_label_set_markup (GTK_LABEL (child), bold_name);
757 path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", item_name, NULL);
758 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
762 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
763 if (GTK_IS_LABEL (child)) {
764 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
765 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
766 gtk_label_set_markup (GTK_LABEL (child), bold_name);
774 g_object_unref (settings);
777 if (priv->accounts_popup) {
778 /* Mandatory in order to view the menu contents */
779 gtk_widget_show_all (priv->accounts_popup);
781 /* Setup tap_and_hold just if was not done before*/
782 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
783 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
787 g_slist_free (accounts);
788 g_free (default_account);
791 /* Make sure that at least one account is viewed if there are any
792 * accounts, for instance when adding the first account: */
793 set_at_least_one_account_visible (self);
797 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
799 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
800 gtk_scrolled_window_add_with_viewport
801 (GTK_SCROLLED_WINDOW(win), widget);
803 gtk_container_add (GTK_CONTAINER(win),
814 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
816 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
818 GList *oerrsignals = priv->queue_err_signals;
819 while (oerrsignals) {
820 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
821 g_signal_handler_disconnect (esignal->queue, esignal->signal);
822 g_slice_free (QueueErrorSignal, esignal);
823 oerrsignals = g_list_next (oerrsignals);
825 g_list_free (priv->queue_err_signals);
826 priv->queue_err_signals = NULL;
831 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
833 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
836 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
840 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
842 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
844 /* Update visibility */
847 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
851 modest_main_window_disconnect_signals (ModestWindow *self)
853 ModestMainWindowPrivate *priv;
854 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
856 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
857 priv->sighandlers = NULL;
861 connect_signals (ModestMainWindow *self)
863 ModestWindowPrivate *parent_priv;
864 ModestMainWindowPrivate *priv;
867 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
868 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
873 modest_signal_mgr_connect (priv->sighandlers,
874 G_OBJECT(priv->folder_view), "key-press-event",
875 G_CALLBACK(on_inner_widgets_key_pressed), self);
877 modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view),
878 "folder_selection_changed",
879 G_CALLBACK (on_folder_selection_changed),
882 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view),
883 "folder-display-name-changed",
884 G_CALLBACK (modest_ui_actions_on_folder_display_name_changed),
887 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view),
889 G_CALLBACK (on_folder_view_focus_in),
892 /* Folder view CSM */
893 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
894 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
895 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
896 G_CALLBACK(_folder_view_csm_menu_activated),
900 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
901 G_CALLBACK(modest_ui_actions_on_header_selected), self);
903 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
904 G_CALLBACK(modest_ui_actions_on_header_activated), self);
906 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
907 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
909 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
910 G_CALLBACK(on_inner_widgets_key_pressed), self);
912 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
913 G_CALLBACK(on_msg_count_changed), self);
915 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
916 G_CALLBACK (on_header_view_focus_in), self);
918 modest_signal_mgr_connect (priv->sighandlers,
919 G_OBJECT (priv->header_view),
921 G_CALLBACK (on_updating_msg_list),
924 /* Header view CSM */
925 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
926 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
928 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
929 G_CALLBACK(_header_view_csm_menu_activated),
934 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
935 G_CALLBACK (modest_main_window_window_state_event),
938 /* Mail Operation Queue */
940 modest_signal_mgr_connect (priv->sighandlers,
941 G_OBJECT (modest_runtime_get_mail_operation_queue ()),
943 G_CALLBACK (on_queue_changed), self);
945 /* Track changes in the device name */
947 modest_signal_mgr_connect (priv->sighandlers,
948 G_OBJECT(modest_runtime_get_conf ()),
950 G_CALLBACK (on_configuration_key_changed),
953 /* Track account changes. We need to refresh the toolbar */
955 modest_signal_mgr_connect (priv->sighandlers,
956 G_OBJECT (modest_runtime_get_account_store ()),
958 G_CALLBACK (on_account_inserted),
961 modest_signal_mgr_connect (priv->sighandlers,
962 G_OBJECT (modest_runtime_get_account_store ()),
964 G_CALLBACK (on_account_removed),
967 /* We need to refresh the send & receive menu to change the bold
968 * account when the default account changes. */
970 modest_signal_mgr_connect (priv->sighandlers,
971 G_OBJECT (modest_runtime_get_account_mgr ()),
972 "default_account_changed",
973 G_CALLBACK (on_default_account_changed),
978 modest_signal_mgr_connect (priv->sighandlers,
979 G_OBJECT (modest_runtime_get_account_store ()),
981 G_CALLBACK (on_account_changed),
985 modest_signal_mgr_connect (priv->sighandlers,
986 G_OBJECT (modest_runtime_get_account_store()),
987 "password_requested",
988 G_CALLBACK (modest_ui_actions_on_password_requested),
993 on_hildon_program_is_topmost_notify(GObject *self,
994 GParamSpec *propert_param,
997 HildonProgram *app = HILDON_PROGRAM (self);
999 /* Note that use of hildon_program_set_can_hibernate()
1000 * is generally referred to as "setting the killable flag",
1001 * though hibernation does not seem equal to death.
1004 if (hildon_program_get_is_topmost (app)) {
1005 /* Prevent hibernation when the progam comes to the foreground,
1006 * because hibernation should only happen when the application
1007 * is in the background: */
1008 hildon_program_set_can_hibernate (app, FALSE);
1010 /* Remove new mail visual notifications */
1011 modest_platform_remove_new_mail_notifications (TRUE);
1013 /* Allow hibernation if the program has gone to the background: */
1015 /* However, prevent hibernation while the settings are being changed: */
1016 const gboolean hibernation_prevented =
1017 modest_window_mgr_get_hibernation_is_prevented (
1018 modest_runtime_get_window_mgr ());
1020 if (hibernation_prevented)
1021 hildon_program_set_can_hibernate (app, FALSE);
1023 /* Allow hibernation, after saving the state: */
1024 modest_osso_save_state();
1025 hildon_program_set_can_hibernate (app, TRUE);
1031 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
1033 GtkWidget *folder_win = (GtkWidget *) user_data;
1034 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1036 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
1037 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
1039 gtk_widget_show (GTK_WIDGET (priv->folder_view));
1041 /* Connect signals */
1042 connect_signals (MODEST_MAIN_WINDOW (self));
1044 /* Set account store */
1045 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
1046 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1048 /* Load previous osso state, for instance if we are being restored from
1050 modest_osso_load_state ();
1052 /* Restore window & widget settings */
1053 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
1055 /* Check if accounts exist and show the account wizard if not */
1056 gboolean accounts_exist =
1057 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1059 if (!accounts_exist) {
1060 /* This is necessary to have the main window shown behind the dialog
1061 It's an ugly hack... jschmid */
1062 gtk_widget_show_all(GTK_WIDGET(self));
1063 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
1066 GtkAction *send_receive_all;
1067 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1068 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
1069 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1070 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1071 gtk_action_set_visible (send_receive_all, g_slist_length (accounts) > 0);
1072 modest_account_mgr_free_account_names (accounts);
1073 update_menus (MODEST_MAIN_WINDOW (self));
1078 osso_display_event_cb (osso_display_state_t state,
1081 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (data);
1083 priv->display_state = state;
1085 /* Stop blinking if the screen becomes on */
1086 if (priv->display_state == OSSO_DISPLAY_ON)
1087 modest_platform_remove_new_mail_notifications (TRUE);
1091 modest_main_window_new (void)
1093 ModestMainWindow *self = NULL;
1094 ModestMainWindowPrivate *priv = NULL;
1095 ModestWindowPrivate *parent_priv = NULL;
1096 GtkWidget *folder_win = NULL;
1097 ModestDimmingRulesGroup *menu_rules_group = NULL;
1098 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1099 GtkActionGroup *action_group = NULL;
1100 GError *error = NULL;
1102 ModestConf *conf = NULL;
1103 GtkAction *action = NULL;
1104 GdkPixbuf *window_icon;
1106 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
1107 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1108 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1110 parent_priv->ui_manager = gtk_ui_manager_new();
1111 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
1113 action_group = gtk_action_group_new ("ModestMainWindowActions");
1114 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1116 menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules", FALSE);
1117 toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules", TRUE);
1119 /* Add common actions */
1120 gtk_action_group_add_actions (action_group,
1121 modest_action_entries,
1122 G_N_ELEMENTS (modest_action_entries),
1125 gtk_action_group_add_actions (action_group,
1126 modest_folder_view_action_entries,
1127 G_N_ELEMENTS (modest_folder_view_action_entries),
1130 gtk_action_group_add_actions (action_group,
1131 modest_header_view_action_entries,
1132 G_N_ELEMENTS (modest_header_view_action_entries),
1135 gtk_action_group_add_toggle_actions (action_group,
1136 modest_toggle_action_entries,
1137 G_N_ELEMENTS (modest_toggle_action_entries),
1140 gtk_action_group_add_toggle_actions (action_group,
1141 modest_main_window_toggle_action_entries,
1142 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
1145 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
1146 g_object_unref (action_group);
1148 /* Load the UI definition */
1149 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
1150 MODEST_UIDIR "modest-main-window-ui.xml", &error);
1151 if (error != NULL) {
1152 g_warning ("Could not merge modest-ui.xml: %s", error->message);
1153 g_error_free (error);
1157 /* Add common dimming rules */
1158 modest_dimming_rules_group_add_rules (menu_rules_group,
1159 modest_main_window_menu_dimming_entries,
1160 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
1161 MODEST_WINDOW (self));
1162 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1163 modest_main_window_toolbar_dimming_entries,
1164 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
1165 MODEST_WINDOW (self));
1167 /* Insert dimming rules group for this window */
1168 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1169 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1170 g_object_unref (menu_rules_group);
1171 g_object_unref (toolbar_rules_group);
1173 /* Add accelerators */
1174 gtk_window_add_accel_group (GTK_WINDOW (self),
1175 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
1177 /* Menubar. Update the state of some toggles */
1178 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1179 conf = modest_runtime_get_conf ();
1180 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1181 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
1182 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1183 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR, NULL));
1184 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1185 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
1186 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1187 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
1188 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
1189 gtk_widget_show (parent_priv->menubar);
1191 /* Get device name */
1192 modest_maemo_utils_get_device_name ();
1196 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
1197 if (!priv->header_view)
1198 g_printerr ("modest: cannot instantiate header view\n");
1199 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
1200 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
1201 MODEST_CONF_HEADER_VIEW_KEY);
1203 /* Other style properties of header view */
1204 g_object_set (G_OBJECT (priv->header_view),
1205 "rules-hint", FALSE,
1207 /* gtk_widget_show (priv->header_view); */
1210 priv->empty_view = create_empty_view ();
1211 gtk_widget_show (priv->empty_view);
1213 /* Create scrolled windows */
1214 folder_win = gtk_scrolled_window_new (NULL, NULL);
1215 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
1216 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
1218 GTK_POLICY_AUTOMATIC);
1219 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
1221 GTK_POLICY_AUTOMATIC);
1222 /* gtk_widget_show (priv->contents_widget); */
1225 priv->main_paned = gtk_hpaned_new ();
1226 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
1227 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
1228 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
1230 /* putting it all together... */
1231 priv->main_vbox = gtk_vbox_new (FALSE, 6);
1232 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
1233 gtk_widget_show (priv->main_vbox);
1235 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
1237 app = hildon_program_get_instance ();
1238 hildon_program_add_window (app, HILDON_WINDOW (self));
1240 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
1241 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
1243 g_signal_connect (G_OBJECT(self), "show",
1244 G_CALLBACK (modest_main_window_on_show), folder_win);
1246 /* Set window icon */
1247 window_icon = modest_platform_get_icon (MODEST_APP_ICON, MODEST_ICON_SIZE_BIG);
1249 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
1250 g_object_unref (window_icon);
1253 /* Listen for changes in the screen, we don't want to show a
1254 led pattern when the display is on for example */
1255 osso_hw_set_display_event_cb (modest_maemo_utils_get_osso_context (),
1256 osso_display_event_cb,
1259 /* Dont't restore settings here,
1260 * because it requires a gtk_widget_show(),
1261 * and we don't want to do that until later,
1262 * so that the UI is not visible for non-menu D-Bus activation.
1265 return MODEST_WINDOW(self);
1269 modest_main_window_set_style (ModestMainWindow *self,
1270 ModestMainWindowStyle style)
1272 ModestMainWindowPrivate *priv;
1273 ModestWindowPrivate *parent_priv;
1277 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1279 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1280 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1282 /* no change -> nothing to do */
1283 if (priv->style == style)
1286 /* Get toggle button and update the state if needed. This will
1287 happen only when the set_style is not invoked from the UI,
1288 for example when it's called from widget memory */
1289 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1290 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
1291 if ((active && style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) ||
1292 (!active && style == MODEST_MAIN_WINDOW_STYLE_SPLIT)) {
1293 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1294 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !active);
1295 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1298 priv->style = style;
1300 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
1301 /* Remove main paned */
1302 g_object_ref (priv->main_paned);
1303 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1305 /* Reparent the contents widget to the main vbox */
1306 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
1309 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1310 /* Remove header view */
1311 g_object_ref (priv->contents_widget);
1312 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1314 /* Reparent the main paned */
1315 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1316 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1320 g_return_if_reached ();
1323 /* Let header view grab the focus if it's being shown */
1324 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1325 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1327 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1330 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1333 ModestMainWindowStyle
1334 modest_main_window_get_style (ModestMainWindow *self)
1336 ModestMainWindowPrivate *priv;
1338 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1340 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1345 toolbar_resize (ModestMainWindow *self)
1347 ModestMainWindowPrivate *priv = NULL;
1348 ModestWindowPrivate *parent_priv = NULL;
1350 gint static_button_size;
1351 ModestWindowMgr *mgr;
1353 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1354 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1355 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1357 mgr = modest_runtime_get_window_mgr ();
1358 static_button_size = modest_window_mgr_get_fullscreen_mode (mgr)?118:108;
1360 if (parent_priv->toolbar) {
1361 /* left size buttons */
1362 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNew");
1363 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1364 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1365 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1366 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply");
1367 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1368 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1369 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1370 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage");
1371 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1372 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1373 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1374 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1375 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1376 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1377 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1379 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1380 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1381 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1382 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1383 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1384 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1385 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1386 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1394 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1396 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1397 ModestWindowPrivate *parent_priv;
1398 ModestWindowMgr *mgr;
1399 gboolean is_fullscreen;
1400 GtkAction *fs_toggle_action;
1403 mgr = modest_runtime_get_window_mgr ();
1405 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1407 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1409 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1410 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1411 if (is_fullscreen != active) {
1412 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1415 toolbar_resize (MODEST_MAIN_WINDOW (widget));
1423 modest_main_window_show_toolbar (ModestWindow *self,
1424 gboolean show_toolbar)
1426 ModestMainWindowPrivate *priv = NULL;
1427 ModestWindowPrivate *parent_priv = NULL;
1428 GtkWidget *reply_button = NULL, *menu = NULL;
1429 GtkWidget *placeholder = NULL;
1431 const gchar *action_name;
1434 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1435 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1436 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1438 /* Set optimized view status */
1439 priv->optimized_view = !show_toolbar;
1441 if (!parent_priv->toolbar) {
1442 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1444 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1446 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1447 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1448 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1449 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1450 toolbar_resize (MODEST_MAIN_WINDOW (self));
1452 /* Add ProgressBar (Transfer toolbar) */
1453 priv->progress_bar = modest_progress_bar_widget_new ();
1454 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1455 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1456 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1457 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1458 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1460 /* Connect cancel 'clicked' signal to abort progress mode */
1461 g_signal_connect(priv->cancel_toolitem, "clicked",
1462 G_CALLBACK(cancel_progressbar),
1465 /* Add it to the observers list */
1466 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1469 hildon_window_add_toolbar (HILDON_WINDOW (self),
1470 GTK_TOOLBAR (parent_priv->toolbar));
1472 /* Set reply button tap and hold menu */
1473 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1474 "/ToolBar/ToolbarMessageReply");
1475 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1476 "/ToolbarReplyCSM");
1477 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1479 /* Set send & receive button tap and hold menu */
1480 update_menus (MODEST_MAIN_WINDOW (self));
1484 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1485 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1486 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1488 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1489 if (modest_main_window_transfer_mode_enabled (MODEST_MAIN_WINDOW(self)))
1490 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_TRANSFER);
1492 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1494 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1498 /* Update also the actions (to update the toggles in the
1499 menus), we have to do it manually because some other window
1500 of the same time could have changed it (remember that the
1501 toolbar fullscreen mode is shared by all the windows of the
1503 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
1504 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu";
1506 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu";
1508 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
1509 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
1514 on_account_inserted (TnyAccountStore *accoust_store,
1515 TnyAccount *account,
1518 /* Transport accounts and local ones (MMC and the Local
1519 folders account do now cause menu changes */
1520 if (TNY_IS_STORE_ACCOUNT (account) &&
1521 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1522 update_menus (MODEST_MAIN_WINDOW (user_data));
1526 on_default_account_changed (ModestAccountMgr* mgr,
1529 update_menus (MODEST_MAIN_WINDOW (user_data));
1533 on_account_removed (TnyAccountStore *accoust_store,
1534 TnyAccount *account,
1537 /* Transport accounts and local ones (MMC and the Local
1538 folders account do now cause menu changes */
1539 if (TNY_IS_STORE_ACCOUNT (account) &&
1540 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1541 update_menus (MODEST_MAIN_WINDOW (user_data));
1545 on_account_changed (TnyAccountStore *account_store,
1546 TnyAccount *account,
1549 ModestMainWindow *win = MODEST_MAIN_WINDOW (user_data);
1551 /* We need to refresh the details widget because it could have changed */
1552 if (modest_main_window_get_contents_style(win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS) {
1553 modest_main_window_set_contents_style (win, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1556 /* Update the menus as well, the account name could be
1557 changed. Transport accounts and local ones (MMC and the
1558 Local folders account do now cause menu changes */
1559 if (TNY_IS_STORE_ACCOUNT (account) &&
1560 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1561 update_menus (MODEST_MAIN_WINDOW (user_data));
1565 * This function manages the key events used to navigate between
1566 * header and folder views (when the window is in split view)
1569 * -------------------------------------------------
1570 * HeaderView GDK_Left Move focus to folder view
1571 * FolderView GDK_Right Move focus to header view
1573 * There is no need to scroll to selected row, the widgets will be the
1574 * responsibles of doing that (probably managing the focus-in event
1577 on_inner_widgets_key_pressed (GtkWidget *widget,
1581 ModestMainWindowPrivate *priv;
1583 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1585 /* Do nothing if we're in SIMPLE style */
1586 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1589 if (MODEST_IS_HEADER_VIEW (widget)) {
1590 if (event->keyval == GDK_Left)
1591 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1592 else if ((event->keyval == GDK_Return)||(event->keyval == GDK_KP_Enter)) {
1593 guint selected_headers = modest_header_view_count_selected_headers (MODEST_HEADER_VIEW (widget));
1594 if (selected_headers > 1) {
1595 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1599 } else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1600 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1606 set_alignment (GtkWidget *widget,
1609 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1610 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1614 create_empty_view (void)
1616 GtkLabel *label = NULL;
1617 GtkWidget *align = NULL;
1619 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1620 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1621 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1622 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1624 return GTK_WIDGET(align);
1628 * Free the returned string
1631 get_gray_color_markup (GtkWidget *styled_widget)
1633 gchar *gray_color_markup = NULL;
1634 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1635 /* Obtain the secondary text color. We need a realized widget, that's why
1636 we get styled_widget from outside */
1638 if (gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color))
1639 gray_color_markup = modest_text_utils_get_color_string (&color);
1640 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
1642 if (!gray_color_markup)
1643 gray_color_markup = g_strdup ("#BBBBBB");
1645 return gray_color_markup;
1649 * Free the returned string
1652 create_device_name_visual_string (const gchar *device_name,
1653 const gchar *gray_color_markup)
1657 /* We have to use "" to fill the %s of the translation. We can
1658 not just use the device name because the device name is
1659 shown in a different color, so it could not be included
1660 into the <span> tag */
1661 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), "");
1662 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1672 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1674 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1679 gchar *gray_color_markup;
1681 vbox = gtk_vbox_new (FALSE, 0);
1683 gray_color_markup = get_gray_color_markup (styled_widget);
1685 /* Account description: */
1686 if (modest_tny_account_is_virtual_local_folders (account)
1687 || (modest_tny_account_is_memory_card_account (account))) {
1689 /* Get device name */
1690 gchar *device_name = NULL;
1691 if (modest_tny_account_is_virtual_local_folders (account))
1692 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1693 MODEST_CONF_DEVICE_NAME, NULL);
1695 device_name = g_strdup (tny_account_get_name (account));
1697 label = create_device_name_visual_string ((const gchar *) device_name,
1698 (const gchar *) gray_color_markup);
1699 label_w = gtk_label_new (NULL);
1700 gtk_label_set_markup (GTK_LABEL (label_w), label);
1701 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1702 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1703 g_free (device_name);
1706 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1707 gtk_box_pack_start (GTK_BOX (vbox),
1708 gtk_label_new (tny_account_get_name (account)),
1711 /* Other accounts, such as IMAP and POP: */
1716 /* Put proto in uppercase */
1717 proto = g_string_new (tny_account_get_proto (account));
1718 proto = g_string_ascii_up (proto);
1720 /* note: mcen_fi_localroot_description is something like "%s account"
1721 * however, we should display "%s account: %s"... therefore, ugly tmp */
1722 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1723 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1724 gray_color_markup, tmp, tny_account_get_name (account));
1727 label_w = gtk_label_new (NULL);
1728 gtk_label_set_markup (GTK_LABEL (label_w), label);
1729 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1730 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1731 g_string_free (proto, TRUE);
1737 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1738 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1739 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1740 modest_tny_folder_store_get_message_count (folder_store));
1741 label_w = gtk_label_new (NULL);
1742 gtk_label_set_markup (GTK_LABEL (label_w), label);
1743 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1744 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1748 label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d",
1750 _("mcen_fi_rootfolder_folders"),
1751 modest_tny_folder_store_get_folder_count (folder_store));
1752 label_w = gtk_label_new (NULL);
1753 gtk_label_set_markup (GTK_LABEL (label_w), label);
1754 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1755 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1759 if (modest_tny_account_is_virtual_local_folders (account)
1760 || modest_tny_account_is_memory_card_account (account)) {
1762 gchar *size = modest_text_utils_get_display_size (
1763 modest_tny_folder_store_get_local_size (folder_store));
1765 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1766 gray_color_markup, _("mcen_fi_rootfolder_size"),
1770 label_w = gtk_label_new (NULL);
1771 gtk_label_set_markup (GTK_LABEL (label_w), label);
1772 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1773 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1775 } else if (TNY_IS_ACCOUNT(folder_store)) {
1776 TnyAccount *account = TNY_ACCOUNT(folder_store);
1778 time_t last_updated;
1779 const gchar *last_updated_string;
1780 /* Get last updated from configuration */
1781 last_updated = modest_account_mgr_get_last_updated (modest_runtime_get_account_mgr (),
1782 tny_account_get_id (account));
1784 if (last_updated > 0)
1785 last_updated_string = modest_text_utils_get_display_date(last_updated);
1787 last_updated_string = g_strdup (_("mcen_va_never"));
1789 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1790 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1791 label_w = gtk_label_new (NULL);
1792 gtk_label_set_markup (GTK_LABEL (label_w), label);
1793 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1794 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1798 g_free (gray_color_markup);
1801 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1807 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1809 ModestMainWindowPrivate *priv = NULL;
1811 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1813 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1815 return priv->send_receive_in_progress;
1819 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1821 GtkAction *action = NULL;
1822 GtkWidget *widget = NULL;
1823 ModestMainWindowPrivate *priv = NULL;
1825 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1826 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1828 priv->send_receive_in_progress = TRUE;
1830 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1831 gtk_action_set_sensitive (action, FALSE);
1832 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1833 /* gtk_action_set_sensitive (action, FALSE); */
1834 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1835 gtk_widget_set_sensitive (widget, FALSE);
1839 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1841 GtkAction *action = NULL;
1842 GtkWidget *widget = NULL;
1843 ModestMainWindowPrivate *priv = NULL;
1845 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1846 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1848 priv->send_receive_in_progress = FALSE;
1850 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1851 gtk_action_set_sensitive (action, TRUE);
1852 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1853 /* gtk_action_set_sensitive (action, TRUE); */
1854 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1855 gtk_widget_set_sensitive (widget, TRUE);
1860 on_msg_count_changed (ModestHeaderView *header_view,
1862 TnyFolderChange *change,
1863 ModestMainWindow *main_window)
1865 gboolean folder_empty = FALSE;
1866 gboolean all_marked_as_deleted = FALSE;
1867 ModestMainWindowPrivate *priv;
1869 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1870 g_return_if_fail (TNY_IS_FOLDER(folder));
1871 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
1873 if (change != NULL) {
1874 TnyFolderChangeChanged changed;
1876 changed = tny_folder_change_get_changed (change);
1877 /* If something changes */
1878 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1879 folder_empty = (tny_folder_change_get_new_all_count (change) == 0);
1881 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1883 /* Play a sound (if configured) and make the LED blink */
1884 if (changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS) {
1885 modest_platform_on_new_headers_received (NULL, FALSE);
1888 /* Checks header removed (hide marked as DELETED headers) */
1889 if (changed & TNY_FOLDER_CHANGE_CHANGED_EXPUNGED_HEADERS) {
1890 modest_header_view_refilter (MODEST_HEADER_VIEW(priv->header_view));
1894 /* Check if all messages are marked to be deleted */
1895 all_marked_as_deleted = modest_header_view_is_empty (header_view);
1896 folder_empty = folder_empty || all_marked_as_deleted ;
1898 /* Set contents style of headers view */
1900 modest_main_window_set_contents_style (main_window,
1901 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1902 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1904 modest_main_window_set_contents_style (main_window,
1905 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1911 modest_main_window_set_contents_style (ModestMainWindow *self,
1912 ModestMainWindowContentsStyle style)
1914 ModestMainWindowPrivate *priv;
1916 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1918 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1920 /* We allow to set the same content style than the previously
1921 set if there are details, because it could happen when we're
1922 selecting different accounts consecutively */
1923 if ((priv->contents_style == style) &&
1924 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1927 /* Remove previous child. Delete it if it was an account
1929 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1931 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1932 g_object_ref (content);
1933 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1934 g_object_ref (priv->empty_view);
1935 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
1938 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1941 priv->contents_style = style;
1943 switch (priv->contents_style) {
1944 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1945 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1946 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1949 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1951 /* if we're started without main win, there may not be a folder
1952 * view. this fixes a GLib-Critical */
1953 if (priv->folder_view) {
1954 TnyFolderStore *selected_folderstore =
1955 modest_folder_view_get_selected (priv->folder_view);
1956 if (TNY_IS_ACCOUNT (selected_folderstore)) {
1957 priv->details_widget = create_details_widget (GTK_WIDGET (self),
1958 TNY_ACCOUNT (selected_folderstore));
1960 wrap_in_scrolled_window (priv->contents_widget,
1961 priv->details_widget);
1963 g_object_unref (selected_folderstore);
1964 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1969 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
1970 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
1971 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1975 g_return_if_reached ();
1979 gtk_widget_show_all (priv->contents_widget);
1982 ModestMainWindowContentsStyle
1983 modest_main_window_get_contents_style (ModestMainWindow *self)
1985 ModestMainWindowPrivate *priv;
1987 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1989 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1990 return priv->contents_style;
1995 on_configuration_key_changed (ModestConf* conf,
1997 ModestConfEvent event,
1998 ModestConfNotificationId id,
1999 ModestMainWindow *self)
2001 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2002 TnyAccount *account = NULL;
2004 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
2007 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
2010 if (priv->folder_view)
2011 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
2013 if (account && TNY_IS_ACCOUNT (account) &&
2014 strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID) == 0) {
2017 const gchar *device_name;
2018 gchar *new_text, *gray_color_markup;
2021 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
2022 label = GTK_LABEL (children->data);
2024 device_name = modest_conf_get_string (modest_runtime_get_conf(),
2025 MODEST_CONF_DEVICE_NAME, NULL);
2027 gray_color_markup = get_gray_color_markup (GTK_WIDGET (self));
2028 new_text = create_device_name_visual_string (device_name, gray_color_markup);
2030 gtk_label_set_markup (label, new_text);
2031 gtk_widget_show (GTK_WIDGET (label));
2033 g_free (gray_color_markup);
2035 g_list_free (children);
2037 g_object_unref (account);
2041 set_toolbar_transfer_mode (ModestMainWindow *self)
2043 ModestMainWindowPrivate *priv = NULL;
2045 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2047 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2049 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
2051 if (priv->progress_bar_timeout > 0) {
2052 g_source_remove (priv->progress_bar_timeout);
2053 priv->progress_bar_timeout = 0;
2060 set_toolbar_mode (ModestMainWindow *self,
2061 ModestToolBarModes mode)
2063 ModestWindowPrivate *parent_priv = NULL;
2064 ModestMainWindowPrivate *priv = NULL;
2065 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
2067 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2069 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2070 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2072 /* In case this was called before the toolbar exists: */
2073 if (!(parent_priv->toolbar))
2076 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
2078 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
2079 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
2080 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
2082 /* Sets current toolbar mode */
2083 priv->current_toolbar_mode = mode;
2085 /* Checks the dimming rules */
2086 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2088 /* Show and hide toolbar items */
2090 case TOOLBAR_MODE_NORMAL:
2092 gtk_action_set_visible (sort_action, TRUE);
2094 gtk_action_set_visible (refresh_action, TRUE);
2095 if (priv->progress_toolitem) {
2096 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
2097 gtk_widget_hide (priv->progress_toolitem);
2099 if (priv->progress_bar)
2100 gtk_widget_hide (priv->progress_bar);
2103 gtk_action_set_visible (cancel_action, FALSE);
2105 /* Hide toolbar if optimized view is enabled */
2106 if (priv->optimized_view)
2107 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
2109 case TOOLBAR_MODE_TRANSFER:
2111 gtk_action_set_visible (sort_action, FALSE);
2113 gtk_action_set_visible (refresh_action, FALSE);
2115 gtk_action_set_visible (cancel_action, TRUE);
2116 if (priv->progress_bar)
2117 gtk_widget_show (priv->progress_bar);
2118 if (priv->progress_toolitem) {
2119 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
2120 gtk_widget_show (priv->progress_toolitem);
2123 /* Show toolbar if it's hiden (optimized view ) */
2124 if (priv->optimized_view)
2125 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2128 g_return_if_reached ();
2133 modest_main_window_transfer_mode_enabled (ModestMainWindow *self)
2135 ModestMainWindowPrivate *priv;
2137 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2138 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2140 return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
2144 cancel_progressbar (GtkToolButton *toolbutton,
2145 ModestMainWindow *self)
2148 ModestMainWindowPrivate *priv;
2150 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2152 /* Get operation observers and cancel all the operations */
2153 tmp = priv->progress_widgets;
2155 modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2156 tmp=g_slist_next(tmp);
2161 observers_empty (ModestMainWindow *self)
2164 ModestMainWindowPrivate *priv;
2165 gboolean is_empty = TRUE;
2166 guint pending_ops = 0;
2168 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2169 tmp = priv->progress_widgets;
2171 /* Check all observers */
2172 while (tmp && is_empty) {
2173 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2174 is_empty = pending_ops == 0;
2176 tmp = g_slist_next(tmp);
2184 * Gets the toolbar mode needed for each mail operation. It stores in
2185 * @mode_changed if the toolbar mode has changed or not
2187 static ModestToolBarModes
2188 get_toolbar_mode_from_mail_operation (ModestMainWindow *self,
2189 ModestMailOperation *mail_op,
2190 gboolean *mode_changed)
2192 ModestToolBarModes mode;
2193 ModestMainWindowPrivate *priv;
2195 *mode_changed = FALSE;
2196 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2198 /* Get toolbar mode from operation id*/
2199 switch (modest_mail_operation_get_type_operation (mail_op)) {
2200 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
2201 case MODEST_MAIL_OPERATION_TYPE_OPEN:
2202 mode = TOOLBAR_MODE_TRANSFER;
2203 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
2204 *mode_changed = TRUE;
2207 mode = TOOLBAR_MODE_NORMAL;
2213 on_mail_operation_started (ModestMailOperation *mail_op,
2216 ModestMainWindow *self;
2217 ModestMailOperationTypeOperation op_type;
2218 ModestMainWindowPrivate *priv;
2219 ModestToolBarModes mode;
2221 gboolean mode_changed = FALSE;
2222 TnyAccount *account;
2224 self = MODEST_MAIN_WINDOW (user_data);
2225 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2227 /* Do not show progress for receiving operations if the
2228 account is the local account or the MMC one */
2229 op_type = modest_mail_operation_get_type_operation (mail_op);
2230 account = modest_mail_operation_get_account (mail_op);
2231 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2234 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2235 modest_tny_account_is_memory_card_account (account));
2236 g_object_unref (account);
2241 /* Get toolbar mode from operation id*/
2242 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2244 /* Add operation observers and change toolbar if neccessary*/
2245 tmp = priv->progress_widgets;
2246 if (mode == TOOLBAR_MODE_TRANSFER) {
2248 GObject *source = modest_mail_operation_get_source(mail_op);
2249 if (G_OBJECT (self) == source) {
2250 set_toolbar_transfer_mode(self);
2252 g_object_unref (source);
2256 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2258 tmp = g_slist_next (tmp);
2264 on_mail_operation_finished (ModestMailOperation *mail_op,
2267 ModestToolBarModes mode;
2268 ModestMailOperationTypeOperation op_type;
2270 ModestMainWindow *self;
2271 gboolean mode_changed;
2272 TnyAccount *account;
2273 ModestMainWindowPrivate *priv;
2275 self = MODEST_MAIN_WINDOW (user_data);
2276 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2278 /* The mail operation was not added to the progress objects if
2279 the account was the local account or the MMC one */
2280 op_type = modest_mail_operation_get_type_operation (mail_op);
2281 account = modest_mail_operation_get_account (mail_op);
2282 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2285 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2286 modest_tny_account_is_memory_card_account (account));
2287 g_object_unref (account);
2292 /* Get toolbar mode from operation id*/
2293 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2295 /* Change toolbar mode */
2296 tmp = priv->progress_widgets;
2297 if (mode == TOOLBAR_MODE_TRANSFER) {
2299 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2301 tmp = g_slist_next (tmp);
2304 /* If no more operations are being observed, NORMAL mode is enabled again */
2305 if (observers_empty (self)) {
2306 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
2312 on_queue_changed (ModestMailOperationQueue *queue,
2313 ModestMailOperation *mail_op,
2314 ModestMailOperationQueueNotification type,
2315 ModestMainWindow *self)
2317 ModestMainWindowPrivate *priv;
2319 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2321 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
2322 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2324 "operation-started",
2325 G_CALLBACK (on_mail_operation_started),
2327 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2329 "operation-finished",
2330 G_CALLBACK (on_mail_operation_finished),
2332 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
2333 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2335 "operation-started");
2336 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2338 "operation-finished");
2343 set_account_visible(ModestMainWindow *self, const gchar *acc_name)
2345 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2347 ModestAccountMgr *mgr;
2348 ModestAccountSettings *settings;
2349 ModestServerAccountSettings *store_settings = NULL;
2351 /* Get account data */
2352 mgr = modest_runtime_get_account_mgr ();
2353 settings = modest_account_mgr_load_account_settings (mgr, acc_name);
2355 store_settings = modest_account_settings_get_store_settings (settings);
2357 /* Set the new visible & active account */
2358 if (settings && (modest_server_account_settings_get_account_name (store_settings)!= NULL)) {
2359 const gchar *account_name;
2361 account_name = modest_account_settings_get_account_name (settings);
2363 modest_folder_view_set_account_id_of_visible_server_account
2365 modest_server_account_settings_get_account_name (store_settings));
2366 modest_window_set_active_account (MODEST_WINDOW (self), account_name);
2367 action = gtk_action_group_get_action (priv->view_additions_group, account_name);
2368 if (action != NULL) {
2369 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2370 modest_utils_toggle_action_set_active_block_notify (
2371 GTK_TOGGLE_ACTION (action),
2377 modest_folder_view_select_first_inbox_or_local (priv->folder_view);
2382 g_object_unref (store_settings);
2383 g_object_unref (settings);
2387 /* Make sure that at least one account is "viewed": */
2389 set_at_least_one_account_visible(ModestMainWindow *self)
2391 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2392 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2394 if (!(priv->folder_view)) {
2395 /* It is too early to do this. */
2399 const gchar *active_server_account_name =
2400 modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);
2402 if (!active_server_account_name ||
2403 !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
2405 gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
2406 gchar* default_modest_name = modest_account_mgr_get_default_account (account_mgr);
2407 if (default_modest_name) {
2408 set_account_visible (self, default_modest_name);
2409 } else if (first_modest_name) {
2410 set_account_visible (self, first_modest_name);
2412 g_free (first_modest_name);
2413 g_free (default_modest_name);
2418 on_show_account_action_toggled (GtkToggleAction *action,
2421 ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
2423 const gchar *acc_name = gtk_action_get_name (GTK_ACTION (action));
2424 if (gtk_toggle_action_get_active (action))
2425 set_account_visible (self, acc_name);
2429 refresh_account (const gchar *account_name)
2433 /* win must already exists here, obviously */
2434 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
2437 g_warning ("%s: BUG: no main window!", __FUNCTION__);
2441 /* If account_name == NULL, we must update all (option All) */
2443 modest_ui_actions_do_send_receive_all (win);
2445 modest_ui_actions_do_send_receive (account_name, win);
2450 on_refresh_account_action_activated (GtkAction *action,
2453 refresh_account ((const gchar*) user_data);
2457 on_send_receive_csm_activated (GtkMenuItem *item,
2460 refresh_account ((const gchar*) user_data);
2464 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2466 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2468 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2474 on_folder_view_focus_in (GtkWidget *widget, GdkEventFocus *event, gpointer userdata)
2476 ModestMainWindow *main_window = NULL;
2478 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2479 main_window = MODEST_MAIN_WINDOW (userdata);
2481 /* Update toolbar dimming state */
2482 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2488 on_header_view_focus_in (GtkWidget *widget,
2489 GdkEventFocus *event,
2492 ModestMainWindow *main_window = NULL;
2494 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2496 main_window = MODEST_MAIN_WINDOW (userdata);
2498 /* Update toolbar dimming state */
2499 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2505 on_folder_selection_changed (ModestFolderView *folder_view,
2506 TnyFolderStore *folder_store,
2508 ModestMainWindow *main_window)
2510 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2511 GtkAction *action = NULL;
2512 gboolean show_reply = TRUE;
2513 gboolean show_forward = TRUE;
2514 gboolean show_cancel_send = FALSE;
2515 gboolean show_clipboard = TRUE;
2516 gboolean show_delete = TRUE;
2519 if (TNY_IS_ACCOUNT (folder_store)) {
2520 show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2521 } else if (TNY_IS_FOLDER (folder_store)) {
2522 if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2523 TnyFolderType folder_type = modest_tny_folder_get_local_or_mmc_folder_type (
2524 TNY_FOLDER (folder_store));
2525 switch (folder_type) {
2526 case TNY_FOLDER_TYPE_DRAFTS:
2527 show_clipboard = show_delete = TRUE;
2528 show_reply = show_forward = show_cancel_send = FALSE;
2530 case TNY_FOLDER_TYPE_SENT:
2531 show_forward = show_clipboard = show_delete = TRUE;
2532 show_reply = show_cancel_send = FALSE;
2534 case TNY_FOLDER_TYPE_OUTBOX:
2535 show_clipboard = show_delete = show_cancel_send = TRUE;
2536 show_reply = show_forward = FALSE;
2538 case TNY_FOLDER_TYPE_INVALID:
2539 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
2542 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2543 show_cancel_send = FALSE;
2546 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2547 show_cancel_send = FALSE;
2552 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2553 gtk_action_set_visible (action, show_reply);
2554 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2555 gtk_action_set_visible (action, show_reply);
2556 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2557 gtk_action_set_visible (action, show_forward);
2558 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2559 gtk_action_set_visible (action, show_cancel_send);
2560 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2561 gtk_action_set_visible (action, show_delete);
2563 /* We finally call to the ui actions handler, after updating properly
2564 * the header view CSM */
2565 modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2569 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2570 GtkTreeModel *model,
2571 GtkTreeRowReference *row_reference,
2572 ModestMainWindow *self)
2574 ModestMainWindowPrivate *priv = NULL;
2575 GtkTreeModel *header_model = NULL;
2576 GtkTreePath *path = NULL;
2578 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
2579 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2580 g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2582 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2583 header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2585 /* Do nothing if we changed the folder in the main view */
2586 if (header_model != model)
2589 /* Select the message in the header view */
2590 path = gtk_tree_row_reference_get_path (row_reference);
2591 gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->header_view),
2593 gtk_tree_path_free (path);
2599 show_updating_banner (gpointer user_data)
2601 ModestMainWindowPrivate *priv = NULL;
2603 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2605 if (priv->updating_banner == NULL) {
2607 /* We're outside the main lock */
2608 gdk_threads_enter ();
2609 priv->updating_banner =
2610 modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2611 _CS ("ckdg_pb_updating"));
2612 gdk_threads_leave ();
2615 /* Remove timeout */
2616 priv->updating_banner_timeout = 0;
2621 * We use this function to show/hide a progress banner showing
2622 * "Updating" while the header view is being filled. We're not showing
2623 * it unless the update takes more than 2 seconds
2625 * If starting = TRUE then the refresh is starting, otherwise it means
2626 * that is has just finished
2629 on_updating_msg_list (ModestHeaderView *header_view,
2633 ModestMainWindowPrivate *priv = NULL;
2635 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2637 /* Remove old timeout */
2638 if (priv->updating_banner_timeout > 0) {
2639 g_source_remove (priv->updating_banner_timeout);
2640 priv->updating_banner_timeout = 0;
2643 /* Create a new timeout */
2645 priv->updating_banner_timeout =
2646 g_timeout_add (2000, show_updating_banner, user_data);
2648 /* Remove the banner if exists */
2649 if (priv->updating_banner) {
2650 gtk_widget_destroy (priv->updating_banner);
2651 priv->updating_banner = NULL;
2657 modest_main_window_screen_is_on (ModestMainWindow *self)
2659 ModestMainWindowPrivate *priv = NULL;
2661 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2663 return (priv->display_state == OSSO_DISPLAY_ON) ? TRUE : FALSE;