/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2009 Hiroyuki Yamamoto and the Claws Mail team
+ * Copyright (C) 1999-2011 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 "codeconv.h"
#include "utils.h"
#include "gtkutils.h"
+#include "gtkshruler.h"
#include "socket.h"
#include "alertpanel.h"
#include "manage_window.h"
-#include "gtkshruler.h"
#include "folder.h"
#include "addr_compl.h"
#include "quote_fmt.h"
COL_MIMETYPE = 0,
COL_SIZE = 1,
COL_NAME = 2,
- COL_DATA = 3,
- COL_AUTODATA = 4,
+ COL_CHARSET = 3,
+ COL_DATA = 4,
+ COL_AUTODATA = 5,
N_COL_COLUMNS
};
static gboolean compose_attach_append (Compose *compose,
const gchar *file,
const gchar *type,
- const gchar *content_type);
+ const gchar *content_type,
+ const gchar *charset);
static void compose_attach_parts (Compose *compose,
MsgInfo *msginfo);
static void compose_close_cb (GtkAction *action,
gpointer data);
+static void compose_print_cb (GtkAction *action,
+ gpointer data);
static void compose_set_encoding_cb (GtkAction *action, GtkRadioAction *current, gpointer data);
gboolean followup_and_reply_to,
const gchar *body);
-static gboolean compose_headerentry_changed_cb (GtkWidget *entry,
+static void compose_headerentry_changed_cb (GtkWidget *entry,
ComposeHeaderEntry *headerentry);
static gboolean compose_headerentry_key_press_event_cb(GtkWidget *entry,
GdkEventKey *event,
static void compose_check_forwards_go (GtkAction *action, gpointer data);
#endif
-static gint compose_defer_auto_save_draft (Compose *compose);
static PrefsAccount *compose_guess_forward_account_from_msginfo (MsgInfo *msginfo);
static MsgInfo *compose_msginfo_new_from_compose(Compose *compose);
/* {"Message/---", NULL, "---" }, */
{"Message/Save", NULL, N_("_Save"), "<control>S", NULL, G_CALLBACK(compose_save_cb) }, /*COMPOSE_KEEP_EDITING*/
/* {"Message/---", NULL, "---" }, */
+ {"Message/Print", NULL, N_("_Print"), NULL, NULL, G_CALLBACK(compose_print_cb) },
+ /* {"Message/---", NULL, "---" }, */
{"Message/Close", NULL, N_("_Close"), "<control>W", NULL, G_CALLBACK(compose_close_cb) },
/* Edit menu */
{"Edit/Copy", NULL, N_("_Copy"), "<control>C", NULL, G_CALLBACK(compose_copy_cb) },
{"Edit/Paste", NULL, N_("_Paste"), "<control>V", NULL, G_CALLBACK(compose_paste_cb) },
- {"Edit/SpecialPaste", NULL, N_("Special paste") },
+ {"Edit/SpecialPaste", NULL, N_("_Special paste") },
{"Edit/SpecialPaste/AsQuotation", NULL, N_("as _quotation"), NULL, NULL, G_CALLBACK(compose_paste_as_quote_cb) },
{"Edit/SpecialPaste/Wrapped", NULL, N_("_wrapped"), NULL, NULL, G_CALLBACK(compose_paste_wrap_cb) },
{"Edit/SpecialPaste/Unwrapped", NULL, N_("_unwrapped"), NULL, NULL, G_CALLBACK(compose_paste_no_wrap_cb) },
{
GtkTextBuffer *buffer;
GdkColor black = {(gulong)0, (gushort)0, (gushort)0, (gushort)0};
+#if !GTK_CHECK_VERSION(2, 24, 0)
GdkColormap *cmap;
- GdkColor color[8];
gboolean success[8];
int i;
+#endif
+ GdkColor color[8];
buffer = gtk_text_view_get_buffer(text);
color[5] = quote_bgcolor3;
color[6] = signature_color;
color[7] = uri_color;
- cmap = gdk_drawable_get_colormap(compose->window->window);
+#if !GTK_CHECK_VERSION(2, 24, 0)
+ cmap = gdk_drawable_get_colormap(gtk_widget_get_window(compose->window));
gdk_colormap_alloc_colors(cmap, color, 8, FALSE, TRUE, success);
for (i = 0; i < 8; i++) {
signature_color = uri_color = black;
}
}
+#endif
}
Compose *compose_new(PrefsAccount *account, const gchar *mailto,
gchar *mailto_from = NULL;
PrefsAccount *mailto_account = NULL;
MsgInfo* dummyinfo = NULL;
+ gint cursor_pos = -1;
MailField mfield = NO_FIELD_PRESENT;
gchar* buf;
GtkTextMark *mark;
dummyinfo = compose_msginfo_new_from_compose(compose);
/* decode \-escape sequences in the internal representation of the quote format */
- tmp = malloc(strlen(item->prefs->compose_override_from_format)+1);
+ tmp = g_malloc(strlen(item->prefs->compose_override_from_format)+1);
pref_get_unescaped_pref(tmp, item->prefs->compose_override_from_format);
#ifdef USE_ENCHANT
dummyinfo = compose_msginfo_new_from_compose(compose);
/* decode \-escape sequences in the internal representation of the quote format */
- tmp = malloc(strlen(subject_format)+1);
+ tmp = g_malloc(strlen(subject_format)+1);
pref_get_unescaped_pref(tmp, subject_format);
subject = gtk_editable_get_chars(GTK_EDITABLE(compose->subject_entry), 0, -1);
for (i = 0; i < attach_files->len; i++) {
file = g_ptr_array_index(attach_files, i);
- compose_attach_append(compose, file, file, NULL);
+ compose_attach_append(compose, file, file, NULL, NULL);
}
}
* is therefore created before placing the cursor
*/
case BODY_FIELD_PRESENT:
- gtk_widget_grab_focus(compose->text);
+ cursor_pos = quote_fmt_get_cursor_pos();
+ if (cursor_pos == -1)
+ gtk_widget_grab_focus(compose->header_last->entry);
+ else
+ gtk_widget_grab_focus(compose->text);
break;
}
compose->modified = FALSE;
compose_set_title(compose);
- hooks_invoke(COMPOSE_CREATED_HOOKLIST, compose);
+ hooks_invoke(COMPOSE_CREATED_HOOKLIST, compose);
return compose;
}
gchar *buf = NULL;
/* decode \-escape sequences in the internal representation of the quote format */
- tmp = malloc(strlen(msginfo->folder->prefs->reply_override_from_format)+1);
+ tmp = g_malloc(strlen(msginfo->folder->prefs->reply_override_from_format)+1);
pref_get_unescaped_pref(tmp, msginfo->folder->prefs->reply_override_from_format);
#ifdef USE_ENCHANT
undo_block(compose->undostruct);
#ifdef USE_ENCHANT
- compose_set_dictionaries_from_folder_prefs(compose, msginfo->folder);
+ compose_set_dictionaries_from_folder_prefs(compose, msginfo->folder);
+ gtkaspell_block_check(compose->gtkaspell);
#endif
if (quote_mode == COMPOSE_QUOTE_FORCED ||
_("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_wrap_all(compose);
+#ifdef USE_ENCHANT
+ if (compose->gtkaspell && compose->gtkaspell->check_while_typing)
+ gtkaspell_highlight_all(compose->gtkaspell);
+ gtkaspell_unblock_check(compose->gtkaspell);
+#endif
SIGNAL_UNBLOCK(textbuf);
gtk_widget_grab_focus(compose->text);
Compose *compose;
GtkTextView *textview;
GtkTextBuffer *textbuf;
- GtkTextIter iter;
+ gint cursor_pos = -1;
+ ComposeMode mode;
cm_return_val_if_fail(msginfo != NULL, NULL);
cm_return_val_if_fail(msginfo->folder != NULL, NULL);
(msginfo)))
account = cur_account;
- compose = compose_create(account, msginfo->folder, COMPOSE_FORWARD, batch);
+ if (!prefs_common.forward_as_attachment)
+ mode = COMPOSE_FORWARD_INLINE;
+ else
+ mode = COMPOSE_FORWARD;
+ compose = compose_create(account, msginfo->folder, mode, batch);
compose->updating = TRUE;
compose->fwdinfo = procmsg_msginfo_get_full_info(msginfo);
full_msginfo = procmsg_msginfo_copy(msginfo);
/* decode \-escape sequences in the internal representation of the quote format */
- tmp = malloc(strlen(msginfo->folder->prefs->forward_override_from_format)+1);
+ tmp = g_malloc(strlen(msginfo->folder->prefs->forward_override_from_format)+1);
pref_get_unescaped_pref(tmp, msginfo->folder->prefs->forward_override_from_format);
#ifdef USE_ENCHANT
+ gtkaspell_block_check(compose->gtkaspell);
quote_fmt_init(full_msginfo, NULL, NULL, FALSE, compose->account, FALSE,
compose->gtkaspell);
#else
g_warning("%s: file not exist\n", msgfile);
else
compose_attach_append(compose, msgfile, msgfile,
- "message/rfc822");
+ "message/rfc822", NULL);
g_free(msgfile);
} else {
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);
compose_wrap_all(compose);
+#ifdef USE_ENCHANT
+ if (compose->gtkaspell && compose->gtkaspell->check_while_typing)
+ gtkaspell_highlight_all(compose->gtkaspell);
+ gtkaspell_unblock_check(compose->gtkaspell);
+#endif
SIGNAL_UNBLOCK(textbuf);
- gtk_text_buffer_get_start_iter(textbuf, &iter);
- gtk_text_buffer_place_cursor(textbuf, &iter);
-
- gtk_widget_grab_focus(compose->header_last->entry);
+ cursor_pos = quote_fmt_get_cursor_pos();
+ if (cursor_pos == -1)
+ gtk_widget_grab_focus(compose->header_last->entry);
+ else
+ gtk_widget_grab_focus(compose->text);
if (!no_extedit && prefs_common.auto_exteditor)
compose_exec_ext_editor(compose);
gchar *buf = NULL;
/* decode \-escape sequences in the internal representation of the quote format */
- tmp = malloc(strlen(msginfo->folder->prefs->forward_override_from_format)+1);
+ tmp = g_malloc(strlen(msginfo->folder->prefs->forward_override_from_format)+1);
pref_get_unescaped_pref(tmp, msginfo->folder->prefs->forward_override_from_format);
#ifdef USE_ENCHANT
g_warning("%s: file not exist\n", msgfile);
else
compose_attach_append(compose, msgfile, msgfile,
- "message/rfc822");
+ "message/rfc822", NULL);
g_free(msgfile);
}
static void compose_entry_mark_default_to(Compose *compose, const gchar *mailto)
{
+#if !GTK_CHECK_VERSION(3, 0, 0)
static GdkColor yellow;
static GdkColor black;
static gboolean yellow_initialised = FALSE;
+#else
+ static GdkColor yellow = { (guint32)0, (guint16)0xf5, (guint16)0xf6, (guint16)0xbe };
+ static GdkColor black = { (guint32)0, (guint16)0x0, (guint16)0x0, (guint16)0x0 };
+#endif
GSList *h_list;
GtkEntry *entry;
+#if !GTK_CHECK_VERSION(3, 0, 0)
if (!yellow_initialised) {
gdk_color_parse("#f5f6be", &yellow);
gdk_color_parse("#000000", &black);
yellow_initialised &= gdk_colormap_alloc_color(
gdk_colormap_get_system(), &black, FALSE, TRUE);
}
+#endif
for (h_list = compose->header_list; h_list != NULL; h_list = h_list->next) {
entry = GTK_ENTRY(((ComposeHeaderEntry *)h_list->data)->entry);
if (gtk_entry_get_text(entry) &&
!g_utf8_collate(gtk_entry_get_text(entry), mailto)) {
+#if !GTK_CHECK_VERSION(3, 0, 0)
if (yellow_initialised) {
+#endif
gtk_widget_modify_base(
GTK_WIDGET(((ComposeHeaderEntry *)h_list->data)->entry),
GTK_STATE_NORMAL, &yellow);
gtk_widget_modify_text(
GTK_WIDGET(((ComposeHeaderEntry *)h_list->data)->entry),
GTK_STATE_NORMAL, &black);
+#if !GTK_CHECK_VERSION(3, 0, 0)
}
+#endif
}
}
}
while (attach[i] != NULL) {
gchar *utf8_filename = conv_filename_to_utf8(attach[i]);
if (utf8_filename) {
- if (compose_attach_append(compose, attach[i], utf8_filename, NULL)) {
+ if (compose_attach_append(compose, attach[i], utf8_filename, NULL, NULL)) {
gchar *tmp = g_strdup_printf("%s%s\n",
warn_files?warn_files:"",
utf8_filename);
if (hentry[H_REPLY_TO].body[0] != '\0') {
compose->replyto =
conv_unmime_header(hentry[H_REPLY_TO].body,
- NULL);
+ NULL, TRUE);
}
g_free(hentry[H_REPLY_TO].body);
hentry[H_REPLY_TO].body = NULL;
}
if (hentry[H_CC].body != NULL) {
- compose->cc = conv_unmime_header(hentry[H_CC].body, NULL);
+ compose->cc = conv_unmime_header(hentry[H_CC].body, NULL, TRUE);
g_free(hentry[H_CC].body);
hentry[H_CC].body = NULL;
}
if (hentry[H_BCC].body != NULL) {
if (compose->mode == COMPOSE_REEDIT)
compose->bcc =
- conv_unmime_header(hentry[H_BCC].body, NULL);
+ conv_unmime_header(hentry[H_BCC].body, NULL, TRUE);
g_free(hentry[H_BCC].body);
hentry[H_BCC].body = NULL;
}
if (hentry[H_FOLLOWUP_TO].body[0] != '\0') {
compose->followup_to =
conv_unmime_header(hentry[H_FOLLOWUP_TO].body,
- NULL);
+ NULL, TRUE);
}
g_free(hentry[H_FOLLOWUP_TO].body);
hentry[H_FOLLOWUP_TO].body = NULL;
gchar *tmp = NULL;
/* decode \-escape sequences in the internal representation of the quote format */
- tmp = malloc(strlen(fmt)+1);
+ tmp = g_malloc(strlen(fmt)+1);
pref_get_unescaped_pref(tmp, fmt);
quote_fmt_scan_string(tmp);
quote_fmt_parse();
compose->followup_to ? compose->followup_to :
compose->newsgroups ? compose->newsgroups : "",
COMPOSE_NEWSGROUPS, PREF_NONE);
- } else if (reply_to_ml) {
- compose_check_for_email_account(compose);
- compose_entry_append(compose,
- compose->ml_post, COMPOSE_TO, PREF_ML);
- } else
+ }
+ else
compose_entry_append
(compose,
compose->followup_to ? compose->followup_to :
compose_reply_set_subject(compose, msginfo);
if (to_ml && compose->ml_post) return;
- if (!to_all) return;
+ if (!to_all || compose->account->protocol == A_NNTP) return;
if (compose->replyto) {
Xstrdup_a(replyto, compose->replyto, return);
static gboolean compose_attach_append(Compose *compose, const gchar *file,
const gchar *filename,
- const gchar *content_type)
+ const gchar *content_type,
+ const gchar *charset)
{
AttachInfo *ainfo;
GtkTreeIter iter;
if (file_from_uri && is_file_exist(file_from_uri)) {
result = compose_attach_append(
compose, file_from_uri,
- filename,
- content_type);
+ filename, content_type,
+ charset);
}
g_free(file_from_uri);
if (result)
procmsg_msginfo_free(msginfo);
} else {
- if (!g_ascii_strncasecmp(content_type, "text", 4))
+ if (!g_ascii_strncasecmp(content_type, "text/", 5)) {
+ ainfo->charset = g_strdup(charset);
ainfo->encoding = procmime_get_encoding_for_text_file(file, &has_binary);
- else
+ } else {
ainfo->encoding = ENC_BASE64;
+ }
name = g_path_get_basename(filename ? filename : file);
ainfo->name = g_strdup(name);
}
ainfo->content_type =
g_strdup("application/octet-stream");
ainfo->encoding = ENC_BASE64;
- } else if (!g_ascii_strncasecmp(ainfo->content_type, "text", 4))
+ } else if (!g_ascii_strncasecmp(ainfo->content_type, "text/", 5))
ainfo->encoding =
procmime_get_encoding_for_text_file(file, &has_binary);
else
if (!strcmp(ainfo->content_type, "unknown") || has_binary) {
g_free(ainfo->content_type);
ainfo->content_type = g_strdup("application/octet-stream");
+ g_free(ainfo->charset);
+ ainfo->charset = NULL;
}
ainfo->size = (goffset)size;
COL_MIMETYPE, ainfo->content_type,
COL_SIZE, size_text,
COL_NAME, ainfo->name,
+ COL_CHARSET, ainfo->charset,
COL_DATA, ainfo,
COL_AUTODATA, auto_ainfo,
-1);
if (partname == NULL)
partname = "";
compose_attach_append(compose, outfile,
- partname, content_type);
+ partname, content_type,
+ procmime_mimeinfo_get_parameter(child, "charset"));
} else {
compose_force_signing(compose, compose->account, NULL);
}
*par_iter = iter;
undo_wrapping(compose->undostruct, FALSE);
compose->autowrap = prev_autowrap;
-
+
return modified;
}
}
if (msgpath == NULL) {
msgpath = folder_item_fetch_msg(folder, msgnum);
- val = procmsg_send_message_queue(msgpath, &errstr, folder, msgnum, &queued_removed);
+ val = procmsg_send_message_queue_with_lock(msgpath, &errstr, folder, msgnum, &queued_removed);
g_free(msgpath);
} else {
- val = procmsg_send_message_queue(msgpath, &errstr, folder, msgnum, &queued_removed);
+ val = procmsg_send_message_queue_with_lock(msgpath, &errstr, folder, msgnum, &queued_removed);
claws_unlink(msgpath);
g_free(msgpath);
}
if (mimepart->type == MIMETYPE_MESSAGE &&
!g_ascii_strcasecmp(mimepart->subtype, "rfc822")) {
mimepart->disposition = DISPOSITIONTYPE_INLINE;
- } else {
- if (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));
+ } else if (mimepart->type == MIMETYPE_TEXT) {
+ if (!ainfo->name && compose->mode == COMPOSE_FORWARD_INLINE) {
+ /* Text parts with no name come from multipart/alternative
+ * forwards. Make sure the recipient won't look at the
+ * original HTML part by mistake. */
mimepart->disposition = DISPOSITIONTYPE_ATTACHMENT;
+ ainfo->name = g_strdup_printf(_("Original %s part"),
+ mimepart->subtype);
}
- }
-
- if (compose->use_signing) {
+ if (ainfo->charset)
+ g_hash_table_insert(mimepart->typeparameters,
+ g_strdup("charset"), g_strdup(ainfo->charset));
+ }
+ if (ainfo->name && mimepart->type != MIMETYPE_MESSAGE) {
+ 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;
+ }
+
+ if (mimepart->type == MIMETYPE_MESSAGE
+ || mimepart->type == MIMETYPE_MULTIPART)
+ ainfo->encoding = ENC_BINARY;
+ else if (compose->use_signing) {
if (ainfo->encoding == ENC_7BIT)
ainfo->encoding = ENC_QUOTED_PRINTABLE;
else if (ainfo->encoding == ENC_8BIT)
ainfo->encoding = ENC_BASE64;
}
+
+
procmime_encode_content(mimepart, ainfo->encoding);
}
/* Program version and system info */
- if (g_slist_length(compose->to_list) && !IS_IN_CUSTOM_HEADER("X-Mailer") &&
+ if (compose->account->gen_xmailer &&
+ g_slist_length(compose->to_list) && !IS_IN_CUSTOM_HEADER("X-Mailer") &&
!compose->newsgroup_list) {
g_string_append_printf(header, "X-Mailer: %s (GTK+ %d.%d.%d; %s)\n",
prog_version,
cur = cur->next) {
CustomHeader *chdr = (CustomHeader *)cur->data;
- if (custom_header_is_allowed(chdr->name)) {
+ if (custom_header_is_allowed(chdr->name)
+ && chdr->value != NULL
+ && *(chdr->value) != '\0') {
compose_convert_header
(compose, buf, sizeof(buf),
- chdr->value ? chdr->value : "",
+ chdr->value,
strlen(chdr->name) + 2, FALSE);
g_string_append_printf(header, "%s: %s\n", chdr->name, buf);
}
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING,
+ G_TYPE_STRING,
G_TYPE_POINTER,
G_TYPE_AUTO_POINTER,
-1);
Compose *compose)
{
gint prev_autowrap;
- GtkTextBuffer *buffer = GTK_TEXT_VIEW(text)->buffer;
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));
#if USE_ENCHANT
if (event->button == 3) {
GtkTextIter iter;
GtkWidget *text;
GtkTextBuffer *buffer;
GtkClipboard *clipboard;
- CLAWS_TIP_DECL();
UndoMain *undostruct;
titles[COL_MIMETYPE] = _("MIME type");
titles[COL_SIZE] = _("Size");
titles[COL_NAME] = _("Name");
+ titles[COL_CHARSET] = _("Charset");
compose->batch = batch;
compose->account = account;
window = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "compose");
gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
- gtk_widget_set_size_request(window, -1, prefs_common.compose_height);
+ gtk_widget_set_size_request(window, prefs_common.compose_width,
+ prefs_common.compose_height);
if (!geometry.max_width) {
geometry.max_width = gdk_screen_width();
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Message", "Separator2", "Message/---", GTK_UI_MANAGER_SEPARATOR)
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Message", "Save", "Message/Save", GTK_UI_MANAGER_MENUITEM)
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Message", "Separator3", "Message/---", GTK_UI_MANAGER_SEPARATOR)
+ MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Message", "Print", "Message/Print", GTK_UI_MANAGER_MENUITEM)
+ MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Message", "Separator4", "Message/---", GTK_UI_MANAGER_SEPARATOR)
MENUITEM_ADDUI_MANAGER(compose->ui_manager, "/Menu/Message", "Close", "Message/Close", GTK_UI_MANAGER_MENUITEM)
/* Edit menu */
ruler_hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(edit_vbox), ruler_hbox, FALSE, FALSE, 0);
- ruler = gtk_shruler_new();
- gtk_ruler_set_range(GTK_RULER(ruler), 0.0, 100.0, 1.0, 100.0);
+ ruler = gtk_shruler_new(GTK_ORIENTATION_HORIZONTAL);
+ gtk_shruler_set_range(GTK_SHRULER(ruler), 0.0, 100.0, 1.0);
gtk_box_pack_start(GTK_BOX(ruler_hbox), ruler, TRUE, TRUE,
BORDER_WIDTH);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwin),
GTK_SHADOW_IN);
gtk_box_pack_start(GTK_BOX(edit_vbox), scrolledwin, TRUE, TRUE, 0);
- gtk_widget_set_size_request(scrolledwin, prefs_common.compose_width, -1);
text = gtk_text_view_new();
if (prefs_common.show_compose_margin) {
gtk_text_buffer_add_selection_clipboard(buffer, clipboard);
gtk_container_add(GTK_CONTAINER(scrolledwin), text);
-
g_signal_connect_after(G_OBJECT(text), "size_allocate",
G_CALLBACK(compose_edit_size_alloc),
ruler);
}
}
}
- compose->gtkaspell = gtkaspell;
+ compose->gtkaspell = gtkaspell;
compose_spell_menu_changed(compose);
claws_spell_entry_set_gtkaspell(CLAWS_SPELL_ENTRY(subject_entry), gtkaspell);
#endif
cm_return_if_fail(GTK_IS_CHECK_MENU_ITEM(widget));
- if (!GTK_CHECK_MENU_ITEM(widget)->active)
+ if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
return;
systemid = g_object_get_data(G_OBJECT(widget), "privacy_system");
{
static gchar *branch_path = "/Menu/Options/PrivacySystem";
GtkWidget *menuitem = NULL;
- GList *amenu;
+ GList *children, *amenu;
gboolean can_sign = FALSE, can_encrypt = FALSE;
gboolean found = FALSE;
gtk_ui_manager_get_widget(compose->ui_manager, branch_path)));
cm_return_if_fail(menuitem != NULL);
- amenu = GTK_MENU_SHELL(menuitem)->children;
+ children = gtk_container_get_children(GTK_CONTAINER(GTK_MENU_SHELL(menuitem)));
+ amenu = children;
menuitem = NULL;
while (amenu != NULL) {
- GList *alist = amenu->next;
-
systemid = g_object_get_data(G_OBJECT(amenu->data), "privacy_system");
if (systemid != NULL) {
if (strcmp(systemid, compose->privacy_system) == 0 &&
break;
}
- amenu = alist;
+ amenu = amenu->next;
}
+ g_list_free(children);
if (menuitem != NULL)
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
static void compose_destroy(Compose *compose)
{
+ GtkAllocation allocation;
GtkTextBuffer *buffer;
GtkClipboard *clipboard;
#endif
if (!compose->batch) {
- prefs_common.compose_width = compose->scrolledwin->allocation.width;
- prefs_common.compose_height = compose->window->allocation.height;
+ gtk_widget_get_allocation(compose->window, &allocation);
+ prefs_common.compose_width = allocation.width;
+ prefs_common.compose_height = allocation.height;
}
if (!gtk_widget_get_parent(compose->paned))
g_free(ainfo->file);
g_free(ainfo->content_type);
g_free(ainfo->name);
+ g_free(ainfo->charset);
g_free(ainfo);
}
COL_MIMETYPE, ainfo->content_type,
COL_SIZE, text,
COL_NAME, ainfo->name,
+ COL_CHARSET, ainfo->charset,
-1);
break;
GdkEventKey *event,
gboolean *cancelled)
{
- if (event && event->keyval == GDK_Escape) {
+ if (event && event->keyval == GDK_KEY_Escape) {
*cancelled = TRUE;
gtk_main_quit();
}
- if (event && event->keyval == GDK_Return) {
+ if (event && event->keyval == GDK_KEY_Return) {
*cancelled = FALSE;
gtk_main_quit();
return TRUE;
Compose *compose = (Compose *)data;
gsize bytes_read;
- debug_print(_("Compose: input from monitoring process\n"));
+ debug_print("Compose: input from monitoring process\n");
g_io_channel_read_chars(source, buf, sizeof(buf), &bytes_read, NULL);
(allocation->width - allocation->x) / char_width;
/* got the maximum */
- gtk_ruler_set_range(GTK_RULER(shruler),
- 0.0, line_width_in_chars, 0,
- /*line_width_in_chars*/ char_width);
+ gtk_shruler_set_range(GTK_SHRULER(shruler),
+ 0.0, line_width_in_chars, 0);
}
return TRUE;
if (!event) return FALSE;
switch (event->keyval) {
- case GDK_Delete:
+ case GDK_KEY_Delete:
compose_attach_remove_selected(NULL, compose);
break;
}
for ( tmp = file_list; tmp; tmp = tmp->next) {
gchar *file = (gchar *) tmp->data;
gchar *utf8_filename = conv_filename_to_utf8(file);
- compose_attach_append(compose, file, utf8_filename, NULL);
+ compose_attach_append(compose, file, utf8_filename, NULL, NULL);
compose_changed_cb(NULL, compose);
if (free_data) {
g_free(file);
compose_close(compose);
}
+static void compose_print_cb(GtkAction *action, gpointer data)
+{
+ Compose *compose = (Compose *) data;
+
+ compose_draft((gpointer)compose, COMPOSE_AUTO_SAVE);
+ if (compose->targetinfo)
+ messageview_print(compose->targetinfo, FALSE, -1, -1, 0);
+}
+
static void compose_set_encoding_cb(GtkAction *action, GtkRadioAction *current, gpointer data)
{
gboolean active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (current));
Compose *compose = (Compose *)data;
if (compose->focused_editable
#ifndef GENERIC_UMPC
- && gtkut_widget_has_focus(compose->focused_editable)
+ && gtk_widget_has_focus(compose->focused_editable)
#endif
)
entry_cut_clipboard(compose->focused_editable);
Compose *compose = (Compose *)data;
if (compose->focused_editable
#ifndef GENERIC_UMPC
- && gtkut_widget_has_focus(compose->focused_editable)
+ && gtk_widget_has_focus(compose->focused_editable)
#endif
)
entry_copy_clipboard(compose->focused_editable);
GtkTextBuffer *buffer;
BLOCK_WRAP();
if (compose->focused_editable &&
- gtkut_widget_has_focus(compose->focused_editable))
+ gtk_widget_has_focus(compose->focused_editable))
entry_paste_clipboard(compose, compose->focused_editable,
prefs_common.linewrap_pastes,
GDK_SELECTION_CLIPBOARD, NULL);
UNBLOCK_WRAP();
#ifdef USE_ENCHANT
- if (gtkut_widget_has_focus(compose->text) &&
+ if (gtk_widget_has_focus(compose->text) &&
compose->gtkaspell &&
compose->gtkaspell->check_while_typing)
gtkaspell_highlight_all(compose->gtkaspell);
gint wrap_quote = prefs_common.linewrap_quote;
if (compose->focused_editable
#ifndef GENERIC_UMPC
- && gtkut_widget_has_focus(compose->focused_editable)
+ && gtk_widget_has_focus(compose->focused_editable)
#endif
) {
/* let text_insert() (called directly or at a later time
BLOCK_WRAP();
if (compose->focused_editable
#ifndef GENERIC_UMPC
- && gtkut_widget_has_focus(compose->focused_editable)
+ && gtk_widget_has_focus(compose->focused_editable)
#endif
)
entry_paste_clipboard(compose, compose->focused_editable, FALSE,
UNBLOCK_WRAP();
#ifdef USE_ENCHANT
- if (gtkut_widget_has_focus(compose->text) &&
+ if (gtk_widget_has_focus(compose->text) &&
compose->gtkaspell &&
compose->gtkaspell->check_while_typing)
gtkaspell_highlight_all(compose->gtkaspell);
BLOCK_WRAP();
if (compose->focused_editable
#ifndef GENERIC_UMPC
- && gtkut_widget_has_focus(compose->focused_editable)
+ && gtk_widget_has_focus(compose->focused_editable)
#endif
)
entry_paste_clipboard(compose, compose->focused_editable, TRUE,
UNBLOCK_WRAP();
#ifdef USE_ENCHANT
- if (gtkut_widget_has_focus(compose->text) &&
+ if (gtk_widget_has_focus(compose->text) &&
compose->gtkaspell &&
compose->gtkaspell->check_while_typing)
gtkaspell_highlight_all(compose->gtkaspell);
Compose *compose = (Compose *)data;
if (compose->focused_editable
#ifndef GENERIC_UMPC
- && gtkut_widget_has_focus(compose->focused_editable)
+ && gtk_widget_has_focus(compose->focused_editable)
#endif
)
entry_allsel(compose->focused_editable);
{textview_delete_to_line_end}
};
- if (!gtkut_widget_has_focus(GTK_WIDGET(text))) return;
+ if (!gtk_widget_has_focus(GTK_WIDGET(text))) return;
if (action >= COMPOSE_CALL_ADVANCED_ACTION_MOVE_BEGINNING_OF_LINE &&
action <= COMPOSE_CALL_ADVANCED_ACTION_DELETE_TO_LINE_END) {
static void compose_grab_focus_cb(GtkWidget *widget, Compose *compose)
{
+ GtkAllocation allocation;
+ GtkWidget *parent;
gchar *str = NULL;
if (GTK_IS_EDITABLE(widget)) {
gtk_editable_set_position(GTK_EDITABLE(widget),
strlen(str));
g_free(str);
- if (widget->parent && widget->parent->parent
- && widget->parent->parent->parent) {
- if (GTK_IS_SCROLLED_WINDOW(widget->parent->parent->parent)) {
- gint y = widget->allocation.y;
- gint height = widget->allocation.height;
+ if ((parent = gtk_widget_get_parent(widget))
+ && (parent = gtk_widget_get_parent(parent))
+ && (parent = gtk_widget_get_parent(parent))) {
+ if (GTK_IS_SCROLLED_WINDOW(parent)) {
+ gtk_widget_get_allocation(widget, &allocation);
+ gint y = allocation.y;
+ gint height = allocation.height;
GtkAdjustment *shown = gtk_scrolled_window_get_vadjustment
- (GTK_SCROLLED_WINDOW(widget->parent->parent->parent));
+ (GTK_SCROLLED_WINDOW(parent));
- if (y < (int)shown->value) {
- gtk_adjustment_set_value(GTK_ADJUSTMENT(shown), y - 1);
+ gfloat value = gtk_adjustment_get_value(shown);
+ gfloat upper = gtk_adjustment_get_upper(shown);
+ gfloat page_size = gtk_adjustment_get_page_size(shown);
+ if (y < (int)value) {
+ gtk_adjustment_set_value(shown, y - 1);
}
- if (y + height > (int)shown->value + (int)shown->page_size) {
- if (y - height - 1 < (int)shown->upper - (int)shown->page_size) {
- gtk_adjustment_set_value(GTK_ADJUSTMENT(shown),
- y + height - (int)shown->page_size - 1);
+ if ((y + height) > ((int)value + (int)page_size)) {
+ if ((y - height - 1) < ((int)upper - (int)page_size)) {
+ gtk_adjustment_set_value(shown,
+ y + height - (int)page_size - 1);
} else {
- gtk_adjustment_set_value(GTK_ADJUSTMENT(shown),
- (int)shown->upper - (int)shown->page_size - 1);
+ gtk_adjustment_set_value(shown,
+ (int)upper - (int)page_size - 1);
}
}
}
{
Compose *compose = (Compose *)user_data;
GList *list, *tmp;
+ GdkAtom type;
- if (((gdk_atom_name(data->type) && !strcmp(gdk_atom_name(data->type), "text/uri-list"))
+ type = gtk_selection_data_get_data_type(data);
+ if (((gdk_atom_name(type) && !strcmp(gdk_atom_name(type), "text/uri-list"))
#ifdef G_OS_WIN32
- || (gdk_atom_name(data->type) && !strcmp(gdk_atom_name(data->type), "DROPFILES_DND"))
+ || (gdk_atom_name(type) && !strcmp(gdk_atom_name(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);
+ list = uri_list_extract_filenames(
+ (const gchar *)gtk_selection_data_get_data(data));
for (tmp = list; tmp != NULL; tmp = tmp->next) {
gchar *utf8_filename = conv_filename_to_utf8((const gchar *)tmp->data);
compose_attach_append
(compose, (const gchar *)tmp->data,
- utf8_filename, NULL);
+ utf8_filename, NULL, NULL);
g_free(utf8_filename);
}
if (list) compose_changed_cb(NULL, compose);
TRUE, TRUE);
if (file) {
compose_attach_append(compose, (const gchar *)file,
- (const gchar *)file, "message/rfc822");
+ (const gchar *)file, "message/rfc822", NULL);
g_free(file);
}
}
{
Compose *compose = (Compose *)user_data;
GList *list, *tmp;
+ GdkAtom type;
/* strangely, testing data->type == gdk_atom_intern("text/uri-list", TRUE)
* does not work */
+ type = gtk_selection_data_get_data_type(data);
#ifndef G_OS_WIN32
- if (gdk_atom_name(data->type) && !strcmp(gdk_atom_name(data->type), "text/uri-list")) {
+ if (gdk_atom_name(type) && !strcmp(gdk_atom_name(type), "text/uri-list")) {
#else
- if (gdk_atom_name(data->type) && !strcmp(gdk_atom_name(data->type), "DROPFILES_DND")) {
+ if (gdk_atom_name(type) && !strcmp(gdk_atom_name(type), "DROPFILES_DND")) {
#endif
AlertValue val = G_ALERTDEFAULT;
+ const gchar* ddata = (const gchar *)gtk_selection_data_get_data(data);
- list = uri_list_extract_filenames((const gchar *)data->data);
- if (list == NULL && strstr((gchar *)(data->data), "://")) {
+ list = uri_list_extract_filenames(ddata);
+ if (list == NULL && strstr(ddata, "://")) {
/* Assume a list of no files, and data has ://, is a remote link */
- gchar *tmpdata = g_strstrip(g_strdup((const gchar *)data->data));
+ gchar *tmpdata = g_strstrip(g_strdup(ddata));
gchar *tmpfile = get_tmp_file();
str_write_to_file(tmpdata, tmpfile);
g_free(tmpdata);
gpointer user_data)
{
GtkEditable *entry = (GtkEditable *)user_data;
- gchar *email = (gchar *)data->data;
+ const gchar *email = (const gchar *)gtk_selection_data_get_data(data);
/* strangely, testing data->type == gdk_atom_intern("text/plain", TRUE)
* does not work */
gchar *decoded=g_new(gchar, strlen(email));
int start = 0;
- email += strlen("mailto:");
- decode_uri(decoded, email); /* will fit */
+ decode_uri(decoded, email + strlen("mailto:")); /* will fit */
gtk_editable_delete_text(entry, 0, -1);
gtk_editable_insert_text(entry, decoded, strlen(decoded), &start);
gtk_drag_finish(drag_context, TRUE, FALSE, time);
if ((g_slist_length(headerentry->compose->header_list) > 0) &&
((headerentry->headernum + 1) != headerentry->compose->header_nextrow) &&
!(event->state & GDK_MODIFIER_MASK) &&
- (event->keyval == GDK_BackSpace) &&
+ (event->keyval == GDK_KEY_BackSpace) &&
(strlen(gtk_entry_get_text(GTK_ENTRY(entry))) == 0)) {
gtk_container_remove
(GTK_CONTAINER(headerentry->compose->header_table),
g_slist_remove(headerentry->compose->header_list,
headerentry);
g_free(headerentry);
- } else if (event->keyval == GDK_Tab) {
+ } else if (event->keyval == GDK_KEY_Tab) {
if (headerentry->compose->header_last == headerentry) {
/* Override default next focus, and give it to subject_entry
* instead of notebook tabs
return FALSE;
}
-static gboolean compose_headerentry_changed_cb(GtkWidget *entry,
+static gboolean scroll_postpone(gpointer data)
+{
+ Compose *compose = (Compose *)data;
+
+ cm_return_val_if_fail(!compose->batch, FALSE);
+
+ GTK_EVENTS_FLUSH();
+ compose_show_first_last_header(compose, FALSE);
+ return FALSE;
+}
+
+static void compose_headerentry_changed_cb(GtkWidget *entry,
ComposeHeaderEntry *headerentry)
{
if (strlen(gtk_entry_get_text(GTK_ENTRY(entry))) != 0) {
g_signal_handlers_disconnect_matched
(G_OBJECT(entry), G_SIGNAL_MATCH_DATA,
0, 0, NULL, NULL, headerentry);
-
- /* Automatically scroll down */
- GTK_EVENTS_FLUSH();
- compose_show_first_last_header(headerentry->compose, FALSE);
-
+
+ if (!headerentry->compose->batch)
+ g_timeout_add(0, scroll_postpone, headerentry->compose);
}
+}
+
+static gboolean compose_defer_auto_save_draft(Compose *compose)
+{
+ compose->draft_timeout_tag = -1;
+ compose_draft((gpointer)compose, COMPOSE_AUTO_SAVE);
return FALSE;
}
GtkAdjustment *vadj;
cm_return_if_fail(compose);
+ cm_return_if_fail(!compose->batch);
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 - vadj->page_size)));
+ cm_return_if_fail(GTK_IS_VIEWPORT(gtk_widget_get_parent(compose->header_table)));
+ vadj = gtk_viewport_get_vadjustment(GTK_VIEWPORT(
+ gtk_widget_get_parent(compose->header_table)));
+ gtk_adjustment_set_value(vadj, (show_first ?
+ gtk_adjustment_get_lower(vadj) :
+ (gtk_adjustment_get_upper(vadj) -
+ gtk_adjustment_get_page_size(vadj))));
gtk_adjustment_changed(vadj);
}
gtk_text_buffer_get_char_count(buffer) % prefs_common.autosave_length == 0 &&
compose->draft_timeout_tag != -2 /* disabled while loading */)
compose->draft_timeout_tag = g_timeout_add
- (500, (GtkFunction) compose_defer_auto_save_draft, compose);
-}
-static gint compose_defer_auto_save_draft(Compose *compose)
-{
- compose->draft_timeout_tag = -1;
- compose_draft((gpointer)compose, COMPOSE_AUTO_SAVE);
- return FALSE;
+ (500, (GSourceFunc) compose_defer_auto_save_draft, compose);
}
#if USE_ENCHANT
if (!compose->gtkaspell)
return;
- if (gtkut_widget_has_focus(compose->subject_entry))
+ if (gtk_widget_has_focus(compose->subject_entry))
claws_spell_entry_check_all(
CLAWS_SPELL_ENTRY(compose->subject_entry));
else
return;
}
- if (gtkut_widget_has_focus(compose->subject_entry))
+ if (gtk_widget_has_focus(compose->subject_entry))
claws_spell_entry_check_backwards(
CLAWS_SPELL_ENTRY(compose->subject_entry));
else
return;
}
- if (gtkut_widget_has_focus(compose->subject_entry))
+ if (gtk_widget_has_focus(compose->subject_entry))
claws_spell_entry_check_forwards_go(
CLAWS_SPELL_ENTRY(compose->subject_entry));
else