aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
Diffstat (limited to 'mail')
-rw-r--r--mail/ChangeLog41
-rw-r--r--mail/folder-browser.c162
-rw-r--r--mail/folder-browser.h5
-rw-r--r--mail/mail-callbacks.c83
-rw-r--r--mail/mail-vfolder.c5
-rw-r--r--mail/mail-vfolder.h2
6 files changed, 219 insertions, 79 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 9373a4c68c..96cc14e7d9 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,5 +1,46 @@
2002-03-26 Not Zed <NotZed@Ximian.com>
+ * mail-callbacks.c (addrbook_sender): Changed to get the address
+ from the messageinfo of the current selected message rather than
+ from the current_message.
+ (requeue_mail_reply): Only re-queue if we got a message, could
+ potentially cause an infinite loop trying to get a message it
+ can't.
+ (reply_to_sender, reply_to_list, reply_to_all): Always pass NULL
+ as the msg to mail_replay, this forces mail_reply to always load
+ the message anew. Fixes FIXME's and popup behaviour. Basically
+ this and stuff below fixes #8542. Its probably not the nicest
+ way, but it works.
+ (mark_as_important): Use the flags properly, we can set all flags
+ to any combination of on or off as we want, so we just need to
+ call set_flags once, thats why its set flags and not set_option.
+ (toggle_flags): Fixed the logic here also, so we dont have to call
+ set_message_flags more than once, and also implement a true toggle
+ for any number of simultaneous flags (whilst simplifying code).
+
+ * mail-vfolder.c (vfolder_gui_add_from_mlist): Removed the 'msg'
+ parameter, its not used, fixed callers.
+
+ * folder-browser.c (on_right_click): Lookup the mlist from
+ messageinfo, and change the 'no selected' logic slightly, fixes
+ most of #8542.
+ (filter_data_free): Free filter data struct.
+ (vfolder_type_got_message): Actually create vfolder once we have
+ the message we need to use for it. Code could probably be changed
+ to use messageinfo instead.
+ (vfolder_type_uid): Lookup a message based on uid, and use that to
+ create a vfolder based on type.
+ (vfolder_subject_uid, vfolder_sender_uid, vfolder_receipient_uid,
+ vfolder_mlist_uid): Callbacks for the popup menu, used to create
+ rules based on the uid rather than the message, which it loads as
+ required.
+ (filter_type_got_message, filter_*_uid): Similar to vfolder
+ stuff above.
+ (filter_menu[]): Changed callbacks to popup specific ones, not
+ folderbrowser specific ones used by bonobo.
+ (on_right_click): Initialise callback data for the filter submenu
+ so it can look up messages for callback implementation.
+
* local-config.glade: New version from anna, with fixed widget
names.
diff --git a/mail/folder-browser.c b/mail/folder-browser.c
index 24f3b12a8c..afa530b11a 100644
--- a/mail/folder-browser.c
+++ b/mail/folder-browser.c
@@ -1273,6 +1273,7 @@ folder_browser_charset_changed (BonoboUIComponent *component,
}
}
+/* external api to vfolder/filter on X, based on current message */
void
vfolder_subject (GtkWidget *w, FolderBrowser *fb)
{
@@ -1301,7 +1302,7 @@ vfolder_mlist (GtkWidget *w, FolderBrowser *fb)
name = header_raw_check_mailing_list(&((CamelMimePart *)fb->mail_display->current_message)->headers);
if (name) {
g_strstrip (name);
- vfolder_gui_add_from_mlist(fb->mail_display->current_message, name, fb->uri);
+ vfolder_gui_add_from_mlist(name, fb->uri);
g_free(name);
}
}
@@ -1338,6 +1339,84 @@ filter_mlist (GtkWidget *w, FolderBrowser *fb)
}
}
+/* ************************************************************ */
+
+/* popup api to vfolder/filter on X, based on current selection */
+struct _filter_data {
+ CamelFolder *folder;
+ char *uid;
+ int type;
+ char *uri;
+ char *mlist;
+};
+
+static void
+filter_data_free(struct _filter_data *fdata)
+{
+ g_free(fdata->uid);
+ g_free(fdata->uri);
+ if (fdata->folder)
+ camel_object_unref((CamelObject *)fdata->folder);
+ g_free(fdata->mlist);
+ g_free(fdata);
+}
+
+static void
+vfolder_type_got_message(CamelFolder *folder, char *uid, CamelMimeMessage *msg, void *d)
+{
+ struct _filter_data *data = d;
+
+ if (msg)
+ vfolder_gui_add_from_message(msg, data->type, data->uri);
+
+ filter_data_free(data);
+}
+
+static void
+vfolder_type_uid(struct _filter_data *fdata, int type)
+{
+ struct _filter_data *data;
+
+ /* sigh, we need to copy this because the menu will free the one we got passed in */
+ data = g_malloc0(sizeof(*data));
+ data->type = type;
+ data->uri = fdata->uri;
+ fdata->uri = NULL;
+ mail_get_message(fdata->folder, fdata->uid, vfolder_type_got_message, data, mail_thread_new);
+}
+
+static void vfolder_subject_uid (GtkWidget *w, struct _filter_data *fdata) { vfolder_type_uid(fdata, AUTO_SUBJECT); }
+static void vfolder_sender_uid(GtkWidget *w, struct _filter_data *fdata) { vfolder_type_uid(fdata, AUTO_FROM); }
+static void vfolder_recipient_uid(GtkWidget *w, struct _filter_data *fdata) { vfolder_type_uid(fdata, AUTO_TO); }
+static void vfolder_mlist_uid(GtkWidget *w, struct _filter_data *fdata) { vfolder_gui_add_from_mlist(fdata->mlist, fdata->uri); }
+
+static void
+filter_type_got_message(CamelFolder *folder, char *uid, CamelMimeMessage *msg, void *d)
+{
+ struct _filter_data *data = d;
+
+ if (msg)
+ filter_gui_add_from_message(msg, data->type);
+
+ filter_data_free(data);
+}
+
+static void
+filter_type_uid(struct _filter_data *fdata, int type)
+{
+ struct _filter_data *data;
+
+ /* sigh, we need to copy this because the menu will free the one we got passed in */
+ data = g_malloc0(sizeof(*data));
+ data->type = type;
+ mail_get_message(fdata->folder, fdata->uid, filter_type_got_message, data, mail_thread_new);
+}
+
+static void filter_subject_uid (GtkWidget *w, struct _filter_data *fdata) { filter_type_uid(fdata, AUTO_SUBJECT); }
+static void filter_sender_uid(GtkWidget *w, struct _filter_data *fdata) { filter_type_uid(fdata, AUTO_FROM); }
+static void filter_recipient_uid(GtkWidget *w, struct _filter_data *fdata) { filter_type_uid(fdata, AUTO_TO); }
+static void filter_mlist_uid(GtkWidget *w, struct _filter_data *fdata) { filter_gui_add_from_mlist(fdata->mlist); }
+
void
hide_none(GtkWidget *w, FolderBrowser *fb)
{
@@ -1493,17 +1572,17 @@ enum {
#define MLIST_FILTER (8)
static EPopupMenu filter_menu[] = {
- { N_("VFolder on _Subject"), NULL, GTK_SIGNAL_FUNC (vfolder_subject), NULL, NULL, SELECTION_SET },
- { N_("VFolder on Se_nder"), NULL, GTK_SIGNAL_FUNC (vfolder_sender), NULL, NULL, SELECTION_SET },
- { N_("VFolder on _Recipients"), NULL, GTK_SIGNAL_FUNC (vfolder_recipient), NULL, NULL, SELECTION_SET },
- { N_("VFolder on Mailing _List"), NULL, GTK_SIGNAL_FUNC (vfolder_mlist), NULL, NULL, SELECTION_SET | IS_MAILING_LIST },
+ { N_("VFolder on _Subject"), NULL, GTK_SIGNAL_FUNC (vfolder_subject_uid), NULL, NULL, SELECTION_SET },
+ { N_("VFolder on Se_nder"), NULL, GTK_SIGNAL_FUNC (vfolder_sender_uid), NULL, NULL, SELECTION_SET },
+ { N_("VFolder on _Recipients"), NULL, GTK_SIGNAL_FUNC (vfolder_recipient_uid), NULL, NULL, SELECTION_SET },
+ { N_("VFolder on Mailing _List"), NULL, GTK_SIGNAL_FUNC (vfolder_mlist_uid), NULL, NULL, SELECTION_SET | IS_MAILING_LIST },
E_POPUP_SEPARATOR,
- { N_("Filter on Sub_ject"), NULL, GTK_SIGNAL_FUNC (filter_subject), NULL, NULL, SELECTION_SET },
- { N_("Filter on Sen_der"), NULL, GTK_SIGNAL_FUNC (filter_sender), NULL, NULL, SELECTION_SET },
- { N_("Filter on Re_cipients"), NULL, GTK_SIGNAL_FUNC (filter_recipient), NULL, NULL, SELECTION_SET },
- { N_("Filter on _Mailing List"), NULL, GTK_SIGNAL_FUNC (filter_mlist), NULL, NULL, SELECTION_SET | IS_MAILING_LIST },
+ { N_("Filter on Sub_ject"), NULL, GTK_SIGNAL_FUNC (filter_subject_uid), NULL, NULL, SELECTION_SET },
+ { N_("Filter on Sen_der"), NULL, GTK_SIGNAL_FUNC (filter_sender_uid), NULL, NULL, SELECTION_SET },
+ { N_("Filter on Re_cipients"), NULL, GTK_SIGNAL_FUNC (filter_recipient_uid), NULL, NULL, SELECTION_SET },
+ { N_("Filter on _Mailing List"), NULL, GTK_SIGNAL_FUNC (filter_mlist_uid), NULL, NULL, SELECTION_SET | IS_MAILING_LIST },
E_POPUP_TERMINATOR
};
@@ -1683,33 +1762,15 @@ on_right_click (ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event
int i;
char *mlist = NULL;
GtkMenu *menu;
+ struct _filter_data *fdata = NULL;
if (fb->folder != sent_folder) {
enable_mask |= CAN_RESEND;
hide_mask |= CAN_RESEND;
}
-
- if (fb->mail_display->current_message == NULL) {
- enable_mask |= SELECTION_SET;
- } else {
- char *mname, *p, c, *o;
-
- mname = header_raw_check_mailing_list (&((CamelMimePart *)fb->mail_display->current_message)->headers);
- /* Escape the mailing list name before showing it */
- if (mname) {
- mlist = alloca (strlen (mname)+2);
- p = mname;
- o = mlist;
- while ((c = *p++)) {
- if (c == '_')
- *o++ = '_';
- *o++ = c;
- }
- *o = 0;
- g_free (mname);
- }
- }
-
+
+ enable_mask |= SELECTION_SET;
+
/* get a list of uids */
uids = g_ptr_array_new ();
message_list_foreach (fb->message_list, enumerate_msg, uids);
@@ -1731,6 +1792,35 @@ on_right_click (ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event
info = camel_folder_get_message_info (fb->folder, uids->pdata[i]);
if (info == NULL)
continue;
+
+ if (i == 0 && uids->len == 1) {
+ const char *mname, *p;
+ char c, *o;
+
+ /* used by filter/vfolder from X callbacks */
+ fdata = g_malloc0(sizeof(*fdata));
+ fdata->uid = g_strdup(uids->pdata[i]);
+ fdata->uri = g_strdup(fb->uri);
+ fdata->folder = fb->folder;
+ camel_object_ref((CamelObject *)fdata->folder);
+
+ enable_mask &= ~SELECTION_SET;
+ mname = camel_message_info_mlist(info);
+ if (mname && mname[0]) {
+ fdata->mlist = g_strdup(mname);
+
+ /* Escape the mailing list name before showing it */
+ mlist = alloca (strlen (mname)+2);
+ p = mname;
+ o = mlist;
+ while ((c = *p++)) {
+ if (c == '_')
+ *o++ = '_';
+ *o++ = c;
+ }
+ *o = 0;
+ }
+ }
if (info->flags & CAMEL_MESSAGE_SEEN)
have_seen = TRUE;
@@ -1874,12 +1964,16 @@ on_right_click (ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event
}
setup_popup_icons ();
+
+ for (i=0;i<sizeof(filter_menu)/sizeof(filter_menu[0]);i++)
+ filter_menu[i].closure = fdata;
menu = e_popup_menu_create (context_menu, enable_mask, hide_mask, fb);
e_auto_kill_popup_menu_on_hide (menu);
- gtk_object_set_data_full (GTK_OBJECT (menu), "colour_closures",
- (GtkDestroyNotify) closures, colour_closures_free);
+ gtk_object_set_data_full (GTK_OBJECT (menu), "colour_closures", closures, (GtkDestroyNotify)colour_closures_free);
+ if (fdata)
+ gtk_object_set_data_full(GTK_OBJECT(menu), "filter_data", fdata, (GtkDestroyNotify)filter_data_free);
if (event->type == GDK_KEY_PRESS) {
struct cmpf_data closure;
@@ -1901,7 +1995,7 @@ on_right_click (ETree *tree, gint row, ETreePath path, gint col, GdkEvent *event
for (i = 0; i < 5; i++) {
g_free (label_menu[i + 2].name);
}
-
+
return TRUE;
}
diff --git a/mail/folder-browser.h b/mail/folder-browser.h
index 5b21efc036..464f1414f6 100644
--- a/mail/folder-browser.h
+++ b/mail/folder-browser.h
@@ -57,7 +57,7 @@ struct _FolderBrowser {
char *new_uid; /* place to save the next uid during idle timeout */
char *loaded_uid; /* what we have loaded */
guint loading_id, seen_id;
-
+
/* a folder we are expunging, dont use other than to compare the pointer value */
CamelFolder *expunging;
@@ -89,6 +89,9 @@ struct _FolderBrowser {
struct _MailAsyncEvent *async_event;
int get_id; /* for getting folder op */
+
+ /* info used by popup for filter/vfolder */
+ struct _popup_filter_data *popup;
};
typedef struct {
diff --git a/mail/mail-callbacks.c b/mail/mail-callbacks.c
index 1dfffd2fbb..736002c915 100644
--- a/mail/mail-callbacks.c
+++ b/mail/mail-callbacks.c
@@ -1029,7 +1029,8 @@ requeue_mail_reply (CamelFolder *folder, char *uid, CamelMimeMessage *msg, void
{
int mode = GPOINTER_TO_INT (data);
- mail_reply (folder, msg, uid, mode);
+ if (msg != NULL)
+ mail_reply (folder, msg, uid, mode);
}
void
@@ -1076,13 +1077,10 @@ reply_to_sender (GtkWidget *widget, gpointer user_data)
{
FolderBrowser *fb = FOLDER_BROWSER (user_data);
- /* FIXME: make this always load the message based on cursor */
-
if (FOLDER_BROWSER_IS_DESTROYED (fb) || !check_send_configuration (fb))
return;
- mail_reply (fb->folder, fb->mail_display->current_message,
- fb->message_list->cursor_uid, REPLY_SENDER);
+ mail_reply(fb->folder, NULL, fb->message_list->cursor_uid, REPLY_SENDER);
}
void
@@ -1093,10 +1091,7 @@ reply_to_list (GtkWidget *widget, gpointer user_data)
if (FOLDER_BROWSER_IS_DESTROYED (fb) || !check_send_configuration (fb))
return;
- /* FIXME: make this always load the message based on cursor */
-
- mail_reply (fb->folder, fb->mail_display->current_message,
- fb->message_list->cursor_uid, REPLY_LIST);
+ mail_reply (fb->folder, NULL, fb->message_list->cursor_uid, REPLY_LIST);
}
void
@@ -1107,10 +1102,7 @@ reply_to_all (GtkWidget *widget, gpointer user_data)
if (FOLDER_BROWSER_IS_DESTROYED (fb) || !check_send_configuration (fb))
return;
- /* FIXME: make this always load the message based on cursor */
-
- mail_reply (fb->folder, fb->mail_display->current_message,
- fb->message_list->cursor_uid, REPLY_ALL);
+ mail_reply(fb->folder, NULL, fb->message_list->cursor_uid, REPLY_ALL);
}
void
@@ -1502,27 +1494,26 @@ void
addrbook_sender (GtkWidget *widget, gpointer user_data)
{
FolderBrowser *fb = FOLDER_BROWSER (user_data);
- CamelMimeMessage *msg = NULL;
- const CamelInternetAddress *addr;
- gchar *addr_str;
+ const char *addr_str;
+ CamelMessageInfo *info;
GtkWidget *win;
GtkWidget *control;
GtkWidget *socket;
-
- /* FIXME: make this use the cursor message id */
-
+ GPtrArray *uids;
+ int i;
+
if (FOLDER_BROWSER_IS_DESTROYED (fb))
return;
-
- msg = fb->mail_display->current_message;
- if (msg == NULL)
- return;
-
- addr = camel_mime_message_get_from (msg);
- if (addr == NULL)
- return;
-
- addr_str = camel_address_format (CAMEL_ADDRESS (addr));
+
+ uids = g_ptr_array_new();
+ message_list_foreach(fb->message_list, enumerate_msg, uids);
+ if (uids->len != 1)
+ goto done;
+
+ info = camel_folder_get_message_info(fb->folder, uids->pdata[0]);
+ if (info == NULL
+ || (addr_str = camel_message_info_from(info)) == NULL)
+ goto done;
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (win), _("Sender"));
@@ -1544,6 +1535,11 @@ addrbook_sender (GtkWidget *widget, gpointer user_data)
gtk_container_add (GTK_CONTAINER (win), control);
gtk_widget_show_all (win);
+
+done:
+ for (i=0; i < uids->len; i++)
+ g_free(uids->pdata[i]);
+ g_ptr_array_free(uids, TRUE);
}
void
@@ -1712,18 +1708,24 @@ toggle_flags (FolderBrowser *fb, guint32 mask)
message_list_foreach (fb->message_list, enumerate_msg, uids);
camel_folder_freeze (fb->folder);
for (i = 0; i < uids->len; i++) {
- int flags;
-
- flags = camel_folder_get_message_flags (fb->folder, uids->pdata[i]);
+ guint32 flags;
- if (flags & mask)
- camel_folder_set_message_flags (fb->folder, uids->pdata[i], mask, 0);
- else {
- if ((mask & CAMEL_MESSAGE_FLAGGED) && (flags & CAMEL_MESSAGE_DELETED))
- camel_folder_set_message_flags (fb->folder, uids->pdata[i], CAMEL_MESSAGE_DELETED, 0);
- camel_folder_set_message_flags (fb->folder, uids->pdata[i], mask, mask);
+ flags = ~(camel_folder_get_message_flags (fb->folder, uids->pdata[i]));
+
+ /* if we're flagging a message important, always undelete it too */
+ if (mask & flags & CAMEL_MESSAGE_FLAGGED) {
+ flags &= ~CAMEL_MESSAGE_DELETED;
+ mask |= CAMEL_MESSAGE_DELETED;
}
-
+
+ /* if we're flagging a message deleted, always mark it seen too */
+ if (mask & flags & CAMEL_MESSAGE_DELETED) {
+ flags |= CAMEL_MESSAGE_SEEN;
+ mask |= CAMEL_MESSAGE_SEEN;
+ }
+
+ camel_folder_set_message_flags (fb->folder, uids->pdata[i], mask, flags);
+
g_free (uids->pdata[i]);
}
camel_folder_thaw (fb->folder);
@@ -1777,8 +1779,7 @@ mark_all_as_seen (BonoboUIComponent *uih, void *user_data, const char *path)
void
mark_as_important (BonoboUIComponent *uih, void *user_data, const char *path)
{
- flag_messages (FOLDER_BROWSER (user_data), CAMEL_MESSAGE_DELETED, 0);
- flag_messages (FOLDER_BROWSER (user_data), CAMEL_MESSAGE_FLAGGED, CAMEL_MESSAGE_FLAGGED);
+ flag_messages (FOLDER_BROWSER (user_data), CAMEL_MESSAGE_FLAGGED|CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_FLAGGED);
}
void
diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c
index 44d0556fee..0c2ee4e2f7 100644
--- a/mail/mail-vfolder.c
+++ b/mail/mail-vfolder.c
@@ -919,11 +919,12 @@ vfolder_gui_add_from_message(CamelMimeMessage *msg, int flags, const char *sourc
}
void
-vfolder_gui_add_from_mlist(CamelMimeMessage *msg, const char *mlist, const char *source)
+vfolder_gui_add_from_mlist(const char *mlist, const char *source)
{
VfolderRule *rule;
- g_return_if_fail (msg != NULL);
+ g_return_if_fail (mlist != NULL);
+ g_return_if_fail (source != NULL);
rule = (VfolderRule*)vfolder_rule_from_mlist(context, mlist, source);
vfolder_gui_add_rule(rule);
diff --git a/mail/mail-vfolder.h b/mail/mail-vfolder.h
index 9561185c4a..6de0ff52b6 100644
--- a/mail/mail-vfolder.h
+++ b/mail/mail-vfolder.h
@@ -19,7 +19,7 @@ FilterPart *vfolder_create_part (const char *name);
FilterRule *vfolder_clone_rule (FilterRule *in);
void vfolder_gui_add_rule (VfolderRule *rule);
void vfolder_gui_add_from_message (CamelMimeMessage *msg, int flags, const char *source);
-void vfolder_gui_add_from_mlist (CamelMimeMessage *msg, const char *mlist, const char *source);
+void vfolder_gui_add_from_mlist (const char *mlist, const char *source);
/* add a uri that is now (un)available to vfolders in a transient manner */
void mail_vfolder_add_uri(CamelStore *store, const char *uri, int remove);