aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog16
-rw-r--r--mail/mail-ops.c84
-rw-r--r--mail/message-list.c105
-rw-r--r--mail/message-list.h5
4 files changed, 150 insertions, 60 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 27ea9425d3..fbd959274f 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,19 @@
+2000-06-16 Dan Winship <danw@helixcode.com>
+
+ * message-list.c (get_message_row): new function to do a uid to
+ row mapping.
+ (mark_msg_seen, select_msg, message_changed,
+ message_list_set_folder): Update for Camel flag changes.
+ (on_cursor_change_cmd): Rename "row_to_select" to "selected_row",
+ and keep a "selected_uid" as well.
+
+ * mail-ops.c (composer_send_cb): Update for Camel flag changes,
+ and fix some memory-handling bugs. (Free the post_send_data when
+ the composer is destroyed, not when the user clicks "send", which
+ could happen never, or more than once.)
+ (delete_msg): Update for Camel flag changes, and fix the "holding
+ down the delete key skips some messages" bug.
+
2000-06-15 Dan Winship <danw@helixcode.com>
* mail-ops.c (fetch_mail):
diff --git a/mail/mail-ops.c b/mail/mail-ops.c
index 81cb5ae139..c28c4a0de6 100644
--- a/mail/mail-ops.c
+++ b/mail/mail-ops.c
@@ -271,7 +271,8 @@ fetch_mail (GtkWidget *button, gpointer user_data)
struct post_send_data {
- CamelMimeMessage *message;
+ CamelFolder *folder;
+ const char *uid;
guint32 flags;
};
@@ -321,7 +322,7 @@ composer_send_cb (EMsgComposer *composer, gpointer data)
mail_exception_dialog ("Could not load mail transport",
ex, composer);
camel_exception_free (ex);
- goto free_psd;
+ return;
}
}
@@ -340,26 +341,29 @@ composer_send_cb (EMsgComposer *composer, gpointer data)
if (camel_exception_is_set (ex))
mail_exception_dialog ("Could not send message", ex, composer);
else {
- gtk_object_destroy (GTK_OBJECT (composer));
if (psd) {
guint32 set;
- set = camel_mime_message_get_flags (psd->message);
- camel_mime_message_set_flags (psd->message,
- psd->flags, ~set);
+ set = camel_folder_get_message_flags (psd->folder,
+ psd->uid, ex);
+ camel_folder_set_message_flags (psd->folder, psd->uid,
+ psd->flags, ~set, ex);
}
+ gtk_object_destroy (GTK_OBJECT (composer));
}
camel_exception_free (ex);
gtk_object_unref (GTK_OBJECT (message));
-
- free_psd:
- if (psd) {
- gtk_object_unref (GTK_OBJECT (psd->message));
- g_free (psd);
- }
}
+static void
+free_psd (GtkWidget *composer, gpointer user_data)
+{
+ struct post_send_data *psd = user_data;
+
+ gtk_object_unref (GTK_OBJECT (psd->folder));
+ g_free (psd);
+}
void
send_msg (GtkWidget *widget, gpointer user_data)
@@ -402,14 +406,18 @@ reply (FolderBrowser *fb, gboolean to_all)
return;
psd = g_new (struct post_send_data, 1);
- psd->message = fb->mail_display->current_message;
- gtk_object_ref (GTK_OBJECT (psd->message));
+ psd->folder = fb->folder;
+ gtk_object_ref (GTK_OBJECT (psd->folder));
+ psd->uid = fb->message_list->selected_uid;
psd->flags = CAMEL_MESSAGE_ANSWERED;
- composer = mail_generate_reply (psd->message, to_all);
+ composer = mail_generate_reply (fb->mail_display->current_message,
+ to_all);
gtk_signal_connect (GTK_OBJECT (composer), "send",
GTK_SIGNAL_FUNC (composer_send_cb), psd);
+ gtk_signal_connect (GTK_OBJECT (composer), "destroy",
+ GTK_SIGNAL_FUNC (free_psd), psd);
gtk_widget_show (GTK_WIDGET (composer));
}
@@ -450,25 +458,35 @@ void
delete_msg (GtkWidget *button, gpointer user_data)
{
FolderBrowser *fb = user_data;
- int row;
-
- if (fb->mail_display->current_message) {
- guint32 flags;
-
- /* FIXME: table should watch the message with a signal and update display! */
-
- flags = camel_mime_message_get_flags(fb->mail_display->current_message);
- camel_mime_message_set_flags(fb->mail_display->current_message, CAMEL_MESSAGE_DELETED, ~flags);
- printf("Message %s set to %s\n", fb->mail_display->current_message->message_uid,
- flags&CAMEL_MESSAGE_DELETED ? "UNDELETED" : "DELETED");
-
-
- /* Move the cursor down a row... FIXME: should skip other
- * deleted messages.
- */
- row = e_table_get_selected_view_row (E_TABLE (fb->message_list->etable));
- e_table_select_row (E_TABLE (fb->message_list->etable), row + 1);
+ MessageList *ml = fb->message_list;
+ CamelException ex;
+ guint32 flags;
+
+ if (!fb->mail_display->current_message)
+ return;
+
+ camel_exception_init (&ex);
+
+ flags = camel_folder_get_message_flags (fb->folder, ml->selected_uid,
+ &ex);
+ if (!camel_exception_is_set (&ex)) {
+ /* Toggle the deleted flag without touching other flags. */
+ camel_folder_set_message_flags (fb->folder, ml->selected_uid,
+ CAMEL_MESSAGE_DELETED,
+ ~flags, &ex);
}
+
+ if (camel_exception_is_set (&ex)) {
+ mail_exception_dialog ("Could not toggle deleted flag",
+ &ex, fb);
+ camel_exception_clear (&ex);
+ return;
+ }
+
+ /* Move the cursor down a row... FIXME: should skip other
+ * deleted messages.
+ */
+ e_table_select_row (E_TABLE (ml->etable), ml->selected_row + 1);
}
void
diff --git a/mail/message-list.c b/mail/message-list.c
index 05db369fc7..5032e7c6af 100644
--- a/mail/message-list.c
+++ b/mail/message-list.c
@@ -61,7 +61,8 @@ select_row (ETable *table,
gpointer user_data);
-static CamelMessageInfo *get_message_info(MessageList *message_list, gint row)
+static CamelMessageInfo *
+get_message_info(MessageList *message_list, gint row)
{
CamelMessageInfo *info = NULL;
@@ -84,27 +85,53 @@ static CamelMessageInfo *get_message_info(MessageList *message_list, gint row)
return info;
}
-static void
-message_changed (CamelMimeMessage *m, enum _MessageChangeType type,
- MessageList *message_list)
+static int
+get_message_row (MessageList *message_list, const char *uid)
{
- guint row = GPOINTER_TO_UINT (gtk_object_get_data (GTK_OBJECT (m),
- "row"));
+ CamelMessageInfo *info;
+ int row;
+
+ if (message_list->search) {
+ GList *l;
+
+ /* Yum. Linear search. See also "FIXME: This should use
+ * a better format" in message-list.h
+ */
+ for (l = message_list->matches, row = 0; l; l = l->next, row++) {
+ if (!strcmp (uid, l->data))
+ return row;
+ }
+ } else {
+ gpointer key, value;
+
+ if (g_hash_table_lookup_extended (message_list->uid_rowmap,
+ uid, &key, &value))
+ return GPOINTER_TO_INT (value);
- e_table_model_row_changed (message_list->table_model, row);
+ row = g_hash_table_size (message_list->uid_rowmap);
+ for (; row < message_list->summary_table->len; row++) {
+ info = message_list->summary_table->pdata[row];
+ g_hash_table_insert (message_list->uid_rowmap,
+ info->uid, GINT_TO_POINTER (row));
+ if (!strcmp (uid, info->uid))
+ return row;
+ }
+ }
+
+ return -1;
}
static gint
mark_msg_seen (gpointer data)
{
- CamelMimeMessage *msg = data;
+ MessageList *ml = data;
guint32 flags;
- g_return_val_if_fail (CAMEL_IS_MIME_MESSAGE (msg), FALSE);
-
- flags = camel_mime_message_get_flags (msg);
- camel_mime_message_set_flags (msg, CAMEL_MESSAGE_SEEN,
- CAMEL_MESSAGE_SEEN);
+ flags = camel_folder_get_message_flags (ml->folder, ml->selected_uid,
+ NULL);
+ camel_folder_set_message_flags (ml->folder, ml->selected_uid,
+ CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN,
+ NULL);
return FALSE;
}
@@ -115,7 +142,6 @@ select_msg (MessageList *message_list, gint row)
CamelException ex;
CamelMimeMessage *message = NULL;
CamelMessageInfo *msg_info;
- static guint timeout;
camel_exception_init (&ex);
@@ -132,16 +158,16 @@ select_msg (MessageList *message_list, gint row)
}
if (message) {
+ static guint timeout;
+
if (timeout)
gtk_timeout_remove (timeout);
- gtk_object_set_data (GTK_OBJECT (message), "row",
- GUINT_TO_POINTER (row));
- gtk_signal_connect(GTK_OBJECT (message), "message_changed",
- message_changed, message_list);
+
mail_display_set_message (message_list->parent_folder_browser->mail_display,
CAMEL_MEDIUM (message));
- timeout = gtk_timeout_add (1500, mark_msg_seen, message);
gtk_object_unref (GTK_OBJECT (message));
+
+ timeout = gtk_timeout_add (1500, mark_msg_seen, message_list);
}
}
@@ -684,6 +710,8 @@ message_list_destroy (GtkObject *object)
g_ptr_array_free(message_list->summary_search_cache, TRUE);
if (message_list->summary_table)
camel_folder_free_summary(message_list->folder, message_list->summary_table);
+ if (message_list->uid_rowmap)
+ g_hash_table_destroy(message_list->uid_rowmap);
for (i = 0; i < COL_LAST; i++)
gtk_object_unref (GTK_OBJECT (message_list->table_cols [i]));
@@ -837,13 +865,29 @@ message_list_set_search (MessageList *message_list, const char *search)
static void
folder_changed(CamelFolder *f, int type, MessageList *message_list)
{
+ int row;
+
if (message_list->summary_table)
camel_folder_free_summary(f, message_list->summary_table);
message_list->summary_table = camel_folder_get_summary (f, NULL);
+ if (message_list->uid_rowmap)
+ g_hash_table_destroy(message_list->uid_rowmap);
+ message_list->uid_rowmap = g_hash_table_new (g_str_hash, g_str_equal);
+
message_list_set_search(message_list, message_list->search);
}
+static void
+message_changed (CamelFolder *f, const char *uid, MessageList *message_list)
+{
+ int row;
+
+ row = get_message_row (message_list, uid);
+ if (row != -1)
+ e_table_model_row_changed (message_list->table_model, row);
+}
+
void
message_list_set_folder (MessageList *message_list, CamelFolder *camel_folder)
{
@@ -863,7 +907,9 @@ message_list_set_folder (MessageList *message_list, CamelFolder *camel_folder)
if (message_list->summary_table)
camel_folder_free_summary(message_list->folder, message_list->summary_table);
-
+ if (message_list->uid_rowmap)
+ g_hash_table_destroy(message_list->uid_rowmap);
+
camel_exception_init (&ex);
if (message_list->folder)
@@ -871,13 +917,14 @@ message_list_set_folder (MessageList *message_list, CamelFolder *camel_folder)
message_list->folder = camel_folder;
- gtk_signal_connect((GtkObject *)camel_folder, "folder_changed", folder_changed, message_list);
+ gtk_signal_connect(GTK_OBJECT (camel_folder), "folder_changed",
+ folder_changed, message_list);
+ gtk_signal_connect(GTK_OBJECT (camel_folder), "message_changed",
+ message_changed, message_list);
gtk_object_ref (GTK_OBJECT (camel_folder));
- message_list->summary_table = camel_folder_get_summary (message_list->folder, NULL);
-
- message_list_set_search(message_list, message_list->search);
+ folder_changed (camel_folder, 0, message_list);
select_msg (message_list, 0);
}
@@ -895,7 +942,7 @@ on_cursor_change_idle (gpointer data)
{
MessageList *message_list = data;
- select_msg (message_list, message_list->row_to_select);
+ select_msg (message_list, message_list->selected_row);
message_list->idle_id = 0;
return FALSE;
@@ -907,10 +954,16 @@ on_cursor_change_cmd (ETable *table,
gpointer user_data)
{
MessageList *message_list;
+ CamelMessageInfo *info;
message_list = MESSAGE_LIST (user_data);
- message_list->row_to_select = row;
+ info = get_message_info (message_list, row);
+ if (!info)
+ return;
+
+ message_list->selected_row = row;
+ message_list->selected_uid = info->uid;
if (!message_list->idle_id)
message_list->idle_id = g_idle_add_full (G_PRIORITY_LOW, on_cursor_change_idle, message_list, NULL);
diff --git a/mail/message-list.h b/mail/message-list.h
index 971aa6c37a..f40263407d 100644
--- a/mail/message-list.h
+++ b/mail/message-list.h
@@ -65,6 +65,7 @@ struct _MessageList {
CamelFolder *folder;
GPtrArray *summary_table; /* the summary of all messages */
+ GHashTable *uid_rowmap;
char *search; /* search string */
/* FIXME: This should use a better format ... */
@@ -72,8 +73,10 @@ struct _MessageList {
int match_count;
GPtrArray *summary_search_cache; /* summary info cache for searches */
+ int selected_row;
+ const char *selected_uid;
+
/* used by the idle-call to select a row */
- int row_to_select;
guint idle_id;
} ;