aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2013-06-15 01:45:08 +0800
committerMatthew Barnes <mbarnes@redhat.com>2013-06-15 11:21:40 +0800
commit9c4500a9b5b030e6fb2b8c02e518254d94c10add (patch)
tree72e5c5e0c50bb93b6d4c4fb683f78e235f8a744f /mail
parent169c9aea03c1ba03d327af2a4f0fb8bb3aabd593 (diff)
downloadgsoc2013-evolution-9c4500a9b5b030e6fb2b8c02e518254d94c10add.tar.gz
gsoc2013-evolution-9c4500a9b5b030e6fb2b8c02e518254d94c10add.tar.zst
gsoc2013-evolution-9c4500a9b5b030e6fb2b8c02e518254d94c10add.zip
MessageList: Add a "folder" property.
Also move the CamelFolder pointer into the private structure. New functions: message_list_ref_folder()
Diffstat (limited to 'mail')
-rw-r--r--mail/e-mail-paned-view.c13
-rw-r--r--mail/e-mail-reader.c10
-rw-r--r--mail/message-list.c358
-rw-r--r--mail/message-list.h4
4 files changed, 272 insertions, 113 deletions
diff --git a/mail/e-mail-paned-view.c b/mail/e-mail-paned-view.c
index 9f39347973..440c83b624 100644
--- a/mail/e-mail-paned-view.c
+++ b/mail/e-mail-paned-view.c
@@ -126,10 +126,13 @@ mail_paned_view_message_list_built_cb (EMailView *view,
EMailPanedViewPrivate *priv;
EShellView *shell_view;
EShellWindow *shell_window;
+ CamelFolder *folder;
GKeyFile *key_file;
priv = E_MAIL_PANED_VIEW_GET_PRIVATE (view);
+ folder = message_list_ref_folder (message_list);
+
g_signal_handler_disconnect (
message_list, priv->message_list_built_id);
priv->message_list_built_id = 0;
@@ -142,20 +145,18 @@ mail_paned_view_message_list_built_cb (EMailView *view,
if (message_list->cursor_uid != NULL)
; /* do nothing */
- else if (message_list->folder == NULL)
+ else if (folder == NULL)
; /* do nothing */
else if (e_shell_window_get_safe_mode (shell_window))
e_shell_window_set_safe_mode (shell_window, FALSE);
else {
- CamelFolder *folder;
const gchar *key;
gchar *folder_uri;
gchar *group_name;
gchar *uid;
- folder = message_list->folder;
folder_uri = e_mail_folder_uri_from_folder (folder);
key = STATE_KEY_SELECTED_MESSAGE;
@@ -170,6 +171,8 @@ mail_paned_view_message_list_built_cb (EMailView *view,
g_free (uid);
}
+
+ g_clear_object (&folder);
}
static void
@@ -184,7 +187,7 @@ mail_paned_view_message_selected_cb (EMailView *view,
gchar *folder_uri;
gchar *group_name;
- folder = message_list->folder;
+ folder = message_list_ref_folder (message_list);
/* This also gets triggered when selecting a store name on
* the sidebar such as "On This Computer", in which case
@@ -208,6 +211,8 @@ mail_paned_view_message_selected_cb (EMailView *view,
g_free (group_name);
g_free (folder_uri);
+
+ g_object_unref (folder);
}
static void
diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c
index a93d7260b5..18d71b39de 100644
--- a/mail/e-mail-reader.c
+++ b/mail/e-mail-reader.c
@@ -2993,10 +2993,18 @@ static CamelFolder *
mail_reader_get_folder (EMailReader *reader)
{
GtkWidget *message_list;
+ CamelFolder *folder;
message_list = e_mail_reader_get_message_list (reader);
- return MESSAGE_LIST (message_list)->folder;
+ /* FIXME This is dangerous. EMailReader should return a
+ * new CamelFolder reference and rename this method
+ * to "ref_folder()" instead of "get_folder()". */
+ folder = message_list_ref_folder (MESSAGE_LIST (message_list));
+ if (folder != NULL)
+ g_object_unref (folder);
+
+ return folder;
}
static void
diff --git a/mail/message-list.c b/mail/message-list.c
index 2619ebf6de..f7c58d22d4 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -91,6 +91,9 @@ struct _MessageListPrivate {
EMailSession *session;
+ CamelFolder *folder;
+ gulong folder_changed_handler_id;
+
/* For message list regeneration. */
GMutex regen_lock;
RegenData *regen_data;
@@ -150,6 +153,7 @@ struct _RegenData {
enum {
PROP_0,
PROP_COPY_TARGET_LIST,
+ PROP_FOLDER,
PROP_PASTE_TARGET_LIST,
PROP_SESSION,
PROP_THREAD_LATEST,
@@ -241,10 +245,6 @@ static void mail_regen_cancel (MessageList *ml);
static void clear_info (gchar *key, ETreePath *node, MessageList *ml);
-static void folder_changed (CamelFolder *folder,
- CamelFolderChangeInfo *info,
- MessageList *ml);
-
enum {
MESSAGE_SELECTED,
MESSAGE_LIST_BUILT,
@@ -308,7 +308,7 @@ regen_data_new (MessageList *message_list,
regen_data->last_row = -1;
/* Capture MessageList state to use for this regen. */
- regen_data->folder = g_object_ref (message_list->folder);
+ regen_data->folder = message_list_ref_folder (message_list);
regen_data->threaded = message_list->threaded;
regen_data->hide_deleted = message_list->hidedeleted;
regen_data->hide_junk = message_list->hidejunk;
@@ -735,7 +735,7 @@ message_list_select_uid (MessageList *message_list,
priv = message_list->priv;
uid_nodemap = message_list->uid_nodemap;
- if (message_list->folder == NULL)
+ if (message_list->priv->folder == NULL)
return;
/* Try to find the requested message UID. */
@@ -1012,22 +1012,28 @@ message_list_copy (MessageList *ml,
if (uids->len > 0) {
if (cut) {
+ CamelFolder *folder;
gint i;
- camel_folder_freeze (ml->folder);
+ folder = message_list_ref_folder (ml);
+
+ camel_folder_freeze (folder);
+
for (i = 0; i < uids->len; i++)
camel_folder_set_message_flags (
- ml->folder, uids->pdata[i],
+ folder, uids->pdata[i],
CAMEL_MESSAGE_SEEN |
CAMEL_MESSAGE_DELETED,
CAMEL_MESSAGE_SEEN |
CAMEL_MESSAGE_DELETED);
- camel_folder_thaw (ml->folder);
+ camel_folder_thaw (folder);
+
+ g_object_unref (folder);
}
p->clipboard.uids = uids;
- p->clipboard.folder = g_object_ref (ml->folder);
+ p->clipboard.folder = message_list_ref_folder (ml);
gtk_selection_owner_set (p->invisible, GDK_SELECTION_CLIPBOARD, gtk_get_current_event_time ());
} else {
em_utils_uids_free (uids);
@@ -1759,7 +1765,7 @@ ml_tree_value_at_ex (ETreeModel *etm,
const gchar *store_name;
const gchar *folder_name;
- folder = message_list->folder;
+ folder = message_list->priv->folder;
if (CAMEL_IS_VEE_FOLDER (folder))
folder = camel_vee_folder_get_location (
@@ -2120,14 +2126,18 @@ message_list_create_extras (void)
}
static void
-save_tree_state (MessageList *ml)
+save_tree_state (MessageList *ml,
+ CamelFolder *folder)
{
gchar *filename;
- if (ml->folder == NULL || (ml->search && *ml->search))
+ if (folder == NULL)
return;
- filename = mail_config_folder_to_cachename (ml->folder, "et-expanded-");
+ if (ml->search != NULL && *ml->search != '\0')
+ return;
+
+ filename = mail_config_folder_to_cachename (folder, "et-expanded-");
e_tree_save_expanded_state (E_TREE (ml), filename);
g_free (filename);
@@ -2136,9 +2146,10 @@ save_tree_state (MessageList *ml)
static void
load_tree_state (MessageList *ml,
+ CamelFolder *folder,
xmlDoc *expand_state)
{
- if (ml->folder == NULL)
+ if (folder == NULL)
return;
if (expand_state) {
@@ -2147,7 +2158,8 @@ load_tree_state (MessageList *ml,
/* only when not searching */
gchar *filename;
- filename = mail_config_folder_to_cachename (ml->folder, "et-expanded-");
+ filename = mail_config_folder_to_cachename (
+ folder, "et-expanded-");
e_tree_load_expanded_state (E_TREE (ml), filename);
g_free (filename);
}
@@ -2158,25 +2170,41 @@ load_tree_state (MessageList *ml,
void
message_list_save_state (MessageList *ml)
{
- save_tree_state (ml);
+ CamelFolder *folder;
+
+ folder = message_list_ref_folder (ml);
+
+ if (folder != NULL) {
+ save_tree_state (ml, folder);
+ g_object_unref (folder);
+ }
}
static void
message_list_setup_etree (MessageList *message_list)
{
- /* build the spec based on the folder, and possibly from a saved file */
- /* otherwise, leave default */
- if (message_list->folder) {
+ CamelFolder *folder;
+
+ /* Build the spec based on the folder, and possibly
+ * from a saved file. Otherwise, leave default. */
+
+ folder = message_list_ref_folder (message_list);
+
+ if (folder != NULL) {
gint data = 1;
ETableItem *item;
item = e_tree_get_item (E_TREE (message_list));
g_object_set (message_list, "uniform_row_height", TRUE, NULL);
- g_object_set_data (G_OBJECT (((GnomeCanvasItem *) item)->canvas), "freeze-cursor", &data);
+ g_object_set_data (
+ G_OBJECT (((GnomeCanvasItem *) item)->canvas),
+ "freeze-cursor", &data);
/* build based on saved file */
- load_tree_state (message_list, NULL);
+ load_tree_state (message_list, folder, NULL);
+
+ g_object_unref (folder);
}
}
@@ -2224,6 +2252,7 @@ ml_selection_received (GtkWidget *widget,
MessageList *message_list)
{
EMailSession *session;
+ CamelFolder *folder;
GdkAtom target;
target = gtk_selection_data_get_target (selection_data);
@@ -2233,12 +2262,14 @@ ml_selection_received (GtkWidget *widget,
return;
}
+ folder = message_list_ref_folder (message_list);
session = message_list_get_session (message_list);
/* FIXME Not passing a GCancellable or GError here. */
em_utils_selection_get_uidlist (
- selection_data, session, message_list->folder,
- FALSE, NULL, NULL);
+ selection_data, session, folder, FALSE, NULL, NULL);
+
+ g_clear_object (&folder);
}
static void
@@ -2252,21 +2283,24 @@ ml_tree_drag_data_get (ETree *tree,
guint time,
MessageList *ml)
{
+ CamelFolder *folder;
GPtrArray *uids;
+ folder = message_list_ref_folder (ml);
uids = message_list_get_selected (ml);
if (uids->len > 0) {
switch (info) {
case DND_X_UID_LIST:
- em_utils_selection_set_uidlist (data, ml->folder, uids);
+ em_utils_selection_set_uidlist (data, folder, uids);
break;
case DND_TEXT_URI_LIST:
- em_utils_selection_set_urilist (data, ml->folder, uids);
+ em_utils_selection_set_urilist (data, folder, uids);
break;
}
}
+ g_clear_object (&folder);
em_utils_uids_free (uids);
}
@@ -2383,20 +2417,22 @@ ml_tree_drag_data_received (ETree *tree,
guint time,
MessageList *ml)
{
+ CamelFolder *folder;
struct _drop_msg *m;
- if (ml->folder == NULL)
- return;
-
if (gtk_selection_data_get_data (selection_data) == NULL)
return;
if (gtk_selection_data_get_length (selection_data) == -1)
return;
+ folder = message_list_ref_folder (ml);
+ if (folder == NULL)
+ return;
+
m = mail_msg_new (&ml_drop_async_info);
m->context = g_object_ref (context);
- m->folder = g_object_ref (ml->folder);
+ m->folder = g_object_ref (folder);
m->message_list = g_object_ref (ml);
m->action = gdk_drag_context_get_selected_action (context);
m->info = info;
@@ -2405,6 +2441,8 @@ ml_tree_drag_data_received (ETree *tree,
m->selection = gtk_selection_data_copy (selection_data);
ml_drop_action (m);
+
+ g_object_unref (folder);
}
struct search_child_struct {
@@ -2447,8 +2485,9 @@ ml_tree_drag_motion (ETree *tree,
GdkDragAction action, actions = 0;
GtkWidget *source_widget;
- /* If drop target is name of the account/store and not actual folder, don't allow any action */
- if (!ml->folder) {
+ /* If drop target is name of the account/store
+ * and not actual folder, don't allow any action. */
+ if (ml->priv->folder == NULL) {
gdk_drag_status (context, 0, time);
return TRUE;
}
@@ -2463,7 +2502,7 @@ ml_tree_drag_motion (ETree *tree,
if (EM_IS_FOLDER_TREE (source_widget)) {
EMFolderTree *folder_tree;
- CamelFolder *folder = NULL;
+ CamelFolder *selected_folder = NULL;
CamelStore *selected_store;
gchar *selected_folder_name;
gboolean has_selection;
@@ -2482,14 +2521,14 @@ ml_tree_drag_motion (ETree *tree,
(!has_selection && selected_folder_name == NULL));
if (has_selection) {
- folder = camel_store_get_folder_sync (
+ selected_folder = camel_store_get_folder_sync (
selected_store, selected_folder_name,
CAMEL_STORE_FOLDER_INFO_FAST, NULL, NULL);
g_object_unref (selected_store);
g_free (selected_folder_name);
}
- if (folder == ml->folder) {
+ if (selected_folder == ml->priv->folder) {
gdk_drag_status (context, 0, time);
return TRUE;
}
@@ -2640,6 +2679,12 @@ message_list_set_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
+ case PROP_FOLDER:
+ message_list_set_folder (
+ MESSAGE_LIST (object),
+ g_value_get_object (value));
+ return;
+
case PROP_SESSION:
message_list_set_session (
MESSAGE_LIST (object),
@@ -2676,6 +2721,13 @@ message_list_get_property (GObject *object,
MESSAGE_LIST (object)));
return;
+ case PROP_FOLDER:
+ g_value_take_object (
+ value,
+ message_list_ref_folder (
+ MESSAGE_LIST (object)));
+ return;
+
case PROP_PASTE_TARGET_LIST:
g_value_set_boxed (
value,
@@ -2716,6 +2768,13 @@ message_list_dispose (GObject *object)
priv = message_list->priv;
+ if (priv->folder_changed_handler_id > 0) {
+ g_signal_handler_disconnect (
+ priv->folder,
+ priv->folder_changed_handler_id);
+ priv->folder_changed_handler_id = 0;
+ }
+
if (priv->session != NULL) {
g_object_unref (priv->session);
priv->session = NULL;
@@ -2733,7 +2792,7 @@ message_list_dispose (GObject *object)
priv->destroyed = TRUE;
- if (message_list->folder)
+ if (message_list->priv->folder != NULL)
mail_regen_cancel (message_list);
if (message_list->uid_nodemap) {
@@ -2742,11 +2801,9 @@ message_list_dispose (GObject *object)
message_list->uid_nodemap = NULL;
}
- if (message_list->folder) {
- g_signal_handlers_disconnect_by_func (
- message_list->folder, folder_changed, message_list);
- g_object_unref (message_list->folder);
- message_list->folder = NULL;
+ if (message_list->priv->folder) {
+ g_object_unref (message_list->priv->folder);
+ message_list->priv->folder = NULL;
}
if (priv->invisible) {
@@ -2856,6 +2913,17 @@ message_list_class_init (MessageListClass *class)
PROP_COPY_TARGET_LIST,
"copy-target-list");
+ g_object_class_install_property (
+ object_class,
+ PROP_FOLDER,
+ g_param_spec_object (
+ "folder",
+ "Folder",
+ "The source folder",
+ CAMEL_TYPE_FOLDER,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
/* Inherited from ESelectableInterface */
g_object_class_override_property (
object_class,
@@ -3037,7 +3105,7 @@ clear_info (gchar *key,
CamelMessageInfo *info;
info = e_tree_memory_node_get_data ((ETreeMemory *) ml->model, node);
- camel_folder_free_message_info (ml->folder, info);
+ camel_folder_free_message_info (ml->priv->folder, info);
e_tree_memory_node_set_data ((ETreeMemory *) ml->model, node, NULL);
}
@@ -3046,6 +3114,7 @@ clear_tree (MessageList *ml,
gboolean tfree)
{
ETreeModel *etm = ml->model;
+ CamelFolder *folder;
#ifdef TIMEIT
struct timeval start, end;
@@ -3056,10 +3125,12 @@ clear_tree (MessageList *ml,
#endif
/* we also reset the uid_rowmap since it is no longer useful/valid anyway */
- if (ml->folder)
+ folder = message_list_ref_folder (ml);
+ if (folder != NULL)
g_hash_table_foreach (ml->uid_nodemap, (GHFunc) clear_info, ml);
g_hash_table_destroy (ml->uid_nodemap);
ml->uid_nodemap = g_hash_table_new (g_str_hash, g_str_equal);
+ g_clear_object (&folder);
ml->priv->newest_read_date = 0;
ml->priv->newest_read_uid = NULL;
@@ -3103,6 +3174,7 @@ static gboolean
is_node_selectable (MessageList *ml,
CamelMessageInfo *info)
{
+ CamelFolder *folder;
gboolean is_junk_folder;
gboolean is_trash_folder;
guint32 flags;
@@ -3110,15 +3182,20 @@ is_node_selectable (MessageList *ml,
gboolean flag_deleted;
gboolean store_has_vjunk;
- g_return_val_if_fail (ml != NULL, FALSE);
- g_return_val_if_fail (ml->folder != NULL, FALSE);
g_return_val_if_fail (info != NULL, FALSE);
- store_has_vjunk = folder_store_supports_vjunk_folder (ml->folder);
+ folder = message_list_ref_folder (ml);
+ g_return_val_if_fail (folder != NULL, FALSE);
+
+ store_has_vjunk = folder_store_supports_vjunk_folder (folder);
/* check folder type */
- is_junk_folder = store_has_vjunk && (ml->folder->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0;
- is_trash_folder = ml->folder->folder_flags & CAMEL_FOLDER_IS_TRASH;
+ is_junk_folder =
+ store_has_vjunk &&
+ (folder->folder_flags & CAMEL_FOLDER_IS_JUNK) != 0;
+ is_trash_folder = folder->folder_flags & CAMEL_FOLDER_IS_TRASH;
+
+ g_object_unref (folder);
/* check flags set on current message */
flags = camel_message_info_flags (info);
@@ -3207,12 +3284,16 @@ ml_uid_nodemap_insert (MessageList *message_list,
ETreePath *parent_node,
gint row)
{
+ CamelFolder *folder;
ETreeMemory *tree;
ETreePath *node;
const gchar *uid;
time_t date;
guint flags;
+ folder = message_list_ref_folder (message_list);
+ g_return_val_if_fail (folder != NULL, NULL);
+
if (parent_node == NULL)
parent_node = message_list->tree_root;
@@ -3223,7 +3304,7 @@ ml_uid_nodemap_insert (MessageList *message_list,
flags = camel_message_info_flags (info);
date = camel_message_info_date_received (info);
- camel_folder_ref_message_info (message_list->folder, info);
+ camel_folder_ref_message_info (folder, info);
g_hash_table_insert (message_list->uid_nodemap, (gpointer) uid, node);
/* Track the latest seen and unseen messages shown, used in
@@ -3243,6 +3324,8 @@ ml_uid_nodemap_insert (MessageList *message_list,
}
}
+ g_object_unref (folder);
+
return node;
}
@@ -3250,8 +3333,12 @@ static void
ml_uid_nodemap_remove (MessageList *message_list,
CamelMessageInfo *info)
{
+ CamelFolder *folder;
const gchar *uid;
+ folder = message_list_ref_folder (message_list);
+ g_return_if_fail (folder != NULL);
+
uid = camel_message_info_uid (info);
if (uid == message_list->priv->newest_read_uid) {
@@ -3265,7 +3352,9 @@ ml_uid_nodemap_remove (MessageList *message_list,
}
g_hash_table_remove (message_list->uid_nodemap, uid);
- camel_folder_free_message_info (message_list->folder, info);
+ camel_folder_free_message_info (folder, info);
+
+ g_object_unref (folder);
}
/* only call if we have a tree model */
@@ -3701,9 +3790,9 @@ mail_folder_hide_by_flag (CamelFolder *folder,
}
static void
-folder_changed (CamelFolder *folder,
- CamelFolderChangeInfo *changes,
- MessageList *ml)
+message_list_folder_changed (CamelFolder *folder,
+ CamelFolderChangeInfo *changes,
+ MessageList *ml)
{
CamelFolderChangeInfo *altered_changes = NULL;
gboolean need_list_regen = TRUE;
@@ -3754,6 +3843,21 @@ folder_changed (CamelFolder *folder,
camel_folder_change_info_free (altered_changes);
}
+CamelFolder *
+message_list_ref_folder (MessageList *message_list)
+{
+ CamelFolder *folder = NULL;
+
+ /* XXX Do we need a property lock to guard this? */
+
+ g_return_val_if_fail (IS_MESSAGE_LIST (message_list), NULL);
+
+ if (message_list->priv->folder != NULL)
+ folder = g_object_ref (message_list->priv->folder);
+
+ return folder;
+}
+
/**
* message_list_set_folder:
* @message_list: Message List widget
@@ -3769,11 +3873,18 @@ message_list_set_folder (MessageList *message_list,
gboolean hide_deleted;
GSettings *settings;
+ /* XXX Do we need a property lock to guard this? */
+
g_return_if_fail (IS_MESSAGE_LIST (message_list));
- if (message_list->folder == folder)
+ if (folder == message_list->priv->folder)
return;
+ if (folder != NULL) {
+ g_return_if_fail (CAMEL_IS_FOLDER (folder));
+ g_object_ref (folder);
+ }
+
g_free (message_list->search);
message_list->search = NULL;
@@ -3790,9 +3901,8 @@ message_list_set_folder (MessageList *message_list,
mail_regen_cancel (message_list);
- if (message_list->folder != NULL) {
- save_tree_state (message_list);
- }
+ if (message_list->priv->folder != NULL)
+ save_tree_state (message_list, message_list->priv->folder);
e_tree_memory_freeze (E_TREE_MEMORY (etm));
clear_tree (message_list, TRUE);
@@ -3804,39 +3914,42 @@ message_list_set_folder (MessageList *message_list,
message_list->idle_id = 0;
}
- if (message_list->folder) {
- g_signal_handlers_disconnect_by_func (
- message_list->folder, folder_changed, message_list);
+ if (message_list->priv->folder != NULL) {
+ g_signal_handler_disconnect (
+ message_list->priv->folder,
+ message_list->priv->folder_changed_handler_id);
+ message_list->priv->folder_changed_handler_id = 0;
- if (message_list->uid_nodemap)
- g_hash_table_foreach (message_list->uid_nodemap, (GHFunc) clear_info, message_list);
+ if (message_list->uid_nodemap != NULL)
+ g_hash_table_foreach (
+ message_list->uid_nodemap,
+ (GHFunc) clear_info, message_list);
- g_object_unref (message_list->folder);
- message_list->folder = NULL;
+ g_clear_object (&message_list->priv->folder);
}
- if (message_list->thread_tree) {
+ if (message_list->thread_tree != NULL) {
camel_folder_thread_messages_unref (message_list->thread_tree);
message_list->thread_tree = NULL;
}
- if (message_list->cursor_uid) {
- g_free (message_list->cursor_uid);
- message_list->cursor_uid = NULL;
- }
+ g_free (message_list->cursor_uid);
+ message_list->cursor_uid = NULL;
/* Always emit message-selected, event when an account node
* (folder == NULL) is selected, so that views know what happened and
* can stop all running operations etc. */
- g_signal_emit (message_list, message_list_signals[MESSAGE_SELECTED], 0, NULL);
+ g_signal_emit (
+ message_list, message_list_signals[MESSAGE_SELECTED], 0, NULL);
- if (CAMEL_IS_FOLDER (folder)) {
+ if (folder != NULL) {
CamelStore *store;
gboolean non_trash_folder;
gint strikeout_col;
ECell *cell;
+ gulong handler_id;
- message_list->folder = g_object_ref (folder);
+ message_list->priv->folder = folder;
message_list->just_set_folder = TRUE;
store = camel_folder_get_parent_store (folder);
@@ -3866,9 +3979,11 @@ message_list_set_folder (MessageList *message_list,
/* Build the etree suitable for this folder */
message_list_setup_etree (message_list);
- g_signal_connect (
+ handler_id = g_signal_connect (
folder, "changed",
- G_CALLBACK (folder_changed), message_list);
+ G_CALLBACK (message_list_folder_changed),
+ message_list);
+ message_list->priv->folder_changed_handler_id = handler_id;
settings = g_settings_new ("org.gnome.evolution.mail");
hide_deleted = !g_settings_get_boolean (settings, "show-deleted");
@@ -3877,7 +3992,7 @@ message_list_set_folder (MessageList *message_list,
message_list->hidedeleted =
hide_deleted && non_trash_folder;
message_list->hidejunk =
- folder_store_supports_vjunk_folder (message_list->folder) &&
+ folder_store_supports_vjunk_folder (folder) &&
!(folder->folder_flags & CAMEL_FOLDER_IS_JUNK) &&
!(folder->folder_flags & CAMEL_FOLDER_IS_TRASH);
@@ -4046,6 +4161,7 @@ on_click (ETree *tree,
GdkEvent *event,
MessageList *list)
{
+ CamelFolder *folder;
CamelMessageInfo *info;
gboolean folder_is_trash;
const gchar *uid;
@@ -4062,6 +4178,9 @@ on_click (ETree *tree,
if (!(info = get_message_info (list, path)))
return FALSE;
+ folder = message_list_ref_folder (list);
+ g_return_val_if_fail (folder != NULL, FALSE);
+
if (col == COL_FOLLOWUP_FLAG_STATUS) {
const gchar *tag, *cmp;
@@ -4091,7 +4210,7 @@ on_click (ETree *tree,
flags = camel_message_info_flags (info);
folder_is_trash =
- ((list->folder->folder_flags & CAMEL_FOLDER_IS_TRASH) != 0);
+ ((folder->folder_flags & CAMEL_FOLDER_IS_TRASH) != 0);
/* If a message was marked as deleted and the user flags it as
* important or unread in a non-Trash folder, then undelete the
@@ -4108,7 +4227,7 @@ on_click (ETree *tree,
}
uid = camel_message_info_uid (info);
- camel_folder_set_message_flags (list->folder, uid, flag, ~flags);
+ camel_folder_set_message_flags (folder, uid, flag, ~flags);
/* Notify the folder tree model that the user has marked a message
* as unread so it doesn't mistake the event as new mail arriving. */
@@ -4116,8 +4235,7 @@ on_click (ETree *tree,
EMFolderTreeModel *model;
model = em_folder_tree_model_get_default ();
- em_folder_tree_model_user_marked_unread (
- model, list->folder, 1);
+ em_folder_tree_model_user_marked_unread (model, folder, 1);
}
if (flag == CAMEL_MESSAGE_SEEN && list->seen_id) {
@@ -4125,6 +4243,8 @@ on_click (ETree *tree,
list->seen_id = 0;
}
+ g_object_unref (folder);
+
return TRUE;
}
@@ -4151,6 +4271,8 @@ ml_getselected_cb (ETreePath path,
GPtrArray *
message_list_get_uids (MessageList *ml)
{
+ CamelFolder *folder;
+
struct _ml_selected_data data = {
ml,
g_ptr_array_new ()
@@ -4158,8 +4280,12 @@ message_list_get_uids (MessageList *ml)
e_tree_path_foreach (E_TREE (ml), ml_getselected_cb, &data);
- if (ml->folder && data.uids->len)
- camel_folder_sort_uids (ml->folder, data.uids);
+ folder = message_list_ref_folder (ml);
+
+ if (folder != NULL && data.uids->len > 0)
+ camel_folder_sort_uids (folder, data.uids);
+
+ g_clear_object (&folder);
return data.uids;
}
@@ -4167,6 +4293,8 @@ message_list_get_uids (MessageList *ml)
GPtrArray *
message_list_get_selected (MessageList *ml)
{
+ CamelFolder *folder;
+
struct _ml_selected_data data = {
ml,
g_ptr_array_new ()
@@ -4174,8 +4302,12 @@ message_list_get_selected (MessageList *ml)
e_tree_selected_path_foreach (E_TREE (ml), ml_getselected_cb, &data);
- if (ml->folder && data.uids->len)
- camel_folder_sort_uids (ml->folder, data.uids);
+ folder = message_list_ref_folder (ml);
+
+ if (folder != NULL && data.uids->len > 0)
+ camel_folder_sort_uids (folder, data.uids);
+
+ g_clear_object (&folder);
return data.uids;
}
@@ -4448,9 +4580,7 @@ cmp_array_uids (gconstpointer a,
g_return_val_if_fail (md2 != NULL, 0);
g_return_val_if_fail (md2->mi != NULL, 0);
- if (!sort_data->ml ||
- sort_data->folder != sort_data->ml->folder ||
- g_cancellable_is_cancelled (sort_data->cancellable))
+ if (g_cancellable_is_cancelled (sort_data->cancellable))
return 0;
for (i = 0;
@@ -4514,16 +4644,18 @@ ml_sort_uids_by_tree (MessageList *ml,
ETreeTableAdapter *adapter;
ETableSortInfo *sort_info;
ETableHeader *full_header;
+ CamelFolder *folder;
struct sort_array_data sort_data;
guint i, len;
if (g_cancellable_is_cancelled (cancellable))
return;
- g_return_if_fail (ml != NULL);
- g_return_if_fail (ml->folder != NULL);
g_return_if_fail (uids != NULL);
+ folder = message_list_ref_folder (ml);
+ g_return_if_fail (folder != NULL);
+
adapter = e_tree_get_table_adapter (E_TREE (ml));
g_return_if_fail (adapter != NULL);
@@ -4531,14 +4663,15 @@ ml_sort_uids_by_tree (MessageList *ml,
full_header = e_tree_table_adapter_get_header (adapter);
if (!sort_info || uids->len == 0 || !full_header || e_table_sort_info_sorting_get_count (sort_info) == 0) {
- camel_folder_sort_uids (ml->folder, uids);
+ camel_folder_sort_uids (folder, uids);
+ g_object_unref (folder);
return;
}
len = e_table_sort_info_sorting_get_count (sort_info);
sort_data.ml = ml;
- sort_data.folder = g_object_ref (ml->folder);
+ sort_data.folder = folder;
sort_data.sort_columns = g_ptr_array_sized_new (len);
sort_data.message_infos = g_hash_table_new (g_str_hash, g_str_equal);
sort_data.cmp_cache = e_table_sorting_utils_create_cmp_cache ();
@@ -4546,7 +4679,6 @@ ml_sort_uids_by_tree (MessageList *ml,
for (i = 0;
i < len
- && ml->folder == sort_data.folder
&& !g_cancellable_is_cancelled (cancellable);
i++) {
ETableSortColumn scol;
@@ -4562,11 +4694,10 @@ ml_sort_uids_by_tree (MessageList *ml,
g_ptr_array_add (sort_data.sort_columns, data);
}
- camel_folder_summary_prepare_fetch_all (ml->folder->summary, NULL);
+ camel_folder_summary_prepare_fetch_all (folder->summary, NULL);
for (i = 0;
i < uids->len
- && ml->folder == sort_data.folder
&& !g_cancellable_is_cancelled (cancellable);
i++) {
gchar *uid;
@@ -4574,9 +4705,12 @@ ml_sort_uids_by_tree (MessageList *ml,
struct sort_message_info_data *md;
uid = g_ptr_array_index (uids, i);
- mi = camel_folder_get_message_info (sort_data.folder, uid);
- if (!mi) {
- g_warning ("%s: Cannot find uid '%s' in folder '%s'", G_STRFUNC, uid, camel_folder_get_full_name (sort_data.folder));
+ mi = camel_folder_get_message_info (folder, uid);
+ if (mi == NULL) {
+ g_warning (
+ "%s: Cannot find uid '%s' in folder '%s'",
+ G_STRFUNC, uid,
+ camel_folder_get_full_name (folder));
continue;
}
@@ -4587,12 +4721,21 @@ ml_sort_uids_by_tree (MessageList *ml,
g_hash_table_insert (sort_data.message_infos, uid, md);
}
- if (sort_data.folder == ml->folder && !g_cancellable_is_cancelled (cancellable))
- g_qsort_with_data (uids->pdata, uids->len, sizeof (gpointer), cmp_array_uids, &sort_data);
+ if (!g_cancellable_is_cancelled (cancellable))
+ g_qsort_with_data (
+ uids->pdata,
+ uids->len,
+ sizeof (gpointer),
+ cmp_array_uids,
+ &sort_data);
- camel_folder_summary_unlock (sort_data.folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
+ camel_folder_summary_unlock (folder->summary, CAMEL_FOLDER_SUMMARY_SUMMARY_LOCK);
- g_hash_table_foreach (sort_data.message_infos, (GHFunc) free_message_info_data, &sort_data);
+ /* FIXME Teach the hash table to destroy its own data. */
+ g_hash_table_foreach (
+ sort_data.message_infos,
+ (GHFunc) free_message_info_data,
+ &sort_data);
g_hash_table_destroy (sort_data.message_infos);
g_ptr_array_foreach (sort_data.sort_columns, (GFunc) g_free, NULL);
@@ -4600,7 +4743,7 @@ ml_sort_uids_by_tree (MessageList *ml,
e_table_sorting_utils_free_cmp_cache (sort_data.cmp_cache);
- g_object_unref (sort_data.folder);
+ g_object_unref (folder);
}
static void
@@ -4897,13 +5040,18 @@ message_list_regen_done_cb (GObject *source_object,
regen_data->tree = NULL;
if (forcing_expand_state || searching) {
- if (message_list->folder != NULL && tree != NULL && !searching)
- save_tree_state (message_list);
+ if (message_list->priv->folder != NULL &&
+ tree != NULL && !searching)
+ save_tree_state (
+ message_list,
+ regen_data->folder);
/* do not forget to set this back to use the default value... */
e_tree_force_expanded_state (tree, 0);
} else {
load_tree_state (
- message_list, regen_data->expand_state);
+ message_list,
+ regen_data->folder,
+ regen_data->expand_state);
}
message_list->expand_all = 0;
@@ -5047,7 +5195,7 @@ mail_regen_list (MessageList *message_list,
search = NULL;
/* Can't list messages in a folder until we have a folder. */
- if (message_list->folder == NULL) {
+ if (message_list->priv->folder == NULL) {
g_free (message_list->search);
message_list->search = g_strdup (search);
return;
diff --git a/mail/message-list.h b/mail/message-list.h
index 829e3c9c21..ec76cc600c 100644
--- a/mail/message-list.h
+++ b/mail/message-list.h
@@ -104,9 +104,6 @@ struct _MessageList {
ETreePath tree_root;
ETableExtras *extras;
- /* The folder being shown. */
- CamelFolder *folder;
-
GHashTable *uid_nodemap; /* uid (from info) -> tree node mapping */
GHashTable *normalised_hash;
@@ -167,6 +164,7 @@ typedef enum {
GType message_list_get_type (void);
GtkWidget * message_list_new (EMailSession *session);
EMailSession * message_list_get_session (MessageList *message_list);
+CamelFolder * message_list_ref_folder (MessageList *message_list);
void message_list_set_folder (MessageList *message_list,
CamelFolder *folder);
GtkTargetList * message_list_get_copy_target_list