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.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 static gboolean show_retrieving_banner (gpointer user_data);
181 static void on_window_destroy (GtkObject *widget,
184 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
185 struct _ModestMainWindowPrivate {
186 GtkWidget *msg_paned;
187 GtkWidget *main_paned;
188 GtkWidget *main_vbox;
189 GtkWidget *contents_widget;
190 GtkWidget *empty_view;
192 /* Progress observers */
193 GtkWidget *progress_bar;
194 GSList *progress_widgets;
197 GtkWidget *progress_toolitem;
198 GtkWidget *cancel_toolitem;
199 GtkWidget *sort_toolitem;
200 GtkWidget *refresh_toolitem;
201 ModestToolBarModes current_toolbar_mode;
203 /* Merge ids used to add/remove accounts to the ViewMenu*/
204 GByteArray *merge_ids;
205 GtkActionGroup *view_additions_group;
207 /* On-demand widgets */
208 GtkWidget *accounts_popup;
209 GtkWidget *details_widget;
211 /* Optimized view enabled */
212 gboolean optimized_view;
214 /* Optimized view enabled */
215 gboolean send_receive_in_progress;
217 ModestHeaderView *header_view;
218 ModestFolderView *folder_view;
220 ModestMainWindowStyle style;
221 ModestMainWindowContentsStyle contents_style;
222 gboolean wait_for_settings;
224 guint progress_bar_timeout;
225 guint restore_paned_timeout;
227 /* Signal handler UIDs */
228 GList *queue_err_signals;
231 /* "Updating" banner for header view */
232 GtkWidget *updating_banner;
233 guint updating_banner_timeout;
235 /* "Retrieving" banner for header view */
236 GtkWidget *retrieving_banner;
237 guint retrieving_banner_timeout;
240 osso_display_state_t display_state;
242 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
243 MODEST_TYPE_MAIN_WINDOW, \
244 ModestMainWindowPrivate))
246 typedef struct _GetMsgAsyncHelper {
247 ModestMainWindowPrivate *main_window_private;
249 ModestTnyMsgReplyType reply_type;
250 ModestTnyMsgForwardType forward_type;
257 static GtkWindowClass *parent_class = NULL;
260 /* Private actions */
261 /* This is the context sensitive menu: */
262 static const GtkActionEntry modest_folder_view_action_entries [] = {
264 /* Folder View CSM actions */
265 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
266 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
267 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_paste)},
268 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
269 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_search_messages) },
270 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
273 static const GtkActionEntry modest_header_view_action_entries [] = {
275 /* Header View CSM actions */
276 { "HeaderViewCSMOpen", NULL, N_("mcen_me_inbox_open"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_open) },
277 { "HeaderViewCSMReply", NULL, N_("mcen_me_inbox_reply"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply) },
278 { "HeaderViewCSMReplyAll", NULL, N_("mcen_me_inbox_replytoall"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply_all) },
279 { "HeaderViewCSMForward", NULL, N_("mcen_me_inbox_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_forward) },
280 { "HeaderViewCSMCut", NULL, N_("mcen_me_inbox_cut"), "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
281 { "HeaderViewCSMCopy", NULL, N_("mcen_me_inbox_copy"), "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
282 { "HeaderViewCSMPaste", NULL, N_("mcen_me_inbox_paste"), "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
283 { "HeaderViewCSMDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_message) },
284 { "HeaderViewCSMCancelSending", NULL, N_("mcen_me_outbox_cancelsend"), NULL, NULL, G_CALLBACK (modest_ui_actions_cancel_send) },
285 { "HeaderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
288 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
289 { "ToggleFolders", MODEST_STOCK_SPLIT_VIEW, N_("mcen_me_inbox_hidefolders"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), TRUE },
292 /************************************************************************/
295 modest_main_window_get_type (void)
297 static GType my_type = 0;
299 static const GTypeInfo my_info = {
300 sizeof(ModestMainWindowClass),
301 NULL, /* base init */
302 NULL, /* base finalize */
303 (GClassInitFunc) modest_main_window_class_init,
304 NULL, /* class finalize */
305 NULL, /* class data */
306 sizeof(ModestMainWindow),
308 (GInstanceInitFunc) modest_main_window_init,
311 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
319 modest_main_window_class_init (ModestMainWindowClass *klass)
321 GObjectClass *gobject_class;
322 gobject_class = (GObjectClass*) klass;
323 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
325 parent_class = g_type_class_peek_parent (klass);
326 gobject_class->finalize = modest_main_window_finalize;
328 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
330 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
331 modest_window_class->save_state_func = save_state;
332 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
333 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
334 modest_window_class->disconnect_signals_func = modest_main_window_disconnect_signals;
338 modest_main_window_init (ModestMainWindow *obj)
340 ModestMainWindowPrivate *priv;
342 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
344 priv->queue_err_signals = NULL;
345 priv->msg_paned = NULL;
346 priv->main_paned = NULL;
347 priv->main_vbox = NULL;
348 priv->header_view = NULL;
349 priv->folder_view = NULL;
350 priv->contents_widget = NULL;
351 priv->accounts_popup = NULL;
352 priv->details_widget = NULL;
353 priv->empty_view = NULL;
354 priv->progress_widgets = NULL;
355 priv->progress_bar = NULL;
356 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
357 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
358 priv->wait_for_settings = TRUE;
359 priv->contents_style = -1; /* invalid contents style. We need this to select it for the first time */
360 priv->merge_ids = NULL;
361 priv->optimized_view = FALSE;
362 priv->send_receive_in_progress = FALSE;
363 priv->progress_bar_timeout = 0;
364 priv->restore_paned_timeout = 0;
365 priv->sighandlers = NULL;
366 priv->updating_banner = NULL;
367 priv->updating_banner_timeout = 0;
368 priv->retrieving_banner = NULL;
369 priv->retrieving_banner_timeout = 0;
370 priv->display_state = OSSO_DISPLAY_ON;
372 modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
374 "applications_email_mainview");
378 modest_main_window_finalize (GObject *obj)
380 ModestMainWindowPrivate *priv;
382 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
384 /* Sanity check: shouldn't be needed, the window mgr should
385 call this function before */
386 modest_main_window_disconnect_signals (MODEST_WINDOW (obj));
387 modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
389 g_slist_free (priv->progress_widgets);
391 g_byte_array_free (priv->merge_ids, TRUE);
393 if (priv->progress_bar_timeout > 0) {
394 g_source_remove (priv->progress_bar_timeout);
395 priv->progress_bar_timeout = 0;
398 if (priv->updating_banner_timeout > 0) {
399 g_source_remove (priv->updating_banner_timeout);
400 priv->updating_banner_timeout = 0;
403 if (priv->updating_banner) {
404 gtk_widget_destroy (priv->updating_banner);
405 priv->updating_banner = NULL;
408 if (priv->retrieving_banner_timeout > 0) {
409 g_source_remove (priv->retrieving_banner_timeout);
410 priv->retrieving_banner_timeout = 0;
413 if (priv->retrieving_banner) {
414 gtk_widget_destroy (priv->retrieving_banner);
415 priv->retrieving_banner = NULL;
418 if (priv->restore_paned_timeout > 0) {
419 g_source_remove (priv->restore_paned_timeout);
420 priv->restore_paned_timeout = 0;
423 G_OBJECT_CLASS(parent_class)->finalize (obj);
427 modest_main_window_get_child_widget (ModestMainWindow *self,
428 ModestMainWindowWidgetType widget_type)
430 ModestMainWindowPrivate *priv;
433 g_return_val_if_fail (self && MODEST_IS_MAIN_WINDOW(self), NULL);
434 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_MAIN_WINDOW_WIDGET_TYPE_NUM,
437 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
439 switch (widget_type) {
440 case MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW:
441 widget = (GtkWidget*)priv->header_view; break;
442 case MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW:
443 widget = (GtkWidget*)priv->folder_view; break;
448 /* Note that the window could have been destroyed, and so
449 their children, but still have some references */
450 return (widget && GTK_IS_WIDGET(widget)) ? GTK_WIDGET(widget) : NULL;
454 restore_paned_timeout_handler (gpointer *data)
456 ModestMainWindow *main_window = MODEST_MAIN_WINDOW (data);
457 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
460 /* Timeouts are outside the main lock */
461 gdk_threads_enter ();
462 if (GTK_WIDGET_VISIBLE (main_window)) {
463 conf = modest_runtime_get_conf ();
464 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
465 MODEST_CONF_MAIN_PANED_KEY);
467 gdk_threads_leave ();
474 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
477 ModestMainWindowPrivate *priv;
479 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
481 conf = modest_runtime_get_conf ();
483 modest_widget_memory_restore (conf, G_OBJECT(self),
484 MODEST_CONF_MAIN_WINDOW_KEY);
486 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
487 MODEST_CONF_HEADER_VIEW_KEY);
489 if (do_folder_view_too)
490 modest_widget_memory_restore (conf, G_OBJECT(priv->folder_view),
491 MODEST_CONF_FOLDER_VIEW_KEY);
493 /* modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned), */
494 /* MODEST_CONF_MAIN_PANED_KEY); */
496 g_timeout_add (250, (GSourceFunc) restore_paned_timeout_handler, self);
498 /* We need to force a redraw here in order to get the right
499 position of the horizontal paned separator */
500 gtk_widget_show (GTK_WIDGET (self));
505 save_state (ModestWindow *window)
508 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
509 ModestMainWindowPrivate *priv;
511 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
512 conf = modest_runtime_get_conf ();
514 modest_widget_memory_save (conf,G_OBJECT(self),
515 MODEST_CONF_MAIN_WINDOW_KEY);
516 /* Only save main paned position if we're in split mode */
517 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SPLIT)
518 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
519 MODEST_CONF_MAIN_PANED_KEY);
520 modest_widget_memory_save (conf, G_OBJECT(priv->folder_view),
521 MODEST_CONF_FOLDER_VIEW_KEY);
525 compare_display_names (ModestAccountSettings *a,
526 ModestAccountSettings *b)
528 return strcmp (modest_account_settings_get_display_name (a),
529 modest_account_settings_get_display_name (b));
532 /* We use this function to prevent the send&receive CSM to be shown
533 when there are less than two account */
535 tap_and_hold_query_cb (GtkWidget *widget, GdkEvent *event)
541 update_menus (ModestMainWindow* self)
543 GSList *account_names, *iter, *accounts;
544 ModestMainWindowPrivate *priv;
545 ModestWindowPrivate *parent_priv;
546 ModestAccountMgr *mgr;
547 gint i, num_accounts;
549 gchar *default_account;
550 const gchar *active_account_name;
551 GtkWidget *send_receive_button, *item;
552 GtkAction *send_receive_all = NULL;
555 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
556 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
558 /* Get enabled account IDs */
559 mgr = modest_runtime_get_account_mgr ();
560 account_names = modest_account_mgr_account_names (mgr, TRUE);
561 iter = account_names;
565 ModestAccountSettings *settings =
566 modest_account_mgr_load_account_settings (mgr, (gchar*) iter->data);
567 accounts = g_slist_prepend (accounts, settings);
571 modest_account_mgr_free_account_names (account_names);
572 account_names = NULL;
574 /* Order the list of accounts by its display name */
575 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
576 num_accounts = g_slist_length (accounts);
578 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
579 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
580 gtk_action_set_visible (send_receive_all, num_accounts > 0);
582 /* Delete old send&receive popup items. We can not just do a
583 menu_detach because it does not work well with
585 if (priv->accounts_popup)
586 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
587 (GtkCallback) gtk_widget_destroy, NULL);
589 /* Delete old entries in the View menu. Do not free groups, it
591 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
593 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
594 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
595 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
596 GTK_ACTION_GROUP (groups->data));
599 if (priv->merge_ids) {
600 for (i = 0; i < priv->merge_ids->len; i++)
601 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
602 g_byte_array_free (priv->merge_ids, TRUE);
604 /* We need to call this in order to ensure
605 that the new actions are added in the right
606 order (alphabetical) */
607 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
609 groups = g_list_next (groups);
611 priv->merge_ids = g_byte_array_sized_new (num_accounts);
613 /* Get send receive button */
614 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
615 "/ToolBar/ToolbarSendReceive");
617 /* Create the menu */
618 if (num_accounts > 1) {
619 if (!priv->accounts_popup)
620 priv->accounts_popup = gtk_menu_new ();
621 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
622 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
623 g_signal_connect (G_OBJECT (item),
625 G_CALLBACK (on_send_receive_csm_activated),
627 item = gtk_separator_menu_item_new ();
628 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
631 /* Create a new action group */
632 default_account = modest_account_mgr_get_default_account (mgr);
633 active_account_name = modest_window_get_active_account (MODEST_WINDOW (self));
635 if (!active_account_name)
636 modest_window_set_active_account (MODEST_WINDOW (self), default_account);
638 priv->view_additions_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
640 for (i = 0; i < num_accounts; i++) {
641 gchar *display_name = NULL;
642 const gchar *account_name;
643 ModestAccountSettings *settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
646 g_warning ("%s: BUG: account_data == NULL", __FUNCTION__);
649 account_name = modest_account_settings_get_account_name (settings);
651 if (default_account && account_name &&
652 !(strcmp (default_account, account_name) == 0)) {
653 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
654 modest_account_settings_get_display_name (settings));
656 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
657 modest_account_settings_get_display_name (settings));
662 /* Create action and add it to the action group. The
663 action name must be the account name, this way we
664 could know in the handlers the account to show */
665 if (settings && account_name) {
666 gchar* item_name, *refresh_action_name;
668 GtkAction *view_account_action, *refresh_account_action;
669 gchar *escaped_display_name;
671 escaped_display_name = modest_text_utils_escape_mnemonics (display_name);
673 view_account_action = GTK_ACTION (gtk_radio_action_new (account_name,
674 escaped_display_name, NULL, NULL, 0));
675 g_free (escaped_display_name);
676 gtk_action_group_add_action (priv->view_additions_group, view_account_action);
677 gtk_radio_action_set_group (GTK_RADIO_ACTION (view_account_action), radio_group);
678 radio_group = gtk_radio_action_get_group (GTK_RADIO_ACTION (view_account_action));
680 if (active_account_name) {
681 if (active_account_name && account_name &&
682 (strcmp (active_account_name, account_name) == 0)) {
683 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (view_account_action), TRUE);
687 /* Add ui from account data. We allow 2^9-1 account
688 changes in a single execution because we're
689 downcasting the guint to a guint8 in order to use a
690 GByteArray. It should be enough. */
691 item_name = g_strconcat (account_name, "Menu", NULL);
692 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
693 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
694 gtk_ui_manager_add_ui (parent_priv->ui_manager,
696 "/MenuBar/ViewMenu/ViewMenuAdditions",
699 GTK_UI_MANAGER_MENUITEM,
702 /* Connect the action signal "activate" */
703 g_signal_connect_after (G_OBJECT (view_account_action),
705 G_CALLBACK (on_show_account_action_toggled),
708 /* Create the items for the Tools->Send&Receive submenu */
709 refresh_action_name = g_strconcat ("SendReceive", account_name, NULL);
710 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
711 display_name, NULL, NULL);
712 gtk_action_group_add_action (priv->view_additions_group, refresh_account_action);
714 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
715 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
716 gtk_ui_manager_add_ui (parent_priv->ui_manager,
718 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
721 GTK_UI_MANAGER_MENUITEM,
723 g_free (refresh_action_name);
725 g_signal_connect_data (G_OBJECT (refresh_account_action),
727 G_CALLBACK (on_refresh_account_action_activated),
728 g_strdup (account_name),
729 (GClosureNotify) g_free,
732 /* Create item and add it to the send&receive
733 CSM. If there is only one account then
735 if (num_accounts > 1) {
736 GtkWidget *label = gtk_label_new(NULL);
737 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
738 if (default_account && (strcmp(account_name, default_account) == 0)) {
739 gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
740 gtk_label_set_markup (GTK_LABEL (label), escaped);
743 gtk_label_set_text (GTK_LABEL (label), display_name);
746 item = gtk_menu_item_new ();
747 gtk_container_add (GTK_CONTAINER (item), label);
749 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
750 g_signal_connect_data (G_OBJECT (item),
752 G_CALLBACK (on_send_receive_csm_activated),
753 g_strdup (account_name),
754 (GClosureNotify) g_free,
761 g_free (display_name);
764 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, priv->view_additions_group, 1);
766 /* We cannot do this in the loop above because this relies on the action
767 * group being inserted. This makes the default account appear in bold.
768 * I agree it is a rather ugly way, but I don't see another possibility. armin. */
769 for (i = 0; i < num_accounts; i++) {
770 gchar *item_name, *path;
772 ModestAccountSettings *settings;
773 const gchar *account_name;
776 settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
777 account_name = modest_account_settings_get_account_name (settings);
778 is_default = (account_name && default_account && !strcmp (account_name, default_account));
780 /* Get the item of the view menu */
781 item_name = g_strconcat (account_name, "Menu", NULL);
782 path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
783 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
787 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
788 if (GTK_IS_LABEL (child)) {
789 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
791 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
792 gtk_label_set_markup (GTK_LABEL (child), bold_name);
795 gtk_label_set_ellipsize (GTK_LABEL (child), PANGO_ELLIPSIZE_END);
799 /* Get the item of the tools menu */
800 path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", item_name, NULL);
801 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
805 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
806 if (GTK_IS_LABEL (child)) {
807 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
809 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
810 gtk_label_set_markup (GTK_LABEL (child), bold_name);
813 gtk_label_set_ellipsize (GTK_LABEL (child), PANGO_ELLIPSIZE_END);
818 g_object_unref (settings);
821 if (num_accounts > 1) {
822 /* Disconnect the tap-and-hold-query if it's connected */
823 if (modest_signal_mgr_is_connected (priv->sighandlers,
824 G_OBJECT (send_receive_button),
825 "tap-and-hold-query"))
826 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
827 G_OBJECT (send_receive_button),
828 "tap-and-hold-query");
830 /* Mandatory in order to view the menu contents */
831 gtk_widget_show_all (priv->accounts_popup);
833 /* Setup tap_and_hold just if was not done before*/
834 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
835 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
837 /* Connect the tap-and-hold-query in order not to show the CSM */
838 if (!modest_signal_mgr_is_connected (priv->sighandlers,
839 G_OBJECT (send_receive_button),
840 "tap-and-hold-query"))
841 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
842 G_OBJECT (send_receive_button),
843 "tap-and-hold-query",
844 G_CALLBACK (tap_and_hold_query_cb),
849 g_slist_free (accounts);
850 g_free (default_account);
853 /* Make sure that at least one account is viewed if there are any
854 * accounts, for instance when adding the first account: */
855 set_at_least_one_account_visible (self);
859 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
861 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
862 gtk_scrolled_window_add_with_viewport
863 (GTK_SCROLLED_WINDOW(win), widget);
865 gtk_container_add (GTK_CONTAINER(win),
876 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
878 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
880 GList *oerrsignals = priv->queue_err_signals;
881 while (oerrsignals) {
882 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
883 g_signal_handler_disconnect (esignal->queue, esignal->signal);
884 g_slice_free (QueueErrorSignal, esignal);
885 oerrsignals = g_list_next (oerrsignals);
887 g_list_free (priv->queue_err_signals);
888 priv->queue_err_signals = NULL;
893 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
895 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
898 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
902 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
904 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
906 /* Update visibility */
909 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
913 modest_main_window_disconnect_signals (ModestWindow *self)
915 ModestMainWindowPrivate *priv;
916 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
918 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
919 priv->sighandlers = NULL;
923 connect_signals (ModestMainWindow *self)
925 ModestWindowPrivate *parent_priv;
926 ModestMainWindowPrivate *priv;
929 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
930 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
935 modest_signal_mgr_connect (priv->sighandlers,
936 G_OBJECT(priv->folder_view), "key-press-event",
937 G_CALLBACK(on_inner_widgets_key_pressed), self);
939 modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view),
940 "folder_selection_changed",
941 G_CALLBACK (on_folder_selection_changed),
944 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view),
945 "folder-display-name-changed",
946 G_CALLBACK (modest_ui_actions_on_folder_display_name_changed),
949 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view),
951 G_CALLBACK (on_folder_view_focus_in),
954 /* Folder view CSM */
955 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
956 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
957 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
958 G_CALLBACK(_folder_view_csm_menu_activated),
962 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
963 G_CALLBACK(modest_ui_actions_on_header_selected), self);
965 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
966 G_CALLBACK(modest_ui_actions_on_header_activated), self);
968 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
969 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
971 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
972 G_CALLBACK(on_inner_widgets_key_pressed), self);
974 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
975 G_CALLBACK(on_msg_count_changed), self);
977 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
978 G_CALLBACK (on_header_view_focus_in), self);
980 modest_signal_mgr_connect (priv->sighandlers,
981 G_OBJECT (priv->header_view),
983 G_CALLBACK (on_updating_msg_list),
986 /* Header view CSM */
987 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
988 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
990 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
991 G_CALLBACK(_header_view_csm_menu_activated),
996 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
997 G_CALLBACK (modest_main_window_window_state_event),
999 /* we don't register this in sighandlers, as it should be run after disconnecting all signals,
1000 * in destroy stage */
1001 g_signal_connect (G_OBJECT (self), "destroy", G_CALLBACK (on_window_destroy), NULL);
1003 /* Mail Operation Queue */
1005 modest_signal_mgr_connect (priv->sighandlers,
1006 G_OBJECT (modest_runtime_get_mail_operation_queue ()),
1008 G_CALLBACK (on_queue_changed), self);
1010 /* Track changes in the device name */
1012 modest_signal_mgr_connect (priv->sighandlers,
1013 G_OBJECT(modest_runtime_get_conf ()),
1015 G_CALLBACK (on_configuration_key_changed),
1018 /* Track account changes. We need to refresh the toolbar */
1020 modest_signal_mgr_connect (priv->sighandlers,
1021 G_OBJECT (modest_runtime_get_account_store ()),
1023 G_CALLBACK (on_account_inserted),
1026 modest_signal_mgr_connect (priv->sighandlers,
1027 G_OBJECT (modest_runtime_get_account_store ()),
1029 G_CALLBACK (on_account_removed),
1032 /* We need to refresh the send & receive menu to change the bold
1033 * account when the default account changes. */
1035 modest_signal_mgr_connect (priv->sighandlers,
1036 G_OBJECT (modest_runtime_get_account_mgr ()),
1037 "default_account_changed",
1038 G_CALLBACK (on_default_account_changed),
1043 modest_signal_mgr_connect (priv->sighandlers,
1044 G_OBJECT (modest_runtime_get_account_store ()),
1046 G_CALLBACK (on_account_changed),
1050 modest_signal_mgr_connect (priv->sighandlers,
1051 G_OBJECT (modest_runtime_get_account_store()),
1052 "password_requested",
1053 G_CALLBACK (modest_ui_actions_on_password_requested),
1058 on_hildon_program_is_topmost_notify(GObject *self,
1059 GParamSpec *propert_param,
1062 HildonProgram *app = HILDON_PROGRAM (self);
1064 /* Note that use of hildon_program_set_can_hibernate()
1065 * is generally referred to as "setting the killable flag",
1066 * though hibernation does not seem equal to death.
1069 if (hildon_program_get_is_topmost (app)) {
1070 /* Prevent hibernation when the progam comes to the foreground,
1071 * because hibernation should only happen when the application
1072 * is in the background: */
1073 hildon_program_set_can_hibernate (app, FALSE);
1075 /* Remove new mail visual notifications */
1076 modest_platform_remove_new_mail_notifications (TRUE);
1078 /* Allow hibernation if the program has gone to the background: */
1080 /* However, prevent hibernation while the settings are being changed: */
1081 const gboolean hibernation_prevented =
1082 modest_window_mgr_get_hibernation_is_prevented (
1083 modest_runtime_get_window_mgr ());
1085 if (hibernation_prevented)
1086 hildon_program_set_can_hibernate (app, FALSE);
1088 /* Allow hibernation, after saving the state: */
1089 modest_osso_save_state();
1090 hildon_program_set_can_hibernate (app, TRUE);
1096 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
1098 GtkWidget *folder_win = (GtkWidget *) user_data;
1099 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1101 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
1102 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
1104 gtk_widget_show (GTK_WIDGET (priv->folder_view));
1106 /* Connect signals */
1107 connect_signals (MODEST_MAIN_WINDOW (self));
1109 /* Set account store */
1110 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
1111 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1113 /* Load previous osso state, for instance if we are being restored from
1115 modest_osso_load_state ();
1117 /* Restore window & widget settings */
1118 priv->wait_for_settings = TRUE;
1119 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
1120 priv->wait_for_settings = FALSE;
1122 /* Check if accounts exist and show the account wizard if not */
1123 gboolean accounts_exist =
1124 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1126 if (!accounts_exist) {
1127 /* This is necessary to have the main window shown behind the dialog
1128 It's an ugly hack... jschmid */
1129 gtk_widget_show_all(GTK_WIDGET(self));
1130 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
1133 GtkAction *send_receive_all;
1134 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1135 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
1136 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1137 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1138 gtk_action_set_visible (send_receive_all, g_slist_length (accounts) > 0);
1139 modest_account_mgr_free_account_names (accounts);
1140 update_menus (MODEST_MAIN_WINDOW (self));
1145 osso_display_event_cb (osso_display_state_t state,
1148 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (data);
1150 priv->display_state = state;
1152 /* Stop blinking if the screen becomes on */
1153 if (priv->display_state == OSSO_DISPLAY_ON)
1154 modest_platform_remove_new_mail_notifications (TRUE);
1158 modest_main_window_new (void)
1160 ModestMainWindow *self = NULL;
1161 ModestMainWindowPrivate *priv = NULL;
1162 ModestWindowPrivate *parent_priv = NULL;
1163 GtkWidget *folder_win = NULL;
1164 ModestDimmingRulesGroup *menu_rules_group = NULL;
1165 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1166 GtkActionGroup *action_group = NULL;
1167 GError *error = NULL;
1169 ModestConf *conf = NULL;
1170 GtkAction *action = NULL;
1171 GdkPixbuf *window_icon;
1173 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
1174 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1175 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1177 parent_priv->ui_manager = gtk_ui_manager_new();
1178 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
1180 action_group = gtk_action_group_new ("ModestMainWindowActions");
1181 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1183 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1184 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1186 /* Add common actions */
1187 gtk_action_group_add_actions (action_group,
1188 modest_action_entries,
1189 G_N_ELEMENTS (modest_action_entries),
1192 gtk_action_group_add_actions (action_group,
1193 modest_folder_view_action_entries,
1194 G_N_ELEMENTS (modest_folder_view_action_entries),
1197 gtk_action_group_add_actions (action_group,
1198 modest_header_view_action_entries,
1199 G_N_ELEMENTS (modest_header_view_action_entries),
1202 gtk_action_group_add_toggle_actions (action_group,
1203 modest_toggle_action_entries,
1204 G_N_ELEMENTS (modest_toggle_action_entries),
1207 gtk_action_group_add_toggle_actions (action_group,
1208 modest_main_window_toggle_action_entries,
1209 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
1212 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
1213 g_object_unref (action_group);
1215 /* Load the UI definition */
1216 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
1217 MODEST_UIDIR "modest-main-window-ui.xml", &error);
1218 if (error != NULL) {
1219 g_warning ("Could not merge modest-ui.xml: %s", error->message);
1220 g_error_free (error);
1224 /* Add common dimming rules */
1225 modest_dimming_rules_group_add_rules (menu_rules_group,
1226 modest_main_window_menu_dimming_entries,
1227 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
1228 MODEST_WINDOW (self));
1229 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1230 modest_main_window_toolbar_dimming_entries,
1231 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
1232 MODEST_WINDOW (self));
1234 /* Insert dimming rules group for this window */
1235 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1236 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1237 g_object_unref (menu_rules_group);
1238 g_object_unref (toolbar_rules_group);
1240 /* Add accelerators */
1241 gtk_window_add_accel_group (GTK_WINDOW (self),
1242 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
1244 /* Menubar. Update the state of some toggles */
1245 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1246 conf = modest_runtime_get_conf ();
1247 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1248 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
1249 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1250 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR, NULL));
1251 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1252 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
1253 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1254 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
1255 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
1256 gtk_widget_show (parent_priv->menubar);
1258 /* Get device name */
1259 modest_maemo_utils_get_device_name ();
1263 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
1264 if (!priv->header_view)
1265 g_printerr ("modest: cannot instantiate header view\n");
1266 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
1267 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
1268 MODEST_CONF_HEADER_VIEW_KEY);
1270 /* Other style properties of header view */
1271 g_object_set (G_OBJECT (priv->header_view),
1272 "rules-hint", FALSE,
1274 /* gtk_widget_show (priv->header_view); */
1277 priv->empty_view = create_empty_view ();
1278 gtk_widget_show (priv->empty_view);
1280 /* Create scrolled windows */
1281 folder_win = gtk_scrolled_window_new (NULL, NULL);
1282 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
1283 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
1285 GTK_POLICY_AUTOMATIC);
1286 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
1288 GTK_POLICY_AUTOMATIC);
1289 /* gtk_widget_show (priv->contents_widget); */
1292 priv->main_paned = gtk_hpaned_new ();
1293 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
1294 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
1295 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
1297 /* putting it all together... */
1298 priv->main_vbox = gtk_vbox_new (FALSE, 6);
1299 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
1300 gtk_widget_show (priv->main_vbox);
1302 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
1304 app = hildon_program_get_instance ();
1305 hildon_program_add_window (app, HILDON_WINDOW (self));
1307 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
1308 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
1310 g_signal_connect (G_OBJECT(self), "show",
1311 G_CALLBACK (modest_main_window_on_show), folder_win);
1313 /* Set window icon */
1314 window_icon = modest_platform_get_icon (MODEST_APP_ICON, MODEST_ICON_SIZE_BIG);
1316 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
1317 g_object_unref (window_icon);
1320 /* Listen for changes in the screen, we don't want to show a
1321 led pattern when the display is on for example */
1322 osso_hw_set_display_event_cb (modest_maemo_utils_get_osso_context (),
1323 osso_display_event_cb,
1326 /* Dont't restore settings here,
1327 * because it requires a gtk_widget_show(),
1328 * and we don't want to do that until later,
1329 * so that the UI is not visible for non-menu D-Bus activation.
1332 return MODEST_WINDOW(self);
1336 modest_main_window_set_style (ModestMainWindow *self,
1337 ModestMainWindowStyle style)
1339 ModestMainWindowPrivate *priv;
1340 ModestWindowPrivate *parent_priv;
1344 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1346 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1347 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1349 /* no change -> nothing to do */
1350 if (priv->style == style)
1353 /* Get toggle button and update the state if needed. This will
1354 happen only when the set_style is not invoked from the UI,
1355 for example when it's called from widget memory */
1356 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1357 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
1358 if ((active && style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) ||
1359 (!active && style == MODEST_MAIN_WINDOW_STYLE_SPLIT)) {
1360 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1361 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !active);
1362 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1365 priv->style = style;
1367 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
1369 if (!priv->wait_for_settings)
1370 modest_widget_memory_save (modest_runtime_get_conf (), G_OBJECT (priv->main_paned),
1371 MODEST_CONF_MAIN_PANED_KEY);
1372 /* Remove main paned */
1373 g_object_ref (priv->main_paned);
1374 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1376 /* Reparent the contents widget to the main vbox */
1377 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
1380 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1381 /* Remove header view */
1382 g_object_ref (priv->contents_widget);
1383 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1385 /* Reparent the main paned */
1386 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1387 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1389 g_timeout_add (500, (GSourceFunc) restore_paned_timeout_handler, self);
1393 g_return_if_reached ();
1396 /* Let header view grab the focus if it's being shown */
1397 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1398 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1400 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1403 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1406 ModestMainWindowStyle
1407 modest_main_window_get_style (ModestMainWindow *self)
1409 ModestMainWindowPrivate *priv;
1411 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1413 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1418 toolbar_resize (ModestMainWindow *self)
1420 ModestMainWindowPrivate *priv = NULL;
1421 ModestWindowPrivate *parent_priv = NULL;
1423 gint static_button_size;
1424 ModestWindowMgr *mgr;
1426 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1427 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1428 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1430 mgr = modest_runtime_get_window_mgr ();
1431 static_button_size = modest_window_mgr_get_fullscreen_mode (mgr)?118:108;
1433 if (parent_priv->toolbar) {
1434 /* left size buttons */
1435 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNew");
1436 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1437 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1438 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1439 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply");
1440 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1441 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1442 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1443 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage");
1444 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1445 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1446 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1447 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1448 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1449 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1450 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1452 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1453 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1454 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1455 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1456 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1457 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1458 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1459 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1467 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1469 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1470 ModestWindowPrivate *parent_priv;
1471 ModestWindowMgr *mgr;
1472 gboolean is_fullscreen;
1473 GtkAction *fs_toggle_action;
1476 mgr = modest_runtime_get_window_mgr ();
1478 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1480 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1482 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1483 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1484 if (is_fullscreen != active) {
1485 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1488 toolbar_resize (MODEST_MAIN_WINDOW (widget));
1496 modest_main_window_show_toolbar (ModestWindow *self,
1497 gboolean show_toolbar)
1499 ModestMainWindowPrivate *priv = NULL;
1500 ModestWindowPrivate *parent_priv = NULL;
1501 GtkWidget *reply_button = NULL, *menu = NULL;
1502 GtkWidget *placeholder = NULL;
1504 const gchar *action_name;
1507 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1508 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1509 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1511 /* Set optimized view status */
1512 priv->optimized_view = !show_toolbar;
1514 if (!parent_priv->toolbar) {
1515 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1517 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1519 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1520 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1521 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1522 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1523 toolbar_resize (MODEST_MAIN_WINDOW (self));
1525 /* Add ProgressBar (Transfer toolbar) */
1526 priv->progress_bar = modest_progress_bar_new ();
1527 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1528 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1529 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1530 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1531 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1533 /* Connect cancel 'clicked' signal to abort progress mode */
1534 g_signal_connect(priv->cancel_toolitem, "clicked",
1535 G_CALLBACK(cancel_progressbar),
1538 /* Add it to the observers list */
1539 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1542 hildon_window_add_toolbar (HILDON_WINDOW (self),
1543 GTK_TOOLBAR (parent_priv->toolbar));
1545 /* Set reply button tap and hold menu */
1546 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1547 "/ToolBar/ToolbarMessageReply");
1548 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1549 "/ToolbarReplyCSM");
1550 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1552 /* Set send & receive button tap and hold menu */
1553 update_menus (MODEST_MAIN_WINDOW (self));
1557 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1558 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1559 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1561 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1562 if (modest_main_window_transfer_mode_enabled (MODEST_MAIN_WINDOW(self)))
1563 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_TRANSFER);
1565 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1567 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1571 /* Update also the actions (to update the toggles in the
1572 menus), we have to do it manually because some other window
1573 of the same time could have changed it (remember that the
1574 toolbar fullscreen mode is shared by all the windows of the
1576 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
1577 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu";
1579 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu";
1581 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
1582 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
1587 on_account_inserted (TnyAccountStore *accoust_store,
1588 TnyAccount *account,
1591 /* Transport accounts and local ones (MMC and the Local
1592 folders account do now cause menu changes */
1593 if (TNY_IS_STORE_ACCOUNT (account) &&
1594 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account))) {
1596 update_menus (MODEST_MAIN_WINDOW (user_data));
1601 on_default_account_changed (ModestAccountMgr* mgr,
1604 update_menus (MODEST_MAIN_WINDOW (user_data));
1608 on_account_removed (TnyAccountStore *accoust_store,
1609 TnyAccount *account,
1612 /* Transport accounts and local ones (MMC and the Local
1613 folders account do now cause menu changes */
1614 if (TNY_IS_STORE_ACCOUNT (account) &&
1615 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1616 update_menus (MODEST_MAIN_WINDOW (user_data));
1620 on_account_changed (TnyAccountStore *account_store,
1621 TnyAccount *account,
1624 ModestMainWindow *win = MODEST_MAIN_WINDOW (user_data);
1626 /* We need to refresh the details widget because it could have changed */
1627 if (modest_main_window_get_contents_style(win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS) {
1628 modest_main_window_set_contents_style (win, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1631 /* Update the menus as well, the account name could be
1632 changed. Transport accounts and local ones (MMC and the
1633 Local folders account do now cause menu changes */
1634 if (TNY_IS_STORE_ACCOUNT (account) &&
1635 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1636 update_menus (MODEST_MAIN_WINDOW (user_data));
1640 * This function manages the key events used to navigate between
1641 * header and folder views (when the window is in split view)
1644 * -------------------------------------------------
1645 * HeaderView GDK_Left Move focus to folder view
1646 * FolderView GDK_Right Move focus to header view
1648 * There is no need to scroll to selected row, the widgets will be the
1649 * responsibles of doing that (probably managing the focus-in event
1652 on_inner_widgets_key_pressed (GtkWidget *widget,
1656 ModestMainWindowPrivate *priv;
1658 if (event->type == GDK_KEY_RELEASE)
1661 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1663 /* Do nothing if we're in SIMPLE style */
1664 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1667 if (MODEST_IS_HEADER_VIEW (widget)) {
1668 if (event->keyval == GDK_Left)
1669 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1670 else if ((event->keyval == GDK_Return)||(event->keyval == GDK_KP_Enter)) {
1671 guint selected_headers = modest_header_view_count_selected_headers (MODEST_HEADER_VIEW (widget));
1672 if (selected_headers > 1) {
1673 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1677 } else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1678 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1684 set_alignment (GtkWidget *widget,
1687 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1688 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1692 create_empty_view (void)
1694 GtkLabel *label = NULL;
1695 GtkWidget *align = NULL;
1697 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1698 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1699 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1700 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1702 return GTK_WIDGET(align);
1706 * Free the returned string
1709 get_gray_color_markup (GtkWidget *styled_widget)
1711 gchar *gray_color_markup = NULL;
1712 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1713 /* Obtain the secondary text color. We need a realized widget, that's why
1714 we get styled_widget from outside */
1716 if (gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color))
1717 gray_color_markup = modest_text_utils_get_color_string (&color);
1718 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
1720 if (!gray_color_markup)
1721 gray_color_markup = g_strdup ("#BBBBBB");
1723 return gray_color_markup;
1727 * Free the returned string
1730 create_device_name_visual_string (const gchar *device_name,
1731 const gchar *gray_color_markup)
1735 /* We have to use "" to fill the %s of the translation. We can
1736 not just use the device name because the device name is
1737 shown in a different color, so it could not be included
1738 into the <span> tag */
1739 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), "");
1740 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1750 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1752 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1757 gchar *gray_color_markup;
1759 vbox = gtk_vbox_new (FALSE, 0);
1761 gray_color_markup = get_gray_color_markup (styled_widget);
1763 /* Account description: */
1764 if (modest_tny_account_is_virtual_local_folders (account)
1765 || (modest_tny_account_is_memory_card_account (account))) {
1767 /* Get device name */
1768 gchar *device_name = NULL;
1769 if (modest_tny_account_is_virtual_local_folders (account))
1770 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1771 MODEST_CONF_DEVICE_NAME, NULL);
1773 device_name = g_strdup (tny_account_get_name (account));
1775 label = create_device_name_visual_string ((const gchar *) device_name,
1776 (const gchar *) gray_color_markup);
1777 label_w = gtk_label_new (NULL);
1778 gtk_label_set_markup (GTK_LABEL (label_w), label);
1779 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1780 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1781 g_free (device_name);
1784 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1785 gtk_box_pack_start (GTK_BOX (vbox),
1786 gtk_label_new (tny_account_get_name (account)),
1789 /* Other accounts, such as IMAP and POP: */
1794 /* Put proto in uppercase */
1795 proto = g_string_new (tny_account_get_proto (account));
1796 proto = g_string_ascii_up (proto);
1798 /* note: mcen_fi_localroot_description is something like "%s account"
1799 * however, we should display "%s account: %s"... therefore, ugly tmp */
1800 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1801 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1802 gray_color_markup, tmp, tny_account_get_name (account));
1805 label_w = gtk_label_new (NULL);
1806 gtk_label_set_markup (GTK_LABEL (label_w), label);
1807 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1808 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1809 g_string_free (proto, TRUE);
1815 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1816 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1817 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1818 modest_tny_folder_store_get_message_count (folder_store));
1819 label_w = gtk_label_new (NULL);
1820 gtk_label_set_markup (GTK_LABEL (label_w), label);
1821 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1822 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1826 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1828 _("mcen_fi_rootfolder_folders"),
1829 modest_tny_folder_store_get_folder_count (folder_store));
1830 label_w = gtk_label_new (NULL);
1831 gtk_label_set_markup (GTK_LABEL (label_w), label);
1832 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1833 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1837 if (modest_tny_account_is_virtual_local_folders (account)
1838 || modest_tny_account_is_memory_card_account (account)) {
1840 gchar *size = modest_text_utils_get_display_size (
1841 modest_tny_folder_store_get_local_size (folder_store));
1843 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1844 gray_color_markup, _("mcen_fi_rootfolder_size"),
1848 label_w = gtk_label_new (NULL);
1849 gtk_label_set_markup (GTK_LABEL (label_w), label);
1850 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1851 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1853 } else if (TNY_IS_ACCOUNT(folder_store)) {
1854 TnyAccount *account = TNY_ACCOUNT(folder_store);
1856 time_t last_updated;
1857 const gchar *last_updated_string;
1858 /* Get last updated from configuration */
1859 last_updated = modest_account_mgr_get_last_updated (modest_runtime_get_account_mgr (),
1860 tny_account_get_id (account));
1862 if (last_updated > 0)
1863 last_updated_string = modest_text_utils_get_display_date(last_updated);
1865 last_updated_string = g_strdup (_("mcen_va_never"));
1867 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1868 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1869 label_w = gtk_label_new (NULL);
1870 gtk_label_set_markup (GTK_LABEL (label_w), label);
1871 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1872 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1876 g_free (gray_color_markup);
1879 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1885 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1887 ModestMainWindowPrivate *priv = NULL;
1889 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1891 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1893 return priv->send_receive_in_progress;
1897 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1899 GtkAction *action = NULL;
1900 GtkWidget *widget = NULL;
1901 ModestMainWindowPrivate *priv = NULL;
1903 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1904 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1906 priv->send_receive_in_progress = TRUE;
1908 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1909 gtk_action_set_sensitive (action, FALSE);
1910 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1911 /* gtk_action_set_sensitive (action, FALSE); */
1912 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1913 gtk_widget_set_sensitive (widget, FALSE);
1917 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1919 GtkAction *action = NULL;
1920 GtkWidget *widget = NULL;
1921 ModestMainWindowPrivate *priv = NULL;
1923 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1924 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1926 priv->send_receive_in_progress = FALSE;
1928 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1929 gtk_action_set_sensitive (action, TRUE);
1930 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1931 /* gtk_action_set_sensitive (action, TRUE); */
1932 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1933 gtk_widget_set_sensitive (widget, TRUE);
1938 on_msg_count_changed (ModestHeaderView *header_view,
1940 TnyFolderChange *change,
1941 ModestMainWindow *main_window)
1943 gboolean refilter = FALSE;
1944 gboolean folder_empty = FALSE;
1945 gboolean all_marked_as_deleted = FALSE;
1946 ModestMainWindowPrivate *priv;
1948 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1949 g_return_if_fail (TNY_IS_FOLDER(folder));
1950 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
1952 if (change != NULL) {
1953 TnyFolderChangeChanged changed;
1955 changed = tny_folder_change_get_changed (change);
1956 /* If something changes */
1957 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1958 folder_empty = (((guint) tny_folder_change_get_new_all_count (change)) == 0);
1960 folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1962 /* Play a sound (if configured) and make the LED blink */
1963 if (changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS) {
1964 modest_platform_push_email_notification ();
1967 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_EXPUNGED_HEADERS)
1970 folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1973 /* Check if all messages are marked to be deleted */
1974 all_marked_as_deleted = modest_header_view_is_empty (header_view);
1975 folder_empty = folder_empty || all_marked_as_deleted;
1977 /* Set contents style of headers view */
1979 modest_main_window_set_contents_style (main_window,
1980 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1981 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1983 modest_main_window_set_contents_style (main_window,
1984 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1988 modest_header_view_refilter (header_view);
1993 modest_main_window_set_contents_style (ModestMainWindow *self,
1994 ModestMainWindowContentsStyle style)
1996 ModestMainWindowPrivate *priv;
1998 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2000 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2002 /* We allow to set the same content style than the previously
2003 set if there are details, because it could happen when we're
2004 selecting different accounts consecutively */
2005 if ((priv->contents_style == style) &&
2006 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
2009 /* Remove previous child. Delete it if it was an account
2011 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
2013 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2014 g_object_ref (content);
2015 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
2016 g_object_ref (priv->empty_view);
2017 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
2020 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
2023 priv->contents_style = style;
2025 switch (priv->contents_style) {
2026 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
2027 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
2028 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2031 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
2033 /* if we're started without main win, there may not be a folder
2034 * view. this fixes a GLib-Critical */
2035 if (priv->folder_view) {
2036 TnyFolderStore *selected_folderstore =
2037 modest_folder_view_get_selected (priv->folder_view);
2038 if (TNY_IS_ACCOUNT (selected_folderstore)) {
2039 priv->details_widget = create_details_widget (GTK_WIDGET (self),
2040 TNY_ACCOUNT (selected_folderstore));
2042 wrap_in_scrolled_window (priv->contents_widget,
2043 priv->details_widget);
2045 g_object_unref (selected_folderstore);
2046 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2051 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
2052 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
2053 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2057 g_return_if_reached ();
2061 gtk_widget_show_all (priv->contents_widget);
2064 ModestMainWindowContentsStyle
2065 modest_main_window_get_contents_style (ModestMainWindow *self)
2067 ModestMainWindowPrivate *priv;
2069 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
2071 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2072 return priv->contents_style;
2077 on_configuration_key_changed (ModestConf* conf,
2079 ModestConfEvent event,
2080 ModestConfNotificationId id,
2081 ModestMainWindow *self)
2083 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2084 TnyAccount *account = NULL;
2086 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
2089 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
2092 if (priv->folder_view)
2093 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
2095 if (account && TNY_IS_ACCOUNT (account) &&
2096 strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID) == 0) {
2099 const gchar *device_name;
2100 gchar *new_text, *gray_color_markup;
2103 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
2104 label = GTK_LABEL (children->data);
2106 device_name = modest_conf_get_string (modest_runtime_get_conf(),
2107 MODEST_CONF_DEVICE_NAME, NULL);
2109 gray_color_markup = get_gray_color_markup (GTK_WIDGET (self));
2110 new_text = create_device_name_visual_string (device_name, gray_color_markup);
2112 gtk_label_set_markup (label, new_text);
2113 gtk_widget_show (GTK_WIDGET (label));
2115 g_free (gray_color_markup);
2117 g_list_free (children);
2119 g_object_unref (account);
2123 set_toolbar_transfer_mode (ModestMainWindow *self)
2125 ModestMainWindowPrivate *priv = NULL;
2127 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2129 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2131 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
2133 if (priv->progress_bar_timeout > 0) {
2134 g_source_remove (priv->progress_bar_timeout);
2135 priv->progress_bar_timeout = 0;
2142 set_toolbar_mode (ModestMainWindow *self,
2143 ModestToolBarModes mode)
2145 ModestWindowPrivate *parent_priv = NULL;
2146 ModestMainWindowPrivate *priv = NULL;
2147 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
2149 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2151 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2152 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2154 /* In case this was called before the toolbar exists: */
2155 if (!(parent_priv->toolbar))
2158 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
2160 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
2161 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
2162 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
2164 /* Sets current toolbar mode */
2165 priv->current_toolbar_mode = mode;
2167 /* Checks the dimming rules */
2168 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2169 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
2171 /* Show and hide toolbar items */
2173 case TOOLBAR_MODE_NORMAL:
2175 gtk_action_set_visible (sort_action, TRUE);
2177 gtk_action_set_visible (refresh_action, TRUE);
2178 if (priv->progress_toolitem) {
2179 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
2180 gtk_widget_hide (priv->progress_toolitem);
2182 if (priv->progress_bar)
2183 gtk_widget_hide (priv->progress_bar);
2186 gtk_action_set_visible (cancel_action, FALSE);
2188 /* Hide toolbar if optimized view is enabled */
2189 if (priv->optimized_view)
2190 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
2192 case TOOLBAR_MODE_TRANSFER:
2194 gtk_action_set_visible (sort_action, FALSE);
2196 gtk_action_set_visible (refresh_action, FALSE);
2198 gtk_action_set_visible (cancel_action, TRUE);
2199 if (priv->progress_bar)
2200 gtk_widget_show (priv->progress_bar);
2201 if (priv->progress_toolitem) {
2202 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
2203 gtk_widget_show (priv->progress_toolitem);
2206 /* Show toolbar if it's hiden (optimized view ) */
2207 if (priv->optimized_view)
2208 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2211 g_return_if_reached ();
2216 modest_main_window_transfer_mode_enabled (ModestMainWindow *self)
2218 ModestMainWindowPrivate *priv;
2220 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2221 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2223 return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
2227 cancel_progressbar (GtkToolButton *toolbutton,
2228 ModestMainWindow *self)
2231 ModestMainWindowPrivate *priv;
2233 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2235 /* Get operation observers and cancel all the operations */
2236 tmp = priv->progress_widgets;
2238 modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2239 tmp=g_slist_next(tmp);
2244 observers_empty (ModestMainWindow *self)
2247 ModestMainWindowPrivate *priv;
2248 gboolean is_empty = TRUE;
2249 guint pending_ops = 0;
2251 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2252 tmp = priv->progress_widgets;
2254 /* Check all observers */
2255 while (tmp && is_empty) {
2256 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2257 is_empty = pending_ops == 0;
2259 tmp = g_slist_next(tmp);
2267 * Gets the toolbar mode needed for each mail operation. It stores in
2268 * @mode_changed if the toolbar mode has changed or not
2270 static ModestToolBarModes
2271 get_toolbar_mode_from_mail_operation (ModestMainWindow *self,
2272 ModestMailOperation *mail_op,
2273 gboolean *mode_changed)
2275 ModestToolBarModes mode;
2276 ModestMainWindowPrivate *priv;
2278 *mode_changed = FALSE;
2279 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2281 /* Get toolbar mode from operation id*/
2282 switch (modest_mail_operation_get_type_operation (mail_op)) {
2283 case MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE:
2284 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
2285 case MODEST_MAIL_OPERATION_TYPE_OPEN:
2286 mode = TOOLBAR_MODE_TRANSFER;
2287 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
2288 *mode_changed = TRUE;
2291 mode = TOOLBAR_MODE_NORMAL;
2297 on_mail_operation_started (ModestMailOperation *mail_op,
2300 ModestMainWindow *self;
2301 ModestMailOperationTypeOperation op_type;
2302 ModestMainWindowPrivate *priv;
2303 ModestToolBarModes mode;
2305 gboolean mode_changed = FALSE;
2306 TnyAccount *account = NULL;
2308 self = MODEST_MAIN_WINDOW (user_data);
2309 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2311 /* Do not show progress for receiving operations if the
2312 account is the local account or the MMC one */
2313 op_type = modest_mail_operation_get_type_operation (mail_op);
2314 account = modest_mail_operation_get_account (mail_op);
2315 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2318 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2319 modest_tny_account_is_memory_card_account (account));
2321 g_object_unref (account);
2325 /* Show information banner. Remove old timeout */
2326 if (priv->retrieving_banner_timeout > 0) {
2327 g_source_remove (priv->retrieving_banner_timeout);
2328 priv->retrieving_banner_timeout = 0;
2330 /* Create a new timeout */
2331 priv->retrieving_banner_timeout =
2332 g_timeout_add (2000, show_retrieving_banner, self);
2335 /* Not every mail operation has account, noop does not */
2337 g_object_unref (account);
2339 /* Get toolbar mode from operation id*/
2340 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2342 /* Add operation observers and change toolbar if neccessary*/
2343 tmp = priv->progress_widgets;
2344 if (mode == TOOLBAR_MODE_TRANSFER) {
2346 GObject *source = modest_mail_operation_get_source(mail_op);
2347 if (G_OBJECT (self) == source) {
2348 set_toolbar_transfer_mode(self);
2350 g_object_unref (source);
2354 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2356 tmp = g_slist_next (tmp);
2360 /* Update the main menu as well, we need to explicitely do
2361 this in order to enable/disable accelerators */
2362 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
2366 on_mail_operation_finished (ModestMailOperation *mail_op,
2369 ModestToolBarModes mode;
2370 ModestMailOperationTypeOperation op_type;
2372 ModestMainWindow *self;
2373 gboolean mode_changed;
2374 TnyAccount *account = NULL;
2375 ModestMainWindowPrivate *priv;
2377 self = MODEST_MAIN_WINDOW (user_data);
2378 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2380 /* The mail operation was not added to the progress objects if
2381 the account was the local account or the MMC one */
2382 op_type = modest_mail_operation_get_type_operation (mail_op);
2383 account = modest_mail_operation_get_account (mail_op);
2384 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2387 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2388 modest_tny_account_is_memory_card_account (account));
2390 g_object_unref (account);
2394 /* Remove old timeout */
2395 if (priv->retrieving_banner_timeout > 0) {
2396 g_source_remove (priv->retrieving_banner_timeout);
2397 priv->retrieving_banner_timeout = 0;
2400 /* Remove the banner if exists */
2401 if (priv->retrieving_banner) {
2402 gtk_widget_destroy (priv->retrieving_banner);
2403 priv->retrieving_banner = NULL;
2407 /* Not every mail operation has account, noop does not */
2409 g_object_unref (account);
2411 /* Get toolbar mode from operation id*/
2412 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2414 /* Change toolbar mode */
2415 tmp = priv->progress_widgets;
2416 if (mode == TOOLBAR_MODE_TRANSFER) {
2418 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2420 tmp = g_slist_next (tmp);
2423 /* If no more operations are being observed, NORMAL mode is enabled again */
2424 if (observers_empty (self)) {
2425 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
2431 on_queue_changed (ModestMailOperationQueue *queue,
2432 ModestMailOperation *mail_op,
2433 ModestMailOperationQueueNotification type,
2434 ModestMainWindow *self)
2436 ModestMainWindowPrivate *priv;
2438 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2440 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
2441 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2443 "operation-started",
2444 G_CALLBACK (on_mail_operation_started),
2446 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2448 "operation-finished",
2449 G_CALLBACK (on_mail_operation_finished),
2451 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
2452 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2454 "operation-started");
2455 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2457 "operation-finished");
2462 set_account_visible(ModestMainWindow *self, const gchar *acc_name)
2464 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2466 ModestAccountMgr *mgr;
2467 ModestAccountSettings *settings;
2468 ModestServerAccountSettings *store_settings = NULL;
2470 /* Get account data */
2471 mgr = modest_runtime_get_account_mgr ();
2472 settings = modest_account_mgr_load_account_settings (mgr, acc_name);
2474 store_settings = modest_account_settings_get_store_settings (settings);
2476 /* Set the new visible & active account */
2477 if (settings && (modest_server_account_settings_get_account_name (store_settings)!= NULL)) {
2478 const gchar *account_name;
2480 account_name = modest_account_settings_get_account_name (settings);
2482 modest_folder_view_set_account_id_of_visible_server_account
2484 modest_server_account_settings_get_account_name (store_settings));
2485 modest_window_set_active_account (MODEST_WINDOW (self), account_name);
2486 action = gtk_action_group_get_action (priv->view_additions_group, account_name);
2487 if (action != NULL) {
2488 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2489 modest_utils_toggle_action_set_active_block_notify (
2490 GTK_TOGGLE_ACTION (action),
2496 modest_folder_view_select_first_inbox_or_local (priv->folder_view);
2501 g_object_unref (store_settings);
2502 g_object_unref (settings);
2506 /* Make sure that at least one account is "viewed": */
2508 set_at_least_one_account_visible(ModestMainWindow *self)
2510 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2511 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2513 if (!(priv->folder_view)) {
2514 /* It is too early to do this. */
2518 const gchar *active_server_account_name =
2519 modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);
2521 if (!active_server_account_name ||
2522 !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
2524 gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
2525 gchar* default_modest_name = modest_account_mgr_get_default_account (account_mgr);
2526 if (default_modest_name) {
2527 set_account_visible (self, default_modest_name);
2528 } else if (first_modest_name) {
2529 set_account_visible (self, first_modest_name);
2531 g_free (first_modest_name);
2532 g_free (default_modest_name);
2537 on_show_account_action_toggled (GtkToggleAction *action,
2540 ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
2542 const gchar *acc_name = gtk_action_get_name (GTK_ACTION (action));
2543 if (gtk_toggle_action_get_active (action))
2544 set_account_visible (self, acc_name);
2548 refresh_account (const gchar *account_name)
2552 /* win must already exists here, obviously */
2553 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
2556 g_warning ("%s: BUG: no main window!", __FUNCTION__);
2560 /* If account_name == NULL, we must update all (option All) */
2562 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2564 modest_ui_actions_do_send_receive (account_name, TRUE, TRUE, TRUE, win);
2569 on_refresh_account_action_activated (GtkAction *action,
2572 refresh_account ((const gchar*) user_data);
2576 on_send_receive_csm_activated (GtkMenuItem *item,
2579 refresh_account ((const gchar*) user_data);
2583 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2585 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2587 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2593 on_folder_view_focus_in (GtkWidget *widget, GdkEventFocus *event, gpointer userdata)
2595 ModestMainWindow *main_window = NULL;
2597 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2598 main_window = MODEST_MAIN_WINDOW (userdata);
2600 /* Update toolbar dimming state */
2601 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2602 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2608 on_header_view_focus_in (GtkWidget *widget,
2609 GdkEventFocus *event,
2612 ModestMainWindow *main_window = NULL;
2614 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2616 main_window = MODEST_MAIN_WINDOW (userdata);
2618 /* Update toolbar dimming state */
2619 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2620 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2626 on_folder_selection_changed (ModestFolderView *folder_view,
2627 TnyFolderStore *folder_store,
2629 ModestMainWindow *main_window)
2631 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2632 GtkAction *action = NULL;
2633 gboolean show_reply = TRUE;
2634 gboolean show_forward = TRUE;
2635 gboolean show_cancel_send = FALSE;
2636 gboolean show_clipboard = TRUE;
2637 gboolean show_delete = TRUE;
2640 if (TNY_IS_ACCOUNT (folder_store)) {
2641 show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2642 } else if (TNY_IS_FOLDER (folder_store)) {
2643 if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2644 TnyFolderType folder_type = modest_tny_folder_get_local_or_mmc_folder_type (
2645 TNY_FOLDER (folder_store));
2646 switch (folder_type) {
2647 case TNY_FOLDER_TYPE_DRAFTS:
2648 show_clipboard = show_delete = TRUE;
2649 show_reply = show_forward = show_cancel_send = FALSE;
2651 case TNY_FOLDER_TYPE_SENT:
2652 show_forward = show_clipboard = show_delete = TRUE;
2653 show_reply = show_cancel_send = FALSE;
2655 case TNY_FOLDER_TYPE_OUTBOX:
2656 show_clipboard = show_delete = show_cancel_send = TRUE;
2657 show_reply = show_forward = FALSE;
2659 case TNY_FOLDER_TYPE_INVALID:
2660 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
2663 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2664 show_cancel_send = FALSE;
2667 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2668 show_cancel_send = FALSE;
2673 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2674 gtk_action_set_visible (action, show_reply);
2675 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2676 gtk_action_set_visible (action, show_reply);
2677 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2678 gtk_action_set_visible (action, show_forward);
2679 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2680 gtk_action_set_visible (action, show_cancel_send);
2681 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2682 gtk_action_set_visible (action, show_delete);
2684 /* We finally call to the ui actions handler, after updating properly
2685 * the header view CSM */
2686 modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2690 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2691 GtkTreeModel *model,
2692 GtkTreeRowReference *row_reference,
2693 ModestMainWindow *self)
2695 ModestMainWindowPrivate *priv = NULL;
2696 GtkTreeModel *header_model = NULL;
2697 GtkTreePath *path = NULL;
2699 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
2700 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2701 g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2703 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2704 header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2706 /* Do nothing if we changed the folder in the main view */
2707 if (header_model != model)
2710 /* Select the message in the header view */
2711 path = gtk_tree_row_reference_get_path (row_reference);
2712 gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->header_view),
2714 gtk_tree_path_free (path);
2720 show_updating_banner (gpointer user_data)
2722 ModestMainWindowPrivate *priv = NULL;
2724 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2726 if (priv->updating_banner == NULL) {
2728 /* We're outside the main lock */
2729 gdk_threads_enter ();
2730 priv->updating_banner =
2731 modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2732 _CS ("ckdg_pb_updating"));
2733 gdk_threads_leave ();
2736 /* Remove timeout */
2737 priv->updating_banner_timeout = 0;
2742 * We use this function to show/hide a progress banner showing
2743 * "Updating" while the header view is being filled. We're not showing
2744 * it unless the update takes more than 2 seconds
2746 * If starting = TRUE then the refresh is starting, otherwise it means
2747 * that is has just finished
2750 on_updating_msg_list (ModestHeaderView *header_view,
2754 ModestMainWindowPrivate *priv = NULL;
2756 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2758 /* Remove old timeout */
2759 if (priv->updating_banner_timeout > 0) {
2760 g_source_remove (priv->updating_banner_timeout);
2761 priv->updating_banner_timeout = 0;
2764 /* Create a new timeout */
2766 priv->updating_banner_timeout =
2767 g_timeout_add (2000, show_updating_banner, user_data);
2769 /* Remove the banner if exists */
2770 if (priv->updating_banner) {
2771 gtk_widget_destroy (priv->updating_banner);
2772 priv->updating_banner = NULL;
2778 modest_main_window_screen_is_on (ModestMainWindow *self)
2780 ModestMainWindowPrivate *priv = NULL;
2782 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(self), FALSE);
2784 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2786 return (priv->display_state == OSSO_DISPLAY_ON) ? TRUE : FALSE;
2790 on_window_destroy (GtkObject *widget, gpointer userdata)
2792 ModestMainWindowPrivate *priv;
2794 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (widget);
2796 if (priv->retrieving_banner_timeout > 0) {
2797 g_source_remove (priv->retrieving_banner_timeout);
2798 priv->retrieving_banner_timeout = 0;
2801 if (priv->retrieving_banner != NULL) {
2802 gtk_widget_destroy (priv->retrieving_banner);
2803 priv->retrieving_banner = NULL;
2806 if (priv->updating_banner_timeout > 0) {
2807 g_source_remove (priv->updating_banner_timeout);
2808 priv->updating_banner_timeout = 0;
2811 if (priv->updating_banner != NULL) {
2812 gtk_widget_destroy (priv->updating_banner);
2813 priv->updating_banner = NULL;
2819 show_retrieving_banner (gpointer user_data)
2821 ModestMainWindowPrivate *priv = NULL;
2823 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2825 if (priv->retrieving_banner == NULL) {
2827 /* We're outside the main lock */
2828 gdk_threads_enter ();
2829 priv->retrieving_banner =
2830 modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2831 _("mcen_ib_getting_items"));
2832 gdk_threads_leave ();
2835 /* Remove timeout */
2836 priv->retrieving_banner_timeout = 0;