#include "customheader.h"
#include "prefs_common.h"
#include "prefs_account.h"
+#include "prefs_actions.h"
#include "account.h"
#include "filesel.h"
#include "procheader.h"
#include "template.h"
#include "undo.h"
#include "foldersel.h"
-#include "prefs_actions.h"
#if USE_GPGME
# include "rfc2015.h"
Compose *compose_generic_new (PrefsAccount *account,
const gchar *to,
- FolderItem *item);
+ FolderItem *item,
+ GPtrArray *attach_files);
static Compose *compose_create (PrefsAccount *account,
ComposeMode mode);
static void compose_cut_cb (Compose *compose);
static void compose_copy_cb (Compose *compose);
static void compose_paste_cb (Compose *compose);
+static void compose_paste_as_quote_cb (Compose *compose);
static void compose_allsel_cb (Compose *compose);
static void compose_gtk_stext_action_cb (Compose *compose,
Compose *compose);
static void newsgroups_activated (GtkWidget *widget,
Compose *compose);
-static void subject_activated (GtkWidget *widget,
- Compose *compose);
static void cc_activated (GtkWidget *widget,
Compose *compose);
static void bcc_activated (GtkWidget *widget,
Compose *compose);
static void followupto_activated (GtkWidget *widget,
Compose *compose);
+static void subject_activated (GtkWidget *widget,
+ Compose *compose);
#endif
+static void text_activated (GtkWidget *widget,
+ Compose *compose);
+static void text_inserted (GtkWidget *widget,
+ const gchar *text,
+ gint length,
+ gint *position,
+ Compose *compose);
static void compose_generic_reply(MsgInfo *msginfo, gboolean quote,
gboolean to_all,
gboolean ignore_replyto,
static void compose_check_forwards_go (Compose *compose);
#endif
-static gboolean compose_send_control_enter (Compose *compose);
-static void text_activated (GtkWidget *widget,
- Compose *compose);
+static gboolean compose_send_control_enter (Compose *compose);
static GtkItemFactoryEntry compose_popup_entries[] =
{
{N_("/_Edit/Cu_t"), "<control>X", compose_cut_cb, 0, NULL},
{N_("/_Edit/_Copy"), "<control>C", compose_copy_cb, 0, NULL},
{N_("/_Edit/_Paste"), "<control>V", compose_paste_cb, 0, NULL},
+ {N_("/_Edit/Paste as _quotation"),
+ NULL, compose_paste_as_quote_cb, 0, NULL},
{N_("/_Edit/Select _all"), "<control>A", compose_allsel_cb, 0, NULL},
{N_("/_Edit/A_dvanced"), NULL, NULL, 0, "<Branch>"},
{N_("/_Edit/A_dvanced/Move a character backward"),
{N_("/_Message/_Encrypt"), NULL, compose_toggle_encrypt_cb, 0, "<ToggleItem>"},
#endif /* USE_GPGME */
{N_("/_Message/---"), NULL, NULL, 0, "<Separator>"},
- {N_("/_Message/Priority"), NULL, NULL, 0, "<Branch>"},
- {N_("/_Message/Priority/Highest"), NULL, compose_set_priority_cb, PRIORITY_HIGHEST, "<RadioItem>"},
- {N_("/_Message/Priority/High"), NULL, compose_set_priority_cb, PRIORITY_HIGH, "/Message/Priority/Highest"},
- {N_("/_Message/Priority/Normal"), NULL, compose_set_priority_cb, PRIORITY_NORMAL, "/Message/Priority/Highest"},
- {N_("/_Message/Priority/Low"), NULL, compose_set_priority_cb, PRIORITY_LOW, "/Message/Priority/Highest"},
- {N_("/_Message/Priority/Lowest"), NULL, compose_set_priority_cb, PRIORITY_LOWEST, "/Message/Priority/Highest"},
+ {N_("/_Message/_Priority"), NULL, NULL, 0, "<Branch>"},
+ {N_("/_Message/Priority/_Highest"), NULL, compose_set_priority_cb, PRIORITY_HIGHEST, "<RadioItem>"},
+ {N_("/_Message/Priority/Hi_gh"), NULL, compose_set_priority_cb, PRIORITY_HIGH, "/Message/Priority/Highest"},
+ {N_("/_Message/Priority/_Normal"), NULL, compose_set_priority_cb, PRIORITY_NORMAL, "/Message/Priority/Highest"},
+ {N_("/_Message/Priority/Lo_w"), NULL, compose_set_priority_cb, PRIORITY_LOW, "/Message/Priority/Highest"},
+ {N_("/_Message/Priority/_Lowest"), NULL, compose_set_priority_cb, PRIORITY_LOWEST, "/Message/Priority/Highest"},
{N_("/_Message/---"), NULL, NULL, 0, "<Separator>"},
{N_("/_Message/_Request Return Receipt"), NULL, compose_toggle_return_receipt_cb, 0, "<ToggleItem>"},
{N_("/_Tools"), NULL, NULL, 0, "<Branch>"},
{"text/uri-list", 0, 0}
};
-Compose *compose_new(PrefsAccount *account)
-{
- return compose_generic_new(account, NULL, NULL);
-}
-
Compose *compose_redirect(PrefsAccount *account, MsgInfo *msginfo)
{
Compose *c;
gchar *filename;
GtkItemFactory *ifactory;
- c = compose_generic_new(account, NULL, NULL);
+ c = compose_generic_new(account, NULL, NULL, NULL);
filename = procmsg_get_message_file(msginfo);
if (filename == NULL)
return c;
}
-Compose *compose_new_with_recipient(PrefsAccount *account, const gchar *mailto)
+Compose *compose_new(PrefsAccount *account, const gchar *mailto,
+ GPtrArray *attach_files)
{
- return compose_generic_new(account, mailto, NULL);
+ return compose_generic_new(account, mailto, NULL, attach_files);
}
Compose *compose_new_with_folderitem(PrefsAccount *account, FolderItem *item)
{
- return compose_generic_new(account, NULL, item);
+ return compose_generic_new(account, NULL, item, NULL);
}
-Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderItem *item)
+Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderItem *item,
+ GPtrArray *attach_files)
{
Compose *compose;
GtkSText *text;
+ GtkItemFactory *ifactory;
+ gboolean grab_focus_on_last = TRUE;
if (item && item->prefs && item->prefs->enable_default_account)
account = account_find_from_id(item->prefs->default_account);
g_return_val_if_fail(account != NULL, NULL);
compose = compose_create(account, COMPOSE_NEW);
+ ifactory = gtk_item_factory_from_widget(compose->menubar);
+
compose->replyinfo = NULL;
text = GTK_STEXT(compose->text);
gtkut_widget_wait_for_draw(compose->text);
if (account->protocol != A_NNTP) {
- if (mailto) {
+ if (mailto && *mailto != '\0') {
compose_entries_set(compose, mailto);
} else if(item && item->prefs->enable_default_to) {
compose_entry_append(compose, item->prefs->default_to, COMPOSE_TO);
+ compose_entry_select(compose, item->prefs->default_to);
+ grab_focus_on_last = FALSE;
}
if (item && item->ret_rcpt) {
- GtkItemFactory *ifactory;
-
- ifactory = gtk_item_factory_from_widget(compose->menubar);
menu_set_toggle(ifactory, "/Message/Request Return Receipt", TRUE);
}
} else {
if (mailto) {
compose_entry_append(compose, mailto, COMPOSE_NEWSGROUPS);
}
+ /*
+ * CLAWS: just don't allow return receipt request, even if the user
+ * may want to send an email. simple but foolproof.
+ */
+ menu_set_sensitive(ifactory, "/Message/Request Return Receipt", FALSE);
}
+
+ if (attach_files) {
+ gint i;
+ gchar *file;
+
+ for (i = 0; i < attach_files->len; i++) {
+ file = g_ptr_array_index(attach_files, i);
+ compose_attach_append(compose, file, file, NULL);
+ }
+ }
+
compose_show_first_last_header(compose, TRUE);
/* Set save folder */
gtk_entry_set_text(GTK_ENTRY(compose->savemsg_entry), folderidentifier);
g_free(folderidentifier);
}
-
- gtk_widget_grab_focus(compose->header_last->entry);
+
+ /* Grab focus on last header only if no default_to was set */
+ if(grab_focus_on_last)
+ gtk_widget_grab_focus(compose->header_last->entry);
if (prefs_common.auto_exteditor)
compose_exec_ext_editor(compose);
} else
reply_account = account;
- MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_FORWARDED);
- MSG_SET_PERM_FLAGS(msginfo->flags, MSG_REPLIED);
- if (MSG_IS_IMAP(msginfo->flags))
- imap_msg_set_perm_flags(msginfo, MSG_REPLIED);
- CHANGE_FLAGS(msginfo);
-
compose = compose_create(account, COMPOSE_REPLY);
- compose->replyinfo = procmsg_msginfo_copy(msginfo);
+ compose->replyinfo = procmsg_msginfo_new_ref(msginfo);
#if 0 /* NEW COMPOSE GUI */
if (followup_and_reply_to) {
static void set_toolbar_style(Compose *compose);
-static gchar *procmime_get_file_name(MimeInfo *mimeinfo)
-{
- gchar *base;
- gchar *filename;
-
- g_return_val_if_fail(mimeinfo != NULL, NULL);
-
- base = mimeinfo->filename ? mimeinfo->filename
- : mimeinfo->name ? mimeinfo->name : NULL;
-
- if (MIME_TEXT_HTML == mimeinfo->mime_type && base == NULL){
- filename = g_strdup_printf("%s%smimetmp.%08x.html",
- get_mime_tmp_dir(),
- G_DIR_SEPARATOR_S,
- (gint)mimeinfo);
- return filename;
- }
- else {
- base = base ? base : "";
- base = g_basename(base);
- if (*base == '\0') {
- filename = g_strdup_printf("%s%smimetmp.%08x",
- get_mime_tmp_dir(),
- G_DIR_SEPARATOR_S,
- (gint)mimeinfo);
- return filename;
- }
- }
-
- filename = g_strconcat(get_mime_tmp_dir(), G_DIR_SEPARATOR_S,
- base, NULL);
-
- return filename;
-}
-
-static gchar *mime_extract_file(gchar *source, MimeInfo *partinfo)
-{
- gchar *filename;
-
- if (!partinfo) return NULL;
-
- filename = procmime_get_file_name(partinfo);
-
- if (procmime_get_part(filename, source, partinfo) < 0)
- alertpanel_error
- (_("Can't get the part of multipart message."));
-
- return filename;
-}
-
-
-
#define INSERT_FW_HEADER(var, hdr) \
if (msginfo->var && *msginfo->var) { \
gtk_stext_insert(text, NULL, NULL, NULL, hdr, -1); \
void compose_entry_append(Compose *compose, const gchar *address,
ComposeEntryType type)
{
- GtkEntry *entry;
- const gchar *text;
gchar *header;
if (!address || *address == '\0') return;
compose_add_header_entry(compose, header, (gchar *)address);
}
+void compose_entry_select (Compose *compose, const gchar *mailto)
+{
+ GSList *header_list;
+
+ for (header_list = compose->header_list; header_list != NULL; header_list = header_list->next) {
+ GtkEntry * entry = GTK_ENTRY(((ComposeHeaderEntry *)header_list->data)->entry);
+
+ if (gtk_entry_get_text(entry) && !g_strcasecmp(gtk_entry_get_text(entry), mailto)) {
+ gtk_entry_select_region(entry, 0, -1);
+ gtk_widget_grab_focus(GTK_WIDGET(entry));
+ }
+ }
+}
+
static void compose_entries_set(Compose *compose, const gchar *mailto)
{
gchar *subject = NULL;
const gchar *body)
{
GtkSText *text = GTK_STEXT(compose->text);
+ static MsgInfo dummyinfo;
gchar *quote_str = NULL;
gchar *buf;
gchar *p, *lastp;
gint len;
+ if (!msginfo)
+ msginfo = &dummyinfo;
+
if (qmark != NULL) {
quote_fmt_init(msginfo, NULL, NULL);
quote_fmt_scan_string(qmark);
static void compose_exec_sig(Compose *compose, gchar *sigfile)
{
- FILE *tmpfp;
- pid_t thepid;
- gchar *sigtext;
FILE *sigprg;
gchar *buf;
size_t buf_len = 128;
(_("Message: %s"),
g_basename(filename ? filename : file));
} else {
- ainfo->encoding = ENC_BASE64;
+ if (!g_strncasecmp(content_type, "text", 4))
+ ainfo->encoding =
+ procmime_get_encoding_for_file(file);
+ else
+ ainfo->encoding = ENC_BASE64;
ainfo->name = g_strdup
(g_basename(filename ? filename : file));
}
} else {
ainfo->content_type = procmime_get_mime_type(file);
- if (!ainfo->content_type)
+ if (!ainfo->content_type) {
ainfo->content_type =
g_strdup("application/octet-stream");
- ainfo->encoding = ENC_BASE64;
+ ainfo->encoding = ENC_BASE64;
+ } else if (!g_strncasecmp(ainfo->content_type, "text", 4))
+ ainfo->encoding = procmime_get_encoding_for_file(file);
+ else
+ ainfo->encoding = ENC_BASE64;
ainfo->name = g_strdup(g_basename(filename ? filename : file));
}
ainfo->size = size;
guint prev_line_pos, guint text_len,
gchar *quote_fmt)
{
- guint i, ins_len;
+ guint i, ins_len = 0;
gchar ch;
if (indent_len) {
/* we have encountered line break */
if (ch_len == 1 && *cbuf == '\n') {
gint clen;
- gchar cb[MB_CUR_MAX];
+ gchar cb[MB_LEN_MAX];
/* should we join the next line */
if ((i_len != cur_len) && do_delete &&
for(list = compose->header_list; list; list = list->next) {
gchar *header;
gchar *entry;
- header = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(((ComposeHeaderEntry *)list->data)->combo)->entry));
+ header = gtk_editable_get_chars(GTK_EDITABLE(GTK_COMBO(((ComposeHeaderEntry *)list->data)->combo)->entry), 0, -1);
entry = gtk_editable_get_chars(GTK_EDITABLE(((ComposeHeaderEntry *)list->data)->entry), 0, -1);
g_strstrip(entry);
if(entry[0] != '\0') {
}
}
}
+ g_free(header);
g_free(entry);
}
return recipient_found;
}
/* write to temporary file */
- g_snprintf(tmp, sizeof(tmp), "%s%ctmpmsg%d",
- get_rc_dir(), G_DIR_SEPARATOR, (gint)compose);
+ g_snprintf(tmp, sizeof(tmp), "%s%ctmpmsg.%08x",
+ get_tmp_dir(), G_DIR_SEPARATOR, (gint)compose);
if (prefs_common.linewrap_at_send)
compose_wrap_line_all(compose);
gchar *cc_hdr;
gchar *to_hdr;
- debug_print(_("Writing redirect header\n"));
+ debug_print("Writing redirect header\n");
cc_hdr = prefs_common.trans_hdr ? _("Cc:") : "Cc:";
to_hdr = prefs_common.trans_hdr ? _("To:") : "To:";
}
-#ifdef USE_GPGME
-/*
- * interfaces to rfc2015 to keep out the prefs stuff there.
+#if USE_GPGME
+/* interfaces to rfc2015 to keep out the prefs stuff there.
* returns 0 on success and -1 on error. */
-static int compose_create_signers_list (Compose *compose, GSList **pkey_list)
+static gint compose_create_signers_list(Compose *compose, GSList **pkey_list)
{
- const char *keyid = NULL;
+ const gchar *key_id = NULL;
GSList *key_list;
switch (compose->account->sign_key) {
case SIGN_KEY_DEFAULT:
*pkey_list = NULL;
- return 0; /* nothing to do */
-
+ return 0;
case SIGN_KEY_BY_FROM:
- keyid = compose->account->address;
+ key_id = compose->account->address;
break;
-
case SIGN_KEY_CUSTOM:
- keyid = compose->account->sign_key_id;
+ key_id = compose->account->sign_key_id;
break;
-
default:
- g_assert_not_reached ();
+ break;
}
- key_list = rfc2015_create_signers_list(keyid);
+ key_list = rfc2015_create_signers_list(key_id);
if (!key_list) {
- alertpanel_error("Could not find any key associated with currently "
- "selected keyid `%s'!", keyid);
- return -1;
+ alertpanel_error(_("Could not find any key associated with "
+ "currently selected key id `%s'."), key_id);
+ return -1;
}
-
+
*pkey_list = key_list;
return 0;
}
+
+/* clearsign message body text */
+static gint compose_clearsign_text(Compose *compose, gchar **text)
+{
+ GSList *key_list;
+ gchar *tmp_file;
+
+ tmp_file = get_tmp_file();
+ if (str_write_to_file(*text, tmp_file) < 0) {
+ g_free(tmp_file);
+ return -1;
+ }
+
+ if (canonicalize_file_replace(tmp_file) < 0 ||
+ compose_create_signers_list(compose, &key_list) < 0 ||
+ rfc2015_clearsign(tmp_file, key_list) < 0) {
+ unlink(tmp_file);
+ g_free(tmp_file);
+ return -1;
+ }
+
+ g_free(*text);
+ *text = file_read_to_str(tmp_file);
+ unlink(tmp_file);
+ g_free(tmp_file);
+ if (*text == NULL)
+ return -1;
+
+ return 0;
+}
#endif /* USE_GPGME */
static gint compose_write_to_file(Compose *compose, const gchar *file,
chars = gtk_editable_get_chars(GTK_EDITABLE(compose->text), 0, -1);
len = strlen(chars);
if (is_ascii_str(chars)) {
- buf = g_strdup(chars);
+ buf = chars;
+ chars = NULL;
out_codeset = CS_US_ASCII;
encoding = ENC_7BIT;
} else {
unlink(file);
return -1;
} else {
- buf = g_strdup(chars);
+ buf = chars;
+ chars = NULL;
}
}
}
g_free(chars);
+#if USE_GPGME
+ if (!is_draft && compose->use_signing && compose->account->clearsign) {
+ if (compose_clearsign_text(compose, &buf) < 0) {
+ g_warning("clearsign failed\n");
+ fclose(fp);
+ unlink(file);
+ g_free(buf);
+ return -1;
+ }
+ }
+#endif
+
/* write headers */
if (compose_write_headers
(compose, fp, out_codeset, encoding, is_draft) < 0) {
for (i = 0; i < len; i += B64_LINE_SIZE) {
l = MIN(B64_LINE_SIZE, len - i);
- to64frombits(outbuf, buf + i, l);
+ base64_encode(outbuf, buf + i, l);
fputs(outbuf, fp);
fputc('\n', fp);
}
}
#if USE_GPGME
- if (compose->use_signing) {
+ if (is_draft)
+ return 0;
+
+ if ((compose->use_signing && !compose->account->clearsign) ||
+ compose->use_encryption) {
+ if (canonicalize_file_replace(file) < 0) {
+ unlink(file);
+ return -1;
+ }
+ }
+
+ if (compose->use_signing && !compose->account->clearsign) {
GSList *key_list;
-
- if (compose_create_signers_list(compose, &key_list) == -1 ||
- rfc2015_sign(file, key_list) < 0) {
-
+
+ if (compose_create_signers_list(compose, &key_list) < 0 ||
+ rfc2015_sign(file, key_list) < 0) {
unlink(file);
return -1;
}
}
if (compose->use_encryption) {
- if (rfc2015_encrypt(file, compose->to_list, compose->account->ascii_armored) < 0) {
+ if (rfc2015_encrypt(file, compose->to_list,
+ compose->account->ascii_armored) < 0) {
unlink(file);
return -1;
}
item = msginfo->folder;
g_return_val_if_fail(item != NULL, -1);
- folder_item_scan(item);
if (procmsg_msg_exist(msginfo) &&
(item->stype == F_DRAFT || item->stype == F_QUEUE)) {
if (folder_item_remove_msg(item, msginfo->msgnum) < 0) {
GSList *cur;
gchar buf[BUFFSIZE];
gint num;
- MsgFlags flag = {0, 0};
static gboolean lock = FALSE;
PrefsAccount *mailac = NULL, *newsac = NULL;
- debug_print(_("queueing message...\n"));
+ debug_print("queueing message...\n");
g_return_val_if_fail(compose->account != NULL, -1);
g_return_val_if_fail(compose->orig_account != NULL, -1);
}
/* Save copy folder */
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn))) {
- gchar *str;
+ gchar *savefolderid;
+
+ savefolderid = gtk_editable_get_chars(GTK_EDITABLE(compose->savemsg_entry), 0, -1);
+ fprintf(fp, "SCF:%s\n", savefolderid);
+ g_free(savefolderid);
+ }
+ /* Message-ID of message replying to */
+ if((compose->replyinfo != NULL) && (compose->replyinfo->msgid != NULL)) {
+ gchar *folderid;
- str = gtk_editable_get_chars(GTK_EDITABLE(compose->savemsg_entry), 0, -1);
- fprintf(fp, "SCF:%s\n", str);
- g_free(str);
+ folderid = folder_item_get_identifier(compose->replyinfo->folder);
+ fprintf(fp, "RMID:%s\x7f%d\x7f%s\n", folderid, compose->replyinfo->msgnum, compose->replyinfo->msgid);
+ g_free(folderid);
}
fprintf(fp, "\n");
(compose->targetinfo->folder, TRUE);
}
- procmsg_add_flags(queue, num, flag);
- folder_item_scan(queue);
folderview_update_item(queue, TRUE);
if((msgnum != NULL) && (item != NULL)) {
while ((len = fread(inbuf, sizeof(gchar),
B64_LINE_SIZE, attach_fp))
== B64_LINE_SIZE) {
- to64frombits(outbuf, inbuf, B64_LINE_SIZE);
+ base64_encode(outbuf, inbuf, B64_LINE_SIZE);
fputs(outbuf, fp);
fputc('\n', fp);
}
if (len > 0 && feof(attach_fp)) {
- to64frombits(outbuf, inbuf, len);
+ base64_encode(outbuf, inbuf, len);
fputs(outbuf, fp);
fputc('\n', fp);
}
#define QUOTE_IF_REQUIRED(out, str) \
{ \
- if (*str != '"' && strchr(str, ',')) { \
+ if (*str != '"' && (strchr(str, ',') \
+ || strchr(str, '.'))) { \
gchar *__tmp; \
gint len; \
\
return 0;
}
- debug_print(_("Writing %s-header\n"), header);
+ debug_print("Writing %s-header\n", header);
header_w_colon = g_strconcat(header, ":", NULL);
trans_hdr = (prefs_common.trans_hdr ? gettext(header_w_colon) : header_w_colon);
fprintf(fp, "X-Mailer: %s (GTK+ %d.%d.%d; %s)\n",
prog_version,
gtk_major_version, gtk_minor_version, gtk_micro_version,
- HOST_ALIAS);
+ TARGET_ALIAS);
/* utsbuf.sysname, utsbuf.release, utsbuf.machine); */
}
if (g_slist_length(compose->newsgroup_list) && !IS_IN_CUSTOM_HEADER("X-Newsreader")) {
fprintf(fp, "X-Newsreader: %s (GTK+ %d.%d.%d; %s)\n",
prog_version,
gtk_major_version, gtk_minor_version, gtk_micro_version,
- HOST_ALIAS);
+ TARGET_ALIAS);
/* utsbuf.sysname, utsbuf.release, utsbuf.machine); */
}
case PRIORITY_LOWEST: fprintf(fp, "Importance: low\n"
"X-Priority: 5 (Lowest)\n");
break;
- default: debug_print(_("compose: priority unknown : %d\n"),
+ default: debug_print("compose: priority unknown : %d\n",
compose->priority);
}
lt->tm_min, lt->tm_sec,
(guint)random(), addr);
- debug_print(_("generated Message-ID: %s\n"), buf);
+ debug_print("generated Message-ID: %s\n", buf);
g_free(addr);
}
-static void compose_add_entry_field(GtkWidget *table, GtkWidget **hbox,
- GtkWidget **entry, gint *count,
- const gchar *label_str,
- gboolean is_addr_entry)
-{
- GtkWidget *label;
-
- if (GTK_TABLE(table)->nrows < (*count) + 1)
- gtk_table_resize(GTK_TABLE(table), (*count) + 1, 2);
-
- *hbox = gtk_hbox_new(FALSE, 0);
- label = gtk_label_new
- (prefs_common.trans_hdr ? gettext(label_str) : label_str);
- gtk_box_pack_end(GTK_BOX(*hbox), label, FALSE, FALSE, 0);
- gtk_table_attach(GTK_TABLE(table), *hbox, 0, 1, *count, (*count) + 1,
- GTK_FILL, 0, 2, 0);
- *entry = gtk_entry_new_with_max_length(MAX_ENTRY_LENGTH);
- gtk_table_attach
- (GTK_TABLE(table), *entry, 1, 2, *count, (*count) + 1, GTK_FILL | GTK_EXPAND, GTK_SHRINK, 0, 0);
-#if 0 /* NEW COMPOSE GUI */
- if (GTK_TABLE(table)->nrows > (*count) + 1)
- gtk_table_set_row_spacing(GTK_TABLE(table), *count, 4);
-#endif
-
- if (is_addr_entry)
- address_completion_register_entry(GTK_ENTRY(*entry));
-
- (*count)++;
-}
-
static void compose_create_header_entry(Compose *compose)
{
gchar *headers[] = {"To:", "Cc:", "Bcc:", "Newsgroups:", "Reply-To:", "Followup-To:", NULL};
GtkWidget *scrolledwin;
GtkWidget *text;
- GtkWidget *table;
-
UndoMain *undostruct;
gchar *titles[N_ATTACH_COLS];
g_return_val_if_fail(account != NULL, NULL);
- debug_print(_("Creating compose window...\n"));
+ debug_print("Creating compose window...\n");
compose = g_new0(Compose, 1);
titles[COL_MIMETYPE] = _("MIME type");
GTK_SIGNAL_FUNC(compose_grab_focus_cb), compose);
gtk_signal_connect(GTK_OBJECT(text), "activate",
GTK_SIGNAL_FUNC(text_activated), compose);
+ gtk_signal_connect(GTK_OBJECT(text), "insert_text",
+ GTK_SIGNAL_FUNC(text_inserted), compose);
gtk_signal_connect_after(GTK_OBJECT(text), "button_press_event",
GTK_SIGNAL_FUNC(compose_button_press_cb),
edit_vbox);
compose->modified = FALSE;
compose->return_receipt = FALSE;
+ compose->paste_as_quotation = FALSE;
compose->to_list = NULL;
compose->newsgroup_list = NULL;
GtkWidget *menuitem;
if (!gtkpspell_set_sug_mode(gtkpspell, prefs_common.pspell_sugmode)) {
- debug_print(_("Pspell: could not set suggestion mode %s"),
+ debug_print("Pspell: could not set suggestion mode %s\n",
gtkpspellcheckers->error_message);
gtkpspell_checkers_reset_error();
}
static void compose_update_priority_menu_item(Compose * compose)
{
GtkItemFactory *ifactory;
- GtkWidget *menuitem;
+ GtkWidget *menuitem = NULL;
ifactory = gtk_item_factory_from_widget(compose->menubar);
gtk_stext_clear(GTK_STEXT(compose->text));
if (compose->replyinfo == NULL) {
- MsgInfo dummyinfo;
-
- memset(&dummyinfo, 0, sizeof(MsgInfo));
- parsed_str = compose_quote_fmt(compose, &dummyinfo,
- tmpl->value, NULL, NULL);
+ parsed_str = compose_quote_fmt(compose, NULL, tmpl->value,
+ NULL, NULL);
} else {
if (prefs_common.quotemark && *prefs_common.quotemark)
qmark = prefs_common.quotemark;
static void compose_exec_ext_editor(Compose *compose)
{
- gchar tmp[64];
+ gchar *tmp;
pid_t pid;
gint pipe_fds[2];
- g_snprintf(tmp, sizeof(tmp), "%s%ctmpmsg.%08x",
- g_get_tmp_dir(), G_DIR_SEPARATOR, (gint)compose);
+ tmp = g_strdup_printf("%s%ctmpmsg.%08x", get_tmp_dir(),
+ G_DIR_SEPARATOR, (gint)compose);
if (pipe(pipe_fds) < 0) {
perror("pipe");
+ g_free(tmp);
return;
}
if ((pid = fork()) < 0) {
perror("fork");
+ g_free(tmp);
return;
}
close(pipe_fds[1]);
_exit(0);
}
+
+ g_free(tmp);
}
static gint compose_exec_ext_editor_real(const gchar *file)
Compose *compose = (Compose *)data;
gint i = 0;
- debug_print(_("Compose: input from monitoring process\n"));
+ debug_print("Compose: input from monitoring process\n");
gdk_input_remove(compose->exteditor_tag);
FolderItem *draft;
gchar *tmp;
gint msgnum;
- MsgFlags flag = {0, 0};
static gboolean lock = FALSE;
-
+ MsgInfo *newmsginfo;
+
if (lock) return;
draft = account_get_special_folder(compose->account, F_DRAFT);
lock = TRUE;
- tmp = g_strdup_printf("%s%cdraft.%d", g_get_tmp_dir(),
+ tmp = g_strdup_printf("%s%cdraft.%08x", get_tmp_dir(),
G_DIR_SEPARATOR, (gint)compose);
if (compose_write_to_file(compose, tmp, TRUE) < 0) {
return;
}
- folder_item_scan(draft);
if ((msgnum = folder_item_add_msg(draft, tmp, TRUE)) < 0) {
unlink(tmp);
g_free(tmp);
TRUE);
}
- procmsg_add_flags(draft, msgnum, flag);
- folder_item_scan(draft);
+ newmsginfo = folder_item_fetch_msginfo(draft, msgnum);
+ procmsg_msginfo_unset_flags(newmsginfo, ~0, ~0);
folderview_update_item(draft, TRUE);
-
+ procmsg_msginfo_free(newmsginfo);
+
lock = FALSE;
/* 0: quit editing 1: keep editing */
g_free(path);
procmsg_msginfo_free(compose->targetinfo);
- compose->targetinfo = g_new0(MsgInfo, 1);
+ compose->targetinfo = procmsg_msginfo_new();
compose->targetinfo->msgnum = msgnum;
compose->targetinfo->size = s.st_size;
compose->targetinfo->mtime = s.st_mtime;
(GTK_EDITABLE(compose->focused_editable));
}
-static void compose_allsel_cb(Compose *compose)
+static void compose_paste_as_quote_cb(Compose *compose)
{
if (compose->focused_editable &&
- GTK_WIDGET_HAS_FOCUS(compose->focused_editable))
- gtk_editable_select_region
- (GTK_EDITABLE(compose->focused_editable), 0, -1);
+ GTK_WIDGET_HAS_FOCUS(compose->focused_editable)) {
+ compose->paste_as_quotation = TRUE;
+ gtk_editable_paste_clipboard
+ (GTK_EDITABLE(compose->focused_editable));
+ compose->paste_as_quotation = FALSE;
+ }
}
-static void compose_move_beginning_of_line_cb(Compose *compose)
+static void compose_allsel_cb(Compose *compose)
{
if (compose->focused_editable &&
- GTK_WIDGET_HAS_FOCUS(compose->focused_editable))
- gtk_stext_move_beginning_of_line(GTK_STEXT(compose->focused_editable));
+ GTK_WIDGET_HAS_FOCUS(compose->focused_editable))
+ gtk_editable_select_region
+ (GTK_EDITABLE(compose->focused_editable), 0, -1);
}
static void compose_gtk_stext_action_cb(Compose *compose, ComposeCallGtkSTextAction action)
compose_send_control_enter(compose);
}
+static void text_inserted(GtkWidget *widget, const gchar *text,
+ gint length, gint *position, Compose *compose)
+{
+ GtkEditable *editable = GTK_EDITABLE(widget);
+
+ gtk_signal_handler_block_by_func(GTK_OBJECT(widget),
+ GTK_SIGNAL_FUNC(text_inserted),
+ compose);
+ if (compose->paste_as_quotation) {
+ gchar *new_text;
+ gchar *qmark;
+ gint pos;
+
+ new_text = g_strndup(text, length);
+ if (prefs_common.quotemark && *prefs_common.quotemark)
+ qmark = prefs_common.quotemark;
+ else
+ qmark = "> ";
+ gtk_stext_set_point(GTK_STEXT(widget), *position);
+ compose_quote_fmt(compose, NULL, "%Q", qmark, new_text);
+ pos = gtk_stext_get_point(GTK_STEXT(widget));
+ gtk_editable_set_position(editable, pos);
+ *position = pos;
+ g_free(new_text);
+ } else
+ gtk_editable_insert_text(editable, text, length, position);
+
+ if (prefs_common.autowrap)
+ compose_wrap_line_all(compose);
+
+ gtk_signal_handler_unblock_by_func(GTK_OBJECT(widget),
+ GTK_SIGNAL_FUNC(text_inserted),
+ compose);
+ gtk_signal_emit_stop_by_name(GTK_OBJECT(editable), "insert_text");
+}
+
static gboolean compose_send_control_enter(Compose *compose)
{
GdkEvent *ev;