#include <modest-main-window-ui.h>
#include "modest-msg-view-window-ui-dimming.h"
#include <modest-widget-memory.h>
+#include <modest-progress-object.h>
#include <modest-runtime.h>
#include <modest-window-priv.h>
#include <modest-tny-folder.h>
#include <modest-text-utils.h>
#include <modest-account-mgr-helpers.h>
#include "modest-progress-bar.h"
+#include <hildon/hildon-pannable-area.h>
+#include <hildon/hildon-picker-dialog.h>
#include "hildon/hildon-pannable-area.h"
#include "modest-defs.h"
#include "modest-hildon-includes.h"
#include <modest-mime-part-view.h>
#include <modest-isearch-view.h>
#include <modest-tny-mime-part.h>
+#include <modest-address-book.h>
#include <math.h>
#include <errno.h>
#include <glib/gstdio.h>
#include <modest-debug.h>
-#define DEFAULT_FOLDER "MyDocs/.documents"
+#define MYDOCS_ENV "MYDOCSDIR"
+#define DOCS_FOLDER ".documents"
+
+typedef struct _ModestMsgViewWindowPrivate ModestMsgViewWindowPrivate;
+struct _ModestMsgViewWindowPrivate {
+
+ GtkWidget *msg_view;
+ GtkWidget *main_scroll;
+ GtkWidget *find_toolbar;
+ gchar *last_search;
+
+ /* Progress observers */
+ GSList *progress_widgets;
+
+ /* Tollbar items */
+ GtkWidget *prev_toolitem;
+ GtkWidget *next_toolitem;
+ gboolean progress_hint;
+
+ /* Optimized view enabled */
+ gboolean optimized_view;
+
+ /* 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,
+ * if the message is currently selected in the header view.
+ */
+ const gchar *header_folder_id;
+ GtkTreeModel *header_model;
+ GtkTreeRowReference *row_reference;
+ GtkTreeRowReference *next_row_reference;
+
+ gulong clipboard_change_handler;
+ gulong queue_change_handler;
+ gulong account_removed_handler;
+ gulong row_changed_handler;
+ gulong row_deleted_handler;
+ gulong row_inserted_handler;
+ gulong rows_reordered_handler;
+
+ guint purge_timeout;
+ GtkWidget *remove_attachment_banner;
+
+ gchar *msg_uid;
+
+ GSList *sighandlers;
+};
static void modest_msg_view_window_class_init (ModestMsgViewWindowClass *klass);
static void modest_msg_view_window_init (ModestMsgViewWindow *obj);
GtkTreeModel *model,
const gchar *tny_folder_id);
-static void cancel_progressbar (GtkToolButton *toolbutton,
- ModestMsgViewWindow *self);
-
static void on_queue_changed (ModestMailOperationQueue *queue,
ModestMailOperation *mail_op,
ModestMailOperationQueueNotification type,
GError *error,
gpointer user_data);
-static void set_toolbar_mode (ModestMsgViewWindow *self,
- ModestToolBarModes mode);
+static void set_progress_hint (ModestMsgViewWindow *self,
+ gboolean enabled);
static void update_window_title (ModestMsgViewWindow *window);
GtkScrollType scroll_type,
gboolean horizontal,
gpointer userdata);
+static gboolean message_reader (ModestMsgViewWindow *window,
+ ModestMsgViewWindowPrivate *priv,
+ TnyHeader *header,
+ GtkTreeRowReference *row_reference);
/* list my signals */
enum {
{ "FindInMessage", MODEST_TOOLBAR_ICON_FIND, N_("qgn_toolb_gene_find"), NULL, NULL, G_CALLBACK (modest_msg_view_window_toggle_find_toolbar), FALSE },
};
-typedef struct _ModestMsgViewWindowPrivate ModestMsgViewWindowPrivate;
-struct _ModestMsgViewWindowPrivate {
-
- GtkWidget *msg_view;
- GtkWidget *main_scroll;
- GtkWidget *find_toolbar;
- gchar *last_search;
-
- /* Progress observers */
- GtkWidget *progress_bar;
- GSList *progress_widgets;
-
- /* Tollbar items */
- GtkWidget *progress_toolitem;
- GtkWidget *cancel_toolitem;
- GtkWidget *prev_toolitem;
- GtkWidget *next_toolitem;
- ModestToolBarModes current_toolbar_mode;
-
- /* Optimized view enabled */
- gboolean optimized_view;
-
- /* 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,
- * if the message is currently selected in the header view.
- */
- const gchar *header_folder_id;
- GtkTreeModel *header_model;
- GtkTreeRowReference *row_reference;
- GtkTreeRowReference *next_row_reference;
-
- gulong clipboard_change_handler;
- gulong queue_change_handler;
- gulong account_removed_handler;
- gulong row_changed_handler;
- gulong row_deleted_handler;
- gulong row_inserted_handler;
- gulong rows_reordered_handler;
-
- guint purge_timeout;
- GtkWidget *remove_attachment_banner;
-
- guint progress_bar_timeout;
-
- gchar *msg_uid;
-
- GSList *sighandlers;
-};
-
#define MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
MODEST_TYPE_MSG_VIEW_WINDOW, \
ModestMsgViewWindowPrivate))
MODEST_CONF_MSG_VIEW_WINDOW_KEY);
}
-static
-gboolean modest_msg_view_window_scroll_child (ModestMsgViewWindow *self,
- GtkScrollType scroll_type,
- gboolean horizontal,
- gpointer userdata)
+static void
+restore_settings (ModestMsgViewWindow *self)
+{
+ ModestConf *conf;
+
+ conf = modest_runtime_get_conf ();
+ modest_widget_memory_restore (conf,
+ G_OBJECT(self),
+ MODEST_CONF_MSG_VIEW_WINDOW_KEY);
+}
+
+static gboolean modest_msg_view_window_scroll_child (ModestMsgViewWindow *self,
+ GtkScrollType scroll_type,
+ gboolean horizontal,
+ gpointer userdata)
{
ModestMsgViewWindowPrivate *priv;
gboolean return_value;
priv->row_deleted_handler = 0;
priv->row_inserted_handler = 0;
priv->rows_reordered_handler = 0;
- priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
+ priv->progress_hint = FALSE;
priv->optimized_view = FALSE;
- priv->progress_bar_timeout = 0;
priv->purge_timeout = 0;
priv->remove_attachment_banner = NULL;
priv->msg_uid = NULL;
priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
- set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
-
- if (priv->progress_bar_timeout > 0) {
- g_source_remove (priv->progress_bar_timeout);
- priv->progress_bar_timeout = 0;
- }
+ set_progress_hint (self, TRUE);
return FALSE;
}
static void
-set_toolbar_mode (ModestMsgViewWindow *self,
- ModestToolBarModes mode)
+set_progress_hint (ModestMsgViewWindow *self,
+ gboolean enabled)
{
ModestWindowPrivate *parent_priv;
ModestMsgViewWindowPrivate *priv;
-/* GtkWidget *widget = NULL; */
g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self));
parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
- /* Sets current toolbar mode */
- priv->current_toolbar_mode = mode;
-
- /* Update toolbar dimming state */
- modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (self));
-
- switch (mode) {
- case TOOLBAR_MODE_NORMAL:
- 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);
- gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
- }
-
- break;
- case TOOLBAR_MODE_TRANSFER:
- if (priv->prev_toolitem)
- gtk_widget_hide (priv->prev_toolitem);
-
- if (priv->next_toolitem)
- gtk_widget_hide (priv->next_toolitem);
-
- 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);
-
- /* Show toolbar if it's hiden (optimized view ) */
- if (priv->optimized_view) {
- gtk_widget_set_no_show_all (parent_priv->toolbar, FALSE);
- gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
- }
+ /* Sets current progress hint */
+ priv->progress_hint = enabled;
- break;
- default:
- g_return_if_reached ();
+ if (GTK_WIDGET_VISIBLE (self)) {
+ hildon_gtk_window_set_progress_indicator (GTK_WINDOW (self), enabled?1:0);
}
}
priv->header_model = NULL;
}
- if (priv->progress_bar_timeout > 0) {
- g_source_remove (priv->progress_bar_timeout);
- priv->progress_bar_timeout = 0;
- }
-
if (priv->remove_attachment_banner) {
gtk_widget_destroy (priv->remove_attachment_banner);
g_object_unref (priv->remove_attachment_banner);
G_CALLBACK (modest_ui_actions_on_msg_attachment_clicked), obj);
g_signal_connect (G_OBJECT(priv->msg_view), "recpt_activated",
G_CALLBACK (modest_ui_actions_on_msg_recpt_activated), obj);
+ g_signal_connect (G_OBJECT(priv->msg_view), "show_details",
+ G_CALLBACK (modest_ui_actions_on_details), obj);
g_signal_connect (G_OBJECT(priv->msg_view), "link_contextual",
G_CALLBACK (modest_ui_actions_on_msg_link_contextual), obj);
g_signal_connect (G_OBJECT (priv->msg_view), "fetch_image",
g_signal_connect (G_OBJECT (priv->find_toolbar), "search", G_CALLBACK (modest_msg_view_window_find_toolbar_search), obj);
priv->last_search = NULL;
+ modest_msg_view_window_show_toolbar (MODEST_WINDOW (obj), TRUE);
+
/* Init the clipboard actions dim status */
modest_msg_view_grab_focus(MODEST_MSG_VIEW (priv->msg_view));
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);
+ /* Check dimming rules */
+ modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
+ modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
+ modest_window_check_dimming_rules_group (MODEST_WINDOW (window), MODEST_DIMMING_RULES_CLIPBOARD);
+
+ return MODEST_WINDOW(window);
+}
+
+ModestWindow *
+modest_msg_view_window_new_from_header_view (ModestHeaderView *header_view,
+ const gchar *modest_account_name,
+ const gchar *msg_uid,
+ GtkTreeRowReference *row_reference)
+{
+ ModestMsgViewWindow *window = NULL;
+ ModestMsgViewWindowPrivate *priv = NULL;
+ TnyFolder *header_folder = NULL;
+ ModestWindowMgr *mgr = NULL;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ 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);
+
+ priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (window);
+
+ /* Remember the message list's TreeModel so we can detect changes
+ * and change the list selection when necessary: */
+
+ if (header_view != NULL){
+ header_folder = modest_header_view_get_folder(header_view);
+ /* This could happen if the header folder was
+ unseleted before opening this msg window (for
+ example if the user selects an account in the
+ folder view of the main window */
+ if (header_folder) {
+ priv->is_outbox = (modest_tny_folder_guess_folder_type (header_folder) == TNY_FOLDER_TYPE_OUTBOX);
+ priv->header_folder_id = tny_folder_get_id(header_folder);
+ g_assert(priv->header_folder_id != NULL);
+ g_object_unref(header_folder);
+ }
+ }
+
+ /* Setup row references and connect signals */
+ priv->header_model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
+
+ if (row_reference) {
+ priv->row_reference = gtk_tree_row_reference_copy (row_reference);
+ priv->next_row_reference = gtk_tree_row_reference_copy (row_reference);
+ select_next_valid_row (priv->header_model, &(priv->next_row_reference), TRUE, priv->is_outbox);
+ } else {
+ priv->row_reference = NULL;
+ priv->next_row_reference = NULL;
+ }
+
+ /* Connect signals */
+ priv->row_changed_handler =
+ g_signal_connect (GTK_TREE_MODEL(priv->header_model), "row-changed",
+ G_CALLBACK(modest_msg_view_window_on_row_changed),
+ window);
+ priv->row_deleted_handler =
+ g_signal_connect (GTK_TREE_MODEL(priv->header_model), "row-deleted",
+ G_CALLBACK(modest_msg_view_window_on_row_deleted),
+ window);
+ priv->row_inserted_handler =
+ g_signal_connect (GTK_TREE_MODEL(priv->header_model), "row-inserted",
+ G_CALLBACK(modest_msg_view_window_on_row_inserted),
+ window);
+ priv->rows_reordered_handler =
+ g_signal_connect(GTK_TREE_MODEL(priv->header_model), "rows-reordered",
+ G_CALLBACK(modest_msg_view_window_on_row_reordered),
+ window);
+
+ if (header_view != NULL){
+ modest_header_view_add_observer(header_view,
+ MODEST_HEADER_VIEW_OBSERVER(window));
+ }
+
+ tny_msg_view_set_msg (TNY_MSG_VIEW (priv->msg_view), NULL);
+
+ path = gtk_tree_row_reference_get_path (row_reference);
+ if (gtk_tree_model_get_iter (priv->header_model, &iter, path)) {
+ TnyHeader *header;
+ gtk_tree_model_get (priv->header_model, &iter,
+ TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,
+ &header, -1);
+ message_reader (window, priv, header, row_reference);
+ }
+ gtk_tree_path_free (path);
/* Check dimming rules */
modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self), FALSE);
priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
- return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
+ return priv->progress_hint;
}
TnyHeader*
gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), FALSE);
gtk_widget_set_size_request (GTK_WIDGET (widget), static_button_size, -1);
- gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
- gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
- gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
- gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->next_toolitem), TRUE);
gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->next_toolitem), TRUE);
gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->prev_toolitem), TRUE);
ModestMsgViewWindowPrivate *priv = NULL;
ModestWindowPrivate *parent_priv;
GtkWidget *reply_button = NULL, *menu = NULL;
- GtkWidget *placeholder = NULL;
- gint insert_index;
-
+ const gchar *action_name;
+ GtkAction *action;
+
parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
"/ToolBar");
gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
- priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
- priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
priv->next_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageNext");
priv->prev_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarMessageBack");
toolbar_resize (MODEST_MSG_VIEW_WINDOW (self));
-
- /* Add ProgressBar (Transfer toolbar) */
- priv->progress_bar = modest_progress_bar_new ();
- gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
- placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressbarView");
- insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
- gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
- gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
-
- /* Connect cancel 'clicked' signal to abort progress mode */
- g_signal_connect(priv->cancel_toolitem, "clicked",
- G_CALLBACK(cancel_progressbar),
- self);
-
- /* Add it to the observers list */
- priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
-
+
/* Add to window */
hildon_window_add_toolbar (HILDON_WINDOW (self),
GTK_TOOLBAR (parent_priv->toolbar));
gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
if (modest_msg_view_window_transfer_mode_enabled (MODEST_MSG_VIEW_WINDOW (self)))
- set_toolbar_mode (MODEST_MSG_VIEW_WINDOW (self), TOOLBAR_MODE_TRANSFER);
+ set_progress_hint (MODEST_MSG_VIEW_WINDOW (self), TRUE);
else
- set_toolbar_mode (MODEST_MSG_VIEW_WINDOW (self), TOOLBAR_MODE_NORMAL);
+ set_progress_hint (MODEST_MSG_VIEW_WINDOW (self), FALSE);
} else {
gtk_widget_set_no_show_all (parent_priv->toolbar, TRUE);
g_return_val_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self), FALSE);
priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
- return priv->current_toolbar_mode == TOOLBAR_MODE_TRANSFER;
+ return priv->progress_hint;
}
-static void
-cancel_progressbar (GtkToolButton *toolbutton,
- ModestMsgViewWindow *self)
-{
- GSList *tmp;
- ModestMsgViewWindowPrivate *priv;
-
- priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE(self);
-
- /* Get operation observers and cancel its current operation */
- tmp = priv->progress_widgets;
- while (tmp) {
- modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
- tmp=g_slist_next(tmp);
- }
-}
static gboolean
observers_empty (ModestMsgViewWindow *self)
{
/* If no more operations are being observed, NORMAL mode is enabled again */
if (observers_empty (self)) {
- set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
+ set_progress_hint (self, FALSE);
}
/* Update dimming rules. We have to do this right here
GTK_FILE_CHOOSER_ACTION_SAVE);
/* set folder */
- folder = g_build_filename (g_get_home_dir (), DEFAULT_FOLDER, NULL);
+ folder = g_build_filename (g_get_home_dir (), g_getenv (MYDOCS_ENV), DOCS_FOLDER, NULL);
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (save_dialog), folder);
g_free (folder);
return TRUE;;
}
+
+void
+modest_msg_view_window_add_to_contacts (ModestMsgViewWindow *self)
+{
+ ModestMsgViewWindowPrivate *priv;
+ priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self);
+ GSList *recipients = NULL;
+ TnyMsg *msg = NULL;
+ gboolean contacts_to_add = FALSE;
+
+ msg = tny_msg_view_get_msg (TNY_MSG_VIEW (priv->msg_view));
+ if (msg == NULL) return;
+ recipients = modest_tny_msg_get_all_recipients_list (msg);
+
+ if (recipients != NULL) {
+ GtkWidget *picker_dialog;
+ GtkWidget *selector;
+ GSList *node;
+ gchar *selected;
+
+ selector = hildon_touch_selector_new_text ();
+ for (node = recipients; node != NULL; node = g_slist_next (node)) {
+ if (!modest_address_book_has_address ((const gchar *) node->data)) {
+ hildon_touch_selector_append_text (HILDON_TOUCH_SELECTOR (selector),
+ (const gchar *) node->data);
+ contacts_to_add = TRUE;
+ }
+ }
+
+ if (contacts_to_add) {
+
+ picker_dialog = hildon_picker_dialog_new (GTK_WINDOW (self));
+ gtk_window_set_title (GTK_WINDOW (picker_dialog), _("mcen_me_viewer_addtocontacts"));
+
+ hildon_picker_dialog_set_selector (HILDON_PICKER_DIALOG (picker_dialog),
+ HILDON_TOUCH_SELECTOR (selector));
+
+ gtk_dialog_run (GTK_DIALOG (picker_dialog));
+ selected = hildon_touch_selector_get_current_text (HILDON_TOUCH_SELECTOR (selector));
+ gtk_widget_destroy (picker_dialog);
+
+ if (selected)
+ modest_address_book_add_address (selected);
+ g_free (selected);
+
+ } else {
+
+ g_object_unref (selector);
+
+ }
+ }
+
+ if (recipients) {g_slist_foreach (recipients, (GFunc) g_free, NULL); g_slist_free (recipients);}
+ g_object_unref (msg);
+}