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_toggled (GtkToggleAction *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_changed (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;
217 GtkActionGroup *view_additions_group;
219 /* On-demand widgets */
220 GtkWidget *accounts_popup;
221 GtkWidget *details_widget;
223 /* Optimized view enabled */
224 gboolean optimized_view;
226 /* Optimized view enabled */
227 gboolean send_receive_in_progress;
229 ModestHeaderView *header_view;
230 ModestFolderView *folder_view;
232 ModestMainWindowStyle style;
233 ModestMainWindowContentsStyle contents_style;
235 guint progress_bar_timeout;
237 /* Signal handler UIDs */
238 GList *queue_err_signals;
241 ModestConfNotificationId notification_id;
243 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
244 MODEST_TYPE_MAIN_WINDOW, \
245 ModestMainWindowPrivate))
247 typedef struct _GetMsgAsyncHelper {
248 ModestMainWindowPrivate *main_window_private;
250 ModestTnyMsgReplyType reply_type;
251 ModestTnyMsgForwardType forward_type;
258 static GtkWindowClass *parent_class = NULL;
261 /* Private actions */
262 /* This is the context sensitive menu: */
263 static const GtkActionEntry modest_folder_view_action_entries [] = {
265 /* Folder View CSM actions */
266 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
267 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
268 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_paste)},
269 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
270 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_search_messages) },
271 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
274 static const GtkActionEntry modest_header_view_action_entries [] = {
276 /* Header View CSM actions */
277 { "HeaderViewCSMOpen", NULL, N_("mcen_me_inbox_open"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_open) },
278 { "HeaderViewCSMReply", NULL, N_("mcen_me_inbox_reply"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply) },
279 { "HeaderViewCSMReplyAll", NULL, N_("mcen_me_inbox_replytoall"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply_all) },
280 { "HeaderViewCSMForward", NULL, N_("mcen_me_inbox_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_forward) },
281 { "HeaderViewCSMCut", NULL, N_("mcen_me_inbox_cut"), "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
282 { "HeaderViewCSMCopy", NULL, N_("mcen_me_inbox_copy"), "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
283 { "HeaderViewCSMPaste", NULL, N_("mcen_me_inbox_paste"), "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
284 { "HeaderViewCSMDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_message) },
285 { "HeaderViewCSMCancelSending", NULL, N_("mcen_me_outbox_cancelsend"), NULL, NULL, G_CALLBACK (modest_ui_actions_cancel_send) },
286 { "HeaderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
289 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
290 { "ToggleFolders", MODEST_STOCK_SPLIT_VIEW, N_("mcen_me_inbox_hidefolders"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), TRUE },
293 /************************************************************************/
296 modest_main_window_get_type (void)
298 static GType my_type = 0;
300 static const GTypeInfo my_info = {
301 sizeof(ModestMainWindowClass),
302 NULL, /* base init */
303 NULL, /* base finalize */
304 (GClassInitFunc) modest_main_window_class_init,
305 NULL, /* class finalize */
306 NULL, /* class data */
307 sizeof(ModestMainWindow),
309 (GInstanceInitFunc) modest_main_window_init,
312 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
320 modest_main_window_class_init (ModestMainWindowClass *klass)
322 GObjectClass *gobject_class;
323 gobject_class = (GObjectClass*) klass;
324 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
326 parent_class = g_type_class_peek_parent (klass);
327 gobject_class->finalize = modest_main_window_finalize;
329 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
331 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
332 modest_window_class->save_state_func = save_state;
333 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
334 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
335 modest_window_class->disconnect_signals_func = modest_main_window_disconnect_signals;
339 modest_main_window_init (ModestMainWindow *obj)
341 ModestMainWindowPrivate *priv;
343 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
345 priv->queue_err_signals = NULL;
346 priv->msg_paned = NULL;
347 priv->main_paned = NULL;
348 priv->main_vbox = NULL;
349 priv->header_view = NULL;
350 priv->folder_view = NULL;
351 priv->contents_widget = NULL;
352 priv->accounts_popup = NULL;
353 priv->details_widget = NULL;
354 priv->empty_view = NULL;
355 priv->progress_widgets = NULL;
356 priv->progress_bar = NULL;
357 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
358 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
359 priv->contents_style = -1; /* invalid contents style. We need this to select it for the first time */
360 priv->merge_ids = NULL;
361 priv->optimized_view = FALSE;
362 priv->send_receive_in_progress = FALSE;
363 priv->progress_bar_timeout = 0;
364 priv->sighandlers = NULL;
368 modest_main_window_finalize (GObject *obj)
370 ModestMainWindowPrivate *priv;
372 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
374 if (priv->notification_id) {
375 modest_conf_forget_namespace (modest_runtime_get_conf (),
376 MODEST_CONF_NAMESPACE,
377 priv->notification_id);
380 /* Sanity check: shouldn't be needed, the window mgr should
381 call this function before */
382 modest_main_window_disconnect_signals (MODEST_WINDOW (obj));
384 modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
386 g_slist_free (priv->progress_widgets);
388 g_byte_array_free (priv->merge_ids, TRUE);
390 if (priv->progress_bar_timeout > 0) {
391 g_source_remove (priv->progress_bar_timeout);
392 priv->progress_bar_timeout = 0;
395 G_OBJECT_CLASS(parent_class)->finalize (obj);
399 modest_main_window_get_child_widget (ModestMainWindow *self,
400 ModestMainWindowWidgetType widget_type)
402 ModestMainWindowPrivate *priv;
405 g_return_val_if_fail (self, NULL);
406 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_MAIN_WINDOW_WIDGET_TYPE_NUM,
409 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
411 switch (widget_type) {
412 case MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW:
413 widget = (GtkWidget*)priv->header_view; break;
414 case MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW:
415 widget = (GtkWidget*)priv->folder_view; break;
420 return widget ? GTK_WIDGET(widget) : NULL;
425 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
428 ModestMainWindowPrivate *priv;
430 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
432 conf = modest_runtime_get_conf ();
434 modest_widget_memory_restore (conf, G_OBJECT(self),
435 MODEST_CONF_MAIN_WINDOW_KEY);
437 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
438 MODEST_CONF_HEADER_VIEW_KEY);
440 if (do_folder_view_too)
441 modest_widget_memory_restore (conf, G_OBJECT(priv->folder_view),
442 MODEST_CONF_FOLDER_VIEW_KEY);
444 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
445 MODEST_CONF_MAIN_PANED_KEY);
447 /* We need to force a redraw here in order to get the right
448 position of the horizontal paned separator */
449 gtk_widget_show (GTK_WIDGET (self));
454 save_state (ModestWindow *window)
457 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
458 ModestMainWindowPrivate *priv;
460 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
461 conf = modest_runtime_get_conf ();
463 modest_widget_memory_save (conf,G_OBJECT(self),
464 MODEST_CONF_MAIN_WINDOW_KEY);
465 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
466 MODEST_CONF_MAIN_PANED_KEY);
467 // modest_widget_memory_save (conf, G_OBJECT(priv->header_view),
468 // MODEST_CONF_HEADER_VIEW_KEY);
469 modest_widget_memory_save (conf, G_OBJECT(priv->folder_view),
470 MODEST_CONF_FOLDER_VIEW_KEY);
474 compare_display_names (ModestAccountData *a,
475 ModestAccountData *b)
477 return strcmp (a->display_name, b->display_name);
481 update_menus (ModestMainWindow* self)
483 GSList *account_names, *iter, *accounts;
484 ModestMainWindowPrivate *priv;
485 ModestWindowPrivate *parent_priv;
486 ModestAccountMgr *mgr;
487 gint i, num_accounts;
489 gchar *default_account;
490 GtkWidget *send_receive_button, *item;
491 GtkAction *send_receive_all = NULL;
494 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
495 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
497 /* Get enabled account IDs */
498 mgr = modest_runtime_get_account_mgr ();
499 account_names = modest_account_mgr_account_names (mgr, TRUE);
500 iter = account_names;
504 ModestAccountData *account_data =
505 modest_account_mgr_get_account_data (mgr, (gchar*) iter->data);
506 accounts = g_slist_prepend (accounts, account_data);
510 modest_account_mgr_free_account_names (account_names);
511 account_names = NULL;
513 /* Order the list of accounts by its display name */
514 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
515 num_accounts = g_slist_length (accounts);
517 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
518 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
519 gtk_action_set_visible (send_receive_all, num_accounts > 1);
521 /* Delete old send&receive popup items. We can not just do a
522 menu_detach because it does not work well with
524 if (priv->accounts_popup)
525 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
526 (GtkCallback) gtk_widget_destroy, NULL);
528 /* Delete old entries in the View menu. Do not free groups, it
530 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
532 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
533 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
534 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
535 GTK_ACTION_GROUP (groups->data));
538 if (priv->merge_ids) {
539 for (i = 0; i < priv->merge_ids->len; i++)
540 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
541 g_byte_array_free (priv->merge_ids, TRUE);
543 /* We need to call this in order to ensure
544 that the new actions are added in the right
545 order (alphabetical */
546 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
548 groups = g_list_next (groups);
550 priv->merge_ids = g_byte_array_sized_new (num_accounts);
552 /* Get send receive button */
553 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
554 "/ToolBar/ToolbarSendReceive");
556 /* Create the menu */
557 if (num_accounts > 1) {
558 if (!priv->accounts_popup)
559 priv->accounts_popup = gtk_menu_new ();
560 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
561 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
562 g_signal_connect (G_OBJECT (item),
564 G_CALLBACK (on_send_receive_csm_activated),
566 item = gtk_separator_menu_item_new ();
567 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
570 /* Create a new action group */
571 default_account = modest_account_mgr_get_default_account (mgr);
572 priv->view_additions_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
574 for (i = 0; i < num_accounts; i++) {
575 gchar *display_name = NULL;
577 ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
579 /* Create display name. The UI specification specifies a different format string
580 * to use for the default account, though both seem to be "%s", so
581 * I don't see what the point is. murrayc. */
582 if (default_account && account_data->account_name &&
583 !(strcmp (default_account, account_data->account_name) == 0)) {
584 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
585 account_data->display_name);
588 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
589 account_data->display_name);
592 /* Create action and add it to the action group. The
593 action name must be the account name, this way we
594 could know in the handlers the account to show */
595 if(account_data && account_data->account_name) {
596 gchar* item_name, *refresh_action_name;
598 GtkAction *view_account_action, *refresh_account_action;
600 view_account_action = GTK_ACTION (gtk_radio_action_new (account_data->account_name,
601 display_name, NULL, NULL, 0));
602 gtk_action_group_add_action (priv->view_additions_group, view_account_action);
603 gtk_radio_action_set_group (GTK_RADIO_ACTION (view_account_action), radio_group);
604 radio_group = gtk_radio_action_get_group (GTK_RADIO_ACTION (view_account_action));
606 if (default_account && account_data->account_name &&
607 (strcmp (default_account, account_data->account_name) == 0)) {
608 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (view_account_action), TRUE);
611 /* Add ui from account data. We allow 2^9-1 account
612 changes in a single execution because we're
613 downcasting the guint to a guint8 in order to use a
614 GByteArray. It should be enough. */
615 item_name = g_strconcat (account_data->account_name, "Menu", NULL);
616 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
617 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
618 gtk_ui_manager_add_ui (parent_priv->ui_manager,
620 "/MenuBar/ViewMenu/ViewMenuAdditions",
622 account_data->account_name,
623 GTK_UI_MANAGER_MENUITEM,
626 /* Connect the action signal "activate" */
627 g_signal_connect_after (G_OBJECT (view_account_action),
629 G_CALLBACK (on_show_account_action_toggled),
632 /* Create the items for the Tools->Send&Receive submenu */
633 refresh_action_name = g_strconcat ("SendReceive", account_data->account_name, NULL);
634 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
635 display_name, NULL, NULL);
636 gtk_action_group_add_action (priv->view_additions_group, refresh_account_action);
638 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
639 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
640 gtk_ui_manager_add_ui (parent_priv->ui_manager,
642 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
645 GTK_UI_MANAGER_MENUITEM,
647 g_free (refresh_action_name);
649 g_signal_connect_data (G_OBJECT (refresh_account_action),
651 G_CALLBACK (on_refresh_account_action_activated),
652 g_strdup (account_data->account_name),
653 (GClosureNotify) g_free,
656 /* Create item and add it to the send&receive
657 CSM. If there is only one account then
659 if (priv->accounts_popup) {
660 GtkWidget *label = gtk_label_new(NULL);
661 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
662 if (default_account && (strcmp(account_data->account_name, default_account) == 0))
664 gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
665 gtk_label_set_markup (GTK_LABEL (label), escaped);
670 gtk_label_set_text (GTK_LABEL (label), display_name);
673 item = gtk_menu_item_new ();
674 gtk_container_add (GTK_CONTAINER (item), label);
676 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
677 g_signal_connect_data (G_OBJECT (item),
679 G_CALLBACK (on_send_receive_csm_activated),
680 g_strdup (account_data->account_name),
681 (GClosureNotify) g_free,
688 g_free (display_name);
691 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, priv->view_additions_group, 1);
693 /* We cannot do this in the loop above because this relies on the action
694 * group being inserted. This makes the default account appear in bold.
695 * I agree it is a rather ugly way, but I don't see another possibility. armin. */
696 for (i = 0; i < num_accounts; i++) {
697 ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
699 if(account_data->account_name && default_account &&
700 strcmp (account_data->account_name, default_account) == 0) {
701 gchar *item_name = g_strconcat (account_data->account_name, "Menu", NULL);
703 gchar *path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
704 GtkWidget *item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
708 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
709 if (GTK_IS_LABEL (child)) {
710 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
711 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
712 gtk_label_set_markup (GTK_LABEL (child), bold_name);
717 path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", item_name, NULL);
718 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
722 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
723 if (GTK_IS_LABEL (child)) {
724 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
725 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
726 gtk_label_set_markup (GTK_LABEL (child), bold_name);
734 modest_account_mgr_free_account_data (mgr, account_data);
737 if (priv->accounts_popup) {
738 /* Mandatory in order to view the menu contents */
739 gtk_widget_show_all (priv->accounts_popup);
741 /* Setup tap_and_hold just if was not done before*/
742 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
743 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
747 g_slist_free (accounts);
748 g_free (default_account);
751 /* Make sure that at least one account is viewed if there are any
752 * accounts, for instance when adding the first account: */
753 set_at_least_one_account_visible (self);
757 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
759 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
760 gtk_scrolled_window_add_with_viewport
761 (GTK_SCROLLED_WINDOW(win), widget);
763 gtk_container_add (GTK_CONTAINER(win),
768 /* static gboolean */
769 /* on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self) */
771 /* modest_window_save_state (MODEST_WINDOW(self)); */
776 /* on_sendqueue_error_happened (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *err, ModestMainWindow *user_data) */
779 /* printf ("DEBUG: %s: err->code=%d, err->message=%s\n", __FUNCTION__, err->code, err->message); */
781 /* if (err->code == TNY_ACCOUNT_ERROR_TRY_CONNECT_USER_CANCEL) */
782 /* /\* Don't show waste the user's time by showing him a dialog telling him */
783 /* * that he has just cancelled something: *\/ */
787 /* /\* Get the server name: *\/ */
788 /* const gchar* server_name = NULL; */
790 /* TnyCamelTransportAccount* server_account = tny_camel_send_queue_get_transport_account ( */
791 /* TNY_CAMEL_SEND_QUEUE (self)); */
792 /* if (server_account) { */
793 /* server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account)); */
795 /* g_object_unref (server_account); */
796 /* server_account = NULL; */
799 /* if (!server_name) */
800 /* server_name = _("Unknown Server"); */
802 /* /\* Show the appropriate message text for the GError: *\/ */
803 /* gchar *message = NULL; */
805 /* switch (err->code) { */
806 /* case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED: */
807 /* message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name); */
809 /* case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE: */
810 /* message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name); */
812 /* case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED: */
813 /* /\* TODO: This logical ID seems more suitable for a wrong username or password than for a */
814 /* * wrong authentication method. The user is unlikely to guess at the real cause. */
816 /* message = g_strdup_printf (_("eemev_ni_ui_smtp_authentication_fail_error"), server_name); */
818 /* case TNY_TRANSPORT_ACCOUNT_ERROR_SEND: */
819 /* /\* TODO: Tinymail is still sending this sometimes when it should */
820 /* * send TNY_ACCOUNT_ERROR_TRY_CONNECT_USER_CANCEL. *\/ */
822 /* message = g_strdup (_("emev_ib_ui_smtp_send_error")); */
826 /* message = g_strdup (_("emev_ib_ui_smtp_send_error")); */
829 /* modest_maemo_show_information_note_and_forget (GTK_WINDOW (user_data), message); */
830 /* g_free (message); */
832 /* /\* TODO: Offer to remove the message, to avoid messages in future? *\/ */
834 /* TnyFolder *outbox = tny_send_queue_get_outbox (queue); */
835 /* tny_folder_remove_msg (outbox, header, NULL); */
836 /* tny_folder_sync (outbox, TRUE, NULL); */
837 /* g_object_unref (outbox); */
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;
863 /* on_account_store_connecting_finished (TnyAccountStore *store, ModestMainWindow *self) */
865 /* ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self); */
867 /* /\* When going online, do the equivalent of pressing the send/receive button, */
868 /* * as per the specification: */
869 /* * (without the check for >0 accounts, though that is not specified): *\/ */
871 /* TnyDevice *device = tny_account_store_get_device (store); */
873 /* /\* modest_folder_view_update_model (MODEST_FOLDER_VIEW (priv->folder_view), store); *\/ */
875 /* /\* Check that we are really online. */
876 /* * This signal should not be emitted when we are not connected, */
877 /* * but it seems to happen sometimes: *\/ */
878 /* if (!tny_device_is_online (device)) */
881 /* const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device)); */
882 /* printf ("DEBUG: %s: connection id=%s\n", __FUNCTION__, iap_id); */
884 /* /\* Stop the existing send queues: *\/ */
885 /* modest_runtime_remove_all_send_queues (); */
887 /* /\* Create the send queues again, using the appropriate transport accounts */
888 /* * for this new connection. */
889 /* * This could be the first time that they are created if this is the first */
890 /* * connection. *\/ */
891 /* /\* TODO: Does this really destroy the TnySendQueues and their threads */
892 /* * We do not want 2 TnySendQueues to exist with the same underlying */
893 /* * outbox directory. *\/ */
895 /* modest_main_window_cleanup_queue_error_signals (self); */
897 /* GSList *account_names = modest_account_mgr_account_names ( */
898 /* modest_runtime_get_account_mgr(), */
899 /* TRUE /\* enabled accounts only *\/); */
900 /* GSList *iter = account_names; */
902 /* const gchar *account_name = (const gchar*)(iter->data); */
903 /* if (account_name) { */
904 /* TnyTransportAccount *account = TNY_TRANSPORT_ACCOUNT ( */
905 /* modest_tny_account_store_get_transport_account_for_open_connection */
906 /* (modest_runtime_get_account_store(), account_name)); */
908 /* /\* Q: Is this the first location where the send-queues are requested? *\/ */
909 /* QueueErrorSignal *esignal = g_slice_new (QueueErrorSignal); */
910 /* printf ("debug: %s:\n Transport account for %s: %s\n", __FUNCTION__, account_name, */
911 /* tny_account_get_id(TNY_ACCOUNT(account))); */
912 /* esignal->queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (account)); */
913 /* esignal->signal = g_signal_connect (G_OBJECT (esignal->queue), "error-happened", */
914 /* G_CALLBACK (on_sendqueue_error_happened), self); */
915 /* priv->queue_err_signals = g_list_prepend (priv->queue_err_signals, esignal); */
919 /* iter = g_slist_next (iter); */
922 /* modest_account_mgr_free_account_names (account_names); */
923 /* account_names = NULL; */
925 /* modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (self)); */
929 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
931 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
934 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
938 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
940 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
942 /* Update visibility */
945 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
949 modest_main_window_disconnect_signals (ModestWindow *self)
951 ModestMainWindowPrivate *priv;
952 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
954 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
955 priv->sighandlers = NULL;
959 connect_signals (ModestMainWindow *self)
961 ModestWindowPrivate *parent_priv;
962 ModestMainWindowPrivate *priv;
965 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
966 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
970 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
971 G_OBJECT(priv->folder_view), "key-press-event",
972 G_CALLBACK(on_inner_widgets_key_pressed), self);
973 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view), "folder_selection_changed",
974 G_CALLBACK(modest_main_window_on_folder_selection_changed), self);
975 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view), "folder-display-name-changed",
976 G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
977 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view), "focus-in-event",
978 G_CALLBACK (on_folder_view_focus_in), self);
980 /* Folder view CSM */
981 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
982 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
983 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
984 G_CALLBACK(_folder_view_csm_menu_activated),
987 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
988 G_CALLBACK(modest_ui_actions_on_header_selected), self);
989 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
990 G_CALLBACK(modest_ui_actions_on_header_activated), self);
991 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
992 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
993 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
994 G_CALLBACK(on_inner_widgets_key_pressed), self);
995 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
996 G_CALLBACK(_on_msg_count_changed), self);
997 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
998 G_CALLBACK (on_header_view_focus_in), self);
1000 /* Header view CSM */
1001 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
1002 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
1003 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
1004 G_CALLBACK(_header_view_csm_menu_activated),
1008 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
1009 G_CALLBACK (modest_main_window_window_state_event),
1012 /* Mail Operation Queue */
1013 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_mail_operation_queue ()),
1014 "queue-changed", G_CALLBACK (on_queue_changed), self);
1016 /* Track changes in the device name */
1017 priv->notification_id = modest_conf_listen_to_namespace (modest_runtime_get_conf (),
1018 MODEST_CONF_NAMESPACE);
1019 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(modest_runtime_get_conf ()),
1020 "key_changed", G_CALLBACK (on_configuration_key_changed),
1023 /* Track account changes. We need to refresh the toolbar */
1024 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_store ()),
1025 "account_inserted", G_CALLBACK (on_account_inserted),
1027 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_store ()),
1028 "account_removed", G_CALLBACK (on_account_removed),
1031 /* We need to refresh the send & receive menu to change the bold
1032 * account when the default account changes. */
1033 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_mgr ()),
1034 "account_changed", G_CALLBACK (on_account_changed),
1038 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_store()),
1039 "password_requested",
1040 G_CALLBACK (modest_ui_actions_on_password_requested), self);
1044 /** Idle handler, to send/receive at startup .*/
1046 sync_accounts_cb (ModestMainWindow *win)
1048 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (win));
1049 return FALSE; /* Do not call this idle handler again. */
1053 static void on_hildon_program_is_topmost_notify(GObject *self,
1054 GParamSpec *propert_param, gpointer user_data)
1056 HildonProgram *app = HILDON_PROGRAM (self);
1059 ModestWindow* self = MODEST_WINDOW(user_data);
1062 /* Note that use of hildon_program_set_can_hibernate()
1063 * is generally referred to as "setting the killable flag",
1064 * though hibernation does not seem equal to death.
1067 if (hildon_program_get_is_topmost (app)) {
1068 /* Prevent hibernation when the progam comes to the foreground,
1069 * because hibernation should only happen when the application
1070 * is in the background: */
1071 hildon_program_set_can_hibernate (app, FALSE);
1073 /* Allow hibernation if the program has gone to the background: */
1075 /* However, prevent hibernation while the settings are being changed: */
1076 const gboolean hibernation_prevented =
1077 modest_window_mgr_get_hibernation_is_prevented (
1078 modest_runtime_get_window_mgr ());
1080 if (hibernation_prevented)
1081 hildon_program_set_can_hibernate (app, FALSE);
1083 /* Allow hibernation, after saving the state: */
1084 modest_osso_save_state();
1085 hildon_program_set_can_hibernate (app, TRUE);
1092 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
1094 GtkWidget *folder_win = (GtkWidget *) user_data;
1095 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1097 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
1098 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
1099 /* wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view)); */
1101 gtk_widget_show (GTK_WIDGET (priv->folder_view));
1103 /* Connect signals */
1104 connect_signals ((ModestMainWindow*)self);
1106 /* Set account store */
1107 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
1108 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1110 /* Load previous osso state, for instance if we are being restored from
1112 modest_osso_load_state ();
1114 /* Restore window & widget settings */
1116 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
1118 /* The UI spec wants us to show a connection dialog when the application is
1119 * started by the user, if there is no connection.
1120 * Do this before showing the account wizard,
1121 * because wizard needs a connection to discover capabilities. */
1122 modest_platform_connect_and_wait (GTK_WINDOW (self), NULL);
1124 /* Check if accounts exist and show the account wizard if not */
1125 gboolean accounts_exist =
1126 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1128 if (!accounts_exist) {
1129 /* This is necessary to have the main window shown behind the dialog
1130 It's an ugly hack... jschmid */
1131 gtk_widget_show_all(GTK_WIDGET(self));
1132 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
1135 GtkAction *send_receive_all;
1136 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1137 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
1138 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1139 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1140 gtk_action_set_visible (send_receive_all, g_slist_length (accounts) > 1);
1141 modest_account_mgr_free_account_names (accounts);
1146 modest_main_window_new (void)
1148 ModestMainWindow *self = NULL;
1149 ModestMainWindowPrivate *priv = NULL;
1150 ModestWindowPrivate *parent_priv = NULL;
1151 GtkWidget *folder_win = NULL;
1152 ModestDimmingRulesGroup *menu_rules_group = NULL;
1153 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1154 GtkActionGroup *action_group = NULL;
1155 GError *error = NULL;
1156 ModestConf *conf = NULL;
1157 GtkAction *action = NULL;
1158 GdkPixbuf *window_icon;
1160 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
1161 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1162 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1164 parent_priv->ui_manager = gtk_ui_manager_new();
1165 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
1167 action_group = gtk_action_group_new ("ModestMainWindowActions");
1168 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1170 menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules", FALSE);
1171 toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules", TRUE);
1173 /* Add common actions */
1174 gtk_action_group_add_actions (action_group,
1175 modest_action_entries,
1176 G_N_ELEMENTS (modest_action_entries),
1179 gtk_action_group_add_actions (action_group,
1180 modest_folder_view_action_entries,
1181 G_N_ELEMENTS (modest_folder_view_action_entries),
1184 gtk_action_group_add_actions (action_group,
1185 modest_header_view_action_entries,
1186 G_N_ELEMENTS (modest_header_view_action_entries),
1189 gtk_action_group_add_toggle_actions (action_group,
1190 modest_toggle_action_entries,
1191 G_N_ELEMENTS (modest_toggle_action_entries),
1194 gtk_action_group_add_toggle_actions (action_group,
1195 modest_main_window_toggle_action_entries,
1196 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
1199 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
1200 g_object_unref (action_group);
1202 /* Load the UI definition */
1203 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
1204 MODEST_UIDIR "modest-main-window-ui.xml", &error);
1205 if (error != NULL) {
1206 g_warning ("Could not merge modest-ui.xml: %s", error->message);
1207 g_error_free (error);
1211 /* Add common dimming rules */
1212 modest_dimming_rules_group_add_rules (menu_rules_group,
1213 modest_main_window_menu_dimming_entries,
1214 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
1215 MODEST_WINDOW (self));
1216 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1217 modest_main_window_toolbar_dimming_entries,
1218 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
1219 MODEST_WINDOW (self));
1221 /* Insert dimming rules group for this window */
1222 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1223 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1224 g_object_unref (menu_rules_group);
1225 g_object_unref (toolbar_rules_group);
1227 /* Add accelerators */
1228 gtk_window_add_accel_group (GTK_WINDOW (self),
1229 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
1231 /* Menubar. Update the state of some toggles */
1232 parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
1233 conf = modest_runtime_get_conf ();
1234 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1235 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
1236 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1237 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR, NULL));
1238 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1239 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
1240 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1241 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
1242 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
1243 gtk_widget_show (parent_priv->menubar);
1245 /* Get device name */
1246 modest_maemo_utils_get_device_name ();
1250 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
1251 if (!priv->header_view)
1252 g_printerr ("modest: cannot instantiate header view\n");
1253 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
1254 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
1255 MODEST_CONF_HEADER_VIEW_KEY);
1257 /* Other style properties of header view */
1258 g_object_set (G_OBJECT (priv->header_view),
1259 "rules-hint", FALSE,
1261 /* gtk_widget_show (priv->header_view); */
1264 priv->empty_view = create_empty_view ();
1265 gtk_widget_show (priv->empty_view);
1267 /* Create scrolled windows */
1268 folder_win = gtk_scrolled_window_new (NULL, NULL);
1269 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
1270 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
1272 GTK_POLICY_AUTOMATIC);
1273 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
1275 GTK_POLICY_AUTOMATIC);
1276 /* gtk_widget_show (priv->contents_widget); */
1279 priv->main_paned = gtk_hpaned_new ();
1280 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
1281 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
1282 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
1284 /* putting it all together... */
1285 priv->main_vbox = gtk_vbox_new (FALSE, 6);
1286 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
1287 gtk_widget_show (priv->main_vbox);
1289 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
1291 HildonProgram *app = hildon_program_get_instance ();
1292 hildon_program_add_window (app, HILDON_WINDOW (self));
1294 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
1295 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
1297 g_signal_connect (G_OBJECT(self), "show",
1298 G_CALLBACK (modest_main_window_on_show), folder_win);
1300 /* Set window icon */
1301 window_icon = modest_platform_get_icon (MODEST_APP_ICON);
1303 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
1304 g_object_unref (window_icon);
1307 /* Dont't restore settings here,
1308 * because it requires a gtk_widget_show(),
1309 * and we don't want to do that until later,
1310 * so that the UI is not visible for non-menu D-Bus activation.
1312 /* restore_settings (MODEST_MAIN_WINDOW(self), FALSE); */
1314 return MODEST_WINDOW(self);
1318 modest_main_window_close_all (ModestMainWindow *self)
1321 GtkResponseType response;
1323 /* Create the confirmation dialog MSG-NOT308 */
1324 note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
1325 _("emev_nc_close_windows"),
1326 _("mcen_bd_yes"), GTK_RESPONSE_YES,
1327 _("mcen_bd_no"), GTK_RESPONSE_NO,
1330 response = gtk_dialog_run (GTK_DIALOG (note));
1331 gtk_widget_destroy (GTK_WIDGET (note));
1333 if (response == GTK_RESPONSE_YES)
1341 modest_main_window_set_style (ModestMainWindow *self,
1342 ModestMainWindowStyle style)
1344 ModestMainWindowPrivate *priv;
1345 ModestWindowPrivate *parent_priv;
1349 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1351 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1352 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1354 /* no change -> nothing to do */
1355 if (priv->style == style)
1358 /* Get toggle button and update the state if needed. This will
1359 happen only when the set_style is not invoked from the UI,
1360 for example when it's called from widget memory */
1361 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1362 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
1363 if ((active && style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) ||
1364 (!active && style == MODEST_MAIN_WINDOW_STYLE_SPLIT)) {
1365 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1366 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !active);
1367 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1370 priv->style = style;
1372 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
1373 /* Remove main paned */
1374 g_object_ref (priv->main_paned);
1375 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1377 /* Reparent the contents widget to the main vbox */
1378 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
1381 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1382 /* Remove header view */
1383 g_object_ref (priv->contents_widget);
1384 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1386 /* Reparent the main paned */
1387 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1388 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1392 g_return_if_reached ();
1395 /* Let header view grab the focus if it's being shown */
1396 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1397 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1399 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1402 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1405 ModestMainWindowStyle
1406 modest_main_window_get_style (ModestMainWindow *self)
1408 ModestMainWindowPrivate *priv;
1410 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1412 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1419 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1421 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1422 ModestWindowPrivate *parent_priv;
1423 ModestWindowMgr *mgr;
1424 gboolean is_fullscreen;
1425 GtkAction *fs_toggle_action;
1428 mgr = modest_runtime_get_window_mgr ();
1430 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1432 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1434 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1435 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1436 if (is_fullscreen != active) {
1437 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1446 set_homogeneous (GtkWidget *widget,
1449 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
1450 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
1454 modest_main_window_show_toolbar (ModestWindow *self,
1455 gboolean show_toolbar)
1457 ModestMainWindowPrivate *priv = NULL;
1458 ModestWindowPrivate *parent_priv = NULL;
1459 GtkWidget *reply_button = NULL, *menu = NULL;
1460 GtkWidget *placeholder = NULL;
1461 ModestAccountMgr *mgr = NULL;
1462 TnyTransportAccount *transport_account = NULL;
1463 ModestTnySendQueue *send_queue = NULL;
1465 GSList *iter = NULL;
1466 GSList *account_names = NULL;
1467 const gchar *action_name;
1470 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1471 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1472 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1474 /* Set optimized view status */
1475 priv->optimized_view = !show_toolbar;
1477 if (!parent_priv->toolbar) {
1478 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1480 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1482 /* Set homogeneous toolbar */
1483 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar),
1484 set_homogeneous, NULL);
1486 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1487 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1488 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1489 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1490 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1491 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1492 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1493 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1495 /* Add ProgressBar (Transfer toolbar) */
1496 priv->progress_bar = modest_progress_bar_widget_new ();
1497 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1498 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1499 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1500 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1501 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1503 /* Connect cancel 'clicked' signal to abort progress mode */
1504 g_signal_connect(priv->cancel_toolitem, "clicked",
1505 G_CALLBACK(cancel_progressbar),
1508 /* Add it to the observers list */
1509 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1512 hildon_window_add_toolbar (HILDON_WINDOW (self),
1513 GTK_TOOLBAR (parent_priv->toolbar));
1515 /* Set reply button tap and hold menu */
1516 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1517 "/ToolBar/ToolbarMessageReply");
1518 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1519 "/ToolbarReplyCSM");
1520 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1522 /* Set send & receive button tap and hold menu */
1523 update_menus (MODEST_MAIN_WINDOW (self));
1525 /* Create send queue for all defined accounts */
1526 mgr = modest_runtime_get_account_mgr ();
1527 account_names = modest_account_mgr_account_names (mgr, TRUE);
1528 iter = account_names;
1531 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1532 (modest_runtime_get_account_store(),
1534 TNY_ACCOUNT_TYPE_TRANSPORT));
1536 /* Create new send queue for this new account */
1537 send_queue = modest_runtime_get_send_queue (transport_account);
1538 if (MODEST_IS_TNY_SEND_QUEUE(send_queue)) {
1540 /* Connect 'status_changed' signal of this new send-queue */
1541 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT (send_queue), "status_changed",
1542 G_CALLBACK (modest_main_window_on_send_queue_status_changed),
1549 if (send_queue != NULL)
1550 g_object_unref (send_queue);
1551 if (transport_account != NULL)
1552 g_object_unref (transport_account);
1555 modest_account_mgr_free_account_names (account_names);
1559 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1560 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1561 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1563 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1564 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1566 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1570 /* Update also the actions (to update the toggles in the
1571 menus), we have to do it manually because some other window
1572 of the same time could have changed it (remember that the
1573 toolbar fullscreen mode is shared by all the windows of the
1575 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
1576 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarFullScreenMenu";
1578 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarNormalScreenMenu";
1580 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
1581 modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
1586 modest_main_window_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
1591 ModestMainWindowPrivate *priv = NULL;
1592 TnyFolderStore *selected_folder = NULL;
1593 TnyFolderType folder_type;
1595 g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (send_queue));
1596 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1597 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(user_data);
1599 /* Check if selected folder is OUTBOX */
1600 selected_folder = modest_folder_view_get_selected (priv->folder_view);
1601 if (!TNY_IS_FOLDER (selected_folder)) goto frees;
1602 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
1603 #if GTK_CHECK_VERSION(2, 8, 0) /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
1604 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1605 GtkTreeViewColumn * tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (priv->header_view),
1606 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
1607 gtk_tree_view_column_queue_resize (tree_column);
1613 if (selected_folder != NULL)
1614 g_object_unref (selected_folder);
1618 on_account_inserted (TnyAccountStore *accoust_store,
1619 TnyAccount *account,
1622 TnyTransportAccount *transport_account = NULL;
1623 ModestTnySendQueue *send_queue = NULL;
1624 ModestMainWindowPrivate *priv;
1625 const gchar *account_name = NULL;
1627 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1628 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1630 update_menus (MODEST_MAIN_WINDOW (user_data));
1632 /* Get transport account */
1633 account_name = tny_account_get_name (TNY_ACCOUNT (account));
1635 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1636 (modest_runtime_get_account_store(),
1638 TNY_ACCOUNT_TYPE_TRANSPORT));
1640 /* Create new send queue for this new account */
1641 send_queue = modest_runtime_get_send_queue (transport_account);
1642 if (!MODEST_IS_TNY_SEND_QUEUE(send_queue)) goto frees;
1644 /* Connect 'status_changed' signal of this new send-queue */
1645 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (send_queue), "status_changed",
1646 G_CALLBACK (modest_main_window_on_send_queue_status_changed),
1651 if (transport_account != NULL)
1652 g_object_unref (G_OBJECT (transport_account));
1653 if (send_queue != NULL)
1654 g_object_unref (send_queue);
1658 on_account_changed (ModestAccountMgr* mgr,
1659 const gchar* account,
1662 gchar *default_account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
1664 /* Actually, we only want to know when another account has become
1665 * the default account, but there is no default_account_changed
1666 * signal in ModestAccountMgr. */
1667 if(strcmp(account, default_account) == 0)
1668 update_menus (MODEST_MAIN_WINDOW (user_data));
1670 g_free (default_account);
1674 on_account_removed (TnyAccountStore *accoust_store,
1675 TnyAccount *account,
1678 update_menus (MODEST_MAIN_WINDOW (user_data));
1682 * This function manages the key events used to navigate between
1683 * header and folder views (when the window is in split view)
1686 * -------------------------------------------------
1687 * HeaderView GDK_Left Move focus to folder view
1688 * FolderView GDK_Right Move focus to header view
1690 * There is no need to scroll to selected row, the widgets will be the
1691 * responsibles of doing that (probably managing the focus-in event
1694 on_inner_widgets_key_pressed (GtkWidget *widget,
1698 ModestMainWindowPrivate *priv;
1700 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1702 /* Do nothing if we're in SIMPLE style */
1703 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1706 if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
1707 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1708 else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1709 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1715 set_alignment (GtkWidget *widget,
1718 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1719 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1723 create_empty_view (void)
1725 GtkLabel *label = NULL;
1726 GtkWidget *align = NULL;
1728 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1729 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1730 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1731 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1733 return GTK_WIDGET(align);
1737 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1739 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1744 gchar *gray_color_markup;
1746 vbox = gtk_vbox_new (FALSE, 0);
1748 /* Obtain the secondary text color. We need a realized widget, that's why
1749 we get styled_widget from outside */
1750 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1752 gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color);
1753 gray_color_markup = modest_text_utils_get_color_string (&color);
1755 // gray_color_markup is freed below
1756 gray_color_markup = g_strdup ("#BBBBBB");
1758 /* Account description: */
1760 if (modest_tny_account_is_virtual_local_folders (account)
1761 || (modest_tny_account_is_memory_card_account (account))) {
1763 /* Local folders: */
1765 /* Get device name */
1766 gchar *device_name = NULL;
1767 if (modest_tny_account_is_virtual_local_folders (account))
1768 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1769 MODEST_CONF_DEVICE_NAME, NULL);
1771 device_name = g_strdup (tny_account_get_name (account));
1773 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), ""); //TODO: Why the ""?
1774 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1775 gray_color_markup, tmp, device_name);
1777 label_w = gtk_label_new (NULL);
1778 gtk_label_set_markup (GTK_LABEL (label_w), label);
1779 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1780 g_free (device_name);
1783 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1784 gtk_box_pack_start (GTK_BOX (vbox),
1785 gtk_label_new (tny_account_get_name (account)),
1788 /* Other accounts, such as IMAP and POP: */
1793 /* Put proto in uppercase */
1794 proto = g_string_new (tny_account_get_proto (account));
1795 proto = g_string_ascii_up (proto);
1797 /* note: mcen_fi_localroot_description is something like "%s account"
1798 * however, we should display "%s account: %s"... therefore, ugly tmp */
1799 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1800 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1801 gray_color_markup, tmp, tny_account_get_name (account));
1804 label_w = gtk_label_new (NULL);
1805 gtk_label_set_markup (GTK_LABEL (label_w), label);
1806 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1807 g_string_free (proto, TRUE);
1813 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1814 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1815 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1816 modest_tny_folder_store_get_message_count (folder_store));
1817 label_w = gtk_label_new (NULL);
1818 gtk_label_set_markup (GTK_LABEL (label_w), label);
1819 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1823 label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d",
1825 _("mcen_fi_rootfolder_folders"),
1826 modest_tny_folder_store_get_folder_count (folder_store));
1827 label_w = gtk_label_new (NULL);
1828 gtk_label_set_markup (GTK_LABEL (label_w), label);
1829 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1833 if (modest_tny_account_is_virtual_local_folders (account)
1834 || modest_tny_account_is_memory_card_account (account)) {
1836 gchar *size = modest_text_utils_get_display_size (
1837 modest_tny_folder_store_get_local_size (folder_store));
1839 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1840 gray_color_markup, _("mcen_fi_rootfolder_size"),
1844 label_w = gtk_label_new (NULL);
1845 gtk_label_set_markup (GTK_LABEL (label_w), label);
1846 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1848 } else if (TNY_IS_ACCOUNT(folder_store)) {
1849 TnyAccount *account = TNY_ACCOUNT(folder_store);
1851 time_t last_updated;
1852 gchar *last_updated_string;
1853 /* Get last updated from configuration */
1854 last_updated = modest_account_mgr_get_int (modest_runtime_get_account_mgr (),
1855 tny_account_get_id (account),
1856 MODEST_ACCOUNT_LAST_UPDATED,
1858 if (last_updated > 0)
1859 last_updated_string = modest_text_utils_get_display_date(last_updated);
1861 last_updated_string = g_strdup (_("mcen_va_never"));
1863 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1864 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1865 label_w = gtk_label_new (NULL);
1866 gtk_label_set_markup (GTK_LABEL (label_w), label);
1867 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1868 g_free (last_updated_string);
1872 g_free (gray_color_markup);
1875 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1881 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1883 ModestMainWindowPrivate *priv = NULL;
1885 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1887 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1889 return priv->send_receive_in_progress;
1893 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1895 GtkAction *action = NULL;
1896 GtkWidget *widget = NULL;
1897 ModestMainWindowPrivate *priv = NULL;
1899 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1900 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1902 priv->send_receive_in_progress = TRUE;
1904 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1905 gtk_action_set_sensitive (action, FALSE);
1906 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1907 /* gtk_action_set_sensitive (action, FALSE); */
1908 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1909 gtk_widget_set_sensitive (widget, FALSE);
1913 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1915 GtkAction *action = NULL;
1916 GtkWidget *widget = NULL;
1917 ModestMainWindowPrivate *priv = NULL;
1919 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1920 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1922 priv->send_receive_in_progress = FALSE;
1924 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1925 gtk_action_set_sensitive (action, TRUE);
1926 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1927 /* gtk_action_set_sensitive (action, TRUE); */
1928 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1929 gtk_widget_set_sensitive (widget, TRUE);
1934 _on_msg_count_changed (ModestHeaderView *header_view,
1936 TnyFolderChange *change,
1937 ModestMainWindow *main_window)
1939 gboolean folder_empty = FALSE;
1940 gboolean all_marked_as_deleted = FALSE;
1941 TnyFolderChangeChanged changed;
1942 ModestMainWindowPrivate *priv;
1944 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1945 g_return_if_fail (TNY_IS_FOLDER(folder));
1946 g_return_if_fail (TNY_IS_FOLDER_CHANGE(change));
1947 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
1949 changed = tny_folder_change_get_changed (change);
1951 /* If something changes */
1952 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1953 folder_empty = (tny_folder_change_get_new_all_count (change) == 0);
1955 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1957 /* Check header removed (hide marked as DELETED headers) */
1958 if (changed & TNY_FOLDER_CHANGE_CHANGED_EXPUNGED_HEADERS) {
1959 modest_header_view_refilter (MODEST_HEADER_VIEW(priv->header_view));
1962 /* Check if all messages are marked to be deleted */
1963 all_marked_as_deleted = modest_header_view_is_empty (header_view);
1964 folder_empty = folder_empty || all_marked_as_deleted ;
1966 /* Set contents style of headers view */
1968 modest_main_window_set_contents_style (main_window,
1969 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1970 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1973 modest_main_window_set_contents_style (main_window,
1974 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1980 modest_main_window_set_contents_style (ModestMainWindow *self,
1981 ModestMainWindowContentsStyle style)
1983 ModestMainWindowPrivate *priv;
1985 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1987 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1989 /* We allow to set the same content style than the previously
1990 set if there are details, because it could happen when we're
1991 selecting different accounts consecutively */
1992 if ((priv->contents_style == style) &&
1993 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1996 /* Remove previous child. Delete it if it was an account
1998 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
2000 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2001 g_object_ref (content);
2002 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
2003 g_object_ref (priv->empty_view);
2004 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
2007 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
2010 priv->contents_style = style;
2012 switch (priv->contents_style) {
2013 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
2014 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
2015 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2018 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
2020 /* if we're started without main win, there may not be a folder
2021 * view. this fixes a GLib-Critical */
2022 if (priv->folder_view) {
2023 TnyFolderStore *selected_folderstore =
2024 modest_folder_view_get_selected (priv->folder_view);
2025 if (TNY_IS_ACCOUNT (selected_folderstore)) {
2026 priv->details_widget = create_details_widget (GTK_WIDGET (self),
2027 TNY_ACCOUNT (selected_folderstore));
2029 wrap_in_scrolled_window (priv->contents_widget,
2030 priv->details_widget);
2032 g_object_unref (selected_folderstore);
2033 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2038 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
2039 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
2040 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2044 g_return_if_reached ();
2048 gtk_widget_show_all (priv->contents_widget);
2051 ModestMainWindowContentsStyle
2052 modest_main_window_get_contents_style (ModestMainWindow *self)
2054 ModestMainWindowPrivate *priv;
2056 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
2058 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2059 return priv->contents_style;
2064 on_configuration_key_changed (ModestConf* conf,
2066 ModestConfEvent event,
2067 ModestConfNotificationId id,
2068 ModestMainWindow *self)
2070 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2071 TnyAccount *account = NULL;
2074 priv->notification_id != id ||
2075 strcmp (key, MODEST_CONF_DEVICE_NAME))
2078 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
2080 if (priv->folder_view)
2081 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
2082 if (account && TNY_IS_ACCOUNT (account) &&
2083 strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID) == 0) {
2086 const gchar *device_name;
2090 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
2091 label = GTK_LABEL (children->data);
2093 device_name = modest_conf_get_string (modest_runtime_get_conf(),
2094 MODEST_CONF_DEVICE_NAME, NULL);
2096 new_text = g_strdup_printf ("%s: %s",
2097 _("mcen_fi_localroot_description"),
2100 gtk_label_set_text (label, new_text);
2101 gtk_widget_show (GTK_WIDGET (label));
2104 g_list_free (children);
2106 g_object_unref (account);
2110 set_toolbar_transfer_mode (ModestMainWindow *self)
2112 ModestMainWindowPrivate *priv = NULL;
2114 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2116 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2118 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
2120 if (priv->progress_bar_timeout > 0) {
2121 g_source_remove (priv->progress_bar_timeout);
2122 priv->progress_bar_timeout = 0;
2129 set_toolbar_mode (ModestMainWindow *self,
2130 ModestToolBarModes mode)
2132 ModestWindowPrivate *parent_priv = NULL;
2133 ModestMainWindowPrivate *priv = NULL;
2134 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
2136 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2138 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2139 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2141 /* In case this was called before the toolbar exists: */
2142 if (!(parent_priv->toolbar))
2145 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
2147 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
2148 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
2149 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
2151 /* Sets current toolbar mode */
2152 priv->current_toolbar_mode = mode;
2154 /* Checks the dimming rules */
2155 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2157 /* Show and hide toolbar items */
2159 case TOOLBAR_MODE_NORMAL:
2161 gtk_action_set_visible (sort_action, TRUE);
2163 gtk_action_set_visible (refresh_action, TRUE);
2164 if (priv->progress_toolitem) {
2165 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
2166 gtk_widget_hide (priv->progress_toolitem);
2168 if (priv->progress_bar)
2169 gtk_widget_hide (priv->progress_bar);
2172 gtk_action_set_visible (cancel_action, FALSE);
2174 /* Hide toolbar if optimized view is enabled */
2175 if (priv->optimized_view)
2176 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
2178 case TOOLBAR_MODE_TRANSFER:
2180 gtk_action_set_visible (sort_action, FALSE);
2182 gtk_action_set_visible (refresh_action, FALSE);
2184 gtk_action_set_visible (cancel_action, TRUE);
2185 if (priv->progress_toolitem) {
2186 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
2187 gtk_widget_show (priv->progress_toolitem);
2189 if (priv->progress_bar)
2190 gtk_widget_show (priv->progress_bar);
2192 /* Show toolbar if it's hiden (optimized view ) */
2193 if (priv->optimized_view)
2194 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2197 g_return_if_reached ();
2202 modest_main_window_transfer_mode_enabled (ModestMainWindow *self)
2204 ModestMainWindowPrivate *priv;
2206 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2207 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2209 return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
2213 cancel_progressbar (GtkToolButton *toolbutton,
2214 ModestMainWindow *self)
2217 ModestMainWindowPrivate *priv;
2219 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2221 /* Get operation observers and cancel all the operations */
2222 tmp = priv->progress_widgets;
2224 modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2225 tmp=g_slist_next(tmp);
2230 observers_empty (ModestMainWindow *self)
2233 ModestMainWindowPrivate *priv;
2234 gboolean is_empty = TRUE;
2235 guint pending_ops = 0;
2237 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2238 tmp = priv->progress_widgets;
2240 /* Check all observers */
2241 while (tmp && is_empty) {
2242 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2243 is_empty = pending_ops == 0;
2245 tmp = g_slist_next(tmp);
2252 on_queue_changed (ModestMailOperationQueue *queue,
2253 ModestMailOperation *mail_op,
2254 ModestMailOperationQueueNotification type,
2255 ModestMainWindow *self)
2257 ModestMainWindowPrivate *priv;
2258 ModestMailOperationTypeOperation op_type;
2259 ModestToolBarModes mode;
2261 gboolean mode_changed = FALSE;
2263 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2264 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2266 /* Get toolbar mode from operation id*/
2267 op_type = modest_mail_operation_get_type_operation (mail_op);
2269 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
2270 case MODEST_MAIL_OPERATION_TYPE_OPEN:
2271 mode = TOOLBAR_MODE_TRANSFER;
2272 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
2273 mode_changed = TRUE;
2276 mode = TOOLBAR_MODE_NORMAL;
2281 /* Add operation observers and change toolbar if neccessary*/
2282 tmp = priv->progress_widgets;
2284 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
2285 if (mode == TOOLBAR_MODE_TRANSFER) {
2287 set_toolbar_transfer_mode(self);
2290 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2292 tmp = g_slist_next (tmp);
2296 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
2297 /* Change toolbar mode */
2298 if (mode == TOOLBAR_MODE_TRANSFER) {
2300 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2302 tmp = g_slist_next (tmp);
2305 /* If no more operations are being observed, NORMAL mode is enabled again */
2306 if (observers_empty (self)) {
2307 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
2317 set_account_visible(ModestMainWindow *self, const gchar *acc_name)
2319 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2322 /* Get account data */
2323 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
2324 ModestAccountData *acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
2326 /* Set the new visible & active account */
2327 if (acc_data && acc_data->store_account) {
2328 modest_folder_view_set_account_id_of_visible_server_account (priv->folder_view,
2329 acc_data->store_account->account_name);
2330 modest_window_set_active_account (MODEST_WINDOW (self), acc_data->account_name);
2331 action = gtk_action_group_get_action (priv->view_additions_group, acc_data->account_name);
2332 if (action != NULL) {
2333 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2334 modest_maemo_toggle_action_set_active_block_notify (
2335 GTK_TOGGLE_ACTION (action),
2341 modest_folder_view_select_first_inbox_or_local (priv->folder_view);
2346 modest_account_mgr_free_account_data (mgr, acc_data);
2349 /* Make sure that at least one account is "viewed": */
2351 set_at_least_one_account_visible(ModestMainWindow *self)
2353 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2354 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2356 if (!(priv->folder_view)) {
2357 /* It is too early to do this. */
2361 const gchar *active_server_account_name =
2362 modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);
2363 if (!active_server_account_name ||
2364 !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
2366 gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
2367 if (first_modest_name) {
2368 set_account_visible (self, first_modest_name);
2369 g_free (first_modest_name);
2375 on_show_account_action_toggled (GtkToggleAction *action,
2378 ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
2380 const gchar *acc_name = gtk_action_get_name (GTK_ACTION (action));
2381 if (gtk_toggle_action_get_active (action))
2382 set_account_visible (self, acc_name);
2386 refresh_account (const gchar *account_name)
2390 win = MODEST_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2392 /* If account_name == NULL, we must update all (option All) */
2394 modest_ui_actions_do_send_receive_all (win);
2396 modest_ui_actions_do_send_receive (account_name, win);
2401 on_refresh_account_action_activated (GtkAction *action,
2404 refresh_account ((const gchar*) user_data);
2408 on_send_receive_csm_activated (GtkMenuItem *item,
2411 refresh_account ((const gchar*) user_data);
2415 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2417 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2419 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2425 on_folder_view_focus_in (GtkWidget *widget,
2426 GdkEventFocus *event,
2429 ModestMainWindow *main_window = NULL;
2431 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2432 main_window = MODEST_MAIN_WINDOW (userdata);
2434 /* Update toolbar dimming state */
2435 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2441 on_header_view_focus_in (GtkWidget *widget,
2442 GdkEventFocus *event,
2445 ModestMainWindow *main_window = NULL;
2446 ModestMainWindowPrivate *priv = NULL;
2448 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2449 main_window = MODEST_MAIN_WINDOW (userdata);
2450 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
2452 /* Update toolbar dimming state */
2453 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2459 modest_main_window_on_folder_selection_changed (ModestFolderView *folder_view,
2460 TnyFolderStore *folder_store,
2462 ModestMainWindow *main_window)
2464 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2465 GtkAction *action = NULL;
2466 gboolean show_reply = TRUE;
2467 gboolean show_forward = TRUE;
2468 gboolean show_cancel_send = FALSE;
2469 gboolean show_clipboard = TRUE;
2470 gboolean show_delete = TRUE;
2473 if (TNY_IS_ACCOUNT (folder_store)) {
2474 show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2475 } else if (TNY_IS_FOLDER (folder_store)) {
2476 if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2477 TnyFolderType folder_type = modest_tny_folder_get_local_or_mmc_folder_type (
2478 TNY_FOLDER (folder_store));
2479 switch (folder_type) {
2480 case TNY_FOLDER_TYPE_DRAFTS:
2481 show_clipboard = show_delete = TRUE;
2482 show_reply = show_forward = show_cancel_send = FALSE;
2484 case TNY_FOLDER_TYPE_SENT:
2485 show_forward = show_clipboard = show_delete = TRUE;
2486 show_reply = show_cancel_send = FALSE;
2488 case TNY_FOLDER_TYPE_OUTBOX:
2489 show_clipboard = show_delete = show_cancel_send = TRUE;
2490 show_reply = show_forward = FALSE;
2493 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2494 show_cancel_send = FALSE;
2497 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2498 show_cancel_send = FALSE;
2503 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2504 gtk_action_set_visible (action, show_reply);
2505 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2506 gtk_action_set_visible (action, show_reply);
2507 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2508 gtk_action_set_visible (action, show_forward);
2509 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2510 gtk_action_set_visible (action, show_cancel_send);
2511 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCut"); */
2512 /* gtk_action_set_visible (action, show_clipboard); */
2513 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCopy"); */
2514 /* gtk_action_set_visible (action, show_clipboard); */
2515 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMPaste"); */
2516 /* gtk_action_set_visible (action, show_clipboard); */
2517 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2518 gtk_action_set_visible (action, show_delete);
2520 /* We finally call to the ui actions handler, after updating properly
2521 * the header view CSM */
2522 modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2527 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2528 GtkTreeModel *model,
2529 GtkTreeRowReference *row_reference,
2530 ModestMainWindow *self)
2532 ModestMainWindowPrivate *priv = NULL;
2533 GtkTreeModel *header_model = NULL;
2534 GtkTreePath *path = NULL;
2536 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
2537 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2538 g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2540 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2541 header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2543 /* Do nothing if we changed the folder in the main view */
2544 if (header_model != model)
2547 /* Select the message in the header view */
2548 path = gtk_tree_row_reference_get_path (row_reference);
2549 gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->header_view),
2551 gtk_tree_path_free (path);