From 58cbe9db1e63b6f9bb18c9bac457e48cdaaff8a0 Mon Sep 17 00:00:00 2001 From: Sergio Villar Senin Date: Tue, 22 May 2007 16:56:16 +0000 Subject: [PATCH] * Fixes: NB#57465 * Fixed a bug in the account store * Fixed several memory leaks * Refactored the code that loads a list of messages from the headers * Improved reference counting in msg view window * Added modest_mail_operation_get_source * Added the global account settings default values to modest init pmo-trunk-r1950 --- src/gnome/modest-msg-view-window.c | 2 + src/maemo/modest-main-window-ui.h | 2 +- src/maemo/modest-msg-view-window.c | 23 ++- src/modest-init.c | 20 +++ src/modest-mail-operation-queue.c | 3 +- src/modest-mail-operation.c | 41 +++-- src/modest-mail-operation.h | 24 ++- src/modest-tny-account-store.c | 33 ++-- src/modest-ui-actions.c | 313 +++++++++++++++++++++------------- src/modest-ui-actions.h | 22 ++- src/widgets/modest-header-view.h | 3 +- src/widgets/modest-msg-view-window.h | 3 +- src/widgets/modest-msg-view.c | 9 +- src/widgets/modest-msg-view.h | 3 +- 14 files changed, 325 insertions(+), 176 deletions(-) diff --git a/src/gnome/modest-msg-view-window.c b/src/gnome/modest-msg-view-window.c index c7a0bc6..849b015 100644 --- a/src/gnome/modest-msg-view-window.c +++ b/src/gnome/modest-msg-view-window.c @@ -313,6 +313,8 @@ modest_msg_view_window_get_message_uid (ModestMsgViewWindow *self) retval = tny_header_get_uid (header); g_object_unref (header); } + g_object_unref (msg); + return retval; } diff --git a/src/maemo/modest-main-window-ui.h b/src/maemo/modest-main-window-ui.h index 83af01a..f3db69f 100644 --- a/src/maemo/modest-main-window-ui.h +++ b/src/maemo/modest-main-window-ui.h @@ -63,7 +63,7 @@ static const GtkActionEntry modest_action_entries [] = { { "EmailReplyAll", NULL, N_("mcen_me_inbox_replytoall"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply_all) }, { "EmailForward", NULL, N_("mcen_me_inbox_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_forward) }, { "EmailDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete) }, - { "EmailContents", NULL, N_("mcen_me_inbox_retrieve_contents"), NULL, NULL, NULL }, + { "EmailContents", NULL, N_("mcen_me_inbox_retrieve_contents"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_retrieve_msg_contents) }, { "EmailDetails", NULL, N_("mcen_me_inbox_messagedetails"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_details) }, { "EmailPurgeAttachments", NULL, N_("mcen_me_inbox_remove_attachments"), NULL, NULL, NULL }, diff --git a/src/maemo/modest-msg-view-window.c b/src/maemo/modest-msg-view-window.c index 3c6d2d0..229cb72 100644 --- a/src/maemo/modest-msg-view-window.c +++ b/src/maemo/modest-msg-view-window.c @@ -96,7 +96,7 @@ static void on_queue_changed (ModestMailOperationQue ModestMailOperationQueueNotification type, ModestMsgViewWindow *self); -static void view_msg_cb (const GObject *obj, TnyMsg *msg, gpointer user_data); +static void view_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg, gpointer user_data); static void set_toolbar_mode (ModestMsgViewWindow *self, ModestToolBarModes mode); @@ -645,6 +645,8 @@ modest_msg_view_window_get_message_uid (ModestMsgViewWindow *self) retval = tny_header_get_uid (header); g_object_unref (header); } + g_object_unref (msg); + return retval; } @@ -1056,20 +1058,24 @@ modest_msg_view_window_select_previous_message (ModestMsgViewWindow *window) } static void -view_msg_cb(const GObject *obj, TnyMsg *msg, gpointer user_data) +view_msg_cb (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg, + gpointer user_data) { ModestMsgViewWindow *self = NULL; ModestMsgViewWindowPrivate *priv = NULL; - TnyMsg *new_msg = NULL; - - g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (obj)); + g_return_if_fail (TNY_IS_MSG (msg)); - self = MODEST_MSG_VIEW_WINDOW (obj); + + /* Get the window */ + self = (ModestMsgViewWindow *) modest_mail_operation_get_source (mail_op); + g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (self)); + priv = MODEST_MSG_VIEW_WINDOW_GET_PRIVATE (self); /* Set new message */ - new_msg = g_object_ref (G_OBJECT(msg)); - modest_msg_view_set_message (MODEST_MSG_VIEW (priv->msg_view), new_msg); + modest_msg_view_set_message (MODEST_MSG_VIEW (priv->msg_view), msg); modest_msg_view_window_update_dimmed (self); modest_msg_view_window_update_priority (self); gtk_widget_grab_focus (priv->msg_view); @@ -1102,6 +1108,7 @@ modest_msg_view_window_get_folder_type (ModestMsgViewWindow *window) g_object_unref (folder); } + g_object_unref (msg); } return folder_type; diff --git a/src/modest-init.c b/src/modest-init.c index 4065dc1..b968267 100644 --- a/src/modest-init.c +++ b/src/modest-init.c @@ -46,6 +46,8 @@ #include #include #include +#include "widgets/modest-global-settings-dialog.h" +#include "modest-tny-msg.h" static gboolean init_header_columns (ModestConf *conf, gboolean overwrite); static gboolean init_local_folders (void); @@ -561,9 +563,27 @@ init_default_settings (ModestConf *conf) if (!modest_conf_key_exists (conf, MODEST_CONF_CONNECT_AT_STARTUP, NULL)) modest_conf_set_bool (conf, MODEST_CONF_CONNECT_AT_STARTUP, TRUE, NULL); + /* Global settings */ + if (!modest_conf_key_exists (conf, MODEST_CONF_AUTO_UPDATE, NULL)) + modest_conf_set_bool (conf, MODEST_CONF_AUTO_UPDATE, TRUE, NULL); + + if (!modest_conf_key_exists (conf, MODEST_CONF_UPDATE_WHEN_CONNECTED_BY, NULL)) + modest_conf_set_int (conf, MODEST_CONF_UPDATE_WHEN_CONNECTED_BY, MODEST_CONNECTED_VIA_WLAN, NULL); + + if (!modest_conf_key_exists (conf, MODEST_CONF_UPDATE_INTERVAL, NULL)) + modest_conf_set_int (conf, MODEST_CONF_UPDATE_INTERVAL, MODEST_UPDATE_INTERVAL_15_MIN, NULL); + + if (!modest_conf_key_exists (conf, MODEST_CONF_MSG_SIZE_LIMIT, NULL)) + modest_conf_set_int (conf, MODEST_CONF_MSG_SIZE_LIMIT, 1000, NULL); + + if (!modest_conf_key_exists (conf, MODEST_CONF_PLAY_SOUND_MSG_ARRIVE, NULL)) + modest_conf_set_bool (conf, MODEST_CONF_PLAY_SOUND_MSG_ARRIVE, FALSE, NULL); + if (!modest_conf_key_exists (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, NULL)) modest_conf_set_bool (conf, MODEST_CONF_PREFER_FORMATTED_TEXT, TRUE, NULL); + if (!modest_conf_key_exists (conf, MODEST_CONF_REPLY_TYPE, NULL)) + modest_conf_set_int (conf, MODEST_CONF_REPLY_TYPE, MODEST_TNY_MSG_REPLY_TYPE_QUOTE, NULL); } diff --git a/src/modest-mail-operation-queue.c b/src/modest-mail-operation-queue.c index 1893768..4524d57 100644 --- a/src/modest-mail-operation-queue.c +++ b/src/modest-mail-operation-queue.c @@ -194,11 +194,12 @@ modest_mail_operation_queue_remove (ModestMailOperationQueue *self, g_queue_remove (priv->op_queue, mail_op); g_mutex_unlock (priv->queue_lock); + /* Debug code */ { const GError *err; err = modest_mail_operation_get_error (mail_op); if (err) - g_printerr ("Error in %s: %s", __FUNCTION__, err->message); + g_printerr ("Error in %s: %s\n", __FUNCTION__, err->message); } /* Notify observers */ diff --git a/src/modest-mail-operation.c b/src/modest-mail-operation.c index d7eb622..f5d4ed4 100644 --- a/src/modest-mail-operation.c +++ b/src/modest-mail-operation.c @@ -57,9 +57,6 @@ static void modest_mail_operation_class_init (ModestMailOperationClass *klass); static void modest_mail_operation_init (ModestMailOperation *obj); static void modest_mail_operation_finalize (GObject *obj); -/* static void update_process_msg_status_cb (GObject *obj, */ -/* TnyStatus *status, */ -/* gpointer user_data); */ static void get_msg_cb (TnyFolder *folder, gboolean cancelled, TnyMsg *msg, @@ -100,7 +97,7 @@ struct _ModestMailOperationPrivate { typedef struct _GetMsgAsyncHelper { ModestMailOperation *mail_op; - GetMsgAsynUserCallback user_callback; + GetMsgAsyncUserCallback user_callback; guint pending_ops; gpointer user_data; } GetMsgAsyncHelper; @@ -280,6 +277,15 @@ modest_mail_operation_is_mine (ModestMailOperation *self, return priv->source == me; } +GObject * +modest_mail_operation_get_source (ModestMailOperation *self) +{ + ModestMailOperationPrivate *priv; + + priv = MODEST_MAIL_OPERATION_GET_PRIVATE(self); + + return g_object_ref (priv->source); +} void modest_mail_operation_send_mail (ModestMailOperation *self, @@ -994,7 +1000,7 @@ modest_mail_operation_xfer_folder (ModestMailOperation *self, void modest_mail_operation_get_msg (ModestMailOperation *self, TnyHeader *header, - GetMsgAsynUserCallback user_callback, + GetMsgAsyncUserCallback user_callback, gpointer user_data) { GetMsgAsyncHelper *helper = NULL; @@ -1067,7 +1073,7 @@ get_msg_cb (TnyFolder *folder, /* If user defined callback function was defined, call it */ if (helper->user_callback) { - helper->user_callback (priv->source, msg, helper->user_data); + helper->user_callback (self, NULL, msg, helper->user_data); } /* Free */ @@ -1116,7 +1122,7 @@ get_msg_status_cb (GObject *obj, typedef struct { ModestMailOperation *mail_op; TnyList *headers; - GetMsgAsynUserCallback user_callback; + GetMsgAsyncUserCallback user_callback; gpointer user_data; GDestroyNotify notify; } GetFullMsgsInfo; @@ -1132,16 +1138,15 @@ notify_get_msgs_full_observers (gpointer data) g_signal_emit (G_OBJECT (mail_op), signals[PROGRESS_CHANGED_SIGNAL], 0, NULL); - g_object_unref (mail_op); - return FALSE; } typedef struct { - GetMsgAsynUserCallback user_callback; + GetMsgAsyncUserCallback user_callback; + TnyHeader *header; TnyMsg *msg; gpointer user_data; - GObject *source; + ModestMailOperation *mail_op; } NotifyGetMsgsInfo; @@ -1157,7 +1162,7 @@ notify_get_msgs_full (gpointer data) info = (NotifyGetMsgsInfo *) data; /* Call the user callback */ - info->user_callback (info->source, info->msg, info->user_data); + info->user_callback (info->mail_op, info->header, info->msg, info->user_data); g_slice_free (NotifyGetMsgsInfo, info); @@ -1215,7 +1220,7 @@ get_msgs_full_thread (gpointer thr_user_data) /* notify progress */ g_idle_add_full (G_PRIORITY_HIGH_IDLE, notify_get_msgs_full_observers, - g_object_ref (info->mail_op), NULL); + info->mail_op, NULL); /* The callback is the responsible for freeing the message */ @@ -1223,15 +1228,15 @@ get_msgs_full_thread (gpointer thr_user_data) NotifyGetMsgsInfo *info_notify; info_notify = g_slice_new0 (NotifyGetMsgsInfo); info_notify->user_callback = info->user_callback; - info_notify->source = priv->source; - info_notify->msg = msg; + info_notify->mail_op = info->mail_op; + info_notify->header = g_object_ref (header); + info_notify->msg = g_object_ref (msg); info_notify->user_data = info->user_data; g_idle_add_full (G_PRIORITY_HIGH_IDLE, notify_get_msgs_full, info_notify, NULL); - } else { - g_object_unref (msg); } + g_object_unref (msg); } } else { /* Set status failed and set an error */ @@ -1256,7 +1261,7 @@ get_msgs_full_thread (gpointer thr_user_data) void modest_mail_operation_get_msgs_full (ModestMailOperation *self, TnyList *header_list, - GetMsgAsynUserCallback user_callback, + GetMsgAsyncUserCallback user_callback, gpointer user_data, GDestroyNotify notify) { diff --git a/src/modest-mail-operation.h b/src/modest-mail-operation.h index 1f046b3..3928049 100644 --- a/src/modest-mail-operation.h +++ b/src/modest-mail-operation.h @@ -99,7 +99,7 @@ struct _ModestMailOperationClass { typedef void (*ErrorCheckingUserCallback) (const GObject *obj, gpointer user_data); /** - * GetMsgAsynUserCallback: + * GetMsgAsyncUserCallback: * * @obj: a #GObject generic object which has created current mail operation. * @msg: a #TnyMsg message retrieved by async operation. @@ -109,7 +109,10 @@ typedef void (*ErrorCheckingUserCallback) (const GObject *obj, gpointer user_dat * used as tinymail operation callback. The private function fills private * fields of mail operation and calls user defined callback if it exists. */ -typedef void (*GetMsgAsynUserCallback) (const GObject *obj, TnyMsg *msg, gpointer user_data); +typedef void (*GetMsgAsyncUserCallback) (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg, + gpointer user_data); /** * XferMsgAsynUserCallback: @@ -186,6 +189,17 @@ gboolean modest_mail_operation_is_mine (ModestMailOperation *self, GObject *me); +/** + * modest_mail_operation_get_source + * @self: a #ModestMailOperation + * + * returns a new reference to the object that created the mail + * operation passed to the constructor, or NULL if none. The caller + * must free the new reference + **/ +GObject * +modest_mail_operation_get_source (ModestMailOperation *self); + /* fill in other public functions, eg.: */ /** @@ -423,7 +437,7 @@ void modest_mail_operation_remove_msg (ModestMailOperation *self, * modest_mail_operation_get_msg: * @self: a #ModestMailOperation * @header_list: the #TnyHeader of the message to get - * @user_callback: a #GetMsgAsynUserCallback function to call after tinymail callback execution. + * @user_callback: a #GetMsgAsyncUserCallback function to call after tinymail callback execution. * @user_data: generic user data which will be passed to @user_callback function. * * Gets a message from header using an user defined @callback function @@ -432,7 +446,7 @@ void modest_mail_operation_remove_msg (ModestMailOperation *self, **/ void modest_mail_operation_get_msg (ModestMailOperation *self, TnyHeader *header, - GetMsgAsynUserCallback user_callback, + GetMsgAsyncUserCallback user_callback, gpointer user_data); /** * modest_mail_operation_get_msgs_full: @@ -447,7 +461,7 @@ void modest_mail_operation_get_msg (ModestMailOperation *self, **/ void modest_mail_operation_get_msgs_full (ModestMailOperation *self, TnyList *headers_list, - GetMsgAsynUserCallback user_callback, + GetMsgAsyncUserCallback user_callback, gpointer user_data, GDestroyNotify notify); diff --git a/src/modest-tny-account-store.c b/src/modest-tny-account-store.c index c577ded..824a67d 100644 --- a/src/modest-tny-account-store.c +++ b/src/modest-tny-account-store.c @@ -818,8 +818,7 @@ modest_tny_account_store_get_tny_account_by_account (ModestTnyAccountStore *self TnyAccountType type) { TnyAccount *account = NULL; - ModestAccountData *account_data; - const gchar *id = NULL; + gchar *id = NULL; ModestTnyAccountStorePrivate *priv; g_return_val_if_fail (self, NULL); @@ -828,17 +827,26 @@ modest_tny_account_store_get_tny_account_by_account (ModestTnyAccountStore *self NULL); priv = MODEST_TNY_ACCOUNT_STORE_GET_PRIVATE(self); - - account_data = modest_account_mgr_get_account_data (priv->account_mgr, account_name); - if (!account_data) { - g_printerr ("modest: cannot get account data for account '%s'\n", account_name); - return NULL; - } - if (type == TNY_ACCOUNT_TYPE_STORE && account_data->store_account) - id = account_data->store_account->account_name; - else if (account_data->transport_account) - id = account_data->transport_account->account_name; + /* Special case for the local account */ + if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) { + id = g_strdup (MODEST_LOCAL_FOLDERS_ACCOUNT_ID); + } else { + ModestAccountData *account_data; + + account_data = modest_account_mgr_get_account_data (priv->account_mgr, account_name); + if (!account_data) { + g_printerr ("modest: cannot get account data for account '%s'\n", account_name); + return NULL; + } + + if (type == TNY_ACCOUNT_TYPE_STORE && account_data->store_account) + id = g_strdup (account_data->store_account->account_name); + else if (account_data->transport_account) + id = g_strdup (account_data->transport_account->account_name); + + modest_account_mgr_free_account_data (priv->account_mgr, account_data); + } if (!id) g_printerr ("modest: could not get an id for account %s\n", @@ -851,7 +859,6 @@ modest_tny_account_store_get_tny_account_by_account (ModestTnyAccountStore *self type == TNY_ACCOUNT_TYPE_STORE? "store" : "transport", account_name, id ? id : ""); - modest_account_mgr_free_account_data (priv->account_mgr, account_data); return account; } diff --git a/src/modest-ui-actions.c b/src/modest-ui-actions.c index e61f593..f454815 100644 --- a/src/modest-ui-actions.c +++ b/src/modest-ui-actions.c @@ -91,13 +91,6 @@ typedef struct _ReplyForwardHelper { gchar *account_name; } ReplyForwardHelper; -typedef struct _HeaderActivatedHelper { - GtkTreeModel *model; - GtkTreeRowReference *row_reference; - TnyFolder *folder; - TnyHeader *header; -} HeaderActivatedHelper; - /* * The do_headers_action uses this kind of functions to perform some * action to each member of a list of headers @@ -110,9 +103,15 @@ do_headers_action (ModestWindow *win, gpointer user_data); -static void open_msg_func (const GObject *obj, TnyMsg *msg, gpointer user_data); +static void open_msg_cb (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg, + gpointer user_data); -static void reply_forward_func (const GObject *obj, TnyMsg *msg, gpointer user_data); +static void reply_forward_cb (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg, + gpointer user_data); static void reply_forward (ReplyForwardAction action, ModestWindow *win); @@ -144,7 +143,14 @@ modest_ui_actions_on_about (GtkAction *action, ModestWindow *win) gtk_widget_destroy(about); } - +/* + * Gets the list of currently selected messages. If the win is the + * main window, then it returns a newly allocated list of the headers + * selected in the header view. If win is the msg view window, then + * the value returned is a list with just a single header. + * + * The caller of this funcion must free the list. + */ static TnyList * get_selected_headers (ModestWindow *win) { @@ -487,70 +493,72 @@ cleanup: } static void -headers_action_open (TnyHeader *header, - ModestWindow *win, - gpointer user_data) -{ - modest_ui_actions_on_header_activated (MODEST_HEADER_VIEW (user_data), - header, - MODEST_MAIN_WINDOW (win)); -} - -void -modest_ui_actions_on_open (GtkAction *action, ModestWindow *win) -{ - GtkWidget *header_view; - - /* Get header view */ - header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win), - MODEST_WIDGET_TYPE_HEADER_VIEW); - - /* Open each message */ - do_headers_action (win, headers_action_open, header_view); -} - - -static void -open_msg_func (const GObject *obj, TnyMsg *msg, gpointer user_data) +open_msg_cb (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg, + gpointer user_data) { ModestWindowMgr *mgr = NULL; ModestWindow *parent_win = NULL; ModestWindow *win = NULL; - HeaderActivatedHelper *helper = NULL; TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN; gchar *account = NULL; + TnyFolder *folder; - g_return_if_fail (MODEST_IS_WINDOW(obj)); - g_return_if_fail (user_data != NULL); - /* TODO: Show an error? (review the specs) */ if (!msg) return; - parent_win = MODEST_WINDOW(obj); - helper = (HeaderActivatedHelper *) user_data; + parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op); + folder = tny_header_get_folder (header); /* Mark header as read */ - headers_action_mark_as_read (helper->header, MODEST_WINDOW(parent_win), NULL); + headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL); /* Get account */ - account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(parent_win))); + account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win))); if (!account) account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr()); - /* Gets foldert type (OUTBOX headers will be opened in edit window */ - if (modest_tny_folder_is_local_folder (helper->folder)) - folder_type = modest_tny_folder_get_local_folder_type (helper->folder); + /* Get folder type */ + if (modest_tny_folder_is_local_folder (folder)) + folder_type = modest_tny_folder_get_local_folder_type (folder); - switch (folder_type) { - case TNY_FOLDER_TYPE_DRAFTS: - win = modest_msg_edit_window_new ((TnyMsg *) msg, account); - break; - default: - if (helper->model != NULL) - win = modest_msg_view_window_new_with_header_model ((TnyMsg *) msg, account, helper->model, helper->row_reference); - else - win = modest_msg_view_window_new ((TnyMsg *) msg, account); + /* If the header is in the drafts folder then open the editor, + else the message view window */ + if (folder_type == TNY_FOLDER_TYPE_DRAFTS) { + win = modest_msg_edit_window_new (msg, account); + } else { + if (MODEST_IS_MAIN_WINDOW (parent_win)) { + GtkWidget *header_view; + GtkTreeSelection *sel; + GList *sel_list = NULL; + GtkTreeModel *model; + + header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win), + MODEST_WIDGET_TYPE_HEADER_VIEW); + + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view)); + sel_list = gtk_tree_selection_get_selected_rows (sel, &model); + + if (sel_list != NULL) { + GtkTreeRowReference *row_reference; + + row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data); + g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL); + g_list_free (sel_list); + + win = modest_msg_view_window_new_with_header_model (msg, + account, + model, + row_reference); + gtk_tree_row_reference_free (row_reference); + } else { + win = modest_msg_view_window_new (msg, account); + } + } else { + win = modest_msg_view_window_new (msg, account); + } } /* Register and show new window */ @@ -563,13 +571,71 @@ open_msg_func (const GObject *obj, TnyMsg *msg, gpointer user_data) /* Free */ g_free(account); -/* g_object_unref (G_OBJECT(msg)); */ - g_object_unref (G_OBJECT(helper->folder)); - g_object_unref (G_OBJECT(helper->header)); - gtk_tree_row_reference_free (helper->row_reference); - g_slice_free (HeaderActivatedHelper, helper); + g_object_unref (msg); + g_object_unref (folder); + g_object_unref (header); } +/* + * This function is used by both modest_ui_actions_on_open and + * modest_ui_actions_on_header_activated. This way we always do the + * same when trying to open messages. + */ +static void +_modest_ui_actions_open (TnyList *headers, ModestWindow *win) +{ + ModestWindowMgr *mgr; + TnyIterator *iter; + ModestMailOperation *mail_op; + + /* Look if we already have a message view for each header. If + true, then remove the header from the list of headers to + open */ + mgr = modest_runtime_get_window_mgr (); + iter = tny_list_create_iterator (headers); + while (!tny_iterator_is_done (iter)) { + ModestWindow *window; + TnyHeader *header; + + header = TNY_HEADER (tny_iterator_get_current (iter)); + window = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header)); + if (window) + tny_list_remove (headers, G_OBJECT (header)); + + g_object_unref (header); + tny_iterator_next (iter); + } + + /* Open each message */ + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT (win)); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); + modest_mail_operation_get_msgs_full (mail_op, + headers, + open_msg_cb, + NULL, + NULL); + + /* Clean */ + g_object_unref(mail_op); +} + +void +modest_ui_actions_on_open (GtkAction *action, ModestWindow *win) +{ + TnyList *headers; + + /* Get headers */ + headers = get_selected_headers (win); + if (!headers) + return; + + /* Open them */ + _modest_ui_actions_open (headers, win); + + g_object_unref(headers); +} + + static void free_reply_forward_helper (gpointer data) { @@ -581,7 +647,10 @@ free_reply_forward_helper (gpointer data) } static void -reply_forward_func (const GObject *obj, TnyMsg *msg, gpointer user_data) +reply_forward_cb (ModestMailOperation *mail_op, + TnyHeader *header, + TnyMsg *msg, + gpointer user_data) { TnyMsg *new_msg; ReplyForwardHelper *rf_helper; @@ -611,19 +680,19 @@ reply_forward_func (const GObject *obj, TnyMsg *msg, gpointer user_data) switch (rf_helper->action) { case ACTION_REPLY: new_msg = - modest_tny_msg_create_reply_msg ((TnyMsg *) msg, from, signature, + modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type, MODEST_TNY_MSG_REPLY_MODE_SENDER); break; case ACTION_REPLY_TO_ALL: new_msg = - modest_tny_msg_create_reply_msg ((TnyMsg *) msg, from, signature, rf_helper->reply_forward_type, + modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type, MODEST_TNY_MSG_REPLY_MODE_ALL); edit_type = MODEST_EDIT_TYPE_REPLY; break; case ACTION_FORWARD: new_msg = - modest_tny_msg_create_forward_msg ((TnyMsg *) msg, from, signature, rf_helper->reply_forward_type); + modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type); edit_type = MODEST_EDIT_TYPE_FORWARD; break; default: @@ -652,8 +721,7 @@ reply_forward_func (const GObject *obj, TnyMsg *msg, gpointer user_data) goto cleanup; } - tny_folder_add_msg (folder, (TnyMsg *) msg, &err); - g_object_unref (msg); + tny_folder_add_msg (folder, msg, &err); if (err) { g_printerr ("modest: error adding msg to Drafts folder: %s", err->message); @@ -675,7 +743,9 @@ cleanup: if (folder) g_object_unref (G_OBJECT (folder)); if (account) - g_object_unref (G_OBJECT (account)); + g_object_unref (G_OBJECT (account)); + g_object_unref (msg); + g_object_unref (header); } /* @@ -714,25 +784,36 @@ reply_forward (ReplyForwardAction action, ModestWindow *win) if (MODEST_IS_MSG_VIEW_WINDOW(win)) { TnyMsg *msg; - msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win)); - if (!msg) { + TnyHeader *header; + /* Get header and message. Do not free them here, the + reply_forward_cb must do it */ + msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win)); + header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win)); + if (!msg || !header) { + if (msg) + g_object_unref (msg); + if (header) + g_object_unref (header); g_printerr ("modest: no message found\n"); return; } else - reply_forward_func (G_OBJECT(win), g_object_ref (msg), rf_helper); + reply_forward_cb (NULL, header, msg, rf_helper); } else { /* Retrieve messages */ mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win)); modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); modest_mail_operation_get_msgs_full (mail_op, header_list, - reply_forward_func, + reply_forward_cb, rf_helper, free_reply_forward_helper); /* Clean */ g_object_unref(mail_op); } + + /* Free */ + g_object_unref (header_list); } void @@ -1001,50 +1082,19 @@ modest_ui_actions_on_header_activated (ModestHeaderView *header_view, TnyHeader *header, ModestMainWindow *main_window) { - ModestMailOperation *mail_op = NULL; - HeaderActivatedHelper *helper = NULL; - ModestWindowMgr *mgr = NULL; - ModestWindow *win = NULL; - GtkTreeModel *model = NULL; - GtkTreeSelection *sel = NULL; - GList *sel_list = NULL; - + TnyList *headers; + g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window)); if (!header) return; - /* Look if we already have a message view for that header */ - mgr = modest_runtime_get_window_mgr (); - win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header)); - if (win) return; - - /* Build helper */ - helper = g_slice_new0 (HeaderActivatedHelper); - helper->folder = tny_header_get_folder (header); - helper->header = g_object_ref(header); - helper->model = NULL; - - /* Get headers tree model and selected row reference to build message view */ - sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view)); - sel_list = gtk_tree_selection_get_selected_rows (sel, &model); - if (sel_list != NULL) { - - /* Fill helpers */ - helper->model = model; - helper->row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data); + headers = tny_simple_list_new (); + tny_list_prepend (headers, G_OBJECT (header)); - g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL); - g_list_free (sel_list); - } - - /* New mail operation */ - mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(main_window)); - modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); - modest_mail_operation_get_msg (mail_op, header, open_msg_func, helper); + _modest_ui_actions_open (headers, MODEST_WINDOW (main_window)); - /* Free */ - g_object_unref (mail_op); + g_object_unref (headers); } static void @@ -2125,21 +2175,23 @@ modest_ui_actions_on_details (GtkAction *action, TnyMsg *msg; msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win)); - if (!msg) { + if (!msg) return; - } else { - headers_list = get_selected_headers (win); - if (!headers_list) - return; + g_object_unref (msg); - iter = tny_list_create_iterator (headers_list); + headers_list = get_selected_headers (win); + if (!headers_list) + return; - header = TNY_HEADER (tny_iterator_get_current (iter)); - headers_action_show_details (header, win, NULL); - g_object_unref (header); + iter = tny_list_create_iterator (headers_list); + + header = TNY_HEADER (tny_iterator_get_current (iter)); + headers_action_show_details (header, win, NULL); + g_object_unref (header); + + g_object_unref (iter); + g_object_unref (headers_list); - g_object_unref (iter); - } } else if (MODEST_IS_MAIN_WINDOW (win)) { GtkWidget *folder_view, *header_view; @@ -2607,6 +2659,7 @@ do_headers_action (ModestWindow *win, tny_iterator_next (iter); } g_object_unref (iter); + g_object_unref (headers_list); } void @@ -2659,3 +2712,25 @@ modest_ui_actions_on_settings (GtkAction *action, gtk_widget_destroy (dialog); } + +void +modest_ui_actions_on_retrieve_msg_contents (GtkAction *action, + ModestWindow *window) +{ + ModestMailOperation *mail_op; + TnyList *headers; + + /* Get headers */ + headers = get_selected_headers (window); + if (!headers) + return; + + /* Create mail operation */ + mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT (window)); + modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op); + modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL); + + /* Frees */ + g_object_unref (headers); + g_object_unref (mail_op); +} diff --git a/src/modest-ui-actions.h b/src/modest-ui-actions.h index 0eff091..bc2b7ab 100644 --- a/src/modest-ui-actions.h +++ b/src/modest-ui-actions.h @@ -303,16 +303,24 @@ void modest_ui_actions_on_folder_display_name_changed (ModestFolderView *fol const gchar *display_name, GtkWindow *window); -void modest_ui_actions_view_attachment (GtkAction *action, - ModestWindow *window); +void modest_ui_actions_view_attachment (GtkAction *action, + ModestWindow *window); -void modest_ui_actions_save_attachments (GtkAction *action, - ModestWindow *window); +void modest_ui_actions_save_attachments (GtkAction *action, + ModestWindow *window); -void modest_ui_actions_remove_attachments (GtkAction *action, - ModestWindow *window); +void modest_ui_actions_remove_attachments (GtkAction *action, + ModestWindow *window); - +/** + * modest_ui_actions_on_retrieve_msg_contents: + * @action: the #GtkAction + * @window: the #ModestWindow that issues the action + * + * Retrieve the contents of the selected messages in the header view + **/ +void modest_ui_actions_on_retrieve_msg_contents (GtkAction *action, + ModestWindow *window); G_END_DECLS #endif /* __MODEST_UI_ACTIONS_H__ */ diff --git a/src/widgets/modest-header-view.h b/src/widgets/modest-header-view.h index 53e79e8..76a7672 100644 --- a/src/widgets/modest-header-view.h +++ b/src/widgets/modest-header-view.h @@ -221,7 +221,8 @@ ModestHeaderViewStyle modest_header_view_get_style (ModestHeaderView *self); * modest_header_view_get_selected_headers: * @self: a ModestHeaderView instance * - * get the list of the currently selected TnyHeader's + * get the list of the currently selected TnyHeader's. The list and + * the headers should be freed by the caller * * Returns: the list with the currently selected headers */ diff --git a/src/widgets/modest-msg-view-window.h b/src/widgets/modest-msg-view-window.h index b029a51..3e56737 100644 --- a/src/widgets/modest-msg-view-window.h +++ b/src/widgets/modest-msg-view-window.h @@ -113,7 +113,8 @@ modest_msg_view_window_get_header (ModestMsgViewWindow *self); * modest_msg_view_window_get_message: * @window: an #ModestMsgViewWindow instance * - * get the message in this msg view + * get a new reference to the message in this msg view. The caller + * must free this new reference * * Returns: a new #TnyMsg instance, or NULL in case of error */ diff --git a/src/widgets/modest-msg-view.c b/src/widgets/modest-msg-view.c index d3ae977..66c205c 100644 --- a/src/widgets/modest-msg-view.c +++ b/src/widgets/modest-msg-view.c @@ -1407,9 +1407,16 @@ modest_msg_view_set_message (ModestMsgView *self, TnyMsg *msg) TnyMsg* modest_msg_view_get_message (ModestMsgView *self) { + TnyMsg *msg; + g_return_val_if_fail (self, NULL); + + msg = MODEST_MSG_VIEW_GET_PRIVATE(self)->msg; + + if (msg) + g_object_ref (msg); - return MODEST_MSG_VIEW_GET_PRIVATE(self)->msg; + return msg; } gboolean diff --git a/src/widgets/modest-msg-view.h b/src/widgets/modest-msg-view.h index ce02e1d..d5dc11a 100644 --- a/src/widgets/modest-msg-view.h +++ b/src/widgets/modest-msg-view.h @@ -113,7 +113,8 @@ void modest_msg_view_set_message (ModestMsgView *self, TnyMsg *tny_msg) * modest_msg_view_set_message * @self: a ModestMsgView instance * - * get the @tny_msg e-mail message. + * gets a new reference the #TnyMsg of the message view. The caller + * must free the new reference * * Returns: the message or NULL */ -- 1.7.9.5