Changed to get the address from the messageinfo of the current selected

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.

svn path=/trunk/; revision=16253
This commit is contained in:
Not Zed
2002-03-26 06:55:05 +00:00
committed by Michael Zucci
parent 22d5307cd1
commit 8ae13b9883
6 changed files with 219 additions and 79 deletions

View File

@ -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.

View File

@ -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;
}

View File

@ -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 {

View File

@ -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;
guint32 flags;
flags = camel_folder_get_message_flags (fb->folder, uids->pdata[i]);
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

View File

@ -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);

View File

@ -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);