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 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
182 struct _ModestMainWindowPrivate {
183 GtkWidget *msg_paned;
184 GtkWidget *main_paned;
185 GtkWidget *main_vbox;
186 GtkWidget *contents_widget;
187 GtkWidget *empty_view;
189 /* Progress observers */
190 GtkWidget *progress_bar;
191 GSList *progress_widgets;
194 GtkWidget *progress_toolitem;
195 GtkWidget *cancel_toolitem;
196 GtkWidget *sort_toolitem;
197 GtkWidget *refresh_toolitem;
198 ModestToolBarModes current_toolbar_mode;
200 /* Merge ids used to add/remove accounts to the ViewMenu*/
201 GByteArray *merge_ids;
202 GtkActionGroup *view_additions_group;
204 /* On-demand widgets */
205 GtkWidget *accounts_popup;
206 GtkWidget *details_widget;
208 /* Optimized view enabled */
209 gboolean optimized_view;
211 /* Optimized view enabled */
212 gboolean send_receive_in_progress;
214 ModestHeaderView *header_view;
215 ModestFolderView *folder_view;
217 ModestMainWindowStyle style;
218 ModestMainWindowContentsStyle contents_style;
219 gboolean wait_for_settings;
221 guint progress_bar_timeout;
222 guint restore_paned_timeout;
224 /* Signal handler UIDs */
225 GList *queue_err_signals;
228 /* "Updating" banner for header view */
229 GtkWidget *updating_banner;
230 guint updating_banner_timeout;
232 /* "Retrieving" banner for header view */
233 GtkWidget *retrieving_banner;
234 guint retrieving_banner_timeout;
237 osso_display_state_t display_state;
239 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
240 MODEST_TYPE_MAIN_WINDOW, \
241 ModestMainWindowPrivate))
243 typedef struct _GetMsgAsyncHelper {
244 ModestMainWindowPrivate *main_window_private;
246 ModestTnyMsgReplyType reply_type;
247 ModestTnyMsgForwardType forward_type;
254 static GtkWindowClass *parent_class = NULL;
257 /* Private actions */
258 /* This is the context sensitive menu: */
259 static const GtkActionEntry modest_folder_view_action_entries [] = {
261 /* Folder View CSM actions */
262 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
263 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
264 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_paste)},
265 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
266 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_search_messages) },
267 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
270 static const GtkActionEntry modest_header_view_action_entries [] = {
272 /* Header View CSM actions */
273 { "HeaderViewCSMOpen", NULL, N_("mcen_me_inbox_open"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_open) },
274 { "HeaderViewCSMReply", NULL, N_("mcen_me_inbox_reply"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply) },
275 { "HeaderViewCSMReplyAll", NULL, N_("mcen_me_inbox_replytoall"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply_all) },
276 { "HeaderViewCSMForward", NULL, N_("mcen_me_inbox_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_forward) },
277 { "HeaderViewCSMCut", NULL, N_("mcen_me_inbox_cut"), "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
278 { "HeaderViewCSMCopy", NULL, N_("mcen_me_inbox_copy"), "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
279 { "HeaderViewCSMPaste", NULL, N_("mcen_me_inbox_paste"), "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
280 { "HeaderViewCSMDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_message) },
281 { "HeaderViewCSMCancelSending", NULL, N_("mcen_me_outbox_cancelsend"), NULL, NULL, G_CALLBACK (modest_ui_actions_cancel_send) },
282 { "HeaderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
285 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
286 { "ToggleFolders", MODEST_STOCK_SPLIT_VIEW, N_("mcen_me_inbox_hidefolders"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), TRUE },
289 /************************************************************************/
292 modest_main_window_get_type (void)
294 static GType my_type = 0;
296 static const GTypeInfo my_info = {
297 sizeof(ModestMainWindowClass),
298 NULL, /* base init */
299 NULL, /* base finalize */
300 (GClassInitFunc) modest_main_window_class_init,
301 NULL, /* class finalize */
302 NULL, /* class data */
303 sizeof(ModestMainWindow),
305 (GInstanceInitFunc) modest_main_window_init,
308 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
316 modest_main_window_class_init (ModestMainWindowClass *klass)
318 GObjectClass *gobject_class;
319 gobject_class = (GObjectClass*) klass;
320 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
322 parent_class = g_type_class_peek_parent (klass);
323 gobject_class->finalize = modest_main_window_finalize;
325 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
327 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
328 modest_window_class->save_state_func = save_state;
329 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
330 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
331 modest_window_class->disconnect_signals_func = modest_main_window_disconnect_signals;
335 modest_main_window_init (ModestMainWindow *obj)
337 ModestMainWindowPrivate *priv;
339 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
341 priv->queue_err_signals = NULL;
342 priv->msg_paned = NULL;
343 priv->main_paned = NULL;
344 priv->main_vbox = NULL;
345 priv->header_view = NULL;
346 priv->folder_view = NULL;
347 priv->contents_widget = NULL;
348 priv->accounts_popup = NULL;
349 priv->details_widget = NULL;
350 priv->empty_view = NULL;
351 priv->progress_widgets = NULL;
352 priv->progress_bar = NULL;
353 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
354 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
355 priv->wait_for_settings = TRUE;
356 priv->contents_style = -1; /* invalid contents style. We need this to select it for the first time */
357 priv->merge_ids = NULL;
358 priv->optimized_view = FALSE;
359 priv->send_receive_in_progress = FALSE;
360 priv->progress_bar_timeout = 0;
361 priv->restore_paned_timeout = 0;
362 priv->sighandlers = NULL;
363 priv->updating_banner = NULL;
364 priv->updating_banner_timeout = 0;
365 priv->retrieving_banner = NULL;
366 priv->retrieving_banner_timeout = 0;
367 priv->display_state = OSSO_DISPLAY_ON;
369 modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
371 "applications_email_mainview");
375 modest_main_window_finalize (GObject *obj)
377 ModestMainWindowPrivate *priv;
379 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
381 /* Sanity check: shouldn't be needed, the window mgr should
382 call this function before */
383 modest_main_window_disconnect_signals (MODEST_WINDOW (obj));
384 modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
386 g_slist_free (priv->progress_widgets);
388 g_byte_array_free (priv->merge_ids, TRUE);
390 if (priv->progress_bar_timeout > 0) {
391 g_source_remove (priv->progress_bar_timeout);
392 priv->progress_bar_timeout = 0;
395 if (priv->updating_banner_timeout > 0) {
396 g_source_remove (priv->updating_banner_timeout);
397 priv->updating_banner_timeout = 0;
400 if (priv->updating_banner) {
401 gtk_widget_destroy (priv->updating_banner);
402 priv->updating_banner = NULL;
405 if (priv->retrieving_banner_timeout > 0) {
406 g_source_remove (priv->retrieving_banner_timeout);
407 priv->retrieving_banner_timeout = 0;
410 if (priv->retrieving_banner) {
411 gtk_widget_destroy (priv->retrieving_banner);
412 priv->retrieving_banner = NULL;
415 if (priv->restore_paned_timeout > 0) {
416 g_source_remove (priv->restore_paned_timeout);
417 priv->restore_paned_timeout = 0;
420 G_OBJECT_CLASS(parent_class)->finalize (obj);
424 modest_main_window_get_child_widget (ModestMainWindow *self,
425 ModestMainWindowWidgetType widget_type)
427 ModestMainWindowPrivate *priv;
430 g_return_val_if_fail (self && MODEST_IS_MAIN_WINDOW(self), NULL);
431 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_MAIN_WINDOW_WIDGET_TYPE_NUM,
434 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
436 switch (widget_type) {
437 case MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW:
438 widget = (GtkWidget*)priv->header_view; break;
439 case MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW:
440 widget = (GtkWidget*)priv->folder_view; break;
445 return widget ? GTK_WIDGET(widget) : NULL;
449 restore_paned_timeout_handler (gpointer *data)
451 ModestMainWindow *main_window = MODEST_MAIN_WINDOW (data);
452 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
455 /* Timeouts are outside the main lock */
456 gdk_threads_enter ();
457 if (GTK_WIDGET_VISIBLE (main_window)) {
458 conf = modest_runtime_get_conf ();
459 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
460 MODEST_CONF_MAIN_PANED_KEY);
462 gdk_threads_leave ();
469 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
472 ModestMainWindowPrivate *priv;
474 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
476 conf = modest_runtime_get_conf ();
478 modest_widget_memory_restore (conf, G_OBJECT(self),
479 MODEST_CONF_MAIN_WINDOW_KEY);
481 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
482 MODEST_CONF_HEADER_VIEW_KEY);
484 if (do_folder_view_too)
485 modest_widget_memory_restore (conf, G_OBJECT(priv->folder_view),
486 MODEST_CONF_FOLDER_VIEW_KEY);
488 /* modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned), */
489 /* MODEST_CONF_MAIN_PANED_KEY); */
491 g_timeout_add (250, (GSourceFunc) restore_paned_timeout_handler, self);
493 /* We need to force a redraw here in order to get the right
494 position of the horizontal paned separator */
495 gtk_widget_show (GTK_WIDGET (self));
500 save_state (ModestWindow *window)
503 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
504 ModestMainWindowPrivate *priv;
506 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
507 conf = modest_runtime_get_conf ();
509 modest_widget_memory_save (conf,G_OBJECT(self),
510 MODEST_CONF_MAIN_WINDOW_KEY);
511 /* Only save main paned position if we're in split mode */
512 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SPLIT)
513 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
514 MODEST_CONF_MAIN_PANED_KEY);
515 modest_widget_memory_save (conf, G_OBJECT(priv->folder_view),
516 MODEST_CONF_FOLDER_VIEW_KEY);
520 compare_display_names (ModestAccountSettings *a,
521 ModestAccountSettings *b)
523 return strcmp (modest_account_settings_get_display_name (a),
524 modest_account_settings_get_display_name (b));
527 /* We use this function to prevent the send&receive CSM to be shown
528 when there are less than two account */
530 tap_and_hold_query_cb (GtkWidget *widget, GdkEvent *event)
536 update_menus (ModestMainWindow* self)
538 GSList *account_names, *iter, *accounts;
539 ModestMainWindowPrivate *priv;
540 ModestWindowPrivate *parent_priv;
541 ModestAccountMgr *mgr;
542 gint i, num_accounts;
544 gchar *default_account;
545 const gchar *active_account_name;
546 GtkWidget *send_receive_button, *item;
547 GtkAction *send_receive_all = NULL;
550 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
551 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
553 /* Get enabled account IDs */
554 mgr = modest_runtime_get_account_mgr ();
555 account_names = modest_account_mgr_account_names (mgr, TRUE);
556 iter = account_names;
560 ModestAccountSettings *settings =
561 modest_account_mgr_load_account_settings (mgr, (gchar*) iter->data);
562 accounts = g_slist_prepend (accounts, settings);
566 modest_account_mgr_free_account_names (account_names);
567 account_names = NULL;
569 /* Order the list of accounts by its display name */
570 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
571 num_accounts = g_slist_length (accounts);
573 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
574 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
575 gtk_action_set_visible (send_receive_all, num_accounts > 0);
577 /* Delete old send&receive popup items. We can not just do a
578 menu_detach because it does not work well with
580 if (priv->accounts_popup)
581 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
582 (GtkCallback) gtk_widget_destroy, NULL);
584 /* Delete old entries in the View menu. Do not free groups, it
586 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
588 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
589 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
590 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
591 GTK_ACTION_GROUP (groups->data));
594 if (priv->merge_ids) {
595 for (i = 0; i < priv->merge_ids->len; i++)
596 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
597 g_byte_array_free (priv->merge_ids, TRUE);
599 /* We need to call this in order to ensure
600 that the new actions are added in the right
601 order (alphabetical) */
602 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
604 groups = g_list_next (groups);
606 priv->merge_ids = g_byte_array_sized_new (num_accounts);
608 /* Get send receive button */
609 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
610 "/ToolBar/ToolbarSendReceive");
612 /* Create the menu */
613 if (num_accounts > 1) {
614 if (!priv->accounts_popup)
615 priv->accounts_popup = gtk_menu_new ();
616 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
617 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
618 g_signal_connect (G_OBJECT (item),
620 G_CALLBACK (on_send_receive_csm_activated),
622 item = gtk_separator_menu_item_new ();
623 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
626 /* Create a new action group */
627 default_account = modest_account_mgr_get_default_account (mgr);
628 active_account_name = modest_window_get_active_account (MODEST_WINDOW (self));
630 if (!active_account_name)
631 modest_window_set_active_account (MODEST_WINDOW (self), default_account);
633 priv->view_additions_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
635 for (i = 0; i < num_accounts; i++) {
636 gchar *display_name = NULL;
637 const gchar *account_name;
638 ModestAccountSettings *settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
641 g_warning ("%s: BUG: account_data == NULL", __FUNCTION__);
644 account_name = modest_account_settings_get_account_name (settings);
646 if (default_account && account_name &&
647 !(strcmp (default_account, account_name) == 0)) {
648 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
649 modest_account_settings_get_display_name (settings));
651 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
652 modest_account_settings_get_display_name (settings));
655 /* Create action and add it to the action group. The
656 action name must be the account name, this way we
657 could know in the handlers the account to show */
658 if (settings && account_name) {
659 gchar* item_name, *refresh_action_name;
661 GtkAction *view_account_action, *refresh_account_action;
663 view_account_action = GTK_ACTION (gtk_radio_action_new (account_name,
664 display_name, NULL, NULL, 0));
665 gtk_action_group_add_action (priv->view_additions_group, view_account_action);
666 gtk_radio_action_set_group (GTK_RADIO_ACTION (view_account_action), radio_group);
667 radio_group = gtk_radio_action_get_group (GTK_RADIO_ACTION (view_account_action));
669 if (active_account_name) {
670 if (active_account_name && account_name &&
671 (strcmp (active_account_name, account_name) == 0)) {
672 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (view_account_action), TRUE);
676 /* Add ui from account data. We allow 2^9-1 account
677 changes in a single execution because we're
678 downcasting the guint to a guint8 in order to use a
679 GByteArray. It should be enough. */
680 item_name = g_strconcat (account_name, "Menu", NULL);
681 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
682 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
683 gtk_ui_manager_add_ui (parent_priv->ui_manager,
685 "/MenuBar/ViewMenu/ViewMenuAdditions",
688 GTK_UI_MANAGER_MENUITEM,
691 /* Connect the action signal "activate" */
692 g_signal_connect_after (G_OBJECT (view_account_action),
694 G_CALLBACK (on_show_account_action_toggled),
697 /* Create the items for the Tools->Send&Receive submenu */
698 refresh_action_name = g_strconcat ("SendReceive", account_name, NULL);
699 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
700 display_name, NULL, NULL);
701 gtk_action_group_add_action (priv->view_additions_group, refresh_account_action);
703 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
704 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
705 gtk_ui_manager_add_ui (parent_priv->ui_manager,
707 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
710 GTK_UI_MANAGER_MENUITEM,
712 g_free (refresh_action_name);
714 g_signal_connect_data (G_OBJECT (refresh_account_action),
716 G_CALLBACK (on_refresh_account_action_activated),
717 g_strdup (account_name),
718 (GClosureNotify) g_free,
721 /* Create item and add it to the send&receive
722 CSM. If there is only one account then
724 if (num_accounts > 1) {
725 GtkWidget *label = gtk_label_new(NULL);
726 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
727 if (default_account && (strcmp(account_name, default_account) == 0)) {
728 gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
729 gtk_label_set_markup (GTK_LABEL (label), escaped);
732 gtk_label_set_text (GTK_LABEL (label), display_name);
735 item = gtk_menu_item_new ();
736 gtk_container_add (GTK_CONTAINER (item), label);
738 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
739 g_signal_connect_data (G_OBJECT (item),
741 G_CALLBACK (on_send_receive_csm_activated),
742 g_strdup (account_name),
743 (GClosureNotify) g_free,
750 g_free (display_name);
753 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, priv->view_additions_group, 1);
755 /* We cannot do this in the loop above because this relies on the action
756 * group being inserted. This makes the default account appear in bold.
757 * I agree it is a rather ugly way, but I don't see another possibility. armin. */
758 for (i = 0; i < num_accounts; i++) {
759 gchar *item_name, *path;
761 ModestAccountSettings *settings;
762 const gchar *account_name;
765 settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
766 account_name = modest_account_settings_get_account_name (settings);
767 is_default = (account_name && default_account && !strcmp (account_name, default_account));
769 /* Get the item of the view menu */
770 item_name = g_strconcat (account_name, "Menu", NULL);
771 path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
772 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
776 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
777 if (GTK_IS_LABEL (child)) {
778 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
780 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
781 gtk_label_set_markup (GTK_LABEL (child), bold_name);
784 gtk_label_set_ellipsize (GTK_LABEL (child), PANGO_ELLIPSIZE_END);
788 /* Get the item of the tools menu */
789 path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", item_name, NULL);
790 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
794 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
795 if (GTK_IS_LABEL (child)) {
796 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
798 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
799 gtk_label_set_markup (GTK_LABEL (child), bold_name);
802 gtk_label_set_ellipsize (GTK_LABEL (child), PANGO_ELLIPSIZE_END);
807 g_object_unref (settings);
810 if (num_accounts > 1) {
811 /* Disconnect the tap-and-hold-query if it's connected */
812 if (modest_signal_mgr_is_connected (priv->sighandlers,
813 G_OBJECT (send_receive_button),
814 "tap-and-hold-query"))
815 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
816 G_OBJECT (send_receive_button),
817 "tap-and-hold-query");
819 /* Mandatory in order to view the menu contents */
820 gtk_widget_show_all (priv->accounts_popup);
822 /* Setup tap_and_hold just if was not done before*/
823 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
824 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
826 /* Connect the tap-and-hold-query in order not to show the CSM */
827 if (!modest_signal_mgr_is_connected (priv->sighandlers,
828 G_OBJECT (send_receive_button),
829 "tap-and-hold-query"))
830 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
831 G_OBJECT (send_receive_button),
832 "tap-and-hold-query",
833 G_CALLBACK (tap_and_hold_query_cb),
838 g_slist_free (accounts);
839 g_free (default_account);
842 /* Make sure that at least one account is viewed if there are any
843 * accounts, for instance when adding the first account: */
844 set_at_least_one_account_visible (self);
848 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
850 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
851 gtk_scrolled_window_add_with_viewport
852 (GTK_SCROLLED_WINDOW(win), widget);
854 gtk_container_add (GTK_CONTAINER(win),
865 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
867 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
869 GList *oerrsignals = priv->queue_err_signals;
870 while (oerrsignals) {
871 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
872 g_signal_handler_disconnect (esignal->queue, esignal->signal);
873 g_slice_free (QueueErrorSignal, esignal);
874 oerrsignals = g_list_next (oerrsignals);
876 g_list_free (priv->queue_err_signals);
877 priv->queue_err_signals = NULL;
882 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
884 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
887 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
891 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
893 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
895 /* Update visibility */
898 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
902 modest_main_window_disconnect_signals (ModestWindow *self)
904 ModestMainWindowPrivate *priv;
905 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
907 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
908 priv->sighandlers = NULL;
912 connect_signals (ModestMainWindow *self)
914 ModestWindowPrivate *parent_priv;
915 ModestMainWindowPrivate *priv;
918 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
919 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
924 modest_signal_mgr_connect (priv->sighandlers,
925 G_OBJECT(priv->folder_view), "key-press-event",
926 G_CALLBACK(on_inner_widgets_key_pressed), self);
928 modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view),
929 "folder_selection_changed",
930 G_CALLBACK (on_folder_selection_changed),
933 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view),
934 "folder-display-name-changed",
935 G_CALLBACK (modest_ui_actions_on_folder_display_name_changed),
938 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view),
940 G_CALLBACK (on_folder_view_focus_in),
943 /* Folder view CSM */
944 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
945 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
946 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
947 G_CALLBACK(_folder_view_csm_menu_activated),
951 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
952 G_CALLBACK(modest_ui_actions_on_header_selected), self);
954 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
955 G_CALLBACK(modest_ui_actions_on_header_activated), self);
957 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
958 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
960 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
961 G_CALLBACK(on_inner_widgets_key_pressed), self);
963 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
964 G_CALLBACK(on_msg_count_changed), self);
966 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
967 G_CALLBACK (on_header_view_focus_in), self);
969 modest_signal_mgr_connect (priv->sighandlers,
970 G_OBJECT (priv->header_view),
972 G_CALLBACK (on_updating_msg_list),
975 /* Header view CSM */
976 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
977 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
979 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
980 G_CALLBACK(_header_view_csm_menu_activated),
985 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
986 G_CALLBACK (modest_main_window_window_state_event),
989 /* Mail Operation Queue */
991 modest_signal_mgr_connect (priv->sighandlers,
992 G_OBJECT (modest_runtime_get_mail_operation_queue ()),
994 G_CALLBACK (on_queue_changed), self);
996 /* Track changes in the device name */
998 modest_signal_mgr_connect (priv->sighandlers,
999 G_OBJECT(modest_runtime_get_conf ()),
1001 G_CALLBACK (on_configuration_key_changed),
1004 /* Track account changes. We need to refresh the toolbar */
1006 modest_signal_mgr_connect (priv->sighandlers,
1007 G_OBJECT (modest_runtime_get_account_store ()),
1009 G_CALLBACK (on_account_inserted),
1012 modest_signal_mgr_connect (priv->sighandlers,
1013 G_OBJECT (modest_runtime_get_account_store ()),
1015 G_CALLBACK (on_account_removed),
1018 /* We need to refresh the send & receive menu to change the bold
1019 * account when the default account changes. */
1021 modest_signal_mgr_connect (priv->sighandlers,
1022 G_OBJECT (modest_runtime_get_account_mgr ()),
1023 "default_account_changed",
1024 G_CALLBACK (on_default_account_changed),
1029 modest_signal_mgr_connect (priv->sighandlers,
1030 G_OBJECT (modest_runtime_get_account_store ()),
1032 G_CALLBACK (on_account_changed),
1036 modest_signal_mgr_connect (priv->sighandlers,
1037 G_OBJECT (modest_runtime_get_account_store()),
1038 "password_requested",
1039 G_CALLBACK (modest_ui_actions_on_password_requested),
1044 on_hildon_program_is_topmost_notify(GObject *self,
1045 GParamSpec *propert_param,
1048 HildonProgram *app = HILDON_PROGRAM (self);
1050 /* Note that use of hildon_program_set_can_hibernate()
1051 * is generally referred to as "setting the killable flag",
1052 * though hibernation does not seem equal to death.
1055 if (hildon_program_get_is_topmost (app)) {
1056 /* Prevent hibernation when the progam comes to the foreground,
1057 * because hibernation should only happen when the application
1058 * is in the background: */
1059 hildon_program_set_can_hibernate (app, FALSE);
1061 /* Remove new mail visual notifications */
1062 modest_platform_remove_new_mail_notifications (TRUE);
1064 /* Allow hibernation if the program has gone to the background: */
1066 /* However, prevent hibernation while the settings are being changed: */
1067 const gboolean hibernation_prevented =
1068 modest_window_mgr_get_hibernation_is_prevented (
1069 modest_runtime_get_window_mgr ());
1071 if (hibernation_prevented)
1072 hildon_program_set_can_hibernate (app, FALSE);
1074 /* Allow hibernation, after saving the state: */
1075 modest_osso_save_state();
1076 hildon_program_set_can_hibernate (app, TRUE);
1082 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
1084 GtkWidget *folder_win = (GtkWidget *) user_data;
1085 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1087 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
1088 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
1090 gtk_widget_show (GTK_WIDGET (priv->folder_view));
1092 /* Connect signals */
1093 connect_signals (MODEST_MAIN_WINDOW (self));
1095 /* Set account store */
1096 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
1097 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1099 /* Load previous osso state, for instance if we are being restored from
1101 modest_osso_load_state ();
1103 /* Restore window & widget settings */
1104 priv->wait_for_settings = TRUE;
1105 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
1106 priv->wait_for_settings = FALSE;
1108 /* Check if accounts exist and show the account wizard if not */
1109 gboolean accounts_exist =
1110 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1112 if (!accounts_exist) {
1113 /* This is necessary to have the main window shown behind the dialog
1114 It's an ugly hack... jschmid */
1115 gtk_widget_show_all(GTK_WIDGET(self));
1116 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
1119 GtkAction *send_receive_all;
1120 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1121 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
1122 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1123 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1124 gtk_action_set_visible (send_receive_all, g_slist_length (accounts) > 0);
1125 modest_account_mgr_free_account_names (accounts);
1126 update_menus (MODEST_MAIN_WINDOW (self));
1131 osso_display_event_cb (osso_display_state_t state,
1134 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (data);
1136 priv->display_state = state;
1138 /* Stop blinking if the screen becomes on */
1139 if (priv->display_state == OSSO_DISPLAY_ON)
1140 modest_platform_remove_new_mail_notifications (TRUE);
1144 modest_main_window_new (void)
1146 ModestMainWindow *self = NULL;
1147 ModestMainWindowPrivate *priv = NULL;
1148 ModestWindowPrivate *parent_priv = NULL;
1149 GtkWidget *folder_win = NULL;
1150 ModestDimmingRulesGroup *menu_rules_group = NULL;
1151 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1152 GtkActionGroup *action_group = NULL;
1153 GError *error = NULL;
1155 ModestConf *conf = NULL;
1156 GtkAction *action = NULL;
1157 GdkPixbuf *window_icon;
1159 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
1160 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1161 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1163 parent_priv->ui_manager = gtk_ui_manager_new();
1164 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
1166 action_group = gtk_action_group_new ("ModestMainWindowActions");
1167 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1169 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1170 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1172 /* Add common actions */
1173 gtk_action_group_add_actions (action_group,
1174 modest_action_entries,
1175 G_N_ELEMENTS (modest_action_entries),
1178 gtk_action_group_add_actions (action_group,
1179 modest_folder_view_action_entries,
1180 G_N_ELEMENTS (modest_folder_view_action_entries),
1183 gtk_action_group_add_actions (action_group,
1184 modest_header_view_action_entries,
1185 G_N_ELEMENTS (modest_header_view_action_entries),
1188 gtk_action_group_add_toggle_actions (action_group,
1189 modest_toggle_action_entries,
1190 G_N_ELEMENTS (modest_toggle_action_entries),
1193 gtk_action_group_add_toggle_actions (action_group,
1194 modest_main_window_toggle_action_entries,
1195 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
1198 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
1199 g_object_unref (action_group);
1201 /* Load the UI definition */
1202 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
1203 MODEST_UIDIR "modest-main-window-ui.xml", &error);
1204 if (error != NULL) {
1205 g_warning ("Could not merge modest-ui.xml: %s", error->message);
1206 g_error_free (error);
1210 /* Add common dimming rules */
1211 modest_dimming_rules_group_add_rules (menu_rules_group,
1212 modest_main_window_menu_dimming_entries,
1213 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
1214 MODEST_WINDOW (self));
1215 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1216 modest_main_window_toolbar_dimming_entries,
1217 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
1218 MODEST_WINDOW (self));
1220 /* Insert dimming rules group for this window */
1221 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1222 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1223 g_object_unref (menu_rules_group);
1224 g_object_unref (toolbar_rules_group);
1226 /* Add accelerators */
1227 gtk_window_add_accel_group (GTK_WINDOW (self),
1228 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
1230 /* Menubar. Update the state of some toggles */
1231 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1232 conf = modest_runtime_get_conf ();
1233 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1234 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
1235 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1236 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR, NULL));
1237 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1238 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
1239 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1240 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
1241 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
1242 gtk_widget_show (parent_priv->menubar);
1244 /* Get device name */
1245 modest_maemo_utils_get_device_name ();
1249 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
1250 if (!priv->header_view)
1251 g_printerr ("modest: cannot instantiate header view\n");
1252 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
1253 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
1254 MODEST_CONF_HEADER_VIEW_KEY);
1256 /* Other style properties of header view */
1257 g_object_set (G_OBJECT (priv->header_view),
1258 "rules-hint", FALSE,
1260 /* gtk_widget_show (priv->header_view); */
1263 priv->empty_view = create_empty_view ();
1264 gtk_widget_show (priv->empty_view);
1266 /* Create scrolled windows */
1267 folder_win = gtk_scrolled_window_new (NULL, NULL);
1268 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
1269 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
1271 GTK_POLICY_AUTOMATIC);
1272 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
1274 GTK_POLICY_AUTOMATIC);
1275 /* gtk_widget_show (priv->contents_widget); */
1278 priv->main_paned = gtk_hpaned_new ();
1279 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
1280 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
1281 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
1283 /* putting it all together... */
1284 priv->main_vbox = gtk_vbox_new (FALSE, 6);
1285 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
1286 gtk_widget_show (priv->main_vbox);
1288 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
1290 app = hildon_program_get_instance ();
1291 hildon_program_add_window (app, HILDON_WINDOW (self));
1293 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
1294 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
1296 g_signal_connect (G_OBJECT(self), "show",
1297 G_CALLBACK (modest_main_window_on_show), folder_win);
1299 /* Set window icon */
1300 window_icon = modest_platform_get_icon (MODEST_APP_ICON, MODEST_ICON_SIZE_BIG);
1302 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
1303 g_object_unref (window_icon);
1306 /* Listen for changes in the screen, we don't want to show a
1307 led pattern when the display is on for example */
1308 osso_hw_set_display_event_cb (modest_maemo_utils_get_osso_context (),
1309 osso_display_event_cb,
1312 /* Dont't restore settings here,
1313 * because it requires a gtk_widget_show(),
1314 * and we don't want to do that until later,
1315 * so that the UI is not visible for non-menu D-Bus activation.
1318 return MODEST_WINDOW(self);
1322 modest_main_window_set_style (ModestMainWindow *self,
1323 ModestMainWindowStyle style)
1325 ModestMainWindowPrivate *priv;
1326 ModestWindowPrivate *parent_priv;
1330 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1332 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1333 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1335 /* no change -> nothing to do */
1336 if (priv->style == style)
1339 /* Get toggle button and update the state if needed. This will
1340 happen only when the set_style is not invoked from the UI,
1341 for example when it's called from widget memory */
1342 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1343 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
1344 if ((active && style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) ||
1345 (!active && style == MODEST_MAIN_WINDOW_STYLE_SPLIT)) {
1346 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1347 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !active);
1348 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1351 priv->style = style;
1353 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
1355 if (!priv->wait_for_settings)
1356 modest_widget_memory_save (modest_runtime_get_conf (), G_OBJECT (priv->main_paned),
1357 MODEST_CONF_MAIN_PANED_KEY);
1358 /* Remove main paned */
1359 g_object_ref (priv->main_paned);
1360 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1362 /* Reparent the contents widget to the main vbox */
1363 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
1366 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1367 /* Remove header view */
1368 g_object_ref (priv->contents_widget);
1369 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1371 /* Reparent the main paned */
1372 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1373 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1375 g_timeout_add (500, (GSourceFunc) restore_paned_timeout_handler, self);
1379 g_return_if_reached ();
1382 /* Let header view grab the focus if it's being shown */
1383 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1384 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1386 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1389 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1392 ModestMainWindowStyle
1393 modest_main_window_get_style (ModestMainWindow *self)
1395 ModestMainWindowPrivate *priv;
1397 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1399 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1404 toolbar_resize (ModestMainWindow *self)
1406 ModestMainWindowPrivate *priv = NULL;
1407 ModestWindowPrivate *parent_priv = NULL;
1409 gint static_button_size;
1410 ModestWindowMgr *mgr;
1412 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1413 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1414 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1416 mgr = modest_runtime_get_window_mgr ();
1417 static_button_size = modest_window_mgr_get_fullscreen_mode (mgr)?118:108;
1419 if (parent_priv->toolbar) {
1420 /* left size buttons */
1421 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNew");
1422 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1423 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1424 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1425 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply");
1426 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1427 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1428 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1429 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage");
1430 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1431 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1432 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1433 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1434 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1435 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1436 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1438 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1439 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1440 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1441 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1442 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1443 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1444 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1445 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1453 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1455 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1456 ModestWindowPrivate *parent_priv;
1457 ModestWindowMgr *mgr;
1458 gboolean is_fullscreen;
1459 GtkAction *fs_toggle_action;
1462 mgr = modest_runtime_get_window_mgr ();
1464 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1466 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1468 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1469 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1470 if (is_fullscreen != active) {
1471 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1474 toolbar_resize (MODEST_MAIN_WINDOW (widget));
1482 modest_main_window_show_toolbar (ModestWindow *self,
1483 gboolean show_toolbar)
1485 ModestMainWindowPrivate *priv = NULL;
1486 ModestWindowPrivate *parent_priv = NULL;
1487 GtkWidget *reply_button = NULL, *menu = NULL;
1488 GtkWidget *placeholder = NULL;
1490 const gchar *action_name;
1493 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1494 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1495 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1497 /* Set optimized view status */
1498 priv->optimized_view = !show_toolbar;
1500 if (!parent_priv->toolbar) {
1501 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1503 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1505 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1506 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1507 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1508 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1509 toolbar_resize (MODEST_MAIN_WINDOW (self));
1511 /* Add ProgressBar (Transfer toolbar) */
1512 priv->progress_bar = modest_progress_bar_new ();
1513 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1514 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1515 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1516 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1517 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1519 /* Connect cancel 'clicked' signal to abort progress mode */
1520 g_signal_connect(priv->cancel_toolitem, "clicked",
1521 G_CALLBACK(cancel_progressbar),
1524 /* Add it to the observers list */
1525 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1528 hildon_window_add_toolbar (HILDON_WINDOW (self),
1529 GTK_TOOLBAR (parent_priv->toolbar));
1531 /* Set reply button tap and hold menu */
1532 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1533 "/ToolBar/ToolbarMessageReply");
1534 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1535 "/ToolbarReplyCSM");
1536 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1538 /* Set send & receive button tap and hold menu */
1539 update_menus (MODEST_MAIN_WINDOW (self));
1543 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1544 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1545 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1547 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1548 if (modest_main_window_transfer_mode_enabled (MODEST_MAIN_WINDOW(self)))
1549 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_TRANSFER);
1551 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1553 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1557 /* Update also the actions (to update the toggles in the
1558 menus), we have to do it manually because some other window
1559 of the same time could have changed it (remember that the
1560 toolbar fullscreen mode is shared by all the windows of the
1562 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
1563 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu";
1565 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu";
1567 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
1568 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
1573 on_account_inserted (TnyAccountStore *accoust_store,
1574 TnyAccount *account,
1577 /* Transport accounts and local ones (MMC and the Local
1578 folders account do now cause menu changes */
1579 if (TNY_IS_STORE_ACCOUNT (account) &&
1580 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1581 update_menus (MODEST_MAIN_WINDOW (user_data));
1585 on_default_account_changed (ModestAccountMgr* mgr,
1588 update_menus (MODEST_MAIN_WINDOW (user_data));
1592 on_account_removed (TnyAccountStore *accoust_store,
1593 TnyAccount *account,
1596 /* Transport accounts and local ones (MMC and the Local
1597 folders account do now cause menu changes */
1598 if (TNY_IS_STORE_ACCOUNT (account) &&
1599 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1600 update_menus (MODEST_MAIN_WINDOW (user_data));
1604 on_account_changed (TnyAccountStore *account_store,
1605 TnyAccount *account,
1608 ModestMainWindow *win = MODEST_MAIN_WINDOW (user_data);
1610 /* We need to refresh the details widget because it could have changed */
1611 if (modest_main_window_get_contents_style(win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS) {
1612 modest_main_window_set_contents_style (win, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1615 /* Update the menus as well, the account name could be
1616 changed. Transport accounts and local ones (MMC and the
1617 Local folders account do now cause menu changes */
1618 if (TNY_IS_STORE_ACCOUNT (account) &&
1619 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1620 update_menus (MODEST_MAIN_WINDOW (user_data));
1624 * This function manages the key events used to navigate between
1625 * header and folder views (when the window is in split view)
1628 * -------------------------------------------------
1629 * HeaderView GDK_Left Move focus to folder view
1630 * FolderView GDK_Right Move focus to header view
1632 * There is no need to scroll to selected row, the widgets will be the
1633 * responsibles of doing that (probably managing the focus-in event
1636 on_inner_widgets_key_pressed (GtkWidget *widget,
1640 ModestMainWindowPrivate *priv;
1642 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1644 /* Do nothing if we're in SIMPLE style */
1645 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1648 if (MODEST_IS_HEADER_VIEW (widget)) {
1649 if (event->keyval == GDK_Left)
1650 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1651 else if ((event->keyval == GDK_Return)||(event->keyval == GDK_KP_Enter)) {
1652 guint selected_headers = modest_header_view_count_selected_headers (MODEST_HEADER_VIEW (widget));
1653 if (selected_headers > 1) {
1654 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1658 } else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1659 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1665 set_alignment (GtkWidget *widget,
1668 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1669 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1673 create_empty_view (void)
1675 GtkLabel *label = NULL;
1676 GtkWidget *align = NULL;
1678 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1679 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1680 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1681 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1683 return GTK_WIDGET(align);
1687 * Free the returned string
1690 get_gray_color_markup (GtkWidget *styled_widget)
1692 gchar *gray_color_markup = NULL;
1693 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1694 /* Obtain the secondary text color. We need a realized widget, that's why
1695 we get styled_widget from outside */
1697 if (gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color))
1698 gray_color_markup = modest_text_utils_get_color_string (&color);
1699 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
1701 if (!gray_color_markup)
1702 gray_color_markup = g_strdup ("#BBBBBB");
1704 return gray_color_markup;
1708 * Free the returned string
1711 create_device_name_visual_string (const gchar *device_name,
1712 const gchar *gray_color_markup)
1716 /* We have to use "" to fill the %s of the translation. We can
1717 not just use the device name because the device name is
1718 shown in a different color, so it could not be included
1719 into the <span> tag */
1720 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), "");
1721 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1731 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1733 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1738 gchar *gray_color_markup;
1740 vbox = gtk_vbox_new (FALSE, 0);
1742 gray_color_markup = get_gray_color_markup (styled_widget);
1744 /* Account description: */
1745 if (modest_tny_account_is_virtual_local_folders (account)
1746 || (modest_tny_account_is_memory_card_account (account))) {
1748 /* Get device name */
1749 gchar *device_name = NULL;
1750 if (modest_tny_account_is_virtual_local_folders (account))
1751 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1752 MODEST_CONF_DEVICE_NAME, NULL);
1754 device_name = g_strdup (tny_account_get_name (account));
1756 label = create_device_name_visual_string ((const gchar *) device_name,
1757 (const gchar *) gray_color_markup);
1758 label_w = gtk_label_new (NULL);
1759 gtk_label_set_markup (GTK_LABEL (label_w), label);
1760 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1761 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1762 g_free (device_name);
1765 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1766 gtk_box_pack_start (GTK_BOX (vbox),
1767 gtk_label_new (tny_account_get_name (account)),
1770 /* Other accounts, such as IMAP and POP: */
1775 /* Put proto in uppercase */
1776 proto = g_string_new (tny_account_get_proto (account));
1777 proto = g_string_ascii_up (proto);
1779 /* note: mcen_fi_localroot_description is something like "%s account"
1780 * however, we should display "%s account: %s"... therefore, ugly tmp */
1781 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1782 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1783 gray_color_markup, tmp, tny_account_get_name (account));
1786 label_w = gtk_label_new (NULL);
1787 gtk_label_set_markup (GTK_LABEL (label_w), label);
1788 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1789 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1790 g_string_free (proto, TRUE);
1796 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1797 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1798 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1799 modest_tny_folder_store_get_message_count (folder_store));
1800 label_w = gtk_label_new (NULL);
1801 gtk_label_set_markup (GTK_LABEL (label_w), label);
1802 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1803 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1807 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1809 _("mcen_fi_rootfolder_folders"),
1810 modest_tny_folder_store_get_folder_count (folder_store));
1811 label_w = gtk_label_new (NULL);
1812 gtk_label_set_markup (GTK_LABEL (label_w), label);
1813 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1814 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1818 if (modest_tny_account_is_virtual_local_folders (account)
1819 || modest_tny_account_is_memory_card_account (account)) {
1821 gchar *size = modest_text_utils_get_display_size (
1822 modest_tny_folder_store_get_local_size (folder_store));
1824 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1825 gray_color_markup, _("mcen_fi_rootfolder_size"),
1829 label_w = gtk_label_new (NULL);
1830 gtk_label_set_markup (GTK_LABEL (label_w), label);
1831 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1832 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1834 } else if (TNY_IS_ACCOUNT(folder_store)) {
1835 TnyAccount *account = TNY_ACCOUNT(folder_store);
1837 time_t last_updated;
1838 const gchar *last_updated_string;
1839 /* Get last updated from configuration */
1840 last_updated = modest_account_mgr_get_last_updated (modest_runtime_get_account_mgr (),
1841 tny_account_get_id (account));
1843 if (last_updated > 0)
1844 last_updated_string = modest_text_utils_get_display_date(last_updated);
1846 last_updated_string = g_strdup (_("mcen_va_never"));
1848 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1849 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1850 label_w = gtk_label_new (NULL);
1851 gtk_label_set_markup (GTK_LABEL (label_w), label);
1852 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1853 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1857 g_free (gray_color_markup);
1860 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1866 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1868 ModestMainWindowPrivate *priv = NULL;
1870 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1872 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1874 return priv->send_receive_in_progress;
1878 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1880 GtkAction *action = NULL;
1881 GtkWidget *widget = NULL;
1882 ModestMainWindowPrivate *priv = NULL;
1884 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1885 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1887 priv->send_receive_in_progress = TRUE;
1889 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1890 gtk_action_set_sensitive (action, FALSE);
1891 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1892 /* gtk_action_set_sensitive (action, FALSE); */
1893 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1894 gtk_widget_set_sensitive (widget, FALSE);
1898 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1900 GtkAction *action = NULL;
1901 GtkWidget *widget = NULL;
1902 ModestMainWindowPrivate *priv = NULL;
1904 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1905 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1907 priv->send_receive_in_progress = FALSE;
1909 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1910 gtk_action_set_sensitive (action, TRUE);
1911 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1912 /* gtk_action_set_sensitive (action, TRUE); */
1913 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1914 gtk_widget_set_sensitive (widget, TRUE);
1919 on_msg_count_changed (ModestHeaderView *header_view,
1921 TnyFolderChange *change,
1922 ModestMainWindow *main_window)
1924 gboolean refilter = FALSE;
1925 gboolean folder_empty = FALSE;
1926 gboolean all_marked_as_deleted = FALSE;
1927 ModestMainWindowPrivate *priv;
1929 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1930 g_return_if_fail (TNY_IS_FOLDER(folder));
1931 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
1933 if (change != NULL) {
1934 TnyFolderChangeChanged changed;
1936 changed = tny_folder_change_get_changed (change);
1937 /* If something changes */
1938 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1939 folder_empty = (((guint) tny_folder_change_get_new_all_count (change)) == 0);
1941 folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1943 /* Play a sound (if configured) and make the LED blink */
1944 if (changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS) {
1945 modest_platform_push_email_notification ();
1948 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_EXPUNGED_HEADERS)
1951 folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1954 /* Check if all messages are marked to be deleted */
1955 all_marked_as_deleted = modest_header_view_is_empty (header_view);
1956 folder_empty = folder_empty || all_marked_as_deleted;
1958 /* Set contents style of headers view */
1960 modest_main_window_set_contents_style (main_window,
1961 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1962 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1964 modest_main_window_set_contents_style (main_window,
1965 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1969 modest_header_view_refilter (header_view);
1974 modest_main_window_set_contents_style (ModestMainWindow *self,
1975 ModestMainWindowContentsStyle style)
1977 ModestMainWindowPrivate *priv;
1979 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1981 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1983 /* We allow to set the same content style than the previously
1984 set if there are details, because it could happen when we're
1985 selecting different accounts consecutively */
1986 if ((priv->contents_style == style) &&
1987 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1990 /* Remove previous child. Delete it if it was an account
1992 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1994 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1995 g_object_ref (content);
1996 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1997 g_object_ref (priv->empty_view);
1998 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
2001 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
2004 priv->contents_style = style;
2006 switch (priv->contents_style) {
2007 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
2008 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
2009 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2012 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
2014 /* if we're started without main win, there may not be a folder
2015 * view. this fixes a GLib-Critical */
2016 if (priv->folder_view) {
2017 TnyFolderStore *selected_folderstore =
2018 modest_folder_view_get_selected (priv->folder_view);
2019 if (TNY_IS_ACCOUNT (selected_folderstore)) {
2020 priv->details_widget = create_details_widget (GTK_WIDGET (self),
2021 TNY_ACCOUNT (selected_folderstore));
2023 wrap_in_scrolled_window (priv->contents_widget,
2024 priv->details_widget);
2026 g_object_unref (selected_folderstore);
2027 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2032 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
2033 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
2034 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2038 g_return_if_reached ();
2042 gtk_widget_show_all (priv->contents_widget);
2045 ModestMainWindowContentsStyle
2046 modest_main_window_get_contents_style (ModestMainWindow *self)
2048 ModestMainWindowPrivate *priv;
2050 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
2052 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2053 return priv->contents_style;
2058 on_configuration_key_changed (ModestConf* conf,
2060 ModestConfEvent event,
2061 ModestConfNotificationId id,
2062 ModestMainWindow *self)
2064 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2065 TnyAccount *account = NULL;
2067 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
2070 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
2073 if (priv->folder_view)
2074 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
2076 if (account && TNY_IS_ACCOUNT (account) &&
2077 strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID) == 0) {
2080 const gchar *device_name;
2081 gchar *new_text, *gray_color_markup;
2084 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
2085 label = GTK_LABEL (children->data);
2087 device_name = modest_conf_get_string (modest_runtime_get_conf(),
2088 MODEST_CONF_DEVICE_NAME, NULL);
2090 gray_color_markup = get_gray_color_markup (GTK_WIDGET (self));
2091 new_text = create_device_name_visual_string (device_name, gray_color_markup);
2093 gtk_label_set_markup (label, new_text);
2094 gtk_widget_show (GTK_WIDGET (label));
2096 g_free (gray_color_markup);
2098 g_list_free (children);
2100 g_object_unref (account);
2104 set_toolbar_transfer_mode (ModestMainWindow *self)
2106 ModestMainWindowPrivate *priv = NULL;
2108 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2110 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2112 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
2114 if (priv->progress_bar_timeout > 0) {
2115 g_source_remove (priv->progress_bar_timeout);
2116 priv->progress_bar_timeout = 0;
2123 set_toolbar_mode (ModestMainWindow *self,
2124 ModestToolBarModes mode)
2126 ModestWindowPrivate *parent_priv = NULL;
2127 ModestMainWindowPrivate *priv = NULL;
2128 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
2130 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2132 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2133 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2135 /* In case this was called before the toolbar exists: */
2136 if (!(parent_priv->toolbar))
2139 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
2141 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
2142 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
2143 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
2145 /* Sets current toolbar mode */
2146 priv->current_toolbar_mode = mode;
2148 /* Checks the dimming rules */
2149 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2151 /* Show and hide toolbar items */
2153 case TOOLBAR_MODE_NORMAL:
2155 gtk_action_set_visible (sort_action, TRUE);
2157 gtk_action_set_visible (refresh_action, TRUE);
2158 if (priv->progress_toolitem) {
2159 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
2160 gtk_widget_hide (priv->progress_toolitem);
2162 if (priv->progress_bar)
2163 gtk_widget_hide (priv->progress_bar);
2166 gtk_action_set_visible (cancel_action, FALSE);
2168 /* Hide toolbar if optimized view is enabled */
2169 if (priv->optimized_view)
2170 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
2172 case TOOLBAR_MODE_TRANSFER:
2174 gtk_action_set_visible (sort_action, FALSE);
2176 gtk_action_set_visible (refresh_action, FALSE);
2178 gtk_action_set_visible (cancel_action, TRUE);
2179 if (priv->progress_bar)
2180 gtk_widget_show (priv->progress_bar);
2181 if (priv->progress_toolitem) {
2182 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
2183 gtk_widget_show (priv->progress_toolitem);
2186 /* Show toolbar if it's hiden (optimized view ) */
2187 if (priv->optimized_view)
2188 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2191 g_return_if_reached ();
2196 modest_main_window_transfer_mode_enabled (ModestMainWindow *self)
2198 ModestMainWindowPrivate *priv;
2200 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2201 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2203 return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
2207 cancel_progressbar (GtkToolButton *toolbutton,
2208 ModestMainWindow *self)
2211 ModestMainWindowPrivate *priv;
2213 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2215 /* Get operation observers and cancel all the operations */
2216 tmp = priv->progress_widgets;
2218 modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2219 tmp=g_slist_next(tmp);
2224 observers_empty (ModestMainWindow *self)
2227 ModestMainWindowPrivate *priv;
2228 gboolean is_empty = TRUE;
2229 guint pending_ops = 0;
2231 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2232 tmp = priv->progress_widgets;
2234 /* Check all observers */
2235 while (tmp && is_empty) {
2236 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2237 is_empty = pending_ops == 0;
2239 tmp = g_slist_next(tmp);
2247 * Gets the toolbar mode needed for each mail operation. It stores in
2248 * @mode_changed if the toolbar mode has changed or not
2250 static ModestToolBarModes
2251 get_toolbar_mode_from_mail_operation (ModestMainWindow *self,
2252 ModestMailOperation *mail_op,
2253 gboolean *mode_changed)
2255 ModestToolBarModes mode;
2256 ModestMainWindowPrivate *priv;
2258 *mode_changed = FALSE;
2259 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2261 /* Get toolbar mode from operation id*/
2262 switch (modest_mail_operation_get_type_operation (mail_op)) {
2263 case MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE:
2264 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
2265 case MODEST_MAIL_OPERATION_TYPE_OPEN:
2266 mode = TOOLBAR_MODE_TRANSFER;
2267 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
2268 *mode_changed = TRUE;
2271 mode = TOOLBAR_MODE_NORMAL;
2277 on_mail_operation_started (ModestMailOperation *mail_op,
2280 ModestMainWindow *self;
2281 ModestMailOperationTypeOperation op_type;
2282 ModestMainWindowPrivate *priv;
2283 ModestToolBarModes mode;
2285 gboolean mode_changed = FALSE;
2286 TnyAccount *account;
2288 self = MODEST_MAIN_WINDOW (user_data);
2289 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2291 /* Do not show progress for receiving operations if the
2292 account is the local account or the MMC one */
2293 op_type = modest_mail_operation_get_type_operation (mail_op);
2294 account = modest_mail_operation_get_account (mail_op);
2295 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2298 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2299 modest_tny_account_is_memory_card_account (account));
2300 g_object_unref (account);
2304 /* Show information banner. Remove old timeout */
2305 if (priv->retrieving_banner_timeout > 0) {
2306 g_source_remove (priv->retrieving_banner_timeout);
2307 priv->retrieving_banner_timeout = 0;
2309 /* Create a new timeout */
2310 priv->retrieving_banner_timeout =
2311 g_timeout_add (2000, show_retrieving_banner, self);
2314 /* Get toolbar mode from operation id*/
2315 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2317 /* Add operation observers and change toolbar if neccessary*/
2318 tmp = priv->progress_widgets;
2319 if (mode == TOOLBAR_MODE_TRANSFER) {
2321 GObject *source = modest_mail_operation_get_source(mail_op);
2322 if (G_OBJECT (self) == source) {
2323 set_toolbar_transfer_mode(self);
2325 g_object_unref (source);
2329 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2331 tmp = g_slist_next (tmp);
2335 /* Update the main menu as well, we need to explicitely do
2336 this in order to enable/disable accelerators */
2337 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
2341 on_mail_operation_finished (ModestMailOperation *mail_op,
2344 ModestToolBarModes mode;
2345 ModestMailOperationTypeOperation op_type;
2347 ModestMainWindow *self;
2348 gboolean mode_changed;
2349 TnyAccount *account;
2350 ModestMainWindowPrivate *priv;
2352 self = MODEST_MAIN_WINDOW (user_data);
2353 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2355 /* The mail operation was not added to the progress objects if
2356 the account was the local account or the MMC one */
2357 op_type = modest_mail_operation_get_type_operation (mail_op);
2358 account = modest_mail_operation_get_account (mail_op);
2359 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2362 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2363 modest_tny_account_is_memory_card_account (account));
2364 g_object_unref (account);
2368 /* Remove old timeout */
2369 if (priv->retrieving_banner_timeout > 0) {
2370 g_source_remove (priv->retrieving_banner_timeout);
2371 priv->retrieving_banner_timeout = 0;
2374 /* Remove the banner if exists */
2375 if (priv->retrieving_banner) {
2376 gtk_widget_destroy (priv->retrieving_banner);
2377 priv->retrieving_banner = NULL;
2381 /* Get toolbar mode from operation id*/
2382 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2384 /* Change toolbar mode */
2385 tmp = priv->progress_widgets;
2386 if (mode == TOOLBAR_MODE_TRANSFER) {
2388 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2390 tmp = g_slist_next (tmp);
2393 /* If no more operations are being observed, NORMAL mode is enabled again */
2394 if (observers_empty (self)) {
2395 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
2401 on_queue_changed (ModestMailOperationQueue *queue,
2402 ModestMailOperation *mail_op,
2403 ModestMailOperationQueueNotification type,
2404 ModestMainWindow *self)
2406 ModestMainWindowPrivate *priv;
2408 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2410 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
2411 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2413 "operation-started",
2414 G_CALLBACK (on_mail_operation_started),
2416 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2418 "operation-finished",
2419 G_CALLBACK (on_mail_operation_finished),
2421 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
2422 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2424 "operation-started");
2425 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2427 "operation-finished");
2432 set_account_visible(ModestMainWindow *self, const gchar *acc_name)
2434 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2436 ModestAccountMgr *mgr;
2437 ModestAccountSettings *settings;
2438 ModestServerAccountSettings *store_settings = NULL;
2440 /* Get account data */
2441 mgr = modest_runtime_get_account_mgr ();
2442 settings = modest_account_mgr_load_account_settings (mgr, acc_name);
2444 store_settings = modest_account_settings_get_store_settings (settings);
2446 /* Set the new visible & active account */
2447 if (settings && (modest_server_account_settings_get_account_name (store_settings)!= NULL)) {
2448 const gchar *account_name;
2450 account_name = modest_account_settings_get_account_name (settings);
2452 modest_folder_view_set_account_id_of_visible_server_account
2454 modest_server_account_settings_get_account_name (store_settings));
2455 modest_window_set_active_account (MODEST_WINDOW (self), account_name);
2456 action = gtk_action_group_get_action (priv->view_additions_group, account_name);
2457 if (action != NULL) {
2458 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2459 modest_utils_toggle_action_set_active_block_notify (
2460 GTK_TOGGLE_ACTION (action),
2466 modest_folder_view_select_first_inbox_or_local (priv->folder_view);
2471 g_object_unref (store_settings);
2472 g_object_unref (settings);
2476 /* Make sure that at least one account is "viewed": */
2478 set_at_least_one_account_visible(ModestMainWindow *self)
2480 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2481 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2483 if (!(priv->folder_view)) {
2484 /* It is too early to do this. */
2488 const gchar *active_server_account_name =
2489 modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);
2491 if (!active_server_account_name ||
2492 !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
2494 gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
2495 gchar* default_modest_name = modest_account_mgr_get_default_account (account_mgr);
2496 if (default_modest_name) {
2497 set_account_visible (self, default_modest_name);
2498 } else if (first_modest_name) {
2499 set_account_visible (self, first_modest_name);
2501 g_free (first_modest_name);
2502 g_free (default_modest_name);
2507 on_show_account_action_toggled (GtkToggleAction *action,
2510 ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
2512 const gchar *acc_name = gtk_action_get_name (GTK_ACTION (action));
2513 if (gtk_toggle_action_get_active (action))
2514 set_account_visible (self, acc_name);
2518 refresh_account (const gchar *account_name)
2522 /* win must already exists here, obviously */
2523 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
2526 g_warning ("%s: BUG: no main window!", __FUNCTION__);
2530 /* If account_name == NULL, we must update all (option All) */
2532 modest_ui_actions_do_send_receive_all (win, TRUE);
2534 modest_ui_actions_do_send_receive (account_name, TRUE, win);
2539 on_refresh_account_action_activated (GtkAction *action,
2542 refresh_account ((const gchar*) user_data);
2546 on_send_receive_csm_activated (GtkMenuItem *item,
2549 refresh_account ((const gchar*) user_data);
2553 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2555 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2557 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2563 on_folder_view_focus_in (GtkWidget *widget, GdkEventFocus *event, gpointer userdata)
2565 ModestMainWindow *main_window = NULL;
2567 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2568 main_window = MODEST_MAIN_WINDOW (userdata);
2570 /* Update toolbar dimming state */
2571 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2577 on_header_view_focus_in (GtkWidget *widget,
2578 GdkEventFocus *event,
2581 ModestMainWindow *main_window = NULL;
2583 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2585 main_window = MODEST_MAIN_WINDOW (userdata);
2587 /* Update toolbar dimming state */
2588 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2594 on_folder_selection_changed (ModestFolderView *folder_view,
2595 TnyFolderStore *folder_store,
2597 ModestMainWindow *main_window)
2599 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2600 GtkAction *action = NULL;
2601 gboolean show_reply = TRUE;
2602 gboolean show_forward = TRUE;
2603 gboolean show_cancel_send = FALSE;
2604 gboolean show_clipboard = TRUE;
2605 gboolean show_delete = TRUE;
2608 if (TNY_IS_ACCOUNT (folder_store)) {
2609 show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2610 } else if (TNY_IS_FOLDER (folder_store)) {
2611 if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2612 TnyFolderType folder_type = modest_tny_folder_get_local_or_mmc_folder_type (
2613 TNY_FOLDER (folder_store));
2614 switch (folder_type) {
2615 case TNY_FOLDER_TYPE_DRAFTS:
2616 show_clipboard = show_delete = TRUE;
2617 show_reply = show_forward = show_cancel_send = FALSE;
2619 case TNY_FOLDER_TYPE_SENT:
2620 show_forward = show_clipboard = show_delete = TRUE;
2621 show_reply = show_cancel_send = FALSE;
2623 case TNY_FOLDER_TYPE_OUTBOX:
2624 show_clipboard = show_delete = show_cancel_send = TRUE;
2625 show_reply = show_forward = FALSE;
2627 case TNY_FOLDER_TYPE_INVALID:
2628 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
2631 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2632 show_cancel_send = FALSE;
2635 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2636 show_cancel_send = FALSE;
2641 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2642 gtk_action_set_visible (action, show_reply);
2643 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2644 gtk_action_set_visible (action, show_reply);
2645 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2646 gtk_action_set_visible (action, show_forward);
2647 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2648 gtk_action_set_visible (action, show_cancel_send);
2649 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2650 gtk_action_set_visible (action, show_delete);
2652 /* We finally call to the ui actions handler, after updating properly
2653 * the header view CSM */
2654 modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2658 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2659 GtkTreeModel *model,
2660 GtkTreeRowReference *row_reference,
2661 ModestMainWindow *self)
2663 ModestMainWindowPrivate *priv = NULL;
2664 GtkTreeModel *header_model = NULL;
2665 GtkTreePath *path = NULL;
2667 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
2668 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2669 g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2671 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2672 header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2674 /* Do nothing if we changed the folder in the main view */
2675 if (header_model != model)
2678 /* Select the message in the header view */
2679 path = gtk_tree_row_reference_get_path (row_reference);
2680 gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->header_view),
2682 gtk_tree_path_free (path);
2688 show_updating_banner (gpointer user_data)
2690 ModestMainWindowPrivate *priv = NULL;
2692 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2694 if (priv->updating_banner == NULL) {
2696 /* We're outside the main lock */
2697 gdk_threads_enter ();
2698 priv->updating_banner =
2699 modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2700 _CS ("ckdg_pb_updating"));
2701 gdk_threads_leave ();
2704 /* Remove timeout */
2705 priv->updating_banner_timeout = 0;
2710 * We use this function to show/hide a progress banner showing
2711 * "Updating" while the header view is being filled. We're not showing
2712 * it unless the update takes more than 2 seconds
2714 * If starting = TRUE then the refresh is starting, otherwise it means
2715 * that is has just finished
2718 on_updating_msg_list (ModestHeaderView *header_view,
2722 ModestMainWindowPrivate *priv = NULL;
2724 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2726 /* Remove old timeout */
2727 if (priv->updating_banner_timeout > 0) {
2728 g_source_remove (priv->updating_banner_timeout);
2729 priv->updating_banner_timeout = 0;
2732 /* Create a new timeout */
2734 priv->updating_banner_timeout =
2735 g_timeout_add (2000, show_updating_banner, user_data);
2737 /* Remove the banner if exists */
2738 if (priv->updating_banner) {
2739 gtk_widget_destroy (priv->updating_banner);
2740 priv->updating_banner = NULL;
2746 modest_main_window_screen_is_on (ModestMainWindow *self)
2748 ModestMainWindowPrivate *priv = NULL;
2750 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(self), FALSE);
2752 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2754 return (priv->display_state == OSSO_DISPLAY_ON) ? TRUE : FALSE;
2758 show_retrieving_banner (gpointer user_data)
2760 ModestMainWindowPrivate *priv = NULL;
2762 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2764 if (priv->retrieving_banner == NULL) {
2766 /* We're outside the main lock */
2767 gdk_threads_enter ();
2768 priv->retrieving_banner =
2769 modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2770 _("mcen_ib_getting_items"));
2771 gdk_threads_leave ();
2774 /* Remove timeout */
2775 priv->retrieving_banner_timeout = 0;