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-maemo-utils.h>
57 #include "modest-tny-platform-factory.h"
58 #include "modest-tny-msg.h"
59 #include "modest-mail-operation.h"
60 #include "modest-icon-names.h"
61 #include "modest-progress-bar-widget.h"
62 #include "modest-text-utils.h"
63 #include "modest-ui-dimming-manager.h"
64 #include "maemo/modest-osso-state-saving.h"
65 #include "modest-text-utils.h"
66 #include "modest-signal-mgr.h"
68 #ifdef MODEST_HAVE_HILDON0_WIDGETS
69 #include <hildon-widgets/hildon-program.h>
71 #include <hildon/hildon-program.h>
72 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
74 #define MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS "ModestMainWindowActionAdditions"
81 /* 'private'/'protected' functions */
82 static void modest_main_window_class_init (ModestMainWindowClass *klass);
83 static void modest_main_window_init (ModestMainWindow *obj);
84 static void modest_main_window_finalize (GObject *obj);
86 static gboolean modest_main_window_window_state_event (GtkWidget *widget,
87 GdkEventWindowState *event,
90 static void connect_signals (ModestMainWindow *self);
92 static void modest_main_window_disconnect_signals (ModestWindow *self);
94 static void restore_settings (ModestMainWindow *self,
95 gboolean do_folder_view_too);
97 static void save_state (ModestWindow *self);
100 update_menus (ModestMainWindow* self);
102 static void modest_main_window_show_toolbar (ModestWindow *window,
103 gboolean show_toolbar);
105 static void cancel_progressbar (GtkToolButton *toolbutton,
106 ModestMainWindow *self);
108 static void on_queue_changed (ModestMailOperationQueue *queue,
109 ModestMailOperation *mail_op,
110 ModestMailOperationQueueNotification type,
111 ModestMainWindow *self);
113 static gboolean on_zoom_minus_plus_not_implemented (ModestWindow *window);
116 on_account_inserted (TnyAccountStore *accoust_store,
121 on_account_removed (TnyAccountStore *accoust_store,
126 on_account_changed (ModestAccountMgr* mgr,
127 const gchar* account,
130 static gboolean on_inner_widgets_key_pressed (GtkWidget *widget,
134 static void on_configuration_key_changed (ModestConf* conf,
136 ModestConfEvent event,
137 ModestConfNotificationId id,
138 ModestMainWindow *self);
140 static void set_toolbar_mode (ModestMainWindow *self,
141 ModestToolBarModes mode);
143 static gboolean set_toolbar_transfer_mode (ModestMainWindow *self);
145 static void on_show_account_action_activated (GtkAction *action,
148 static void on_refresh_account_action_activated (GtkAction *action,
151 static void on_send_receive_csm_activated (GtkMenuItem *item,
155 _on_msg_count_changed (ModestHeaderView *header_view,
157 TnyFolderChange *change,
158 ModestMainWindow *main_window);
161 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self);
164 static GtkWidget * create_empty_view (void);
167 on_folder_view_focus_in (GtkWidget *widget,
168 GdkEventFocus *event,
171 on_header_view_focus_in (GtkWidget *widget,
172 GdkEventFocus *event,
175 modest_main_window_on_folder_selection_changed (ModestFolderView *folder_view,
176 TnyFolderStore *folder_store,
178 ModestMainWindow *main_window);
181 set_at_least_one_account_visible(ModestMainWindow *self);
184 modest_main_window_on_send_queue_status_canged (ModestTnySendQueue *send_queue,
189 /* list my signals */
196 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
197 struct _ModestMainWindowPrivate {
198 GtkWidget *msg_paned;
199 GtkWidget *main_paned;
200 GtkWidget *main_vbox;
201 GtkWidget *contents_widget;
202 GtkWidget *empty_view;
204 /* Progress observers */
205 GtkWidget *progress_bar;
206 GSList *progress_widgets;
209 GtkWidget *progress_toolitem;
210 GtkWidget *cancel_toolitem;
211 GtkWidget *sort_toolitem;
212 GtkWidget *refresh_toolitem;
213 ModestToolBarModes current_toolbar_mode;
215 /* Merge ids used to add/remove accounts to the ViewMenu*/
216 GByteArray *merge_ids;
218 /* On-demand widgets */
219 GtkWidget *accounts_popup;
220 GtkWidget *details_widget;
222 /* Optimized view enabled */
223 gboolean optimized_view;
225 /* Optimized view enabled */
226 gboolean send_receive_in_progress;
228 ModestHeaderView *header_view;
229 ModestFolderView *folder_view;
231 ModestMainWindowStyle style;
232 ModestMainWindowContentsStyle contents_style;
234 guint progress_bar_timeout;
236 /* Signal handler UIDs */
237 GList *queue_err_signals;
240 ModestConfNotificationId notification_id;
242 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
243 MODEST_TYPE_MAIN_WINDOW, \
244 ModestMainWindowPrivate))
246 typedef struct _GetMsgAsyncHelper {
247 ModestMainWindowPrivate *main_window_private;
249 ModestTnyMsgReplyType reply_type;
250 ModestTnyMsgForwardType forward_type;
257 static GtkWindowClass *parent_class = NULL;
260 /* Private actions */
261 /* This is the context sensitive menu: */
262 static const GtkActionEntry modest_folder_view_action_entries [] = {
264 /* Folder View CSM actions */
265 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
266 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
267 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_paste)},
268 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
269 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_search_messages) },
270 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
273 static const GtkActionEntry modest_header_view_action_entries [] = {
275 /* Header View CSM actions */
276 { "HeaderViewCSMOpen", NULL, N_("mcen_me_inbox_open"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_open) },
277 { "HeaderViewCSMReply", NULL, N_("mcen_me_inbox_reply"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply) },
278 { "HeaderViewCSMReplyAll", NULL, N_("mcen_me_inbox_replytoall"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply_all) },
279 { "HeaderViewCSMForward", NULL, N_("mcen_me_inbox_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_forward) },
280 { "HeaderViewCSMCut", NULL, N_("mcen_me_inbox_cut"), "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
281 { "HeaderViewCSMCopy", NULL, N_("mcen_me_inbox_copy"), "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
282 { "HeaderViewCSMPaste", NULL, N_("mcen_me_inbox_paste"), "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
283 { "HeaderViewCSMDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_message) },
284 { "HeaderViewCSMCancelSending", NULL, N_("mcen_me_outbox_cancelsend"), NULL, NULL, G_CALLBACK (modest_ui_actions_cancel_send) },
285 { "HeaderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
288 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
289 { "ToggleFolders", MODEST_STOCK_SPLIT_VIEW, N_("mcen_me_inbox_hidefolders"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), TRUE },
292 /************************************************************************/
295 modest_main_window_get_type (void)
297 static GType my_type = 0;
299 static const GTypeInfo my_info = {
300 sizeof(ModestMainWindowClass),
301 NULL, /* base init */
302 NULL, /* base finalize */
303 (GClassInitFunc) modest_main_window_class_init,
304 NULL, /* class finalize */
305 NULL, /* class data */
306 sizeof(ModestMainWindow),
308 (GInstanceInitFunc) modest_main_window_init,
311 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
319 modest_main_window_class_init (ModestMainWindowClass *klass)
321 GObjectClass *gobject_class;
322 gobject_class = (GObjectClass*) klass;
323 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
325 parent_class = g_type_class_peek_parent (klass);
326 gobject_class->finalize = modest_main_window_finalize;
328 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
330 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
331 modest_window_class->save_state_func = save_state;
332 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
333 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
334 modest_window_class->disconnect_signals_func = modest_main_window_disconnect_signals;
338 modest_main_window_init (ModestMainWindow *obj)
340 ModestMainWindowPrivate *priv;
342 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
344 priv->queue_err_signals = NULL;
345 priv->msg_paned = NULL;
346 priv->main_paned = NULL;
347 priv->main_vbox = NULL;
348 priv->header_view = NULL;
349 priv->folder_view = NULL;
350 priv->contents_widget = NULL;
351 priv->accounts_popup = NULL;
352 priv->details_widget = NULL;
353 priv->empty_view = NULL;
354 priv->progress_widgets = NULL;
355 priv->progress_bar = NULL;
356 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
357 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
358 priv->contents_style = -1; /* invalid contents style. We need this to select it for the first time */
359 priv->merge_ids = NULL;
360 priv->optimized_view = FALSE;
361 priv->send_receive_in_progress = FALSE;
362 priv->progress_bar_timeout = 0;
363 priv->sighandlers = NULL;
367 modest_main_window_finalize (GObject *obj)
369 ModestMainWindowPrivate *priv;
371 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
373 if (priv->notification_id) {
374 modest_conf_forget_namespace (modest_runtime_get_conf (),
375 MODEST_CONF_NAMESPACE,
376 priv->notification_id);
379 /* Sanity check: shouldn't be needed, the window mgr should
380 call this function before */
381 modest_main_window_disconnect_signals (MODEST_WINDOW (obj));
383 modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
385 g_slist_free (priv->progress_widgets);
387 g_byte_array_free (priv->merge_ids, TRUE);
389 if (priv->progress_bar_timeout > 0) {
390 g_source_remove (priv->progress_bar_timeout);
391 priv->progress_bar_timeout = 0;
394 G_OBJECT_CLASS(parent_class)->finalize (obj);
398 modest_main_window_get_child_widget (ModestMainWindow *self,
399 ModestWidgetType widget_type)
401 ModestMainWindowPrivate *priv;
404 g_return_val_if_fail (self, NULL);
405 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_WIDGET_TYPE_NUM,
408 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
410 switch (widget_type) {
411 case MODEST_WIDGET_TYPE_HEADER_VIEW:
412 widget = (GtkWidget*)priv->header_view; break;
413 case MODEST_WIDGET_TYPE_FOLDER_VIEW:
414 widget = (GtkWidget*)priv->folder_view; break;
419 return widget ? GTK_WIDGET(widget) : NULL;
424 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
427 ModestMainWindowPrivate *priv;
429 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
431 conf = modest_runtime_get_conf ();
433 modest_widget_memory_restore (conf, G_OBJECT(self),
434 MODEST_CONF_MAIN_WINDOW_KEY);
436 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
437 MODEST_CONF_HEADER_VIEW_KEY);
439 if (do_folder_view_too)
440 modest_widget_memory_restore (conf, G_OBJECT(priv->folder_view),
441 MODEST_CONF_FOLDER_VIEW_KEY);
443 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
444 MODEST_CONF_MAIN_PANED_KEY);
446 /* We need to force a redraw here in order to get the right
447 position of the horizontal paned separator */
448 gtk_widget_show (GTK_WIDGET (self));
453 save_state (ModestWindow *window)
456 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
457 ModestMainWindowPrivate *priv;
459 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
460 conf = modest_runtime_get_conf ();
462 modest_widget_memory_save (conf,G_OBJECT(self),
463 MODEST_CONF_MAIN_WINDOW_KEY);
464 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
465 MODEST_CONF_MAIN_PANED_KEY);
466 // modest_widget_memory_save (conf, G_OBJECT(priv->header_view),
467 // MODEST_CONF_HEADER_VIEW_KEY);
468 modest_widget_memory_save (conf, G_OBJECT(priv->folder_view),
469 MODEST_CONF_FOLDER_VIEW_KEY);
473 compare_display_names (ModestAccountData *a,
474 ModestAccountData *b)
476 return strcmp (a->display_name, b->display_name);
480 update_menus (ModestMainWindow* self)
482 GSList *account_names, *iter, *accounts;
483 ModestMainWindowPrivate *priv;
484 ModestWindowPrivate *parent_priv;
485 ModestAccountMgr *mgr;
486 gint i, num_accounts;
487 GtkActionGroup *action_group;
489 gchar *default_account;
490 GtkWidget *send_receive_button, *item;
491 GtkAction *send_receive_all = NULL;
493 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
494 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
496 /* Get enabled account IDs */
497 mgr = modest_runtime_get_account_mgr ();
498 account_names = modest_account_mgr_account_names (mgr, TRUE);
499 iter = account_names;
503 ModestAccountData *account_data =
504 modest_account_mgr_get_account_data (mgr, (gchar*) iter->data);
505 accounts = g_slist_prepend (accounts, account_data);
509 modest_account_mgr_free_account_names (account_names);
510 account_names = NULL;
512 /* Order the list of accounts by its display name */
513 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
514 num_accounts = g_slist_length (accounts);
516 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
517 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
518 gtk_action_set_visible (send_receive_all, num_accounts > 1);
520 /* Delete old send&receive popup items. We can not just do a
521 menu_detach because it does not work well with
523 if (priv->accounts_popup)
524 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
525 (GtkCallback) gtk_widget_destroy, NULL);
527 /* Delete old entries in the View menu. Do not free groups, it
529 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
531 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
532 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
533 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
534 GTK_ACTION_GROUP (groups->data));
537 if (priv->merge_ids) {
538 for (i = 0; i < priv->merge_ids->len; i++)
539 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
540 g_byte_array_free (priv->merge_ids, TRUE);
542 /* We need to call this in order to ensure
543 that the new actions are added in the right
544 order (alphabetical */
545 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
547 groups = g_list_next (groups);
549 priv->merge_ids = g_byte_array_sized_new (num_accounts);
551 /* Get send receive button */
552 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
553 "/ToolBar/ToolbarSendReceive");
555 /* Create the menu */
556 if (num_accounts > 1) {
557 if (!priv->accounts_popup)
558 priv->accounts_popup = gtk_menu_new ();
559 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
560 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
561 g_signal_connect (G_OBJECT (item),
563 G_CALLBACK (on_send_receive_csm_activated),
565 item = gtk_separator_menu_item_new ();
566 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
569 /* Create a new action group */
570 default_account = modest_account_mgr_get_default_account (mgr);
571 action_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
572 for (i = 0; i < num_accounts; i++) {
573 gchar *display_name = NULL;
575 ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
577 /* Create display name. The UI specification specifies a different format string
578 * to use for the default account, though both seem to be "%s", so
579 * I don't see what the point is. murrayc. */
580 if (default_account && account_data->account_name &&
581 !(strcmp (default_account, account_data->account_name) == 0)) {
582 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
583 account_data->display_name);
586 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
587 account_data->display_name);
590 /* Create action and add it to the action group. The
591 action name must be the account name, this way we
592 could know in the handlers the account to show */
593 if(account_data && account_data->account_name) {
594 gchar* item_name, *refresh_action_name;
596 GtkAction *view_account_action, *refresh_account_action;
598 view_account_action = gtk_action_new (account_data->account_name,
599 display_name, NULL, NULL);
600 gtk_action_group_add_action (action_group, view_account_action);
602 /* Add ui from account data. We allow 2^9-1 account
603 changes in a single execution because we're
604 downcasting the guint to a guint8 in order to use a
605 GByteArray. It should be enough. */
606 item_name = g_strconcat (account_data->account_name, "Menu", NULL);
607 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
608 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
609 gtk_ui_manager_add_ui (parent_priv->ui_manager,
611 "/MenuBar/ViewMenu/ViewMenuAdditions",
613 account_data->account_name,
614 GTK_UI_MANAGER_MENUITEM,
617 /* Connect the action signal "activate" */
618 g_signal_connect (G_OBJECT (view_account_action),
620 G_CALLBACK (on_show_account_action_activated),
623 /* Create the items for the Tools->Send&Receive submenu */
624 refresh_action_name = g_strconcat ("SendReceive", account_data->account_name, NULL);
625 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
626 display_name, NULL, NULL);
627 printf("DEBUG: %s: menu display_name=%s\n", __FUNCTION__, display_name);
628 gtk_action_group_add_action (action_group, refresh_account_action);
630 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
631 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
632 gtk_ui_manager_add_ui (parent_priv->ui_manager,
634 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
637 GTK_UI_MANAGER_MENUITEM,
639 g_free (refresh_action_name);
641 g_signal_connect_data (G_OBJECT (refresh_account_action),
643 G_CALLBACK (on_refresh_account_action_activated),
644 g_strdup (account_data->account_name),
645 (GClosureNotify) g_free,
648 /* Create item and add it to the send&receive
649 CSM. If there is only one account then
651 if (priv->accounts_popup) {
652 GtkWidget *label = gtk_label_new(NULL);
653 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
654 if (default_account && (strcmp(account_data->account_name, default_account) == 0))
656 gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
657 gtk_label_set_markup (GTK_LABEL (label), escaped);
662 gtk_label_set_text (GTK_LABEL (label), display_name);
665 item = gtk_menu_item_new ();
666 gtk_container_add (GTK_CONTAINER (item), label);
668 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
669 g_signal_connect_data (G_OBJECT (item),
671 G_CALLBACK (on_send_receive_csm_activated),
672 g_strdup (account_data->account_name),
673 (GClosureNotify) g_free,
680 g_free (display_name);
683 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 1);
685 /* We cannot do this in the loop above because this relies on the action
686 * group being inserted. This makes the default account appear in bold.
687 * I agree it is a rather ugly way, but I don't see another possibility. armin. */
688 for (i = 0; i < num_accounts; i++) {
689 ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
691 if(account_data->account_name && default_account &&
692 strcmp (account_data->account_name, default_account) == 0) {
693 gchar *item_name = g_strconcat (account_data->account_name, "Menu", NULL);
695 gchar *path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
696 GtkWidget *item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
700 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
701 if (GTK_IS_LABEL (child)) {
702 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
703 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
704 gtk_label_set_markup (GTK_LABEL (child), bold_name);
709 path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", item_name, NULL);
710 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
714 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
715 if (GTK_IS_LABEL (child)) {
716 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
717 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
718 gtk_label_set_markup (GTK_LABEL (child), bold_name);
726 modest_account_mgr_free_account_data (mgr, account_data);
729 if (priv->accounts_popup) {
730 /* Mandatory in order to view the menu contents */
731 gtk_widget_show_all (priv->accounts_popup);
733 /* Setup tap_and_hold just if was not done before*/
734 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
735 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
739 g_slist_free (accounts);
740 g_free (default_account);
743 /* Make sure that at least one account is viewed if there are any
744 * accounts, for instance when adding the first account: */
745 set_at_least_one_account_visible (self);
749 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
751 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
752 gtk_scrolled_window_add_with_viewport
753 (GTK_SCROLLED_WINDOW(win), widget);
755 gtk_container_add (GTK_CONTAINER(win),
760 /* static gboolean */
761 /* on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self) */
763 /* modest_window_save_state (MODEST_WINDOW(self)); */
768 /* on_sendqueue_error_happened (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *err, ModestMainWindow *user_data) */
771 /* printf ("DEBUG: %s: err->code=%d, err->message=%s\n", __FUNCTION__, err->code, err->message); */
773 /* if (err->code == TNY_ACCOUNT_ERROR_TRY_CONNECT_USER_CANCEL) */
774 /* /\* Don't show waste the user's time by showing him a dialog telling him */
775 /* * that he has just cancelled something: *\/ */
779 /* /\* Get the server name: *\/ */
780 /* const gchar* server_name = NULL; */
782 /* TnyCamelTransportAccount* server_account = tny_camel_send_queue_get_transport_account ( */
783 /* TNY_CAMEL_SEND_QUEUE (self)); */
784 /* if (server_account) { */
785 /* server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account)); */
787 /* g_object_unref (server_account); */
788 /* server_account = NULL; */
791 /* if (!server_name) */
792 /* server_name = _("Unknown Server"); */
794 /* /\* Show the appropriate message text for the GError: *\/ */
795 /* gchar *message = NULL; */
797 /* switch (err->code) { */
798 /* case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED: */
799 /* message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name); */
801 /* case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE: */
802 /* message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name); */
804 /* case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED: */
805 /* /\* TODO: This logical ID seems more suitable for a wrong username or password than for a */
806 /* * wrong authentication method. The user is unlikely to guess at the real cause. */
808 /* message = g_strdup_printf (_("eemev_ni_ui_smtp_authentication_fail_error"), server_name); */
810 /* case TNY_TRANSPORT_ACCOUNT_ERROR_SEND: */
811 /* /\* TODO: Tinymail is still sending this sometimes when it should */
812 /* * send TNY_ACCOUNT_ERROR_TRY_CONNECT_USER_CANCEL. *\/ */
814 /* message = g_strdup (_("emev_ib_ui_smtp_send_error")); */
818 /* message = g_strdup (_("emev_ib_ui_smtp_send_error")); */
821 /* modest_maemo_show_information_note_and_forget (GTK_WINDOW (user_data), message); */
822 /* g_free (message); */
824 /* /\* TODO: Offer to remove the message, to avoid messages in future? *\/ */
826 /* TnyFolder *outbox = tny_send_queue_get_outbox (queue); */
827 /* tny_folder_remove_msg (outbox, header, NULL); */
828 /* tny_folder_sync (outbox, TRUE, NULL); */
829 /* g_object_unref (outbox); */
839 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
841 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
843 GList *oerrsignals = priv->queue_err_signals;
844 while (oerrsignals) {
845 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
846 g_signal_handler_disconnect (esignal->queue, esignal->signal);
847 g_slice_free (QueueErrorSignal, esignal);
848 oerrsignals = g_list_next (oerrsignals);
850 g_list_free (priv->queue_err_signals);
851 priv->queue_err_signals = NULL;
855 /* on_account_store_connecting_finished (TnyAccountStore *store, ModestMainWindow *self) */
857 /* ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self); */
859 /* /\* When going online, do the equivalent of pressing the send/receive button, */
860 /* * as per the specification: */
861 /* * (without the check for >0 accounts, though that is not specified): *\/ */
863 /* TnyDevice *device = tny_account_store_get_device (store); */
865 /* /\* modest_folder_view_update_model (MODEST_FOLDER_VIEW (priv->folder_view), store); *\/ */
867 /* /\* Check that we are really online. */
868 /* * This signal should not be emitted when we are not connected, */
869 /* * but it seems to happen sometimes: *\/ */
870 /* if (!tny_device_is_online (device)) */
873 /* const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device)); */
874 /* printf ("DEBUG: %s: connection id=%s\n", __FUNCTION__, iap_id); */
876 /* /\* Stop the existing send queues: *\/ */
877 /* modest_runtime_remove_all_send_queues (); */
879 /* /\* Create the send queues again, using the appropriate transport accounts */
880 /* * for this new connection. */
881 /* * This could be the first time that they are created if this is the first */
882 /* * connection. *\/ */
883 /* /\* TODO: Does this really destroy the TnySendQueues and their threads */
884 /* * We do not want 2 TnySendQueues to exist with the same underlying */
885 /* * outbox directory. *\/ */
887 /* modest_main_window_cleanup_queue_error_signals (self); */
889 /* GSList *account_names = modest_account_mgr_account_names ( */
890 /* modest_runtime_get_account_mgr(), */
891 /* TRUE /\* enabled accounts only *\/); */
892 /* GSList *iter = account_names; */
894 /* const gchar *account_name = (const gchar*)(iter->data); */
895 /* if (account_name) { */
896 /* TnyTransportAccount *account = TNY_TRANSPORT_ACCOUNT ( */
897 /* modest_tny_account_store_get_transport_account_for_open_connection */
898 /* (modest_runtime_get_account_store(), account_name)); */
900 /* /\* Q: Is this the first location where the send-queues are requested? *\/ */
901 /* QueueErrorSignal *esignal = g_slice_new (QueueErrorSignal); */
902 /* printf ("debug: %s:\n Transport account for %s: %s\n", __FUNCTION__, account_name, */
903 /* tny_account_get_id(TNY_ACCOUNT(account))); */
904 /* esignal->queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (account)); */
905 /* esignal->signal = g_signal_connect (G_OBJECT (esignal->queue), "error-happened", */
906 /* G_CALLBACK (on_sendqueue_error_happened), self); */
907 /* priv->queue_err_signals = g_list_prepend (priv->queue_err_signals, esignal); */
911 /* iter = g_slist_next (iter); */
914 /* modest_account_mgr_free_account_names (account_names); */
915 /* account_names = NULL; */
917 /* modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (self)); */
921 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
923 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
926 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
930 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
932 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
934 /* Update visibility */
937 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
941 modest_main_window_disconnect_signals (ModestWindow *self)
943 ModestMainWindowPrivate *priv;
944 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
946 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
947 priv->sighandlers = NULL;
951 connect_signals (ModestMainWindow *self)
953 ModestWindowPrivate *parent_priv;
954 ModestMainWindowPrivate *priv;
957 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
958 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
962 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
963 G_OBJECT(priv->folder_view), "key-press-event",
964 G_CALLBACK(on_inner_widgets_key_pressed), self);
965 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view), "folder_selection_changed",
966 G_CALLBACK(modest_main_window_on_folder_selection_changed), self);
967 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view), "folder-display-name-changed",
968 G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
969 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view), "focus-in-event",
970 G_CALLBACK (on_folder_view_focus_in), self);
972 /* Folder view CSM */
973 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
974 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
975 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
976 G_CALLBACK(_folder_view_csm_menu_activated),
979 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
980 G_CALLBACK(modest_ui_actions_on_header_selected), self);
981 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
982 G_CALLBACK(modest_ui_actions_on_header_activated), self);
983 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
984 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
985 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
986 G_CALLBACK(on_inner_widgets_key_pressed), self);
987 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
988 G_CALLBACK(_on_msg_count_changed), self);
989 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
990 G_CALLBACK (on_header_view_focus_in), self);
992 /* Header view CSM */
993 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
994 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
995 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
996 G_CALLBACK(_header_view_csm_menu_activated),
1000 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
1001 G_CALLBACK (modest_main_window_window_state_event),
1004 /* Mail Operation Queue */
1005 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_mail_operation_queue ()),
1006 "queue-changed", G_CALLBACK (on_queue_changed), self);
1008 /* Track changes in the device name */
1009 priv->notification_id = modest_conf_listen_to_namespace (modest_runtime_get_conf (),
1010 MODEST_CONF_NAMESPACE);
1011 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(modest_runtime_get_conf ()),
1012 "key_changed", G_CALLBACK (on_configuration_key_changed),
1015 /* Track account changes. We need to refresh the toolbar */
1016 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_store ()),
1017 "account_inserted", G_CALLBACK (on_account_inserted),
1019 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_store ()),
1020 "account_removed", G_CALLBACK (on_account_removed),
1023 /* We need to refresh the send & receive menu to change the bold
1024 * account when the default account changes. */
1025 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_mgr ()),
1026 "account_changed", G_CALLBACK (on_account_changed),
1030 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_store()),
1031 "password_requested",
1032 G_CALLBACK (modest_ui_actions_on_password_requested), self);
1036 /** Idle handler, to send/receive at startup .*/
1038 sync_accounts_cb (ModestMainWindow *win)
1040 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (win));
1041 return FALSE; /* Do not call this idle handler again. */
1045 static void on_hildon_program_is_topmost_notify(GObject *self,
1046 GParamSpec *propert_param, gpointer user_data)
1048 HildonProgram *app = HILDON_PROGRAM (self);
1051 ModestWindow* self = MODEST_WINDOW(user_data);
1054 /* Note that use of hildon_program_set_can_hibernate()
1055 * is generally referred to as "setting the killable flag",
1056 * though hibernation does not seem equal to death.
1059 if (hildon_program_get_is_topmost (app)) {
1060 /* Prevent hibernation when the progam comes to the foreground,
1061 * because hibernation should only happen when the application
1062 * is in the background: */
1063 hildon_program_set_can_hibernate (app, FALSE);
1065 /* Allow hibernation if the program has gone to the background: */
1067 /* However, prevent hibernation while the settings are being changed: */
1068 const gboolean hibernation_prevented =
1069 modest_window_mgr_get_hibernation_is_prevented (
1070 modest_runtime_get_window_mgr ());
1072 if (hibernation_prevented)
1073 hildon_program_set_can_hibernate (app, FALSE);
1075 /* Allow hibernation, after saving the state: */
1076 modest_osso_save_state();
1077 hildon_program_set_can_hibernate (app, TRUE);
1084 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
1086 GtkWidget *folder_win = (GtkWidget *) user_data;
1087 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1089 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
1090 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
1091 /* wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view)); */
1093 gtk_widget_show (GTK_WIDGET (priv->folder_view));
1095 /* Connect signals */
1096 connect_signals ((ModestMainWindow*)self);
1098 /* Set account store */
1099 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
1100 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1102 /* Load previous osso state, for instance if we are being restored from
1104 modest_osso_load_state ();
1106 /* Restore window & widget settings */
1108 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
1110 /* The UI spec wants us to show a connection dialog when the application is
1111 * started by the user, if there is no connection.
1112 * Do this before showing the account wizard,
1113 * because wizard needs a connection to discover capabilities. */
1114 modest_platform_connect_and_wait (GTK_WINDOW (self), NULL);
1116 /* Check if accounts exist and show the account wizard if not */
1117 gboolean accounts_exist =
1118 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1120 if (!accounts_exist) {
1121 /* This is necessary to have the main window shown behind the dialog
1122 It's an ugly hack... jschmid */
1123 gtk_widget_show_all(GTK_WIDGET(self));
1124 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
1127 GtkAction *send_receive_all;
1128 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1129 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
1130 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1131 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1132 gtk_action_set_visible (send_receive_all, g_slist_length (accounts) > 1);
1133 modest_account_mgr_free_account_names (accounts);
1138 modest_main_window_new (void)
1140 ModestMainWindow *self = NULL;
1141 ModestMainWindowPrivate *priv = NULL;
1142 ModestWindowPrivate *parent_priv = NULL;
1143 GtkWidget *folder_win = NULL;
1144 ModestDimmingRulesGroup *menu_rules_group = NULL;
1145 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1146 GtkActionGroup *action_group = NULL;
1147 GError *error = NULL;
1148 ModestConf *conf = NULL;
1149 GtkAction *action = NULL;
1150 GdkPixbuf *window_icon;
1152 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
1153 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1154 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1156 parent_priv->ui_manager = gtk_ui_manager_new();
1157 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
1159 action_group = gtk_action_group_new ("ModestMainWindowActions");
1160 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1162 menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules", FALSE);
1163 toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules", TRUE);
1165 /* Add common actions */
1166 gtk_action_group_add_actions (action_group,
1167 modest_action_entries,
1168 G_N_ELEMENTS (modest_action_entries),
1171 gtk_action_group_add_actions (action_group,
1172 modest_folder_view_action_entries,
1173 G_N_ELEMENTS (modest_folder_view_action_entries),
1176 gtk_action_group_add_actions (action_group,
1177 modest_header_view_action_entries,
1178 G_N_ELEMENTS (modest_header_view_action_entries),
1181 gtk_action_group_add_toggle_actions (action_group,
1182 modest_toggle_action_entries,
1183 G_N_ELEMENTS (modest_toggle_action_entries),
1186 gtk_action_group_add_toggle_actions (action_group,
1187 modest_main_window_toggle_action_entries,
1188 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
1191 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
1192 g_object_unref (action_group);
1194 /* Load the UI definition */
1195 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
1196 MODEST_UIDIR "modest-main-window-ui.xml", &error);
1197 if (error != NULL) {
1198 g_warning ("Could not merge modest-ui.xml: %s", error->message);
1199 g_error_free (error);
1203 /* Add common dimming rules */
1204 modest_dimming_rules_group_add_rules (menu_rules_group,
1205 modest_main_window_menu_dimming_entries,
1206 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
1208 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1209 modest_main_window_toolbar_dimming_entries,
1210 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
1213 /* Insert dimming rules group for this window */
1214 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1215 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1216 g_object_unref (menu_rules_group);
1217 g_object_unref (toolbar_rules_group);
1219 /* Add accelerators */
1220 gtk_window_add_accel_group (GTK_WINDOW (self),
1221 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
1223 /* Menubar. Update the state of some toggles */
1224 parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
1225 conf = modest_runtime_get_conf ();
1226 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1227 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
1228 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1229 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR, NULL));
1230 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1231 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
1232 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1233 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
1234 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
1235 gtk_widget_show (parent_priv->menubar);
1237 /* Get device name */
1238 modest_maemo_utils_get_device_name ();
1242 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
1243 if (!priv->header_view)
1244 g_printerr ("modest: cannot instantiate header view\n");
1245 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
1246 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
1247 MODEST_CONF_HEADER_VIEW_KEY);
1249 /* Other style properties of header view */
1250 g_object_set (G_OBJECT (priv->header_view),
1251 "rules-hint", FALSE,
1253 /* gtk_widget_show (priv->header_view); */
1256 priv->empty_view = create_empty_view ();
1257 gtk_widget_show (priv->empty_view);
1259 /* Create scrolled windows */
1260 folder_win = gtk_scrolled_window_new (NULL, NULL);
1261 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
1262 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
1264 GTK_POLICY_AUTOMATIC);
1265 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
1267 GTK_POLICY_AUTOMATIC);
1268 /* gtk_widget_show (priv->contents_widget); */
1271 priv->main_paned = gtk_hpaned_new ();
1272 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
1273 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
1274 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
1276 /* putting it all together... */
1277 priv->main_vbox = gtk_vbox_new (FALSE, 6);
1278 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
1279 gtk_widget_show (priv->main_vbox);
1281 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
1283 HildonProgram *app = hildon_program_get_instance ();
1284 hildon_program_add_window (app, HILDON_WINDOW (self));
1286 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
1287 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
1289 g_signal_connect (G_OBJECT(self), "show",
1290 G_CALLBACK (modest_main_window_on_show), folder_win);
1292 /* Set window icon */
1293 window_icon = modest_platform_get_icon (MODEST_APP_ICON);
1295 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
1296 g_object_unref (window_icon);
1299 /* Dont't restore settings here,
1300 * because it requires a gtk_widget_show(),
1301 * and we don't want to do that until later,
1302 * so that the UI is not visible for non-menu D-Bus activation.
1304 /* restore_settings (MODEST_MAIN_WINDOW(self), FALSE); */
1306 return MODEST_WINDOW(self);
1310 modest_main_window_close_all (ModestMainWindow *self)
1313 GtkResponseType response;
1315 /* Create the confirmation dialog MSG-NOT308 */
1316 note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
1317 _("emev_nc_close_windows"),
1318 _("mcen_bd_yes"), GTK_RESPONSE_YES,
1319 _("mcen_bd_no"), GTK_RESPONSE_NO,
1322 response = gtk_dialog_run (GTK_DIALOG (note));
1323 gtk_widget_destroy (GTK_WIDGET (note));
1325 if (response == GTK_RESPONSE_YES)
1333 modest_main_window_set_style (ModestMainWindow *self,
1334 ModestMainWindowStyle style)
1336 ModestMainWindowPrivate *priv;
1337 ModestWindowPrivate *parent_priv;
1341 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1343 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1344 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1346 /* no change -> nothing to do */
1347 if (priv->style == style)
1350 /* Get toggle button and update the state if needed. This will
1351 happen only when the set_style is not invoked from the UI,
1352 for example when it's called from widget memory */
1353 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1354 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
1355 if ((active && style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) ||
1356 (!active && style == MODEST_MAIN_WINDOW_STYLE_SPLIT)) {
1357 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1358 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !active);
1359 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1362 priv->style = style;
1364 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
1365 /* Remove main paned */
1366 g_object_ref (priv->main_paned);
1367 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1369 /* Reparent the contents widget to the main vbox */
1370 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
1373 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1374 /* Remove header view */
1375 g_object_ref (priv->contents_widget);
1376 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1378 /* Reparent the main paned */
1379 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1380 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1384 g_return_if_reached ();
1387 /* Let header view grab the focus if it's being shown */
1388 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1389 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1391 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1394 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1397 ModestMainWindowStyle
1398 modest_main_window_get_style (ModestMainWindow *self)
1400 ModestMainWindowPrivate *priv;
1402 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1404 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1411 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1413 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1414 ModestWindowPrivate *parent_priv;
1415 ModestWindowMgr *mgr;
1416 gboolean is_fullscreen;
1417 GtkAction *fs_toggle_action;
1420 mgr = modest_runtime_get_window_mgr ();
1422 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1424 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1426 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1427 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1428 if (is_fullscreen != active) {
1429 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1438 set_homogeneous (GtkWidget *widget,
1441 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
1442 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
1446 modest_main_window_show_toolbar (ModestWindow *self,
1447 gboolean show_toolbar)
1449 ModestMainWindowPrivate *priv = NULL;
1450 ModestWindowPrivate *parent_priv = NULL;
1451 GtkWidget *reply_button = NULL, *menu = NULL;
1452 GtkWidget *placeholder = NULL;
1453 ModestAccountMgr *mgr = NULL;
1454 TnyTransportAccount *transport_account = NULL;
1455 ModestTnySendQueue *send_queue = NULL;
1457 GSList *iter = NULL;
1458 GSList *account_names = NULL;
1459 const gchar *action_name;
1462 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1463 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1464 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1466 /* Set optimized view status */
1467 priv->optimized_view = !show_toolbar;
1469 if (!parent_priv->toolbar) {
1470 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1472 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1474 /* Set homogeneous toolbar */
1475 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar),
1476 set_homogeneous, NULL);
1478 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1479 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1480 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1481 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1482 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1483 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1484 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1485 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1487 /* Add ProgressBar (Transfer toolbar) */
1488 priv->progress_bar = modest_progress_bar_widget_new ();
1489 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1490 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1491 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1492 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1493 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1495 /* Connect cancel 'clicked' signal to abort progress mode */
1496 g_signal_connect(priv->cancel_toolitem, "clicked",
1497 G_CALLBACK(cancel_progressbar),
1500 /* Add it to the observers list */
1501 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1504 hildon_window_add_toolbar (HILDON_WINDOW (self),
1505 GTK_TOOLBAR (parent_priv->toolbar));
1507 /* Set reply button tap and hold menu */
1508 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1509 "/ToolBar/ToolbarMessageReply");
1510 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1511 "/ToolbarReplyCSM");
1512 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1514 /* Set send & receive button tap and hold menu */
1515 update_menus (MODEST_MAIN_WINDOW (self));
1517 /* Create send queue for all defined accounts */
1518 mgr = modest_runtime_get_account_mgr ();
1519 account_names = modest_account_mgr_account_names (mgr, TRUE);
1520 iter = account_names;
1523 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1524 (modest_runtime_get_account_store(),
1526 TNY_ACCOUNT_TYPE_TRANSPORT));
1528 /* Create new send queue for this new account */
1529 send_queue = modest_runtime_get_send_queue (transport_account);
1530 if (MODEST_IS_TNY_SEND_QUEUE(send_queue)) {
1532 /* Connect 'status_changed' signal of this new send-queue */
1533 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT (send_queue), "status_changed",
1534 G_CALLBACK (modest_main_window_on_send_queue_status_canged),
1541 if (send_queue != NULL)
1542 g_object_unref (send_queue);
1543 if (transport_account != NULL)
1544 g_object_unref (transport_account);
1547 modest_account_mgr_free_account_names (account_names);
1551 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1552 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1553 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1555 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1556 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1558 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1562 /* Update also the actions (to update the toggles in the
1563 menus), we have to do it manually because some other window
1564 of the same time could have changed it (remember that the
1565 toolbar fullscreen mode is shared by all the windows of the
1567 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
1568 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarFullScreenMenu";
1570 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarNormalScreenMenu";
1572 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
1573 modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
1578 modest_main_window_on_send_queue_status_canged (ModestTnySendQueue *send_queue,
1583 ModestMainWindowPrivate *priv = NULL;
1584 TnyFolderStore *selected_folder = NULL;
1585 TnyFolderType folder_type;
1587 g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (send_queue));
1588 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1589 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(user_data);
1591 /* Check if selected folder is OUTBOX */
1592 selected_folder = modest_folder_view_get_selected (priv->folder_view);
1593 if (!TNY_IS_FOLDER (selected_folder)) goto frees;
1594 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
1595 #if GTK_CHECK_VERSION(2, 8, 0) /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
1596 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1597 GtkTreeViewColumn * tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (priv->header_view),
1598 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
1599 gtk_tree_view_column_queue_resize (tree_column);
1605 if (selected_folder != NULL)
1606 g_object_unref (selected_folder);
1610 on_account_inserted (TnyAccountStore *accoust_store,
1611 TnyAccount *account,
1614 TnyTransportAccount *transport_account = NULL;
1615 ModestTnySendQueue *send_queue = NULL;
1616 ModestMainWindowPrivate *priv;
1617 const gchar *account_name = NULL;
1619 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1620 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1622 update_menus (MODEST_MAIN_WINDOW (user_data));
1624 /* Get transport account */
1625 account_name = tny_account_get_name (TNY_ACCOUNT (account));
1627 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1628 (modest_runtime_get_account_store(),
1630 TNY_ACCOUNT_TYPE_TRANSPORT));
1632 /* Create new send queue for this new account */
1633 send_queue = modest_runtime_get_send_queue (transport_account);
1634 if (!MODEST_IS_TNY_SEND_QUEUE(send_queue)) goto frees;
1636 /* Connect 'status_changed' signal of this new send-queue */
1637 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (send_queue), "status_changed",
1638 G_CALLBACK (modest_main_window_on_send_queue_status_canged),
1643 if (transport_account != NULL)
1644 g_object_unref (G_OBJECT (transport_account));
1645 if (send_queue != NULL)
1646 g_object_unref (send_queue);
1650 on_account_changed (ModestAccountMgr* mgr,
1651 const gchar* account,
1654 gchar *default_account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
1656 /* Actually, we only want to know when another account has become
1657 * the default account, but there is no default_account_changed
1658 * signal in ModestAccountMgr. */
1659 if(strcmp(account, default_account) == 0)
1660 update_menus (MODEST_MAIN_WINDOW (user_data));
1662 g_free (default_account);
1666 on_account_removed (TnyAccountStore *accoust_store,
1667 TnyAccount *account,
1670 update_menus (MODEST_MAIN_WINDOW (user_data));
1674 * This function manages the key events used to navigate between
1675 * header and folder views (when the window is in split view)
1678 * -------------------------------------------------
1679 * HeaderView GDK_Left Move focus to folder view
1680 * FolderView GDK_Right Move focus to header view
1682 * There is no need to scroll to selected row, the widgets will be the
1683 * responsibles of doing that (probably managing the focus-in event
1686 on_inner_widgets_key_pressed (GtkWidget *widget,
1690 ModestMainWindowPrivate *priv;
1692 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1694 /* Do nothing if we're in SIMPLE style */
1695 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1698 if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
1699 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1700 else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1701 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1707 set_alignment (GtkWidget *widget,
1710 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1711 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1715 create_empty_view (void)
1717 GtkLabel *label = NULL;
1718 GtkWidget *align = NULL;
1720 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1721 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1722 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1723 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1725 return GTK_WIDGET(align);
1729 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1731 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1736 gchar *gray_color_markup;
1738 vbox = gtk_vbox_new (FALSE, 0);
1740 /* Obtain the secondary text color. We need a realized widget, that's why
1741 we get styled_widget from outside */
1742 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1744 gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color);
1745 gray_color_markup = modest_text_utils_get_color_string (&color);
1747 // gray_color_markup is freed below
1748 gray_color_markup = g_strdup ("#BBBBBB");
1750 /* Account description: */
1752 if (modest_tny_account_is_virtual_local_folders (account)
1753 || (modest_tny_account_is_memory_card_account (account))) {
1755 /* Local folders: */
1757 /* Get device name */
1758 gchar *device_name = NULL;
1759 if (modest_tny_account_is_virtual_local_folders (account))
1760 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1761 MODEST_CONF_DEVICE_NAME, NULL);
1763 device_name = g_strdup (tny_account_get_name (account));
1765 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), ""); //TODO: Why the ""?
1766 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1767 gray_color_markup, tmp, device_name);
1769 label_w = gtk_label_new (NULL);
1770 gtk_label_set_markup (GTK_LABEL (label_w), label);
1771 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1772 g_free (device_name);
1775 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1776 gtk_box_pack_start (GTK_BOX (vbox),
1777 gtk_label_new (tny_account_get_name (account)),
1780 /* Other accounts, such as IMAP and POP: */
1785 /* Put proto in uppercase */
1786 proto = g_string_new (tny_account_get_proto (account));
1787 proto = g_string_ascii_up (proto);
1789 /* note: mcen_fi_localroot_description is something like "%s account"
1790 * however, we should display "%s account: %s"... therefore, ugly tmp */
1791 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1792 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1793 gray_color_markup, tmp, tny_account_get_name (account));
1796 label_w = gtk_label_new (NULL);
1797 gtk_label_set_markup (GTK_LABEL (label_w), label);
1798 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1799 g_string_free (proto, TRUE);
1805 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1806 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1807 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1808 modest_tny_folder_store_get_message_count (folder_store));
1809 label_w = gtk_label_new (NULL);
1810 gtk_label_set_markup (GTK_LABEL (label_w), label);
1811 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1815 label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d",
1817 _("mcen_fi_rootfolder_folders"),
1818 modest_tny_folder_store_get_folder_count (folder_store));
1819 label_w = gtk_label_new (NULL);
1820 gtk_label_set_markup (GTK_LABEL (label_w), label);
1821 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1825 if (modest_tny_account_is_virtual_local_folders (account)
1826 || modest_tny_account_is_memory_card_account (account)) {
1828 gchar *size = modest_text_utils_get_display_size (
1829 modest_tny_folder_store_get_local_size (folder_store));
1831 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1832 gray_color_markup, _("mcen_fi_rootfolder_size"),
1836 label_w = gtk_label_new (NULL);
1837 gtk_label_set_markup (GTK_LABEL (label_w), label);
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 gchar *last_updated_string;
1845 /* Get last updated from configuration */
1846 last_updated = modest_account_mgr_get_int (modest_runtime_get_account_mgr (),
1847 tny_account_get_id (account),
1848 MODEST_ACCOUNT_LAST_UPDATED,
1850 if (last_updated > 0)
1851 last_updated_string = modest_text_utils_get_display_date(last_updated);
1853 last_updated_string = g_strdup (_("mcen_va_never"));
1855 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1856 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1857 label_w = gtk_label_new (NULL);
1858 gtk_label_set_markup (GTK_LABEL (label_w), label);
1859 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1860 g_free (last_updated_string);
1864 g_free (gray_color_markup);
1867 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1873 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1875 ModestMainWindowPrivate *priv = NULL;
1877 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1879 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1881 return priv->send_receive_in_progress;
1885 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1887 GtkAction *action = NULL;
1888 GtkWidget *widget = NULL;
1889 ModestMainWindowPrivate *priv = NULL;
1891 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1892 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1894 priv->send_receive_in_progress = TRUE;
1896 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1897 gtk_action_set_sensitive (action, FALSE);
1898 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1899 /* gtk_action_set_sensitive (action, FALSE); */
1900 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1901 gtk_widget_set_sensitive (widget, FALSE);
1905 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1907 GtkAction *action = NULL;
1908 GtkWidget *widget = NULL;
1909 ModestMainWindowPrivate *priv = NULL;
1911 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1912 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1914 priv->send_receive_in_progress = FALSE;
1916 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1917 gtk_action_set_sensitive (action, TRUE);
1918 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1919 /* gtk_action_set_sensitive (action, TRUE); */
1920 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1921 gtk_widget_set_sensitive (widget, TRUE);
1926 _on_msg_count_changed (ModestHeaderView *header_view,
1928 TnyFolderChange *change,
1929 ModestMainWindow *main_window)
1931 printf ("DEBUG: %s\n", __FUNCTION__);
1932 gboolean folder_empty = FALSE;
1933 gboolean all_marked_as_deleted = FALSE;
1934 TnyFolderChangeChanged changed;
1935 ModestMainWindowPrivate *priv;
1937 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1938 g_return_if_fail (TNY_IS_FOLDER(folder));
1939 g_return_if_fail (TNY_IS_FOLDER_CHANGE(change));
1940 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
1942 changed = tny_folder_change_get_changed (change);
1944 /* If something changes */
1945 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1946 folder_empty = (tny_folder_change_get_new_all_count (change) == 0);
1948 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1950 printf ("DEBUG: %s: folder_empty=%d\n", __FUNCTION__, folder_empty);
1952 /* Check header removed (hide marked as DELETED headers) */
1953 if (changed & TNY_FOLDER_CHANGE_CHANGED_EXPUNGED_HEADERS) {
1954 modest_header_view_refilter (MODEST_HEADER_VIEW(priv->header_view));
1957 /* Check if all messages are marked to be deleted */
1958 all_marked_as_deleted = modest_header_view_is_empty (header_view);
1959 folder_empty = folder_empty || all_marked_as_deleted ;
1961 /* Set contents style of headers view */
1963 modest_main_window_set_contents_style (main_window,
1964 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1965 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1968 modest_main_window_set_contents_style (main_window,
1969 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1975 modest_main_window_set_contents_style (ModestMainWindow *self,
1976 ModestMainWindowContentsStyle style)
1978 ModestMainWindowPrivate *priv;
1980 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1982 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1984 /* We allow to set the same content style than the previously
1985 set if there are details, because it could happen when we're
1986 selecting different accounts consecutively */
1987 if ((priv->contents_style == style) &&
1988 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1991 /* Remove previous child. Delete it if it was an account
1993 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1995 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1996 g_object_ref (content);
1997 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1998 g_object_ref (priv->empty_view);
1999 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
2002 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
2005 priv->contents_style = style;
2007 switch (priv->contents_style) {
2008 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
2009 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
2010 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2013 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
2015 /* if we're started without main win, there may not be a folder
2016 * view. this fixes a GLib-Critical */
2017 if (priv->folder_view) {
2018 TnyFolderStore *selected_folderstore =
2019 modest_folder_view_get_selected (priv->folder_view);
2020 if (TNY_IS_ACCOUNT (selected_folderstore)) {
2021 priv->details_widget = create_details_widget (GTK_WIDGET (self),
2022 TNY_ACCOUNT (selected_folderstore));
2024 wrap_in_scrolled_window (priv->contents_widget,
2025 priv->details_widget);
2027 g_object_unref (selected_folderstore);
2028 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2033 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
2034 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
2035 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2039 g_return_if_reached ();
2043 gtk_widget_show_all (priv->contents_widget);
2046 ModestMainWindowContentsStyle
2047 modest_main_window_get_contents_style (ModestMainWindow *self)
2049 ModestMainWindowPrivate *priv;
2051 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
2053 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2054 return priv->contents_style;
2059 on_configuration_key_changed (ModestConf* conf,
2061 ModestConfEvent event,
2062 ModestConfNotificationId id,
2063 ModestMainWindow *self)
2065 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2066 TnyAccount *account = NULL;
2069 priv->notification_id != id ||
2070 strcmp (key, MODEST_CONF_DEVICE_NAME))
2073 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
2075 if (priv->folder_view)
2076 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
2077 if (account && TNY_IS_ACCOUNT (account) &&
2078 strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID) == 0) {
2081 const gchar *device_name;
2085 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
2086 label = GTK_LABEL (children->data);
2088 device_name = modest_conf_get_string (modest_runtime_get_conf(),
2089 MODEST_CONF_DEVICE_NAME, NULL);
2091 new_text = g_strdup_printf ("%s: %s",
2092 _("mcen_fi_localroot_description"),
2095 gtk_label_set_text (label, new_text);
2096 gtk_widget_show (GTK_WIDGET (label));
2099 g_list_free (children);
2101 g_object_unref (account);
2105 set_toolbar_transfer_mode (ModestMainWindow *self)
2107 ModestMainWindowPrivate *priv = NULL;
2109 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2111 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2113 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
2115 if (priv->progress_bar_timeout > 0) {
2116 g_source_remove (priv->progress_bar_timeout);
2117 priv->progress_bar_timeout = 0;
2124 set_toolbar_mode (ModestMainWindow *self,
2125 ModestToolBarModes mode)
2127 ModestWindowPrivate *parent_priv = NULL;
2128 ModestMainWindowPrivate *priv = NULL;
2129 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
2131 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2133 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2134 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2136 /* In case this was called before the toolbar exists: */
2137 if (!(parent_priv->toolbar))
2140 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
2142 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
2143 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
2144 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
2146 /* Sets current toolbar mode */
2147 priv->current_toolbar_mode = mode;
2149 /* Checks the dimming rules */
2150 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2152 /* Show and hide toolbar items */
2154 case TOOLBAR_MODE_NORMAL:
2156 gtk_action_set_visible (sort_action, TRUE);
2158 gtk_action_set_visible (refresh_action, TRUE);
2159 if (priv->progress_toolitem) {
2160 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
2161 gtk_widget_hide (priv->progress_toolitem);
2163 if (priv->progress_bar)
2164 gtk_widget_hide (priv->progress_bar);
2167 gtk_action_set_visible (cancel_action, FALSE);
2169 /* Hide toolbar if optimized view is enabled */
2170 if (priv->optimized_view)
2171 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
2173 case TOOLBAR_MODE_TRANSFER:
2175 gtk_action_set_visible (sort_action, FALSE);
2177 gtk_action_set_visible (refresh_action, FALSE);
2179 gtk_action_set_visible (cancel_action, TRUE);
2180 if (priv->progress_toolitem) {
2181 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
2182 gtk_widget_show (priv->progress_toolitem);
2184 if (priv->progress_bar)
2185 gtk_widget_show (priv->progress_bar);
2187 /* Show toolbar if it's hiden (optimized view ) */
2188 if (priv->optimized_view)
2189 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2192 g_return_if_reached ();
2197 modest_main_window_transfer_mode_enabled (ModestMainWindow *self)
2199 ModestMainWindowPrivate *priv;
2201 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2202 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2204 return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
2208 cancel_progressbar (GtkToolButton *toolbutton,
2209 ModestMainWindow *self)
2212 ModestMainWindowPrivate *priv;
2214 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2216 /* Get operation observers and cancel all the operations */
2217 tmp = priv->progress_widgets;
2219 modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2220 tmp=g_slist_next(tmp);
2225 observers_empty (ModestMainWindow *self)
2228 ModestMainWindowPrivate *priv;
2229 gboolean is_empty = TRUE;
2230 guint pending_ops = 0;
2232 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2233 tmp = priv->progress_widgets;
2235 /* Check all observers */
2236 while (tmp && is_empty) {
2237 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2238 is_empty = pending_ops == 0;
2240 tmp = g_slist_next(tmp);
2247 on_queue_changed (ModestMailOperationQueue *queue,
2248 ModestMailOperation *mail_op,
2249 ModestMailOperationQueueNotification type,
2250 ModestMainWindow *self)
2252 ModestMainWindowPrivate *priv;
2253 ModestMailOperationTypeOperation op_type;
2254 ModestToolBarModes mode;
2256 gboolean mode_changed = FALSE;
2258 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2259 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2261 /* Get toolbar mode from operation id*/
2262 op_type = modest_mail_operation_get_type_operation (mail_op);
2264 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
2265 case MODEST_MAIL_OPERATION_TYPE_OPEN:
2266 mode = TOOLBAR_MODE_TRANSFER;
2267 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
2268 mode_changed = TRUE;
2271 mode = TOOLBAR_MODE_NORMAL;
2276 /* Add operation observers and change toolbar if neccessary*/
2277 tmp = priv->progress_widgets;
2279 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
2280 if (mode == TOOLBAR_MODE_TRANSFER) {
2282 set_toolbar_transfer_mode(self);
2285 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2287 tmp = g_slist_next (tmp);
2291 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
2292 /* Change toolbar mode */
2293 if (mode == TOOLBAR_MODE_TRANSFER) {
2295 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2297 tmp = g_slist_next (tmp);
2300 /* If no more operations are being observed, NORMAL mode is enabled again */
2301 if (observers_empty (self)) {
2302 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
2312 set_account_visible(ModestMainWindow *self, const gchar *acc_name)
2314 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2316 /* Get account data */
2317 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
2318 ModestAccountData *acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
2320 /* Set the new visible & active account */
2321 if (acc_data && acc_data->store_account) {
2322 modest_folder_view_set_account_id_of_visible_server_account (priv->folder_view,
2323 acc_data->store_account->account_name);
2324 modest_window_set_active_account (MODEST_WINDOW (self), acc_data->account_name);
2327 modest_folder_view_select_first_inbox_or_local (priv->folder_view);
2331 modest_account_mgr_free_account_data (mgr, acc_data);
2334 /* Make sure that at least one account is "viewed": */
2336 set_at_least_one_account_visible(ModestMainWindow *self)
2338 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2339 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2341 if (!(priv->folder_view)) {
2342 /* It is too early to do this. */
2346 const gchar *active_server_account_name =
2347 modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);
2348 if (!active_server_account_name ||
2349 !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
2351 gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
2352 if (first_modest_name) {
2353 set_account_visible (self, first_modest_name);
2354 g_free (first_modest_name);
2360 on_show_account_action_activated (GtkAction *action,
2363 ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
2365 const gchar *acc_name = gtk_action_get_name (action);
2366 set_account_visible (self, acc_name);
2370 refresh_account (const gchar *account_name)
2374 win = MODEST_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2376 /* If account_name == NULL, we must update all (option All) */
2378 modest_ui_actions_do_send_receive_all (win);
2380 modest_ui_actions_do_send_receive (account_name, win);
2385 on_refresh_account_action_activated (GtkAction *action,
2388 refresh_account ((const gchar*) user_data);
2392 on_send_receive_csm_activated (GtkMenuItem *item,
2395 refresh_account ((const gchar*) user_data);
2399 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2401 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2403 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2409 on_folder_view_focus_in (GtkWidget *widget,
2410 GdkEventFocus *event,
2413 ModestMainWindow *main_window = NULL;
2415 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2416 main_window = MODEST_MAIN_WINDOW (userdata);
2418 /* Update toolbar dimming state */
2419 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2425 on_header_view_focus_in (GtkWidget *widget,
2426 GdkEventFocus *event,
2429 ModestMainWindow *main_window = NULL;
2430 ModestMainWindowPrivate *priv = NULL;
2432 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2433 main_window = MODEST_MAIN_WINDOW (userdata);
2434 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
2436 /* Update toolbar dimming state */
2437 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2443 modest_main_window_on_folder_selection_changed (ModestFolderView *folder_view,
2444 TnyFolderStore *folder_store,
2446 ModestMainWindow *main_window)
2448 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2449 GtkAction *action = NULL;
2450 gboolean show_reply = TRUE;
2451 gboolean show_forward = TRUE;
2452 gboolean show_cancel_send = FALSE;
2453 gboolean show_clipboard = TRUE;
2454 gboolean show_delete = TRUE;
2457 if (TNY_IS_ACCOUNT (folder_store)) {
2458 show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2459 } else if (TNY_IS_FOLDER (folder_store)) {
2460 if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2461 TnyFolderType folder_type = modest_tny_folder_get_local_or_mmc_folder_type (
2462 TNY_FOLDER (folder_store));
2463 switch (folder_type) {
2464 case TNY_FOLDER_TYPE_DRAFTS:
2465 show_clipboard = show_delete = TRUE;
2466 show_reply = show_forward = show_cancel_send = FALSE;
2468 case TNY_FOLDER_TYPE_SENT:
2469 show_forward = show_clipboard = show_delete = TRUE;
2470 show_reply = show_cancel_send = FALSE;
2472 case TNY_FOLDER_TYPE_OUTBOX:
2473 show_clipboard = show_delete = show_cancel_send = TRUE;
2474 show_reply = show_forward = FALSE;
2477 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2478 show_cancel_send = FALSE;
2481 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2482 show_cancel_send = FALSE;
2487 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2488 gtk_action_set_visible (action, show_reply);
2489 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2490 gtk_action_set_visible (action, show_reply);
2491 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2492 gtk_action_set_visible (action, show_forward);
2493 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2494 gtk_action_set_visible (action, show_cancel_send);
2495 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCut");
2496 gtk_action_set_visible (action, show_clipboard);
2497 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCopy");
2498 gtk_action_set_visible (action, show_clipboard);
2499 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMPaste");
2500 gtk_action_set_visible (action, show_clipboard);
2501 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2502 gtk_action_set_visible (action, show_delete);
2504 /* We finally call to the ui actions handler, after updating properly
2505 * the header view CSM */
2506 modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2511 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2512 GtkTreeModel *model,
2513 GtkTreeRowReference *row_reference,
2514 ModestMainWindow *self)
2516 ModestMainWindowPrivate *priv = NULL;
2517 GtkTreeModel *header_model = NULL;
2518 GtkTreePath *path = NULL;
2520 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
2521 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2522 g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2524 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2525 header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2527 /* Do nothing if we changed the folder in the main view */
2528 if (header_model != model)
2531 /* Select the message in the header view */
2532 path = gtk_tree_row_reference_get_path (row_reference);
2533 gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->header_view),
2535 gtk_tree_path_free (path);