/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2004 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2005 Hiroyuki Yamamoto
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
static void compose_toggle_encrypt_cb (gpointer data,
guint action,
GtkWidget *widget);
-static void compose_set_privacy_system_cb(gpointer data,
- guint action,
- GtkWidget *widget);
+static void compose_set_privacy_system_cb(GtkWidget *widget,
+ gpointer data);
static void compose_update_privacy_system_menu_item(Compose * compose);
static void activate_privacy_system (Compose *compose,
PrefsAccount *account);
static gint compose_defer_auto_save_draft (Compose *compose);
static PrefsAccount *compose_guess_forward_account_from_msginfo (MsgInfo *msginfo);
+static void compose_close (Compose *compose);
+
static GtkItemFactoryEntry compose_popup_entries[] =
{
{N_("/_Add..."), NULL, compose_attach_cb, 0, NULL},
NULL, NULL, 0, "<Branch>"},
#endif
{N_("/_Options"), NULL, NULL, 0, "<Branch>"},
- {N_("/_Options/---"), NULL, NULL, 0, "<Separator>"},
{N_("/_Options/Privacy System"), NULL, NULL, 0, "<Branch>"},
- {N_("/_Options/Privacy System/None"), NULL, compose_set_privacy_system_cb, 0, "<RadioItem>"},
+ {N_("/_Options/Privacy System/None"), NULL, NULL, 0, "<RadioItem>"},
{N_("/_Options/Si_gn"), NULL, compose_toggle_sign_cb , 0, "<ToggleItem>"},
{N_("/_Options/_Encrypt"), NULL, compose_toggle_encrypt_cb, 0, "<ToggleItem>"},
{N_("/_Options/---"), NULL, NULL, 0, "<Separator>"},
{"text/uri-list", 0, 0}
};
+static gboolean compose_put_existing_to_front(MsgInfo *info)
+{
+ GList *compose_list = compose_get_compose_list();
+ GList *elem = NULL;
+
+ if (compose_list) {
+ for (elem = compose_list; elem != NULL && elem->data != NULL;
+ elem = elem->next) {
+ Compose *c = (Compose*)elem->data;
+
+ if (!c->targetinfo || !c->targetinfo->msgid ||
+ !info->msgid)
+ continue;
+
+ if (!strcmp(c->targetinfo->msgid, info->msgid)) {
+ gtkut_window_popup(c->window);
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
Compose *compose_new(PrefsAccount *account, const gchar *mailto,
GPtrArray *attach_files)
{
compose = compose_create(account, COMPOSE_REPLY);
ifactory = gtk_item_factory_from_widget(compose->menubar);
- menu_set_active(ifactory, "/Message/Remove references", FALSE);
- menu_set_sensitive(ifactory, "/Message/Remove references", TRUE);
+ menu_set_active(ifactory, "/Options/Remove references", FALSE);
+ menu_set_sensitive(ifactory, "/Options/Remove references", TRUE);
compose->replyinfo = procmsg_msginfo_get_full_info(msginfo);
if (!compose->replyinfo)
g_return_if_fail(msginfo != NULL);
g_return_if_fail(msginfo->folder != NULL);
+ if (compose_put_existing_to_front(msginfo))
+ return;
+
if (msginfo->folder->stype == F_QUEUE || msginfo->folder->stype == F_DRAFT) {
gchar queueheader_buf[BUFFSIZE];
gint id, param;
gtk_widget_grab_focus(compose->header_last->entry);
- filename = procmsg_get_message_file(msginfo);
+ filename = procmsg_get_message_file_path(msginfo);
if (filename == NULL)
return NULL;
ifactory = gtk_item_factory_from_widget(compose->popupmenu);
menu_set_sensitive(ifactory, "/Add...", FALSE);
menu_set_sensitive(ifactory, "/Remove", FALSE);
- menu_set_sensitive(ifactory, "/Property...", FALSE);
+ menu_set_sensitive(ifactory, "/Properties...", FALSE);
ifactory = gtk_item_factory_from_widget(compose->menubar);
menu_set_sensitive(ifactory, "/Message/Save", FALSE);
menu_set_sensitive(ifactory, "/Message/Attach file", FALSE);
menu_set_sensitive(ifactory, "/Message/Insert signature", FALSE);
menu_set_sensitive(ifactory, "/Edit", FALSE);
- menu_set_sensitive(ifactory, "/Options/Sign", FALSE);
- menu_set_sensitive(ifactory, "/Options/Encrypt", FALSE);
- menu_set_sensitive(ifactory, "/Options/Priority", FALSE);
- menu_set_sensitive(ifactory, "/Options/Request Return Receipt", FALSE);
+ menu_set_sensitive(ifactory, "/Options", FALSE);
menu_set_sensitive(ifactory, "/Tools/Show ruler", FALSE);
menu_set_sensitive(ifactory, "/Tools/Actions", FALSE);
};
FILE *fp;
+ gchar buf[BUFFSIZE];
g_return_val_if_fail(msginfo != NULL, -1);
fclose(fp);
if (hentry[H_REPLY_TO].body != NULL) {
- conv_unmime_header_overwrite(hentry[H_REPLY_TO].body);
- compose->replyto = hentry[H_REPLY_TO].body;
+ conv_unmime_header(buf, sizeof(buf), hentry[H_REPLY_TO].body,
+ NULL);
+ compose->replyto = g_strdup(buf);
+ g_free(hentry[H_REPLY_TO].body);
hentry[H_REPLY_TO].body = NULL;
}
if (hentry[H_CC].body != NULL) {
- conv_unmime_header_overwrite(hentry[H_CC].body);
- compose->cc = hentry[H_CC].body;
+ conv_unmime_header(buf, sizeof(buf), hentry[H_CC].body, NULL);
+ compose->cc = g_strdup(buf);
+ g_free(hentry[H_CC].body);
hentry[H_CC].body = NULL;
}
if (hentry[H_REFERENCES].body != NULL) {
}
if (hentry[H_BCC].body != NULL) {
if (compose->mode == COMPOSE_REEDIT) {
- conv_unmime_header_overwrite(hentry[H_BCC].body);
- compose->bcc = hentry[H_BCC].body;
- } else
- g_free(hentry[H_BCC].body);
+ conv_unmime_header
+ (buf, sizeof(buf), hentry[H_BCC].body, NULL);
+ compose->bcc = g_strdup(buf);
+ }
+ g_free(hentry[H_BCC].body);
hentry[H_BCC].body = NULL;
}
if (hentry[H_NEWSGROUPS].body != NULL) {
- conv_unmime_header_overwrite(hentry[H_NEWSGROUPS].body);
compose->newsgroups = hentry[H_NEWSGROUPS].body;
hentry[H_NEWSGROUPS].body = NULL;
}
if (hentry[H_FOLLOWUP_TO].body != NULL) {
- conv_unmime_header_overwrite(hentry[H_FOLLOWUP_TO].body);
- compose->followup_to = hentry[H_FOLLOWUP_TO].body;
+ conv_unmime_header
+ (buf, sizeof(buf), hentry[H_FOLLOWUP_TO].body, NULL);
+ compose->followup_to = g_strdup(buf);
+ g_free(hentry[H_FOLLOWUP_TO].body);
hentry[H_FOLLOWUP_TO].body = NULL;
}
if (hentry[H_LIST_POST].body != NULL) {
compose->priority = priority;
}
- if (compose->mode == COMPOSE_REEDIT && msginfo->inreplyto)
- compose->inreplyto = g_strdup(msginfo->inreplyto);
- else if (compose->mode != COMPOSE_REEDIT &&
- msginfo->msgid && *msginfo->msgid) {
+ if (compose->mode == COMPOSE_REEDIT) {
+ if (msginfo->inreplyto && *msginfo->inreplyto)
+ compose->inreplyto = g_strdup(msginfo->inreplyto);
+ return 0;
+ }
+
+ if (msginfo->msgid && *msginfo->msgid)
compose->inreplyto = g_strdup(msginfo->msgid);
- if (!compose->references) {
+ if (!compose->references) {
+ if (msginfo->msgid && *msginfo->msgid) {
if (msginfo->inreplyto && *msginfo->inreplyto)
compose->references =
g_strdup_printf("<%s>\n\t<%s>",
compose->references =
g_strconcat("<", msginfo->msgid, ">",
NULL);
+ } else if (msginfo->inreplyto && *msginfo->inreplyto) {
+ compose->references =
+ g_strconcat("<", msginfo->inreplyto, ">",
+ NULL);
}
}
MsgFlags flags = {0, 0};
gchar *name;
- if (procmime_get_encoding_for_file(file) == ENC_7BIT)
+ if (procmime_get_encoding_for_text_file(file) == ENC_7BIT)
ainfo->encoding = ENC_7BIT;
else
ainfo->encoding = ENC_8BIT;
procmsg_msginfo_free(msginfo);
} else {
if (!g_strncasecmp(content_type, "text", 4))
- ainfo->encoding =
- procmime_get_encoding_for_file(file);
+ ainfo->encoding = procmime_get_encoding_for_text_file(file);
else
ainfo->encoding = ENC_BASE64;
ainfo->name = g_strdup
g_strdup("application/octet-stream");
ainfo->encoding = ENC_BASE64;
} else if (!g_strncasecmp(ainfo->content_type, "text", 4))
- ainfo->encoding = procmime_get_encoding_for_file(file);
+ ainfo->encoding =
+ procmime_get_encoding_for_text_file(file);
else
ainfo->encoding = ENC_BASE64;
ainfo->name = g_strdup(g_basename(filename ? filename : file));
}
+
+ if (!strcmp(ainfo->content_type, "unknown")) {
+ g_free(ainfo->content_type);
+ ainfo->content_type = g_strdup("application/octet-stream");
+ }
+
ainfo->size = size;
text[COL_MIMETYPE] = ainfo->content_type;
gint ch_len;
gboolean is_new_line = TRUE, do_delete = FALSE;
guint i_len = 0;
- gboolean linewrap_quote = TRUE;
+ gboolean linewrap_quote = prefs_common.linewrap_quote;
gboolean set_editable_pos = FALSE;
gint editable_pos = 0;
gboolean frozen = FALSE;
g_print("l_len=%d wrap_len=%d do_del=%d\n",
line_len, linewrap_len, do_delete);
#endif
- /* should we delete to perform smart wrapping */
if (line_len < linewrap_len && do_delete) {
STEXT_FREEZE();
/* get rid of newline */
}
GET_CHAR(cur_pos, cb, clen);
-
- /* insert space if it's alphanumeric */
- if ((cur_pos != line_pos) &&
- ((clen > 1) || isalnum((guchar)cb[0]))) {
- gtk_stext_insert(text, NULL, NULL,
- NULL, " ", 1);
- tlen++;
+ /* insert space between the next line */
+ if (cur_pos > 0) {
+ gint clen_prev;
+ gchar cb_prev[MB_LEN_MAX];
+
+ GET_CHAR(cur_pos - 1, cb_prev,
+ clen_prev);
+ if ((clen_prev != clen && clen > 1) ||
+ (clen == 1 &&
+ !isspace((guchar)cb[0]))) {
+ gtk_stext_insert
+ (text, NULL, NULL,
+ NULL, " ", 1);
+ tlen++;
+ }
}
/* and start over with current line */
#endif
- if (account->default_sign)
+ if (account->default_sign && compose->mode != COMPOSE_REDIRECT)
menu_set_active(ifactory, "/Options/Sign", TRUE);
else
menu_set_active(ifactory, "/Options/Sign", FALSE);
- if (account->default_encrypt)
+ if (account->default_encrypt && compose->mode != COMPOSE_REDIRECT)
menu_set_active(ifactory, "/Options/Encrypt", TRUE);
else
menu_set_active(ifactory, "/Options/Encrypt", FALSE);
if (prefs_common.send_dialog_mode != SEND_DIALOG_ALWAYS) {
compose->sending = FALSE;
- gtk_widget_destroy(compose->window);
+ compose_close(compose);
/* No more compose access in the normal codepath
* after this point! */
}
folder_item_remove_msg(folder, msgnum);
folder_item_scan(folder);
if (prefs_common.send_dialog_mode == SEND_DIALOG_ALWAYS)
- gtk_widget_destroy(compose->window);
- }
+ compose_close(compose);
+ } else {
+ alertpanel_error(_("The message was queued but could not be "
+ "sent.\nUse \"Send queued messages\" from "
+ "the main window to retry."));
+ if (prefs_common.send_dialog_mode == SEND_DIALOG_ALWAYS) {
+ compose_allow_user_actions (compose, TRUE);
+ compose->sending = FALSE;
+ }
+ return -1;
+ }
return 0;
/* Resent-Message-ID */
if (compose->account->gen_msgid) {
- generate_msgid(compose->account->address, buf, sizeof(buf));
+ generate_msgid(buf, sizeof(buf));
fprintf(fp, "Resent-Message-ID: <%s>\n", buf);
compose->msgid = g_strdup(buf);
}
if (action == COMPOSE_WRITE_FOR_SEND) {
buf = conv_codeset_strdup(chars, src_codeset, out_codeset);
+
if (!buf) {
AlertValue aval;
gchar *msg;
}
g_free(chars);
+ if (encoding == ENC_8BIT || encoding == ENC_7BIT) {
+ if (!strncmp(buf, "From ", sizeof("From ")-1) ||
+ strstr(buf, "\nFrom ") != NULL) {
+ encoding = ENC_QUOTED_PRINTABLE;
+ }
+ }
+
mimetext = procmime_mimeinfo_new();
mimetext->content = MIMECONTENT_MEM;
mimetext->data.mem = buf;
mimetext->subtype = g_strdup("plain");
g_hash_table_insert(mimetext->typeparameters, g_strdup("charset"),
g_strdup(out_codeset));
+ /* protect trailing spaces when signing message */
+ if (action == COMPOSE_WRITE_FOR_SEND && compose->use_signing &&
+ privacy_system_can_sign(compose->privacy_system))
+ if (encoding == ENC_7BIT)
+ encoding = ENC_QUOTED_PRINTABLE;
+ else if (encoding == ENC_8BIT)
+ encoding = ENC_BASE64;
+ if (encoding != ENC_UNKNOWN)
+ procmime_encode_content(mimetext, encoding);
/* append attachment parts */
if (compose_use_attach(compose)) {
} else
g_node_append(mimemsg->node, mimetext->node);
- /* sign message */
- if (compose->use_signing && privacy_system_can_sign(compose->privacy_system))
- if (!privacy_sign(compose->privacy_system, mimemsg))
+ /* sign message if sending */
+ if (action == COMPOSE_WRITE_FOR_SEND && compose->use_signing &&
+ privacy_system_can_sign(compose->privacy_system))
+ if (!privacy_sign(compose->privacy_system, mimemsg, compose->account))
return -1;
procmime_write_mimeinfo(mimemsg, fp);
+
+ procmime_mimeinfo_free_all(mimemsg);
return 0;
}
gchar *encdata;
encdata = privacy_get_encrypt_data(compose->privacy_system, compose->to_list);
- fprintf(fp, "X-Sylpheed-Encrypt-Data:%s\n", encdata);
+ if (encdata != NULL)
+ fprintf(fp, "X-Sylpheed-Encrypt-Data:%s\n",
+ encdata);
g_free(encdata);
}
}
mimepart->length = statbuf.st_size;
type = g_strdup(ainfo->content_type);
+
+ if (!strchr(type, '/')) {
+ g_free(type);
+ type = g_strdup("application/octet-stream");
+ }
+
subtype = strchr(type, '/') + 1;
*(subtype - 1) = '\0';
mimepart->type = procmime_get_media_type(type);
mimepart->disposition = DISPOSITIONTYPE_ATTACHMENT;
}
+ if (compose->use_signing) {
+ if (ainfo->encoding == ENC_7BIT)
+ ainfo->encoding = ENC_QUOTED_PRINTABLE;
+ else if (ainfo->encoding == ENC_8BIT)
+ ainfo->encoding = ENC_BASE64;
+ }
+
procmime_encode_content(mimepart, ainfo->encoding);
g_node_append(parent->node, mimepart->node);
/* Message-ID */
if (compose->account->gen_msgid) {
- generate_msgid(compose->account->address, buf, sizeof(buf));
+ generate_msgid(buf, sizeof(buf));
g_string_sprintfa(header, "Message-ID: <%s>\n", buf);
compose->msgid = g_strdup(buf);
}
GTK_STEXT(text)->cursor_type = GTK_STEXT_CURSOR_BLOCK;
}
- if (prefs_common.smart_wrapping) {
- gtk_stext_set_word_wrap(GTK_STEXT(text), TRUE);
- gtk_stext_set_wrap_rmargin(GTK_STEXT(text), prefs_common.linewrap_len);
- }
-
gtk_container_add(GTK_CONTAINER(scrolledwin), text);
gtk_signal_connect(GTK_OBJECT(text), "changed",
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
}
-static void compose_set_privacy_system_cb(gpointer data,
- guint action,
- GtkWidget *widget)
+static void compose_set_privacy_system_cb(GtkWidget *widget, gpointer data)
{
Compose *compose = (Compose *) data;
gchar *systemid;
GtkItemFactory *ifactory;
gboolean can_sign = FALSE, can_encrypt = FALSE;
+ g_return_if_fail(GTK_IS_CHECK_MENU_ITEM(widget));
+
+ if (!GTK_CHECK_MENU_ITEM(widget)->active)
+ return;
+
systemid = gtk_object_get_data(GTK_OBJECT(widget), "privacy_system");
g_free(compose->privacy_system);
compose->privacy_system = NULL;
can_encrypt = privacy_system_can_encrypt(systemid);
}
+ debug_print("activated privacy system: %s\n", systemid != NULL ? systemid : "None");
+
ifactory = gtk_item_factory_from_widget(compose->menubar);
menu_set_sensitive(ifactory, "/Options/Sign", can_sign);
+ if (!can_sign)
+ menu_set_active(ifactory, "/Options/Sign", FALSE);
menu_set_sensitive(ifactory, "/Options/Encrypt", can_encrypt);
+ if (!can_encrypt)
+ menu_set_active(ifactory, "/Options/Encrypt", FALSE);
}
static void compose_update_privacy_system_menu_item(Compose * compose)
void compose_update_privacy_systems_menu(Compose *compose)
{
static gchar *branch_path = "/Options/Privacy System";
+ static gboolean connected = FALSE;
GtkItemFactory *ifactory;
GtkWidget *menuitem;
- gchar *menu_path;
GSList *systems, *cur;
GList *amenu;
- GtkItemFactoryEntry ifentry = {NULL, NULL, NULL, 0, "<Branch>"};
GtkWidget *widget;
+ GtkWidget *system_none;
+ GSList *group;
ifactory = gtk_item_factory_from_widget(compose->menubar);
/* remove old entries */
- ifentry.path = branch_path;
menuitem = gtk_item_factory_get_widget(ifactory, branch_path);
g_return_if_fail(menuitem != NULL);
amenu = alist;
}
- ifentry.accelerator = NULL;
- ifentry.callback_action = 0;
- ifentry.callback = compose_set_privacy_system_cb;
- ifentry.item_type = "/Options/Privacy System/None";
+ system_none = gtk_item_factory_get_widget(ifactory,
+ "/Options/Privacy System/None");
+ if (!connected) {
+ gtk_signal_connect(GTK_OBJECT(system_none), "activate",
+ GTK_SIGNAL_FUNC(compose_set_privacy_system_cb), compose);
+ connected = TRUE;
+ }
systems = privacy_get_system_ids();
for (cur = systems; cur != NULL; cur = g_slist_next(cur)) {
gchar *systemid = cur->data;
- menu_path = g_strdup_printf("%s/%s", branch_path,
- privacy_system_get_name(systemid));
- ifentry.path = menu_path;
- gtk_item_factory_create_item(ifactory, &ifentry, compose, 1);
- widget = gtk_item_factory_get_widget(ifactory, menu_path);
-
+ group = gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(system_none));
+ widget = gtk_radio_menu_item_new_with_label(group,
+ privacy_system_get_name(systemid));
gtk_object_set_data_full(GTK_OBJECT(widget), "privacy_system",
g_strdup(systemid), g_free);
+ gtk_signal_connect(GTK_OBJECT(widget), "activate",
+ GTK_SIGNAL_FUNC(compose_set_privacy_system_cb), compose);
+ gtk_menu_append(GTK_MENU(system_none->parent), widget);
+ gtk_widget_show(widget);
g_free(systemid);
- g_free(menu_path);
}
g_slist_free(systems);
}
prefs_common.compose_width = compose->scrolledwin->allocation.width;
prefs_common.compose_height = compose->window->allocation.height;
- gtk_widget_destroy(compose->paned);
+ if (!compose->paned->parent)
+ gtk_widget_destroy(compose->paned);
+ gtk_widget_destroy(compose->popupmenu);
toolbar_destroy(compose->toolbar);
g_free(compose->toolbar);
gint val;
val = compose_queue_sub(compose, NULL, NULL, TRUE);
- if (!val) gtk_widget_destroy(compose->window);
+ if (!val)
+ compose_close(compose);
}
void compose_draft (gpointer data)
}
fprintf(fp, "X-Sylpheed-Sign:%d\n", compose->use_signing);
fprintf(fp, "X-Sylpheed-Encrypt:%d\n", compose->use_encryption);
- fprintf(fp, "X-Sylpheed-Gnupg-Mode:%s\n", compose->privacy_system);
+ fprintf(fp, "X-Sylpheed-Privacy-System:%s\n", compose->privacy_system);
fprintf(fp, "\n");
if (compose_write_to_file(compose, fp, COMPOSE_WRITE_FOR_STORE) < 0) {
lock = FALSE;
if (action == COMPOSE_QUIT_EDITING)
- gtk_widget_destroy(compose->window);
+ compose_close(compose);
else {
struct stat s;
gchar *path;
}
}
- gtk_widget_destroy(compose->window);
+ compose_close(compose);
}
static void compose_address_cb(gpointer data, guint action, GtkWidget *widget)
static void activate_privacy_system(Compose *compose, PrefsAccount *account)
{
- /* TODO
- if (account->default_gnupg_mode)
- compose->gnupg_mode = GNUPG_MODE_INLINE;
- else
- compose->gnupg_mode = GNUPG_MODE_DETACH;
- */
+ g_free(compose->privacy_system);
+ compose->privacy_system = g_strdup(account->default_privacy_system);
compose_update_privacy_system_menu_item(compose);
}
return account;
}
+static void compose_close(Compose *compose)
+{
+ gint x, y;
+
+ g_return_if_fail(compose);
+ gtkut_widget_get_uposition(compose->window, &x, &y);
+ prefs_common.compose_x = x;
+ prefs_common.compose_y = y;
+ gtk_widget_destroy(compose->window);
+}
+
/**
* Add entry field for each address in list.
* \param compose E-Mail composition object.
}
}
+void compose_reply_from_messageview(MessageView *msgview, GSList *msginfo_list,
+ guint action)
+{
+ gchar *body;
+ GSList *new_msglist = NULL;
+ MsgInfo *tmp_msginfo = NULL;
+
+ g_return_if_fail(msgview != NULL);
+
+ g_return_if_fail(msginfo_list != NULL);
+
+ if (g_slist_length(msginfo_list) == 1) {
+ MimeInfo *mimeinfo = messageview_get_selected_mime_part(msgview);
+ MsgInfo *orig_msginfo = (MsgInfo *)msginfo_list->data;
+
+ if (mimeinfo != NULL && mimeinfo->type == MIMETYPE_MESSAGE &&
+ !g_strcasecmp(mimeinfo->subtype, "rfc822")) {
+
+ tmp_msginfo = procmsg_msginfo_new_from_mimeinfo(
+ orig_msginfo, mimeinfo);
+ if (tmp_msginfo != NULL) {
+ new_msglist = g_slist_append(NULL, tmp_msginfo);
+ }
+ }
+ }
+
+ body = messageview_get_selection(msgview);
+
+ if (new_msglist) {
+ compose_reply_mode((ComposeMode)action, new_msglist, body);
+ procmsg_msginfo_free(tmp_msginfo);
+ g_slist_free(new_msglist);
+ } else
+ compose_reply_mode((ComposeMode)action, msginfo_list, body);
+
+ g_free(body);
+}
+
/*
* End of Source.
*/
-