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 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
180 struct _ModestMainWindowPrivate {
181 GtkWidget *msg_paned;
182 GtkWidget *main_paned;
183 GtkWidget *main_vbox;
184 GtkWidget *contents_widget;
185 GtkWidget *empty_view;
187 /* Progress observers */
188 GtkWidget *progress_bar;
189 GSList *progress_widgets;
192 GtkWidget *progress_toolitem;
193 GtkWidget *cancel_toolitem;
194 GtkWidget *sort_toolitem;
195 GtkWidget *refresh_toolitem;
196 ModestToolBarModes current_toolbar_mode;
198 /* Merge ids used to add/remove accounts to the ViewMenu*/
199 GByteArray *merge_ids;
200 GtkActionGroup *view_additions_group;
202 /* On-demand widgets */
203 GtkWidget *accounts_popup;
204 GtkWidget *details_widget;
206 /* Optimized view enabled */
207 gboolean optimized_view;
209 /* Optimized view enabled */
210 gboolean send_receive_in_progress;
212 ModestHeaderView *header_view;
213 ModestFolderView *folder_view;
215 ModestMainWindowStyle style;
216 ModestMainWindowContentsStyle contents_style;
217 gboolean wait_for_settings;
219 guint progress_bar_timeout;
220 guint restore_paned_timeout;
222 /* Signal handler UIDs */
223 GList *queue_err_signals;
226 /* "Updating" banner for header view */
227 GtkWidget *updating_banner;
228 guint updating_banner_timeout;
231 osso_display_state_t display_state;
233 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
234 MODEST_TYPE_MAIN_WINDOW, \
235 ModestMainWindowPrivate))
237 typedef struct _GetMsgAsyncHelper {
238 ModestMainWindowPrivate *main_window_private;
240 ModestTnyMsgReplyType reply_type;
241 ModestTnyMsgForwardType forward_type;
248 static GtkWindowClass *parent_class = NULL;
251 /* Private actions */
252 /* This is the context sensitive menu: */
253 static const GtkActionEntry modest_folder_view_action_entries [] = {
255 /* Folder View CSM actions */
256 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
257 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
258 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_paste)},
259 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
260 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_search_messages) },
261 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
264 static const GtkActionEntry modest_header_view_action_entries [] = {
266 /* Header View CSM actions */
267 { "HeaderViewCSMOpen", NULL, N_("mcen_me_inbox_open"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_open) },
268 { "HeaderViewCSMReply", NULL, N_("mcen_me_inbox_reply"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply) },
269 { "HeaderViewCSMReplyAll", NULL, N_("mcen_me_inbox_replytoall"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply_all) },
270 { "HeaderViewCSMForward", NULL, N_("mcen_me_inbox_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_forward) },
271 { "HeaderViewCSMCut", NULL, N_("mcen_me_inbox_cut"), "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
272 { "HeaderViewCSMCopy", NULL, N_("mcen_me_inbox_copy"), "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
273 { "HeaderViewCSMPaste", NULL, N_("mcen_me_inbox_paste"), "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
274 { "HeaderViewCSMDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_message) },
275 { "HeaderViewCSMCancelSending", NULL, N_("mcen_me_outbox_cancelsend"), NULL, NULL, G_CALLBACK (modest_ui_actions_cancel_send) },
276 { "HeaderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
279 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
280 { "ToggleFolders", MODEST_STOCK_SPLIT_VIEW, N_("mcen_me_inbox_hidefolders"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), TRUE },
283 /************************************************************************/
286 modest_main_window_get_type (void)
288 static GType my_type = 0;
290 static const GTypeInfo my_info = {
291 sizeof(ModestMainWindowClass),
292 NULL, /* base init */
293 NULL, /* base finalize */
294 (GClassInitFunc) modest_main_window_class_init,
295 NULL, /* class finalize */
296 NULL, /* class data */
297 sizeof(ModestMainWindow),
299 (GInstanceInitFunc) modest_main_window_init,
302 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
310 modest_main_window_class_init (ModestMainWindowClass *klass)
312 GObjectClass *gobject_class;
313 gobject_class = (GObjectClass*) klass;
314 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
316 parent_class = g_type_class_peek_parent (klass);
317 gobject_class->finalize = modest_main_window_finalize;
319 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
321 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
322 modest_window_class->save_state_func = save_state;
323 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
324 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
325 modest_window_class->disconnect_signals_func = modest_main_window_disconnect_signals;
329 modest_main_window_init (ModestMainWindow *obj)
331 ModestMainWindowPrivate *priv;
333 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
335 priv->queue_err_signals = NULL;
336 priv->msg_paned = NULL;
337 priv->main_paned = NULL;
338 priv->main_vbox = NULL;
339 priv->header_view = NULL;
340 priv->folder_view = NULL;
341 priv->contents_widget = NULL;
342 priv->accounts_popup = NULL;
343 priv->details_widget = NULL;
344 priv->empty_view = NULL;
345 priv->progress_widgets = NULL;
346 priv->progress_bar = NULL;
347 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
348 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
349 priv->wait_for_settings = TRUE;
350 priv->contents_style = -1; /* invalid contents style. We need this to select it for the first time */
351 priv->merge_ids = NULL;
352 priv->optimized_view = FALSE;
353 priv->send_receive_in_progress = FALSE;
354 priv->progress_bar_timeout = 0;
355 priv->restore_paned_timeout = 0;
356 priv->sighandlers = NULL;
357 priv->updating_banner = NULL;
358 priv->updating_banner_timeout = 0;
359 priv->display_state = OSSO_DISPLAY_ON;
361 modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(),
363 "applications_email_mainview");
367 modest_main_window_finalize (GObject *obj)
369 ModestMainWindowPrivate *priv;
371 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
373 /* Sanity check: shouldn't be needed, the window mgr should
374 call this function before */
375 modest_main_window_disconnect_signals (MODEST_WINDOW (obj));
376 modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
378 g_slist_free (priv->progress_widgets);
380 g_byte_array_free (priv->merge_ids, TRUE);
382 if (priv->progress_bar_timeout > 0) {
383 g_source_remove (priv->progress_bar_timeout);
384 priv->progress_bar_timeout = 0;
387 if (priv->updating_banner_timeout > 0) {
388 g_source_remove (priv->updating_banner_timeout);
389 priv->updating_banner_timeout = 0;
392 if (priv->updating_banner) {
393 gtk_widget_destroy (priv->updating_banner);
394 priv->updating_banner = NULL;
397 if (priv->restore_paned_timeout > 0) {
398 g_source_remove (priv->restore_paned_timeout);
399 priv->restore_paned_timeout = 0;
402 G_OBJECT_CLASS(parent_class)->finalize (obj);
406 modest_main_window_get_child_widget (ModestMainWindow *self,
407 ModestMainWindowWidgetType widget_type)
409 ModestMainWindowPrivate *priv;
412 g_return_val_if_fail (self && MODEST_IS_MAIN_WINDOW(self), NULL);
413 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_MAIN_WINDOW_WIDGET_TYPE_NUM,
416 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
418 switch (widget_type) {
419 case MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW:
420 widget = (GtkWidget*)priv->header_view; break;
421 case MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW:
422 widget = (GtkWidget*)priv->folder_view; break;
427 return widget ? GTK_WIDGET(widget) : NULL;
431 restore_paned_timeout_handler (gpointer *data)
433 ModestMainWindow *main_window = MODEST_MAIN_WINDOW (data);
434 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
437 /* Timeouts are outside the main lock */
438 gdk_threads_enter ();
439 if (GTK_WIDGET_VISIBLE (main_window)) {
440 conf = modest_runtime_get_conf ();
441 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
442 MODEST_CONF_MAIN_PANED_KEY);
444 gdk_threads_leave ();
451 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
454 ModestMainWindowPrivate *priv;
456 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
458 conf = modest_runtime_get_conf ();
460 modest_widget_memory_restore (conf, G_OBJECT(self),
461 MODEST_CONF_MAIN_WINDOW_KEY);
463 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
464 MODEST_CONF_HEADER_VIEW_KEY);
466 if (do_folder_view_too)
467 modest_widget_memory_restore (conf, G_OBJECT(priv->folder_view),
468 MODEST_CONF_FOLDER_VIEW_KEY);
470 /* modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned), */
471 /* MODEST_CONF_MAIN_PANED_KEY); */
473 g_timeout_add (250, (GSourceFunc) restore_paned_timeout_handler, self);
475 /* We need to force a redraw here in order to get the right
476 position of the horizontal paned separator */
477 gtk_widget_show (GTK_WIDGET (self));
482 save_state (ModestWindow *window)
485 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
486 ModestMainWindowPrivate *priv;
488 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
489 conf = modest_runtime_get_conf ();
491 modest_widget_memory_save (conf,G_OBJECT(self),
492 MODEST_CONF_MAIN_WINDOW_KEY);
493 /* Only save main paned position if we're in split mode */
494 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SPLIT)
495 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
496 MODEST_CONF_MAIN_PANED_KEY);
497 modest_widget_memory_save (conf, G_OBJECT(priv->folder_view),
498 MODEST_CONF_FOLDER_VIEW_KEY);
502 compare_display_names (ModestAccountSettings *a,
503 ModestAccountSettings *b)
505 return strcmp (modest_account_settings_get_display_name (a),
506 modest_account_settings_get_display_name (b));
509 /* We use this function to prevent the send&receive CSM to be shown
510 when there are less than two account */
512 tap_and_hold_query_cb (GtkWidget *widget, GdkEvent *event)
518 update_menus (ModestMainWindow* self)
520 GSList *account_names, *iter, *accounts;
521 ModestMainWindowPrivate *priv;
522 ModestWindowPrivate *parent_priv;
523 ModestAccountMgr *mgr;
524 gint i, num_accounts;
526 gchar *default_account;
527 const gchar *active_account_name;
528 GtkWidget *send_receive_button, *item;
529 GtkAction *send_receive_all = NULL;
532 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
533 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
535 /* Get enabled account IDs */
536 mgr = modest_runtime_get_account_mgr ();
537 account_names = modest_account_mgr_account_names (mgr, TRUE);
538 iter = account_names;
542 ModestAccountSettings *settings =
543 modest_account_mgr_load_account_settings (mgr, (gchar*) iter->data);
544 accounts = g_slist_prepend (accounts, settings);
548 modest_account_mgr_free_account_names (account_names);
549 account_names = NULL;
551 /* Order the list of accounts by its display name */
552 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
553 num_accounts = g_slist_length (accounts);
555 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
556 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
557 gtk_action_set_visible (send_receive_all, num_accounts > 0);
559 /* Delete old send&receive popup items. We can not just do a
560 menu_detach because it does not work well with
562 if (priv->accounts_popup)
563 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
564 (GtkCallback) gtk_widget_destroy, NULL);
566 /* Delete old entries in the View menu. Do not free groups, it
568 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
570 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
571 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
572 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
573 GTK_ACTION_GROUP (groups->data));
576 if (priv->merge_ids) {
577 for (i = 0; i < priv->merge_ids->len; i++)
578 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
579 g_byte_array_free (priv->merge_ids, TRUE);
581 /* We need to call this in order to ensure
582 that the new actions are added in the right
583 order (alphabetical) */
584 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
586 groups = g_list_next (groups);
588 priv->merge_ids = g_byte_array_sized_new (num_accounts);
590 /* Get send receive button */
591 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
592 "/ToolBar/ToolbarSendReceive");
594 /* Create the menu */
595 if (num_accounts > 1) {
596 if (!priv->accounts_popup)
597 priv->accounts_popup = gtk_menu_new ();
598 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
599 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
600 g_signal_connect (G_OBJECT (item),
602 G_CALLBACK (on_send_receive_csm_activated),
604 item = gtk_separator_menu_item_new ();
605 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
608 /* Create a new action group */
609 default_account = modest_account_mgr_get_default_account (mgr);
610 active_account_name = modest_window_get_active_account (MODEST_WINDOW (self));
612 if (!active_account_name)
613 modest_window_set_active_account (MODEST_WINDOW (self), default_account);
615 priv->view_additions_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
617 for (i = 0; i < num_accounts; i++) {
618 gchar *display_name = NULL;
619 const gchar *account_name;
620 ModestAccountSettings *settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
623 g_warning ("%s: BUG: account_data == NULL", __FUNCTION__);
626 account_name = modest_account_settings_get_account_name (settings);
628 if (default_account && account_name &&
629 !(strcmp (default_account, account_name) == 0)) {
630 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
631 modest_account_settings_get_display_name (settings));
633 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
634 modest_account_settings_get_display_name (settings));
637 /* Create action and add it to the action group. The
638 action name must be the account name, this way we
639 could know in the handlers the account to show */
640 if (settings && account_name) {
641 gchar* item_name, *refresh_action_name;
643 GtkAction *view_account_action, *refresh_account_action;
645 view_account_action = GTK_ACTION (gtk_radio_action_new (account_name,
646 display_name, NULL, NULL, 0));
647 gtk_action_group_add_action (priv->view_additions_group, view_account_action);
648 gtk_radio_action_set_group (GTK_RADIO_ACTION (view_account_action), radio_group);
649 radio_group = gtk_radio_action_get_group (GTK_RADIO_ACTION (view_account_action));
651 if (active_account_name) {
652 if (active_account_name && account_name &&
653 (strcmp (active_account_name, account_name) == 0)) {
654 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (view_account_action), TRUE);
658 /* Add ui from account data. We allow 2^9-1 account
659 changes in a single execution because we're
660 downcasting the guint to a guint8 in order to use a
661 GByteArray. It should be enough. */
662 item_name = g_strconcat (account_name, "Menu", NULL);
663 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
664 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
665 gtk_ui_manager_add_ui (parent_priv->ui_manager,
667 "/MenuBar/ViewMenu/ViewMenuAdditions",
670 GTK_UI_MANAGER_MENUITEM,
673 /* Connect the action signal "activate" */
674 g_signal_connect_after (G_OBJECT (view_account_action),
676 G_CALLBACK (on_show_account_action_toggled),
679 /* Create the items for the Tools->Send&Receive submenu */
680 refresh_action_name = g_strconcat ("SendReceive", account_name, NULL);
681 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
682 display_name, NULL, NULL);
683 gtk_action_group_add_action (priv->view_additions_group, refresh_account_action);
685 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
686 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
687 gtk_ui_manager_add_ui (parent_priv->ui_manager,
689 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
692 GTK_UI_MANAGER_MENUITEM,
694 g_free (refresh_action_name);
696 g_signal_connect_data (G_OBJECT (refresh_account_action),
698 G_CALLBACK (on_refresh_account_action_activated),
699 g_strdup (account_name),
700 (GClosureNotify) g_free,
703 /* Create item and add it to the send&receive
704 CSM. If there is only one account then
706 if (num_accounts > 1) {
707 GtkWidget *label = gtk_label_new(NULL);
708 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
709 if (default_account && (strcmp(account_name, default_account) == 0)) {
710 gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
711 gtk_label_set_markup (GTK_LABEL (label), escaped);
714 gtk_label_set_text (GTK_LABEL (label), display_name);
717 item = gtk_menu_item_new ();
718 gtk_container_add (GTK_CONTAINER (item), label);
720 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
721 g_signal_connect_data (G_OBJECT (item),
723 G_CALLBACK (on_send_receive_csm_activated),
724 g_strdup (account_name),
725 (GClosureNotify) g_free,
732 g_free (display_name);
735 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, priv->view_additions_group, 1);
737 /* We cannot do this in the loop above because this relies on the action
738 * group being inserted. This makes the default account appear in bold.
739 * I agree it is a rather ugly way, but I don't see another possibility. armin. */
740 for (i = 0; i < num_accounts; i++) {
741 gchar *item_name, *path;
743 ModestAccountSettings *settings;
744 const gchar *account_name;
747 settings = (ModestAccountSettings *) g_slist_nth_data (accounts, i);
748 account_name = modest_account_settings_get_account_name (settings);
749 is_default = (account_name && default_account && !strcmp (account_name, default_account));
751 /* Get the item of the view menu */
752 item_name = g_strconcat (account_name, "Menu", NULL);
753 path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
754 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
758 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
759 if (GTK_IS_LABEL (child)) {
760 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
762 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
763 gtk_label_set_markup (GTK_LABEL (child), bold_name);
766 gtk_label_set_ellipsize (GTK_LABEL (child), PANGO_ELLIPSIZE_END);
770 /* Get the item of the tools menu */
771 path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", 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);
789 g_object_unref (settings);
792 if (num_accounts > 1) {
793 /* Disconnect the tap-and-hold-query if it's connected */
794 if (modest_signal_mgr_is_connected (priv->sighandlers,
795 G_OBJECT (send_receive_button),
796 "tap-and-hold-query"))
797 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
798 G_OBJECT (send_receive_button),
799 "tap-and-hold-query");
801 /* Mandatory in order to view the menu contents */
802 gtk_widget_show_all (priv->accounts_popup);
804 /* Setup tap_and_hold just if was not done before*/
805 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
806 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
808 /* Connect the tap-and-hold-query in order not to show the CSM */
809 if (!modest_signal_mgr_is_connected (priv->sighandlers,
810 G_OBJECT (send_receive_button),
811 "tap-and-hold-query"))
812 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
813 G_OBJECT (send_receive_button),
814 "tap-and-hold-query",
815 G_CALLBACK (tap_and_hold_query_cb),
820 g_slist_free (accounts);
821 g_free (default_account);
824 /* Make sure that at least one account is viewed if there are any
825 * accounts, for instance when adding the first account: */
826 set_at_least_one_account_visible (self);
830 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
832 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
833 gtk_scrolled_window_add_with_viewport
834 (GTK_SCROLLED_WINDOW(win), widget);
836 gtk_container_add (GTK_CONTAINER(win),
847 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
849 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
851 GList *oerrsignals = priv->queue_err_signals;
852 while (oerrsignals) {
853 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
854 g_signal_handler_disconnect (esignal->queue, esignal->signal);
855 g_slice_free (QueueErrorSignal, esignal);
856 oerrsignals = g_list_next (oerrsignals);
858 g_list_free (priv->queue_err_signals);
859 priv->queue_err_signals = NULL;
864 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
866 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
869 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
873 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
875 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
877 /* Update visibility */
880 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW(user_data));
884 modest_main_window_disconnect_signals (ModestWindow *self)
886 ModestMainWindowPrivate *priv;
887 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
889 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
890 priv->sighandlers = NULL;
894 connect_signals (ModestMainWindow *self)
896 ModestWindowPrivate *parent_priv;
897 ModestMainWindowPrivate *priv;
900 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
901 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
906 modest_signal_mgr_connect (priv->sighandlers,
907 G_OBJECT(priv->folder_view), "key-press-event",
908 G_CALLBACK(on_inner_widgets_key_pressed), self);
910 modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view),
911 "folder_selection_changed",
912 G_CALLBACK (on_folder_selection_changed),
915 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view),
916 "folder-display-name-changed",
917 G_CALLBACK (modest_ui_actions_on_folder_display_name_changed),
920 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view),
922 G_CALLBACK (on_folder_view_focus_in),
925 /* Folder view CSM */
926 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
927 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
928 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
929 G_CALLBACK(_folder_view_csm_menu_activated),
933 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
934 G_CALLBACK(modest_ui_actions_on_header_selected), self);
936 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
937 G_CALLBACK(modest_ui_actions_on_header_activated), self);
939 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
940 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
942 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
943 G_CALLBACK(on_inner_widgets_key_pressed), self);
945 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
946 G_CALLBACK(on_msg_count_changed), self);
948 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
949 G_CALLBACK (on_header_view_focus_in), self);
951 modest_signal_mgr_connect (priv->sighandlers,
952 G_OBJECT (priv->header_view),
954 G_CALLBACK (on_updating_msg_list),
957 /* Header view CSM */
958 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
959 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
961 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
962 G_CALLBACK(_header_view_csm_menu_activated),
967 modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
968 G_CALLBACK (modest_main_window_window_state_event),
971 /* Mail Operation Queue */
973 modest_signal_mgr_connect (priv->sighandlers,
974 G_OBJECT (modest_runtime_get_mail_operation_queue ()),
976 G_CALLBACK (on_queue_changed), self);
978 /* Track changes in the device name */
980 modest_signal_mgr_connect (priv->sighandlers,
981 G_OBJECT(modest_runtime_get_conf ()),
983 G_CALLBACK (on_configuration_key_changed),
986 /* Track account changes. We need to refresh the toolbar */
988 modest_signal_mgr_connect (priv->sighandlers,
989 G_OBJECT (modest_runtime_get_account_store ()),
991 G_CALLBACK (on_account_inserted),
994 modest_signal_mgr_connect (priv->sighandlers,
995 G_OBJECT (modest_runtime_get_account_store ()),
997 G_CALLBACK (on_account_removed),
1000 /* We need to refresh the send & receive menu to change the bold
1001 * account when the default account changes. */
1003 modest_signal_mgr_connect (priv->sighandlers,
1004 G_OBJECT (modest_runtime_get_account_mgr ()),
1005 "default_account_changed",
1006 G_CALLBACK (on_default_account_changed),
1011 modest_signal_mgr_connect (priv->sighandlers,
1012 G_OBJECT (modest_runtime_get_account_store ()),
1014 G_CALLBACK (on_account_changed),
1018 modest_signal_mgr_connect (priv->sighandlers,
1019 G_OBJECT (modest_runtime_get_account_store()),
1020 "password_requested",
1021 G_CALLBACK (modest_ui_actions_on_password_requested),
1026 on_hildon_program_is_topmost_notify(GObject *self,
1027 GParamSpec *propert_param,
1030 HildonProgram *app = HILDON_PROGRAM (self);
1032 /* Note that use of hildon_program_set_can_hibernate()
1033 * is generally referred to as "setting the killable flag",
1034 * though hibernation does not seem equal to death.
1037 if (hildon_program_get_is_topmost (app)) {
1038 /* Prevent hibernation when the progam comes to the foreground,
1039 * because hibernation should only happen when the application
1040 * is in the background: */
1041 hildon_program_set_can_hibernate (app, FALSE);
1043 /* Remove new mail visual notifications */
1044 modest_platform_remove_new_mail_notifications (TRUE);
1046 /* Allow hibernation if the program has gone to the background: */
1048 /* However, prevent hibernation while the settings are being changed: */
1049 const gboolean hibernation_prevented =
1050 modest_window_mgr_get_hibernation_is_prevented (
1051 modest_runtime_get_window_mgr ());
1053 if (hibernation_prevented)
1054 hildon_program_set_can_hibernate (app, FALSE);
1056 /* Allow hibernation, after saving the state: */
1057 modest_osso_save_state();
1058 hildon_program_set_can_hibernate (app, TRUE);
1064 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
1066 GtkWidget *folder_win = (GtkWidget *) user_data;
1067 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1069 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
1070 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
1072 gtk_widget_show (GTK_WIDGET (priv->folder_view));
1074 /* Connect signals */
1075 connect_signals (MODEST_MAIN_WINDOW (self));
1077 /* Set account store */
1078 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
1079 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1081 /* Load previous osso state, for instance if we are being restored from
1083 modest_osso_load_state ();
1085 /* Restore window & widget settings */
1086 priv->wait_for_settings = TRUE;
1087 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
1088 priv->wait_for_settings = FALSE;
1090 /* Check if accounts exist and show the account wizard if not */
1091 gboolean accounts_exist =
1092 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1094 if (!accounts_exist) {
1095 /* This is necessary to have the main window shown behind the dialog
1096 It's an ugly hack... jschmid */
1097 gtk_widget_show_all(GTK_WIDGET(self));
1098 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
1101 GtkAction *send_receive_all;
1102 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1103 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
1104 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1105 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1106 gtk_action_set_visible (send_receive_all, g_slist_length (accounts) > 0);
1107 modest_account_mgr_free_account_names (accounts);
1108 update_menus (MODEST_MAIN_WINDOW (self));
1113 osso_display_event_cb (osso_display_state_t state,
1116 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (data);
1118 priv->display_state = state;
1120 /* Stop blinking if the screen becomes on */
1121 if (priv->display_state == OSSO_DISPLAY_ON)
1122 modest_platform_remove_new_mail_notifications (TRUE);
1126 modest_main_window_new (void)
1128 ModestMainWindow *self = NULL;
1129 ModestMainWindowPrivate *priv = NULL;
1130 ModestWindowPrivate *parent_priv = NULL;
1131 GtkWidget *folder_win = NULL;
1132 ModestDimmingRulesGroup *menu_rules_group = NULL;
1133 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1134 GtkActionGroup *action_group = NULL;
1135 GError *error = NULL;
1137 ModestConf *conf = NULL;
1138 GtkAction *action = NULL;
1139 GdkPixbuf *window_icon;
1141 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
1142 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1143 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1145 parent_priv->ui_manager = gtk_ui_manager_new();
1146 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
1148 action_group = gtk_action_group_new ("ModestMainWindowActions");
1149 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1151 menu_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_MENU, FALSE);
1152 toolbar_rules_group = modest_dimming_rules_group_new (MODEST_DIMMING_RULES_TOOLBAR, TRUE);
1154 /* Add common actions */
1155 gtk_action_group_add_actions (action_group,
1156 modest_action_entries,
1157 G_N_ELEMENTS (modest_action_entries),
1160 gtk_action_group_add_actions (action_group,
1161 modest_folder_view_action_entries,
1162 G_N_ELEMENTS (modest_folder_view_action_entries),
1165 gtk_action_group_add_actions (action_group,
1166 modest_header_view_action_entries,
1167 G_N_ELEMENTS (modest_header_view_action_entries),
1170 gtk_action_group_add_toggle_actions (action_group,
1171 modest_toggle_action_entries,
1172 G_N_ELEMENTS (modest_toggle_action_entries),
1175 gtk_action_group_add_toggle_actions (action_group,
1176 modest_main_window_toggle_action_entries,
1177 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
1180 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
1181 g_object_unref (action_group);
1183 /* Load the UI definition */
1184 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
1185 MODEST_UIDIR "modest-main-window-ui.xml", &error);
1186 if (error != NULL) {
1187 g_warning ("Could not merge modest-ui.xml: %s", error->message);
1188 g_error_free (error);
1192 /* Add common dimming rules */
1193 modest_dimming_rules_group_add_rules (menu_rules_group,
1194 modest_main_window_menu_dimming_entries,
1195 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
1196 MODEST_WINDOW (self));
1197 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1198 modest_main_window_toolbar_dimming_entries,
1199 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
1200 MODEST_WINDOW (self));
1202 /* Insert dimming rules group for this window */
1203 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1204 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1205 g_object_unref (menu_rules_group);
1206 g_object_unref (toolbar_rules_group);
1208 /* Add accelerators */
1209 gtk_window_add_accel_group (GTK_WINDOW (self),
1210 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
1212 /* Menubar. Update the state of some toggles */
1213 parent_priv->menubar = modest_maemo_utils_get_manager_menubar_as_menu (parent_priv->ui_manager, "/MenuBar");
1214 conf = modest_runtime_get_conf ();
1215 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1216 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
1217 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1218 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR, NULL));
1219 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1220 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
1221 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1222 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
1223 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
1224 gtk_widget_show (parent_priv->menubar);
1226 /* Get device name */
1227 modest_maemo_utils_get_device_name ();
1231 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
1232 if (!priv->header_view)
1233 g_printerr ("modest: cannot instantiate header view\n");
1234 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
1235 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
1236 MODEST_CONF_HEADER_VIEW_KEY);
1238 /* Other style properties of header view */
1239 g_object_set (G_OBJECT (priv->header_view),
1240 "rules-hint", FALSE,
1242 /* gtk_widget_show (priv->header_view); */
1245 priv->empty_view = create_empty_view ();
1246 gtk_widget_show (priv->empty_view);
1248 /* Create scrolled windows */
1249 folder_win = gtk_scrolled_window_new (NULL, NULL);
1250 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
1251 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
1253 GTK_POLICY_AUTOMATIC);
1254 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
1256 GTK_POLICY_AUTOMATIC);
1257 /* gtk_widget_show (priv->contents_widget); */
1260 priv->main_paned = gtk_hpaned_new ();
1261 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
1262 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
1263 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
1265 /* putting it all together... */
1266 priv->main_vbox = gtk_vbox_new (FALSE, 6);
1267 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
1268 gtk_widget_show (priv->main_vbox);
1270 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
1272 app = hildon_program_get_instance ();
1273 hildon_program_add_window (app, HILDON_WINDOW (self));
1275 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
1276 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
1278 g_signal_connect (G_OBJECT(self), "show",
1279 G_CALLBACK (modest_main_window_on_show), folder_win);
1281 /* Set window icon */
1282 window_icon = modest_platform_get_icon (MODEST_APP_ICON, MODEST_ICON_SIZE_BIG);
1284 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
1285 g_object_unref (window_icon);
1288 /* Listen for changes in the screen, we don't want to show a
1289 led pattern when the display is on for example */
1290 osso_hw_set_display_event_cb (modest_maemo_utils_get_osso_context (),
1291 osso_display_event_cb,
1294 /* Dont't restore settings here,
1295 * because it requires a gtk_widget_show(),
1296 * and we don't want to do that until later,
1297 * so that the UI is not visible for non-menu D-Bus activation.
1300 return MODEST_WINDOW(self);
1304 modest_main_window_set_style (ModestMainWindow *self,
1305 ModestMainWindowStyle style)
1307 ModestMainWindowPrivate *priv;
1308 ModestWindowPrivate *parent_priv;
1312 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1314 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1315 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1317 /* no change -> nothing to do */
1318 if (priv->style == style)
1321 /* Get toggle button and update the state if needed. This will
1322 happen only when the set_style is not invoked from the UI,
1323 for example when it's called from widget memory */
1324 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1325 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
1326 if ((active && style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) ||
1327 (!active && style == MODEST_MAIN_WINDOW_STYLE_SPLIT)) {
1328 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1329 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !active);
1330 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1333 priv->style = style;
1335 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
1337 if (!priv->wait_for_settings)
1338 modest_widget_memory_save (modest_runtime_get_conf (), G_OBJECT (priv->main_paned),
1339 MODEST_CONF_MAIN_PANED_KEY);
1340 /* Remove main paned */
1341 g_object_ref (priv->main_paned);
1342 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1344 /* Reparent the contents widget to the main vbox */
1345 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
1348 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1349 /* Remove header view */
1350 g_object_ref (priv->contents_widget);
1351 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1353 /* Reparent the main paned */
1354 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1355 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1357 g_timeout_add (500, (GSourceFunc) restore_paned_timeout_handler, self);
1361 g_return_if_reached ();
1364 /* Let header view grab the focus if it's being shown */
1365 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1366 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1368 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1371 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1374 ModestMainWindowStyle
1375 modest_main_window_get_style (ModestMainWindow *self)
1377 ModestMainWindowPrivate *priv;
1379 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1381 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1386 toolbar_resize (ModestMainWindow *self)
1388 ModestMainWindowPrivate *priv = NULL;
1389 ModestWindowPrivate *parent_priv = NULL;
1391 gint static_button_size;
1392 ModestWindowMgr *mgr;
1394 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1395 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1396 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1398 mgr = modest_runtime_get_window_mgr ();
1399 static_button_size = modest_window_mgr_get_fullscreen_mode (mgr)?118:108;
1401 if (parent_priv->toolbar) {
1402 /* left size buttons */
1403 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNew");
1404 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1405 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1406 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1407 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply");
1408 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1409 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1410 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1411 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage");
1412 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1413 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1414 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1415 widget = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1416 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), FALSE);
1417 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
1418 gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
1420 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1421 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1422 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1423 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1424 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1425 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->refresh_toolitem), TRUE);
1426 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1427 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->sort_toolitem), TRUE);
1435 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1437 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1438 ModestWindowPrivate *parent_priv;
1439 ModestWindowMgr *mgr;
1440 gboolean is_fullscreen;
1441 GtkAction *fs_toggle_action;
1444 mgr = modest_runtime_get_window_mgr ();
1446 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1448 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1450 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1451 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1452 if (is_fullscreen != active) {
1453 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1456 toolbar_resize (MODEST_MAIN_WINDOW (widget));
1464 modest_main_window_show_toolbar (ModestWindow *self,
1465 gboolean show_toolbar)
1467 ModestMainWindowPrivate *priv = NULL;
1468 ModestWindowPrivate *parent_priv = NULL;
1469 GtkWidget *reply_button = NULL, *menu = NULL;
1470 GtkWidget *placeholder = NULL;
1472 const gchar *action_name;
1475 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1476 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1477 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1479 /* Set optimized view status */
1480 priv->optimized_view = !show_toolbar;
1482 if (!parent_priv->toolbar) {
1483 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1485 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1487 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1488 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1489 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1490 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1491 toolbar_resize (MODEST_MAIN_WINDOW (self));
1493 /* Add ProgressBar (Transfer toolbar) */
1494 priv->progress_bar = modest_progress_bar_new ();
1495 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1496 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1497 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1498 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1499 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1501 /* Connect cancel 'clicked' signal to abort progress mode */
1502 g_signal_connect(priv->cancel_toolitem, "clicked",
1503 G_CALLBACK(cancel_progressbar),
1506 /* Add it to the observers list */
1507 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1510 hildon_window_add_toolbar (HILDON_WINDOW (self),
1511 GTK_TOOLBAR (parent_priv->toolbar));
1513 /* Set reply button tap and hold menu */
1514 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1515 "/ToolBar/ToolbarMessageReply");
1516 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1517 "/ToolbarReplyCSM");
1518 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1520 /* Set send & receive button tap and hold menu */
1521 update_menus (MODEST_MAIN_WINDOW (self));
1525 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1526 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1527 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1529 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1530 if (modest_main_window_transfer_mode_enabled (MODEST_MAIN_WINDOW(self)))
1531 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_TRANSFER);
1533 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1535 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1539 /* Update also the actions (to update the toggles in the
1540 menus), we have to do it manually because some other window
1541 of the same time could have changed it (remember that the
1542 toolbar fullscreen mode is shared by all the windows of the
1544 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
1545 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu";
1547 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu";
1549 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
1550 modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
1555 on_account_inserted (TnyAccountStore *accoust_store,
1556 TnyAccount *account,
1559 /* Transport accounts and local ones (MMC and the Local
1560 folders account do now cause menu changes */
1561 if (TNY_IS_STORE_ACCOUNT (account) &&
1562 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1563 update_menus (MODEST_MAIN_WINDOW (user_data));
1567 on_default_account_changed (ModestAccountMgr* mgr,
1570 update_menus (MODEST_MAIN_WINDOW (user_data));
1574 on_account_removed (TnyAccountStore *accoust_store,
1575 TnyAccount *account,
1578 /* Transport accounts and local ones (MMC and the Local
1579 folders account do now cause menu changes */
1580 if (TNY_IS_STORE_ACCOUNT (account) &&
1581 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1582 update_menus (MODEST_MAIN_WINDOW (user_data));
1586 on_account_changed (TnyAccountStore *account_store,
1587 TnyAccount *account,
1590 ModestMainWindow *win = MODEST_MAIN_WINDOW (user_data);
1592 /* We need to refresh the details widget because it could have changed */
1593 if (modest_main_window_get_contents_style(win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS) {
1594 modest_main_window_set_contents_style (win, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1597 /* Update the menus as well, the account name could be
1598 changed. Transport accounts and local ones (MMC and the
1599 Local folders account do now cause menu changes */
1600 if (TNY_IS_STORE_ACCOUNT (account) &&
1601 modest_tny_folder_store_is_remote (TNY_FOLDER_STORE (account)))
1602 update_menus (MODEST_MAIN_WINDOW (user_data));
1606 * This function manages the key events used to navigate between
1607 * header and folder views (when the window is in split view)
1610 * -------------------------------------------------
1611 * HeaderView GDK_Left Move focus to folder view
1612 * FolderView GDK_Right Move focus to header view
1614 * There is no need to scroll to selected row, the widgets will be the
1615 * responsibles of doing that (probably managing the focus-in event
1618 on_inner_widgets_key_pressed (GtkWidget *widget,
1622 ModestMainWindowPrivate *priv;
1624 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1626 /* Do nothing if we're in SIMPLE style */
1627 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1630 if (MODEST_IS_HEADER_VIEW (widget)) {
1631 if (event->keyval == GDK_Left)
1632 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1633 else if ((event->keyval == GDK_Return)||(event->keyval == GDK_KP_Enter)) {
1634 guint selected_headers = modest_header_view_count_selected_headers (MODEST_HEADER_VIEW (widget));
1635 if (selected_headers > 1) {
1636 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1640 } else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1641 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1647 set_alignment (GtkWidget *widget,
1650 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1651 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1655 create_empty_view (void)
1657 GtkLabel *label = NULL;
1658 GtkWidget *align = NULL;
1660 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1661 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1662 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1663 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1665 return GTK_WIDGET(align);
1669 * Free the returned string
1672 get_gray_color_markup (GtkWidget *styled_widget)
1674 gchar *gray_color_markup = NULL;
1675 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1676 /* Obtain the secondary text color. We need a realized widget, that's why
1677 we get styled_widget from outside */
1679 if (gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color))
1680 gray_color_markup = modest_text_utils_get_color_string (&color);
1681 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
1683 if (!gray_color_markup)
1684 gray_color_markup = g_strdup ("#BBBBBB");
1686 return gray_color_markup;
1690 * Free the returned string
1693 create_device_name_visual_string (const gchar *device_name,
1694 const gchar *gray_color_markup)
1698 /* We have to use "" to fill the %s of the translation. We can
1699 not just use the device name because the device name is
1700 shown in a different color, so it could not be included
1701 into the <span> tag */
1702 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), "");
1703 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1713 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1715 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1720 gchar *gray_color_markup;
1722 vbox = gtk_vbox_new (FALSE, 0);
1724 gray_color_markup = get_gray_color_markup (styled_widget);
1726 /* Account description: */
1727 if (modest_tny_account_is_virtual_local_folders (account)
1728 || (modest_tny_account_is_memory_card_account (account))) {
1730 /* Get device name */
1731 gchar *device_name = NULL;
1732 if (modest_tny_account_is_virtual_local_folders (account))
1733 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1734 MODEST_CONF_DEVICE_NAME, NULL);
1736 device_name = g_strdup (tny_account_get_name (account));
1738 label = create_device_name_visual_string ((const gchar *) device_name,
1739 (const gchar *) gray_color_markup);
1740 label_w = gtk_label_new (NULL);
1741 gtk_label_set_markup (GTK_LABEL (label_w), label);
1742 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1743 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1744 g_free (device_name);
1747 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1748 gtk_box_pack_start (GTK_BOX (vbox),
1749 gtk_label_new (tny_account_get_name (account)),
1752 /* Other accounts, such as IMAP and POP: */
1757 /* Put proto in uppercase */
1758 proto = g_string_new (tny_account_get_proto (account));
1759 proto = g_string_ascii_up (proto);
1761 /* note: mcen_fi_localroot_description is something like "%s account"
1762 * however, we should display "%s account: %s"... therefore, ugly tmp */
1763 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1764 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1765 gray_color_markup, tmp, tny_account_get_name (account));
1768 label_w = gtk_label_new (NULL);
1769 gtk_label_set_markup (GTK_LABEL (label_w), label);
1770 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1771 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1772 g_string_free (proto, TRUE);
1778 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1779 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1780 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1781 modest_tny_folder_store_get_message_count (folder_store));
1782 label_w = gtk_label_new (NULL);
1783 gtk_label_set_markup (GTK_LABEL (label_w), label);
1784 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1785 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1789 label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d",
1791 _("mcen_fi_rootfolder_folders"),
1792 modest_tny_folder_store_get_folder_count (folder_store));
1793 label_w = gtk_label_new (NULL);
1794 gtk_label_set_markup (GTK_LABEL (label_w), label);
1795 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1796 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1800 if (modest_tny_account_is_virtual_local_folders (account)
1801 || modest_tny_account_is_memory_card_account (account)) {
1803 gchar *size = modest_text_utils_get_display_size (
1804 modest_tny_folder_store_get_local_size (folder_store));
1806 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1807 gray_color_markup, _("mcen_fi_rootfolder_size"),
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);
1816 } else if (TNY_IS_ACCOUNT(folder_store)) {
1817 TnyAccount *account = TNY_ACCOUNT(folder_store);
1819 time_t last_updated;
1820 const gchar *last_updated_string;
1821 /* Get last updated from configuration */
1822 last_updated = modest_account_mgr_get_last_updated (modest_runtime_get_account_mgr (),
1823 tny_account_get_id (account));
1825 if (last_updated > 0)
1826 last_updated_string = modest_text_utils_get_display_date(last_updated);
1828 last_updated_string = g_strdup (_("mcen_va_never"));
1830 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1831 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1832 label_w = gtk_label_new (NULL);
1833 gtk_label_set_markup (GTK_LABEL (label_w), label);
1834 gtk_label_set_ellipsize (GTK_LABEL (label_w), PANGO_ELLIPSIZE_END);
1835 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1839 g_free (gray_color_markup);
1842 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1848 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1850 ModestMainWindowPrivate *priv = NULL;
1852 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1854 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1856 return priv->send_receive_in_progress;
1860 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1862 GtkAction *action = NULL;
1863 GtkWidget *widget = NULL;
1864 ModestMainWindowPrivate *priv = NULL;
1866 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1867 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1869 priv->send_receive_in_progress = TRUE;
1871 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1872 gtk_action_set_sensitive (action, FALSE);
1873 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1874 /* gtk_action_set_sensitive (action, FALSE); */
1875 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1876 gtk_widget_set_sensitive (widget, FALSE);
1880 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1882 GtkAction *action = NULL;
1883 GtkWidget *widget = NULL;
1884 ModestMainWindowPrivate *priv = NULL;
1886 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1887 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1889 priv->send_receive_in_progress = FALSE;
1891 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1892 gtk_action_set_sensitive (action, TRUE);
1893 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1894 /* gtk_action_set_sensitive (action, TRUE); */
1895 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1896 gtk_widget_set_sensitive (widget, TRUE);
1901 on_msg_count_changed (ModestHeaderView *header_view,
1903 TnyFolderChange *change,
1904 ModestMainWindow *main_window)
1906 gboolean refilter = FALSE;
1907 gboolean folder_empty = FALSE;
1908 gboolean all_marked_as_deleted = FALSE;
1909 ModestMainWindowPrivate *priv;
1911 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1912 g_return_if_fail (TNY_IS_FOLDER(folder));
1913 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
1915 if (change != NULL) {
1916 TnyFolderChangeChanged changed;
1918 changed = tny_folder_change_get_changed (change);
1919 /* If something changes */
1920 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1921 folder_empty = (((guint) tny_folder_change_get_new_all_count (change)) == 0);
1923 folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1925 /* Play a sound (if configured) and make the LED blink */
1926 if (changed & TNY_FOLDER_CHANGE_CHANGED_ADDED_HEADERS) {
1927 modest_platform_push_email_notification ();
1930 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_EXPUNGED_HEADERS)
1933 folder_empty = (((guint) tny_folder_get_all_count (TNY_FOLDER (folder))) == 0);
1936 /* Check if all messages are marked to be deleted */
1937 all_marked_as_deleted = modest_header_view_is_empty (header_view);
1938 folder_empty = folder_empty || all_marked_as_deleted;
1940 /* Set contents style of headers view */
1942 modest_main_window_set_contents_style (main_window,
1943 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1944 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1946 modest_main_window_set_contents_style (main_window,
1947 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1951 modest_header_view_refilter (header_view);
1956 modest_main_window_set_contents_style (ModestMainWindow *self,
1957 ModestMainWindowContentsStyle style)
1959 ModestMainWindowPrivate *priv;
1961 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1963 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1965 /* We allow to set the same content style than the previously
1966 set if there are details, because it could happen when we're
1967 selecting different accounts consecutively */
1968 if ((priv->contents_style == style) &&
1969 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1972 /* Remove previous child. Delete it if it was an account
1974 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1976 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1977 g_object_ref (content);
1978 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1979 g_object_ref (priv->empty_view);
1980 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
1983 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1986 priv->contents_style = style;
1988 switch (priv->contents_style) {
1989 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1990 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1991 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
1994 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1996 /* if we're started without main win, there may not be a folder
1997 * view. this fixes a GLib-Critical */
1998 if (priv->folder_view) {
1999 TnyFolderStore *selected_folderstore =
2000 modest_folder_view_get_selected (priv->folder_view);
2001 if (TNY_IS_ACCOUNT (selected_folderstore)) {
2002 priv->details_widget = create_details_widget (GTK_WIDGET (self),
2003 TNY_ACCOUNT (selected_folderstore));
2005 wrap_in_scrolled_window (priv->contents_widget,
2006 priv->details_widget);
2008 g_object_unref (selected_folderstore);
2009 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2014 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
2015 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
2016 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2020 g_return_if_reached ();
2024 gtk_widget_show_all (priv->contents_widget);
2027 ModestMainWindowContentsStyle
2028 modest_main_window_get_contents_style (ModestMainWindow *self)
2030 ModestMainWindowPrivate *priv;
2032 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
2034 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2035 return priv->contents_style;
2040 on_configuration_key_changed (ModestConf* conf,
2042 ModestConfEvent event,
2043 ModestConfNotificationId id,
2044 ModestMainWindow *self)
2046 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2047 TnyAccount *account = NULL;
2049 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
2052 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
2055 if (priv->folder_view)
2056 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
2058 if (account && TNY_IS_ACCOUNT (account) &&
2059 strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID) == 0) {
2062 const gchar *device_name;
2063 gchar *new_text, *gray_color_markup;
2066 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
2067 label = GTK_LABEL (children->data);
2069 device_name = modest_conf_get_string (modest_runtime_get_conf(),
2070 MODEST_CONF_DEVICE_NAME, NULL);
2072 gray_color_markup = get_gray_color_markup (GTK_WIDGET (self));
2073 new_text = create_device_name_visual_string (device_name, gray_color_markup);
2075 gtk_label_set_markup (label, new_text);
2076 gtk_widget_show (GTK_WIDGET (label));
2078 g_free (gray_color_markup);
2080 g_list_free (children);
2082 g_object_unref (account);
2086 set_toolbar_transfer_mode (ModestMainWindow *self)
2088 ModestMainWindowPrivate *priv = NULL;
2090 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2092 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2094 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
2096 if (priv->progress_bar_timeout > 0) {
2097 g_source_remove (priv->progress_bar_timeout);
2098 priv->progress_bar_timeout = 0;
2105 set_toolbar_mode (ModestMainWindow *self,
2106 ModestToolBarModes mode)
2108 ModestWindowPrivate *parent_priv = NULL;
2109 ModestMainWindowPrivate *priv = NULL;
2110 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
2112 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2114 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2115 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2117 /* In case this was called before the toolbar exists: */
2118 if (!(parent_priv->toolbar))
2121 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
2123 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
2124 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
2125 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
2127 /* Sets current toolbar mode */
2128 priv->current_toolbar_mode = mode;
2130 /* Checks the dimming rules */
2131 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2133 /* Show and hide toolbar items */
2135 case TOOLBAR_MODE_NORMAL:
2137 gtk_action_set_visible (sort_action, TRUE);
2139 gtk_action_set_visible (refresh_action, TRUE);
2140 if (priv->progress_toolitem) {
2141 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
2142 gtk_widget_hide (priv->progress_toolitem);
2144 if (priv->progress_bar)
2145 gtk_widget_hide (priv->progress_bar);
2148 gtk_action_set_visible (cancel_action, FALSE);
2150 /* Hide toolbar if optimized view is enabled */
2151 if (priv->optimized_view)
2152 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
2154 case TOOLBAR_MODE_TRANSFER:
2156 gtk_action_set_visible (sort_action, FALSE);
2158 gtk_action_set_visible (refresh_action, FALSE);
2160 gtk_action_set_visible (cancel_action, TRUE);
2161 if (priv->progress_bar)
2162 gtk_widget_show (priv->progress_bar);
2163 if (priv->progress_toolitem) {
2164 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
2165 gtk_widget_show (priv->progress_toolitem);
2168 /* Show toolbar if it's hiden (optimized view ) */
2169 if (priv->optimized_view)
2170 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2173 g_return_if_reached ();
2178 modest_main_window_transfer_mode_enabled (ModestMainWindow *self)
2180 ModestMainWindowPrivate *priv;
2182 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2183 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2185 return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
2189 cancel_progressbar (GtkToolButton *toolbutton,
2190 ModestMainWindow *self)
2193 ModestMainWindowPrivate *priv;
2195 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2197 /* Get operation observers and cancel all the operations */
2198 tmp = priv->progress_widgets;
2200 modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2201 tmp=g_slist_next(tmp);
2206 observers_empty (ModestMainWindow *self)
2209 ModestMainWindowPrivate *priv;
2210 gboolean is_empty = TRUE;
2211 guint pending_ops = 0;
2213 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2214 tmp = priv->progress_widgets;
2216 /* Check all observers */
2217 while (tmp && is_empty) {
2218 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2219 is_empty = pending_ops == 0;
2221 tmp = g_slist_next(tmp);
2229 * Gets the toolbar mode needed for each mail operation. It stores in
2230 * @mode_changed if the toolbar mode has changed or not
2232 static ModestToolBarModes
2233 get_toolbar_mode_from_mail_operation (ModestMainWindow *self,
2234 ModestMailOperation *mail_op,
2235 gboolean *mode_changed)
2237 ModestToolBarModes mode;
2238 ModestMainWindowPrivate *priv;
2240 *mode_changed = FALSE;
2241 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2243 /* Get toolbar mode from operation id*/
2244 switch (modest_mail_operation_get_type_operation (mail_op)) {
2245 case MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE:
2246 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
2247 case MODEST_MAIL_OPERATION_TYPE_OPEN:
2248 mode = TOOLBAR_MODE_TRANSFER;
2249 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
2250 *mode_changed = TRUE;
2253 mode = TOOLBAR_MODE_NORMAL;
2259 on_mail_operation_started (ModestMailOperation *mail_op,
2262 ModestMainWindow *self;
2263 ModestMailOperationTypeOperation op_type;
2264 ModestMainWindowPrivate *priv;
2265 ModestToolBarModes mode;
2267 gboolean mode_changed = FALSE;
2268 TnyAccount *account;
2270 self = MODEST_MAIN_WINDOW (user_data);
2271 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2273 /* Do not show progress for receiving operations if the
2274 account is the local account or the MMC one */
2275 op_type = modest_mail_operation_get_type_operation (mail_op);
2276 account = modest_mail_operation_get_account (mail_op);
2277 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2280 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2281 modest_tny_account_is_memory_card_account (account));
2282 g_object_unref (account);
2287 /* Get toolbar mode from operation id*/
2288 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2290 /* Add operation observers and change toolbar if neccessary*/
2291 tmp = priv->progress_widgets;
2292 if (mode == TOOLBAR_MODE_TRANSFER) {
2294 GObject *source = modest_mail_operation_get_source(mail_op);
2295 if (G_OBJECT (self) == source) {
2296 set_toolbar_transfer_mode(self);
2298 g_object_unref (source);
2302 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2304 tmp = g_slist_next (tmp);
2310 on_mail_operation_finished (ModestMailOperation *mail_op,
2313 ModestToolBarModes mode;
2314 ModestMailOperationTypeOperation op_type;
2316 ModestMainWindow *self;
2317 gboolean mode_changed;
2318 TnyAccount *account;
2319 ModestMainWindowPrivate *priv;
2321 self = MODEST_MAIN_WINDOW (user_data);
2322 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2324 /* The mail operation was not added to the progress objects if
2325 the account was the local account or the MMC one */
2326 op_type = modest_mail_operation_get_type_operation (mail_op);
2327 account = modest_mail_operation_get_account (mail_op);
2328 if (account && op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE) {
2331 is_remote = !(modest_tny_account_is_virtual_local_folders (account) ||
2332 modest_tny_account_is_memory_card_account (account));
2333 g_object_unref (account);
2338 /* Get toolbar mode from operation id*/
2339 mode = get_toolbar_mode_from_mail_operation (self, mail_op, &mode_changed);
2341 /* Change toolbar mode */
2342 tmp = priv->progress_widgets;
2343 if (mode == TOOLBAR_MODE_TRANSFER) {
2345 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2347 tmp = g_slist_next (tmp);
2350 /* If no more operations are being observed, NORMAL mode is enabled again */
2351 if (observers_empty (self)) {
2352 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
2358 on_queue_changed (ModestMailOperationQueue *queue,
2359 ModestMailOperation *mail_op,
2360 ModestMailOperationQueueNotification type,
2361 ModestMainWindow *self)
2363 ModestMainWindowPrivate *priv;
2365 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2367 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
2368 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2370 "operation-started",
2371 G_CALLBACK (on_mail_operation_started),
2373 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
2375 "operation-finished",
2376 G_CALLBACK (on_mail_operation_finished),
2378 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
2379 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2381 "operation-started");
2382 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
2384 "operation-finished");
2389 set_account_visible(ModestMainWindow *self, const gchar *acc_name)
2391 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2393 ModestAccountMgr *mgr;
2394 ModestAccountSettings *settings;
2395 ModestServerAccountSettings *store_settings = NULL;
2397 /* Get account data */
2398 mgr = modest_runtime_get_account_mgr ();
2399 settings = modest_account_mgr_load_account_settings (mgr, acc_name);
2401 store_settings = modest_account_settings_get_store_settings (settings);
2403 /* Set the new visible & active account */
2404 if (settings && (modest_server_account_settings_get_account_name (store_settings)!= NULL)) {
2405 const gchar *account_name;
2407 account_name = modest_account_settings_get_account_name (settings);
2409 modest_folder_view_set_account_id_of_visible_server_account
2411 modest_server_account_settings_get_account_name (store_settings));
2412 modest_window_set_active_account (MODEST_WINDOW (self), account_name);
2413 action = gtk_action_group_get_action (priv->view_additions_group, account_name);
2414 if (action != NULL) {
2415 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2416 modest_utils_toggle_action_set_active_block_notify (
2417 GTK_TOGGLE_ACTION (action),
2423 modest_folder_view_select_first_inbox_or_local (priv->folder_view);
2428 g_object_unref (store_settings);
2429 g_object_unref (settings);
2433 /* Make sure that at least one account is "viewed": */
2435 set_at_least_one_account_visible(ModestMainWindow *self)
2437 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2438 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2440 if (!(priv->folder_view)) {
2441 /* It is too early to do this. */
2445 const gchar *active_server_account_name =
2446 modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);
2448 if (!active_server_account_name ||
2449 !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
2451 gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
2452 gchar* default_modest_name = modest_account_mgr_get_default_account (account_mgr);
2453 if (default_modest_name) {
2454 set_account_visible (self, default_modest_name);
2455 } else if (first_modest_name) {
2456 set_account_visible (self, first_modest_name);
2458 g_free (first_modest_name);
2459 g_free (default_modest_name);
2464 on_show_account_action_toggled (GtkToggleAction *action,
2467 ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
2469 const gchar *acc_name = gtk_action_get_name (GTK_ACTION (action));
2470 if (gtk_toggle_action_get_active (action))
2471 set_account_visible (self, acc_name);
2475 refresh_account (const gchar *account_name)
2479 /* win must already exists here, obviously */
2480 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
2483 g_warning ("%s: BUG: no main window!", __FUNCTION__);
2487 /* If account_name == NULL, we must update all (option All) */
2489 modest_ui_actions_do_send_receive_all (win, TRUE);
2491 modest_ui_actions_do_send_receive (account_name, TRUE, win);
2496 on_refresh_account_action_activated (GtkAction *action,
2499 refresh_account ((const gchar*) user_data);
2503 on_send_receive_csm_activated (GtkMenuItem *item,
2506 refresh_account ((const gchar*) user_data);
2510 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2512 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2514 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2520 on_folder_view_focus_in (GtkWidget *widget, GdkEventFocus *event, gpointer userdata)
2522 ModestMainWindow *main_window = NULL;
2524 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2525 main_window = MODEST_MAIN_WINDOW (userdata);
2527 /* Update toolbar dimming state */
2528 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2534 on_header_view_focus_in (GtkWidget *widget,
2535 GdkEventFocus *event,
2538 ModestMainWindow *main_window = NULL;
2540 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2542 main_window = MODEST_MAIN_WINDOW (userdata);
2544 /* Update toolbar dimming state */
2545 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2551 on_folder_selection_changed (ModestFolderView *folder_view,
2552 TnyFolderStore *folder_store,
2554 ModestMainWindow *main_window)
2556 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2557 GtkAction *action = NULL;
2558 gboolean show_reply = TRUE;
2559 gboolean show_forward = TRUE;
2560 gboolean show_cancel_send = FALSE;
2561 gboolean show_clipboard = TRUE;
2562 gboolean show_delete = TRUE;
2565 if (TNY_IS_ACCOUNT (folder_store)) {
2566 show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2567 } else if (TNY_IS_FOLDER (folder_store)) {
2568 if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2569 TnyFolderType folder_type = modest_tny_folder_get_local_or_mmc_folder_type (
2570 TNY_FOLDER (folder_store));
2571 switch (folder_type) {
2572 case TNY_FOLDER_TYPE_DRAFTS:
2573 show_clipboard = show_delete = TRUE;
2574 show_reply = show_forward = show_cancel_send = FALSE;
2576 case TNY_FOLDER_TYPE_SENT:
2577 show_forward = show_clipboard = show_delete = TRUE;
2578 show_reply = show_cancel_send = FALSE;
2580 case TNY_FOLDER_TYPE_OUTBOX:
2581 show_clipboard = show_delete = show_cancel_send = TRUE;
2582 show_reply = show_forward = FALSE;
2584 case TNY_FOLDER_TYPE_INVALID:
2585 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
2588 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2589 show_cancel_send = FALSE;
2592 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2593 show_cancel_send = FALSE;
2598 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2599 gtk_action_set_visible (action, show_reply);
2600 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2601 gtk_action_set_visible (action, show_reply);
2602 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2603 gtk_action_set_visible (action, show_forward);
2604 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2605 gtk_action_set_visible (action, show_cancel_send);
2606 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2607 gtk_action_set_visible (action, show_delete);
2609 /* We finally call to the ui actions handler, after updating properly
2610 * the header view CSM */
2611 modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2615 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2616 GtkTreeModel *model,
2617 GtkTreeRowReference *row_reference,
2618 ModestMainWindow *self)
2620 ModestMainWindowPrivate *priv = NULL;
2621 GtkTreeModel *header_model = NULL;
2622 GtkTreePath *path = NULL;
2624 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
2625 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2626 g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2628 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2629 header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2631 /* Do nothing if we changed the folder in the main view */
2632 if (header_model != model)
2635 /* Select the message in the header view */
2636 path = gtk_tree_row_reference_get_path (row_reference);
2637 gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->header_view),
2639 gtk_tree_path_free (path);
2645 show_updating_banner (gpointer user_data)
2647 ModestMainWindowPrivate *priv = NULL;
2649 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2651 if (priv->updating_banner == NULL) {
2653 /* We're outside the main lock */
2654 gdk_threads_enter ();
2655 priv->updating_banner =
2656 modest_platform_animation_banner (GTK_WIDGET (user_data), NULL,
2657 _CS ("ckdg_pb_updating"));
2658 gdk_threads_leave ();
2661 /* Remove timeout */
2662 priv->updating_banner_timeout = 0;
2667 * We use this function to show/hide a progress banner showing
2668 * "Updating" while the header view is being filled. We're not showing
2669 * it unless the update takes more than 2 seconds
2671 * If starting = TRUE then the refresh is starting, otherwise it means
2672 * that is has just finished
2675 on_updating_msg_list (ModestHeaderView *header_view,
2679 ModestMainWindowPrivate *priv = NULL;
2681 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
2683 /* Remove old timeout */
2684 if (priv->updating_banner_timeout > 0) {
2685 g_source_remove (priv->updating_banner_timeout);
2686 priv->updating_banner_timeout = 0;
2689 /* Create a new timeout */
2691 priv->updating_banner_timeout =
2692 g_timeout_add (2000, show_updating_banner, user_data);
2694 /* Remove the banner if exists */
2695 if (priv->updating_banner) {
2696 gtk_widget_destroy (priv->updating_banner);
2697 priv->updating_banner = NULL;
2703 modest_main_window_screen_is_on (ModestMainWindow *self)
2705 ModestMainWindowPrivate *priv = NULL;
2707 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW(self), FALSE);
2709 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2711 return (priv->display_state == OSSO_DISPLAY_ON) ? TRUE : FALSE;