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));
657 /* Create action and add it to the action group. The
658 action name must be the account name, this way we
659 could know in the handlers the account to show */
660 if (settings && account_name) {
661 gchar* item_name, *refresh_action_name;
663 GtkAction *view_account_action, *refresh_account_action;
664 gchar *escaped_display_name;
666 escaped_display_name = modest_text_utils_escape_mnemonics (display_name);
668 view_account_action = GTK_ACTION (gtk_radio_action_new (account_name,
669 escaped_display_name, NULL, NULL, 0));
670 g_free (escaped_display_name);
671 gtk_action_group_add_action (priv->view_additions_group, view_account_action);
672 gtk_radio_action_set_group (GTK_RADIO_ACTION (view_account_action), radio_group);
673 radio_group = gtk_radio_action_get_group (GTK_RADIO_ACTION (view_account_action));
675 if (active_account_name) {
676 if (active_account_name && account_name &&
677 (strcmp (active_account_name, account_name) == 0)) {
678 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (view_account_action), TRUE);
682 /* Add ui from account data. We allow 2^9-1 account
683 changes in a single execution because we're
684 downcasting the guint to a guint8 in order to use a
685 GByteArray. It should be enough. */
686 item_name = g_strconcat (account_name, "Menu", NULL);
687 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
688 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
689 gtk_ui_manager_add_ui (parent_priv->ui_manager,
691 "/MenuBar/ViewMenu/ViewMenuAdditions",
694 GTK_UI_MANAGER_MENUITEM,
697 /* Connect the action signal "activate" */
698 g_signal_connect_after (G_OBJECT (view_account_action),
700 G_CALLBACK (on_show_account_action_toggled),
703 /* Create the items for the Tools->Send&Receive submenu */
704 refresh_action_name = g_strconcat ("SendReceive", account_name, NULL);
705 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
706 display_name, NULL, NULL);
707 gtk_action_group_add_action (priv->view_additions_group, refresh_account_action);
709 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
710 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
711 gtk_ui_manager_add_ui (parent_priv->ui_manager,
713 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
716 GTK_UI_MANAGER_MENUITEM,
718 g_free (refresh_action_name);
720 g_signal_connect_data (G_OBJECT (refresh_account_action),
722 G_CALLBACK (on_refresh_account_action_activated),
723 g_strdup (account_name),
724 (GClosureNotify) g_free,
727 /* Create item and add it to the send&receive
728 CSM. If there is only one account then
730 if (num_accounts > 1) {
731 GtkWidget *label = gtk_label_new(NULL);
732 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
733 if (default_account && (strcmp(account_name, default_account) == 0)) {
734 gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
735 gtk_label_set_markup (GTK_LABEL (label), escaped);
738 gtk_label_set_text (GTK_LABEL (label), display_name);
741 item = gtk_menu_item_new ();
742 gtk_container_add (GTK_CONTAINER (item), label);
744 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
745 g_signal_connect_data (G_OBJECT (item),
747 G_CALLBACK (on_send_receive_csm_activated),
748 g_strdup (account_name),
749 (GClosureNotify) g_free,
756 g_free (display_name);
759 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, priv->view_additions_group, 1);
761 /* We cannot do this in the loop above because this relies on the action
762 * group being inserted. This makes the default account appear in bold.
763 * I agree it is a rather ugly way, but I don't see another possibility. armin. */
764 for (i = 0; i < num_accounts; i++) {
765 gchar *item_name, *path;
767 ModestAccountSettings *settings;
768 const gchar *account_name;
771 settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
772 account_name = modest_account_settings_get_account_name (settings);
773 is_default = (account_name && default_account && !strcmp (account_name, default_account));
775 /* Get the item of the view menu */
776 item_name = g_strconcat (account_name, "Menu", NULL);
777 path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
778 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
782 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
783 if (GTK_IS_LABEL (child)) {
784 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
786 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
787 gtk_label_set_markup (GTK_LABEL (child), bold_name);
790 gtk_label_set_ellipsize (GTK_LABEL (child), PANGO_ELLIPSIZE_END);
794 /* Get the item of the tools menu */
795 path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", item_name, NULL);
796 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
800 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
801 if (GTK_IS_LABEL (child)) {
802 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
804 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
805 gtk_label_set_markup (GTK_LABEL (child), bold_name);
808 gtk_label_set_ellipsize (GTK_LABEL (child), PANGO_ELLIPSIZE_END);
813 g_object_unref (settings);
816 if (num_accounts > 1) {
817 /* Disconnect the tap-and-hold-query if it's connected */
818 if (modest_signal_mgr_is_connected (priv->sighandlers,
819 G_OBJECT (send_receive_button),
820 "tap-and-hold-query"))
821 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
822 G_OBJECT (send_receive_button),
823 "tap-and-hold-query");
825 /* Mandatory in order to view the menu contents */
826 gtk_widget_show_all (priv->accounts_popup);
828 /* Setup tap_and_hold just if was not done before*/
829 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
830 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
832 /* Connect the tap-and-hold-query in order not to show the CSM */
833 if (!modest_signal_mgr_is_connected (priv->sighandlers,
834 G_OBJECT (send_receive_button),
835 "tap-and-hold-query"))
836 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
837 G_OBJECT (send_receive_button),
838 "tap-and-hold-query",
839 G_CALLBACK (tap_and_hold_query_cb),
844 g_slist_free (accounts);
845 g_free (default_account);
848 /* Make sure that at least one account is viewed if there are any
849 * accounts, for instance when adding the first account: */
850 set_at_least_one_account_visible (self);
854 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
856 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
857 gtk_scrolled_window_add_with_viewport
858 (GTK_SCROLLED_WINDOW(win), widget);
860 gtk_container_add (GTK_CONTAINER(win),
871 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
873 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
875 GList *oerrsignals = priv->queue_err_signals;
876 while (oerrsignals) {
877 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
878 g_signal_handler_disconnect (esignal->queue, esignal->signal);
879 g_slice_free (QueueErrorSignal, esignal);
880 oerrsignals = g_list_next (oerrsignals);
882 g_list_free (priv->queue_err_signals);
883 priv->queue_err_signals = NULL;
888 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
890 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
893 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
897 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
899 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
901 /* Update visibility */
904 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
908 modest_main_window_disconnect_signals (ModestWindow *self)
910 ModestMainWindowPrivate *priv;
911 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
913 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
914 priv->sighandlers = NULL;
918 connect_signals (ModestMainWindow *self)
920 ModestWindowPrivate *parent_priv;
921 ModestMainWindowPrivate *priv;
924 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
925 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
930 modest_signal_mgr_connect (priv->sighandlers,
931 G_OBJECT(priv->folder_view), "key-press-event",
932 G_CALLBACK(on_inner_widgets_key_pressed), self);
934 modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view),
935 "folder_selection_changed",
936 G_CALLBACK (on_folder_selection_changed),
939 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view),
940 "folder-display-name-changed",
941 G_CALLBACK (modest_ui_actions_on_folder_display_name_changed),
944 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view),
946 G_CALLBACK (on_folder_view_focus_in),
949 /* Folder view CSM */
950 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
951 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
952 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
953 G_CALLBACK(_folder_view_csm_menu_activated),
957 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
958 G_CALLBACK(modest_ui_actions_on_header_selected), self);
960 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
961 G_CALLBACK(modest_ui_actions_on_header_activated), self);
963 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
964 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
966 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
967 G_CALLBACK(on_inner_widgets_key_pressed), self);
969 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
970 G_CALLBACK(on_msg_count_changed), self);
972 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
973 G_CALLBACK (on_header_view_focus_in), self);
975 modest_signal_mgr_connect (priv->sighandlers,
976 G_OBJECT (priv->header_view),
978 G_CALLBACK (on_updating_msg_list),
981 /* Header view CSM */
982 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
983 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
985 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
986 G_CALLBACK(_header_view_csm_menu_activated),
991 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
992 G_CALLBACK (modest_main_window_window_state_event),
995 /* Mail Operation Queue */
997 modest_signal_mgr_connect (priv->sighandlers,
998 G_OBJECT (modest_runtime_get_mail_operation_queue ()),
1000 G_CALLBACK (on_queue_changed), self);
1002 /* Track changes in the device name */
1004 modest_signal_mgr_connect (priv->sighandlers,
1005 G_OBJECT(modest_runtime_get_conf ()),
1007 G_CALLBACK (on_configuration_key_changed),
1010 /* Track account changes. We need to refresh the toolbar */
1012 modest_signal_mgr_connect (priv->sighandlers,
1013 G_OBJECT (modest_runtime_get_account_store ()),
1015 G_CALLBACK (on_account_inserted),
1018 modest_signal_mgr_connect (priv->sighandlers,
1019 G_OBJECT (modest_runtime_get_account_store ()),
1021 G_CALLBACK (on_account_removed),
1024 /* We need to refresh the send & receive menu to change the bold
1025 * account when the default account changes. */
1027 modest_signal_mgr_connect (priv->sighandlers,
1028 G_OBJECT (modest_runtime_get_account_mgr ()),
1029 "default_account_changed",
1030 G_CALLBACK (on_default_account_changed),
1035 modest_signal_mgr_connect (priv->sighandlers,
1036 G_OBJECT (modest_runtime_get_account_store ()),
1038 G_CALLBACK (on_account_changed),
1042 modest_signal_mgr_connect (priv->sighandlers,
1043 G_OBJECT (modest_runtime_get_account_store()),
1044 "password_requested",
1045 G_CALLBACK (modest_ui_actions_on_password_requested),
1050 on_hildon_program_is_topmost_notify(GObject *self,
1051 GParamSpec *propert_param,
1054 HildonProgram *app = HILDON_PROGRAM (self);
1056 /* Note that use of hildon_program_set_can_hibernate()
1057 * is generally referred to as "setting the killable flag",
1058 * though hibernation does not seem equal to death.
1061 if (hildon_program_get_is_topmost (app)) {
1062 /* Prevent hibernation when the progam comes to the foreground,
1063 * because hibernation should only happen when the application
1064 * is in the background: */
1065 hildon_program_set_can_hibernate (app, FALSE);
1067 /* Remove new mail visual notifications */
1068 modest_platform_remove_new_mail_notifications (TRUE);
1070 /* Allow hibernation if the program has gone to the background: */
1072 /* However, prevent hibernation while the settings are being changed: */
1073 const gboolean hibernation_prevented =
1074 modest_window_mgr_get_hibernation_is_prevented (
1075 modest_runtime_get_window_mgr ());
1077 if (hibernation_prevented)
1078 hildon_program_set_can_hibernate (app, FALSE);
1080 /* Allow hibernation, after saving the state: */
1081 modest_osso_save_state();
1082 hildon_program_set_can_hibernate (app, TRUE);
1088 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
1090 GtkWidget *folder_win = (GtkWidget *) user_data;
1091 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1093 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
1094 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
1096 gtk_widget_show (GTK_WIDGET (priv->folder_view));
1098 /* Connect signals */
1099 connect_signals (MODEST_MAIN_WINDOW (self));
1101 /* Set account store */
1102 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
1103 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1105 /* Load previous osso state, for instance if we are being restored from
1107 modest_osso_load_state ();
1109 /* Restore window & widget settings */
1110 priv->wait_for_settings = TRUE;
1111 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
1112 priv->wait_for_settings = FALSE;
1114 /* Check if accounts exist and show the account wizard if not */
1115 gboolean accounts_exist =
1116 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1118 if (!accounts_exist) {
1119 /* This is necessary to have the main window shown behind the dialog
1120 It's an ugly hack... jschmid */
1121 gtk_widget_show_all(GTK_WIDGET(self));
1122 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
1125 GtkAction *send_receive_all;
1126 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1127 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
1128 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1129 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1130 gtk_action_set_visible (send_receive_all, g_slist_length (accounts) > 0);
1131 modest_account_mgr_free_account_names (accounts);
1132 update_menus (MODEST_MAIN_WINDOW (self));
1137 osso_display_event_cb (osso_display_state_t state,
1140 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (data);
1142 priv->display_state = state;
1144 /* Stop blinking if the screen becomes on */
1145 if (priv->display_state == OSSO_DISPLAY_ON)
1146 modest_platform_remove_new_mail_notifications (TRUE);
1150 modest_main_window_new (void)
1152 ModestMainWindow *self = NULL;
1153 ModestMainWindowPrivate *priv = NULL;
1154 ModestWindowPrivate *parent_priv = NULL;
1155 GtkWidget *folder_win = NULL;
1156 ModestDimmingRulesGroup *menu_rules_group = NULL;
1157 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1158 GtkActionGroup *action_group = NULL;
1159 GError *error = NULL;
1161 ModestConf *conf = NULL;
1162 GtkAction *action = NULL;
1163 GdkPixbuf *window_icon;
1165 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
1166 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1167 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1169 parent_priv->ui_manager = gtk_ui_manager_new();
1170 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
1172 action_group = gtk_action_group_new ("ModestMainWindowActions");
1173 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1175 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1176 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1178 /* Add common actions */
1179 gtk_action_group_add_actions (action_group,
1180 modest_action_entries,
1181 G_N_ELEMENTS (modest_action_entries),
1184 gtk_action_group_add_actions (action_group,
1185 modest_folder_view_action_entries,
1186 G_N_ELEMENTS (modest_folder_view_action_entries),
1189 gtk_action_group_add_actions (action_group,
1190 modest_header_view_action_entries,
1191 G_N_ELEMENTS (modest_header_view_action_entries),
1194 gtk_action_group_add_toggle_actions (action_group,
1195 modest_toggle_action_entries,
1196 G_N_ELEMENTS (modest_toggle_action_entries),
1199 gtk_action_group_add_toggle_actions (action_group,
1200 modest_main_window_toggle_action_entries,
1201 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
1204 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
1205 g_object_unref (action_group);
1207 /* Load the UI definition */
1208 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
1209 MODEST_UIDIR "modest-main-window-ui.xml", &error);
1210 if (error != NULL) {
1211 g_warning ("Could not merge modest-ui.xml: %s", error->message);
1212 g_error_free (error);
1216 /* Add common dimming rules */
1217 modest_dimming_rules_group_add_rules (menu_rules_group,
1218 modest_main_window_menu_dimming_entries,
1219 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
1220 MODEST_WINDOW (self));
1221 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1222 modest_main_window_toolbar_dimming_entries,
1223 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
1224 MODEST_WINDOW (self));
1226 /* Insert dimming rules group for this window */
1227 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1228 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1229 g_object_unref (menu_rules_group);
1230 g_object_unref (toolbar_rules_group);
1232 /* Add accelerators */
1233 gtk_window_add_accel_group (GTK_WINDOW (self),
1234 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
1236 /* Menubar. Update the state of some toggles */
1237 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1238 conf = modest_runtime_get_conf ();
1239 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1240 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
1241 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1242 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR, NULL));
1243 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1244 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
1245 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1246 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
1247 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
1248 gtk_widget_show (parent_priv->menubar);
1250 /* Get device name */
1251 modest_maemo_utils_get_device_name ();
1255 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
1256 if (!priv->header_view)
1257 g_printerr ("modest: cannot instantiate header view\n");
1258 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
1259 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
1260 MODEST_CONF_HEADER_VIEW_KEY);
1262 /* Other style properties of header view */
1263 g_object_set (G_OBJECT (priv->header_view),
1264 "rules-hint", FALSE,
1266 /* gtk_widget_show (priv->header_view); */
1269 priv->empty_view = create_empty_view ();
1270 gtk_widget_show (priv->empty_view);
1272 /* Create scrolled windows */
1273 folder_win = gtk_scrolled_window_new (NULL, NULL);
1274 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
1275 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
1277 GTK_POLICY_AUTOMATIC);
1278 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
1280 GTK_POLICY_AUTOMATIC);
1281 /* gtk_widget_show (priv->contents_widget); */
1284 priv->main_paned = gtk_hpaned_new ();
1285 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
1286 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
1287 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
1289 /* putting it all together... */
1290 priv->main_vbox = gtk_vbox_new (FALSE, 6);
1291 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
1292 gtk_widget_show (priv->main_vbox);
1294 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
1296 app = hildon_program_get_instance ();
1297 hildon_program_add_window (app, HILDON_WINDOW (self));
1299 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
1300 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
1302 g_signal_connect (G_OBJECT(self), "show",
1303 G_CALLBACK (modest_main_window_on_show), folder_win);
1305 /* Set window icon */
1306 window_icon = modest_platform_get_icon (MODEST_APP_ICON, MODEST_ICON_SIZE_BIG);
1308 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
1309 g_object_unref (window_icon);
1312 /* Listen for changes in the screen, we don't want to show a
1313 led pattern when the display is on for example */
1314 osso_hw_set_display_event_cb (modest_maemo_utils_get_osso_context (),
1315 osso_display_event_cb,
1318 /* Dont't restore settings here,
1319 * because it requires a gtk_widget_show(),
1320 * and we don't want to do that until later,
1321 * so that the UI is not visible for non-menu D-Bus activation.
1324 return MODEST_WINDOW(self);
1328 modest_main_window_set_style (ModestMainWindow *self,
1329 ModestMainWindowStyle style)
1331 ModestMainWindowPrivate *priv;
1332 ModestWindowPrivate *parent_priv;
1336 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1338 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1339 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1341 /* no change -> nothing to do */
1342 if (priv->style == style)
1345 /* Get toggle button and update the state if needed. This will
1346 happen only when the set_style is not invoked from the UI,
1347 for example when it's called from widget memory */
1348 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1349 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
1350 if ((active && style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) ||
1351 (!active && style == MODEST_MAIN_WINDOW_STYLE_SPLIT)) {
1352 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1353 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !active);
1354 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1357 priv->style = style;
1359 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
1361 if (!priv->wait_for_settings)
1362 modest_widget_memory_save (modest_runtime_get_conf (), G_OBJECT (priv->main_paned),
1363 MODEST_CONF_MAIN_PANED_KEY);
1364 /* Remove main paned */
1365 g_object_ref (priv->main_paned);
1366 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1368 /* Reparent the contents widget to the main vbox */
1369 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
1372 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1373 /* Remove header view */
1374 g_object_ref (priv->contents_widget);
1375 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1377 /* Reparent the main paned */
1378 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1379 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1381 g_timeout_add (500, (GSourceFunc) restore_paned_timeout_handler, self);
1385 g_return_if_reached ();
1388 /* Let header view grab the focus if it's being shown */
1389 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1390 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1392 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1395 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1398 ModestMainWindowStyle
1399 modest_main_window_get_style (ModestMainWindow *self)
1401 ModestMainWindowPrivate *priv;
1403 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1405 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1410 toolbar_resize (ModestMainWindow *self)
1412 ModestMainWindowPrivate *priv = NULL;
1413 ModestWindowPrivate *parent_priv = NULL;
1415 gint static_button_size;
1416 ModestWindowMgr *mgr;
1418 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1419 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1420 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1422 mgr = modest_runtime_get_window_mgr ();
1423 static_button_size = modest_window_mgr_get_fullscreen_mode (mgr)?118:108;
1425 if (parent_priv->toolbar) {
1426 /* left size buttons */
1427 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNew");
1428 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1429 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1430 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1431 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply");
1432 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1433 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1434 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1435 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage");
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/ToggleFolders");
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);
1444 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1445 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1446 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1447 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1448 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1449 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1450 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1451 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1459 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1461 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1462 ModestWindowPrivate *parent_priv;
1463 ModestWindowMgr *mgr;
1464 gboolean is_fullscreen;
1465 GtkAction *fs_toggle_action;
1468 mgr = modest_runtime_get_window_mgr ();
1470 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1472 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1474 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1475 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1476 if (is_fullscreen != active) {
1477 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1480 toolbar_resize (MODEST_MAIN_WINDOW (widget));
1488 modest_main_window_show_toolbar (ModestWindow *self,
1489 gboolean show_toolbar)
1491 ModestMainWindowPrivate *priv = NULL;
1492 ModestWindowPrivate *parent_priv = NULL;
1493 GtkWidget *reply_button = NULL, *menu = NULL;
1494 GtkWidget *placeholder = NULL;
1496 const gchar *action_name;
1499 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1500 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1501 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1503 /* Set optimized view status */
1504 priv->optimized_view = !show_toolbar;
1506 if (!parent_priv->toolbar) {
1507 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1509 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1511 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1512 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1513 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1514 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1515 toolbar_resize (MODEST_MAIN_WINDOW (self));
1517 /* Add ProgressBar (Transfer toolbar) */
1518 priv->progress_bar = modest_progress_bar_new ();
1519 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1520 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1521 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1522 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1523 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1525 /* Connect cancel 'clicked' signal to abort progress mode */
1526 g_signal_connect(priv->cancel_toolitem, "clicked",
1527 G_CALLBACK(cancel_progressbar),
1530 /* Add it to the observers list */
1531 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1534 hildon_window_add_toolbar (HILDON_WINDOW (self),
1535 GTK_TOOLBAR (parent_priv->toolbar));
1537 /* Set reply button tap and hold menu */
1538 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1539 "/ToolBar/ToolbarMessageReply");
1540 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1541 "/ToolbarReplyCSM");
1542 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1544 /* Set send & receive button tap and hold menu */
1545 update_menus (MODEST_MAIN_WINDOW (self));
1549 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1550 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1551 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1553 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1554 if (modest_main_window_transfer_mode_enabled (MODEST_MAIN_WINDOW(self)))
1555 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_TRANSFER);
1557 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1559 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1563 /* Update also the actions (to update the toggles in the
1564 menus), we have to do it manually because some other window
1565 of the same time could have changed it (remember that the
1566 toolbar fullscreen mode is shared by all the windows of the
1568 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
1569 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu";
1571 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu";
1573 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
1574 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
1579 on_account_inserted (TnyAccountStore *accoust_store,
1580 TnyAccount *account,
1583 /* Transport accounts and local ones (MMC and the Local
1584 folders account do now cause menu changes */
1585 if (TNY_IS_STORE_ACCOUNT (account) &&
1586 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1587 update_menus (MODEST_MAIN_WINDOW (user_data));
1591 on_default_account_changed (ModestAccountMgr* mgr,
1594 update_menus (MODEST_MAIN_WINDOW (user_data));
1598 on_account_removed (TnyAccountStore *accoust_store,
1599 TnyAccount *account,
1602 /* Transport accounts and local ones (MMC and the Local
1603 folders account do now cause menu changes */
1604 if (TNY_IS_STORE_ACCOUNT (account) &&
1605 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1606 update_menus (MODEST_MAIN_WINDOW (user_data));
1610 on_account_changed (TnyAccountStore *account_store,
1611 TnyAccount *account,
1614 ModestMainWindow *win = MODEST_MAIN_WINDOW (user_data);
1616 /* We need to refresh the details widget because it could have changed */
1617 if (modest_main_window_get_contents_style(win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS) {
1618 modest_main_window_set_contents_style (win, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1621 /* Update the menus as well, the account name could be
1622 changed. Transport accounts and local ones (MMC and the
1623 Local folders account do now cause menu changes */
1624 if (TNY_IS_STORE_ACCOUNT (account) &&
1625 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1626 update_menus (MODEST_MAIN_WINDOW (user_data));
1630 * This function manages the key events used to navigate between
1631 * header and folder views (when the window is in split view)
1634 * -------------------------------------------------
1635 * HeaderView GDK_Left Move focus to folder view
1636 * FolderView GDK_Right Move focus to header view
1638 * There is no need to scroll to selected row, the widgets will be the
1639 * responsibles of doing that (probably managing the focus-in event
1642 on_inner_widgets_key_pressed (GtkWidget *widget,
1646 ModestMainWindowPrivate *priv;
1648 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1650 /* Do nothing if we're in SIMPLE style */
1651 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1654 if (MODEST_IS_HEADER_VIEW (widget)) {
1655 if (event->keyval == GDK_Left)
1656 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1657 else if ((event->keyval == GDK_Return)||(event->keyval == GDK_KP_Enter)) {
1658 guint selected_headers = modest_header_view_count_selected_headers (MODEST_HEADER_VIEW (widget));
1659 if (selected_headers > 1) {
1660 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1664 } else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1665 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1671 set_alignment (GtkWidget *widget,
1674 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1675 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1679 create_empty_view (void)
1681 GtkLabel *label = NULL;
1682 GtkWidget *align = NULL;
1684 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1685 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1686 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1687 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1689 return GTK_WIDGET(align);
1693 * Free the returned string
1696 get_gray_color_markup (GtkWidget *styled_widget)
1698 gchar *gray_color_markup = NULL;
1699 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1700 /* Obtain the secondary text color. We need a realized widget, that's why
1701 we get styled_widget from outside */
1703 if (gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color))
1704 gray_color_markup = modest_text_utils_get_color_string (&color);
1705 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
1707 if (!gray_color_markup)
1708 gray_color_markup = g_strdup ("#BBBBBB");
1710 return gray_color_markup;
1714 * Free the returned string
1717 create_device_name_visual_string (const gchar *device_name,
1718 const gchar *gray_color_markup)
1722 /* We have to use "" to fill the %s of the translation. We can
1723 not just use the device name because the device name is
1724 shown in a different color, so it could not be included
1725 into the <span> tag */
1726 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), "");
1727 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1737 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1739 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1744 gchar *gray_color_markup;
1746 vbox = gtk_vbox_new (FALSE, 0);
1748 gray_color_markup = get_gray_color_markup (styled_widget);
1750 /* Account description: */
1751 if (modest_tny_account_is_virtual_local_folders (account)
1752 || (modest_tny_account_is_memory_card_account (account))) {
1754 /* Get device name */
1755 gchar *device_name = NULL;
1756 if (modest_tny_account_is_virtual_local_folders (account))
1757 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1758 MODEST_CONF_DEVICE_NAME, NULL);
1760 device_name = g_strdup (tny_account_get_name (account));
1762 label = create_device_name_visual_string ((const gchar *) device_name,
1763 (const gchar *) gray_color_markup);
1764 label_w = gtk_label_new (NULL);
1765 gtk_label_set_markup (GTK_LABEL (label_w), label);
1766 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1767 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1768 g_free (device_name);
1771 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1772 gtk_box_pack_start (GTK_BOX (vbox),
1773 gtk_label_new (tny_account_get_name (account)),
1776 /* Other accounts, such as IMAP and POP: */
1781 /* Put proto in uppercase */
1782 proto = g_string_new (tny_account_get_proto (account));
1783 proto = g_string_ascii_up (proto);
1785 /* note: mcen_fi_localroot_description is something like "%s account"
1786 * however, we should display "%s account: %s"... therefore, ugly tmp */
1787 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1788 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1789 gray_color_markup, tmp, tny_account_get_name (account));
1792 label_w = gtk_label_new (NULL);
1793 gtk_label_set_markup (GTK_LABEL (label_w), label);
1794 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1795 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1796 g_string_free (proto, TRUE);
1802 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1803 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1804 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1805 modest_tny_folder_store_get_message_count (folder_store));
1806 label_w = gtk_label_new (NULL);
1807 gtk_label_set_markup (GTK_LABEL (label_w), label);
1808 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1809 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1813 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1815 _("mcen_fi_rootfolder_folders"),
1816 modest_tny_folder_store_get_folder_count (folder_store));
1817 label_w = gtk_label_new (NULL);
1818 gtk_label_set_markup (GTK_LABEL (label_w), label);
1819 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1820 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1824 if (modest_tny_account_is_virtual_local_folders (account)
1825 || modest_tny_account_is_memory_card_account (account)) {
1827 gchar *size = modest_text_utils_get_display_size (
1828 modest_tny_folder_store_get_local_size (folder_store));
1830 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1831 gray_color_markup, _("mcen_fi_rootfolder_size"),
1835 label_w = gtk_label_new (NULL);
1836 gtk_label_set_markup (GTK_LABEL (label_w), label);
1837 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1838 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1840 } else if (TNY_IS_ACCOUNT(folder_store)) {
1841 TnyAccount *account = TNY_ACCOUNT(folder_store);
1843 time_t last_updated;
1844 const gchar *last_updated_string;
1845 /* Get last updated from configuration */
1846 last_updated = modest_account_mgr_get_last_updated (modest_runtime_get_account_mgr (),
1847 tny_account_get_id (account));
1849 if (last_updated > 0)
1850 last_updated_string = modest_text_utils_get_display_date(last_updated);
1852 last_updated_string = g_strdup (_("mcen_va_never"));
1854 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1855 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1856 label_w = gtk_label_new (NULL);
1857 gtk_label_set_markup (GTK_LABEL (label_w), label);
1858 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1859 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1863 g_free (gray_color_markup);
1866 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1872 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1874 ModestMainWindowPrivate *priv = NULL;
1876 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1878 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1880 return priv->send_receive_in_progress;
1884 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1886 GtkAction *action = NULL;
1887 GtkWidget *widget = NULL;
1888 ModestMainWindowPrivate *priv = NULL;
1890 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1891 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1893 priv->send_receive_in_progress = TRUE;
1895 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1896 gtk_action_set_sensitive (action, FALSE);
1897 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1898 /* gtk_action_set_sensitive (action, FALSE); */
1899 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1900 gtk_widget_set_sensitive (widget, FALSE);
1904 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1906 GtkAction *action = NULL;
1907 GtkWidget *widget = NULL;
1908 ModestMainWindowPrivate *priv = NULL;
1910 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1911 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1913 priv->send_receive_in_progress = FALSE;
1915 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1916 gtk_action_set_sensitive (action, TRUE);
1917 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1918 /* gtk_action_set_sensitive (action, TRUE); */
1919 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1920 gtk_widget_set_sensitive (widget, TRUE);
1925 on_msg_count_changed (ModestHeaderView *header_view,
1927 TnyFolderChange *change,
1928 ModestMainWindow *main_window)
1930 gboolean refilter = FALSE;
1931 gboolean folder_empty = FALSE;
1932 gboolean all_marked_as_deleted = FALSE;
1933 ModestMainWindowPrivate *priv;
1935 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1936 g_return_if_fail (TNY_IS_FOLDER(folder));
1937 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
1939 if (change != NULL) {
1940 TnyFolderChangeChanged changed;
1942 changed = tny_folder_change_get_changed (change);
1943 /* If something changes */
1944 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1945 folder_empty = (((guint) tny_folder_change_get_new_all_count (change)) == 0);
1947 folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1949 /* Play a sound (if configured) and make the LED blink */
1950 if (changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS) {
1951 modest_platform_push_email_notification ();
1954 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_EXPUNGED_HEADERS)
1957 folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1960 /* Check if all messages are marked to be deleted */
1961 all_marked_as_deleted = modest_header_view_is_empty (header_view);
1962 folder_empty = folder_empty || all_marked_as_deleted;
1964 /* Set contents style of headers view */
1966 modest_main_window_set_contents_style (main_window,
1967 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1968 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1970 modest_main_window_set_contents_style (main_window,
1971 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1975 modest_header_view_refilter (header_view);
1980 modest_main_window_set_contents_style (ModestMainWindow *self,
1981 ModestMainWindowContentsStyle style)
1983 ModestMainWindowPrivate *priv;
1985 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1987 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1989 /* We allow to set the same content style than the previously
1990 set if there are details, because it could happen when we're
1991 selecting different accounts consecutively */
1992 if ((priv->contents_style == style) &&
1993 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1996 /* Remove previous child. Delete it if it was an account
1998 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
2000 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2001 g_object_ref (content);
2002 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
2003 g_object_ref (priv->empty_view);
2004 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
2007 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
2010 priv->contents_style = style;
2012 switch (priv->contents_style) {
2013 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
2014 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
2015 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2018 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
2020 /* if we're started without main win, there may not be a folder
2021 * view. this fixes a GLib-Critical */
2022 if (priv->folder_view) {
2023 TnyFolderStore *selected_folderstore =
2024 modest_folder_view_get_selected (priv->folder_view);
2025 if (TNY_IS_ACCOUNT (selected_folderstore)) {
2026 priv->details_widget = create_details_widget (GTK_WIDGET (self),
2027 TNY_ACCOUNT (selected_folderstore));
2029 wrap_in_scrolled_window (priv->contents_widget,
2030 priv->details_widget);
2032 g_object_unref (selected_folderstore);
2033 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2038 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
2039 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
2040 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2044 g_return_if_reached ();
2048 gtk_widget_show_all (priv->contents_widget);
2051 ModestMainWindowContentsStyle
2052 modest_main_window_get_contents_style (ModestMainWindow *self)
2054 ModestMainWindowPrivate *priv;
2056 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
2058 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2059 return priv->contents_style;
2064 on_configuration_key_changed (ModestConf* conf,
2066 ModestConfEvent event,
2067 ModestConfNotificationId id,
2068 ModestMainWindow *self)
2070 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2071 TnyAccount *account = NULL;
2073 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
2076 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
2079 if (priv->folder_view)
2080 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
2082 if (account && TNY_IS_ACCOUNT (account) &&
2083 strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID) == 0) {
2086 const gchar *device_name;
2087 gchar *new_text, *gray_color_markup;
2090 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
2091 label = GTK_LABEL (children->data);
2093 device_name = modest_conf_get_string (modest_runtime_get_conf(),
2094 MODEST_CONF_DEVICE_NAME, NULL);
2096 gray_color_markup = get_gray_color_markup (GTK_WIDGET (self));
2097 new_text = create_device_name_visual_string (device_name, gray_color_markup);
2099 gtk_label_set_markup (label, new_text);
2100 gtk_widget_show (GTK_WIDGET (label));
2102 g_free (gray_color_markup);
2104 g_list_free (children);
2106 g_object_unref (account);
2110 set_toolbar_transfer_mode (ModestMainWindow *self)
2112 ModestMainWindowPrivate *priv = NULL;
2114 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2116 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2118 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
2120 if (priv->progress_bar_timeout > 0) {
2121 g_source_remove (priv->progress_bar_timeout);
2122 priv->progress_bar_timeout = 0;
2129 set_toolbar_mode (ModestMainWindow *self,
2130 ModestToolBarModes mode)
2132 ModestWindowPrivate *parent_priv = NULL;
2133 ModestMainWindowPrivate *priv = NULL;
2134 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
2136 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2138 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2139 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2141 /* In case this was called before the toolbar exists: */
2142 if (!(parent_priv->toolbar))
2145 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
2147 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
2148 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
2149 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
2151 /* Sets current toolbar mode */
2152 priv->current_toolbar_mode = mode;
2154 /* Checks the dimming rules */
2155 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2157 /* Show and hide toolbar items */
2159 case TOOLBAR_MODE_NORMAL:
2161 gtk_action_set_visible (sort_action, TRUE);
2163 gtk_action_set_visible (refresh_action, TRUE);
2164 if (priv->progress_toolitem) {
2165 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
2166 gtk_widget_hide (priv->progress_toolitem);
2168 if (priv->progress_bar)
2169 gtk_widget_hide (priv->progress_bar);
2172 gtk_action_set_visible (cancel_action, FALSE);
2174 /* Hide toolbar if optimized view is enabled */
2175 if (priv->optimized_view)
2176 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
2178 case TOOLBAR_MODE_TRANSFER:
2180 gtk_action_set_visible (sort_action, FALSE);
2182 gtk_action_set_visible (refresh_action, FALSE);
2184 gtk_action_set_visible (cancel_action, TRUE);
2185 if (priv->progress_bar)
2186 gtk_widget_show (priv->progress_bar);
2187 if (priv->progress_toolitem) {
2188 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
2189 gtk_widget_show (priv->progress_toolitem);
2192 /* Show toolbar if it's hiden (optimized view ) */
2193 if (priv->optimized_view)
2194 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2197 g_return_if_reached ();
2202 modest_main_window_transfer_mode_enabled (ModestMainWindow *self)
2204 ModestMainWindowPrivate *priv;
2206 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2207 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2209 return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
2213 cancel_progressbar (GtkToolButton *toolbutton,
2214 ModestMainWindow *self)
2217 ModestMainWindowPrivate *priv;
2219 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2221 /* Get operation observers and cancel all the operations */
2222 tmp = priv->progress_widgets;
2224 modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2225 tmp=g_slist_next(tmp);
2230 observers_empty (ModestMainWindow *self)
2233 ModestMainWindowPrivate *priv;
2234 gboolean is_empty = TRUE;
2235 guint pending_ops = 0;
2237 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2238 tmp = priv->progress_widgets;
2240 /* Check all observers */
2241 while (tmp && is_empty) {
2242 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2243 is_empty = pending_ops == 0;
2245 tmp = g_slist_next(tmp);
2253 * Gets the toolbar mode needed for each mail operation. It stores in
2254 * @mode_changed if the toolbar mode has changed or not
2256 static ModestToolBarModes
2257 get_toolbar_mode_from_mail_operation (ModestMainWindow *self,
2258 ModestMailOperation *mail_op,
2259 gboolean *mode_changed)
2261 ModestToolBarModes mode;
2262 ModestMainWindowPrivate *priv;
2264 *mode_changed = FALSE;
2265 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2267 /* Get toolbar mode from operation id*/
2268 switch (modest_mail_operation_get_type_operation (mail_op)) {
2269 case MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE:
2270 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
2271 case MODEST_MAIL_OPERATION_TYPE_OPEN:
2272 mode = TOOLBAR_MODE_TRANSFER;
2273 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
2274 *mode_changed = TRUE;
2277 mode = TOOLBAR_MODE_NORMAL;
2283 on_mail_operation_started (ModestMailOperation *mail_op,
2286 ModestMainWindow *self;
2287 ModestMailOperationTypeOperation op_type;
2288 ModestMainWindowPrivate *priv;
2289 ModestToolBarModes mode;
2291 gboolean mode_changed = FALSE;
2292 TnyAccount *account;
2294 self = MODEST_MAIN_WINDOW (user_data);
2295 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2297 /* Do not show progress for receiving operations if the
2298 account is the local account or the MMC one */
2299 op_type = modest_mail_operation_get_type_operation (mail_op);
2300 account = modest_mail_operation_get_account (mail_op);
2301 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2304 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2305 modest_tny_account_is_memory_card_account (account));
2307 g_object_unref (account);
2311 /* Show information banner. Remove old timeout */
2312 if (priv->retrieving_banner_timeout > 0) {
2313 g_source_remove (priv->retrieving_banner_timeout);
2314 priv->retrieving_banner_timeout = 0;
2316 /* Create a new timeout */
2317 priv->retrieving_banner_timeout =
2318 g_timeout_add (2000, show_retrieving_banner, self);
2320 g_object_unref (account);
2322 /* Get toolbar mode from operation id*/
2323 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2325 /* Add operation observers and change toolbar if neccessary*/
2326 tmp = priv->progress_widgets;
2327 if (mode == TOOLBAR_MODE_TRANSFER) {
2329 GObject *source = modest_mail_operation_get_source(mail_op);
2330 if (G_OBJECT (self) == source) {
2331 set_toolbar_transfer_mode(self);
2333 g_object_unref (source);
2337 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2339 tmp = g_slist_next (tmp);
2343 /* Update the main menu as well, we need to explicitely do
2344 this in order to enable/disable accelerators */
2345 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (self));
2349 on_mail_operation_finished (ModestMailOperation *mail_op,
2352 ModestToolBarModes mode;
2353 ModestMailOperationTypeOperation op_type;
2355 ModestMainWindow *self;
2356 gboolean mode_changed;
2357 TnyAccount *account;
2358 ModestMainWindowPrivate *priv;
2360 self = MODEST_MAIN_WINDOW (user_data);
2361 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2363 /* The mail operation was not added to the progress objects if
2364 the account was the local account or the MMC one */
2365 op_type = modest_mail_operation_get_type_operation (mail_op);
2366 account = modest_mail_operation_get_account (mail_op);
2367 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2370 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2371 modest_tny_account_is_memory_card_account (account));
2373 g_object_unref (account);
2377 /* Remove old timeout */
2378 if (priv->retrieving_banner_timeout > 0) {
2379 g_source_remove (priv->retrieving_banner_timeout);
2380 priv->retrieving_banner_timeout = 0;
2383 /* Remove the banner if exists */
2384 if (priv->retrieving_banner) {
2385 gtk_widget_destroy (priv->retrieving_banner);
2386 priv->retrieving_banner = NULL;
2389 g_object_unref (account);
2391 /* Get toolbar mode from operation id*/
2392 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2394 /* Change toolbar mode */
2395 tmp = priv->progress_widgets;
2396 if (mode == TOOLBAR_MODE_TRANSFER) {
2398 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2400 tmp = g_slist_next (tmp);
2403 /* If no more operations are being observed, NORMAL mode is enabled again */
2404 if (observers_empty (self)) {
2405 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
2411 on_queue_changed (ModestMailOperationQueue *queue,
2412 ModestMailOperation *mail_op,
2413 ModestMailOperationQueueNotification type,
2414 ModestMainWindow *self)
2416 ModestMainWindowPrivate *priv;
2418 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2420 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
2421 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2423 "operation-started",
2424 G_CALLBACK (on_mail_operation_started),
2426 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2428 "operation-finished",
2429 G_CALLBACK (on_mail_operation_finished),
2431 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
2432 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2434 "operation-started");
2435 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2437 "operation-finished");
2442 set_account_visible(ModestMainWindow *self, const gchar *acc_name)
2444 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2446 ModestAccountMgr *mgr;
2447 ModestAccountSettings *settings;
2448 ModestServerAccountSettings *store_settings = NULL;
2450 /* Get account data */
2451 mgr = modest_runtime_get_account_mgr ();
2452 settings = modest_account_mgr_load_account_settings (mgr, acc_name);
2454 store_settings = modest_account_settings_get_store_settings (settings);
2456 /* Set the new visible & active account */
2457 if (settings && (modest_server_account_settings_get_account_name (store_settings)!= NULL)) {
2458 const gchar *account_name;
2460 account_name = modest_account_settings_get_account_name (settings);
2462 modest_folder_view_set_account_id_of_visible_server_account
2464 modest_server_account_settings_get_account_name (store_settings));
2465 modest_window_set_active_account (MODEST_WINDOW (self), account_name);
2466 action = gtk_action_group_get_action (priv->view_additions_group, account_name);
2467 if (action != NULL) {
2468 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2469 modest_utils_toggle_action_set_active_block_notify (
2470 GTK_TOGGLE_ACTION (action),
2476 modest_folder_view_select_first_inbox_or_local (priv->folder_view);
2481 g_object_unref (store_settings);
2482 g_object_unref (settings);
2486 /* Make sure that at least one account is "viewed": */
2488 set_at_least_one_account_visible(ModestMainWindow *self)
2490 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2491 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2493 if (!(priv->folder_view)) {
2494 /* It is too early to do this. */
2498 const gchar *active_server_account_name =
2499 modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);
2501 if (!active_server_account_name ||
2502 !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
2504 gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
2505 gchar* default_modest_name = modest_account_mgr_get_default_account (account_mgr);
2506 if (default_modest_name) {
2507 set_account_visible (self, default_modest_name);
2508 } else if (first_modest_name) {
2509 set_account_visible (self, first_modest_name);
2511 g_free (first_modest_name);
2512 g_free (default_modest_name);
2517 on_show_account_action_toggled (GtkToggleAction *action,
2520 ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
2522 const gchar *acc_name = gtk_action_get_name (GTK_ACTION (action));
2523 if (gtk_toggle_action_get_active (action))
2524 set_account_visible (self, acc_name);
2528 refresh_account (const gchar *account_name)
2532 /* win must already exists here, obviously */
2533 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
2536 g_warning ("%s: BUG: no main window!", __FUNCTION__);
2540 /* If account_name == NULL, we must update all (option All) */
2542 modest_ui_actions_do_send_receive_all (win, TRUE);
2544 modest_ui_actions_do_send_receive (account_name, TRUE, win);
2549 on_refresh_account_action_activated (GtkAction *action,
2552 refresh_account ((const gchar*) user_data);
2556 on_send_receive_csm_activated (GtkMenuItem *item,
2559 refresh_account ((const gchar*) user_data);
2563 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2565 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2567 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2573 on_folder_view_focus_in (GtkWidget *widget, GdkEventFocus *event, gpointer userdata)
2575 ModestMainWindow *main_window = NULL;
2577 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2578 main_window = MODEST_MAIN_WINDOW (userdata);
2580 /* Update toolbar dimming state */
2581 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2587 on_header_view_focus_in (GtkWidget *widget,
2588 GdkEventFocus *event,
2591 ModestMainWindow *main_window = NULL;
2593 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2595 main_window = MODEST_MAIN_WINDOW (userdata);
2597 /* Update toolbar dimming state */
2598 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2604 on_folder_selection_changed (ModestFolderView *folder_view,
2605 TnyFolderStore *folder_store,
2607 ModestMainWindow *main_window)
2609 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2610 GtkAction *action = NULL;
2611 gboolean show_reply = TRUE;
2612 gboolean show_forward = TRUE;
2613 gboolean show_cancel_send = FALSE;
2614 gboolean show_clipboard = TRUE;
2615 gboolean show_delete = TRUE;
2618 if (TNY_IS_ACCOUNT (folder_store)) {
2619 show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2620 } else if (TNY_IS_FOLDER (folder_store)) {
2621 if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2622 TnyFolderType folder_type = modest_tny_folder_get_local_or_mmc_folder_type (
2623 TNY_FOLDER (folder_store));
2624 switch (folder_type) {
2625 case TNY_FOLDER_TYPE_DRAFTS:
2626 show_clipboard = show_delete = TRUE;
2627 show_reply = show_forward = show_cancel_send = FALSE;
2629 case TNY_FOLDER_TYPE_SENT:
2630 show_forward = show_clipboard = show_delete = TRUE;
2631 show_reply = show_cancel_send = FALSE;
2633 case TNY_FOLDER_TYPE_OUTBOX:
2634 show_clipboard = show_delete = show_cancel_send = TRUE;
2635 show_reply = show_forward = FALSE;
2637 case TNY_FOLDER_TYPE_INVALID:
2638 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
2641 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2642 show_cancel_send = FALSE;
2645 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2646 show_cancel_send = FALSE;
2651 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2652 gtk_action_set_visible (action, show_reply);
2653 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2654 gtk_action_set_visible (action, show_reply);
2655 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2656 gtk_action_set_visible (action, show_forward);
2657 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2658 gtk_action_set_visible (action, show_cancel_send);
2659 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2660 gtk_action_set_visible (action, show_delete);
2662 /* We finally call to the ui actions handler, after updating properly
2663 * the header view CSM */
2664 modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2668 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2669 GtkTreeModel *model,
2670 GtkTreeRowReference *row_reference,
2671 ModestMainWindow *self)
2673 ModestMainWindowPrivate *priv = NULL;
2674 GtkTreeModel *header_model = NULL;
2675 GtkTreePath *path = NULL;
2677 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
2678 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2679 g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2681 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2682 header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2684 /* Do nothing if we changed the folder in the main view */
2685 if (header_model != model)
2688 /* Select the message in the header view */
2689 path = gtk_tree_row_reference_get_path (row_reference);
2690 gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->header_view),
2692 gtk_tree_path_free (path);
2698 show_updating_banner (gpointer user_data)
2700 ModestMainWindowPrivate *priv = NULL;
2702 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2704 if (priv->updating_banner == NULL) {
2706 /* We're outside the main lock */
2707 gdk_threads_enter ();
2708 priv->updating_banner =
2709 modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2710 _CS ("ckdg_pb_updating"));
2711 gdk_threads_leave ();
2714 /* Remove timeout */
2715 priv->updating_banner_timeout = 0;
2720 * We use this function to show/hide a progress banner showing
2721 * "Updating" while the header view is being filled. We're not showing
2722 * it unless the update takes more than 2 seconds
2724 * If starting = TRUE then the refresh is starting, otherwise it means
2725 * that is has just finished
2728 on_updating_msg_list (ModestHeaderView *header_view,
2732 ModestMainWindowPrivate *priv = NULL;
2734 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2736 /* Remove old timeout */
2737 if (priv->updating_banner_timeout > 0) {
2738 g_source_remove (priv->updating_banner_timeout);
2739 priv->updating_banner_timeout = 0;
2742 /* Create a new timeout */
2744 priv->updating_banner_timeout =
2745 g_timeout_add (2000, show_updating_banner, user_data);
2747 /* Remove the banner if exists */
2748 if (priv->updating_banner) {
2749 gtk_widget_destroy (priv->updating_banner);
2750 priv->updating_banner = NULL;
2756 modest_main_window_screen_is_on (ModestMainWindow *self)
2758 ModestMainWindowPrivate *priv = NULL;
2760 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(self), FALSE);
2762 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2764 return (priv->display_state == OSSO_DISPLAY_ON) ? TRUE : FALSE;
2768 show_retrieving_banner (gpointer user_data)
2770 ModestMainWindowPrivate *priv = NULL;
2772 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2774 if (priv->retrieving_banner == NULL) {
2776 /* We're outside the main lock */
2777 gdk_threads_enter ();
2778 priv->retrieving_banner =
2779 modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2780 _("mcen_ib_getting_items"));
2781 gdk_threads_leave ();
2784 /* Remove timeout */
2785 priv->retrieving_banner_timeout = 0;