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 printf("DEBUG: %s: menu display_name=%s\n", __FUNCTION__, display_name);
637 gtk_action_group_add_action (priv->view_additions_group, refresh_account_action);
639 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
640 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
641 gtk_ui_manager_add_ui (parent_priv->ui_manager,
643 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
646 GTK_UI_MANAGER_MENUITEM,
648 g_free (refresh_action_name);
650 g_signal_connect_data (G_OBJECT (refresh_account_action),
652 G_CALLBACK (on_refresh_account_action_activated),
653 g_strdup (account_data->account_name),
654 (GClosureNotify) g_free,
657 /* Create item and add it to the send&receive
658 CSM. If there is only one account then
660 if (priv->accounts_popup) {
661 GtkWidget *label = gtk_label_new(NULL);
662 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
663 if (default_account && (strcmp(account_data->account_name, default_account) == 0))
665 gchar *escaped = g_markup_printf_escaped ("<b>%s</b>", display_name);
666 gtk_label_set_markup (GTK_LABEL (label), escaped);
671 gtk_label_set_text (GTK_LABEL (label), display_name);
674 item = gtk_menu_item_new ();
675 gtk_container_add (GTK_CONTAINER (item), label);
677 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
678 g_signal_connect_data (G_OBJECT (item),
680 G_CALLBACK (on_send_receive_csm_activated),
681 g_strdup (account_data->account_name),
682 (GClosureNotify) g_free,
689 g_free (display_name);
692 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, priv->view_additions_group, 1);
694 /* We cannot do this in the loop above because this relies on the action
695 * group being inserted. This makes the default account appear in bold.
696 * I agree it is a rather ugly way, but I don't see another possibility. armin. */
697 for (i = 0; i < num_accounts; i++) {
698 ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
700 if(account_data->account_name && default_account &&
701 strcmp (account_data->account_name, default_account) == 0) {
702 gchar *item_name = g_strconcat (account_data->account_name, "Menu", NULL);
704 gchar *path = g_strconcat ("/MenuBar/ViewMenu/ViewMenuAdditions/", item_name, NULL);
705 GtkWidget *item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
709 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
710 if (GTK_IS_LABEL (child)) {
711 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
712 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
713 gtk_label_set_markup (GTK_LABEL (child), bold_name);
718 path = g_strconcat("/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions/", item_name, NULL);
719 item = gtk_ui_manager_get_widget (parent_priv->ui_manager, path);
723 GtkWidget *child = gtk_bin_get_child (GTK_BIN (item));
724 if (GTK_IS_LABEL (child)) {
725 const gchar *cur_name = gtk_label_get_text (GTK_LABEL (child));
726 gchar *bold_name = g_markup_printf_escaped("<b>%s</b>", cur_name);
727 gtk_label_set_markup (GTK_LABEL (child), bold_name);
735 modest_account_mgr_free_account_data (mgr, account_data);
738 if (priv->accounts_popup) {
739 /* Mandatory in order to view the menu contents */
740 gtk_widget_show_all (priv->accounts_popup);
742 /* Setup tap_and_hold just if was not done before*/
743 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
744 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
748 g_slist_free (accounts);
749 g_free (default_account);
752 /* Make sure that at least one account is viewed if there are any
753 * accounts, for instance when adding the first account: */
754 set_at_least_one_account_visible (self);
758 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
760 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
761 gtk_scrolled_window_add_with_viewport
762 (GTK_SCROLLED_WINDOW(win), widget);
764 gtk_container_add (GTK_CONTAINER(win),
769 /* static gboolean */
770 /* on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self) */
772 /* modest_window_save_state (MODEST_WINDOW(self)); */
777 /* on_sendqueue_error_happened (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *err, ModestMainWindow *user_data) */
780 /* printf ("DEBUG: %s: err->code=%d, err->message=%s\n", __FUNCTION__, err->code, err->message); */
782 /* if (err->code == TNY_ACCOUNT_ERROR_TRY_CONNECT_USER_CANCEL) */
783 /* /\* Don't show waste the user's time by showing him a dialog telling him */
784 /* * that he has just cancelled something: *\/ */
788 /* /\* Get the server name: *\/ */
789 /* const gchar* server_name = NULL; */
791 /* TnyCamelTransportAccount* server_account = tny_camel_send_queue_get_transport_account ( */
792 /* TNY_CAMEL_SEND_QUEUE (self)); */
793 /* if (server_account) { */
794 /* server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account)); */
796 /* g_object_unref (server_account); */
797 /* server_account = NULL; */
800 /* if (!server_name) */
801 /* server_name = _("Unknown Server"); */
803 /* /\* Show the appropriate message text for the GError: *\/ */
804 /* gchar *message = NULL; */
806 /* switch (err->code) { */
807 /* case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED: */
808 /* message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name); */
810 /* case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE: */
811 /* message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name); */
813 /* case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED: */
814 /* /\* TODO: This logical ID seems more suitable for a wrong username or password than for a */
815 /* * wrong authentication method. The user is unlikely to guess at the real cause. */
817 /* message = g_strdup_printf (_("eemev_ni_ui_smtp_authentication_fail_error"), server_name); */
819 /* case TNY_TRANSPORT_ACCOUNT_ERROR_SEND: */
820 /* /\* TODO: Tinymail is still sending this sometimes when it should */
821 /* * send TNY_ACCOUNT_ERROR_TRY_CONNECT_USER_CANCEL. *\/ */
823 /* message = g_strdup (_("emev_ib_ui_smtp_send_error")); */
827 /* message = g_strdup (_("emev_ib_ui_smtp_send_error")); */
830 /* modest_maemo_show_information_note_and_forget (GTK_WINDOW (user_data), message); */
831 /* g_free (message); */
833 /* /\* TODO: Offer to remove the message, to avoid messages in future? *\/ */
835 /* TnyFolder *outbox = tny_send_queue_get_outbox (queue); */
836 /* tny_folder_remove_msg (outbox, header, NULL); */
837 /* tny_folder_sync (outbox, TRUE, NULL); */
838 /* g_object_unref (outbox); */
848 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
850 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
852 GList *oerrsignals = priv->queue_err_signals;
853 while (oerrsignals) {
854 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
855 g_signal_handler_disconnect (esignal->queue, esignal->signal);
856 g_slice_free (QueueErrorSignal, esignal);
857 oerrsignals = g_list_next (oerrsignals);
859 g_list_free (priv->queue_err_signals);
860 priv->queue_err_signals = NULL;
864 /* on_account_store_connecting_finished (TnyAccountStore *store, ModestMainWindow *self) */
866 /* ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self); */
868 /* /\* When going online, do the equivalent of pressing the send/receive button, */
869 /* * as per the specification: */
870 /* * (without the check for >0 accounts, though that is not specified): *\/ */
872 /* TnyDevice *device = tny_account_store_get_device (store); */
874 /* /\* modest_folder_view_update_model (MODEST_FOLDER_VIEW (priv->folder_view), store); *\/ */
876 /* /\* Check that we are really online. */
877 /* * This signal should not be emitted when we are not connected, */
878 /* * but it seems to happen sometimes: *\/ */
879 /* if (!tny_device_is_online (device)) */
882 /* const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device)); */
883 /* printf ("DEBUG: %s: connection id=%s\n", __FUNCTION__, iap_id); */
885 /* /\* Stop the existing send queues: *\/ */
886 /* modest_runtime_remove_all_send_queues (); */
888 /* /\* Create the send queues again, using the appropriate transport accounts */
889 /* * for this new connection. */
890 /* * This could be the first time that they are created if this is the first */
891 /* * connection. *\/ */
892 /* /\* TODO: Does this really destroy the TnySendQueues and their threads */
893 /* * We do not want 2 TnySendQueues to exist with the same underlying */
894 /* * outbox directory. *\/ */
896 /* modest_main_window_cleanup_queue_error_signals (self); */
898 /* GSList *account_names = modest_account_mgr_account_names ( */
899 /* modest_runtime_get_account_mgr(), */
900 /* TRUE /\* enabled accounts only *\/); */
901 /* GSList *iter = account_names; */
903 /* const gchar *account_name = (const gchar*)(iter->data); */
904 /* if (account_name) { */
905 /* TnyTransportAccount *account = TNY_TRANSPORT_ACCOUNT ( */
906 /* modest_tny_account_store_get_transport_account_for_open_connection */
907 /* (modest_runtime_get_account_store(), account_name)); */
909 /* /\* Q: Is this the first location where the send-queues are requested? *\/ */
910 /* QueueErrorSignal *esignal = g_slice_new (QueueErrorSignal); */
911 /* printf ("debug: %s:\n Transport account for %s: %s\n", __FUNCTION__, account_name, */
912 /* tny_account_get_id(TNY_ACCOUNT(account))); */
913 /* esignal->queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (account)); */
914 /* esignal->signal = g_signal_connect (G_OBJECT (esignal->queue), "error-happened", */
915 /* G_CALLBACK (on_sendqueue_error_happened), self); */
916 /* priv->queue_err_signals = g_list_prepend (priv->queue_err_signals, esignal); */
920 /* iter = g_slist_next (iter); */
923 /* modest_account_mgr_free_account_names (account_names); */
924 /* account_names = NULL; */
926 /* modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (self)); */
930 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
932 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
935 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
939 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
941 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
943 /* Update visibility */
946 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
950 modest_main_window_disconnect_signals (ModestWindow *self)
952 ModestMainWindowPrivate *priv;
953 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
955 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
956 priv->sighandlers = NULL;
960 connect_signals (ModestMainWindow *self)
962 ModestWindowPrivate *parent_priv;
963 ModestMainWindowPrivate *priv;
966 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
967 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
971 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
972 G_OBJECT(priv->folder_view), "key-press-event",
973 G_CALLBACK(on_inner_widgets_key_pressed), self);
974 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view), "folder_selection_changed",
975 G_CALLBACK(modest_main_window_on_folder_selection_changed), self);
976 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->folder_view), "folder-display-name-changed",
977 G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
978 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->folder_view), "focus-in-event",
979 G_CALLBACK (on_folder_view_focus_in), self);
981 /* Folder view CSM */
982 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
983 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
984 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT(priv->folder_view), "tap-and-hold",
985 G_CALLBACK(_folder_view_csm_menu_activated),
988 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_selected",
989 G_CALLBACK(modest_ui_actions_on_header_selected), self);
990 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "header_activated",
991 G_CALLBACK(modest_ui_actions_on_header_activated), self);
992 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "item_not_found",
993 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
994 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "key-press-event",
995 G_CALLBACK(on_inner_widgets_key_pressed), self);
996 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "msg_count_changed",
997 G_CALLBACK(_on_msg_count_changed), self);
998 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (priv->header_view), "focus-in-event",
999 G_CALLBACK (on_header_view_focus_in), self);
1001 /* Header view CSM */
1002 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
1003 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
1004 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(priv->header_view), "tap-and-hold",
1005 G_CALLBACK(_header_view_csm_menu_activated),
1009 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (self), "window-state-event",
1010 G_CALLBACK (modest_main_window_window_state_event),
1013 /* Mail Operation Queue */
1014 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_mail_operation_queue ()),
1015 "queue-changed", G_CALLBACK (on_queue_changed), self);
1017 /* Track changes in the device name */
1018 priv->notification_id = modest_conf_listen_to_namespace (modest_runtime_get_conf (),
1019 MODEST_CONF_NAMESPACE);
1020 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT(modest_runtime_get_conf ()),
1021 "key_changed", G_CALLBACK (on_configuration_key_changed),
1024 /* Track account changes. We need to refresh the toolbar */
1025 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_store ()),
1026 "account_inserted", G_CALLBACK (on_account_inserted),
1028 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_store ()),
1029 "account_removed", G_CALLBACK (on_account_removed),
1032 /* We need to refresh the send & receive menu to change the bold
1033 * account when the default account changes. */
1034 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_mgr ()),
1035 "account_changed", G_CALLBACK (on_account_changed),
1039 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (modest_runtime_get_account_store()),
1040 "password_requested",
1041 G_CALLBACK (modest_ui_actions_on_password_requested), self);
1045 /** Idle handler, to send/receive at startup .*/
1047 sync_accounts_cb (ModestMainWindow *win)
1049 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (win));
1050 return FALSE; /* Do not call this idle handler again. */
1054 static void on_hildon_program_is_topmost_notify(GObject *self,
1055 GParamSpec *propert_param, gpointer user_data)
1057 HildonProgram *app = HILDON_PROGRAM (self);
1060 ModestWindow* self = MODEST_WINDOW(user_data);
1063 /* Note that use of hildon_program_set_can_hibernate()
1064 * is generally referred to as "setting the killable flag",
1065 * though hibernation does not seem equal to death.
1068 if (hildon_program_get_is_topmost (app)) {
1069 /* Prevent hibernation when the progam comes to the foreground,
1070 * because hibernation should only happen when the application
1071 * is in the background: */
1072 hildon_program_set_can_hibernate (app, FALSE);
1074 /* Allow hibernation if the program has gone to the background: */
1076 /* However, prevent hibernation while the settings are being changed: */
1077 const gboolean hibernation_prevented =
1078 modest_window_mgr_get_hibernation_is_prevented (
1079 modest_runtime_get_window_mgr ());
1081 if (hibernation_prevented)
1082 hildon_program_set_can_hibernate (app, FALSE);
1084 /* Allow hibernation, after saving the state: */
1085 modest_osso_save_state();
1086 hildon_program_set_can_hibernate (app, TRUE);
1093 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
1095 GtkWidget *folder_win = (GtkWidget *) user_data;
1096 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1098 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
1099 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
1100 /* wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view)); */
1102 gtk_widget_show (GTK_WIDGET (priv->folder_view));
1104 /* Connect signals */
1105 connect_signals ((ModestMainWindow*)self);
1107 /* Set account store */
1108 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
1109 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1111 /* Load previous osso state, for instance if we are being restored from
1113 modest_osso_load_state ();
1115 /* Restore window & widget settings */
1117 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
1119 /* The UI spec wants us to show a connection dialog when the application is
1120 * started by the user, if there is no connection.
1121 * Do this before showing the account wizard,
1122 * because wizard needs a connection to discover capabilities. */
1123 modest_platform_connect_and_wait (GTK_WINDOW (self), NULL);
1125 /* Check if accounts exist and show the account wizard if not */
1126 gboolean accounts_exist =
1127 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1129 if (!accounts_exist) {
1130 /* This is necessary to have the main window shown behind the dialog
1131 It's an ugly hack... jschmid */
1132 gtk_widget_show_all(GTK_WIDGET(self));
1133 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
1136 GtkAction *send_receive_all;
1137 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1138 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
1139 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1140 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1141 gtk_action_set_visible (send_receive_all, g_slist_length (accounts) > 1);
1142 modest_account_mgr_free_account_names (accounts);
1147 modest_main_window_new (void)
1149 ModestMainWindow *self = NULL;
1150 ModestMainWindowPrivate *priv = NULL;
1151 ModestWindowPrivate *parent_priv = NULL;
1152 GtkWidget *folder_win = NULL;
1153 ModestDimmingRulesGroup *menu_rules_group = NULL;
1154 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
1155 GtkActionGroup *action_group = NULL;
1156 GError *error = NULL;
1157 ModestConf *conf = NULL;
1158 GtkAction *action = NULL;
1159 GdkPixbuf *window_icon;
1161 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
1162 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1163 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1165 parent_priv->ui_manager = gtk_ui_manager_new();
1166 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
1168 action_group = gtk_action_group_new ("ModestMainWindowActions");
1169 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
1171 menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules", FALSE);
1172 toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules", TRUE);
1174 /* Add common actions */
1175 gtk_action_group_add_actions (action_group,
1176 modest_action_entries,
1177 G_N_ELEMENTS (modest_action_entries),
1180 gtk_action_group_add_actions (action_group,
1181 modest_folder_view_action_entries,
1182 G_N_ELEMENTS (modest_folder_view_action_entries),
1185 gtk_action_group_add_actions (action_group,
1186 modest_header_view_action_entries,
1187 G_N_ELEMENTS (modest_header_view_action_entries),
1190 gtk_action_group_add_toggle_actions (action_group,
1191 modest_toggle_action_entries,
1192 G_N_ELEMENTS (modest_toggle_action_entries),
1195 gtk_action_group_add_toggle_actions (action_group,
1196 modest_main_window_toggle_action_entries,
1197 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
1200 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
1201 g_object_unref (action_group);
1203 /* Load the UI definition */
1204 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
1205 MODEST_UIDIR "modest-main-window-ui.xml", &error);
1206 if (error != NULL) {
1207 g_warning ("Could not merge modest-ui.xml: %s", error->message);
1208 g_error_free (error);
1212 /* Add common dimming rules */
1213 modest_dimming_rules_group_add_rules (menu_rules_group,
1214 modest_main_window_menu_dimming_entries,
1215 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
1216 MODEST_WINDOW (self));
1217 modest_dimming_rules_group_add_rules (toolbar_rules_group,
1218 modest_main_window_toolbar_dimming_entries,
1219 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
1220 MODEST_WINDOW (self));
1222 /* Insert dimming rules group for this window */
1223 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
1224 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
1225 g_object_unref (menu_rules_group);
1226 g_object_unref (toolbar_rules_group);
1228 /* Add accelerators */
1229 gtk_window_add_accel_group (GTK_WINDOW (self),
1230 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
1232 /* Menubar. Update the state of some toggles */
1233 parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
1234 conf = modest_runtime_get_conf ();
1235 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1236 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
1237 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1238 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR, NULL));
1239 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
1240 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
1241 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
1242 modest_conf_get_bool (conf, MODEST_CONF_MAIN_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL));
1243 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
1244 gtk_widget_show (parent_priv->menubar);
1246 /* Get device name */
1247 modest_maemo_utils_get_device_name ();
1251 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
1252 if (!priv->header_view)
1253 g_printerr ("modest: cannot instantiate header view\n");
1254 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
1255 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
1256 MODEST_CONF_HEADER_VIEW_KEY);
1258 /* Other style properties of header view */
1259 g_object_set (G_OBJECT (priv->header_view),
1260 "rules-hint", FALSE,
1262 /* gtk_widget_show (priv->header_view); */
1265 priv->empty_view = create_empty_view ();
1266 gtk_widget_show (priv->empty_view);
1268 /* Create scrolled windows */
1269 folder_win = gtk_scrolled_window_new (NULL, NULL);
1270 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
1271 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
1273 GTK_POLICY_AUTOMATIC);
1274 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
1276 GTK_POLICY_AUTOMATIC);
1277 /* gtk_widget_show (priv->contents_widget); */
1280 priv->main_paned = gtk_hpaned_new ();
1281 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
1282 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
1283 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
1285 /* putting it all together... */
1286 priv->main_vbox = gtk_vbox_new (FALSE, 6);
1287 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
1288 gtk_widget_show (priv->main_vbox);
1290 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
1292 HildonProgram *app = hildon_program_get_instance ();
1293 hildon_program_add_window (app, HILDON_WINDOW (self));
1295 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
1296 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
1298 g_signal_connect (G_OBJECT(self), "show",
1299 G_CALLBACK (modest_main_window_on_show), folder_win);
1301 /* Set window icon */
1302 window_icon = modest_platform_get_icon (MODEST_APP_ICON);
1304 gtk_window_set_icon (GTK_WINDOW (self), window_icon);
1305 g_object_unref (window_icon);
1308 /* Dont't restore settings here,
1309 * because it requires a gtk_widget_show(),
1310 * and we don't want to do that until later,
1311 * so that the UI is not visible for non-menu D-Bus activation.
1313 /* restore_settings (MODEST_MAIN_WINDOW(self), FALSE); */
1315 return MODEST_WINDOW(self);
1319 modest_main_window_close_all (ModestMainWindow *self)
1322 GtkResponseType response;
1324 /* Create the confirmation dialog MSG-NOT308 */
1325 note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
1326 _("emev_nc_close_windows"),
1327 _("mcen_bd_yes"), GTK_RESPONSE_YES,
1328 _("mcen_bd_no"), GTK_RESPONSE_NO,
1331 response = gtk_dialog_run (GTK_DIALOG (note));
1332 gtk_widget_destroy (GTK_WIDGET (note));
1334 if (response == GTK_RESPONSE_YES)
1342 modest_main_window_set_style (ModestMainWindow *self,
1343 ModestMainWindowStyle style)
1345 ModestMainWindowPrivate *priv;
1346 ModestWindowPrivate *parent_priv;
1350 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1352 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1353 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1355 /* no change -> nothing to do */
1356 if (priv->style == style)
1359 /* Get toggle button and update the state if needed. This will
1360 happen only when the set_style is not invoked from the UI,
1361 for example when it's called from widget memory */
1362 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToggleFolders");
1363 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
1364 if ((active && style == MODEST_MAIN_WINDOW_STYLE_SIMPLE) ||
1365 (!active && style == MODEST_MAIN_WINDOW_STYLE_SPLIT)) {
1366 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1367 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), !active);
1368 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1371 priv->style = style;
1373 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
1374 /* Remove main paned */
1375 g_object_ref (priv->main_paned);
1376 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1378 /* Reparent the contents widget to the main vbox */
1379 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
1382 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1383 /* Remove header view */
1384 g_object_ref (priv->contents_widget);
1385 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1387 /* Reparent the main paned */
1388 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1389 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1393 g_return_if_reached ();
1396 /* Let header view grab the focus if it's being shown */
1397 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1398 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1400 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1403 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1406 ModestMainWindowStyle
1407 modest_main_window_get_style (ModestMainWindow *self)
1409 ModestMainWindowPrivate *priv;
1411 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1413 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1420 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1422 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1423 ModestWindowPrivate *parent_priv;
1424 ModestWindowMgr *mgr;
1425 gboolean is_fullscreen;
1426 GtkAction *fs_toggle_action;
1429 mgr = modest_runtime_get_window_mgr ();
1431 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1433 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1435 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1436 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1437 if (is_fullscreen != active) {
1438 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1447 set_homogeneous (GtkWidget *widget,
1450 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
1451 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
1455 modest_main_window_show_toolbar (ModestWindow *self,
1456 gboolean show_toolbar)
1458 ModestMainWindowPrivate *priv = NULL;
1459 ModestWindowPrivate *parent_priv = NULL;
1460 GtkWidget *reply_button = NULL, *menu = NULL;
1461 GtkWidget *placeholder = NULL;
1462 ModestAccountMgr *mgr = NULL;
1463 TnyTransportAccount *transport_account = NULL;
1464 ModestTnySendQueue *send_queue = NULL;
1466 GSList *iter = NULL;
1467 GSList *account_names = NULL;
1468 const gchar *action_name;
1471 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1472 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1473 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1475 /* Set optimized view status */
1476 priv->optimized_view = !show_toolbar;
1478 if (!parent_priv->toolbar) {
1479 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1481 gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
1483 /* Set homogeneous toolbar */
1484 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar),
1485 set_homogeneous, NULL);
1487 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1488 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1489 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1490 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1491 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1492 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1493 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1494 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1496 /* Add ProgressBar (Transfer toolbar) */
1497 priv->progress_bar = modest_progress_bar_widget_new ();
1498 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1499 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1500 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1501 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1502 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1504 /* Connect cancel 'clicked' signal to abort progress mode */
1505 g_signal_connect(priv->cancel_toolitem, "clicked",
1506 G_CALLBACK(cancel_progressbar),
1509 /* Add it to the observers list */
1510 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1513 hildon_window_add_toolbar (HILDON_WINDOW (self),
1514 GTK_TOOLBAR (parent_priv->toolbar));
1516 /* Set reply button tap and hold menu */
1517 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1518 "/ToolBar/ToolbarMessageReply");
1519 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1520 "/ToolbarReplyCSM");
1521 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1523 /* Set send & receive button tap and hold menu */
1524 update_menus (MODEST_MAIN_WINDOW (self));
1526 /* Create send queue for all defined accounts */
1527 mgr = modest_runtime_get_account_mgr ();
1528 account_names = modest_account_mgr_account_names (mgr, TRUE);
1529 iter = account_names;
1532 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1533 (modest_runtime_get_account_store(),
1535 TNY_ACCOUNT_TYPE_TRANSPORT));
1537 /* Create new send queue for this new account */
1538 send_queue = modest_runtime_get_send_queue (transport_account);
1539 if (MODEST_IS_TNY_SEND_QUEUE(send_queue)) {
1541 /* Connect 'status_changed' signal of this new send-queue */
1542 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, G_OBJECT (send_queue), "status_changed",
1543 G_CALLBACK (modest_main_window_on_send_queue_status_changed),
1550 if (send_queue != NULL)
1551 g_object_unref (send_queue);
1552 if (transport_account != NULL)
1553 g_object_unref (transport_account);
1556 modest_account_mgr_free_account_names (account_names);
1560 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1561 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1562 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1564 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1565 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1567 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1571 /* Update also the actions (to update the toggles in the
1572 menus), we have to do it manually because some other window
1573 of the same time could have changed it (remember that the
1574 toolbar fullscreen mode is shared by all the windows of the
1576 if (modest_window_mgr_get_fullscreen_mode (modest_runtime_get_window_mgr ()))
1577 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarFullScreenMenu";
1579 action_name = "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarNormalScreenMenu";
1581 action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name);
1582 modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action),
1587 modest_main_window_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
1592 ModestMainWindowPrivate *priv = NULL;
1593 TnyFolderStore *selected_folder = NULL;
1594 TnyFolderType folder_type;
1596 g_return_if_fail (MODEST_IS_TNY_SEND_QUEUE (send_queue));
1597 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1598 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(user_data);
1600 /* Check if selected folder is OUTBOX */
1601 selected_folder = modest_folder_view_get_selected (priv->folder_view);
1602 if (!TNY_IS_FOLDER (selected_folder)) goto frees;
1603 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
1604 #if GTK_CHECK_VERSION(2, 8, 0) /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
1605 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1606 GtkTreeViewColumn * tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (priv->header_view),
1607 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
1608 gtk_tree_view_column_queue_resize (tree_column);
1614 if (selected_folder != NULL)
1615 g_object_unref (selected_folder);
1619 on_account_inserted (TnyAccountStore *accoust_store,
1620 TnyAccount *account,
1623 TnyTransportAccount *transport_account = NULL;
1624 ModestTnySendQueue *send_queue = NULL;
1625 ModestMainWindowPrivate *priv;
1626 const gchar *account_name = NULL;
1628 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1629 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1631 update_menus (MODEST_MAIN_WINDOW (user_data));
1633 /* Get transport account */
1634 account_name = tny_account_get_name (TNY_ACCOUNT (account));
1636 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1637 (modest_runtime_get_account_store(),
1639 TNY_ACCOUNT_TYPE_TRANSPORT));
1641 /* Create new send queue for this new account */
1642 send_queue = modest_runtime_get_send_queue (transport_account);
1643 if (!MODEST_IS_TNY_SEND_QUEUE(send_queue)) goto frees;
1645 /* Connect 'status_changed' signal of this new send-queue */
1646 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,G_OBJECT (send_queue), "status_changed",
1647 G_CALLBACK (modest_main_window_on_send_queue_status_changed),
1652 if (transport_account != NULL)
1653 g_object_unref (G_OBJECT (transport_account));
1654 if (send_queue != NULL)
1655 g_object_unref (send_queue);
1659 on_account_changed (ModestAccountMgr* mgr,
1660 const gchar* account,
1663 gchar *default_account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
1665 /* Actually, we only want to know when another account has become
1666 * the default account, but there is no default_account_changed
1667 * signal in ModestAccountMgr. */
1668 if(strcmp(account, default_account) == 0)
1669 update_menus (MODEST_MAIN_WINDOW (user_data));
1671 g_free (default_account);
1675 on_account_removed (TnyAccountStore *accoust_store,
1676 TnyAccount *account,
1679 update_menus (MODEST_MAIN_WINDOW (user_data));
1683 * This function manages the key events used to navigate between
1684 * header and folder views (when the window is in split view)
1687 * -------------------------------------------------
1688 * HeaderView GDK_Left Move focus to folder view
1689 * FolderView GDK_Right Move focus to header view
1691 * There is no need to scroll to selected row, the widgets will be the
1692 * responsibles of doing that (probably managing the focus-in event
1695 on_inner_widgets_key_pressed (GtkWidget *widget,
1699 ModestMainWindowPrivate *priv;
1701 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1703 /* Do nothing if we're in SIMPLE style */
1704 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1707 if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
1708 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1709 else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1710 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1716 set_alignment (GtkWidget *widget,
1719 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1720 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1724 create_empty_view (void)
1726 GtkLabel *label = NULL;
1727 GtkWidget *align = NULL;
1729 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1730 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1731 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1732 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1734 return GTK_WIDGET(align);
1738 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1740 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1745 gchar *gray_color_markup;
1747 vbox = gtk_vbox_new (FALSE, 0);
1749 /* Obtain the secondary text color. We need a realized widget, that's why
1750 we get styled_widget from outside */
1751 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1753 gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color);
1754 gray_color_markup = modest_text_utils_get_color_string (&color);
1756 // gray_color_markup is freed below
1757 gray_color_markup = g_strdup ("#BBBBBB");
1759 /* Account description: */
1761 if (modest_tny_account_is_virtual_local_folders (account)
1762 || (modest_tny_account_is_memory_card_account (account))) {
1764 /* Local folders: */
1766 /* Get device name */
1767 gchar *device_name = NULL;
1768 if (modest_tny_account_is_virtual_local_folders (account))
1769 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1770 MODEST_CONF_DEVICE_NAME, NULL);
1772 device_name = g_strdup (tny_account_get_name (account));
1774 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), ""); //TODO: Why the ""?
1775 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1776 gray_color_markup, tmp, device_name);
1778 label_w = gtk_label_new (NULL);
1779 gtk_label_set_markup (GTK_LABEL (label_w), label);
1780 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1781 g_free (device_name);
1784 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1785 gtk_box_pack_start (GTK_BOX (vbox),
1786 gtk_label_new (tny_account_get_name (account)),
1789 /* Other accounts, such as IMAP and POP: */
1794 /* Put proto in uppercase */
1795 proto = g_string_new (tny_account_get_proto (account));
1796 proto = g_string_ascii_up (proto);
1798 /* note: mcen_fi_localroot_description is something like "%s account"
1799 * however, we should display "%s account: %s"... therefore, ugly tmp */
1800 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1801 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1802 gray_color_markup, tmp, tny_account_get_name (account));
1805 label_w = gtk_label_new (NULL);
1806 gtk_label_set_markup (GTK_LABEL (label_w), label);
1807 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1808 g_string_free (proto, TRUE);
1814 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1815 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1816 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1817 modest_tny_folder_store_get_message_count (folder_store));
1818 label_w = gtk_label_new (NULL);
1819 gtk_label_set_markup (GTK_LABEL (label_w), label);
1820 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1824 label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d",
1826 _("mcen_fi_rootfolder_folders"),
1827 modest_tny_folder_store_get_folder_count (folder_store));
1828 label_w = gtk_label_new (NULL);
1829 gtk_label_set_markup (GTK_LABEL (label_w), label);
1830 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1834 if (modest_tny_account_is_virtual_local_folders (account)
1835 || modest_tny_account_is_memory_card_account (account)) {
1837 gchar *size = modest_text_utils_get_display_size (
1838 modest_tny_folder_store_get_local_size (folder_store));
1840 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1841 gray_color_markup, _("mcen_fi_rootfolder_size"),
1845 label_w = gtk_label_new (NULL);
1846 gtk_label_set_markup (GTK_LABEL (label_w), label);
1847 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1849 } else if (TNY_IS_ACCOUNT(folder_store)) {
1850 TnyAccount *account = TNY_ACCOUNT(folder_store);
1852 time_t last_updated;
1853 gchar *last_updated_string;
1854 /* Get last updated from configuration */
1855 last_updated = modest_account_mgr_get_int (modest_runtime_get_account_mgr (),
1856 tny_account_get_id (account),
1857 MODEST_ACCOUNT_LAST_UPDATED,
1859 if (last_updated > 0)
1860 last_updated_string = modest_text_utils_get_display_date(last_updated);
1862 last_updated_string = g_strdup (_("mcen_va_never"));
1864 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1865 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1866 label_w = gtk_label_new (NULL);
1867 gtk_label_set_markup (GTK_LABEL (label_w), label);
1868 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1869 g_free (last_updated_string);
1873 g_free (gray_color_markup);
1876 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1882 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1884 ModestMainWindowPrivate *priv = NULL;
1886 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1888 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1890 return priv->send_receive_in_progress;
1894 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1896 GtkAction *action = NULL;
1897 GtkWidget *widget = NULL;
1898 ModestMainWindowPrivate *priv = NULL;
1900 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1901 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1903 priv->send_receive_in_progress = TRUE;
1905 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1906 gtk_action_set_sensitive (action, FALSE);
1907 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1908 /* gtk_action_set_sensitive (action, FALSE); */
1909 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1910 gtk_widget_set_sensitive (widget, FALSE);
1914 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1916 GtkAction *action = NULL;
1917 GtkWidget *widget = NULL;
1918 ModestMainWindowPrivate *priv = NULL;
1920 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1921 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1923 priv->send_receive_in_progress = FALSE;
1925 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1926 gtk_action_set_sensitive (action, TRUE);
1927 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1928 /* gtk_action_set_sensitive (action, TRUE); */
1929 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1930 gtk_widget_set_sensitive (widget, TRUE);
1935 _on_msg_count_changed (ModestHeaderView *header_view,
1937 TnyFolderChange *change,
1938 ModestMainWindow *main_window)
1940 printf ("DEBUG: %s\n", __FUNCTION__);
1941 gboolean folder_empty = FALSE;
1942 gboolean all_marked_as_deleted = FALSE;
1943 TnyFolderChangeChanged changed;
1944 ModestMainWindowPrivate *priv;
1946 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1947 g_return_if_fail (TNY_IS_FOLDER(folder));
1948 g_return_if_fail (TNY_IS_FOLDER_CHANGE(change));
1949 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
1951 changed = tny_folder_change_get_changed (change);
1953 /* If something changes */
1954 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1955 folder_empty = (tny_folder_change_get_new_all_count (change) == 0);
1957 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1959 printf ("DEBUG: %s: folder_empty=%d\n", __FUNCTION__, folder_empty);
1961 /* Check header removed (hide marked as DELETED headers) */
1962 if (changed & TNY_FOLDER_CHANGE_CHANGED_EXPUNGED_HEADERS) {
1963 modest_header_view_refilter (MODEST_HEADER_VIEW(priv->header_view));
1966 /* Check if all messages are marked to be deleted */
1967 all_marked_as_deleted = modest_header_view_is_empty (header_view);
1968 folder_empty = folder_empty || all_marked_as_deleted ;
1970 /* Set contents style of headers view */
1972 modest_main_window_set_contents_style (main_window,
1973 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1974 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1977 modest_main_window_set_contents_style (main_window,
1978 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1984 modest_main_window_set_contents_style (ModestMainWindow *self,
1985 ModestMainWindowContentsStyle style)
1987 ModestMainWindowPrivate *priv;
1989 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1991 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1993 /* We allow to set the same content style than the previously
1994 set if there are details, because it could happen when we're
1995 selecting different accounts consecutively */
1996 if ((priv->contents_style == style) &&
1997 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
2000 /* Remove previous child. Delete it if it was an account
2002 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
2004 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2005 g_object_ref (content);
2006 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
2007 g_object_ref (priv->empty_view);
2008 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
2011 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
2014 priv->contents_style = style;
2016 switch (priv->contents_style) {
2017 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
2018 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
2019 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2022 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
2024 /* if we're started without main win, there may not be a folder
2025 * view. this fixes a GLib-Critical */
2026 if (priv->folder_view) {
2027 TnyFolderStore *selected_folderstore =
2028 modest_folder_view_get_selected (priv->folder_view);
2029 if (TNY_IS_ACCOUNT (selected_folderstore)) {
2030 priv->details_widget = create_details_widget (GTK_WIDGET (self),
2031 TNY_ACCOUNT (selected_folderstore));
2033 wrap_in_scrolled_window (priv->contents_widget,
2034 priv->details_widget);
2036 g_object_unref (selected_folderstore);
2037 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2042 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
2043 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
2044 modest_maemo_set_thumbable_scrollbar (GTK_SCROLLED_WINDOW(priv->contents_widget),
2048 g_return_if_reached ();
2052 gtk_widget_show_all (priv->contents_widget);
2055 ModestMainWindowContentsStyle
2056 modest_main_window_get_contents_style (ModestMainWindow *self)
2058 ModestMainWindowPrivate *priv;
2060 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
2062 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2063 return priv->contents_style;
2068 on_configuration_key_changed (ModestConf* conf,
2070 ModestConfEvent event,
2071 ModestConfNotificationId id,
2072 ModestMainWindow *self)
2074 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2075 TnyAccount *account = NULL;
2078 priv->notification_id != id ||
2079 strcmp (key, MODEST_CONF_DEVICE_NAME))
2082 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
2084 if (priv->folder_view)
2085 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
2086 if (account && TNY_IS_ACCOUNT (account) &&
2087 strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID) == 0) {
2090 const gchar *device_name;
2094 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
2095 label = GTK_LABEL (children->data);
2097 device_name = modest_conf_get_string (modest_runtime_get_conf(),
2098 MODEST_CONF_DEVICE_NAME, NULL);
2100 new_text = g_strdup_printf ("%s: %s",
2101 _("mcen_fi_localroot_description"),
2104 gtk_label_set_text (label, new_text);
2105 gtk_widget_show (GTK_WIDGET (label));
2108 g_list_free (children);
2110 g_object_unref (account);
2114 set_toolbar_transfer_mode (ModestMainWindow *self)
2116 ModestMainWindowPrivate *priv = NULL;
2118 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2120 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2122 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
2124 if (priv->progress_bar_timeout > 0) {
2125 g_source_remove (priv->progress_bar_timeout);
2126 priv->progress_bar_timeout = 0;
2133 set_toolbar_mode (ModestMainWindow *self,
2134 ModestToolBarModes mode)
2136 ModestWindowPrivate *parent_priv = NULL;
2137 ModestMainWindowPrivate *priv = NULL;
2138 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
2140 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2142 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
2143 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2145 /* In case this was called before the toolbar exists: */
2146 if (!(parent_priv->toolbar))
2149 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
2151 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
2152 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
2153 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
2155 /* Sets current toolbar mode */
2156 priv->current_toolbar_mode = mode;
2158 /* Checks the dimming rules */
2159 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
2161 /* Show and hide toolbar items */
2163 case TOOLBAR_MODE_NORMAL:
2165 gtk_action_set_visible (sort_action, TRUE);
2167 gtk_action_set_visible (refresh_action, TRUE);
2168 if (priv->progress_toolitem) {
2169 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
2170 gtk_widget_hide (priv->progress_toolitem);
2172 if (priv->progress_bar)
2173 gtk_widget_hide (priv->progress_bar);
2176 gtk_action_set_visible (cancel_action, FALSE);
2178 /* Hide toolbar if optimized view is enabled */
2179 if (priv->optimized_view)
2180 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
2182 case TOOLBAR_MODE_TRANSFER:
2184 gtk_action_set_visible (sort_action, FALSE);
2186 gtk_action_set_visible (refresh_action, FALSE);
2188 gtk_action_set_visible (cancel_action, TRUE);
2189 if (priv->progress_toolitem) {
2190 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
2191 gtk_widget_show (priv->progress_toolitem);
2193 if (priv->progress_bar)
2194 gtk_widget_show (priv->progress_bar);
2196 /* Show toolbar if it's hiden (optimized view ) */
2197 if (priv->optimized_view)
2198 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
2201 g_return_if_reached ();
2206 modest_main_window_transfer_mode_enabled (ModestMainWindow *self)
2208 ModestMainWindowPrivate *priv;
2210 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2211 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2213 return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
2217 cancel_progressbar (GtkToolButton *toolbutton,
2218 ModestMainWindow *self)
2221 ModestMainWindowPrivate *priv;
2223 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2225 /* Get operation observers and cancel all the operations */
2226 tmp = priv->progress_widgets;
2228 modest_progress_object_cancel_all_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2229 tmp=g_slist_next(tmp);
2234 observers_empty (ModestMainWindow *self)
2237 ModestMainWindowPrivate *priv;
2238 gboolean is_empty = TRUE;
2239 guint pending_ops = 0;
2241 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2242 tmp = priv->progress_widgets;
2244 /* Check all observers */
2245 while (tmp && is_empty) {
2246 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
2247 is_empty = pending_ops == 0;
2249 tmp = g_slist_next(tmp);
2256 on_queue_changed (ModestMailOperationQueue *queue,
2257 ModestMailOperation *mail_op,
2258 ModestMailOperationQueueNotification type,
2259 ModestMainWindow *self)
2261 ModestMainWindowPrivate *priv;
2262 ModestMailOperationTypeOperation op_type;
2263 ModestToolBarModes mode;
2265 gboolean mode_changed = FALSE;
2267 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
2268 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2270 /* Get toolbar mode from operation id*/
2271 op_type = modest_mail_operation_get_type_operation (mail_op);
2273 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
2274 case MODEST_MAIL_OPERATION_TYPE_OPEN:
2275 mode = TOOLBAR_MODE_TRANSFER;
2276 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
2277 mode_changed = TRUE;
2280 mode = TOOLBAR_MODE_NORMAL;
2285 /* Add operation observers and change toolbar if neccessary*/
2286 tmp = priv->progress_widgets;
2288 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
2289 if (mode == TOOLBAR_MODE_TRANSFER) {
2291 set_toolbar_transfer_mode(self);
2294 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2296 tmp = g_slist_next (tmp);
2300 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
2301 /* Change toolbar mode */
2302 if (mode == TOOLBAR_MODE_TRANSFER) {
2304 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
2306 tmp = g_slist_next (tmp);
2309 /* If no more operations are being observed, NORMAL mode is enabled again */
2310 if (observers_empty (self)) {
2311 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
2321 set_account_visible(ModestMainWindow *self, const gchar *acc_name)
2323 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2326 /* Get account data */
2327 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
2328 ModestAccountData *acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
2330 /* Set the new visible & active account */
2331 if (acc_data && acc_data->store_account) {
2332 modest_folder_view_set_account_id_of_visible_server_account (priv->folder_view,
2333 acc_data->store_account->account_name);
2334 modest_window_set_active_account (MODEST_WINDOW (self), acc_data->account_name);
2335 action = gtk_action_group_get_action (priv->view_additions_group, acc_data->account_name);
2336 if (action != NULL) {
2337 if (!gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) {
2338 modest_maemo_toggle_action_set_active_block_notify (
2339 GTK_TOGGLE_ACTION (action),
2345 modest_folder_view_select_first_inbox_or_local (priv->folder_view);
2350 modest_account_mgr_free_account_data (mgr, acc_data);
2353 /* Make sure that at least one account is "viewed": */
2355 set_at_least_one_account_visible(ModestMainWindow *self)
2357 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2358 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2360 if (!(priv->folder_view)) {
2361 /* It is too early to do this. */
2365 const gchar *active_server_account_name =
2366 modest_folder_view_get_account_id_of_visible_server_account (priv->folder_view);
2367 if (!active_server_account_name ||
2368 !modest_account_mgr_account_exists (account_mgr, active_server_account_name, TRUE))
2370 gchar* first_modest_name = modest_account_mgr_get_first_account_name (account_mgr);
2371 if (first_modest_name) {
2372 set_account_visible (self, first_modest_name);
2373 g_free (first_modest_name);
2379 on_show_account_action_toggled (GtkToggleAction *action,
2382 ModestMainWindow *self = MODEST_MAIN_WINDOW (user_data);
2384 const gchar *acc_name = gtk_action_get_name (GTK_ACTION (action));
2385 if (gtk_toggle_action_get_active (action))
2386 set_account_visible (self, acc_name);
2390 refresh_account (const gchar *account_name)
2394 win = MODEST_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2396 /* If account_name == NULL, we must update all (option All) */
2398 modest_ui_actions_do_send_receive_all (win);
2400 modest_ui_actions_do_send_receive (account_name, win);
2405 on_refresh_account_action_activated (GtkAction *action,
2408 refresh_account ((const gchar*) user_data);
2412 on_send_receive_csm_activated (GtkMenuItem *item,
2415 refresh_account ((const gchar*) user_data);
2419 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2421 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2423 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2429 on_folder_view_focus_in (GtkWidget *widget,
2430 GdkEventFocus *event,
2433 ModestMainWindow *main_window = NULL;
2435 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2436 main_window = MODEST_MAIN_WINDOW (userdata);
2438 /* Update toolbar dimming state */
2439 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2445 on_header_view_focus_in (GtkWidget *widget,
2446 GdkEventFocus *event,
2449 ModestMainWindow *main_window = NULL;
2450 ModestMainWindowPrivate *priv = NULL;
2452 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (userdata), FALSE);
2453 main_window = MODEST_MAIN_WINDOW (userdata);
2454 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
2456 /* Update toolbar dimming state */
2457 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2463 modest_main_window_on_folder_selection_changed (ModestFolderView *folder_view,
2464 TnyFolderStore *folder_store,
2466 ModestMainWindow *main_window)
2468 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2469 GtkAction *action = NULL;
2470 gboolean show_reply = TRUE;
2471 gboolean show_forward = TRUE;
2472 gboolean show_cancel_send = FALSE;
2473 gboolean show_clipboard = TRUE;
2474 gboolean show_delete = TRUE;
2477 if (TNY_IS_ACCOUNT (folder_store)) {
2478 show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2479 } else if (TNY_IS_FOLDER (folder_store)) {
2480 if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2481 TnyFolderType folder_type = modest_tny_folder_get_local_or_mmc_folder_type (
2482 TNY_FOLDER (folder_store));
2483 switch (folder_type) {
2484 case TNY_FOLDER_TYPE_DRAFTS:
2485 show_clipboard = show_delete = TRUE;
2486 show_reply = show_forward = show_cancel_send = FALSE;
2488 case TNY_FOLDER_TYPE_SENT:
2489 show_forward = show_clipboard = show_delete = TRUE;
2490 show_reply = show_cancel_send = FALSE;
2492 case TNY_FOLDER_TYPE_OUTBOX:
2493 show_clipboard = show_delete = show_cancel_send = TRUE;
2494 show_reply = show_forward = FALSE;
2497 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2498 show_cancel_send = FALSE;
2501 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2502 show_cancel_send = FALSE;
2507 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2508 gtk_action_set_visible (action, show_reply);
2509 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2510 gtk_action_set_visible (action, show_reply);
2511 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2512 gtk_action_set_visible (action, show_forward);
2513 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2514 gtk_action_set_visible (action, show_cancel_send);
2515 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCut"); */
2516 /* gtk_action_set_visible (action, show_clipboard); */
2517 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCopy"); */
2518 /* gtk_action_set_visible (action, show_clipboard); */
2519 /* action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMPaste"); */
2520 /* gtk_action_set_visible (action, show_clipboard); */
2521 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2522 gtk_action_set_visible (action, show_delete);
2524 /* We finally call to the ui actions handler, after updating properly
2525 * the header view CSM */
2526 modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);
2531 modest_main_window_on_msg_view_window_msg_changed (ModestMsgViewWindow *view_window,
2532 GtkTreeModel *model,
2533 GtkTreeRowReference *row_reference,
2534 ModestMainWindow *self)
2536 ModestMainWindowPrivate *priv = NULL;
2537 GtkTreeModel *header_model = NULL;
2538 GtkTreePath *path = NULL;
2540 g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (view_window), FALSE);
2541 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
2542 g_return_val_if_fail (gtk_tree_row_reference_valid (row_reference), FALSE);
2544 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
2545 header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->header_view));
2547 /* Do nothing if we changed the folder in the main view */
2548 if (header_model != model)
2551 /* Select the message in the header view */
2552 path = gtk_tree_row_reference_get_path (row_reference);
2553 gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->header_view),
2555 gtk_tree_path_free (path);