/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2007 Hiroyuki Yamamoto and the Claws Mail team
+ * Copyright (C) 1999-2009 Hiroyuki Yamamoto and the Claws Mail team
*
* 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
#include "privacy.h"
#include "timing.h"
#include "autofaces.h"
+#include "spell_entry.h"
enum
{
COMPOSE_QUOTE_SKIP
} ComposeQuoteMode;
+typedef enum {
+ TO_FIELD_PRESENT,
+ SUBJECT_FIELD_PRESENT,
+ BODY_FIELD_PRESENT,
+ NO_FIELD_PRESENT
+} MailField;
+
#define B64_LINE_SIZE 57
#define B64_BUFFSIZE 77
(Compose *compose);
static void compose_set_out_encoding (Compose *compose);
static void compose_set_template_menu (Compose *compose);
-static void compose_template_apply (Compose *compose,
- Template *tmpl,
- gboolean replace);
static void compose_destroy (Compose *compose);
-static void compose_entries_set (Compose *compose,
+static MailField compose_entries_set (Compose *compose,
const gchar *mailto,
ComposeEntryType to_type);
static gint compose_parse_header (Compose *compose,
static void compose_insert_sig (Compose *compose,
gboolean replace);
-static gchar *compose_get_signature_str (Compose *compose);
static ComposeInsertResult compose_insert_file (Compose *compose,
const gchar *file);
gchar **msgpath,
gboolean check_subject,
gboolean remove_reedit_target);
-static void compose_add_attachments (Compose *compose,
+static int compose_add_attachments (Compose *compose,
MimeInfo *parent);
static gchar *compose_get_header (Compose *compose);
static void compose_attach_remove_selected (GtkAction *action,
gpointer data);
+static void compose_template_apply (Compose *compose,
+ Template *tmpl,
+ gboolean replace);
static void compose_attach_property (GtkAction *action,
gpointer data);
static void compose_attach_property_create (gboolean *cancelled);
gpointer data);
static void compose_create_header_entry (Compose *compose);
-static void compose_add_header_entry (Compose *compose, const gchar *header, gchar *text);
+static void compose_add_header_entry (Compose *compose, const gchar *header,
+ gchar *text, ComposePrefType pref_type);
static void compose_remove_header_entries(Compose *compose);
static void compose_update_priority_menu_item(Compose * compose);
-#if USE_ASPELL
+#if USE_ENCHANT
static void compose_spell_menu_changed (void *data);
+static void compose_dict_changed (void *data);
#endif
static void compose_add_field_list ( Compose *compose,
GList *listAddress );
gpointer data);
static void compose_toggle_autowrap_cb (GtkToggleAction *action,
gpointer data);
+static void compose_toggle_autoindent_cb(GtkToggleAction *action,
+ gpointer data);
static void compose_toggle_ruler_cb (GtkToggleAction *action,
gpointer data);
static gboolean compose_headerentry_key_press_event_cb(GtkWidget *entry,
GdkEventKey *event,
ComposeHeaderEntry *headerentry);
+static gboolean compose_headerentry_button_clicked_cb (GtkWidget *button,
+ ComposeHeaderEntry *headerentry);
static void compose_show_first_last_header (Compose *compose, gboolean show_first);
}
-#if USE_ASPELL
+#if USE_ENCHANT
static void compose_check_all (GtkAction *action, gpointer data);
static void compose_highlight_all (GtkAction *action, gpointer data);
static void compose_check_backwards (GtkAction *action, gpointer data);
static MsgInfo *compose_msginfo_new_from_compose(Compose *compose);
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
static void compose_set_dictionaries_from_folder_prefs(Compose *compose,
FolderItem *folder_item);
#endif
static void compose_attach_update_label(Compose *compose);
-static void compose_attach_from_list(Compose *compose, GList *file_list, gboolean free_data);
-
static GtkActionEntry compose_popup_entries[] =
{
{"Compose", NULL, "Compose" },
/* menus */
{"Message", NULL, N_("_Message") },
{"Edit", NULL, N_("_Edit") },
-#if USE_ASPELL
+#if USE_ENCHANT
{"Spelling", NULL, N_("_Spelling") },
#endif
{"Options", NULL, N_("_Options") },
{"Edit/WrapAllLines", NULL, N_("Wrap all long _lines"), "<control><alt>L", NULL, G_CALLBACK(compose_wrap_all_cb) }, /* 1 */
/* {"Edit/---", NULL, "---" }, */
{"Edit/ExtEditor", NULL, N_("Edit with e_xternal editor"), "<shift><control>X", NULL, G_CALLBACK(compose_ext_editor_cb) },
-#if USE_ASPELL
+#if USE_ENCHANT
/* Spelling menu */
{"Spelling/CheckAllSel", NULL, N_("_Check all or check selection"), NULL, NULL, G_CALLBACK(compose_check_all) },
{"Spelling/HighlightAll", NULL, N_("_Highlight all misspelled words"), NULL, NULL, G_CALLBACK(compose_highlight_all) },
static GtkToggleActionEntry compose_toggle_entries[] =
{
{"Edit/AutoWrap", NULL, N_("Aut_o wrapping"), "<shift><control>L", NULL, G_CALLBACK(compose_toggle_autowrap_cb) }, /* TOGGLE */
+ {"Edit/AutoIndent", NULL, N_("Auto _indent"), NULL, NULL, G_CALLBACK(compose_toggle_autoindent_cb) }, /* TOGGLE */
{"Options/Sign", NULL, N_("Si_gn"), NULL, NULL, G_CALLBACK(compose_toggle_sign_cb) }, /* Toggle */
{"Options/Encrypt", NULL, N_("_Encrypt"), NULL, NULL, G_CALLBACK(compose_toggle_encrypt_cb) }, /* Toggle */
{"Options/RequestRetRcpt", NULL, N_("_Request Return Receipt"), NULL, NULL, G_CALLBACK(compose_toggle_return_receipt_cb) }, /* TOGGLE */
static GtkRadioActionEntry compose_radio_enc_entries[] =
{
- ENC_ACTION(CS_AUTO, C_AUTO, "_Automatic"), /* RADIO compose_set_encoding_cb */
- ENC_ACTION(CS_US_ASCII, C_US_ASCII, "7bit ASCII (US-ASC_II)"), /* RADIO compose_set_encoding_cb */
- ENC_ACTION(CS_UTF_8, C_UTF_8, "Unicode (_UTF-8)"), /* RADIO compose_set_encoding_cb */
+ ENC_ACTION(CS_AUTO, C_AUTO, N_("_Automatic")), /* RADIO compose_set_encoding_cb */
+ ENC_ACTION(CS_US_ASCII, C_US_ASCII, N_("7bit ASCII (US-ASC_II)")), /* RADIO compose_set_encoding_cb */
+ ENC_ACTION(CS_UTF_8, C_UTF_8, N_("Unicode (_UTF-8)")), /* RADIO compose_set_encoding_cb */
ENC_ACTION("Western/"CS_ISO_8859_1, C_ISO_8859_1, "ISO-8859-_1"), /* RADIO compose_set_encoding_cb */
ENC_ACTION("Western/"CS_ISO_8859_15, C_ISO_8859_15, "ISO-8859-15"), /* RADIO compose_set_encoding_cb */
ENC_ACTION("Western/"CS_WINDOWS_1252, C_WINDOWS_1252, "Windows-1252"), /* RADIO compose_set_encoding_cb */
- ENC_ACTION(CS_ISO_8859_2, C_ISO_8859_2, "Central European (ISO-8859-_2)"), /* RADIO compose_set_encoding_cb */
+ ENC_ACTION(CS_ISO_8859_2, C_ISO_8859_2, N_("Central European (ISO-8859-_2)")), /* RADIO compose_set_encoding_cb */
ENC_ACTION("Baltic/"CS_ISO_8859_13, C_ISO_8859_13, "ISO-8859-13"), /* RADIO compose_set_encoding_cb */
ENC_ACTION("Baltic/"CS_ISO_8859_4, C_ISO_8859_14, "ISO-8859-_4"), /* RADIO compose_set_encoding_cb */
- ENC_ACTION(CS_ISO_8859_7, C_ISO_8859_7, "Greek (ISO-8859-_7)"), /* RADIO compose_set_encoding_cb */
+ ENC_ACTION(CS_ISO_8859_7, C_ISO_8859_7, N_("Greek (ISO-8859-_7)")), /* RADIO compose_set_encoding_cb */
ENC_ACTION("Hebrew/"CS_ISO_8859_8, C_ISO_8859_8, "ISO-8859-_8"), /* RADIO compose_set_encoding_cb */
ENC_ACTION("Hebrew/"CS_WINDOWS_1255, C_WINDOWS_1255, "Windows-1255"), /* RADIO compose_set_encoding_cb */
ENC_ACTION("Arabic/"CS_ISO_8859_6, C_ISO_8859_6, "ISO-8859-_6"), /* RADIO compose_set_encoding_cb */
ENC_ACTION("Arabic/"CS_WINDOWS_1256, C_WINDOWS_1256, "Windows-1256"), /* RADIO compose_set_encoding_cb */
- ENC_ACTION(CS_ISO_8859_9, C_ISO_8859_9, "Turkish (ISO-8859-_9)"), /* RADIO compose_set_encoding_cb */
+ ENC_ACTION(CS_ISO_8859_9, C_ISO_8859_9, N_("Turkish (ISO-8859-_9)")), /* RADIO compose_set_encoding_cb */
ENC_ACTION("Cyrillic/"CS_ISO_8859_5, C_ISO_8859_5, "ISO-8859-_5"), /* RADIO compose_set_encoding_cb */
ENC_ACTION("Cyrillic/"CS_KOI8_R, C_KOI8_R, "KOI8-_R"), /* RADIO compose_set_encoding_cb */
ENC_ACTION("Cyrillic/"CS_KOI8_U, C_KOI8_U, "KOI8-_U"), /* RADIO compose_set_encoding_cb */
cmark); \
}
+static void compose_set_save_to(Compose *compose, const gchar *folderidentifier)
+{
+ GtkEditable *entry;
+ if (folderidentifier) {
+ combobox_unset_popdown_strings(GTK_COMBO_BOX(compose->savemsg_combo));
+ prefs_common.compose_save_to_history = add_history(
+ prefs_common.compose_save_to_history, folderidentifier);
+ combobox_set_popdown_strings(GTK_COMBO_BOX(compose->savemsg_combo),
+ prefs_common.compose_save_to_history);
+ }
+
+ entry = GTK_EDITABLE(gtk_bin_get_child(GTK_BIN(compose->savemsg_combo)));
+ if (folderidentifier)
+ gtk_entry_set_text(GTK_ENTRY(entry), folderidentifier);
+ else
+ gtk_entry_set_text(GTK_ENTRY(entry), "");
+}
+
+static gchar *compose_get_save_to(Compose *compose)
+{
+ GtkEditable *entry;
+ gchar *result = NULL;
+ entry = GTK_EDITABLE(gtk_bin_get_child(GTK_BIN(compose->savemsg_combo)));
+ result = gtk_editable_get_chars(entry, 0, -1);
+
+ if (result) {
+ combobox_unset_popdown_strings(GTK_COMBO_BOX(compose->savemsg_combo));
+ prefs_common.compose_save_to_history = add_history(
+ prefs_common.compose_save_to_history, result);
+ combobox_set_popdown_strings(GTK_COMBO_BOX(compose->savemsg_combo),
+ prefs_common.compose_save_to_history);
+ }
+ return result;
+}
+
Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderItem *item,
GPtrArray *attach_files, GList *listAddress )
{
gchar *mailto_from = NULL;
PrefsAccount *mailto_account = NULL;
MsgInfo* dummyinfo = NULL;
+ MailField mfield = NO_FIELD_PRESENT;
+ gchar* buf;
+ GtkTextMark *mark;
/* check if mailto defines a from */
if (mailto && *mailto != '\0') {
- scan_mailto_url(mailto, &mailto_from, NULL, NULL, NULL, NULL, NULL, NULL);
+ scan_mailto_url(mailto, &mailto_from, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
/* mailto defines a from, check if we can get account prefs from it,
if not, the account prefs will be guessed using other ways, but we'll keep
the from anyway */
/* if no account prefs set, fallback to the current one */
if (!account) account = cur_account;
- g_return_val_if_fail(account != NULL, NULL);
+ cm_return_val_if_fail(account != NULL, NULL);
compose = compose_create(account, item, COMPOSE_NEW, FALSE);
tmp = malloc(strlen(item->prefs->compose_override_from_format)+1);
pref_get_unescaped_pref(tmp, item->prefs->compose_override_from_format);
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
quote_fmt_init(dummyinfo, NULL, NULL, FALSE, compose->account, FALSE,
compose->gtkaspell);
#else
compose_create_tags(textview, compose);
undo_block(compose->undostruct);
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
compose_set_dictionaries_from_folder_prefs(compose, item);
#endif
if (account->protocol != A_NNTP) {
if (mailto && *mailto != '\0') {
- compose_entries_set(compose, mailto, COMPOSE_TO);
+ mfield = compose_entries_set(compose, mailto, COMPOSE_TO);
- } else if (item && item->prefs->enable_default_to) {
- compose_entry_append(compose, item->prefs->default_to, COMPOSE_TO);
- compose_entry_mark_default_to(compose, item->prefs->default_to);
+ } else if (item && item->prefs) {
+ if (item->prefs->enable_default_bcc) {
+ compose_entry_append(compose, item->prefs->default_bcc,
+ COMPOSE_BCC, PREF_FOLDER);
+ }
+ if (item->prefs->enable_default_cc) {
+ compose_entry_append(compose, item->prefs->default_cc,
+ COMPOSE_CC, PREF_FOLDER);
+ }
+ if (item->prefs->enable_default_replyto) {
+ compose_entry_append(compose, item->prefs->default_replyto,
+ COMPOSE_REPLYTO, PREF_FOLDER);
+ }
+ if (item->prefs->enable_default_to) {
+ compose_entry_append(compose, item->prefs->default_to,
+ COMPOSE_TO, PREF_FOLDER);
+ compose_entry_mark_default_to(compose, item->prefs->default_to);
+ }
}
if (item && item->ret_rcpt) {
cm_toggle_menu_set_active_full(compose->ui_manager, "Menu/Options/RequestRetRcpt", TRUE);
} else {
if (mailto && *mailto != '\0') {
if (!strchr(mailto, '@'))
- compose_entries_set(compose, mailto, COMPOSE_NEWSGROUPS);
+ mfield = compose_entries_set(compose, mailto, COMPOSE_NEWSGROUPS);
else
- compose_entries_set(compose, mailto, COMPOSE_TO);
+ mfield = compose_entries_set(compose, mailto, COMPOSE_TO);
} else if (item && FOLDER_CLASS(item->folder) == news_get_class()) {
- compose_entry_append(compose, item->path, COMPOSE_NEWSGROUPS);
+ compose_entry_append(compose, item->path, COMPOSE_NEWSGROUPS, PREF_FOLDER);
+ mfield = TO_FIELD_PRESENT;
}
/*
* CLAWS: just don't allow return receipt request, even if the user
pref_get_unescaped_pref(tmp, subject_format);
subject = gtk_editable_get_chars(GTK_EDITABLE(compose->subject_entry), 0, -1);
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
quote_fmt_init(dummyinfo, NULL, subject, FALSE, compose->account, FALSE,
compose->gtkaspell);
#else
g_free(subject);
g_free(tmp);
+ mfield = SUBJECT_FIELD_PRESENT;
}
if ( body_format
compose_quote_fmt(compose, dummyinfo,
body_format,
NULL, tmp, FALSE, TRUE,
- _("New message body format error at line %d."));
+ _("The body of the \"New message\" template has an error at line %d."));
compose_attach_from_list(compose, quote_fmt_get_attachments_list(), FALSE);
quote_fmt_reset_vartable();
g_free(tmp);
+#ifdef USE_ENCHANT
+ if (compose->gtkaspell && compose->gtkaspell->check_while_typing)
+ gtkaspell_highlight_all(compose->gtkaspell);
+#endif
+ mfield = BODY_FIELD_PRESENT;
}
}
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn), prefs_common.savemsg);
folderidentifier = folder_item_get_identifier(item);
- gtk_entry_set_text(GTK_ENTRY(compose->savemsg_entry), folderidentifier);
+ compose_set_save_to(compose, folderidentifier);
g_free(folderidentifier);
}
-
- gtk_widget_grab_focus(compose->header_last->entry);
+
+ /* Place cursor according to provided input (mfield) */
+ switch (mfield) {
+ case NO_FIELD_PRESENT:
+ if (compose->header_last)
+ gtk_widget_grab_focus(compose->header_last->entry);
+ break;
+ case TO_FIELD_PRESENT:
+ buf = gtk_editable_get_chars(GTK_EDITABLE(compose->subject_entry), 0, -1);
+ if (buf) {
+ gtk_entry_set_text(GTK_ENTRY(compose->subject_entry), buf);
+ g_free(buf);
+ }
+ gtk_widget_grab_focus(compose->subject_entry);
+ break;
+ case SUBJECT_FIELD_PRESENT:
+ textview = GTK_TEXT_VIEW(compose->text);
+ if (!textview)
+ break;
+ textbuf = gtk_text_view_get_buffer(textview);
+ if (!textbuf)
+ break;
+ mark = gtk_text_buffer_get_insert(textbuf);
+ gtk_text_buffer_get_iter_at_mark(textbuf, &iter, mark);
+ gtk_text_buffer_insert(textbuf, &iter, "", -1);
+ /*
+ * SUBJECT_FIELD_PRESENT and BODY_FIELD_PRESENT
+ * only defers where it comes to the variable body
+ * is not null. If no body is present compose->text
+ * will be null in which case you cannot place the
+ * cursor inside the component so. An empty component
+ * is therefore created before placing the cursor
+ */
+ case BODY_FIELD_PRESENT:
+ gtk_widget_grab_focus(compose->text);
+ break;
+ }
undo_unblock(compose->undostruct);
compose->modified = FALSE;
compose_set_title(compose);
+
+ hooks_invoke(COMPOSE_CREATED_HOOKLIST, compose);
+
return compose;
}
static void compose_force_encryption(Compose *compose, PrefsAccount *account,
- gboolean override_pref)
+ gboolean override_pref, const gchar *system)
{
- gchar *privacy = NULL;
+ const gchar *privacy = NULL;
- g_return_if_fail(compose != NULL);
- g_return_if_fail(account != NULL);
+ cm_return_if_fail(compose != NULL);
+ cm_return_if_fail(account != NULL);
if (override_pref == FALSE && account->default_encrypt_reply == FALSE)
return;
- if (account->default_privacy_system
+ if (system)
+ privacy = system;
+ else if (account->default_privacy_system
&& strlen(account->default_privacy_system)) {
privacy = account->default_privacy_system;
} else {
}
}
if (privacy != NULL) {
+ if (system) {
+ g_free(compose->privacy_system);
+ compose->privacy_system = NULL;
+ }
if (compose->privacy_system == NULL)
compose->privacy_system = g_strdup(privacy);
else if (*(compose->privacy_system) == '\0') {
}
}
-static void compose_force_signing(Compose *compose, PrefsAccount *account)
+static void compose_force_signing(Compose *compose, PrefsAccount *account, const gchar *system)
{
- gchar *privacy = NULL;
+ const gchar *privacy = NULL;
- if (account->default_privacy_system
+ if (system)
+ privacy = system;
+ else if (account->default_privacy_system
&& strlen(account->default_privacy_system)) {
privacy = account->default_privacy_system;
} else {
privacy = (gchar *)(privacy_avail->data);
}
}
+
if (privacy != NULL) {
+ if (system) {
+ g_free(compose->privacy_system);
+ compose->privacy_system = NULL;
+ }
if (compose->privacy_system == NULL)
compose->privacy_system = g_strdup(privacy);
compose_update_privacy_system_menu_item(compose, FALSE);
guint list_len;
Compose *compose = NULL;
- g_return_val_if_fail(msginfo_list != NULL, NULL);
+ cm_return_val_if_fail(msginfo_list != NULL, NULL);
msginfo = (MsgInfo*)g_slist_nth_data(msginfo_list, 0);
- g_return_val_if_fail(msginfo != NULL, NULL);
+ cm_return_val_if_fail(msginfo != NULL, NULL);
list_len = g_slist_length(msginfo_list);
gboolean quote = FALSE;
const gchar *qmark = NULL;
const gchar *body_fmt = NULL;
+ gchar *s_system = NULL;
START_TIMING("");
- g_return_val_if_fail(msginfo != NULL, NULL);
- g_return_val_if_fail(msginfo->folder != NULL, NULL);
+ cm_return_val_if_fail(msginfo != NULL, NULL);
+ cm_return_val_if_fail(msginfo->folder != NULL, NULL);
account = account_get_reply_account(msginfo, prefs_common.reply_account_autosel);
- g_return_val_if_fail(account != NULL, NULL);
+ cm_return_val_if_fail(account != NULL, NULL);
compose = compose_create(account, msginfo->folder, COMPOSE_REPLY, FALSE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn), TRUE);
folderidentifier = folder_item_get_identifier(msginfo->folder);
- gtk_entry_set_text(GTK_ENTRY(compose->savemsg_entry), folderidentifier);
+ compose_set_save_to(compose, folderidentifier);
g_free(folderidentifier);
}
tmp = malloc(strlen(msginfo->folder->prefs->reply_override_from_format)+1);
pref_get_unescaped_pref(tmp, msginfo->folder->prefs->reply_override_from_format);
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
quote_fmt_init(compose->replyinfo, NULL, NULL, FALSE, compose->account, FALSE,
compose->gtkaspell);
#else
buf = quote_fmt_get_buffer();
if (buf == NULL)
- alertpanel_error(_("Message reply From format error."));
+ alertpanel_error(_("The \"From\" field of the \"Reply\" template contains an invalid email address."));
else
gtk_entry_set_text(GTK_ENTRY(compose->from_name), buf);
quote_fmt_reset_vartable();
compose_create_tags(textview, compose);
undo_block(compose->undostruct);
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
compose_set_dictionaries_from_folder_prefs(compose, msginfo->folder);
#endif
qmark = "> ";
compose_quote_fmt(compose, compose->replyinfo,
body_fmt, qmark, body, FALSE, TRUE,
- _("Message reply format error at line %d."));
+ _("The body of the \"Reply\" template has an error at line %d."));
compose_attach_from_list(compose, quote_fmt_get_attachments_list(), FALSE);
quote_fmt_reset_vartable();
+#ifdef USE_ENCHANT
+ if (compose->gtkaspell && compose->gtkaspell->check_while_typing)
+ gtkaspell_highlight_all(compose->gtkaspell);
+#endif
}
if (MSG_IS_ENCRYPTED(compose->replyinfo->flags)) {
- compose_force_encryption(compose, account, FALSE);
+ compose_force_encryption(compose, account, FALSE, s_system);
+ }
+
+ privacy_msginfo_get_signed_state(compose->replyinfo, &s_system);
+ if (MSG_IS_SIGNED(compose->replyinfo->flags) && account->default_sign_reply) {
+ compose_force_signing(compose, account, s_system);
}
+ g_free(s_system);
SIGNAL_BLOCK(textbuf);
return NULL;
}
END_TIMING();
+
return compose;
}
GtkTextBuffer *textbuf;
GtkTextIter iter;
- g_return_val_if_fail(msginfo != NULL, NULL);
- g_return_val_if_fail(msginfo->folder != NULL, NULL);
+ cm_return_val_if_fail(msginfo != NULL, NULL);
+ cm_return_val_if_fail(msginfo->folder != NULL, NULL);
if (!account &&
!(account = compose_guess_forward_account_from_msginfo
tmp = malloc(strlen(msginfo->folder->prefs->forward_override_from_format)+1);
pref_get_unescaped_pref(tmp, msginfo->folder->prefs->forward_override_from_format);
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
quote_fmt_init(full_msginfo, NULL, NULL, FALSE, compose->account, FALSE,
compose->gtkaspell);
#else
buf = quote_fmt_get_buffer();
if (buf == NULL)
- alertpanel_error(_("Message forward From format error."));
+ alertpanel_error(_("The \"From\" field of the \"Forward\" template contains an invalid email address."));
else
gtk_entry_set_text(GTK_ENTRY(compose->from_name), buf);
quote_fmt_reset_vartable();
compose_quote_fmt(compose, full_msginfo,
body_fmt, qmark, body, FALSE, TRUE,
- _("Message forward format error at line %d."));
+ _("The body of the \"Forward\" template has an error at line %d."));
compose_attach_from_list(compose, quote_fmt_get_attachments_list(), FALSE);
quote_fmt_reset_vartable();
compose_attach_parts(compose, msginfo);
procmsg_msginfo_free(full_msginfo);
+#ifdef USE_ENCHANT
+ if (compose->gtkaspell && compose->gtkaspell->check_while_typing)
+ gtkaspell_highlight_all(compose->gtkaspell);
+#endif
}
SIGNAL_BLOCK(textbuf);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn), TRUE);
folderidentifier = folder_item_get_identifier(msginfo->folder);
- gtk_entry_set_text(GTK_ENTRY(compose->savemsg_entry), folderidentifier);
+ compose_set_save_to(compose, folderidentifier);
g_free(folderidentifier);
}
return NULL;
}
+ hooks_invoke(COMPOSE_CREATED_HOOKLIST, compose);
+
return compose;
}
gchar *msgfile;
gboolean single_mail = TRUE;
- g_return_val_if_fail(msginfo_list != NULL, NULL);
+ cm_return_val_if_fail(msginfo_list != NULL, NULL);
if (g_slist_length(msginfo_list) > 1)
single_mail = FALSE;
(msginfo_list->data)))
account = cur_account;
- g_return_val_if_fail(account != NULL, NULL);
+ cm_return_val_if_fail(account != NULL, NULL);
for (msginfo = msginfo_list; msginfo != NULL; msginfo = msginfo->next) {
- MSG_UNSET_PERM_FLAGS(((MsgInfo *)msginfo->data)->flags, MSG_REPLIED);
- MSG_SET_PERM_FLAGS(((MsgInfo *)msginfo->data)->flags, MSG_FORWARDED);
+ if (msginfo->data) {
+ MSG_UNSET_PERM_FLAGS(((MsgInfo *)msginfo->data)->flags, MSG_REPLIED);
+ MSG_SET_PERM_FLAGS(((MsgInfo *)msginfo->data)->flags, MSG_FORWARDED);
+ }
+ }
+
+ if (msginfo_list == NULL || msginfo_list->data == NULL) {
+ g_warning("no msginfo_list");
+ return NULL;
}
compose = compose_create(account, ((MsgInfo *)msginfo_list->data)->folder, COMPOSE_FORWARD, FALSE);
tmp = malloc(strlen(msginfo->folder->prefs->forward_override_from_format)+1);
pref_get_unescaped_pref(tmp, msginfo->folder->prefs->forward_override_from_format);
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account, FALSE,
compose->gtkaspell);
#else
buf = quote_fmt_get_buffer();
if (buf == NULL)
- alertpanel_error(_("Message forward From format error."));
+ alertpanel_error(_("The \"From\" field of the \"Forward\" template contains an invalid email address."));
else
gtk_entry_set_text(GTK_ENTRY(compose->from_name), buf);
quote_fmt_reset_vartable();
return NULL;
}
+ hooks_invoke(COMPOSE_CREATED_HOOKLIST, compose);
+
return compose;
}
gchar *privacy_system = NULL;
int priority = PRIORITY_NORMAL;
MsgInfo *replyinfo = NULL, *fwdinfo = NULL;
+ gboolean autowrap = prefs_common.autowrap;
+ gboolean autoindent = prefs_common.auto_indent;
- g_return_val_if_fail(msginfo != NULL, NULL);
- g_return_val_if_fail(msginfo->folder != NULL, NULL);
+ cm_return_val_if_fail(msginfo != NULL, NULL);
+ cm_return_val_if_fail(msginfo->folder != NULL, NULL);
if (compose_put_existing_to_front(msginfo)) {
return NULL;
}
if (folder_has_parent_of_type(msginfo->folder, F_QUEUE) ||
- folder_has_parent_of_type(msginfo->folder, F_DRAFT)) {
+ folder_has_parent_of_type(msginfo->folder, F_DRAFT) ||
+ folder_has_parent_of_type(msginfo->folder, F_OUTBOX)) {
gchar queueheader_buf[BUFFSIZE];
gint id, param;
param = atoi(&queueheader_buf[strlen("X-Sylpheed-Encrypt:")]);
use_encryption = param;
}
+ if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf,
+ sizeof(queueheader_buf), "X-Claws-Auto-Wrapping:")) {
+ param = atoi(&queueheader_buf[strlen("X-Claws-Auto-Wrapping:")]);
+ autowrap = param;
+ }
+ if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf,
+ sizeof(queueheader_buf), "X-Claws-Auto-Indent:")) {
+ param = atoi(&queueheader_buf[strlen("X-Claws-Auto-Indent:")]);
+ autoindent = param;
+ }
if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf,
sizeof(queueheader_buf), "X-Claws-Privacy-System:")) {
privacy_system = g_strdup(&queueheader_buf[strlen("X-Claws-Privacy-System:")]);
if (!account) {
account = cur_account;
}
- g_return_val_if_fail(account != NULL, NULL);
+ cm_return_val_if_fail(account != NULL, NULL);
compose = compose_create(account, msginfo->folder, COMPOSE_REEDIT, batch);
-
+
+ cm_toggle_menu_set_active_full(compose->ui_manager, "Menu/Edit/AutoWrap", autowrap);
+ cm_toggle_menu_set_active_full(compose->ui_manager, "Menu/Edit/AutoIndent", autoindent);
+ compose->autowrap = autowrap;
compose->replyinfo = replyinfo;
compose->fwdinfo = fwdinfo;
compose_extract_original_charset(compose);
if (folder_has_parent_of_type(msginfo->folder, F_QUEUE) ||
- folder_has_parent_of_type(msginfo->folder, F_DRAFT)) {
+ folder_has_parent_of_type(msginfo->folder, F_DRAFT) ||
+ folder_has_parent_of_type(msginfo->folder, F_OUTBOX)) {
gchar queueheader_buf[BUFFSIZE];
/* Set message save folder */
if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, sizeof(queueheader_buf), "SCF:")) {
- gint startpos = 0;
-
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn), TRUE);
- gtk_editable_delete_text(GTK_EDITABLE(compose->savemsg_entry), 0, -1);
- gtk_editable_insert_text(GTK_EDITABLE(compose->savemsg_entry), &queueheader_buf[4], strlen(&queueheader_buf[4]), &startpos);
+ compose_set_save_to(compose, &queueheader_buf[4]);
}
if (!procheader_get_header_from_msginfo(msginfo, queueheader_buf, sizeof(queueheader_buf), "RRCPT:")) {
gint active = atoi(&queueheader_buf[strlen("RRCPT:")]);
if (MSG_IS_ENCRYPTED(msginfo->flags)) {
fp = procmime_get_first_encrypted_text_content(msginfo);
if (fp) {
- compose_force_encryption(compose, account, TRUE);
+ compose_force_encryption(compose, account, TRUE, NULL);
}
} else {
fp = procmime_get_first_text_content(msginfo);
return NULL;
}
- compose->sig_str = compose_get_signature_str(compose);
+ compose->sig_str = account_get_signature_str(compose->account);
+ hooks_invoke(COMPOSE_CREATED_HOOKLIST, compose);
+
return compose;
}
gchar *filename;
FolderItem *item;
- g_return_val_if_fail(msginfo != NULL, NULL);
+ cm_return_val_if_fail(msginfo != NULL, NULL);
if (!account)
account = account_get_reply_account(msginfo,
prefs_common.reply_account_autosel);
- g_return_val_if_fail(account != NULL, NULL);
+ cm_return_val_if_fail(account != NULL, NULL);
compose = compose_create(account, msginfo->folder, COMPOSE_REDIRECT, batch);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn), prefs_common.savemsg);
folderidentifier = folder_item_get_identifier(item);
- gtk_entry_set_text(GTK_ENTRY(compose->savemsg_entry), folderidentifier);
+ compose_set_save_to(compose, folderidentifier);
g_free(folderidentifier);
}
gtk_editable_set_editable(GTK_EDITABLE(compose->subject_entry), FALSE);
compose_quote_fmt(compose, msginfo, "%M", NULL, NULL, FALSE, FALSE,
- _("Message redirect format error at line %d."));
+ _("The body of the \"Redirect\" template has an error at line %d."));
quote_fmt_reset_vartable();
gtk_text_view_set_editable(GTK_TEXT_VIEW(compose->text), FALSE);
return NULL;
}
+ hooks_invoke(COMPOSE_CREATED_HOOKLIST, compose);
+
return compose;
}
}
void compose_entry_append(Compose *compose, const gchar *address,
- ComposeEntryType type)
+ ComposeEntryType type, ComposePrefType pref_type)
{
const gchar *header;
gchar *cur, *begin;
case COMPOSE_FOLLOWUPTO:
header = N_( "Followup-To:");
break;
+ case COMPOSE_INREPLYTO:
+ header = N_( "In-Reply-To:");
+ break;
case COMPOSE_TO:
default:
header = N_("To:");
begin = cur;
while (*tmp == ' ' || *tmp == '\t')
tmp++;
- compose_add_header_entry(compose, header, tmp);
+ compose_add_header_entry(compose, header, tmp, pref_type);
g_free(o_tmp);
continue;
}
begin = cur;
while (*tmp == ' ' || *tmp == '\t')
tmp++;
- compose_add_header_entry(compose, header, tmp);
+ compose_add_header_entry(compose, header, tmp, pref_type);
g_free(o_tmp);
}
}
ToolbarItem *toolbar_item = (ToolbarItem*)data;
Compose *compose = (Compose*)toolbar_item->parent;
- g_return_if_fail(compose != NULL);
+ cm_return_if_fail(compose != NULL);
switch(action) {
case A_SEND:
case A_ADDRBOOK:
compose_address_cb(NULL, compose);
break;
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
case A_CHECK_SPELLING:
compose_check_all(NULL, compose);
break;
}
}
-static void compose_entries_set(Compose *compose, const gchar *mailto, ComposeEntryType to_type)
+static MailField compose_entries_set(Compose *compose, const gchar *mailto, ComposeEntryType to_type)
{
gchar *to = NULL;
gchar *cc = NULL;
gchar *temp = NULL;
gsize len = 0;
gchar **attach = NULL;
+ gchar *inreplyto = NULL;
+ MailField mfield = NO_FIELD_PRESENT;
/* get mailto parts but skip from */
- scan_mailto_url(mailto, NULL, &to, &cc, &bcc, &subject, &body, &attach);
+ scan_mailto_url(mailto, NULL, &to, &cc, &bcc, &subject, &body, &attach, &inreplyto);
- if (to)
- compose_entry_append(compose, to, to_type);
+ if (to) {
+ compose_entry_append(compose, to, to_type, PREF_MAILTO);
+ mfield = TO_FIELD_PRESENT;
+ }
if (cc)
- compose_entry_append(compose, cc, COMPOSE_CC);
+ compose_entry_append(compose, cc, COMPOSE_CC, PREF_MAILTO);
if (bcc)
- compose_entry_append(compose, bcc, COMPOSE_BCC);
+ compose_entry_append(compose, bcc, COMPOSE_BCC, PREF_MAILTO);
if (subject) {
if (!g_utf8_validate (subject, -1, NULL)) {
temp = g_locale_to_utf8 (subject, -1, NULL, &len, NULL);
} else {
gtk_entry_set_text(GTK_ENTRY(compose->subject_entry), subject);
}
+ mfield = SUBJECT_FIELD_PRESENT;
}
if (body) {
GtkTextView *text = GTK_TEXT_VIEW(compose->text);
compose->autowrap = prev_autowrap;
if (compose->autowrap)
compose_wrap_all(compose);
+ mfield = BODY_FIELD_PRESENT;
}
if (attach) {
g_free(warn_files);
}
}
+ if (inreplyto)
+ compose_entry_append(compose, inreplyto, COMPOSE_INREPLYTO, PREF_MAILTO);
+
g_free(to);
g_free(cc);
g_free(bcc);
g_free(subject);
g_free(body);
g_strfreev(attach);
+ g_free(inreplyto);
+
+ return mfield;
}
static gint compose_parse_header(Compose *compose, MsgInfo *msginfo)
FILE *fp;
- g_return_val_if_fail(msginfo != NULL, -1);
+ cm_return_val_if_fail(msginfo != NULL, -1);
if ((fp = procmsg_open_message(msginfo)) == NULL) return -1;
procheader_get_header_fields(fp, hentry);
hentry[H_FOLLOWUP_TO].body = NULL;
}
if (hentry[H_LIST_POST].body != NULL) {
- gchar *to = NULL;
+ gchar *to = NULL, *start = NULL;
extract_address(hentry[H_LIST_POST].body);
if (hentry[H_LIST_POST].body[0] != '\0') {
- scan_mailto_url(hentry[H_LIST_POST].body,
- NULL, &to, NULL, NULL, NULL, NULL, NULL);
+ start = strstr(hentry[H_LIST_POST].body, "mailto:");
+
+ scan_mailto_url(start ? start : hentry[H_LIST_POST].body,
+ NULL, &to, NULL, NULL, NULL, NULL, NULL, NULL);
+
if (to) {
g_free(compose->ml_post);
compose->ml_post = to;
}
if (qmark != NULL) {
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account, FALSE,
compose->gtkaspell);
#else
buf = quote_fmt_get_buffer();
if (buf == NULL)
- alertpanel_error(_("Quote mark format error."));
+ alertpanel_error(_("The \"Quotation mark\" of the template is invalid."));
else
Xstrdup_a(quote_str, buf, goto error)
}
while (*trimmed_body == '\n')
trimmed_body++;
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
quote_fmt_init(msginfo, quote_str, trimmed_body, FALSE, compose->account, FALSE,
compose->gtkaspell);
#else
return result;
}
-static gboolean same_address(const gchar *addr1, const gchar *addr2)
-{
- gchar *my_addr1, *my_addr2;
-
- if (!addr1 || !addr2)
- return FALSE;
-
- Xstrdup_a(my_addr1, addr1, return FALSE);
- Xstrdup_a(my_addr2, addr2, return FALSE);
-
- extract_address(my_addr1);
- extract_address(my_addr2);
-
- return !strcasecmp(my_addr1, my_addr2);
-}
-
static void compose_reply_set_entry(Compose *compose, MsgInfo *msginfo,
gboolean to_all, gboolean to_ml,
gboolean to_sender,
GSList *cur;
gchar *from = NULL;
gchar *replyto = NULL;
- GHashTable *to_table;
+ gchar *ac_email = NULL;
gboolean reply_to_ml = FALSE;
gboolean default_reply_to = FALSE;
- g_return_if_fail(compose->account != NULL);
- g_return_if_fail(msginfo != NULL);
+ cm_return_if_fail(compose->account != NULL);
+ cm_return_if_fail(msginfo != NULL);
reply_to_ml = to_ml && compose->ml_post;
msginfo->folder->prefs->enable_default_reply_to;
if (compose->account->protocol != A_NNTP) {
+ if (msginfo && msginfo->folder && msginfo->folder->prefs) {
+ if (msginfo->folder->prefs->enable_default_replyto) {
+ compose_entry_append(compose, msginfo->folder->prefs->default_replyto,
+ COMPOSE_REPLYTO, PREF_FOLDER);
+ }
+ if (msginfo->folder->prefs->enable_default_bcc) {
+ compose_entry_append(compose, msginfo->folder->prefs->default_bcc,
+ COMPOSE_BCC, PREF_FOLDER);
+ }
+ if (msginfo->folder->prefs->enable_default_cc) {
+ compose_entry_append(compose, msginfo->folder->prefs->default_cc,
+ COMPOSE_CC, PREF_FOLDER);
+ }
+ }
if (reply_to_ml && !default_reply_to) {
gboolean is_subscr = is_subscription(compose->ml_post,
/* normal answer to ml post with a reply-to */
compose_entry_append(compose,
compose->ml_post,
- COMPOSE_TO);
- if (compose->replyto
- && !same_address(compose->ml_post, compose->replyto))
+ COMPOSE_TO, PREF_ML);
+ if (compose->replyto)
compose_entry_append(compose,
compose->replyto,
- COMPOSE_CC);
+ COMPOSE_CC, PREF_ML);
} else {
/* answer to subscription confirmation */
if (compose->replyto)
compose_entry_append(compose,
compose->replyto,
- COMPOSE_TO);
+ COMPOSE_TO, PREF_ML);
else if (msginfo->from)
compose_entry_append(compose,
msginfo->from,
- COMPOSE_TO);
+ COMPOSE_TO, PREF_ML);
}
}
else if (!(to_all || to_sender) && default_reply_to) {
compose_entry_append(compose,
msginfo->folder->prefs->default_reply_to,
- COMPOSE_TO);
+ COMPOSE_TO, PREF_FOLDER);
compose_entry_mark_default_to(compose,
msginfo->folder->prefs->default_reply_to);
} else {
(compose->replyto && !to_sender)
? compose->replyto :
msginfo->from ? msginfo->from : "",
- COMPOSE_TO);
+ COMPOSE_TO, PREF_NONE);
else if (!to_all && !to_sender) {
if (!folder_has_parent_of_type(msginfo->folder, F_QUEUE) &&
!folder_has_parent_of_type(msginfo->folder, F_OUTBOX) &&
if (compose->replyto) {
compose_entry_append(compose,
compose->replyto,
- COMPOSE_TO);
+ COMPOSE_TO, PREF_NONE);
} else {
compose_entry_append(compose,
msginfo->from ? msginfo->from : "",
- COMPOSE_TO);
+ COMPOSE_TO, PREF_NONE);
}
} else {
/* replying to own mail, use original recp */
compose_entry_append(compose,
msginfo->to ? msginfo->to : "",
- COMPOSE_TO);
+ COMPOSE_TO, PREF_NONE);
compose_entry_append(compose,
msginfo->cc ? msginfo->cc : "",
- COMPOSE_CC);
+ COMPOSE_CC, PREF_NONE);
}
}
}
(compose,
(compose->replyto ? compose->replyto :
msginfo->from ? msginfo->from : ""),
- COMPOSE_TO);
+ COMPOSE_TO, PREF_NONE);
else if (followup_and_reply_to || to_all) {
compose_entry_append
(compose,
(compose->replyto ? compose->replyto :
msginfo->from ? msginfo->from : ""),
- COMPOSE_TO);
+ COMPOSE_TO, PREF_NONE);
compose_entry_append
(compose,
compose->followup_to ? compose->followup_to :
compose->newsgroups ? compose->newsgroups : "",
- COMPOSE_NEWSGROUPS);
+ COMPOSE_NEWSGROUPS, PREF_NONE);
}
else
compose_entry_append
(compose,
compose->followup_to ? compose->followup_to :
compose->newsgroups ? compose->newsgroups : "",
- COMPOSE_NEWSGROUPS);
+ COMPOSE_NEWSGROUPS, PREF_NONE);
}
if (msginfo->subject && *msginfo->subject) {
cc_list = address_list_append_with_comments(cc_list, msginfo->to);
cc_list = address_list_append_with_comments(cc_list, compose->cc);
- to_table = g_hash_table_new(g_str_hash, g_str_equal);
- if (replyto)
- g_hash_table_insert(to_table, g_utf8_strdown(replyto, -1), GINT_TO_POINTER(1));
- if (compose->account) {
- g_hash_table_insert(to_table, g_utf8_strdown(compose->account->address, -1),
- GINT_TO_POINTER(1));
- }
- /* remove address on To: and that of current account */
- for (cur = cc_list; cur != NULL; ) {
- GSList *next = cur->next;
- gchar *addr;
-
- addr = g_utf8_strdown(cur->data, -1);
- extract_address(addr);
-
- if (GPOINTER_TO_INT(g_hash_table_lookup(to_table, addr)) == 1)
- cc_list = g_slist_remove(cc_list, cur->data);
- else
- g_hash_table_insert(to_table, addr, GINT_TO_POINTER(1));
-
- cur = next;
- }
- hash_free_strings(to_table);
- g_hash_table_destroy(to_table);
+ ac_email = g_utf8_strdown(compose->account->address, -1);
if (cc_list) {
- for (cur = cc_list; cur != NULL; cur = cur->next)
- compose_entry_append(compose, (gchar *)cur->data,
- COMPOSE_CC);
+ for (cur = cc_list; cur != NULL; cur = cur->next) {
+ gchar *addr = g_utf8_strdown(cur->data, -1);
+ extract_address(addr);
+
+ if (strcmp(ac_email, addr))
+ compose_entry_append(compose, (gchar *)cur->data,
+ COMPOSE_CC, PREF_NONE);
+ else
+ debug_print("Cc address same as compose account's, ignoring\n");
+
+ g_free(addr);
+ }
+
slist_free_strings(cc_list);
g_slist_free(cc_list);
}
-
+
+ g_free(ac_email);
}
#define SET_ENTRY(entry, str) \
#define SET_ADDRESS(type, str) \
{ \
if (str && *str) \
- compose_entry_append(compose, str, type); \
+ compose_entry_append(compose, str, type, PREF_NONE); \
}
static void compose_reedit_set_entry(Compose *compose, MsgInfo *msginfo)
{
- g_return_if_fail(msginfo != NULL);
+ cm_return_if_fail(msginfo != NULL);
SET_ENTRY(subject_entry, msginfo->subject);
SET_ENTRY(from_name, msginfo->from);
SET_ADDRESS(COMPOSE_REPLYTO, compose->replyto);
SET_ADDRESS(COMPOSE_NEWSGROUPS, compose->newsgroups);
SET_ADDRESS(COMPOSE_FOLLOWUPTO, compose->followup_to);
+ SET_ADDRESS(COMPOSE_INREPLYTO, compose->inreplyto);
compose_update_priority_menu_item(compose);
compose_update_privacy_system_menu_item(compose, FALSE);
gboolean found = FALSE;
gboolean exists = FALSE;
- g_return_if_fail(compose->account != NULL);
+ cm_return_if_fail(compose->account != NULL);
BLOCK_WRAP();
}
g_free(compose->sig_str);
- compose->sig_str = compose_get_signature_str(compose);
+ compose->sig_str = account_get_signature_str(compose->account);
cur_pos = gtk_text_iter_get_offset(&iter);
else
gtk_text_buffer_get_iter_at_offset(buffer, &iter,
compose->set_cursor_pos);
-
+
+ compose->set_cursor_pos = -1;
gtk_text_buffer_place_cursor(buffer, &iter);
g_signal_handlers_unblock_by_func(G_OBJECT(buffer),
G_CALLBACK(compose_changed_cb),
UNBLOCK_WRAP();
}
-static gchar *compose_get_signature_str(Compose *compose)
-{
- gchar *sig_body = NULL;
- gchar *sig_str = NULL;
- gchar *utf8_sig_str = NULL;
-
- g_return_val_if_fail(compose->account != NULL, NULL);
-
- if (!compose->account->sig_path)
- return NULL;
-
- if (compose->account->sig_type == SIG_FILE) {
- if (!is_file_or_fifo_exist(compose->account->sig_path)) {
- g_warning("can't open signature file: %s\n",
- compose->account->sig_path);
- return NULL;
- }
- }
-
- if (compose->account->sig_type == SIG_COMMAND)
- sig_body = get_command_output(compose->account->sig_path);
- else {
- gchar *tmp;
-
- tmp = file_read_to_str(compose->account->sig_path);
- if (!tmp)
- return NULL;
- sig_body = normalize_newlines(tmp);
- g_free(tmp);
- }
-
- if (compose->account->sig_sep) {
- sig_str = g_strconcat("\n", compose->account->sig_sep, "\n", sig_body,
- NULL);
- g_free(sig_body);
- } else
- sig_str = g_strconcat("\n", sig_body, NULL);
-
- if (sig_str) {
- if (g_utf8_validate(sig_str, -1, NULL) == TRUE)
- utf8_sig_str = sig_str;
- else {
- utf8_sig_str = conv_codeset_strdup
- (sig_str, conv_get_locale_charset_str_no_utf8(),
- CS_INTERNAL);
- g_free(sig_str);
- }
- }
-
- return utf8_sig_str;
-}
-
static ComposeInsertResult compose_insert_file(Compose *compose, const gchar *file)
{
GtkTextView *text;
FILE *fp;
gboolean prev_autowrap;
gboolean badtxt = FALSE;
+ struct stat file_stat;
+ int ret;
+
+ cm_return_val_if_fail(file != NULL, COMPOSE_INSERT_NO_FILE);
+
+ /* get the size of the file we are about to insert */
+ ret = g_stat(file, &file_stat);
+ if (ret != 0) {
+ gchar *shortfile = g_path_get_basename(file);
+ alertpanel_error(_("Could not get size of file '%s'."), shortfile);
+ g_free(shortfile);
+ return COMPOSE_INSERT_NO_FILE;
+ } else if (prefs_common.warn_large_insert == TRUE) {
+
+ /* ask user for confirmation if the file is large */
+ if (prefs_common.warn_large_insert_size < 0 ||
+ file_stat.st_size > (prefs_common.warn_large_insert_size * 1024)) {
+ AlertValue aval;
+ gchar *msg;
+
+ msg = g_strdup_printf(_("You are about to insert a file of %s "
+ "in the message body. Are you sure you want to do that?"),
+ to_human_readable(file_stat.st_size));
+ aval = alertpanel_full(_("Are you sure?"), msg, GTK_STOCK_CANCEL,
+ _("+_Insert"), NULL, TRUE, NULL, ALERT_QUESTION, G_ALERTDEFAULT);
+ g_free(msg);
+
+ /* do we ask for confirmation next time? */
+ if (aval & G_ALERTDISABLE) {
+ /* no confirmation next time, disable feature in preferences */
+ aval &= ~G_ALERTDISABLE;
+ prefs_common.warn_large_insert = FALSE;
+ }
+
+ /* abort file insertion if user canceled action */
+ if (aval != G_ALERTALTERNATE) {
+ return COMPOSE_INSERT_NO_FILE;
+ }
+ }
+ }
- g_return_val_if_fail(file != NULL, COMPOSE_INSERT_NO_FILE);
if ((fp = g_fopen(file, "rb")) == NULL) {
FILE_OP_ERROR(file, "fopen");
while (child && child->node->children && (child->type == MIMETYPE_MULTIPART))
child = (MimeInfo *)child->node->children->data;
- if (child->type == MIMETYPE_TEXT) {
- firsttext = child;
- debug_print("First text part found\n");
- } else if (compose->mode == COMPOSE_REEDIT &&
- child->type == MIMETYPE_APPLICATION &&
- !g_ascii_strcasecmp(child->subtype, "pgp-encrypted")) {
- encrypted = (MimeInfo *)child->node->parent->data;
+ if (child) {
+ if (child->type == MIMETYPE_TEXT) {
+ firsttext = child;
+ debug_print("First text part found\n");
+ } else if (compose->mode == COMPOSE_REEDIT &&
+ child->type == MIMETYPE_APPLICATION &&
+ !g_ascii_strcasecmp(child->subtype, "pgp-encrypted")) {
+ encrypted = (MimeInfo *)child->node->parent->data;
+ }
}
-
child = (MimeInfo *) mimeinfo->node->children->data;
while (child != NULL) {
gint err;
compose_attach_append(compose, outfile,
partname, content_type);
} else {
- compose_force_signing(compose, compose->account);
+ compose_force_signing(compose, compose->account, NULL);
}
g_free(content_type);
}
return NULL;
}
-/* return TRUE if the line is itemized */
-static gboolean compose_is_itemized(GtkTextBuffer *buffer,
+/* return >0 if the line is itemized */
+static int compose_itemized_length(GtkTextBuffer *buffer,
const GtkTextIter *start)
{
GtkTextIter iter = *start;
gunichar wc;
gchar ch[6];
gint clen;
-
+ gint len = 0;
if (gtk_text_iter_ends_line(&iter))
- return FALSE;
+ return 0;
while (1) {
+ len++;
wc = gtk_text_iter_get_char(&iter);
if (!g_unichar_isspace(wc))
break;
gtk_text_iter_forward_char(&iter);
if (gtk_text_iter_ends_line(&iter))
- return FALSE;
+ return 0;
}
clen = g_unichar_to_utf8(wc, ch);
if (clen != 1)
- return FALSE;
+ return 0;
if (!strchr("*-+", ch[0]))
- return FALSE;
+ return 0;
gtk_text_iter_forward_char(&iter);
if (gtk_text_iter_ends_line(&iter))
- return FALSE;
+ return 0;
wc = gtk_text_iter_get_char(&iter);
- if (g_unichar_isspace(wc))
- return TRUE;
+ if (g_unichar_isspace(wc)) {
+ return len+1;
+ }
+ return 0;
+}
- return FALSE;
+/* return the string at the start of the itemization */
+static gchar * compose_get_itemized_chars(GtkTextBuffer *buffer,
+ const GtkTextIter *start)
+{
+ GtkTextIter iter = *start;
+ gunichar wc;
+ gint len = 0;
+ GString *item_chars = g_string_new("");
+ gchar *str = NULL;
+
+ if (gtk_text_iter_ends_line(&iter))
+ return NULL;
+
+ while (1) {
+ len++;
+ wc = gtk_text_iter_get_char(&iter);
+ if (!g_unichar_isspace(wc))
+ break;
+ gtk_text_iter_forward_char(&iter);
+ if (gtk_text_iter_ends_line(&iter))
+ break;
+ g_string_append_unichar(item_chars, wc);
+ }
+
+ str = item_chars->str;
+ g_string_free(item_chars, FALSE);
+ return str;
+}
+
+/* return the number of spaces at a line's start */
+static int compose_left_offset_length(GtkTextBuffer *buffer,
+ const GtkTextIter *start)
+{
+ GtkTextIter iter = *start;
+ gunichar wc;
+ gint len = 0;
+ if (gtk_text_iter_ends_line(&iter))
+ return 0;
+
+ while (1) {
+ wc = gtk_text_iter_get_char(&iter);
+ if (!g_unichar_isspace(wc))
+ break;
+ len++;
+ gtk_text_iter_forward_char(&iter);
+ if (gtk_text_iter_ends_line(&iter))
+ return 0;
+ }
+
+ gtk_text_iter_forward_char(&iter);
+ if (gtk_text_iter_ends_line(&iter))
+ return 0;
+ return len;
}
static gboolean compose_get_line_break_pos(GtkTextBuffer *buffer,
can_break = TRUE;
}
- debug_print("compose_get_line_break_pos(): do_break = %d, pos = %d, col = %d\n", do_break, pos, col);
+// debug_print("compose_get_line_break_pos(): do_break = %d, pos = %d, col = %d\n", do_break, pos, col);
g_free(attrs);
g_free(str);
}
/* don't join itemized lines */
- if (compose_is_itemized(buffer, &end)) {
+ if (compose_itemized_length(buffer, &end) > 0) {
return FALSE;
}
gboolean modified_before_remove = FALSE;
gint lines = 0;
gboolean start = TRUE;
+ gint itemized_len = 0, rem_item_len = 0;
+ gchar *itemized_chars = NULL;
+ gboolean item_continuation = FALSE;
if (force) {
modified = TRUE;
/* move to line start */
gtk_text_iter_set_line_offset(&iter, 0);
}
+
+ itemized_len = compose_itemized_length(buffer, &iter);
+
+ if (!itemized_len) {
+ itemized_len = compose_left_offset_length(buffer, &iter);
+ item_continuation = TRUE;
+ }
+
+ if (itemized_len)
+ itemized_chars = compose_get_itemized_chars(buffer, &iter);
+
/* go until paragraph end (empty line) */
while (start || !gtk_text_iter_ends_line(&iter)) {
gchar *scanpos = NULL;
{"https://", strcasestr, get_uri_part, make_uri_string},
{"ftp://", strcasestr, get_uri_part, make_uri_string},
{"sftp://", strcasestr, get_uri_part, make_uri_string},
+ {"gopher://",strcasestr, get_uri_part, make_uri_string},
{"www.", strcasestr, get_uri_part, make_http_string},
{"mailto:", strcasestr, get_uri_part, make_uri_string},
{"@", strcasestr, get_email_part, make_email_string}
quote_str = compose_get_quote_str(buffer, &iter, "e_len);
if (quote_str) {
- debug_print("compose_beautify_paragraph(): quote_str = '%s'\n", quote_str);
+// debug_print("compose_beautify_paragraph(): quote_str = '%s'\n", quote_str);
if (startq_offset == -1)
startq_offset = gtk_text_iter_get_offset(&iter);
quotelevel = get_quote_level(quote_str, prefs_common.quote_chars);
prefs_common.linewrap_len,
quote_len)) {
GtkTextIter prev, next, cur;
-
if (prev_autowrap != FALSE || force) {
compose->automatic_break = TRUE;
modified = TRUE;
gtk_text_buffer_insert(buffer, &break_pos, "\n", 1);
compose->automatic_break = FALSE;
+ if (itemized_len && compose->autoindent) {
+ gtk_text_buffer_insert(buffer, &break_pos, itemized_chars, -1);
+ if (!item_continuation)
+ gtk_text_buffer_insert(buffer, &break_pos, " ", 2);
+ }
} else if (quote_str && wrap_quote) {
compose->automatic_break = TRUE;
modified = TRUE;
gtk_text_buffer_insert(buffer, &break_pos, "\n", 1);
compose->automatic_break = FALSE;
+ if (itemized_len && compose->autoindent) {
+ gtk_text_buffer_insert(buffer, &break_pos, itemized_chars, -1);
+ if (!item_continuation)
+ gtk_text_buffer_insert(buffer, &break_pos, " ", 2);
+ }
} else
goto colorize;
/* remove trailing spaces */
cur = break_pos;
+ rem_item_len = itemized_len;
+ while (compose->autoindent && rem_item_len-- > 0)
+ gtk_text_iter_backward_char(&cur);
gtk_text_iter_backward_char(&cur);
+
prev = next = cur;
while (!gtk_text_iter_starts_line(&cur)) {
gunichar wc;
}
}
if (!modified) {
- debug_print("not modified, out after %d lines\n", lines);
+// debug_print("not modified, out after %d lines\n", lines);
goto end;
}
}
-
- debug_print("modified, out after %d lines\n", lines);
+// debug_print("modified, out after %d lines\n", lines);
end:
+ g_free(itemized_chars);
if (par_iter)
*par_iter = iter;
undo_wrapping(compose->undostruct, FALSE);
static void compose_select_account(Compose *compose, PrefsAccount *account,
gboolean init)
{
- gchar *from = NULL;
+ gchar *from = NULL, *header;
+ ComposeHeaderEntry *header_entry;
- g_return_if_fail(account != NULL);
+ cm_return_if_fail(account != NULL);
compose->account = account;
-
if (account->name && *account->name) {
gchar *buf;
QUOTE_IF_REQUIRED_NORMAL(buf, account->name, return);
compose_insert_sig(compose, TRUE);
undo_unblock(compose->undostruct);
}
-
-#ifdef USE_ASPELL
+
+ header_entry = (ComposeHeaderEntry *) compose->header_list->data;
+ header = gtk_combo_box_get_active_text(GTK_COMBO_BOX(header_entry->combo));
+
+ if (header && !strlen(gtk_entry_get_text(GTK_ENTRY(header_entry->entry)))) {
+ if (account->protocol == A_NNTP) {
+ if (!strcmp(header, _("To:")))
+ combobox_select_by_text(
+ GTK_COMBO_BOX(header_entry->combo),
+ _("Newsgroups:"));
+ } else {
+ if (!strcmp(header, _("Newsgroups:")))
+ combobox_select_by_text(
+ GTK_COMBO_BOX(header_entry->combo),
+ _("To:"));
+ }
+
+ }
+ g_free(header);
+
+#ifdef USE_ENCHANT
/* use account's dict info if set */
if (compose->gtkaspell) {
if (account->enable_default_dictionary)
for (list = compose->header_list; list; list = list->next) {
gchar *header;
gchar *entry;
- header = gtk_editable_get_chars(GTK_EDITABLE(GTK_BIN(((ComposeHeaderEntry *)list->data)->combo)->child), 0, -1);
+ header = gtk_editable_get_chars(GTK_EDITABLE(gtk_bin_get_child(GTK_BIN((((ComposeHeaderEntry *)list->data)->combo)))), 0, -1);
entry = gtk_editable_get_chars(GTK_EDITABLE(((ComposeHeaderEntry *)list->data)->entry), 0, -1);
g_strstrip(entry);
g_strstrip(header);
if (entry[0] != '\0') {
for (strptr = recipient_headers_mail; *strptr != NULL; strptr++) {
- if (!strcmp(header, prefs_common_translated_header_name(*strptr))) {
+ if (!g_ascii_strcasecmp(header, prefs_common_translated_header_name(*strptr))) {
compose->to_list = address_list_append(compose->to_list, entry);
recipient_found = TRUE;
}
}
for (strptr = recipient_headers_news; *strptr != NULL; strptr++) {
- if (!strcmp(header, prefs_common_translated_header_name(*strptr))) {
+ if (!g_ascii_strcasecmp(header, prefs_common_translated_header_name(*strptr))) {
compose->newsgroup_list = newsgroup_list_append(compose->newsgroup_list, entry);
recipient_found = TRUE;
}
gchar *entry;
gchar *header;
entry = gtk_editable_get_chars(GTK_EDITABLE(((ComposeHeaderEntry *)list->data)->entry), 0, -1);
- header = gtk_editable_get_chars(GTK_EDITABLE(GTK_BIN(((ComposeHeaderEntry *)list->data)->combo)->child), 0, -1);
+ header = gtk_editable_get_chars(GTK_EDITABLE(gtk_bin_get_child(GTK_BIN((((ComposeHeaderEntry *)list->data)->combo)))), 0, -1);
g_strstrip(entry);
g_strstrip(header);
if (strcmp(entry, compose->account->auto_cc)
gchar *entry;
gchar *header;
entry = gtk_editable_get_chars(GTK_EDITABLE(((ComposeHeaderEntry *)list->data)->entry), 0, -1);
- header = gtk_editable_get_chars(GTK_EDITABLE(GTK_BIN(((ComposeHeaderEntry *)list->data)->combo)->child), 0, -1);
+ header = gtk_editable_get_chars(GTK_EDITABLE(gtk_bin_get_child(GTK_BIN((((ComposeHeaderEntry *)list->data)->combo)))), 0, -1);
g_strstrip(entry);
g_strstrip(header);
if (strcmp(entry, compose->account->auto_bcc)
first_to_address = TRUE;
for (list = compose->header_list; list; list = list->next) {
headerentry = ((ComposeHeaderEntry *)list->data);
- headerentryname = gtk_entry_get_text(GTK_ENTRY(GTK_BIN(headerentry->combo)->child));
+ headerentryname = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((headerentry->combo)))));
if (g_utf8_collate(headerentryname, to_hdr) == 0) {
const gchar *entstr = gtk_entry_get_text(GTK_ENTRY(headerentry->entry));
first_cc_address = TRUE;
for (list = compose->header_list; list; list = list->next) {
headerentry = ((ComposeHeaderEntry *)list->data);
- headerentryname = gtk_entry_get_text(GTK_ENTRY(GTK_BIN(headerentry->combo)->child));
+ headerentryname = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((headerentry->combo)))));
if (g_utf8_collate(headerentryname, cc_hdr) == 0) {
const gchar *strg = gtk_entry_get_text(GTK_ENTRY(headerentry->entry));
/* struct utsname utsbuf; */
gboolean err = FALSE;
- g_return_val_if_fail(fp != NULL, -1);
- g_return_val_if_fail(compose->account != NULL, -1);
- g_return_val_if_fail(compose->account->address != NULL, -1);
+ cm_return_val_if_fail(fp != NULL, -1);
+ cm_return_val_if_fail(compose->account != NULL, -1);
+ cm_return_val_if_fail(compose->account->address != NULL, -1);
/* Resent-Date */
get_rfc822_date(buf, sizeof(buf));
}
if (compose->account->gen_msgid) {
- generate_msgid(buf, sizeof(buf));
+ gchar *addr = NULL;
+ if (compose->account->msgid_with_addr) {
+ addr = compose->account->address;
+ }
+ generate_msgid(buf, sizeof(buf), addr);
err |= (fprintf(fp, "Resent-Message-ID: <%s>\n", buf) < 0);
compose->msgid = g_strdup(buf);
} else {
"X-Claws-End-Special-Headers:", "X-Claws-Account-Id:",
"X-Sylpheed-Privacy", "X-Sylpheed-Sign:", "X-Sylpheed-Encrypt",
"X-Sylpheed-End-Special-Headers:", "X-Sylpheed-Account-Id:",
+ "X-Claws-Auto-Wrapping:", "X-Claws-Auto-Indent:",
NULL
};
if ((fp = g_fopen(compose->redirect_filename, "rb")) == NULL) {
MimeInfo *mimemsg, *mimetext;
gint line;
const gchar *src_codeset = CS_INTERNAL;
+ gchar *from_addr = NULL;
+ gchar *from_name = NULL;
if (action == COMPOSE_WRITE_FOR_SEND)
attach_parts = TRUE;
g_node_append(mimempart->node, mimetext->node);
g_node_append(mimemsg->node, mimempart->node);
- compose_add_attachments(compose, mimempart);
+ if (compose_add_attachments(compose, mimempart) < 0)
+ return -1;
} else
g_node_append(mimemsg->node, mimetext->node);
g_free(buf);
+ if (strlen(gtk_entry_get_text(GTK_ENTRY(compose->from_name))) != 0) {
+ gchar *spec = gtk_editable_get_chars(GTK_EDITABLE(compose->from_name), 0, -1);
+ /* extract name and address */
+ if (strstr(spec, " <") && strstr(spec, ">")) {
+ from_addr = g_strdup(strrchr(spec, '<')+1);
+ *(strrchr(from_addr, '>')) = '\0';
+ from_name = g_strdup(spec);
+ *(strrchr(from_name, '<')) = '\0';
+ } else {
+ from_name = NULL;
+ from_addr = NULL;
+ }
+ g_free(spec);
+ }
/* 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))
+ if (!privacy_sign(compose->privacy_system, mimemsg,
+ compose->account, from_addr)) {
+ g_free(from_name);
+ g_free(from_addr);
return -2;
-
+ }
+ g_free(from_name);
+ g_free(from_addr);
procmime_write_mimeinfo(mimemsg, fp);
procmime_mimeinfo_free_all(mimemsg);
FolderItem *item;
MsgInfo *msginfo = compose->targetinfo;
- g_return_val_if_fail(compose->mode == COMPOSE_REEDIT, -1);
+ cm_return_val_if_fail(compose->mode == COMPOSE_REEDIT, -1);
if (!msginfo) return -1;
if (!force && MSG_IS_LOCKED(msginfo->flags))
return 0;
item = msginfo->folder;
- g_return_val_if_fail(item != NULL, -1);
+ cm_return_val_if_fail(item != NULL, -1);
if (procmsg_msg_exist(msginfo) &&
(folder_has_parent_of_type(item, F_QUEUE) ||
gboolean err = FALSE;
debug_print("queueing message...\n");
- g_return_val_if_fail(compose->account != NULL, -1);
+ cm_return_val_if_fail(compose->account != NULL, -1);
lock = TRUE;
if (compose->newsgroup_list) {
if (compose->account->protocol == A_NNTP)
newsac = compose->account;
- else if (!newsac->protocol != A_NNTP) {
+ else {
lock = FALSE;
- alertpanel_error(_("No account for posting news available!"));
+ alertpanel_error(_("Selected account isn't NNTP: Posting is impossible."));
return -1;
}
}
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn))) {
gchar *savefolderid;
- savefolderid = gtk_editable_get_chars(GTK_EDITABLE(compose->savemsg_entry), 0, -1);
+ savefolderid = compose_get_save_to(compose);
err |= (fprintf(fp, "SCF:%s\n", savefolderid) < 0);
g_free(savefolderid);
}
g_free(folderid);
}
+ err |= (fprintf(fp, "X-Claws-Auto-Wrapping:%d\n", compose->autowrap) < 0);
+ err |= (fprintf(fp, "X-Claws-Auto-Indent:%d\n", compose->autoindent) < 0);
+
/* end of headers */
err |= (fprintf(fp, "X-Claws-End-Special-Headers: 1\n") < 0);
return 0;
}
-static void compose_add_attachments(Compose *compose, MimeInfo *parent)
+static int compose_add_attachments(Compose *compose, MimeInfo *parent)
{
AttachInfo *ainfo;
GtkTreeView *tree_view = GTK_TREE_VIEW(compose->attach_clist);
model = gtk_tree_view_get_model(tree_view);
if (!gtk_tree_model_get_iter_first(model, &iter))
- return;
+ return 0;
do {
gtk_tree_model_get(model, &iter,
COL_DATA, &ainfo,
-1);
-
+
+ if (!is_file_exist(ainfo->file)) {
+ gchar *msg = g_strdup_printf(_("Attachment %s doesn't exist anymore. Ignore?"), ainfo->file);
+ AlertValue val = alertpanel_full(_("Warning"), msg, _("Cancel sending"), _("Ignore attachment"),
+ NULL, FALSE, NULL, ALERT_WARNING, G_ALERTDEFAULT);
+ g_free(msg);
+ if (val == G_ALERTDEFAULT) {
+ return -1;
+ }
+ continue;
+ }
mimepart = procmime_mimeinfo_new();
mimepart->content = MIMECONTENT_FILE;
mimepart->data.filename = g_strdup(ainfo->file);
mimepart->tmp = FALSE; /* or we destroy our attachment */
mimepart->offset = 0;
- stat(ainfo->file, &statbuf);
+ g_stat(ainfo->file, &statbuf);
mimepart->length = statbuf.st_size;
type = g_strdup(ainfo->content_type);
mimepart->disposition = DISPOSITIONTYPE_INLINE;
} else {
if (ainfo->name) {
- g_hash_table_insert(mimepart->typeparameters,
- g_strdup("name"), g_strdup(ainfo->name));
+ if (mimepart->type == MIMETYPE_APPLICATION &&
+ !strcmp2(mimepart->subtype, "octet-stream"))
+ g_hash_table_insert(mimepart->typeparameters,
+ g_strdup("name"), g_strdup(ainfo->name));
g_hash_table_insert(mimepart->dispositionparameters,
g_strdup("filename"), g_strdup(ainfo->name));
mimepart->disposition = DISPOSITIONTYPE_ATTACHMENT;
g_node_append(parent->node, mimepart->node);
} while (gtk_tree_model_iter_next(model, &iter));
+
+ return 0;
}
#define IS_IN_CUSTOM_HEADER(header) \
for (list = compose->header_list; list; list = list->next) {
headerentry = ((ComposeHeaderEntry *)list->data);
- headerentryname = gtk_entry_get_text(GTK_ENTRY(GTK_BIN(headerentry->combo)->child));
+ headerentryname = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((headerentry->combo)))));
if (!g_utf8_collate(trans_fieldname, headerentryname)) {
str = gtk_editable_get_chars(GTK_EDITABLE(headerentry->entry), 0, -1);
gchar *from_name = NULL, *from_address = NULL;
gchar *tmp;
- g_return_val_if_fail(compose->account != NULL, NULL);
- g_return_val_if_fail(compose->account->address != NULL, NULL);
+ cm_return_val_if_fail(compose->account != NULL, NULL);
+ cm_return_val_if_fail(compose->account->address != NULL, NULL);
header = g_string_sized_new(64);
}
if (compose->account->gen_msgid) {
- generate_msgid(buf, sizeof(buf));
+ gchar *addr = NULL;
+ if (compose->account->msgid_with_addr) {
+ addr = compose->account->address;
+ }
+ generate_msgid(buf, sizeof(buf), addr);
g_string_append_printf(header, "Message-ID: <%s>\n", buf);
compose->msgid = g_strdup(buf);
} else {
headerentry = ((ComposeHeaderEntry *)list->data);
- tmp = g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_BIN(headerentry->combo)->child)));
+ tmp = g_strdup(gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((headerentry->combo))))));
g_strstrip(tmp);
if (*tmp == '\0' || strchr(tmp, ' ') != NULL || strchr(tmp, '\r') != NULL || strchr(tmp, '\n') != NULL) {
g_free(tmp);
gchar *tmpstr = NULL;
const gchar *out_codeset = NULL;
- g_return_if_fail(src != NULL);
- g_return_if_fail(dest != NULL);
+ cm_return_if_fail(src != NULL);
+ cm_return_if_fail(dest != NULL);
if (len < 1) return;
{
gchar *address;
- g_return_if_fail(user_data != NULL);
+ cm_return_if_fail(user_data != NULL);
address = g_strdup(gtk_entry_get_text(GTK_ENTRY(user_data)));
g_strstrip(address);
GtkWidget *menuitem;
gchar *address;
- g_return_if_fail(menu != NULL);
- g_return_if_fail(GTK_IS_MENU_SHELL(menu));
+ cm_return_if_fail(menu != NULL);
+ cm_return_if_fail(GTK_IS_MENU_SHELL(menu));
menuitem = gtk_separator_menu_item_new();
gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), menuitem);
GtkWidget *combo;
GtkWidget *entry;
+ GtkWidget *button;
+ GtkWidget *hbox;
gchar **string;
const gchar *header = NULL;
ComposeHeaderEntry *headerentry;
gboolean standard_header = FALSE;
+ GtkListStore *model;
+ GtkTreeIter iter;
#if !(GTK_CHECK_VERSION(2,12,0))
GtkTooltips *tips = compose->tooltips;
#endif
headerentry = g_new0(ComposeHeaderEntry, 1);
/* Combo box */
- combo = gtk_combo_box_entry_new_text();
- string = headers;
- while(*string != NULL) {
- gtk_combo_box_append_text(GTK_COMBO_BOX(combo),
- (gchar*)prefs_common_translated_header_name(*string));
- string++;
- }
+ model = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_BOOLEAN);
+ combo = gtk_combo_box_entry_new_with_model(GTK_TREE_MODEL(model), 0);
+ COMBOBOX_ADD(model, prefs_common_translated_header_name("To:"),
+ COMPOSE_TO);
+ COMBOBOX_ADD(model, prefs_common_translated_header_name("Cc:"),
+ COMPOSE_CC);
+ COMBOBOX_ADD(model, prefs_common_translated_header_name("Bcc:"),
+ COMPOSE_BCC);
+ COMBOBOX_ADD(model, prefs_common_translated_header_name("Newsgroups:"),
+ COMPOSE_NEWSGROUPS);
+ COMBOBOX_ADD(model, prefs_common_translated_header_name("Reply-To:"),
+ COMPOSE_REPLYTO);
+ COMBOBOX_ADD(model, prefs_common_translated_header_name("Followup-To:"),
+ COMPOSE_FOLLOWUPTO);
+
gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
- g_signal_connect(G_OBJECT(GTK_BIN(combo)->child), "grab_focus",
+ g_signal_connect(G_OBJECT(gtk_bin_get_child(GTK_BIN((combo)))), "grab_focus",
G_CALLBACK(compose_grab_focus_cb), compose);
gtk_widget_show(combo);
gtk_table_attach(GTK_TABLE(compose->header_table), combo, 0, 1,
compose->header_nextrow, compose->header_nextrow+1,
GTK_SHRINK, GTK_FILL, 0, 0);
- if (compose->header_last) {
+ if (compose->header_last && (compose->draft_timeout_tag != -2)) {
const gchar *last_header_entry = gtk_entry_get_text(
- GTK_ENTRY(GTK_BIN(compose->header_last->combo)->child));
+ GTK_ENTRY(gtk_bin_get_child(GTK_BIN((compose->header_last->combo)))));
string = headers;
while (*string != NULL) {
- if (!strcmp(*string, last_header_entry))
+ if (!strcmp(prefs_common_translated_header_name(*string), last_header_entry))
standard_header = TRUE;
string++;
}
if (standard_header)
- header = gtk_entry_get_text(GTK_ENTRY(GTK_BIN(compose->header_last->combo)->child));
+ header = gtk_entry_get_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((compose->header_last->combo)))));
}
if (!compose->header_last || !standard_header) {
switch(compose->account->protocol) {
}
}
if (header)
- gtk_entry_set_text(GTK_ENTRY(GTK_BIN(combo)->child), header);
+ gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((combo)))), header);
- g_signal_connect_after(G_OBJECT(GTK_BIN(combo)->child), "grab_focus",
+ g_signal_connect_after(G_OBJECT(gtk_bin_get_child(GTK_BIN((combo)))), "grab_focus",
G_CALLBACK(compose_grab_focus_cb), compose);
- /* Entry field */
+ /* Entry field with cleanup button */
+#if GTK_CHECK_VERSION(2, 8, 0)
+ button = gtk_button_new();
+ gtk_button_set_image(GTK_BUTTON(button),
+ gtk_image_new_from_stock(GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU));
+#else
+ button = gtk_button_new_with_label(_("Clear"));
+#endif
+ gtk_widget_show(button);
+ CLAWS_SET_TIP(button,
+ _("Delete entry contents"));
entry = gtk_entry_new();
gtk_widget_show(entry);
CLAWS_SET_TIP(entry,
_("Use <tab> to autocomplete from addressbook"));
- gtk_table_attach(GTK_TABLE(compose->header_table), entry, 1, 2,
+ hbox = gtk_hbox_new (FALSE, 0);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+ gtk_table_attach(GTK_TABLE(compose->header_table), hbox, 1, 2,
compose->header_nextrow, compose->header_nextrow+1,
GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
headerentry);
g_signal_connect_after(G_OBJECT(entry), "grab_focus",
G_CALLBACK(compose_grab_focus_cb), compose);
+
+ g_signal_connect(G_OBJECT(button), "clicked",
+ G_CALLBACK(compose_headerentry_button_clicked_cb),
+ headerentry);
/* email dnd */
gtk_drag_dest_set(entry, GTK_DEST_DEFAULT_ALL, compose_mime_types,
headerentry->compose = compose;
headerentry->combo = combo;
headerentry->entry = entry;
+ headerentry->button = button;
+ headerentry->hbox = hbox;
headerentry->headernum = compose->header_nextrow;
+ headerentry->type = PREF_NONE;
compose->header_nextrow++;
compose->header_last = headerentry;
headerentry);
}
-static void compose_add_header_entry(Compose *compose, const gchar *header, gchar *text)
+static void compose_add_header_entry(Compose *compose, const gchar *header,
+ gchar *text, ComposePrefType pref_type)
{
- ComposeHeaderEntry *last_header;
+ ComposeHeaderEntry *last_header = compose->header_last;
+ gchar *tmp = g_strdup(text), *email;
+ gboolean replyto_hdr = g_str_has_suffix(header, "-To:");
- last_header = compose->header_last;
-
- gtk_entry_set_text(GTK_ENTRY(GTK_BIN(last_header->combo)->child), header);
+ extract_address(tmp);
+ email = g_utf8_strdown(tmp, -1);
+
+ if (replyto_hdr == FALSE &&
+ g_hash_table_lookup(compose->email_hashtable, email) != NULL)
+ {
+ debug_print("Ignoring duplicate address - %s %s, pref_type: %d\n",
+ header, text, (gint) pref_type);
+ g_free(email);
+ g_free(tmp);
+ return;
+ }
+
+ if (!strcmp(header, prefs_common_translated_header_name("In-Reply-To:")))
+ gtk_entry_set_text(GTK_ENTRY(
+ gtk_bin_get_child(GTK_BIN(last_header->combo))), header);
+ else
+ combobox_select_by_text(GTK_COMBO_BOX(last_header->combo), header);
gtk_entry_set_text(GTK_ENTRY(last_header->entry), text);
+ last_header->type = pref_type;
+
+ if (replyto_hdr == FALSE)
+ g_hash_table_insert(compose->email_hashtable, email,
+ GUINT_TO_POINTER(1));
+ else
+ g_free(email);
+
+ g_free(tmp);
+}
+
+static void compose_destroy_headerentry(Compose *compose,
+ ComposeHeaderEntry *headerentry)
+{
+ gchar *text = gtk_editable_get_chars(GTK_EDITABLE(headerentry->entry), 0, -1);
+ gchar *email;
+
+ extract_address(text);
+ email = g_utf8_strdown(text, -1);
+ g_hash_table_remove(compose->email_hashtable, email);
+ g_free(text);
+ g_free(email);
+
+ gtk_widget_destroy(headerentry->combo);
+ gtk_widget_destroy(headerentry->entry);
+ gtk_widget_destroy(headerentry->button);
+ gtk_widget_destroy(headerentry->hbox);
+ g_free(headerentry);
}
static void compose_remove_header_entries(Compose *compose)
{
GSList *list;
- for (list = compose->header_list; list; list = list->next) {
- ComposeHeaderEntry *headerentry =
- (ComposeHeaderEntry *)list->data;
- gtk_widget_destroy(headerentry->combo);
- gtk_widget_destroy(headerentry->entry);
- g_free(headerentry);
- }
+ for (list = compose->header_list; list; list = list->next)
+ compose_destroy_headerentry(compose, (ComposeHeaderEntry *)list->data);
+
compose->header_last = NULL;
g_slist_free(compose->header_list);
compose->header_list = NULL;
gtk_widget_show(header_table);
gtk_container_set_border_width(GTK_CONTAINER(header_table), BORDER_WIDTH);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(header_scrolledwin), header_table);
- gtk_viewport_set_shadow_type(GTK_VIEWPORT(GTK_BIN(header_scrolledwin)->child), GTK_SHADOW_NONE);
+ gtk_viewport_set_shadow_type(GTK_VIEWPORT(gtk_bin_get_child(GTK_BIN((header_scrolledwin)))), GTK_SHADOW_NONE);
count = 0;
/* option menu for selecting accounts */
{
GtkWidget *table;
GtkWidget *savemsg_checkbtn;
- GtkWidget *savemsg_entry;
+ GtkWidget *savemsg_combo;
GtkWidget *savemsg_select;
guint rowcount = 0;
g_signal_connect(G_OBJECT(savemsg_checkbtn), "toggled",
G_CALLBACK(compose_savemsg_checkbtn_cb), compose);
- savemsg_entry = gtk_entry_new();
- gtk_widget_show(savemsg_entry);
- gtk_table_attach_defaults(GTK_TABLE(table), savemsg_entry, 1, 2, rowcount, rowcount + 1);
- gtk_editable_set_editable(GTK_EDITABLE(savemsg_entry), prefs_common.savemsg);
- g_signal_connect_after(G_OBJECT(savemsg_entry), "grab_focus",
+ savemsg_combo = gtk_combo_box_entry_new_text();
+ compose->savemsg_checkbtn = savemsg_checkbtn;
+ compose->savemsg_combo = savemsg_combo;
+ gtk_widget_show(savemsg_combo);
+
+ if (prefs_common.compose_save_to_history)
+ combobox_set_popdown_strings(GTK_COMBO_BOX(savemsg_combo),
+ prefs_common.compose_save_to_history);
+
+ gtk_table_attach(GTK_TABLE(table), savemsg_combo, 1, 2, rowcount, rowcount + 1, GTK_FILL|GTK_EXPAND, GTK_SHRINK, 0, 0);
+ gtk_widget_set_sensitive(GTK_WIDGET(savemsg_combo), prefs_common.savemsg);
+ g_signal_connect_after(G_OBJECT(savemsg_combo), "grab_focus",
G_CALLBACK(compose_grab_focus_cb), compose);
if (account_get_special_folder(compose->account, F_OUTBOX)) {
folderidentifier = folder_item_get_identifier(account_get_special_folder
(compose->account, F_OUTBOX));
- gtk_entry_set_text(GTK_ENTRY(savemsg_entry), folderidentifier);
+ compose_set_save_to(compose, folderidentifier);
g_free(folderidentifier);
}
rowcount++;
- compose->savemsg_checkbtn = savemsg_checkbtn;
- compose->savemsg_entry = savemsg_entry;
-
return table;
}
static void compose_savemsg_checkbtn_cb(GtkWidget *widget, Compose *compose)
{
- gtk_editable_set_editable(GTK_EDITABLE(compose->savemsg_entry),
+ gtk_widget_set_sensitive(GTK_WIDGET(compose->savemsg_combo),
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn)));
}
path = folder_item_get_identifier(dest);
- gtk_entry_set_text(GTK_ENTRY(compose->savemsg_entry), path);
+ compose_set_save_to(compose, path);
g_free(path);
}
{
gint prev_autowrap;
GtkTextBuffer *buffer = GTK_TEXT_VIEW(text)->buffer;
-#if USE_ASPELL
+#if USE_ENCHANT
if (event->button == 3) {
GtkTextIter iter;
GtkTextIter sel_start, sel_end;
return FALSE;
}
-#if USE_ASPELL
+#if USE_ENCHANT
static void compose_spell_menu_changed(void *data)
{
Compose *compose = (Compose *)data;
g_slist_free(spell_menu);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent_item), GTK_WIDGET(menu));
-
+ gtk_widget_show(parent_item);
+}
+
+static void compose_dict_changed(void *data)
+{
+ Compose *compose = (Compose *) data;
+
+ if(compose->gtkaspell &&
+ compose->gtkaspell->recheck_when_changing_dict == FALSE)
+ return;
+
+ gtkaspell_highlight_all(compose->gtkaspell);
+ claws_spell_entry_recheck_all(CLAWS_SPELL_ENTRY(compose->subject_entry));
}
#endif
GtkWidget *tmpl_menu;
GtkActionGroup *action_group = NULL;
-#if USE_ASPELL
+#if USE_ENCHANT
GtkAspell * gtkaspell = NULL;
#endif
static GdkGeometry geometry;
- g_return_val_if_fail(account != NULL, NULL);
+ cm_return_val_if_fail(account != NULL, NULL);
debug_print("Creating compose window...\n");
compose = g_new0(Compose, 1);
&geometry, GDK_HINT_MAX_SIZE);
if (!geometry.min_width) {
geometry.min_width = 600;
- geometry.min_height = 480;
+ geometry.min_height = 440;
}
gtk_window_set_geometry_hints(GTK_WINDOW(window), NULL,
&geometry, GDK_HINT_MIN_SIZE);
#ifndef MAEMO
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/", "Menu", NULL, GTK_UI_MANAGER_MENUBAR)
#else
- MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/", "Menu", NULL, GTK_UI_MANAGER_MENU)
+ MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/", "Menu", NULL, GTK_UI_MANAGER_POPUP)
#endif
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu", "Message", "Message", GTK_UI_MANAGER_MENU)
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu", "Edit", "Edit", GTK_UI_MANAGER_MENU)
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu", "Spelling", "Spelling", GTK_UI_MANAGER_MENU)
#endif
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu", "Options", "Options", GTK_UI_MANAGER_MENU)
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Edit", "WrapPara", "Edit/WrapPara", GTK_UI_MANAGER_MENUITEM)
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Edit", "WrapAllLines", "Edit/WrapAllLines", GTK_UI_MANAGER_MENUITEM)
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Edit", "AutoWrap", "Edit/AutoWrap", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Edit", "AutoIndent", "Edit/AutoIndent", GTK_UI_MANAGER_MENUITEM)
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Edit", "Separator3", "Edit/---", GTK_UI_MANAGER_SEPARATOR)
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Edit", "ExtEditor", "Edit/ExtEditor", GTK_UI_MANAGER_MENUITEM)
-#if USE_ASPELL
+#if USE_ENCHANT
/* Spelling menu */
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Spelling", "CheckAllSel", "Spelling/CheckAllSel", GTK_UI_MANAGER_MENUITEM)
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Spelling", "HighlightAll", "Spelling/HighlightAll", GTK_UI_MANAGER_MENUITEM)
gtk_box_pack_start(GTK_BOX(subject), label, FALSE, FALSE, 0);
gtk_widget_show(label);
+#ifdef USE_ENCHANT
+ subject_entry = claws_spell_entry_new();
+#else
subject_entry = gtk_entry_new();
+#endif
gtk_box_pack_start(GTK_BOX(subject), subject_entry, TRUE, TRUE, 0);
g_signal_connect_after(G_OBJECT(subject_entry), "grab_focus",
G_CALLBACK(compose_grab_focus_cb), compose);
compose->replyinfo = NULL;
compose->fwdinfo = NULL;
+ compose->email_hashtable = g_hash_table_new_full(g_str_hash,
+ g_str_equal, (GDestroyNotify) g_free, NULL);
+
compose->replyto = NULL;
compose->cc = NULL;
compose->bcc = NULL;
compose->boundary = NULL;
compose->autowrap = prefs_common.autowrap;
-
+ compose->autoindent = prefs_common.auto_indent;
compose->use_signing = FALSE;
compose->use_encryption = FALSE;
compose->privacy_system = NULL;
compose->exteditor_tag = -1;
compose->draft_timeout_tag = -2; /* inhibit auto-drafting while loading */
-#if USE_ASPELL
+#if USE_ENCHANT
cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Spelling", FALSE);
if (mode != COMPOSE_REDIRECT) {
if (prefs_common.enable_aspell && prefs_common.dictionary &&
strcmp(prefs_common.dictionary, "")) {
- gtkaspell = gtkaspell_new(prefs_common.aspell_path,
- prefs_common.dictionary,
+ gtkaspell = gtkaspell_new(prefs_common.dictionary,
prefs_common.alt_dictionary,
conv_get_locale_charset_str(),
prefs_common.misspelled_col,
prefs_common.use_both_dicts,
GTK_TEXT_VIEW(text),
GTK_WINDOW(compose->window),
+ compose_dict_changed,
compose_spell_menu_changed,
compose);
if (!gtkaspell) {
gtkaspell_checkers_strerror());
gtkaspell_checkers_reset_error();
} else {
- if (!gtkaspell_set_sug_mode(gtkaspell,
- prefs_common.aspell_sugmode)) {
- debug_print("Aspell: could not set "
- "suggestion mode %s\n",
- gtkaspell_checkers_strerror());
- gtkaspell_checkers_reset_error();
- }
-
cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Spelling", TRUE);
}
}
}
- compose->gtkaspell = gtkaspell;
+ compose->gtkaspell = gtkaspell;
compose_spell_menu_changed(compose);
+ claws_spell_entry_set_gtkaspell(CLAWS_SPELL_ENTRY(subject_entry), gtkaspell);
#endif
compose_select_account(compose, account, TRUE);
cm_toggle_menu_set_active_full(compose->ui_manager, "Menu/Edit/AutoWrap", prefs_common.autowrap);
+ cm_toggle_menu_set_active_full(compose->ui_manager, "Menu/Edit/AutoIndent", prefs_common.auto_indent);
if (account->set_autocc && account->auto_cc && mode != COMPOSE_REEDIT)
- compose_entry_append(compose, account->auto_cc, COMPOSE_CC);
+ compose_entry_append(compose, account->auto_cc, COMPOSE_CC, PREF_ACCOUNT);
if (account->set_autobcc && account->auto_bcc && mode != COMPOSE_REEDIT)
- compose_entry_append(compose, account->auto_bcc, COMPOSE_BCC);
+ compose_entry_append(compose, account->auto_bcc, COMPOSE_BCC, PREF_ACCOUNT);
if (account->set_autoreplyto && account->auto_replyto && mode != COMPOSE_REEDIT)
- compose_entry_append(compose, account->auto_replyto, COMPOSE_REPLYTO);
+ compose_entry_append(compose, account->auto_replyto, COMPOSE_REPLYTO, PREF_ACCOUNT);
cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Options/ReplyMode", compose->mode == COMPOSE_REPLY);
if (account->protocol != A_NNTP)
- gtk_entry_set_text(GTK_ENTRY(GTK_BIN(compose->header_last->combo)->child),
+ gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((compose->header_last->combo)))),
prefs_common_translated_header_name("To:"));
else
- gtk_entry_set_text(GTK_ENTRY(GTK_BIN(compose->header_last->combo)->child),
+ gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((compose->header_last->combo)))),
prefs_common_translated_header_name("Newsgroups:"));
addressbook_set_target_compose(compose);
gint num = 0, def_menu = 0;
accounts = account_get_list();
- g_return_val_if_fail(accounts != NULL, NULL);
+ cm_return_val_if_fail(accounts != NULL, NULL);
optmenubox = gtk_event_box_new();
optmenu = gtkut_sc_combobox_create(optmenubox, FALSE);
gint value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (current));
Compose *compose = (Compose *) data;
if (active) {
- printf("activated %d\n", value);
compose->priority = value;
}
}
gboolean all = FALSE, ml = FALSE, sender = FALSE, followup = FALSE;
- g_return_if_fail(compose->replyinfo != NULL);
+ cm_return_if_fail(compose->replyinfo != NULL);
if (action == COMPOSE_REPLY && prefs_common.default_reply_list)
ml = TRUE;
compose_remove_header_entries(compose);
compose_reply_set_entry(compose, compose->replyinfo, all, ml, sender, followup);
if (compose->account->set_autocc && compose->account->auto_cc)
- compose_entry_append(compose, compose->account->auto_cc, COMPOSE_CC);
+ compose_entry_append(compose, compose->account->auto_cc, COMPOSE_CC, PREF_ACCOUNT);
if (compose->account->set_autobcc && compose->account->auto_bcc)
- compose_entry_append(compose, compose->account->auto_bcc, COMPOSE_BCC);
+ compose_entry_append(compose, compose->account->auto_bcc, COMPOSE_BCC, PREF_ACCOUNT);
if (compose->account->set_autoreplyto && compose->account->auto_replyto)
- compose_entry_append(compose, compose->account->auto_replyto, COMPOSE_REPLYTO);
+ compose_entry_append(compose, compose->account->auto_replyto, COMPOSE_REPLYTO, PREF_ACCOUNT);
compose_show_first_last_header(compose, TRUE);
compose->modified = was_modified;
compose_set_title(compose);
gchar *systemid;
gboolean can_sign = FALSE, can_encrypt = FALSE;
- g_return_if_fail(GTK_IS_CHECK_MENU_ITEM(widget));
+ cm_return_if_fail(GTK_IS_CHECK_MENU_ITEM(widget));
if (!GTK_CHECK_MENU_ITEM(widget)->active)
return;
gchar *systemid;
menuitem = gtk_menu_item_get_submenu(GTK_MENU_ITEM(
gtk_ui_manager_get_widget(compose->ui_manager, branch_path)));
- g_return_if_fail(menuitem != NULL);
+ cm_return_if_fail(menuitem != NULL);
amenu = GTK_MENU_SHELL(menuitem)->children;
menuitem = NULL;
{
const gchar *qmark = NULL;
- g_return_val_if_fail(compose != NULL, NULL);
+ cm_return_val_if_fail(compose != NULL, NULL);
switch (compose->mode) {
/* use forward-specific quote char */
const gchar *qmark;
gchar *parsed_str = NULL;
gint cursor_pos = 0;
- const gchar *err_msg = _("Template body format error at line %d.");
+ const gchar *err_msg = _("The body of the template has an error at line %d.");
if (!tmpl) return;
/* process the body */
compose_attach_from_list(compose, quote_fmt_get_attachments_list(), FALSE);
quote_fmt_reset_vartable();
compose_changed_cb(NULL, compose);
+
+#ifdef USE_ENCHANT
+ if (compose->gtkaspell && compose->gtkaspell->check_while_typing)
+ gtkaspell_highlight_all(compose->gtkaspell);
+#endif
}
static void compose_template_apply_fields(Compose *compose, Template *tmpl)
}
if (tmpl->from && *tmpl->from != '\0') {
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account, FALSE,
compose->gtkaspell);
#else
}
if (tmpl->to && *tmpl->to != '\0') {
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account, FALSE,
compose->gtkaspell);
#else
if (buf == NULL) {
alertpanel_error(_("Template To format error."));
} else {
- compose_entry_append(compose, buf, COMPOSE_TO);
+ compose_entry_append(compose, buf, COMPOSE_TO, PREF_TEMPLATE);
}
}
if (tmpl->cc && *tmpl->cc != '\0') {
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account, FALSE,
compose->gtkaspell);
#else
if (buf == NULL) {
alertpanel_error(_("Template Cc format error."));
} else {
- compose_entry_append(compose, buf, COMPOSE_CC);
+ compose_entry_append(compose, buf, COMPOSE_CC, PREF_TEMPLATE);
}
}
if (tmpl->bcc && *tmpl->bcc != '\0') {
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account, FALSE,
compose->gtkaspell);
#else
if (buf == NULL) {
alertpanel_error(_("Template Bcc format error."));
} else {
- compose_entry_append(compose, buf, COMPOSE_BCC);
+ compose_entry_append(compose, buf, COMPOSE_BCC, PREF_TEMPLATE);
}
}
/* process the subject */
if (tmpl->subject && *tmpl->subject != '\0') {
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
quote_fmt_init(msginfo, NULL, NULL, FALSE, compose->account, FALSE,
compose->gtkaspell);
#else
slist_free_strings(compose->header_list);
g_slist_free(compose->header_list);
+ compose->header_list = compose->newsgroup_list = compose->to_list = NULL;
+
+ g_hash_table_destroy(compose->email_hashtable);
+
procmsg_msginfo_free(compose->targetinfo);
procmsg_msginfo_free(compose->replyinfo);
procmsg_msginfo_free(compose->fwdinfo);
if (addressbook_get_target_compose() == compose)
addressbook_set_target_compose(NULL);
-#if USE_ASPELL
+#if USE_ENCHANT
if (compose->gtkaspell) {
gtkaspell_delete(compose->gtkaspell);
compose->gtkaspell = NULL;
}
#endif
- prefs_common.compose_width = compose->scrolledwin->allocation.width;
- prefs_common.compose_height = compose->window->allocation.height;
+ if (!compose->batch) {
+ prefs_common.compose_width = compose->scrolledwin->allocation.width;
+ prefs_common.compose_height = compose->window->allocation.height;
+ }
if (!gtk_widget_get_parent(compose->paned))
gtk_widget_destroy(compose->paned);
if (!attach_prop.window)
compose_attach_property_create(&cancelled);
+ gtk_window_set_modal(GTK_WINDOW(attach_prop.window), TRUE);
gtk_widget_grab_focus(attach_prop.ok_btn);
gtk_widget_show(attach_prop.window);
manage_window_set_transient(GTK_WINDOW(attach_prop.window));
gtk_main();
gtk_widget_hide(attach_prop.window);
+ gtk_window_set_modal(GTK_WINDOW(attach_prop.window), FALSE);
if (cancelled)
break;
gtk_container_set_border_width(GTK_CONTAINER(window), 8);
gtk_window_set_title(GTK_WINDOW(window), _("Properties"));
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
- gtk_window_set_modal(GTK_WINDOW(window), TRUE);
g_signal_connect(G_OBJECT(window), "delete_event",
G_CALLBACK(attach_property_delete_event),
cancelled);
}
g_list_free(strlist);
gtk_combo_box_set_active(GTK_COMBO_BOX(mimetype_entry), 0);
- mimetype_entry = GTK_BIN(mimetype_entry)->child;
+ mimetype_entry = gtk_bin_get_child(GTK_BIN((mimetype_entry)));
label = gtk_label_new(_("Encoding"));
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
*cancelled = TRUE;
gtk_main_quit();
}
+ if (event && event->keyval == GDK_Return) {
+ *cancelled = FALSE;
+ gtk_main_quit();
+ return TRUE;
+ }
return FALSE;
}
compose_set_ext_editor_sensitive(compose, FALSE);
+#ifndef G_OS_WIN32
compose->exteditor_ch = g_io_channel_unix_new(pipe_fds[0]);
+#else
+ compose->exteditor_ch = g_io_channel_win32_new_fd(pipe_fds[0]);
+#endif
compose->exteditor_tag = g_io_add_watch(compose->exteditor_ch,
G_IO_IN,
compose_input_cb,
gchar **cmdline;
pid_t pid;
- g_return_val_if_fail(file != NULL, -1);
+ cm_return_val_if_fail(file != NULL, -1);
if ((pid = fork()) < 0) {
perror("fork");
g_snprintf(buf, sizeof(buf), prefs_common_get_ext_editor_cmd(), file);
} else {
if (prefs_common_get_ext_editor_cmd())
- g_warning("External editor command line is invalid: '%s'\n",
+ g_warning("External editor command-line is invalid: '%s'\n",
prefs_common_get_ext_editor_cmd());
g_snprintf(buf, sizeof(buf), DEFAULT_EDITOR_CMD, file);
}
gtk_text_buffer_set_text(buffer, "", -1);
compose_insert_file(compose, compose->exteditor_file);
compose_changed_cb(NULL, compose);
+ compose_draft((gpointer)compose, COMPOSE_AUTO_SAVE);
if (claws_unlink(compose->exteditor_file) < 0)
FILE_OP_ERROR(compose->exteditor_file, "unlink");
return TRUE;
}
+typedef struct {
+ ComposeEntryType header;
+ gchar *entry;
+ ComposePrefType type;
+ gboolean entry_marked;
+} HeaderEntryState;
+
static void account_activated(GtkComboBox *optmenu, gpointer data)
{
Compose *compose = (Compose *)data;
gint account_id = 0;
GtkTreeModel *menu;
GtkTreeIter iter;
+ GSList *list, *saved_list = NULL;
+ HeaderEntryState *state;
+ GtkRcStyle *style = NULL;
+ static GdkColor yellow;
+ static gboolean color_set = FALSE;
/* Get ID of active account in the combo box */
menu = gtk_combo_box_get_model(optmenu);
gtk_tree_model_get(menu, &iter, 1, &account_id, -1);
ac = account_find_from_id(account_id);
- g_return_if_fail(ac != NULL);
+ cm_return_if_fail(ac != NULL);
- if (ac != compose->account)
+ if (ac != compose->account) {
compose_select_account(compose, ac, FALSE);
+ for (list = compose->header_list; list; list = list->next) {
+ ComposeHeaderEntry *hentry=(ComposeHeaderEntry *)list->data;
+
+ if (hentry->type == PREF_ACCOUNT || !list->next) {
+ compose_destroy_headerentry(compose, hentry);
+ continue;
+ }
+
+ state = g_malloc0(sizeof(HeaderEntryState));
+ state->header = combobox_get_active_data(
+ GTK_COMBO_BOX(hentry->combo));
+ state->entry = gtk_editable_get_chars(
+ GTK_EDITABLE(hentry->entry), 0, -1);
+ state->type = hentry->type;
+
+ if (!color_set) {
+ gdk_color_parse("#f5f6be", &yellow);
+ color_set = gdk_colormap_alloc_color(
+ gdk_colormap_get_system(),
+ &yellow, FALSE, TRUE);
+ }
+
+ style = gtk_widget_get_modifier_style(hentry->entry);
+ state->entry_marked = gdk_color_equal(&yellow,
+ &style->base[GTK_STATE_NORMAL]);
+
+ saved_list = g_slist_append(saved_list, state);
+ compose_destroy_headerentry(compose, hentry);
+ }
+
+ compose->header_last = NULL;
+ g_slist_free(compose->header_list);
+ compose->header_list = NULL;
+ compose->header_nextrow = 1;
+ compose_create_header_entry(compose);
+
+ if (ac->set_autocc && ac->auto_cc)
+ compose_entry_append(compose, ac->auto_cc,
+ COMPOSE_CC, PREF_ACCOUNT);
+
+ if (ac->set_autobcc && ac->auto_bcc)
+ compose_entry_append(compose, ac->auto_bcc,
+ COMPOSE_BCC, PREF_ACCOUNT);
+
+ if (ac->set_autoreplyto && ac->auto_replyto)
+ compose_entry_append(compose, ac->auto_replyto,
+ COMPOSE_REPLYTO, PREF_ACCOUNT);
+
+ for (list = saved_list; list; list = list->next) {
+ state = (HeaderEntryState *) list->data;
+
+ compose_entry_append(compose, state->entry,
+ state->header, state->type);
+ if (state->entry_marked)
+ compose_entry_mark_default_to(compose, state->entry);
+
+ g_free(state->entry);
+ }
+ g_slist_free(saved_list);
+
+ combobox_select_by_data(GTK_COMBO_BOX(compose->header_last->combo),
+ (ac->protocol == A_NNTP) ?
+ COMPOSE_NEWSGROUPS : COMPOSE_TO);
+ }
+
/* Set message save folder */
if (account_get_special_folder(compose->account, F_OUTBOX)) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn), prefs_common.savemsg);
g_signal_connect(G_OBJECT(compose->savemsg_checkbtn), "toggled",
G_CALLBACK(compose_savemsg_checkbtn_cb), compose);
- gtk_editable_delete_text(GTK_EDITABLE(compose->savemsg_entry), 0, -1);
+ compose_set_save_to(compose, NULL);
if (account_get_special_folder(compose->account, F_OUTBOX)) {
folderidentifier = folder_item_get_identifier(account_get_special_folder
(compose->account, F_OUTBOX));
- gtk_entry_set_text(GTK_ENTRY(compose->savemsg_entry), folderidentifier);
+ compose_set_save_to(compose, folderidentifier);
g_free(folderidentifier);
}
}
toolbar_comp_set_sensitive(compose, allow);
cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Message", allow);
cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Edit", allow);
-#if USE_ASPELL
+#if USE_ENCHANT
cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Spelling", allow);
#endif
cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Options", allow);
gint val;
inc_lock();
+ compose_allow_user_actions(compose, FALSE);
val = compose_queue_sub(compose, NULL, NULL, NULL, TRUE, TRUE);
+ compose_allow_user_actions(compose, TRUE);
inc_unlock();
if (!val) {
{
gchar *filepath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
DRAFTED_AT_EXIT, NULL);
- FILE *fp = fopen(filepath, "ab");
+ FILE *fp = g_fopen(filepath, "ab");
if (fp) {
fprintf(fp, "%s\t%d\n", folder_item_get_identifier(info->folder),
return TRUE;
draft = account_get_special_folder(compose->account, F_DRAFT);
- g_return_val_if_fail(draft != NULL, FALSE);
+ cm_return_val_if_fail(draft != NULL, FALSE);
if (!g_mutex_trylock(compose->mutex)) {
/* we don't want to lock the mutex once it's available,
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compose->savemsg_checkbtn))) {
gchar *savefolderid;
- savefolderid = gtk_editable_get_chars(GTK_EDITABLE(compose->savemsg_entry), 0, -1);
+ savefolderid = compose_get_save_to(compose);
err |= (fprintf(fp, "SCF:%s\n", savefolderid) < 0);
g_free(savefolderid);
}
g_free(folderid);
}
+ err |= (fprintf(fp, "X-Claws-Auto-Wrapping:%d\n", compose->autowrap) < 0);
+ err |= (fprintf(fp, "X-Claws-Auto-Indent:%d\n", compose->autoindent) < 0);
+
/* end of headers */
err |= (fprintf(fp, "X-Claws-End-Special-Headers: 1\n") < 0);
{
gchar *filepath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
DRAFTED_AT_EXIT, NULL);
- FILE *fp = fopen(filepath, "rb");
+ FILE *fp = g_fopen(filepath, "rb");
gchar buf[1024];
if (fp) {
static void compose_save_cb(GtkAction *action, gpointer data)
{
- compose_draft(data, COMPOSE_KEEP_EDITING);
+ Compose *compose = (Compose *)data;
+ compose_draft(compose, COMPOSE_KEEP_EDITING);
+ compose->rmode = COMPOSE_REEDIT;
}
-static void compose_attach_from_list(Compose *compose, GList *file_list, gboolean free_data)
+void compose_attach_from_list(Compose *compose, GList *file_list, gboolean free_data)
{
if (compose && file_list) {
GList *tmp;
{
Compose *compose = (Compose *)data;
GList *file_list;
+ gint files_inserted = 0;
file_list = filesel_select_multiple_files_open(_("Select file"));
gchar *filedup = g_strdup(file);
gchar *shortfile = g_path_get_basename(filedup);
ComposeInsertResult res;
-
+ /* insert the file if the file is short or if the user confirmed that
+ he/she wants to insert the large file */
res = compose_insert_file(compose, file);
if (res == COMPOSE_INSERT_READ_ERROR) {
alertpanel_error(_("File '%s' could not be read."), shortfile);
} else if (res == COMPOSE_INSERT_INVALID_CHARACTER) {
alertpanel_error(_("File '%s' contained invalid characters\n"
- "for the current encoding, insertion may be incorrect."), shortfile);
- }
+ "for the current encoding, insertion may be incorrect."),
+ shortfile);
+ } else if (res == COMPOSE_INSERT_SUCCESS)
+ files_inserted++;
+
g_free(shortfile);
g_free(filedup);
g_free(file);
}
g_list_free(file_list);
}
+
+#ifdef USE_ENCHANT
+ if (files_inserted > 0 && compose->gtkaspell &&
+ compose->gtkaspell->check_while_typing)
+ gtkaspell_highlight_all(compose->gtkaspell);
+#endif
}
static void compose_insert_sig_cb(GtkAction *action, gpointer data)
Compose *compose = (Compose *)data;
gtkut_widget_get_uposition(widget, &x, &y);
- prefs_common.compose_x = x;
- prefs_common.compose_y = y;
-
+ if (!compose->batch) {
+ prefs_common.compose_x = x;
+ prefs_common.compose_y = y;
+ }
if (compose->sending || compose->updating)
return TRUE;
compose_close_cb(NULL, compose);
#endif
if (compose->modified) {
+ gboolean reedit = (compose->rmode == COMPOSE_REEDIT);
if (!g_mutex_trylock(compose->mutex)) {
/* we don't want to lock the mutex once it's available,
* because as the only other part of compose.c locking
debug_print("couldn't lock mutex, probably sending\n");
return;
}
- val = alertpanel(_("Discard message"),
+ if (!reedit) {
+ val = alertpanel(_("Discard message"),
_("This message has been modified. Discard it?"),
_("_Discard"), _("_Save to Drafts"), GTK_STOCK_CANCEL);
+ } else {
+ val = alertpanel(_("Save changes"),
+ _("This message has been modified. Save the latest changes?"),
+ _("_Don't save"), _("+_Save to Drafts"), GTK_STOCK_CANCEL);
+ }
g_mutex_unlock(compose->mutex);
switch (val) {
case G_ALERTDEFAULT:
- if (prefs_common.autosave)
+ if (prefs_common.autosave && !reedit)
compose_remove_draft(compose);
break;
case G_ALERTALTERNATE:
AlertValue val;
tmpl = g_object_get_data(G_OBJECT(widget), "template");
- g_return_if_fail(tmpl != NULL);
+ cm_return_if_fail(tmpl != NULL);
msg = g_strdup_printf(_("Do you want to apply the template '%s' ?"),
tmpl->name);
* used for mid-click-pasting */
start = gtk_text_iter_get_offset(insert_place);
gtk_text_buffer_insert(buffer, insert_place, contents, strlen(contents));
+ if (prefs_common.primary_paste_unselects)
+ gtk_text_buffer_select_range(buffer, insert_place, insert_place);
}
if (!wrap) {
prefs_common.linewrap_pastes,
GDK_SELECTION_CLIPBOARD, NULL);
UNBLOCK_WRAP();
+
+#ifdef USE_ENCHANT
+ if (GTK_WIDGET_HAS_FOCUS(compose->text) &&
+ compose->gtkaspell &&
+ compose->gtkaspell->check_while_typing)
+ gtkaspell_highlight_all(compose->gtkaspell);
+#endif
}
static void compose_paste_as_quote_cb(GtkAction *action, gpointer data)
entry_paste_clipboard(compose, compose->focused_editable, FALSE,
GDK_SELECTION_CLIPBOARD, NULL);
UNBLOCK_WRAP();
+
+#ifdef USE_ENCHANT
+ if (GTK_WIDGET_HAS_FOCUS(compose->text) &&
+ compose->gtkaspell &&
+ compose->gtkaspell->check_while_typing)
+ gtkaspell_highlight_all(compose->gtkaspell);
+#endif
}
static void compose_paste_wrap_cb(GtkAction *action, gpointer data)
entry_paste_clipboard(compose, compose->focused_editable, TRUE,
GDK_SELECTION_CLIPBOARD, NULL);
UNBLOCK_WRAP();
+
+#ifdef USE_ENCHANT
+ if (GTK_WIDGET_HAS_FOCUS(compose->text) &&
+ compose->gtkaspell &&
+ compose->gtkaspell->check_while_typing)
+ gtkaspell_highlight_all(compose->gtkaspell);
+#endif
}
static void compose_allsel_cb(GtkAction *action, gpointer data)
GtkTextMark *mark;
GtkTextIter ins;
- g_return_if_fail(GTK_IS_TEXT_VIEW(text));
+ cm_return_if_fail(GTK_IS_TEXT_VIEW(text));
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
mark = gtk_text_buffer_get_insert(buffer);
GtkTextMark *mark;
GtkTextIter ins;
- g_return_if_fail(GTK_IS_TEXT_VIEW(text));
+ cm_return_if_fail(GTK_IS_TEXT_VIEW(text));
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
mark = gtk_text_buffer_get_insert(buffer);
GtkTextMark *mark;
GtkTextIter ins;
- g_return_if_fail(GTK_IS_TEXT_VIEW(text));
+ cm_return_if_fail(GTK_IS_TEXT_VIEW(text));
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
mark = gtk_text_buffer_get_insert(buffer);
GtkTextIter ins;
gint count;
- g_return_if_fail(GTK_IS_TEXT_VIEW(text));
+ cm_return_if_fail(GTK_IS_TEXT_VIEW(text));
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
mark = gtk_text_buffer_get_insert(buffer);
GtkTextIter ins;
gint count;
- g_return_if_fail(GTK_IS_TEXT_VIEW(text));
+ cm_return_if_fail(GTK_IS_TEXT_VIEW(text));
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
mark = gtk_text_buffer_get_insert(buffer);
GtkTextMark *mark;
GtkTextIter ins;
- g_return_if_fail(GTK_IS_TEXT_VIEW(text));
+ cm_return_if_fail(GTK_IS_TEXT_VIEW(text));
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
mark = gtk_text_buffer_get_insert(buffer);
GtkTextIter ins;
gint offset;
- g_return_if_fail(GTK_IS_TEXT_VIEW(text));
+ cm_return_if_fail(GTK_IS_TEXT_VIEW(text));
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
mark = gtk_text_buffer_get_insert(buffer);
GtkTextIter ins;
gint offset;
- g_return_if_fail(GTK_IS_TEXT_VIEW(text));
+ cm_return_if_fail(GTK_IS_TEXT_VIEW(text));
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
mark = gtk_text_buffer_get_insert(buffer);
GtkTextMark *mark;
GtkTextIter ins, end_iter;
- g_return_if_fail(GTK_IS_TEXT_VIEW(text));
+ cm_return_if_fail(GTK_IS_TEXT_VIEW(text));
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
mark = gtk_text_buffer_get_insert(buffer);
GtkTextMark *mark;
GtkTextIter ins, end_iter;
- g_return_if_fail(GTK_IS_TEXT_VIEW(text));
+ cm_return_if_fail(GTK_IS_TEXT_VIEW(text));
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
mark = gtk_text_buffer_get_insert(buffer);
GtkTextMark *mark;
GtkTextIter ins, end_iter;
- g_return_if_fail(GTK_IS_TEXT_VIEW(text));
+ cm_return_if_fail(GTK_IS_TEXT_VIEW(text));
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
mark = gtk_text_buffer_get_insert(buffer);
GtkTextMark *mark;
GtkTextIter ins, end_iter;
- g_return_if_fail(GTK_IS_TEXT_VIEW(text));
+ cm_return_if_fail(GTK_IS_TEXT_VIEW(text));
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
mark = gtk_text_buffer_get_insert(buffer);
GtkTextMark *mark;
GtkTextIter ins, start_iter, end_iter;
- g_return_if_fail(GTK_IS_TEXT_VIEW(text));
+ cm_return_if_fail(GTK_IS_TEXT_VIEW(text));
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
mark = gtk_text_buffer_get_insert(buffer);
GtkTextMark *mark;
GtkTextIter ins, end_iter;
- g_return_if_fail(GTK_IS_TEXT_VIEW(text));
+ cm_return_if_fail(GTK_IS_TEXT_VIEW(text));
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
mark = gtk_text_buffer_get_insert(buffer);
static void compose_changed_cb(GtkTextBuffer *textbuf, Compose *compose)
{
compose->modified = TRUE;
+// compose_beautify_paragraph(compose, NULL, TRUE);
#ifndef GENERIC_UMPC
compose_set_title(compose);
#endif
compose->autowrap = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
}
+static void compose_toggle_autoindent_cb(GtkToggleAction *action,
+ gpointer data)
+{
+ Compose *compose = (Compose *)data;
+ compose->autoindent = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+}
+
static void compose_toggle_sign_cb(GtkToggleAction *action, gpointer data)
{
Compose *compose = (Compose *)data;
Compose *compose = (Compose *)user_data;
GList *list, *tmp;
- if (gdk_atom_name(data->type) &&
- !strcmp(gdk_atom_name(data->type), "text/uri-list")
- && gtk_drag_get_source_widget(context) !=
+ if (((gdk_atom_name(data->type) && !strcmp(gdk_atom_name(data->type), "text/uri-list"))
+#ifdef G_OS_WIN32
+ || (gdk_atom_name(data->type) && !strcmp(gdk_atom_name(data->type), "DROPFILES_DND"))
+#endif
+ ) && gtk_drag_get_source_widget(context) !=
summary_get_main_widget(mainwindow_get_mainwindow()->summaryview)) {
list = uri_list_extract_filenames((const gchar *)data->data);
for (tmp = list; tmp != NULL; tmp = tmp->next) {
/* strangely, testing data->type == gdk_atom_intern("text/uri-list", TRUE)
* does not work */
+#ifndef G_OS_WIN32
if (gdk_atom_name(data->type) && !strcmp(gdk_atom_name(data->type), "text/uri-list")) {
+#else
+ if (gdk_atom_name(data->type) && !strcmp(gdk_atom_name(data->type), "DROPFILES_DND")) {
+#endif
AlertValue val = G_ALERTDEFAULT;
list = uri_list_extract_filenames((const gchar *)data->data);
-
if (list == NULL && strstr((gchar *)(data->data), "://")) {
/* Assume a list of no files, and data has ://, is a remote link */
gchar *tmpdata = g_strstrip(g_strdup((const gchar *)data->data));
compose->remove_references = FALSE;
}
+static gboolean compose_headerentry_button_clicked_cb (GtkWidget *button,
+ ComposeHeaderEntry *headerentry)
+{
+ gtk_entry_set_text(GTK_ENTRY(headerentry->entry), "");
+ return FALSE;
+}
+
static gboolean compose_headerentry_key_press_event_cb(GtkWidget *entry,
GdkEventKey *event,
ComposeHeaderEntry *headerentry)
0, 0, NULL, NULL, headerentry);
/* Automatically scroll down */
+ GTK_EVENTS_FLUSH();
compose_show_first_last_header(headerentry->compose, FALSE);
}
{
GtkAdjustment *vadj;
- g_return_if_fail(compose);
- g_return_if_fail(GTK_IS_WIDGET(compose->header_table));
- g_return_if_fail(GTK_IS_VIEWPORT(compose->header_table->parent));
-
+ cm_return_if_fail(compose);
+ cm_return_if_fail(GTK_IS_WIDGET(compose->header_table));
+ cm_return_if_fail(GTK_IS_VIEWPORT(compose->header_table->parent));
vadj = gtk_viewport_get_vadjustment(GTK_VIEWPORT(compose->header_table->parent));
- gtk_adjustment_set_value(vadj, (show_first ? vadj->lower : vadj->upper));
+ gtk_adjustment_set_value(vadj, (show_first ? vadj->lower : (vadj->upper - vadj->page_size)));
gtk_adjustment_changed(vadj);
}
(G_OBJECT(compose->text), "paste_as_quotation"));
GtkTextMark *mark;
- g_return_if_fail(text != NULL);
+ cm_return_if_fail(text != NULL);
g_signal_handlers_block_by_func(G_OBJECT(buffer),
G_CALLBACK(text_inserted),
gtk_text_buffer_delete_mark(buffer, mark);
} else {
if (strcmp(text, "\n") || compose->automatic_break
- || gtk_text_iter_starts_line(iter))
+ || gtk_text_iter_starts_line(iter)) {
+ GtkTextIter before_ins;
gtk_text_buffer_insert(buffer, iter, text, len);
- else {
+ if (!strstr(text, "\n") && gtk_text_iter_has_tag(iter, compose->no_join_tag)) {
+ before_ins = *iter;
+ gtk_text_iter_backward_chars(&before_ins, len);
+ gtk_text_buffer_remove_tag_by_name(buffer, "no_join", &before_ins, iter);
+ }
+ } else {
/* check if the preceding is just whitespace or quote */
GtkTextIter start_line;
gchar *tmp = NULL, *quote = NULL;
gtk_text_iter_set_line_offset(&start_line, 0);
tmp = gtk_text_buffer_get_text(buffer, &start_line, iter, FALSE);
g_strstrip(tmp);
+
if (*tmp == '\0') {
is_normal = 1;
} else {
return FALSE;
}
-#if USE_ASPELL
+#if USE_ENCHANT
static void compose_check_all(GtkAction *action, gpointer data)
{
Compose *compose = (Compose *)data;
- if (compose->gtkaspell)
+ if (!compose->gtkaspell)
+ return;
+
+ if (GTK_WIDGET_HAS_FOCUS(compose->subject_entry))
+ claws_spell_entry_check_all(
+ CLAWS_SPELL_ENTRY(compose->subject_entry));
+ else
gtkaspell_check_all(compose->gtkaspell);
}
static void compose_highlight_all(GtkAction *action, gpointer data)
{
Compose *compose = (Compose *)data;
- if (compose->gtkaspell)
+ if (compose->gtkaspell) {
+ claws_spell_entry_recheck_all(
+ CLAWS_SPELL_ENTRY(compose->subject_entry));
gtkaspell_highlight_all(compose->gtkaspell);
+ }
}
static void compose_check_backwards(GtkAction *action, gpointer data)
{
Compose *compose = (Compose *)data;
- if (compose->gtkaspell)
- gtkaspell_check_backwards(compose->gtkaspell);
- else {
+ if (!compose->gtkaspell) {
cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Spelling", FALSE);
+ return;
}
+
+ if (GTK_WIDGET_HAS_FOCUS(compose->subject_entry))
+ claws_spell_entry_check_backwards(
+ CLAWS_SPELL_ENTRY(compose->subject_entry));
+ else
+ gtkaspell_check_backwards(compose->gtkaspell);
}
static void compose_check_forwards_go(GtkAction *action, gpointer data)
{
Compose *compose = (Compose *)data;
- if (compose->gtkaspell)
- gtkaspell_check_forwards_go(compose->gtkaspell);
- else {
+ if (!compose->gtkaspell) {
cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Spelling", FALSE);
+ return;
}
+
+ if (GTK_WIDGET_HAS_FOCUS(compose->subject_entry))
+ claws_spell_entry_check_forwards_go(
+ CLAWS_SPELL_ENTRY(compose->subject_entry));
+ else
+ gtkaspell_check_forwards_go(compose->gtkaspell);
}
#endif
{
PrefsAccount *account = NULL;
- g_return_val_if_fail(msginfo, NULL);
- g_return_val_if_fail(msginfo->folder, NULL);
- g_return_val_if_fail(msginfo->folder->prefs, NULL);
+ cm_return_val_if_fail(msginfo, NULL);
+ cm_return_val_if_fail(msginfo->folder, NULL);
+ cm_return_val_if_fail(msginfo->folder->prefs, NULL);
if (msginfo->folder->prefs->enable_default_account)
account = account_find_from_id(msginfo->folder->prefs->default_account);
g_timeout_add (500, (GSourceFunc) compose_close, compose);
return FALSE;
}
- g_return_val_if_fail(compose, FALSE);
+ cm_return_val_if_fail(compose, FALSE);
gtkut_widget_get_uposition(compose->window, &x, &y);
- prefs_common.compose_x = x;
- prefs_common.compose_y = y;
+ if (!compose->batch) {
+ prefs_common.compose_x = x;
+ prefs_common.compose_y = y;
+ }
g_mutex_unlock(compose->mutex);
compose_destroy(compose);
return FALSE;
node = listAddress;
while( node ) {
addr = ( gchar * ) node->data;
- compose_entry_append( compose, addr, COMPOSE_TO );
+ compose_entry_append( compose, addr, COMPOSE_TO, PREF_NONE );
node = g_list_next( node );
}
}
GSList *new_msglist = NULL;
MsgInfo *tmp_msginfo = NULL;
gboolean originally_enc = FALSE;
+ gboolean originally_sig = FALSE;
Compose *compose = NULL;
+ gchar *s_system = NULL;
- g_return_if_fail(msgview != NULL);
+ cm_return_if_fail(msgview != NULL);
- g_return_if_fail(msginfo_list != NULL);
+ cm_return_if_fail(msginfo_list != NULL);
if (g_slist_length(msginfo_list) == 1 && !opening_multiple) {
MimeInfo *mimeinfo = messageview_get_selected_mime_part(msgview);
new_msglist = g_slist_append(NULL, tmp_msginfo);
originally_enc = MSG_IS_ENCRYPTED(orig_msginfo->flags);
+ privacy_msginfo_get_signed_state(orig_msginfo, &s_system);
+ originally_sig = MSG_IS_SIGNED(orig_msginfo->flags);
+
tmp_msginfo->folder = orig_msginfo->folder;
tmp_msginfo->msgnum = orig_msginfo->msgnum;
- if (orig_msginfo->tags)
+ if (orig_msginfo->tags) {
tmp_msginfo->tags = g_slist_copy(orig_msginfo->tags);
+ tmp_msginfo->folder->tags_dirty = TRUE;
+ }
}
}
}
compose = compose_reply_mode((ComposeMode)action, msginfo_list, body);
if (compose && originally_enc) {
- compose_force_encryption(compose, compose->account, FALSE);
+ compose_force_encryption(compose, compose->account, FALSE, s_system);
}
+ if (compose && originally_sig && compose->account->default_sign_reply) {
+ compose_force_signing(compose, compose->account, s_system);
+ }
+ g_free(s_system);
g_free(body);
+ hooks_invoke(COMPOSE_CREATED_HOOKLIST, compose);
}
void compose_reply_from_messageview(MessageView *msgview, GSList *msginfo_list,
GSList *list;
gchar buf[BUFFSIZE];
- g_return_val_if_fail( compose != NULL, NULL );
+ cm_return_val_if_fail( compose != NULL, NULL );
newmsginfo = procmsg_msginfo_new();
for (list = compose->header_list; list; list = list->next) {
gchar *header = gtk_editable_get_chars(
GTK_EDITABLE(
- GTK_BIN(((ComposeHeaderEntry *)list->data)->combo)->child), 0, -1);
+ gtk_bin_get_child(GTK_BIN((((ComposeHeaderEntry *)list->data)->combo)))), 0, -1);
gchar *entry = gtk_editable_get_chars(
GTK_EDITABLE(((ComposeHeaderEntry *)list->data)->entry), 0, -1);
return newmsginfo;
}
-#ifdef USE_ASPELL
+#ifdef USE_ENCHANT
/* update compose's dictionaries from folder dict settings */
static void compose_set_dictionaries_from_folder_prefs(Compose *compose,
FolderItem *folder_item)
{
- g_return_if_fail(compose != NULL);
+ cm_return_if_fail(compose != NULL);
if (compose->gtkaspell && folder_item && folder_item->prefs) {
FolderItemPrefs *prefs = folder_item->prefs;