X-Git-Url: http://git.maemo.org/git/?p=modest;a=blobdiff_plain;f=src%2Fmaemo%2Fmodest-msg-view-window.c;h=5159c34f35d1e28ffeb12356c6cb047b8adfff5a;hp=f1cfae48c778f117446ca688d4a1ef099723ef39;hb=16d0ac8ab2e3792b9351d280311dab516f9b6051;hpb=d4537d8a01b0789310de9a11d3344147ee9691c0 diff --git a/src/maemo/modest-msg-view-window.c b/src/maemo/modest-msg-view-window.c index f1cfae4..5159c34 100644 --- a/src/maemo/modest-msg-view-window.c +++ b/src/maemo/modest-msg-view-window.c @@ -35,6 +35,7 @@ #include #include "modest-marshal.h" #include "modest-platform.h" +#include #include #include #include @@ -56,6 +57,8 @@ #include #include #include +#include +#include #define DEFAULT_FOLDER "MyDocs/.documents" @@ -77,14 +80,12 @@ static void modest_msg_view_window_set_zoom (ModestWindow *window, static gdouble modest_msg_view_window_get_zoom (ModestWindow *window); static gboolean modest_msg_view_window_zoom_minus (ModestWindow *window); static gboolean modest_msg_view_window_zoom_plus (ModestWindow *window); -static gboolean modest_msg_view_window_key_release_event (GtkWidget *window, - GdkEventKey *event, - gpointer userdata); +static gboolean modest_msg_view_window_key_event (GtkWidget *window, + GdkEventKey *event, + gpointer userdata); static gboolean modest_msg_view_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata); -static void modest_msg_view_window_scroll_up (ModestWindow *window); -static void modest_msg_view_window_scroll_down (ModestWindow *window); static void modest_msg_view_window_update_priority (ModestMsgViewWindow *window); static void modest_msg_view_window_show_toolbar (ModestWindow *window, @@ -134,13 +135,15 @@ static void on_account_removed (TnyAccountStore *account_store, TnyAccount *account, gpointer user_data); -static void on_move_focus (ModestMsgViewWindow *window, +static void on_move_focus (GtkWidget *widget, GtkDirectionType direction, gpointer userdata); static void view_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, + gboolean canceled, TnyMsg *msg, + GError *error, gpointer user_data); static void set_toolbar_mode (ModestMsgViewWindow *self, @@ -149,6 +152,9 @@ static void set_toolbar_mode (ModestMsgViewWindow *self, static void update_window_title (ModestMsgViewWindow *window); static gboolean set_toolbar_transfer_mode (ModestMsgViewWindow *self); +static void init_window (ModestMsgViewWindow *obj); + +static gboolean msg_is_visible (TnyHeader *header, gboolean check_outbox); /* list my signals */ @@ -159,7 +165,7 @@ enum { static const GtkToggleActionEntry msg_view_toggle_action_entries [] = { { "FindInMessage", MODEST_TOOLBAR_ICON_FIND, N_("qgn_toolb_gene_find"), NULL, NULL, G_CALLBACK (modest_msg_view_window_toggle_find_toolbar), FALSE }, - { "ToolsFindInMessage", NULL, N_("mcen_me_viewer_find"), NULL, NULL, G_CALLBACK (modest_msg_view_window_toggle_find_toolbar), FALSE }, + { "ToolsFindInMessage", NULL, N_("mcen_me_viewer_find"), "F", NULL, G_CALLBACK (modest_msg_view_window_toggle_find_toolbar), FALSE }, }; static const GtkRadioActionEntry msg_view_zoom_action_entries [] = { @@ -195,6 +201,9 @@ struct _ModestMsgViewWindowPrivate { /* Whether this was created via the *_new_for_search_result() function. */ gboolean is_search_result; + + /* Whether the message is in outbox */ + gboolean is_outbox; /* A reference to the @model of the header view * to allow selecting previous/next messages, @@ -219,6 +228,8 @@ struct _ModestMsgViewWindowPrivate { guint progress_bar_timeout; gchar *msg_uid; + + GSList *sighandlers; }; #define MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ @@ -277,7 +288,20 @@ save_state (ModestWindow *self) static void restore_settings (ModestMsgViewWindow *self) { - modest_widget_memory_restore (modest_runtime_get_conf (), + ModestConf *conf; + ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self); + GtkAction *action; + + conf = modest_runtime_get_conf (); + action = gtk_ui_manager_get_action (parent_priv->ui_manager, + "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarNormalScreenMenu"); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), + modest_conf_get_bool (conf, MODEST_CONF_MSG_VIEW_WINDOW_SHOW_TOOLBAR, NULL)); + action = gtk_ui_manager_get_action (parent_priv->ui_manager, + "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarFullScreenMenu"); + gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), + modest_conf_get_bool (conf, MODEST_CONF_MSG_VIEW_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL)); + modest_widget_memory_restore (conf, G_OBJECT(self), MODEST_CONF_MSG_VIEW_WINDOW_KEY); } @@ -324,9 +348,57 @@ static void modest_msg_view_window_init (ModestMsgViewWindow *obj) { ModestMsgViewWindowPrivate *priv; + ModestWindowPrivate *parent_priv = NULL; + GtkActionGroup *action_group = NULL; + GError *error = NULL; + GdkPixbuf *window_icon; + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj); + parent_priv = MODEST_WINDOW_GET_PRIVATE(obj); + parent_priv->ui_manager = gtk_ui_manager_new(); + + action_group = gtk_action_group_new ("ModestMsgViewWindowActions"); + gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE); + /* Add common actions */ + gtk_action_group_add_actions (action_group, + modest_action_entries, + G_N_ELEMENTS (modest_action_entries), + obj); + gtk_action_group_add_toggle_actions (action_group, + modest_toggle_action_entries, + G_N_ELEMENTS (modest_toggle_action_entries), + obj); + gtk_action_group_add_toggle_actions (action_group, + msg_view_toggle_action_entries, + G_N_ELEMENTS (msg_view_toggle_action_entries), + obj); + gtk_action_group_add_radio_actions (action_group, + msg_view_zoom_action_entries, + G_N_ELEMENTS (msg_view_zoom_action_entries), + 100, + G_CALLBACK (modest_ui_actions_on_change_zoom), + obj); + + gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0); + g_object_unref (action_group); + + /* Load the UI definition */ + gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-view-window-ui.xml", + &error); + if (error) { + g_printerr ("modest: could not merge modest-msg-view-window-ui.xml: %s\n", error->message); + g_error_free (error); + error = NULL; + } + /* ****** */ + + /* Add accelerators */ + gtk_window_add_accel_group (GTK_WINDOW (obj), + gtk_ui_manager_get_accel_group (parent_priv->ui_manager)); + priv->is_search_result = FALSE; + priv->is_outbox = FALSE; priv->msg_view = NULL; priv->header_model = NULL; @@ -346,6 +418,31 @@ modest_msg_view_window_init (ModestMsgViewWindow *obj) priv->remove_attachment_banner = NULL; priv->msg_uid = NULL; + priv->sighandlers = NULL; + + /* Init window */ + init_window (MODEST_MSG_VIEW_WINDOW(obj)); + + /* Set window icon */ + window_icon = modest_platform_get_icon (MODEST_APP_MSG_VIEW_ICON); + if (window_icon) { + /* scale the icon, because it won't be shown unless it's + * 64 x 54 -- hildon quirk. this looks a bit ugly now, + * so waiting for correctly sized icons, then this scaling + * code can disappear -- djcb + */ + GdkPixbuf *scaled = + gdk_pixbuf_scale_simple (window_icon, 64, 54, GDK_INTERP_BILINEAR); + if (scaled) { + gtk_window_set_icon (GTK_WINDOW (obj), scaled); + g_object_unref (scaled); + } + g_object_unref (window_icon); + } + + hildon_program_add_window (hildon_program_get_instance(), + HILDON_WINDOW(obj)); + modest_window_mgr_register_help_id (modest_runtime_get_window_mgr(), GTK_WINDOW(obj),"applications_email_viewer"); } @@ -391,29 +488,23 @@ set_toolbar_mode (ModestMsgViewWindow *self, switch (mode) { case TOOLBAR_MODE_NORMAL: -/* widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply"); */ -/* gtk_action_set_sensitive (widget, TRUE); */ -/* widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage"); */ -/* gtk_action_set_sensitive (widget, TRUE); */ -/* widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageMoveTo"); */ -/* gtk_action_set_sensitive (widget, TRUE); */ -/* widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/FindInMessage"); */ -/* gtk_action_set_sensitive (widget, TRUE); */ - - if (priv->prev_toolitem) - gtk_widget_show (priv->prev_toolitem); - - if (priv->next_toolitem) - gtk_widget_show (priv->next_toolitem); - - if (priv->progress_toolitem) + if (priv->progress_toolitem) { gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE); + gtk_widget_hide (priv->progress_toolitem); + } + if (priv->progress_bar) gtk_widget_hide (priv->progress_bar); if (priv->cancel_toolitem) gtk_widget_hide (priv->cancel_toolitem); + if (priv->prev_toolitem) + gtk_widget_show (priv->prev_toolitem); + + if (priv->next_toolitem) + gtk_widget_show (priv->next_toolitem); + /* Hide toolbar if optimized view is enabled */ if (priv->optimized_view) { gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE); @@ -422,25 +513,19 @@ set_toolbar_mode (ModestMsgViewWindow *self, break; case TOOLBAR_MODE_TRANSFER: -/* widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply"); */ -/* gtk_action_set_sensitive (widget, FALSE); */ -/* widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarDeleteMessage"); */ -/* gtk_action_set_sensitive (widget, FALSE); */ -/* widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarMessageMoveTo"); */ -/* gtk_action_set_sensitive (widget, FALSE); */ -/* widget = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/FindInMessage"); */ -/* gtk_action_set_sensitive (widget, FALSE); */ - if (priv->prev_toolitem) gtk_widget_hide (priv->prev_toolitem); if (priv->next_toolitem) gtk_widget_hide (priv->next_toolitem); - if (priv->progress_toolitem) - gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE); if (priv->progress_bar) gtk_widget_show (priv->progress_bar); + + if (priv->progress_toolitem) { + gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE); + gtk_widget_show (priv->progress_toolitem); + } if (priv->cancel_toolitem) gtk_widget_show (priv->cancel_toolitem); @@ -463,26 +548,10 @@ static GtkWidget * menubar_to_menu (GtkUIManager *ui_manager) { GtkWidget *main_menu; - GtkWidget *menubar; - GList *iter, *children; - - /* Create new main menu */ - main_menu = gtk_menu_new(); /* Get the menubar from the UI manager */ - menubar = gtk_ui_manager_get_widget (ui_manager, "/MenuBar"); - - iter = children = gtk_container_get_children (GTK_CONTAINER (menubar)); - while (iter) { - GtkWidget *menu; + main_menu = gtk_ui_manager_get_widget (ui_manager, "/MenuBar"); - menu = GTK_WIDGET (iter->data); - gtk_widget_reparent(menu, main_menu); - - iter = g_list_next (iter); - } - g_list_free (children); - return main_menu; } @@ -492,8 +561,6 @@ init_window (ModestMsgViewWindow *obj) GtkWidget *main_vbox; ModestMsgViewWindowPrivate *priv; ModestWindowPrivate *parent_priv; - ModestConf *conf; - GtkAction *action = NULL; priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj); parent_priv = MODEST_WINDOW_GET_PRIVATE(obj); @@ -502,20 +569,6 @@ init_window (ModestMsgViewWindow *obj) modest_msg_view_set_shadow_type (MODEST_MSG_VIEW (priv->msg_view), GTK_SHADOW_NONE); main_vbox = gtk_vbox_new (FALSE, 6); - /* Menubar */ - parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager); - conf = modest_runtime_get_conf (); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, - "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarNormalScreenMenu"); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), - modest_conf_get_bool (conf, MODEST_CONF_MSG_VIEW_WINDOW_SHOW_TOOLBAR, NULL)); - action = gtk_ui_manager_get_action (parent_priv->ui_manager, - "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarFullScreenMenu"); - gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), - modest_conf_get_bool (conf, MODEST_CONF_MSG_VIEW_WINDOW_SHOW_TOOLBAR_FULLSCREEN, NULL)); - hildon_window_set_menu (HILDON_WINDOW(obj), GTK_MENU(parent_priv->menubar)); - gtk_widget_show (GTK_WIDGET(parent_priv->menubar)); - #ifdef MODEST_USE_MOZEMBED priv->main_scroll = priv->msg_view; gtk_widget_set_size_request (priv->msg_view, -1, 1600); @@ -533,10 +586,7 @@ init_window (ModestMsgViewWindow *obj) priv->find_toolbar = hildon_find_toolbar_new (NULL); hildon_window_add_toolbar (HILDON_WINDOW (obj), GTK_TOOLBAR (priv->find_toolbar)); gtk_widget_set_no_show_all (priv->find_toolbar, TRUE); - g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_view_window_find_toolbar_close), obj); - g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_view_window_find_toolbar_search), obj); - priv->clipboard_change_handler = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change", G_CALLBACK (modest_msg_view_window_clipboard_owner_change), obj); gtk_widget_show_all (GTK_WIDGET(main_vbox)); } @@ -587,6 +637,9 @@ modest_msg_view_window_disconnect_signals (ModestWindow *self) priv->rows_reordered_handler); } + modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers); + priv->sighandlers = NULL; + main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(), FALSE); /* don't create */ if (!main_window) @@ -701,9 +754,6 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self, ModestDimmingRulesGroup *menu_rules_group = NULL; ModestDimmingRulesGroup *toolbar_rules_group = NULL; ModestDimmingRulesGroup *clipboard_rules_group = NULL; - GtkActionGroup *action_group = NULL; - GError *error = NULL; - GdkPixbuf *window_icon; obj = G_OBJECT (self); priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(obj); @@ -711,49 +761,16 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self, priv->msg_uid = g_strdup (msg_uid); - parent_priv->ui_manager = gtk_ui_manager_new(); + /* Menubar */ + parent_priv->menubar = menubar_to_menu (parent_priv->ui_manager); + hildon_window_set_menu (HILDON_WINDOW(obj), GTK_MENU(parent_priv->menubar)); + gtk_widget_show (parent_priv->menubar); parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new(); - action_group = gtk_action_group_new ("ModestMsgViewWindowActions"); - gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE); - menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules", FALSE); toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules", TRUE); clipboard_rules_group = modest_dimming_rules_group_new ("ModestClipboardDimmingRules", FALSE); - /* Add common actions */ - gtk_action_group_add_actions (action_group, - modest_action_entries, - G_N_ELEMENTS (modest_action_entries), - obj); - gtk_action_group_add_toggle_actions (action_group, - modest_toggle_action_entries, - G_N_ELEMENTS (modest_toggle_action_entries), - obj); - gtk_action_group_add_toggle_actions (action_group, - msg_view_toggle_action_entries, - G_N_ELEMENTS (msg_view_toggle_action_entries), - obj); - gtk_action_group_add_radio_actions (action_group, - msg_view_zoom_action_entries, - G_N_ELEMENTS (msg_view_zoom_action_entries), - 100, - G_CALLBACK (modest_ui_actions_on_change_zoom), - obj); - - gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0); - g_object_unref (action_group); - - /* Load the UI definition */ - gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager, MODEST_UIDIR "modest-msg-view-window-ui.xml", - &error); - if (error) { - g_printerr ("modest: could not merge modest-msg-view-window-ui.xml: %s\n", error->message); - g_error_free (error); - error = NULL; - } - /* ****** */ - /* Add common dimming rules */ modest_dimming_rules_group_add_rules (menu_rules_group, modest_msg_view_menu_dimming_entries, @@ -776,23 +793,11 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self, g_object_unref (toolbar_rules_group); g_object_unref (clipboard_rules_group); - /* Add accelerators */ - gtk_window_add_accel_group (GTK_WINDOW (obj), - gtk_ui_manager_get_accel_group (parent_priv->ui_manager)); - - /* Init window */ - init_window (MODEST_MSG_VIEW_WINDOW(obj)); restore_settings (MODEST_MSG_VIEW_WINDOW(obj)); - /* Set window icon */ - window_icon = modest_platform_get_icon (MODEST_APP_MSG_VIEW_ICON); - if (window_icon) { - gtk_window_set_icon (GTK_WINDOW (obj), window_icon); - g_object_unref (window_icon); - } - /* g_signal_connect (G_OBJECT(obj), "delete-event", G_CALLBACK(on_delete_event), obj); */ + priv->clipboard_change_handler = g_signal_connect (G_OBJECT (gtk_clipboard_get (GDK_SELECTION_PRIMARY)), "owner-change", G_CALLBACK (modest_msg_view_window_clipboard_owner_change), obj); g_signal_connect (G_OBJECT(priv->msg_view), "activate_link", G_CALLBACK (modest_ui_actions_on_msg_link_clicked), obj); g_signal_connect (G_OBJECT(priv->msg_view), "link_hover", @@ -805,7 +810,11 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self, G_CALLBACK (modest_ui_actions_on_msg_link_contextual), obj); g_signal_connect (G_OBJECT (obj), "key-release-event", - G_CALLBACK (modest_msg_view_window_key_release_event), + G_CALLBACK (modest_msg_view_window_key_event), + NULL); + + g_signal_connect (G_OBJECT (obj), "key-press-event", + G_CALLBACK (modest_msg_view_window_key_event), NULL); g_signal_connect (G_OBJECT (obj), "window-state-event", @@ -829,6 +838,8 @@ modest_msg_view_window_construct (ModestMsgViewWindow *self, modest_window_set_active_account (MODEST_WINDOW(obj), modest_account_name); + g_signal_connect (G_OBJECT (priv->find_toolbar), "close", G_CALLBACK (modest_msg_view_window_find_toolbar_close), obj); + g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_view_window_find_toolbar_search), obj); priv->last_search = NULL; /* Init the clipboard actions dim status */ @@ -855,8 +866,10 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg, TnyFolder *header_folder = NULL; ModestHeaderView *header_view = NULL; ModestWindow *main_window = NULL; - - window = g_object_new(MODEST_TYPE_MSG_VIEW_WINDOW, NULL); + ModestWindowMgr *mgr = NULL; + + mgr = modest_runtime_get_window_mgr (); + window = MODEST_MSG_VIEW_WINDOW (modest_window_mgr_get_msg_view_window (mgr)); g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), NULL); modest_msg_view_window_construct (window, modest_account_name, msg_uid); @@ -866,8 +879,7 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg, /* Remember the message list's TreeModel so we can detect changes * and change the list selection when necessary: */ - main_window = modest_window_mgr_get_main_window( - modest_runtime_get_window_mgr(), FALSE); /* don't create */ + main_window = modest_window_mgr_get_main_window(mgr, FALSE); /* don't create */ if (!main_window) { g_warning ("%s: BUG: no main window", __FUNCTION__); return NULL; @@ -878,6 +890,7 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW)); if (header_view != NULL){ header_folder = modest_header_view_get_folder(header_view); + priv->is_outbox = (modest_tny_folder_guess_folder_type (header_folder) == TNY_FOLDER_TYPE_OUTBOX); g_assert(header_folder != NULL); priv->header_folder_id = tny_folder_get_id(header_folder); g_assert(priv->header_folder_id != NULL); @@ -911,9 +924,9 @@ modest_msg_view_window_new_with_header_model (TnyMsg *msg, MODEST_HEADER_VIEW_OBSERVER(window)); } - gtk_widget_show_all (GTK_WIDGET (window)); - tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg); + update_window_title (MODEST_MSG_VIEW_WINDOW (window)); + gtk_widget_show_all (GTK_WIDGET (window)); modest_msg_view_window_update_priority (window); @@ -930,8 +943,10 @@ modest_msg_view_window_new_for_search_result (TnyMsg *msg, { ModestMsgViewWindow *window = NULL; ModestMsgViewWindowPrivate *priv = NULL; + ModestWindowMgr *mgr = NULL; - window = g_object_new(MODEST_TYPE_MSG_VIEW_WINDOW, NULL); + mgr = modest_runtime_get_window_mgr (); + window = MODEST_MSG_VIEW_WINDOW (modest_window_mgr_get_msg_view_window (mgr)); g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window), NULL); modest_msg_view_window_construct (window, modest_account_name, msg_uid); @@ -942,6 +957,7 @@ modest_msg_view_window_new_for_search_result (TnyMsg *msg, priv->is_search_result = TRUE; tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg); + update_window_title (window); return MODEST_WINDOW(window); } @@ -952,15 +968,18 @@ modest_msg_view_window_new_for_attachment (TnyMsg *msg, const gchar *msg_uid) { GObject *obj = NULL; - ModestMsgViewWindowPrivate *priv; + ModestMsgViewWindowPrivate *priv; + ModestWindowMgr *mgr = NULL; + g_return_val_if_fail (msg, NULL); - - obj = g_object_new(MODEST_TYPE_MSG_VIEW_WINDOW, NULL); + mgr = modest_runtime_get_window_mgr (); + obj = G_OBJECT (modest_window_mgr_get_msg_view_window (mgr)); priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (obj); modest_msg_view_window_construct (MODEST_MSG_VIEW_WINDOW (obj), modest_account_name, msg_uid); tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), msg); + update_window_title (MODEST_MSG_VIEW_WINDOW (obj)); return MODEST_WINDOW(obj); } @@ -1024,6 +1043,8 @@ void modest_msg_view_window_on_row_inserted( gtk_tree_model_get (new_model, tree_iter, TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, &header, -1); uid = modest_tny_folder_get_header_unique_id(header); + g_object_unref(G_OBJECT(header)); + header = NULL; if(!g_str_equal(priv->msg_uid, uid)){ g_free(uid); return; @@ -1095,10 +1116,9 @@ void modest_msg_view_window_update_model_replaced( * not care about it's model (msg list). Else if the * header-view shows the folder the msg shown by us is in, we * shall replace our model reference and make some check. */ - if(tny_folder_id == NULL || - !g_str_equal(tny_folder_id, priv->header_folder_id)) + if(tny_folder_id == NULL || !g_str_equal(tny_folder_id, priv->header_folder_id)) return; - + /* Model is changed(replaced), so we should forget the old * one. Because there might be other references and there * might be some change on the model even if we unreferenced @@ -1132,9 +1152,6 @@ void modest_msg_view_window_update_model_replaced( modest_ui_actions_check_toolbar_dimming_rules(MODEST_WINDOW(window)); - if(tny_folder_id == NULL) - return; - g_assert(model != NULL); /* Also we must connect to the new model for row insertions. @@ -1206,15 +1223,12 @@ modest_msg_view_window_get_header (ModestMsgViewWindow *self) TnyMsg* modest_msg_view_window_get_message (ModestMsgViewWindow *self) { - ModestMsgView *msg_view; ModestMsgViewWindowPrivate *priv; - + g_return_val_if_fail (self, NULL); - + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self); - - msg_view = MODEST_MSG_VIEW (priv->msg_view); - + return tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view)); } @@ -1251,9 +1265,9 @@ modest_msg_view_window_toggle_find_toolbar (GtkToggleAction *toggle, /* update the toggle buttons status */ action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/FindInMessage"); - modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), is_active); + modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), is_active); action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ToolsMenu/ToolsFindInMessageMenu"); - modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), is_active); + modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), is_active); } @@ -1404,49 +1418,56 @@ modest_msg_view_window_zoom_minus (ModestWindow *window) } static gboolean -modest_msg_view_window_key_release_event (GtkWidget *window, - GdkEventKey *event, - gpointer userdata) -{ - if (event->type == GDK_KEY_RELEASE) { - switch (event->keyval) { - case GDK_Up: - modest_msg_view_window_scroll_up (MODEST_WINDOW (window)); - return TRUE; - break; - case GDK_Down: - modest_msg_view_window_scroll_down (MODEST_WINDOW (window)); +modest_msg_view_window_key_event (GtkWidget *window, + GdkEventKey *event, + gpointer userdata) +{ + + if (event->keyval == GDK_Up || event->keyval == GDK_KP_Up || + event->keyval == GDK_Down || event->keyval == GDK_KP_Down || + event->keyval == GDK_Page_Up || event->keyval == GDK_KP_Page_Up || + event->keyval == GDK_Page_Down || event->keyval == GDK_KP_Page_Down || + event->keyval == GDK_Home || event->keyval == GDK_KP_Home || + event->keyval == GDK_End || event->keyval == GDK_KP_End) { + ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + gboolean return_value; + + if (event->type == GDK_KEY_RELEASE) { + GtkScrollType scroll_type; + + switch (event->keyval) { + case GDK_Up: + case GDK_KP_Up: + scroll_type = GTK_SCROLL_STEP_UP; break; + case GDK_Down: + case GDK_KP_Down: + scroll_type = GTK_SCROLL_STEP_DOWN; break; + case GDK_Page_Up: + case GDK_KP_Page_Up: + scroll_type = GTK_SCROLL_PAGE_UP; break; + case GDK_Page_Down: + case GDK_KP_Page_Down: + scroll_type = GTK_SCROLL_PAGE_DOWN; break; + case GDK_Home: + case GDK_KP_Home: + scroll_type = GTK_SCROLL_START; break; + case GDK_End: + case GDK_KP_End: + scroll_type = GTK_SCROLL_END; break; + default: scroll_type = GTK_SCROLL_NONE; + } + + g_signal_emit_by_name (G_OBJECT (priv->main_scroll), "scroll-child", + scroll_type, FALSE, &return_value); return TRUE; - break; - default: + } else { return FALSE; - break; - }; + } } else { return FALSE; } } -static void -modest_msg_view_window_scroll_up (ModestWindow *window) -{ - ModestMsgViewWindowPrivate *priv; - gboolean return_value; - - priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); - g_signal_emit_by_name (G_OBJECT (priv->main_scroll), "scroll-child", GTK_SCROLL_STEP_UP, FALSE, &return_value); -} - -static void -modest_msg_view_window_scroll_down (ModestWindow *window) -{ - ModestMsgViewWindowPrivate *priv; - gboolean return_value; - - priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); - g_signal_emit_by_name (G_OBJECT (priv->main_scroll), "scroll-child", GTK_SCROLL_STEP_DOWN, FALSE, &return_value); -} - gboolean modest_msg_view_window_last_message_selected (ModestMsgViewWindow *window) { @@ -1475,8 +1496,11 @@ modest_msg_view_window_last_message_selected (ModestMsgViewWindow *window) gtk_tree_model_get (priv->header_model, &tmp_iter, TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, &header, -1); - if (!(tny_header_get_flags(header) & TNY_HEADER_FLAG_DELETED)) - is_last_selected = FALSE; + if (header) { + if (msg_is_visible (header, priv->is_outbox)) + is_last_selected = FALSE; + g_object_unref(G_OBJECT(header)); + } } gtk_tree_path_free (path); return is_last_selected; @@ -1504,6 +1528,14 @@ modest_msg_view_window_is_search_result (ModestMsgViewWindow *window) return priv->is_search_result; } +static gboolean +msg_is_visible (TnyHeader *header, gboolean check_outbox) +{ + return (!(tny_header_get_flags(header) & TNY_HEADER_FLAG_DELETED)) && + ( (!check_outbox) || (modest_tny_all_send_queues_get_msg_status (header) != MODEST_TNY_SEND_QUEUE_FAILED)) ; + +} + gboolean modest_msg_view_window_first_message_selected (ModestMsgViewWindow *window) { @@ -1544,8 +1576,11 @@ modest_msg_view_window_first_message_selected (ModestMsgViewWindow *window) gtk_tree_model_get (priv->header_model, &tmp_iter, TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, &header, -1); - if (!(tny_header_get_flags(header) & TNY_HEADER_FLAG_DELETED)) - is_first_selected = FALSE; + if (header) { + if (msg_is_visible (header, priv->is_outbox)) + is_first_selected = FALSE; + g_object_unref(G_OBJECT(header)); + } } gtk_tree_path_free (path); return is_first_selected; @@ -1570,7 +1605,6 @@ message_reader (ModestMsgViewWindow *window, GtkTreeRowReference *row_reference) { ModestMailOperation *mail_op = NULL; - ModestMailOperationTypeOperation op_type; gboolean already_showing = FALSE; ModestWindow *msg_window = NULL; ModestWindowMgr *mgr; @@ -1588,11 +1622,7 @@ message_reader (ModestMsgViewWindow *window, } /* Msg download completed */ - if (tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED) { - op_type = MODEST_MAIL_OPERATION_TYPE_OPEN; - } else { - op_type = MODEST_MAIL_OPERATION_TYPE_RECEIVE; - + if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED)) { /* Ask the user if he wants to download the message if we're not online */ if (!tny_device_is_online (modest_runtime_get_device())) { @@ -1707,7 +1737,7 @@ modest_msg_view_window_select_first_message (ModestMsgViewWindow *self) TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, &header, -1); g_return_val_if_fail (TNY_IS_HEADER (header), FALSE); - if (tny_header_get_flags (header) & TNY_HEADER_FLAG_DELETED) { + if (!msg_is_visible (header, priv->is_outbox)) { g_object_unref (header); return modest_msg_view_window_select_next_message (self); } @@ -1750,7 +1780,7 @@ modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window) &header, -1); if (!header) break; - if (tny_header_get_flags (header) & TNY_HEADER_FLAG_DELETED) { + if (!msg_is_visible (header, priv->is_outbox)) { g_object_unref (header); continue; } @@ -1776,7 +1806,9 @@ modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window) static void view_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, + gboolean canceled, TnyMsg *msg, + GError *error, gpointer user_data) { ModestMsgViewWindow *self = NULL; @@ -1874,7 +1906,10 @@ modest_msg_view_window_update_priority (ModestMsgViewWindow *window) gtk_tree_model_get (priv->header_model, &iter, TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, &header, -1); - flags = tny_header_get_flags (header); + if (header) { + flags = tny_header_get_flags (header); + g_object_unref(G_OBJECT(header)); + } gtk_tree_path_free (path); } @@ -1974,7 +2009,6 @@ modest_msg_view_window_show_toolbar (ModestWindow *self, hildon_window_add_toolbar (HILDON_WINDOW (self), GTK_TOOLBAR (parent_priv->toolbar)); - /* Set reply button tap and hold menu */ reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageReply"); @@ -1987,10 +2021,13 @@ modest_msg_view_window_show_toolbar (ModestWindow *self, /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */ /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */ gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE); - + gtk_widget_show (GTK_WIDGET (parent_priv->toolbar)); - set_toolbar_mode (MODEST_MSG_VIEW_WINDOW(self), TOOLBAR_MODE_NORMAL); - + if (modest_msg_view_window_transfer_mode_enabled (MODEST_MSG_VIEW_WINDOW (self))) + set_toolbar_mode (MODEST_MSG_VIEW_WINDOW (self), TOOLBAR_MODE_TRANSFER); + else + set_toolbar_mode (MODEST_MSG_VIEW_WINDOW (self), TOOLBAR_MODE_NORMAL); + } else { gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE); gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar)); @@ -2007,7 +2044,7 @@ modest_msg_view_window_show_toolbar (ModestWindow *self, action_name = "/MenuBar/ViewMenu/ViewShowToolbarMenu/ViewShowToolbarNormalScreenMenu"; action = gtk_ui_manager_get_action (parent_priv->ui_manager, action_name); - modest_maemo_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), + modest_utils_toggle_action_set_active_block_notify (GTK_TOGGLE_ACTION (action), show_toolbar); } @@ -2091,67 +2128,92 @@ on_account_removed (TnyAccountStore *account_store, } } +static void +on_mail_operation_started (ModestMailOperation *mail_op, + gpointer user_data) +{ + ModestMsgViewWindow *self; + ModestMailOperationTypeOperation op_type; + GSList *tmp; + ModestMsgViewWindowPrivate *priv; + + self = MODEST_MSG_VIEW_WINDOW (user_data); + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self); + op_type = modest_mail_operation_get_type_operation (mail_op); + tmp = priv->progress_widgets; + + if (op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE || op_type == MODEST_MAIL_OPERATION_TYPE_OPEN ) { + set_toolbar_transfer_mode(self); + while (tmp) { + modest_progress_object_add_operation ( + MODEST_PROGRESS_OBJECT (tmp->data), + mail_op); + tmp = g_slist_next (tmp); + } + } +} + +static void +on_mail_operation_finished (ModestMailOperation *mail_op, + gpointer user_data) +{ + ModestMsgViewWindow *self; + ModestMailOperationTypeOperation op_type; + GSList *tmp; + ModestMsgViewWindowPrivate *priv; + + self = MODEST_MSG_VIEW_WINDOW (user_data); + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self); + op_type = modest_mail_operation_get_type_operation (mail_op); + tmp = priv->progress_widgets; + + if (op_type == MODEST_MAIL_OPERATION_TYPE_RECEIVE || op_type == MODEST_MAIL_OPERATION_TYPE_OPEN ) { + while (tmp) { + modest_progress_object_remove_operation ( + MODEST_PROGRESS_OBJECT (tmp->data), + mail_op); + tmp = g_slist_next (tmp); + } + + /* If no more operations are being observed, NORMAL mode is enabled again */ + if (observers_empty (self)) { + set_toolbar_mode (self, TOOLBAR_MODE_NORMAL); + } + } +} + static void on_queue_changed (ModestMailOperationQueue *queue, ModestMailOperation *mail_op, ModestMailOperationQueueNotification type, ModestMsgViewWindow *self) -{ - GSList *tmp; +{ ModestMsgViewWindowPrivate *priv; - ModestMailOperationTypeOperation op_type; - ModestToolBarModes mode; - - g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self)); - priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self); + + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self); /* If this operations was created by another window, do nothing */ if (!modest_mail_operation_is_mine (mail_op, G_OBJECT(self))) return; - /* Get toolbar mode from operation id*/ - op_type = modest_mail_operation_get_type_operation (mail_op); - switch (op_type) { -/* case MODEST_MAIL_OPERATION_TYPE_SEND: */ - case MODEST_MAIL_OPERATION_TYPE_RECEIVE: - case MODEST_MAIL_OPERATION_TYPE_OPEN: - mode = TOOLBAR_MODE_TRANSFER; - break; - default: - mode = TOOLBAR_MODE_NORMAL; - - } - - /* Add operation observers and change toolbar if neccessary*/ - tmp = priv->progress_widgets; - switch (type) { - case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED: - if (mode == TOOLBAR_MODE_TRANSFER) { - /* Enable transfer toolbar mode */ - set_toolbar_transfer_mode(self); - while (tmp) { - modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data), - mail_op); - tmp = g_slist_next (tmp); - } - - } - break; - case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED: - if (mode == TOOLBAR_MODE_TRANSFER) { - while (tmp) { - modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data), - mail_op); - tmp = g_slist_next (tmp); - - } - - /* If no more operations are being observed, NORMAL mode is enabled again */ - if (observers_empty (self)) { - set_toolbar_mode (self, TOOLBAR_MODE_NORMAL); - } - } - break; + if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) { + priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, + G_OBJECT (mail_op), + "operation-started", + G_CALLBACK (on_mail_operation_started), + self); + priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers, + G_OBJECT (mail_op), + "operation-finished", + G_CALLBACK (on_mail_operation_finished), + self); + } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) { + priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers, + G_OBJECT (mail_op), + "operation-started"); + priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers, + G_OBJECT (mail_op), + "operation-finished"); } } @@ -2220,19 +2282,31 @@ modest_msg_view_window_view_attachment (ModestMsgViewWindow *window, TnyMimePart if (!TNY_IS_MSG (mime_part)) { gchar *filepath = NULL; const gchar *att_filename = tny_mime_part_get_filename (mime_part); + const gchar *content_type; TnyFsStream *temp_stream = NULL; - temp_stream = modest_maemo_utils_create_temp_stream (att_filename, attachment_uid, &filepath); + temp_stream = modest_utils_create_temp_stream (att_filename, attachment_uid, + &filepath); - if (temp_stream) { - const gchar *content_type; + if (temp_stream != NULL) { content_type = tny_mime_part_get_content_type (mime_part); tny_mime_part_decode_to_stream (mime_part, TNY_STREAM (temp_stream)); + + /* make the file read-only */ + if (g_chmod(filepath, 0444) != 0) + g_warning ("%s: failed to set file '%s' to read-only: %s", + __FUNCTION__, filepath, strerror(errno)); modest_platform_activate_file (filepath, content_type); g_object_unref (temp_stream); g_free (filepath); /* NOTE: files in the temporary area will be automatically * cleaned after some time if they are no longer in use */ + } else if (filepath != NULL) { + /* the file may already exist but it isn't writable, + * let's try to open it anyway */ + content_type = tny_mime_part_get_content_type (mime_part); + modest_platform_activate_file (filepath, content_type); + g_free (filepath); } } else { /* message attachment */ @@ -2340,7 +2414,7 @@ save_mime_part_to_file (SaveMimePartInfo *info) TnyStream *stream; SaveMimePartPair *pair = (SaveMimePartPair *) info->pairs->data; - result = gnome_vfs_create (&handle, pair->filename, GNOME_VFS_OPEN_WRITE, FALSE, 0777); + result = gnome_vfs_create (&handle, pair->filename, GNOME_VFS_OPEN_WRITE, FALSE, 0644); if (result == GNOME_VFS_OK) { stream = tny_vfs_stream_new (handle); tny_mime_part_decode_to_stream (pair->part, stream); @@ -2368,8 +2442,8 @@ save_mime_parts_to_file_with_checks (SaveMimePartInfo *info) for (iter = files; (iter != NULL) && (replaced_files < 2); iter = g_list_next(iter)) { SaveMimePartPair *pair = iter->data; - if (modest_maemo_utils_file_exists (pair->filename)) { - replaced_files++; + if (modest_utils_file_exists (pair->filename)) { + replaced_files++; } } if (replaced_files) { @@ -2455,7 +2529,7 @@ modest_msg_view_window_save_attachments (ModestMsgViewWindow *window, GList *mim if (gtk_dialog_run (GTK_DIALOG (save_dialog)) == GTK_RESPONSE_OK) { gchar *chooser_uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (save_dialog)); - if (!modest_maemo_utils_folder_writable (chooser_uri)) { + if (!modest_utils_folder_writable (chooser_uri)) { hildon_banner_show_information (NULL, NULL, dgettext("hildon-fm", "sfil_ib_readonly_location")); } else { @@ -2508,6 +2582,9 @@ show_remove_attachment_information (gpointer userdata) ModestMsgViewWindow *window = (ModestMsgViewWindow *) userdata; ModestMsgViewWindowPrivate *priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window); + /* We're outside the main lock */ + gdk_threads_enter (); + if (priv->remove_attachment_banner != NULL) { gtk_widget_destroy (priv->remove_attachment_banner); g_object_unref (priv->remove_attachment_banner); @@ -2516,6 +2593,8 @@ show_remove_attachment_information (gpointer userdata) priv->remove_attachment_banner = g_object_ref ( hildon_banner_show_animation (NULL, NULL, _("mcen_ib_removing_attachment"))); + gdk_threads_leave (); + return FALSE; } @@ -2623,8 +2702,9 @@ update_window_title (ModestMsgViewWindow *window) TnyMsg *msg = NULL; TnyHeader *header = NULL; const gchar *subject = NULL; - + msg = tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view)); + if (msg != NULL) { header = tny_msg_get_header (msg); subject = tny_header_get_subject (header); @@ -2637,16 +2717,11 @@ update_window_title (ModestMsgViewWindow *window) gtk_window_set_title (GTK_WINDOW (window), subject); } -static void on_move_focus (ModestMsgViewWindow *window, + +static void on_move_focus (GtkWidget *widget, GtkDirectionType direction, gpointer userdata) { - GtkWidget *current_focus = NULL; - - current_focus = gtk_window_get_focus (GTK_WINDOW (window)); - if ((current_focus != NULL) && - MODEST_IS_ATTACHMENTS_VIEW (current_focus)) { - g_signal_stop_emission_by_name (G_OBJECT (window), "move-focus"); - } + g_signal_stop_emission_by_name (G_OBJECT (widget), "move-focus"); }