MsgInfo *msginfo);
static void compose_wrap_line (Compose *compose);
static void compose_wrap_line_all (Compose *compose);
+static void compose_wrap_line_all_full (Compose *compose,
+ gboolean autowrap);
static void compose_set_title (Compose *compose);
static PrefsAccount *compose_current_mail_account(void);
static gint compose_write_body_to_file (Compose *compose,
const gchar *file);
static gint compose_remove_reedit_target (Compose *compose);
+void compose_remove_draft (Compose *compose);
static gint compose_queue (Compose *compose,
gint *msgnum,
FolderItem **item);
static void compose_show_first_last_header (Compose *compose, gboolean show_first);
-#if USE_PSPELL
+#if USE_ASPELL
static void compose_check_all (Compose *compose);
static void compose_highlight_all (Compose *compose);
static void compose_check_backwards (Compose *compose);
"<control><alt>L", compose_wrap_line_all, 0, NULL},
{N_("/_Edit/Edit with e_xternal editor"),
"<shift><control>X", compose_ext_editor_cb, 0, NULL},
-#if USE_PSPELL
+#if USE_ASPELL
{N_("/_Spelling"), NULL, NULL, 0, "<Branch>"},
{N_("/_Spelling/_Check all or check selection"),
NULL, compose_check_all, 0, NULL},
gtk_stext_set_point(GTK_STEXT(compose->text), 0);
gtk_stext_thaw(text);
+ gtk_widget_grab_focus(compose->header_last->entry);
+
#if 0 /* NEW COMPOSE GUI */
if (account->protocol != A_NNTP)
gtk_widget_grab_focus(compose->to_entry);
/* check if we should join the next line */
static gboolean join_next_line(GtkSText *text, guint start_pos, guint tlen,
- guint prev_ilen)
+ guint prev_ilen, gboolean autowrap)
{
guint indent_len, ch_len;
gboolean do_join = FALSE;
indent_len = get_indent_length(text, start_pos, tlen);
- if (indent_len == prev_ilen) {
+ if ((autowrap || indent_len > 0) && indent_len == prev_ilen) {
GET_CHAR(start_pos + indent_len, cbuf, ch_len);
if (ch_len > 0 && (cbuf[0] != '\n'))
do_join = TRUE;
}
static void compose_wrap_line_all(Compose *compose)
+{
+ compose_wrap_line_all_full(compose, FALSE);
+}
+
+#define STEXT_FREEZE() \
+ if (!frozen) { gtk_stext_freeze(text); frozen = TRUE; }
+
+static void compose_wrap_line_all_full(Compose *compose, gboolean autowrap)
{
GtkSText *text = GTK_STEXT(compose->text);
guint tlen;
gboolean linewrap_quote = TRUE;
gboolean set_editable_pos = FALSE;
gint editable_pos = 0;
+ gboolean frozen = FALSE;
guint linewrap_len = prefs_common.linewrap_len;
gchar *qfmt = prefs_common.quotemark;
gchar cbuf[MB_LEN_MAX];
- gtk_stext_freeze(text);
-
tlen = gtk_stext_get_length(text);
for (; cur_pos < tlen; cur_pos++) {
gchar cb[MB_LEN_MAX];
/* should we join the next line */
- if (do_delete &&
- join_next_line(text, cur_pos + 1, tlen, i_len))
+ if ((autowrap || i_len != cur_len) && do_delete &&
+ join_next_line
+ (text, cur_pos + 1, tlen, i_len, autowrap))
do_delete = TRUE;
else
do_delete = FALSE;
#endif
/* should we delete to perform smart wrapping */
if (line_len < linewrap_len && do_delete) {
+ STEXT_FREEZE();
/* get rid of newline */
gtk_stext_set_point(text, cur_pos);
gtk_stext_forward_delete(text, 1);
if (p_pos + i_len != line_pos ||
!gtkut_stext_is_uri_string
(text, line_pos, tlen)) {
+ STEXT_FREEZE();
/* workaround for correct cursor
position */
if (set_editable_pos == FALSE) {
}
/* insert CR */
+ STEXT_FREEZE();
gtk_stext_set_point(text, line_pos);
gtk_stext_insert(text, NULL, NULL, NULL, "\n", 1);
/* gtk_stext_compact_buffer(text); */
cur_pos = line_pos - 1;
/* start over with current line */
is_new_line = TRUE;
- line_len = 0;
- cur_len = 0;
- do_delete = TRUE;
+ line_len = cur_len = 0;
+ if (autowrap || i_len > 0)
+ do_delete = TRUE;
+ else
+ do_delete = FALSE;
#ifdef WRAP_DEBUG
g_print("after CR insert ");
dump_text(text, line_pos, tlen, 1);
ins_len = ins_quote
(text, i_len, p_pos,
tlen, qfmt);
-
- /* gtk_stext_compact_buffer(text); */
tlen += ins_len;
}
#ifdef WRAP_DEBUG
cur_len += ch_len;
}
- gtk_stext_thaw(text);
+ if (frozen)
+ gtk_stext_thaw(text);
if (set_editable_pos && editable_pos <= tlen)
gtk_editable_set_position(GTK_EDITABLE(text), editable_pos);
}
+#undef STEXT_FREEZE
#undef GET_CHAR
static void compose_set_title(Compose *compose)
return 0;
}
+void compose_remove_draft(Compose *compose)
+{
+ FolderItem *drafts;
+ MsgInfo *msginfo = compose->targetinfo;
+ drafts = account_get_special_folder(compose->account, F_DRAFT);
+
+ if (procmsg_msg_exist(msginfo)) {
+ folder_item_remove_msg(drafts, msginfo->msgnum);
+ folderview_update_item(drafts, TRUE);
+ }
+
+}
+
static gint compose_queue(Compose *compose, gint *msgnum, FolderItem **item)
{
return compose_queue_sub (compose, msgnum, item, FALSE);
GtkWidget *tmpl_menu;
gint n_entries;
-#if USE_PSPELL
- GtkPspell * gtkpspell = NULL;
+#if USE_ASPELL
+ GtkAspell * gtkaspell = NULL;
#endif
static GdkGeometry geometry;
compose->redirect_filename = NULL;
compose->undostruct = undostruct;
-#if USE_PSPELL
+#if USE_ASPELL
menu_set_sensitive(ifactory, "/Spelling", FALSE);
- if (prefs_common.enable_pspell) {
- gtkpspell = gtkpspell_new((const gchar*)prefs_common.dictionary,
+ if (prefs_common.enable_aspell) {
+ gtkaspell = gtkaspell_new((const gchar*)prefs_common.dictionary,
conv_get_current_charset_str(),
prefs_common.misspelled_col,
prefs_common.check_while_typing,
prefs_common.use_alternate,
GTK_STEXT(text));
- if (!gtkpspell) {
- alertpanel_error(_("Spell checker could not be started.\n%s"), gtkpspellcheckers->error_message);
- gtkpspell_checkers_reset_error();
+ if (!gtkaspell) {
+ alertpanel_error(_("Spell checker could not be started.\n%s"), gtkaspellcheckers->error_message);
+ gtkaspell_checkers_reset_error();
} else {
GtkWidget *menuitem;
- if (!gtkpspell_set_sug_mode(gtkpspell, prefs_common.pspell_sugmode)) {
- debug_print("Pspell: could not set suggestion mode %s\n",
- gtkpspellcheckers->error_message);
- gtkpspell_checkers_reset_error();
+ if (!gtkaspell_set_sug_mode(gtkaspell, prefs_common.aspell_sugmode)) {
+ debug_print("Aspell: could not set suggestion mode %s\n",
+ gtkaspellcheckers->error_message);
+ gtkaspell_checkers_reset_error();
}
menuitem = gtk_item_factory_get_item(ifactory, "/Spelling/Spelling Configuration");
- gtkpspell_populate_submenu(gtkpspell, menuitem);
+ gtkaspell_populate_submenu(gtkaspell, menuitem);
menu_set_sensitive(ifactory, "/Spelling", TRUE);
}
}
compose->use_followupto = FALSE;
#endif
-#if USE_PSPELL
- compose->gtkpspell = gtkpspell;
+#if USE_ASPELL
+ compose->gtkaspell = gtkaspell;
#endif
#if 0 /* NEW COMPOSE GUI */
if (addressbook_get_target_compose() == compose)
addressbook_set_target_compose(NULL);
-#if USE_PSPELL
- if (compose->gtkpspell) {
- gtkpspell_delete(compose->gtkpspell);
+#if USE_ASPELL
+ if (compose->gtkaspell) {
+ gtkaspell_delete(compose->gtkaspell);
}
#endif
{
Compose *compose = (Compose *)data;
AlertValue val;
-
+
if (compose->exteditor_tag != -1) {
if (!compose_ext_editor_kill(compose))
return;
switch (val) {
case G_ALERTDEFAULT:
+ if (prefs_common.autosave)
+ compose_remove_draft(compose);
break;
case G_ALERTALTERNATE:
compose_draft_cb(data, 0, NULL);
return;
}
}
+
gtk_widget_destroy(compose->window);
}
(GTK_EDITABLE(compose->focused_editable), 0, -1);
}
-static void compose_gtk_stext_action_cb(Compose *compose, ComposeCallGtkSTextAction action)
+static void compose_gtk_stext_action_cb(Compose *compose,
+ ComposeCallGtkSTextAction action)
{
- if (!(compose->focused_editable && GTK_WIDGET_HAS_FOCUS(compose->focused_editable))) return;
-
- switch (action) {
- case COMPOSE_CALL_GTK_STEXT_MOVE_BEGINNING_OF_LINE:
- gtk_stext_move_beginning_of_line(GTK_STEXT(compose->focused_editable));
- break;
- case COMPOSE_CALL_GTK_STEXT_MOVE_FORWARD_CHARACTER:
- gtk_stext_move_forward_character(GTK_STEXT(compose->focused_editable));
- break;
- case COMPOSE_CALL_GTK_STEXT_MOVE_BACKWARD_CHARACTER:
- gtk_stext_move_backward_character(GTK_STEXT(compose->focused_editable));
- break;
- case COMPOSE_CALL_GTK_STEXT_MOVE_FORWARD_WORD:
- gtk_stext_move_forward_word(GTK_STEXT(compose->focused_editable));
- break;
- case COMPOSE_CALL_GTK_STEXT_MOVE_BACKWARD_WORD:
- gtk_stext_move_backward_word(GTK_STEXT(compose->focused_editable));
- break;
- case COMPOSE_CALL_GTK_STEXT_MOVE_END_OF_LINE:
- gtk_stext_move_end_of_line(GTK_STEXT(compose->focused_editable));
- break;
- case COMPOSE_CALL_GTK_STEXT_MOVE_NEXT_LINE:
- gtk_stext_move_next_line(GTK_STEXT(compose->focused_editable));
- break;
- case COMPOSE_CALL_GTK_STEXT_MOVE_PREVIOUS_LINE:
- gtk_stext_move_previous_line(GTK_STEXT(compose->focused_editable));
- break;
- case COMPOSE_CALL_GTK_STEXT_DELETE_FORWARD_CHARACTER:
- gtk_stext_delete_forward_character(GTK_STEXT(compose->focused_editable));
- break;
- case COMPOSE_CALL_GTK_STEXT_DELETE_BACKWARD_CHARACTER:
- gtk_stext_delete_backward_character(GTK_STEXT(compose->focused_editable));
- break;
- case COMPOSE_CALL_GTK_STEXT_DELETE_FORWARD_WORD:
- gtk_stext_delete_forward_word(GTK_STEXT(compose->focused_editable));
- break;
- case COMPOSE_CALL_GTK_STEXT_DELETE_BACKWARD_WORD:
- gtk_stext_delete_backward_word(GTK_STEXT(compose->focused_editable));
- break;
- case COMPOSE_CALL_GTK_STEXT_DELETE_LINE:
- gtk_stext_delete_line(GTK_STEXT(compose->focused_editable));
- break;
- case COMPOSE_CALL_GTK_STEXT_DELETE_LINE_N:
- gtk_stext_delete_line(GTK_STEXT(compose->focused_editable));
- gtk_stext_delete_forward_character(GTK_STEXT(compose->focused_editable));
- break;
- case COMPOSE_CALL_GTK_STEXT_DELETE_TO_LINE_END:
- gtk_stext_delete_to_line_end(GTK_STEXT(compose->focused_editable));
- break;
- default:
- break;
- }
+ GtkSText *text = GTK_STEXT(compose->text);
+ static struct {
+ void (*do_action) (GtkSText *text);
+ } action_table[] = {
+ {gtk_stext_move_beginning_of_line},
+ {gtk_stext_move_forward_character},
+ {gtk_stext_move_backward_character},
+ {gtk_stext_move_forward_word},
+ {gtk_stext_move_backward_word},
+ {gtk_stext_move_end_of_line},
+ {gtk_stext_move_next_line},
+ {gtk_stext_move_previous_line},
+ {gtk_stext_delete_forward_character},
+ {gtk_stext_delete_backward_character},
+ {gtk_stext_delete_forward_word},
+ {gtk_stext_delete_backward_word},
+ {gtk_stext_delete_line},
+ {gtk_stext_delete_line}, /* gtk_stext_delete_line_n */
+ {gtk_stext_delete_to_line_end}
+ };
+
+ if (!GTK_WIDGET_HAS_FOCUS(text)) return;
+
+ if (action >= COMPOSE_CALL_GTK_STEXT_MOVE_BEGINNING_OF_LINE &&
+ action <= COMPOSE_CALL_GTK_STEXT_DELETE_TO_LINE_END)
+ action_table[action].do_action(text);
}
static void compose_grab_focus_cb(GtkWidget *widget, Compose *compose)
compose_send_control_enter(compose);
}
+#define EDITABLE_LENGTH(x) \
+ strlen(gtk_editable_get_chars(x,0,-1))
+
static void text_inserted(GtkWidget *widget, const gchar *text,
gint length, gint *position, Compose *compose)
{
gtk_editable_insert_text(editable, text, length, position);
if (prefs_common.autowrap)
- compose_wrap_line_all(compose);
+ compose_wrap_line_all_full(compose, TRUE);
gtk_signal_handler_unblock_by_func(GTK_OBJECT(widget),
GTK_SIGNAL_FUNC(text_inserted),
compose);
gtk_signal_emit_stop_by_name(GTK_OBJECT(editable), "insert_text");
+
+
+ if (prefs_common.autosave &&
+ EDITABLE_LENGTH(editable) % prefs_common.autosave_length == 0)
+ compose_draft_cb((gpointer)compose, 1, NULL);
}
static gboolean compose_send_control_enter(Compose *compose)
return FALSE;
}
-#if USE_PSPELL
+#if USE_ASPELL
static void compose_check_all(Compose *compose)
{
- if (compose->gtkpspell)
- gtkpspell_check_all(compose->gtkpspell);
+ if (compose->gtkaspell)
+ gtkaspell_check_all(compose->gtkaspell);
}
static void compose_highlight_all(Compose *compose)
{
- if (compose->gtkpspell)
- gtkpspell_highlight_all(compose->gtkpspell);
+ if (compose->gtkaspell)
+ gtkaspell_highlight_all(compose->gtkaspell);
}
static void compose_check_backwards(Compose *compose)
{
- if (compose->gtkpspell)
- gtkpspell_check_backwards(compose->gtkpspell);
+ if (compose->gtkaspell)
+ gtkaspell_check_backwards(compose->gtkaspell);
else {
GtkItemFactory *ifactory;
ifactory = gtk_item_factory_from_widget(compose->popupmenu);
static void compose_check_forwards_go(Compose *compose)
{
- if (compose->gtkpspell)
- gtkpspell_check_forwards_go(compose->gtkpspell);
+ if (compose->gtkaspell)
+ gtkaspell_check_forwards_go(compose->gtkaspell);
else {
GtkItemFactory *ifactory;
ifactory = gtk_item_factory_from_widget(compose->popupmenu);