aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
Diffstat (limited to 'mail')
-rw-r--r--mail/ChangeLog78
-rw-r--r--mail/folder-browser.c12
-rw-r--r--mail/mail-callbacks.c96
-rw-r--r--mail/mail-ops.c98
-rw-r--r--mail/mail-tools.c7
-rw-r--r--mail/mail-view.c7
-rw-r--r--mail/message-list.c150
-rw-r--r--mail/message-list.h12
8 files changed, 315 insertions, 145 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index df5e22876a..193d276e05 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,7 @@
+2000-12-24 Not Zed <NotZed@HelixCode.com>
+
+ * Merge from camel-mt-branch.
+
2000-12-23 Christopher James Lahey <clahey@helixcode.com>
* message-list.c (filter_date): Changed this to do different
@@ -46,6 +50,80 @@
* mail-ops.c (do_view_messages): Only update display every 2 seconds.
+2000-12-23 Not Zed <NotZed@HelixCode.com>
+
+ * message-list.h (MessageList): Add a specific hide data lock.
+
+ * message-list.c (message_list_drag_data_get): Do not use
+ cursor_uid, but get all currentlys elected messages directly off
+ the message-list.
+ (message_list_destroy): Removed mail_tool_camel_lock stuff.
+ (on_click): "
+ (message_list_hide_add, message_list_hide_uids, hide_load_state,
+ hide_save_state, message_list_hide_clear): ", but use a specfic
+ lock for the hide data.
+ (do_regenerate_messagelist): remove mail_tool_camel_lock stuff,
+ add hide_lock where required.
+ (message_list_init): Setup the hide_lock.
+ (message_list_destroy): Free the hide_lock.
+
+2000-12-22 Not Zed <NotZed@HelixCode.com>
+
+ * mail-ops.c (mail_do_sync_folder): Run sync in different thread
+ each time. Just a quick litlte hack to check multithreading.
+ There are now few operations that single-queue. Need to work out
+ a way to make the allocation of threads & resources easier, so we
+ dont get overwhelmed with threads, but we dont block when we dont
+ have to, either.
+
+ * message-list.c (main_folder_changed): If we have only changed
+ events, then process them directly.
+ (mail_do_regenerate_messagelist): Run regenerate in a new thread
+ each time, another quick hack to check mutlithreading.
+
+ * mail-view.c (view_delete_msg): Call camel folder set message
+ flags directly. mail_do_set_message_flags() is now completely
+ unused.
+
+ * folder-browser.c (mark_msg_seen): Call camel folder
+ set_message_flags directly.
+
+ * mail-callbacks.c (flag_messages): New function, that just sets
+ flags of all selected messages, without all that messy thread
+ stuff (setting flags is in-memory).
+ (mark_as_seen): Use flag_messages().
+ (mark_as_unseen): "
+ (undelete_msg): "
+ (delete_msg): "
+
+2000-12-20 Not Zed <NotZed@HelixCode.com>
+
+ * message-list.c (message_list_select): Free messageinfo lookups.
+ (message_list_drag_data_get): "
+ (subtree_unread): "
+ (subtree_size): "
+ (subtree_earliest): "
+ (ml_tree_value_at): " Also, keep the message info around in a
+ static variable, and ref'd, so that any internal references we
+ have to it dont vanish while we're not looking. This has a couple
+ of problems ... esp since we never unref the last access, although
+ camel-folder-summary wont check this when its unref'd, so we're
+ 'safe'.
+ (save_node_state): free messageinfo lookups.
+ (on_click): "
+ (get_message_info): deconstify return.
+
+ * mail-tools.c (mail_tool_move_folder_contents): Free messageinfo
+ lookups.
+
+ * mail-ops.c (do_filter_ondemand): Free messageinfo lookups.
+ (do_flag_messages): "
+ (do_fetch_mail): Remove mail_tool_lock stuff.
+ (mail_operation_run): Quick hack to run an operation
+ asynchrounously, in a brand-new thread.
+
+ * folder-browser.c (on_right_click): Free messageinfo lookups.
+
2000-12-16 Not Zed <NotZed@HelixCode.com>
* message-list.c (build_tree): Always use the slow (full-update)
diff --git a/mail/folder-browser.c b/mail/folder-browser.c
index 829848650c..5a94c91ba9 100644
--- a/mail/folder-browser.c
+++ b/mail/folder-browser.c
@@ -555,7 +555,7 @@ static gint
on_right_click (ETable *table, gint row, gint col, GdkEvent *event, FolderBrowser *fb)
{
extern CamelFolder *drafts_folder;
- const CamelMessageInfo *info;
+ CamelMessageInfo *info;
GPtrArray *uids;
int enable_mask = 0;
int last_item, i;
@@ -668,6 +668,8 @@ on_right_click (ETable *table, gint row, gint col, GdkEvent *event, FolderBrowse
else
have_undeleted = TRUE;
+ camel_folder_free_message_info(fb->folder, info);
+
if (have_seen && have_unseen && have_deleted && have_undeleted)
break;
}
@@ -852,15 +854,11 @@ static gint
mark_msg_seen (gpointer data)
{
MessageList *ml = data;
- GPtrArray *uids;
if (!ml->cursor_uid)
return FALSE;
-
- uids = g_ptr_array_new ();
- g_ptr_array_add (uids, g_strdup (ml->cursor_uid));
- mail_do_flag_messages (ml->folder, uids, FALSE,
- CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
+
+ camel_folder_set_message_flags(ml->folder, ml->cursor_uid, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
return FALSE;
}
diff --git a/mail/mail-callbacks.c b/mail/mail-callbacks.c
index 5307eb976f..32104dba76 100644
--- a/mail/mail-callbacks.c
+++ b/mail/mail-callbacks.c
@@ -620,36 +620,40 @@ invert_selection (BonoboUIComponent *uih, void *user_data, const char *path)
e_table_invert_selection (ml->table);
}
-void
-mark_as_seen (BonoboUIComponent *uih, void *user_data, const char *path)
+/* flag all selected messages */
+static void
+flag_messages(FolderBrowser *fb, guint32 mask, guint32 set)
{
- FolderBrowser *fb = FOLDER_BROWSER(user_data);
MessageList *ml = fb->message_list;
GPtrArray *uids;
-
+ int i;
+
if (ml->folder == NULL)
return;
-
+
+ /* could just use specific callback but i'm lazy */
uids = g_ptr_array_new ();
message_list_foreach (ml, enumerate_msg, uids);
- mail_do_flag_messages (ml->folder, uids, FALSE,
- CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
+ camel_folder_freeze(ml->folder);
+ for (i=0;i<uids->len;i++) {
+ camel_folder_set_message_flags(ml->folder, uids->pdata[i], mask, set);
+ g_free(uids->pdata[i]);
+ }
+ camel_folder_thaw(ml->folder);
+
+ g_ptr_array_free(uids, TRUE);
+}
+
+void
+mark_as_seen (BonoboUIComponent *uih, void *user_data, const char *path)
+{
+ flag_messages(FOLDER_BROWSER(user_data), CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN);
}
void
mark_as_unseen (BonoboUIComponent *uih, void *user_data, const char *path)
{
- FolderBrowser *fb = FOLDER_BROWSER(user_data);
- MessageList *ml = fb->message_list;
- GPtrArray *uids;
-
- if (ml->folder == NULL)
- return;
-
- uids = g_ptr_array_new ();
- message_list_foreach (ml, enumerate_msg, uids);
- mail_do_flag_messages (ml->folder, uids, FALSE,
- CAMEL_MESSAGE_SEEN, 0);
+ flag_messages(FOLDER_BROWSER(user_data), CAMEL_MESSAGE_SEEN, 0);
}
void
@@ -764,65 +768,13 @@ save_msg (GtkWidget *widget, gpointer user_data)
void
delete_msg (GtkWidget *button, gpointer user_data)
{
- FolderBrowser *fb = user_data;
- MessageList *ml = fb->message_list;
- GPtrArray *uids;
-
- uids = g_ptr_array_new ();
- message_list_foreach (ml, enumerate_msg, uids);
-
- /*
- * Toggling a flag is an "instantaneous" operation, so if
- * we're only doing one, just do it and return, rather than
- * queueing it for the other thread. This makes the "Delete"
- * key work correctly (move to the next message) again.
- * - Dan
- */
- if (uids->len == 1) {
- char *uid = uids->pdata[0];
-
- mail_tool_camel_lock_up ();
- camel_folder_set_message_flags (ml->folder, uid,
- CAMEL_MESSAGE_DELETED,
- CAMEL_MESSAGE_DELETED);
- mail_tool_camel_lock_down ();
- } else {
- mail_do_flag_messages (ml->folder, uids, FALSE,
- CAMEL_MESSAGE_DELETED,
- CAMEL_MESSAGE_DELETED);
- }
+ flag_messages(FOLDER_BROWSER(user_data), CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_DELETED);
}
void
undelete_msg (GtkWidget *button, gpointer user_data)
{
- FolderBrowser *fb = user_data;
- MessageList *ml = fb->message_list;
- GPtrArray *uids;
-
- uids = g_ptr_array_new ();
- message_list_foreach (ml, enumerate_msg, uids);
-
- /*
- * Toggling a flag is an "instantaneous" operation, so if
- * we're only doing one, just do it and return, rather than
- * queueing it for the other thread. This makes the "Delete"
- * key work correctly (move to the next message) again.
- * - Dan
- */
- if (uids->len == 1) {
- char *uid = uids->pdata[0];
-
- mail_tool_camel_lock_up ();
- camel_folder_set_message_flags (ml->folder, uid,
- CAMEL_MESSAGE_DELETED,
- 0);
- mail_tool_camel_lock_down ();
- } else {
- mail_do_flag_messages (ml->folder, uids, FALSE,
- CAMEL_MESSAGE_DELETED,
- 0);
- }
+ flag_messages(FOLDER_BROWSER(user_data), CAMEL_MESSAGE_DELETED, 0);
}
void
diff --git a/mail/mail-ops.c b/mail/mail-ops.c
index 5e0e4a56e7..bea8e335f2 100644
--- a/mail/mail-ops.c
+++ b/mail/mail-ops.c
@@ -37,6 +37,9 @@
#include "folder-browser.h"
#include "e-util/e-html-utils.h"
+/* temporary 'hack' */
+int mail_operation_run(const mail_operation_spec *op, void *in, int free);
+
/* ** FETCH MAIL ********************************************************** */
typedef struct fetch_mail_input_s
@@ -244,9 +247,6 @@ do_fetch_mail (gpointer in_data, gpointer op_data, CamelException *ex)
filter_driver_set_logfile (filter, logfile);
filter_driver_set_status_func (filter, mail_op_report_status, NULL);
- /* why on earth we 'up' a lock to get it, ... */
- mail_tool_camel_lock_up ();
-
camel_folder_freeze (input->destination);
if (!strncmp (input->source_url, "mbox:", 5)) {
@@ -315,8 +315,6 @@ do_fetch_mail (gpointer in_data, gpointer op_data, CamelException *ex)
camel_folder_thaw (input->destination);
- mail_tool_camel_lock_down ();
-
/*camel_object_unref (CAMEL_OBJECT (input->destination));*/
gtk_object_unref (GTK_OBJECT (filter));
}
@@ -458,10 +456,12 @@ do_filter_ondemand (gpointer in_data, gpointer op_data, CamelException *ex)
CamelMessageInfo *info;
message = camel_folder_get_message (input->source, input->uids->pdata[i], ex);
- info = (CamelMessageInfo *) camel_folder_get_message_info (input->source, input->uids->pdata[i]);
+ info = camel_folder_get_message_info (input->source, input->uids->pdata[i]);
/* filter the message - use "incoming" rules since we don't want special "demand" filters? */
filter_driver_filter_message (driver, message, info, "", FILTER_SOURCE_INCOMING, ex);
+
+ camel_folder_free_message_info(input->source, info);
}
if (logfile)
@@ -1178,12 +1178,13 @@ do_flag_messages (gpointer in_data, gpointer op_data, CamelException *ex)
}
if (input->invert) {
- const CamelMessageInfo *info;
+ CamelMessageInfo *info;
mail_tool_camel_lock_up ();
info = camel_folder_get_message_info (input->source, input->uids->pdata[i]);
camel_folder_set_message_flags (input->source, input->uids->pdata[i],
input->mask, ~info->flags);
+ camel_folder_free_message_info(input->source, info);
mail_tool_camel_lock_down ();
} else {
mail_tool_set_uid_flags (input->source, input->uids->pdata[i],
@@ -1985,7 +1986,8 @@ mail_do_sync_folder (CamelFolder *folder)
{
g_return_if_fail (CAMEL_IS_FOLDER (folder));
- mail_operation_queue (&op_sync_folder, folder, FALSE);
+ /*mail_operation_queue (&op_sync_folder, folder, FALSE);*/
+ mail_operation_run (&op_sync_folder, folder, FALSE);
}
/* ** DISPLAY MESSAGE ***************************************************** */
@@ -2112,9 +2114,87 @@ mail_do_display_message (MessageList *ml, MailDisplay *md, const char *uid,
input->uid = g_strdup (uid);
input->timeout = timeout;
- mail_operation_queue (&op_display_message, input, TRUE);
+ /* this is only temporary */
+ /*mail_operation_queue (&op_display_message, input, TRUE);*/
+ mail_operation_run (&op_display_message, input, TRUE);
+}
+
+/* dum de dum, below is an entirely async 'operation' thingy */
+struct _op_data {
+ void *out;
+ void *in;
+ CamelException *ex;
+ const mail_operation_spec *op;
+ int pipe[2];
+ int free;
+ GIOChannel *channel;
+};
+
+static void *
+runthread(void *oin)
+{
+ struct _op_data *o = oin;
+
+ o->op->callback(o->in, o->out, o->ex);
+
+ printf("thread run, sending notificaiton\n");
+
+ write(o->pipe[1], "", 1);
+
+ return oin;
}
+static gboolean
+runcleanup(GIOChannel *source, GIOCondition cond, void *d)
+{
+ struct _op_data *o = d;
+
+ printf("ggot notification, blup\n");
+
+ o->op->cleanup(o->in, o->out, o->ex);
+
+ /*close(o->pipe[0]);*/
+ close(o->pipe[1]);
+
+ if (o->free)
+ g_free(o->in);
+ g_free(o->out);
+ camel_exception_free(o->ex);
+ g_free(o);
+
+ g_io_channel_unref(source);
+
+ return FALSE;
+}
+
+#include <pthread.h>
+
+/* quick hack, like queue, but it runs it instantly in a new thread ! */
+int
+mail_operation_run(const mail_operation_spec *op, void *in, int free)
+{
+ struct _op_data *o;
+ pthread_t id;
+
+ o = g_malloc0(sizeof(*o));
+ o->op = op;
+ o->in = in;
+ o->out = g_malloc0(op->datasize);
+ o->ex = camel_exception_new();
+ o->free = free;
+ pipe(o->pipe);
+
+ o->channel = g_io_channel_unix_new(o->pipe[0]);
+ g_io_add_watch(o->channel, G_IO_IN, (GIOFunc)runcleanup, o);
+
+ o->op->setup(o->in, o->out, o->ex);
+
+ pthread_create(&id, 0, runthread, o);
+
+ return TRUE;
+}
+
+
/* ** EDIT MESSAGES ******************************************************* */
typedef struct edit_messages_input_s {
diff --git a/mail/mail-tools.c b/mail/mail-tools.c
index 80e9638ce1..0014d48553 100644
--- a/mail/mail-tools.c
+++ b/mail/mail-tools.c
@@ -284,10 +284,10 @@ mail_tool_move_folder_contents (CamelFolder *source, CamelFolder *dest, gboolean
/* Copy the messages */
for (i = 0; i < uids->len; i++) {
CamelMimeMessage *msg;
- const CamelMessageInfo *info = NULL;
+ CamelMessageInfo *info = NULL;
const gboolean last_message = (i+1 == uids->len);
time_t now;
-
+
/* Info */
/*
@@ -317,6 +317,9 @@ mail_tool_move_folder_contents (CamelFolder *source, CamelFolder *dest, gboolean
if (summary_capability)
info = camel_folder_get_message_info (source, uids->pdata[i]);
camel_folder_append_message (dest, msg, info, ex);
+ if (summary_capability)
+ camel_folder_free_message_info(source, info);
+
if (camel_exception_is_set (ex)) {
camel_object_unref (CAMEL_OBJECT (msg));
goto cleanup;
diff --git a/mail/mail-view.c b/mail/mail-view.c
index 54ec02de32..cd18b4ff69 100644
--- a/mail/mail-view.c
+++ b/mail/mail-view.c
@@ -130,12 +130,7 @@ view_delete_msg (GtkWidget *button, gpointer user_data)
{
mail_view_data *data = (mail_view_data *) user_data;
- GPtrArray *uids;
-
- uids = g_ptr_array_new();
- g_ptr_array_add (uids, g_strdup (data->uid));
- mail_do_flag_messages (data->source, uids, TRUE,
- CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_DELETED);
+ camel_folder_set_message_flags(data->source, data->uid, CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_DELETED);
}
static void
diff --git a/mail/message-list.c b/mail/message-list.c
index bc33ae5237..c34b01c18f 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -330,7 +330,7 @@ get_message_uid (MessageList *message_list, int row)
/* Gets the CamelMessageInfo for the message displayed at the given
* view row.
*/
-static const CamelMessageInfo *
+static CamelMessageInfo *
get_message_info (MessageList *message_list, int row)
{
const char *uid;
@@ -364,7 +364,7 @@ message_list_select (MessageList *message_list, int base_row,
MessageListSelectDirection direction,
guint32 flags, guint32 mask)
{
- const CamelMessageInfo *info;
+ CamelMessageInfo *info;
int vrow, mrow, last;
ETable *et = message_list->table;
@@ -393,8 +393,10 @@ message_list_select (MessageList *message_list, int base_row,
if (info && (info->flags & mask) == flags) {
e_table_set_cursor_row (et, mrow);
gtk_signal_emit(GTK_OBJECT (message_list), message_list_signals [MESSAGE_SELECTED], camel_message_info_uid(info));
+ camel_folder_free_message_info(message_list->folder, info);
return;
}
+ camel_folder_free_message_info(message_list->folder, info);
vrow += direction;
}
@@ -402,6 +404,12 @@ message_list_select (MessageList *message_list, int base_row,
}
static void
+add_uid (MessageList *ml, const char *uid, gpointer data)
+{
+ g_ptr_array_add ((GPtrArray *) data, g_strdup (uid));
+}
+
+static void
message_list_drag_data_get (ETable *table,
int row,
int col,
@@ -412,7 +420,7 @@ message_list_drag_data_get (ETable *table,
gpointer user_data)
{
MessageList *mlist = (MessageList *) user_data;
- const CamelMessageInfo *minfo = get_message_info (mlist, row);
+ CamelMessageInfo *minfo;
GPtrArray *uids = NULL;
char *tmpl, *tmpdir, *filename, *subject;
@@ -433,14 +441,21 @@ message_list_drag_data_get (ETable *table,
g_free (tmpl);
return;
}
-
+
+ minfo = get_message_info (mlist, row);
+ if (minfo == NULL) {
+ g_warning("Row %d is invalid", row);
+ g_free(tmpl);
+ return;
+ }
subject = g_strdup (camel_message_info_subject (minfo));
+ camel_folder_free_message_info(mlist->folder, minfo);
e_filename_make_safe (subject);
filename = g_strdup_printf ("%s/%s.eml", tmpdir, subject);
g_free (subject);
uids = g_ptr_array_new ();
- g_ptr_array_add (uids, g_strdup (mlist->cursor_uid));
+ message_list_foreach (mlist, add_uid, uids);
mail_do_save_messages (mlist->folder, uids, filename);
@@ -646,7 +661,7 @@ ml_tree_icon_at (ETreeModel *etm, ETreePath *path, void *model_data)
static int
subtree_unread(MessageList *ml, ETreePath *node)
{
- const CamelMessageInfo *info;
+ CamelMessageInfo *info;
char *uid;
while (node) {
@@ -656,8 +671,11 @@ subtree_unread(MessageList *ml, ETreePath *node)
g_warning("I got a NULL uid at node %p", node);
} else if (id_is_uid(uid)
&& (info = camel_folder_get_message_info(ml->folder, id_uid(uid)))) {
- if (!(info->flags & CAMEL_MESSAGE_SEEN))
+ if (!(info->flags & CAMEL_MESSAGE_SEEN)) {
+ camel_folder_free_message_info(ml->folder, info);
return TRUE;
+ }
+ camel_folder_free_message_info(ml->folder, info);
}
if ((child = e_tree_model_node_get_first_child (E_TREE_MODEL (ml->table_model), node)))
if (subtree_unread(ml, child))
@@ -670,7 +688,7 @@ subtree_unread(MessageList *ml, ETreePath *node)
static int
subtree_size(MessageList *ml, ETreePath *node)
{
- const CamelMessageInfo *info;
+ CamelMessageInfo *info;
char *uid;
int size = 0;
@@ -682,6 +700,7 @@ subtree_size(MessageList *ml, ETreePath *node)
} else if (id_is_uid(uid)
&& (info = camel_folder_get_message_info(ml->folder, id_uid(uid)))) {
size += info->size;
+ camel_folder_free_message_info(ml->folder, info);
}
if ((child = e_tree_model_node_get_first_child (E_TREE_MODEL (ml->table_model), node)))
size += subtree_size(ml, child);
@@ -694,7 +713,7 @@ subtree_size(MessageList *ml, ETreePath *node)
static time_t
subtree_earliest(MessageList *ml, ETreePath *node, int sent)
{
- const CamelMessageInfo *info;
+ CamelMessageInfo *info;
char *uid;
time_t earliest = 0, date;
@@ -711,6 +730,7 @@ subtree_earliest(MessageList *ml, ETreePath *node, int sent)
date = info->date_received;
if (earliest == 0 || date < earliest)
earliest = date;
+ camel_folder_free_message_info(ml->folder, info);
}
if ((child = e_tree_model_node_get_first_child (E_TREE_MODEL (ml->table_model), node))) {
date = subtree_earliest(ml, child, sent);
@@ -728,9 +748,10 @@ static void *
ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data)
{
MessageList *message_list = model_data;
- const CamelMessageInfo *msg_info;
char *uid;
static char *saved;
+ CamelMessageInfo *info;
+ static CamelMessageInfo *msg_info;
/* simlated(tm) static dynamic memory (sigh) */
if (saved) {
@@ -748,10 +769,21 @@ ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data)
goto fake;
uid = id_uid(uid);
- msg_info = camel_folder_get_message_info (message_list->folder, uid);
- if (msg_info == NULL) {
- g_warning("UID for message-list not found in folder: %s", uid);
- return NULL;
+ /* we need ot keep the msg_info ref'd as we return the data, sigh.
+
+ Well, since we have it around, also check to see if its the same
+ one each call, and save the folder lookup */
+ if (msg_info == NULL || strcmp(camel_message_info_uid(msg_info), uid) != 0) {
+ /* FIXME: what if the folder changes? Nothing sets the folder
+ yet, but this probably means we need to cache this inside the ml itself */
+ if (msg_info)
+ camel_folder_free_message_info(message_list->folder, msg_info);
+
+ msg_info = camel_folder_get_message_info (message_list->folder, uid);
+ if (msg_info == NULL) {
+ g_warning("UID for message-list not found in folder: %s", uid);
+ return NULL;
+ }
}
switch (col){
@@ -856,9 +888,10 @@ ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data)
if ( (child = e_tree_model_node_get_first_child(etm, path))
&& (uid = e_tree_model_node_get_data (etm, child))
&& id_is_uid(uid)
- && (msg_info = camel_folder_get_message_info (message_list->folder, id_uid(uid))) ) {
+ && (info = camel_folder_get_message_info (message_list->folder, id_uid(uid))) ) {
/* well, we could scan more children, build up a (more accurate) list, but this should do ok */
- saved = g_strdup_printf(_("%s, et al."), camel_message_info_from(msg_info));
+ saved = g_strdup_printf(_("%s, et al."), camel_message_info_from(info));
+ camel_folder_free_message_info(message_list->folder, info);
} else {
return _("<unknown>");
}
@@ -871,9 +904,10 @@ ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data)
if ( (child = e_tree_model_node_get_first_child(etm, path))
&& (uid = e_tree_model_node_get_data (etm, child))
&& id_is_uid(uid)
- && (msg_info = camel_folder_get_message_info (message_list->folder, id_uid(uid))) ) {
+ && (info = camel_folder_get_message_info (message_list->folder, id_uid(uid))) ) {
/* well, we could scan more children, build up a (more accurate) list, but this should do ok */
- saved = g_strdup_printf(_("%s, et al."), camel_message_info_to(msg_info));
+ saved = g_strdup_printf(_("%s, et al."), camel_message_info_to(info));
+ camel_folder_free_message_info(message_list->folder, info);
} else {
return _("<unknown>");
}
@@ -1115,6 +1149,8 @@ message_list_init (GtkObject *object)
message_list->hidden_pool = NULL;
message_list->hide_before = ML_HIDE_NONE_START;
message_list->hide_after = ML_HIDE_NONE_END;
+
+ message_list->hide_lock = g_mutex_new();
}
static void
@@ -1139,7 +1175,6 @@ message_list_destroy (GtkObject *object)
if (message_list->seen_id)
gtk_timeout_remove (message_list->seen_id);
- mail_tool_camel_lock_up();
if (message_list->folder) {
camel_object_unhook_event((CamelObject *)message_list->folder, "folder_changed",
folder_changed, message_list);
@@ -1154,8 +1189,9 @@ message_list_destroy (GtkObject *object)
message_list->hidden = NULL;
message_list->hidden_pool = NULL;
}
- mail_tool_camel_lock_down();
+ g_mutex_free(message_list->hide_lock);
+
GTK_OBJECT_CLASS (message_list_parent_class)->destroy (object);
}
@@ -1291,7 +1327,7 @@ static void
save_node_state(MessageList *ml, FILE *out, ETreePath *node)
{
char *data;
- const CamelMessageInfo *info;
+ CamelMessageInfo *info;
while (node) {
ETreePath *child = e_tree_model_node_get_first_child (E_TREE_MODEL (ml->table_model), node);
@@ -1303,6 +1339,7 @@ save_node_state(MessageList *ml, FILE *out, ETreePath *node)
info = camel_folder_get_message_info(ml->folder, id_uid(data));
if (info) {
fprintf(out, "%08x%08x\n", info->message_id.id.part.hi, info->message_id.id.part.lo);
+ camel_folder_free_message_info(ml->folder, info);
}
} else {
fprintf(out, "%s\n", data);
@@ -1888,7 +1925,24 @@ main_folder_changed (CamelObject *o, gpointer event_data, gpointer user_data)
CamelFolderChangeInfo *changes = (CamelFolderChangeInfo *)event_data;
printf("folder changed event, changes = %p\n", changes);
+ if (changes) {
+ printf("changed = %d added = %d removed = %d\n",
+ changes->uid_changed->len, changes->uid_added->len, changes->uid_removed->len);
+ if (changes->uid_added->len == 0 && changes->uid_removed->len == 0) {
+ int i;
+
+ for (i=0;i<changes->uid_changed->len;i++) {
+ int row = GPOINTER_TO_INT (g_hash_table_lookup (ml->uid_rowmap, changes->uid_changed->pdata[i]));
+ if (row != -1)
+ e_table_model_row_changed(ml->table_model, row);
+ }
+
+ camel_folder_change_info_free(changes);
+ return;
+ }
+ }
+
mail_do_regenerate_messagelist(ml, ml->search, NULL, changes);
}
@@ -2010,7 +2064,7 @@ static gint
on_click (ETableScrolled *table, gint row, gint col, GdkEvent *event, MessageList *list)
{
int flag;
- const CamelMessageInfo *info;
+ CamelMessageInfo *info;
if (col == COL_MESSAGE_STATUS)
flag = CAMEL_MESSAGE_SEEN;
@@ -2019,17 +2073,13 @@ on_click (ETableScrolled *table, gint row, gint col, GdkEvent *event, MessageLis
else
return FALSE;
- mail_tool_camel_lock_up();
-
info = get_message_info(list, row);
if (info == NULL) {
- mail_tool_camel_lock_down();
return FALSE;
}
camel_folder_set_message_flags(list->folder, camel_message_info_uid(info), flag, ~info->flags);
-
- mail_tool_camel_lock_down();
+ camel_folder_free_message_info(list->folder, info);
if (flag == CAMEL_MESSAGE_SEEN && list->seen_id) {
gtk_timeout_remove (list->seen_id);
@@ -2118,12 +2168,14 @@ unsigned int message_list_length(MessageList *ml)
*/
void message_list_hide_add(MessageList *ml, const char *expr, unsigned int lower, unsigned int upper)
{
- mail_tool_camel_lock_up();
+ MESSAGE_LIST_LOCK(ml, hide_lock);
+
if (lower != ML_HIDE_SAME)
ml->hide_before = lower;
if (upper != ML_HIDE_SAME)
ml->hide_after = upper;
- mail_tool_camel_lock_down();
+
+ MESSAGE_LIST_UNLOCK(ml, hide_lock);
mail_do_regenerate_messagelist(ml, ml->search, expr, NULL);
}
@@ -2137,7 +2189,7 @@ void message_list_hide_uids(MessageList *ml, GPtrArray *uids)
/* first see if we need to do any work, if so, then do it all at once */
for (i=0;i<uids->len;i++) {
if (g_hash_table_lookup(ml->uid_rowmap, uids->pdata[i])) {
- mail_tool_camel_lock_up();
+ MESSAGE_LIST_LOCK(ml, hide_lock);
if (ml->hidden == NULL) {
ml->hidden = g_hash_table_new(g_str_hash, g_str_equal);
ml->hidden_pool = e_mempool_new(512, 256, E_MEMPOOL_ALIGN_BYTE);
@@ -2151,7 +2203,7 @@ void message_list_hide_uids(MessageList *ml, GPtrArray *uids)
g_hash_table_insert(ml->hidden, uid, uid);
}
}
- mail_tool_camel_lock_down();
+ MESSAGE_LIST_UNLOCK(ml, hide_lock);
mail_do_regenerate_messagelist(ml, ml->search, NULL, NULL);
break;
}
@@ -2161,7 +2213,7 @@ void message_list_hide_uids(MessageList *ml, GPtrArray *uids)
/* no longer hide any messages */
void message_list_hide_clear(MessageList *ml)
{
- mail_tool_camel_lock_up();
+ MESSAGE_LIST_LOCK(ml, hide_lock);
if (ml->hidden) {
g_hash_table_destroy(ml->hidden);
e_mempool_destroy(ml->hidden_pool);
@@ -2170,7 +2222,7 @@ void message_list_hide_clear(MessageList *ml)
}
ml->hide_before = ML_HIDE_NONE_START;
ml->hide_after = ML_HIDE_NONE_END;
- mail_tool_camel_lock_down();
+ MESSAGE_LIST_UNLOCK(ml, hide_lock);
mail_do_regenerate_messagelist(ml, ml->search, NULL, NULL);
}
@@ -2195,7 +2247,7 @@ static void hide_load_state(MessageList *ml)
if (in) {
camel_folder_summary_decode_fixed_int32(in, &version);
if (version == HIDE_STATE_VERSION) {
- mail_tool_camel_lock_up();
+ MESSAGE_LIST_LOCK(ml, hide_lock);
if (ml->hidden == NULL) {
ml->hidden = g_hash_table_new(g_str_hash, g_str_equal);
ml->hidden_pool = e_mempool_new(512, 256, E_MEMPOOL_ALIGN_BYTE);
@@ -2212,7 +2264,7 @@ static void hide_load_state(MessageList *ml)
g_hash_table_insert(ml->hidden, uid, uid);
}
}
- mail_tool_camel_lock_down();
+ MESSAGE_LIST_UNLOCK(ml, hide_lock);
}
fclose(in);
}
@@ -2231,8 +2283,9 @@ static void hide_save_state(MessageList *ml)
char *filename;
FILE *out;
+ MESSAGE_LIST_LOCK(ml, hide_lock);
+
filename = mail_config_folder_to_cachename(ml->folder, "hidestate-");
- mail_tool_camel_lock_up();
if (ml->hidden == NULL && ml->hide_before == ML_HIDE_NONE_START && ml->hide_after == ML_HIDE_NONE_END) {
unlink(filename);
} else if ( (out = fopen(filename, "w")) ) {
@@ -2243,11 +2296,11 @@ static void hide_save_state(MessageList *ml)
g_hash_table_foreach(ml->hidden, (GHFunc)hide_save_1, out);
fclose(out);
}
- mail_tool_camel_lock_down();
+
+ MESSAGE_LIST_UNLOCK(ml, hide_lock);
}
/* ** REGENERATE MESSAGELIST ********************************************** */
-
typedef struct regenerate_messagelist_input_s {
MessageList *ml;
CamelFolder *folder;
@@ -2297,8 +2350,6 @@ static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, Camel
int i;
GPtrArray *uids, *uidnew;
- mail_tool_camel_lock_up();
-
if (input->search) {
data->uids = camel_folder_search_by_expression(input->ml->folder, input->search, ex);
} else {
@@ -2306,7 +2357,6 @@ static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, Camel
}
if (camel_exception_is_set (ex)) {
- mail_tool_camel_lock_down();
return;
}
@@ -2317,6 +2367,8 @@ static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, Camel
camel_exception_clear(ex);
if (uidnew) {
+ MESSAGE_LIST_LOCK(input->ml, hide_lock);
+
if (input->ml->hidden == NULL) {
input->ml->hidden = g_hash_table_new(g_str_hash, g_str_equal);
input->ml->hidden_pool = e_mempool_new(512, 256, E_MEMPOOL_ALIGN_BYTE);
@@ -2328,10 +2380,15 @@ static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, Camel
g_hash_table_insert(input->ml->hidden, uid, uid);
}
}
+
+ MESSAGE_LIST_UNLOCK(input->ml, hide_lock);
+
camel_folder_search_free(input->ml->folder, uidnew);
}
}
+ MESSAGE_LIST_LOCK(input->ml, hide_lock);
+
input->ml->hide_unhidden = data->uids->len;
/* what semantics do we want from hide_before, hide_after?
@@ -2379,12 +2436,12 @@ static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, Camel
data->realuids = NULL;
}
+ MESSAGE_LIST_UNLOCK(input->ml, hide_lock);
+
if (input->dotree && data->uids)
data->tree = camel_folder_thread_messages_new(input->ml->folder, data->uids);
else
data->tree = NULL;
-
- mail_tool_camel_lock_down();
}
static void cleanup_regenerate_messagelist (gpointer in_data, gpointer op_data, CamelException *ex)
@@ -2392,9 +2449,6 @@ static void cleanup_regenerate_messagelist (gpointer in_data, gpointer op_data,
regenerate_messagelist_input_t *input = (regenerate_messagelist_input_t *) in_data;
regenerate_messagelist_data_t *data = (regenerate_messagelist_data_t *) op_data;
GPtrArray *uids;
- ETreeModel *etm;
-
- etm = E_TREE_MODEL (input->ml->table_model);
if (data->uids == NULL) { /*exception*/
gtk_object_unref (GTK_OBJECT (input->ml));
@@ -2470,5 +2524,7 @@ mail_do_regenerate_messagelist (MessageList *list, const gchar *search, const ch
input->changes = changes;
input->dotree = list->threaded;
- mail_operation_queue (&op_regenerate_messagelist, input, TRUE);
+ /* just a quick hack, so dont unwarn yet, or die */
+ mail_operation_run (&op_regenerate_messagelist, input, TRUE);
+ /*mail_operation_queue (&op_regenerate_messagelist, input, TRUE);*/
}
diff --git a/mail/message-list.h b/mail/message-list.h
index 8e150c8a3d..468f8cc3dc 100644
--- a/mail/message-list.h
+++ b/mail/message-list.h
@@ -2,7 +2,9 @@
#ifndef _MESSAGE_LIST_H_
#define _MESSAGE_LIST_H_
-#include <gnome.h>
+/*#include <gnome.h>*/
+#include <gtk/gtk.h>
+
#include "mail-types.h"
#include <gal/e-table/e-table-scrolled.h>
#include <gal/e-table/e-table-simple.h>
@@ -62,7 +64,7 @@ struct _MessageList {
struct _EMemPool *uid_pool;
/* UID's to hide. Keys in the mempool */
- /* IMPORTANT: You MUST have obtained the camel lock, to operate on these structures */
+ /* IMPORTANT: You MUST have obtained the hide lock, to operate on this data */
GHashTable *hidden;
struct _EMemPool *hidden_pool;
int hide_unhidden, /* total length, before hiding */
@@ -80,6 +82,9 @@ struct _MessageList {
/* Row-selection and seen-marking timers */
guint idle_id, seen_id;
+
+ /* locks */
+ GMutex *hide_lock; /* for any 'hide' info above */
};
typedef struct {
@@ -123,4 +128,7 @@ void message_list_hide_clear(MessageList *ml);
void message_list_set_threaded(MessageList *ml, gboolean threaded);
void message_list_set_search(MessageList *ml, const char *search);
+#define MESSAGE_LIST_LOCK(m, l) g_mutex_lock(((MessageList *)m)->l)
+#define MESSAGE_LIST_UNLOCK(m, l) g_mutex_unlock(((MessageList *)m)->l)
+
#endif /* _MESSAGE_LIST_H_ */