/*
* Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2015 Hiroyuki Yamamoto and the Claws Mail team
+ * Copyright (C) 1999-2016 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
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
*/
#ifdef HAVE_CONFIG_H
#include "main.h"
#include "mainwindow.h"
#include "compose.h"
-#ifndef USE_NEW_ADDRBOOK
+#ifndef USE_ALT_ADDRBOOK
#include "addressbook.h"
#else
#include "addressbook-dbus.h"
static void compose_exec_ext_editor (Compose *compose);
#ifdef G_OS_UNIX
-static gint compose_exec_ext_editor_real (const gchar *file);
+static gint compose_exec_ext_editor_real (const gchar *file,
+ GdkNativeWindow socket_wid);
static gboolean compose_ext_editor_kill (Compose *compose);
static gboolean compose_input_cb (GIOChannel *source,
GIOCondition condition,
gpointer data);
static void compose_set_ext_editor_sensitive (Compose *compose,
gboolean sensitive);
+static gboolean compose_get_ext_editor_cmd_valid();
+static gboolean compose_get_ext_editor_uses_socket();
+static gboolean compose_ext_editor_plug_removed_cb
+ (GtkSocket *socket,
+ Compose *compose);
#endif /* G_OS_UNIX */
static void compose_undo_state_changed (UndoMain *undostruct,
static gboolean compose_edit_size_alloc (GtkEditable *widget,
GtkAllocation *allocation,
GtkSHRuler *shruler);
-static void account_activated (GtkComboBox *optmenu,
- gpointer data);
static void attach_selected (GtkTreeView *tree_view,
GtkTreePath *tree_path,
GtkTreeViewColumn *column,
}
}
- procmsg_msginfo_free( dummyinfo );
+ procmsg_msginfo_free( &dummyinfo );
if (attach_files) {
GList *curr;
g_strdup(procmime_mimeinfo_get_parameter(
partinfo, "charset"));
}
- procmime_mimeinfo_free_all(mimeinfo);
+ procmime_mimeinfo_free_all(&mimeinfo);
}
}
quote_fmt_reset_vartable();
g_free(tmp);
- procmsg_msginfo_free(full_msginfo);
+ procmsg_msginfo_free(&full_msginfo);
}
textview = GTK_TEXT_VIEW(compose->text);
quote_fmt_reset_vartable();
compose_attach_parts(compose, msginfo);
- procmsg_msginfo_free(full_msginfo);
+ procmsg_msginfo_free(&full_msginfo);
}
SIGNAL_BLOCK(textbuf);
gtk_text_buffer_get_start_iter(textbuf, &iter);
gtk_text_buffer_place_cursor(textbuf, &iter);
+ if (prefs_common.auto_exteditor)
+ compose_exec_ext_editor(compose);
+
gtk_widget_grab_focus(compose->header_last->entry);
undo_unblock(compose->undostruct);
compose->modified = FALSE;
if (compose->mode == COMPOSE_REEDIT) {
if (msginfo->inreplyto && *msginfo->inreplyto)
compose->inreplyto = g_strdup(msginfo->inreplyto);
- return 0;
- }
-
- if (msginfo->msgid && *msginfo->msgid)
- compose->inreplyto = g_strdup(msginfo->msgid);
- if (!compose->references) {
- if (msginfo->msgid && *msginfo->msgid) {
- if (msginfo->inreplyto && *msginfo->inreplyto)
- compose->references =
- g_strdup_printf("<%s>\n\t<%s>",
- msginfo->inreplyto,
- msginfo->msgid);
- else
+ if (msginfo->msgid && *msginfo->msgid)
+ compose->msgid = g_strdup(msginfo->msgid);
+ } else {
+ if (msginfo->msgid && *msginfo->msgid)
+ compose->inreplyto = g_strdup(msginfo->msgid);
+
+ if (!compose->references) {
+ if (msginfo->msgid && *msginfo->msgid) {
+ if (msginfo->inreplyto && *msginfo->inreplyto)
+ compose->references =
+ g_strdup_printf("<%s>\n\t<%s>",
+ msginfo->inreplyto,
+ msginfo->msgid);
+ else
+ compose->references =
+ g_strconcat("<", msginfo->msgid, ">",
+ NULL);
+ } else if (msginfo->inreplyto && *msginfo->inreplyto) {
compose->references =
- g_strconcat("<", msginfo->msgid, ">",
+ g_strconcat("<", msginfo->inreplyto, ">",
NULL);
- } else if (msginfo->inreplyto && *msginfo->inreplyto) {
- compose->references =
- g_strconcat("<", msginfo->inreplyto, ">",
- NULL);
+ }
}
}
ok:
SIGNAL_UNBLOCK(buffer);
- procmsg_msginfo_free( dummyinfo );
+ procmsg_msginfo_free( &dummyinfo );
return buf;
}
? msginfo->from :
msginfo->to,
COMPOSE_TO, PREF_NONE);
+ if (compose->replyto)
+ compose_entry_append(compose,
+ compose->replyto,
+ COMPOSE_CC, PREF_NONE);
} else {
if (!folder_has_parent_of_type(msginfo->folder, F_QUEUE) &&
!folder_has_parent_of_type(msginfo->folder, F_OUTBOX) &&
compose->followup_to ? compose->followup_to :
compose->newsgroups ? compose->newsgroups : "",
COMPOSE_NEWSGROUPS, PREF_NONE);
+
+ compose_entry_append
+ (compose,
+ msginfo->cc ? msginfo->cc : "",
+ COMPOSE_CC, PREF_NONE);
}
else
compose_entry_append
ainfo->name = g_strdup_printf(_("Message: %s"), name);
- procmsg_msginfo_free(msginfo);
+ procmsg_msginfo_free(&msginfo);
} else {
if (!g_ascii_strncasecmp(content_type, "text/", 5)) {
ainfo->charset = g_strdup(charset);
if (!mimeinfo) return;
if (mimeinfo->node->children == NULL) {
- procmime_mimeinfo_free_all(mimeinfo);
+ procmime_mimeinfo_free_all(&mimeinfo);
return;
}
g_free(outfile);
NEXT_PART_NOT_CHILD(child);
}
- procmime_mimeinfo_free_all(mimeinfo);
+ procmime_mimeinfo_free_all(&mimeinfo);
}
#undef NEXT_PART_NOT_CHILD
if (tmp) {
debug_print("removing %d via %s\n", tmp->msgnum, tmsgid);
folder_item_remove_msg(folder, tmp->msgnum);
- procmsg_msginfo_free(tmp);
+ procmsg_msginfo_free(&tmp);
}
}
}
if (tmp) {
debug_print("removing %d via %s\n", tmp->msgnum, tmsgid);
folder_item_remove_msg(folder, tmp->msgnum);
- procmsg_msginfo_free(tmp);
+ procmsg_msginfo_free(&tmp);
}
}
if (!discard_window) {
cm_return_val_if_fail(compose->account->address != NULL, -1);
/* Resent-Date */
- get_rfc822_date(buf, sizeof(buf));
+ if (prefs_common.hide_timezone)
+ get_rfc822_date_hide_tz(buf, sizeof(buf));
+ else
+ get_rfc822_date(buf, sizeof(buf));
err |= (fprintf(fp, "Resent-Date: %s\n", buf) < 0);
/* Resent-From */
}
/* Resent-Message-ID */
- if (compose->account->set_domain && compose->account->domain) {
- g_snprintf(buf, sizeof(buf), "%s", compose->account->domain);
- } else if (!strncmp(get_domain_name(), "localhost", strlen("localhost"))) {
- g_snprintf(buf, sizeof(buf), "%s",
- strchr(compose->account->address, '@') ?
- strchr(compose->account->address, '@')+1 :
- compose->account->address);
- } else {
- g_snprintf(buf, sizeof(buf), "%s", "");
- }
-
if (compose->account->gen_msgid) {
- 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);
+ gchar *addr = prefs_account_generate_msgid(compose->account);
+ err |= (fprintf(fp, "Resent-Message-ID: <%s>\n", addr) < 0);
if (compose->msgid)
g_free(compose->msgid);
- compose->msgid = g_strdup(buf);
+ compose->msgid = addr;
} else {
compose->msgid = NULL;
}
gchar *from_name = NULL;
FolderItem *outbox;
- if (action == COMPOSE_WRITE_FOR_SEND)
+ if (action == COMPOSE_WRITE_FOR_SEND) {
attach_parts = TRUE;
+ /* We're sending the message, generate a Message-ID
+ * if necessary. */
+ if (compose->msgid == NULL &&
+ compose->account->gen_msgid) {
+ compose->msgid = prefs_account_generate_msgid(compose->account);
+ }
+ }
+
/* create message MimeInfo */
mimemsg = procmime_mimeinfo_new();
mimemsg->type = MIMETYPE_MESSAGE;
}
g_free(chars);
- if (encoding == ENC_8BIT || encoding == ENC_7BIT) {
+ if (prefs_common.rewrite_first_from && (encoding == ENC_8BIT || encoding == ENC_7BIT)) {
if (!strncmp(buf, "From ", sizeof("From ")-1) ||
strstr(buf, "\nFrom ") != NULL) {
encoding = ENC_QUOTED_PRINTABLE;
privacy_system_can_sign(compose->privacy_system)) {
encoding = ENC_QUOTED_PRINTABLE;
}
-
+
+#ifdef G_OS_WIN32
+ debug_print("main text: %Id bytes encoded as %s in %d\n",
+#else
debug_print("main text: %zd bytes encoded as %s in %d\n",
+#endif
strlen(buf), out_codeset, encoding);
/* check for line length limit */
procmime_write_mimeinfo(mimemsg, fp);
- procmime_mimeinfo_free_all(mimemsg);
+ procmime_mimeinfo_free_all(&mimemsg);
return 0;
}
faddr = g_strconcat(name, addr, NULL);
g_free(name);
g_free(addr);
- debug_print("new auto-quoted address: '%s'", faddr);
+ debug_print("new auto-quoted address: '%s'\n", faddr);
}
}
if (result == NULL)
header = g_string_sized_new(64);
/* Date */
- get_rfc822_date(buf, sizeof(buf));
+ if (prefs_common.hide_timezone)
+ get_rfc822_date_hide_tz(buf, sizeof(buf));
+ else
+ get_rfc822_date(buf, sizeof(buf));
g_string_append_printf(header, "Date: %s\n", buf);
/* From */
g_string_append_printf(header, "From: %s <%s>\n",
qname, from_address);
+ if (!IS_IN_CUSTOM_HEADER("Disposition-Notification-To") &&
+ compose->return_receipt) {
+ compose_convert_header(compose, buf, sizeof(buf), from_name,
+ strlen("Disposition-Notification-To: "),
+ TRUE);
+ g_string_append_printf(header, "Disposition-Notification-To: %s <%s>\n", buf, from_address);
+ }
if (qname != name)
g_free(qname);
- } else
+ } else {
g_string_append_printf(header, "From: %s\n", from_address);
-
+ if (!IS_IN_CUSTOM_HEADER("Disposition-Notification-To") &&
+ compose->return_receipt)
+ g_string_append_printf(header, "Disposition-Notification-To: %s\n", from_address);
+
+ }
g_free(from_name);
g_free(from_address);
g_free(str);
/* Message-ID */
- if (compose->account->set_domain && compose->account->domain) {
- g_snprintf(buf, sizeof(buf), "%s", compose->account->domain);
- } else if (!strncmp(get_domain_name(), "localhost", strlen("localhost"))) {
- g_snprintf(buf, sizeof(buf), "%s",
- strchr(compose->account->address, '@') ?
- strchr(compose->account->address, '@')+1 :
- compose->account->address);
- } else {
- g_snprintf(buf, sizeof(buf), "%s", "");
- }
-
- if (compose->account->gen_msgid) {
- 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);
- if (compose->msgid)
- g_free(compose->msgid);
- compose->msgid = g_strdup(buf);
- } else {
- compose->msgid = NULL;
+ if (compose->msgid != NULL && strlen(compose->msgid) > 0) {
+ g_string_append_printf(header, "Message-ID: <%s>\n",
+ compose->msgid);
}
if (compose->remove_references == FALSE) {
compose->priority);
}
- /* Request Return Receipt */
- if (!IS_IN_CUSTOM_HEADER("Disposition-Notification-To")) {
- if (compose->return_receipt) {
- if (compose->account->name
- && *compose->account->name) {
- compose_convert_header(compose, buf, sizeof(buf),
- compose->account->name,
- strlen("Disposition-Notification-To: "),
- TRUE);
- g_string_append_printf(header, "Disposition-Notification-To: %s <%s>\n", buf, compose->account->address);
- } else
- g_string_append_printf(header, "Disposition-Notification-To: %s\n", compose->account->address);
- }
- }
-
/* get special headers */
for (list = compose->header_list; list; list = list->next) {
ComposeHeaderEntry *headerentry;
if (*address != '\0') {
gchar *name = procheader_get_fromname(address);
extract_address(address);
-#ifndef USE_NEW_ADDRBOOK
+#ifndef USE_ALT_ADDRBOOK
addressbook_add_contact(name, address, NULL, NULL);
#else
debug_print("%s: %s\n", name, address);
static GtkWidget *compose_create_header(Compose *compose)
{
GtkWidget *from_optmenu_hbox;
- GtkWidget *header_scrolledwin_main;
GtkWidget *header_table_main;
GtkWidget *header_scrolledwin;
GtkWidget *header_table;
/* parent with account selection and from header */
- header_scrolledwin_main = gtk_scrolled_window_new(NULL, NULL);
- gtk_widget_show(header_scrolledwin_main);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(header_scrolledwin_main), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-
header_table_main = gtk_table_new(2, 2, FALSE);
gtk_widget_show(header_table_main);
gtk_container_set_border_width(GTK_CONTAINER(header_table_main), BORDER_WIDTH);
- gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(header_scrolledwin_main), header_table_main);
- gtk_viewport_set_shadow_type(GTK_VIEWPORT(gtk_bin_get_child(GTK_BIN((header_scrolledwin_main)))), GTK_SHADOW_NONE);
from_optmenu_hbox = compose_account_option_menu_create(compose);
gtk_table_attach(GTK_TABLE(header_table_main), from_optmenu_hbox,
compose->table = NULL;
- return header_scrolledwin_main;
+ return header_table_main;
}
static gboolean popup_attach_button_pressed(GtkWidget *widget, gpointer data)
compose->exteditor_file = NULL;
compose->exteditor_pid = -1;
compose->exteditor_tag = -1;
+ compose->exteditor_socket = NULL;
compose->draft_timeout_tag = COMPOSE_DRAFT_TIMEOUT_FORBIDDEN; /* inhibit auto-drafting while loading */
compose->folder_update_callback_id =
gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN((compose->header_last->combo)))),
prefs_common_translated_header_name("Newsgroups:"));
-#ifndef USE_NEW_ADDRBOOK
+#ifndef USE_ALT_ADDRBOOK
addressbook_set_target_compose(compose);
#endif
if (mode != COMPOSE_REDIRECT)
if (ac == compose->account) def_menu = num;
- name = g_markup_printf_escaped(_("<i>%s</i>"),
+ name = g_markup_printf_escaped("<i>%s</i>",
ac->account_name);
if (ac == compose->account) {
gtk_combo_box_set_active(GTK_COMBO_BOX(optmenu), def_menu);
- g_signal_connect(G_OBJECT(optmenu), "changed",
- G_CALLBACK(account_activated),
- compose);
g_signal_connect(G_OBJECT(from_name), "populate-popup",
G_CALLBACK(compose_entry_popup_extend),
NULL);
parsed_str = compose_quote_fmt(compose, dummyinfo,
tmpl->value, qmark, tmp, FALSE, FALSE, err_msg);
- procmsg_msginfo_free( dummyinfo );
+ procmsg_msginfo_free( &dummyinfo );
g_free( tmp );
}
}
}
- procmsg_msginfo_free( dummyinfo );
+ procmsg_msginfo_free( &dummyinfo );
}
static void compose_destroy(Compose *compose)
hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST,
compose->folder_update_callback_id);
- procmsg_msginfo_free(compose->targetinfo);
- procmsg_msginfo_free(compose->replyinfo);
- procmsg_msginfo_free(compose->fwdinfo);
+ procmsg_msginfo_free(&(compose->targetinfo));
+ procmsg_msginfo_free(&(compose->replyinfo));
+ procmsg_msginfo_free(&(compose->fwdinfo));
g_free(compose->replyto);
g_free(compose->cc);
g_free(compose->privacy_system);
g_free(compose->encdata);
-#ifndef USE_NEW_ADDRBOOK
+#ifndef USE_ALT_ADDRBOOK
if (addressbook_get_target_compose() == compose)
addressbook_set_target_compose(NULL);
#endif
{
#ifdef G_OS_UNIX
gchar *tmp;
+ GtkWidget *socket;
+ GdkNativeWindow socket_wid = 0;
pid_t pid;
gint pipe_fds[2];
tmp = g_strdup_printf("%s%ctmpmsg.%p", get_tmp_dir(),
G_DIR_SEPARATOR, compose);
+ if (compose_get_ext_editor_uses_socket()) {
+ /* Only allow one socket */
+ if (compose->exteditor_socket != NULL) {
+ if (gtk_widget_is_focus(compose->exteditor_socket)) {
+ /* Move the focus off of the socket */
+ gtk_widget_child_focus(compose->window, GTK_DIR_TAB_BACKWARD);
+ }
+ g_free(tmp);
+ return;
+ }
+ /* Create the receiving GtkSocket */
+ socket = gtk_socket_new ();
+ g_signal_connect (GTK_OBJECT(socket), "plug-removed",
+ G_CALLBACK(compose_ext_editor_plug_removed_cb),
+ compose);
+ gtk_box_pack_start(GTK_BOX(compose->edit_vbox), socket, TRUE, TRUE, 0);
+ gtk_widget_set_size_request(socket, prefs_common.compose_width, -1);
+ /* Realize the socket so that we can use its ID */
+ gtk_widget_realize(socket);
+ socket_wid = gtk_socket_get_id(GTK_SOCKET (socket));
+ compose->exteditor_socket = socket;
+ }
+
if (pipe(pipe_fds) < 0) {
perror("pipe");
g_free(tmp);
_exit(1);
}
- pid_ed = compose_exec_ext_editor_real(tmp);
+ pid_ed = compose_exec_ext_editor_real(tmp, socket_wid);
if (pid_ed < 0) {
fd_write_all(pipe_fds[1], "1\n", 2);
_exit(1);
}
#ifdef G_OS_UNIX
-static gint compose_exec_ext_editor_real(const gchar *file)
+static gboolean compose_get_ext_editor_cmd_valid()
+{
+ gboolean has_s = FALSE;
+ gboolean has_w = FALSE;
+ const gchar *p = prefs_common_get_ext_editor_cmd();
+ if (!p)
+ return FALSE;
+ while ((p = strchr(p, '%'))) {
+ p++;
+ if (*p == 's') {
+ if (has_s)
+ return FALSE;
+ has_s = TRUE;
+ } else if (*p == 'w') {
+ if (has_w)
+ return FALSE;
+ has_w = TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static gint compose_exec_ext_editor_real(const gchar *file, GdkNativeWindow socket_wid)
{
gchar buf[1024];
- gchar *p;
+ gchar *p, *s;
gchar **cmdline;
pid_t pid;
if (setpgid(0, getppid()))
perror("setpgid");
- if (prefs_common_get_ext_editor_cmd() &&
- (p = strchr(prefs_common_get_ext_editor_cmd(), '%')) &&
- *(p + 1) == 's' && !strchr(p + 2, '%')) {
- g_snprintf(buf, sizeof(buf), prefs_common_get_ext_editor_cmd(), file);
+ if (compose_get_ext_editor_cmd_valid()) {
+ if (compose_get_ext_editor_uses_socket()) {
+ p = g_strdup(prefs_common_get_ext_editor_cmd());
+ s = strstr(p, "%w");
+ s[1] = 'u';
+ if (strstr(p, "%s") < s)
+ g_snprintf(buf, sizeof(buf), p, file, socket_wid);
+ else
+ g_snprintf(buf, sizeof(buf), p, socket_wid, file);
+ g_free(p);
+ } else {
+ 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'",
compose->exteditor_pid = -1;
compose->exteditor_ch = NULL;
compose->exteditor_tag = -1;
+ if (compose->exteditor_socket) {
+ gtk_widget_destroy(compose->exteditor_socket);
+ compose->exteditor_socket = NULL;
+ }
+
return FALSE;
}
+static char *ext_editor_menu_entries[] = {
+ "Menu/Message/Send",
+ "Menu/Message/SendLater",
+ "Menu/Message/InsertFile",
+ "Menu/Message/InsertSig",
+ "Menu/Message/ReplaceSig",
+ "Menu/Message/Save",
+ "Menu/Message/Print",
+ "Menu/Edit",
+#if USE_ENCHANT
+ "Menu/Spelling",
+#endif
+ "Menu/Tools/ShowRuler",
+ "Menu/Tools/Actions",
+ "Menu/Help",
+ NULL
+};
+
static void compose_set_ext_editor_sensitive(Compose *compose,
gboolean sensitive)
{
- cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Message/Send", sensitive);
- cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Message/SendLater", sensitive);
- cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Message/InsertFile", sensitive);
- cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Message/InsertSig", sensitive);
- cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Message/ReplaceSig", sensitive);
- cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Edit/WrapPara", sensitive);
- cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Edit/WrapAllLines", sensitive);
- cm_menu_set_sensitive_full(compose->ui_manager, "Menu/Edit/ExtEditor", sensitive);
+ int i;
- gtk_widget_set_sensitive(compose->text, sensitive);
+ for (i = 0; ext_editor_menu_entries[i]; ++i) {
+ cm_menu_set_sensitive_full(compose->ui_manager,
+ ext_editor_menu_entries[i], sensitive);
+ }
+
+ if (compose_get_ext_editor_uses_socket()) {
+ if (sensitive) {
+ if (compose->exteditor_socket)
+ gtk_widget_hide(compose->exteditor_socket);
+ gtk_widget_show(compose->scrolledwin);
+ if (prefs_common.show_ruler)
+ gtk_widget_show(compose->ruler_hbox);
+ /* Fix the focus, as it doesn't go anywhere when the
+ * socket is hidden or destroyed */
+ gtk_widget_child_focus(compose->window, GTK_DIR_TAB_BACKWARD);
+ } else {
+ g_assert (compose->exteditor_socket != NULL);
+ /* Fix the focus, as it doesn't go anywhere when the
+ * edit box is hidden */
+ if (gtk_widget_is_focus(compose->text))
+ gtk_widget_child_focus(compose->window, GTK_DIR_TAB_BACKWARD);
+ gtk_widget_hide(compose->scrolledwin);
+ gtk_widget_hide(compose->ruler_hbox);
+ gtk_widget_show(compose->exteditor_socket);
+ }
+ } else {
+ gtk_widget_set_sensitive(compose->text, sensitive);
+ }
if (compose->toolbar->send_btn)
gtk_widget_set_sensitive(compose->toolbar->send_btn, sensitive);
if (compose->toolbar->sendl_btn)
if (compose->toolbar->linewrap_all_btn)
gtk_widget_set_sensitive(compose->toolbar->linewrap_all_btn, sensitive);
}
+
+static gboolean compose_get_ext_editor_uses_socket()
+{
+ return (prefs_common_get_ext_editor_cmd() &&
+ strstr(prefs_common_get_ext_editor_cmd(), "%w"));
+}
+
+static gboolean compose_ext_editor_plug_removed_cb(GtkSocket *socket, Compose *compose)
+{
+ compose->exteditor_socket = NULL;
+ /* returning FALSE allows destruction of the socket */
+ return FALSE;
+}
#endif /* G_OS_UNIX */
/**
gboolean entry_marked;
} HeaderEntryState;
-static void account_activated(GtkComboBox *optmenu, gpointer data)
-{
- Compose *compose = (Compose *)data;
-
- PrefsAccount *ac;
- gchar *folderidentifier;
- gint account_id = 0;
- GtkTreeModel *menu;
- GtkTreeIter iter;
- GSList *list, *saved_list = NULL;
- HeaderEntryState *state;
- GtkRcStyle *style = NULL;
-#if !GTK_CHECK_VERSION(3, 0, 0)
- static GdkColor yellow;
- static gboolean color_set = FALSE;
-#else
- static GdkColor yellow = { (guint32)0, (guint32)0xf5, (guint32)0xf6, (guint32)0xbe };
-#endif
-
- /* Get ID of active account in the combo box */
- menu = gtk_combo_box_get_model(optmenu);
- cm_return_if_fail(gtk_combo_box_get_active_iter(optmenu, &iter));
- gtk_tree_model_get(menu, &iter, 1, &account_id, -1);
-
- ac = account_find_from_id(account_id);
- cm_return_if_fail(ac != NULL);
-
- 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 = gtk_editable_get_chars(GTK_EDITABLE(
- gtk_bin_get_child(GTK_BIN(hentry->combo))), 0, -1);
- state->entry = gtk_editable_get_chars(
- GTK_EDITABLE(hentry->entry), 0, -1);
- state->type = hentry->type;
-
-#if !GTK_CHECK_VERSION(3, 0, 0)
- if (!color_set) {
- gdk_color_parse("#f5f6be", &yellow);
- color_set = gdk_colormap_alloc_color(
- gdk_colormap_get_system(),
- &yellow, FALSE, TRUE);
- }
-#endif
-
- 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_add_header_entry(compose, state->header,
- state->entry, state->type);
- if (state->entry_marked)
- compose_entry_mark_default_to(compose, state->entry);
-
- g_free(state->header);
- g_free(state->entry);
- g_free(state);
- }
- 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);
-
- 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));
- compose_set_save_to(compose, folderidentifier);
- g_free(folderidentifier);
- }
-}
-
static void attach_selected(GtkTreeView *tree_view, GtkTreePath *tree_path,
GtkTreeViewColumn *column, Compose *compose)
{
{
Compose *compose = (Compose *)data;
+#ifdef G_OS_UNIX
+ if (compose->exteditor_tag != -1) {
+ debug_print("ignoring send: external editor still open\n");
+ return;
+ }
+#endif
if (prefs_common.work_offline &&
!inc_offline_should_override(TRUE,
_("Claws Mail needs network access in order "
}
if (tmpinfo) {
msgnum = tmpinfo->msgnum;
- procmsg_msginfo_free(tmpinfo);
+ procmsg_msginfo_free(&tmpinfo);
debug_print("got draft msgnum %d from scanning\n", msgnum);
} else {
debug_print("didn't get draft msgnum after scanning\n");
if (action == COMPOSE_DRAFT_FOR_EXIT) {
compose_register_draft(newmsginfo);
}
- procmsg_msginfo_free(newmsginfo);
+ procmsg_msginfo_free(&newmsginfo);
}
folder_item_scan(draft);
}
g_free(path);
- procmsg_msginfo_free(compose->targetinfo);
+ procmsg_msginfo_free(&(compose->targetinfo));
compose->targetinfo = procmsg_msginfo_new();
compose->targetinfo->msgnum = msgnum;
compose->targetinfo->size = (goffset)s.st_size;
* which unsets it (via focus_out_event callback on compose window). */
manage_window_focus_in(compose->window, NULL, NULL);
- file_list = filesel_select_multiple_files_open(_("Select file"));
+ file_list = filesel_select_multiple_files_open(_("Select file"), NULL);
if (file_list) {
compose_attach_from_list(compose, file_list, TRUE);
GList *file_list;
gint files_inserted = 0;
- file_list = filesel_select_multiple_files_open(_("Select file"));
+ file_list = filesel_select_multiple_files_open(_("Select file"), NULL);
if (file_list) {
GList *tmp;
{
Compose *compose = (Compose *)data;
-#ifndef USE_NEW_ADDRBOOK
+#ifndef USE_ALT_ADDRBOOK
addressbook_open(compose);
#else
GError* error = NULL;
{
Compose *compose = (Compose *)data;
+#ifdef G_OS_UNIX
+ if (compose->exteditor_tag != -1) {
+ debug_print("ignoring open external editor: external editor still open\n");
+ return;
+ }
+#endif
compose_exec_ext_editor(compose);
}
Compose *compose = (Compose *)user_data;
GList *list, *tmp;
GdkAtom type;
+ guint num_files;
+ gchar *msg;
/* strangely, testing data->type == gdk_atom_intern("text/uri-list", TRUE)
* does not work */
const gchar* ddata = (const gchar *)gtk_selection_data_get_data(data);
list = uri_list_extract_filenames(ddata);
+ num_files = g_list_length(list);
if (list == NULL && strstr(ddata, "://")) {
/* Assume a list of no files, and data has ://, is a remote link */
gchar *tmpdata = g_strstrip(g_strdup(ddata));
}
switch (prefs_common.compose_dnd_mode) {
case COMPOSE_DND_ASK:
- val = alertpanel_full(_("Insert or attach?"),
- _("Do you want to insert the contents of the file(s) "
- "into the message body, or attach it to the email?"),
+ msg = g_strdup_printf(
+ ngettext(
+ "Do you want to insert the contents of the file "
+ "into the message body, or attach it to the email?",
+ "Do you want to insert the contents of the %d files "
+ "into the message body, or attach them to the email?",
+ num_files),
+ num_files);
+ val = alertpanel_full(_("Insert or attach?"), msg,
GTK_STOCK_CANCEL, g_strconcat("+", _("_Insert"), NULL), _("_Attach"),
TRUE, NULL, ALERT_QUESTION, G_ALERTALTERNATE);
+ g_free(msg);
break;
case COMPOSE_DND_INSERT:
val = G_ALERTALTERNATE;
if (msginfo->folder->prefs->enable_default_account)
account = account_find_from_id(msginfo->folder->prefs->default_account);
- if (!account)
- account = msginfo->folder->folder->account;
-
if (!account && msginfo->to && prefs_common.forward_account_autosel) {
gchar *to;
Xstrdup_a(to, msginfo->to, return NULL);
account = account_find_from_address(buf, FALSE);
}
}
+
+ if (!account)
+ account = msginfo->folder->folder->account;
return account;
}
if (new_msglist) {
compose = compose_reply_mode((ComposeMode)action, new_msglist, body);
- procmsg_msginfo_free(tmp_msginfo);
+ procmsg_msginfo_free(&tmp_msginfo);
g_slist_free(new_msglist);
} else
compose = compose_reply_mode((ComposeMode)action, msginfo_list, body);