From: Paul Mangan Date: Sat, 12 Apr 2003 00:28:06 +0000 (+0000) Subject: sync with 0.8.11cvs21 X-Git-Tag: rel_0_9_0~125 X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=commitdiff_plain;h=70d5f679fa0acf082fb2268f61469fb4850a7441 sync with 0.8.11cvs21 --- diff --git a/ChangeLog b/ChangeLog index 2bd1693d4..d34dc6a84 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2003-04-11 + + * src/compose.[ch]: implemented auto signature replacement on + changing accounts. + compose_insert_sig(): added a flag to replace current signature. + compose_get_signature_str(): new. It returns signature string. + compose_insert_command_output(): removed. + compose_select_account(): call compose_insert_sig() on account + change. + compose_destroy(): fixed a memory leak of UndoMain object. + Compose::sig_str: new. It stores current signature string. + * src/gtkutils.[ch]: gtkut_stext_find(): new. + Renamed gtk_stext_clear() to gtkut_stext_clear(). + * src/utils.[ch]: get_wcs_len(): returns wide-character length of + multibyte string. + normalize_newlines(): converts CR+LF and CR into LF. + get_command_output(): returns command output. + 2003-04-08 * src/procmsg.[ch]: procmsg_get_filter_keyword(): new. It returns diff --git a/ChangeLog.claws b/ChangeLog.claws index a1f70306b..eed3b2bfc 100644 --- a/ChangeLog.claws +++ b/ChangeLog.claws @@ -1,3 +1,8 @@ +2003-04-12 [paul] 0.8.11claws85 + + * sync with 0.8.11cvs21 + see ChangeLog 2003-04-11 + 2003-04-11 [paul] 0.8.11claws84 * po/es.po diff --git a/ChangeLog.jp b/ChangeLog.jp index f8b88b53a..31710acb8 100644 --- a/ChangeLog.jp +++ b/ChangeLog.jp @@ -1,3 +1,20 @@ +2003-04-11 + + * src/compose.[ch]: ¥¢¥«¥¦¥ó¥ÈÊѹ¹»þ¤Î¼«Æ°½ð̾ÀÚ¤êÂؤ¨¤ò¼ÂÁõ¡£ + compose_insert_sig(): ¸½ºß¤Î½ð̾¤òÃÖ´¹¤¹¤ë¥Õ¥é¥°¤òÄɲᣠ+ compose_get_signature_str(): ¿·µ¬¡£½ð̾¤Îʸ»úÎó¤òÊÖ¤¹¡£ + compose_insert_command_output(): ºï½ü¡£ + compose_select_account(): ¥¢¥«¥¦¥ó¥ÈÊѹ¹»þ¤Ë compose_insert_sig() + ¤ò¸Æ¤Ö¤è¤¦¤Ë¤·¤¿¡£ + compose_destroy(): UndoMain ¥ª¥Ö¥¸¥§¥¯¥È¤Î¥á¥â¥ê¥ê¡¼¥¯¤ò½¤Àµ¡£ + Compose::sig_str: ¿·µ¬¡£¸½ºß¤Î½ð̾¤Îʸ»úÎó¤òÊÝ»ý¤¹¤ë¡£ + * src/gtkutils.[ch]: gtkut_stext_find(): ¿·µ¬¡£ + gtk_stext_clear() ¤ò gtkut_stext_clear() ¤Ë²þ̾¡£ + * src/utils.[ch]: get_wcs_len(): ¥Þ¥ë¥Á¥Ð¥¤¥Èʸ»úÎó¤Î¥ï¥¤¥É¥­¥ã¥é¥¯¥¿ + ŤòÊÖ¤¹¡£ + normalize_newlines(): CR+LF ¤È CR ¤ò LF ¤ËÊÑ´¹¤¹¤ë¡£ + get_command_output(): ¥³¥Þ¥ó¥É¤Î½ÐÎϤòÊÖ¤¹¡£ + 2003-04-08 * src/procmsg.[ch]: procmsg_get_filter_keyword(): ¿·µ¬¡£¥á¥Ã¥»¡¼¥¸¤Î diff --git a/configure.ac b/configure.ac index 661f95d5b..43f017615 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ MINOR_VERSION=8 MICRO_VERSION=11 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=claws84 +EXTRA_VERSION=claws85 VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION$EXTRA_VERSION dnl set $target diff --git a/src/common/utils.c b/src/common/utils.c index c439dc28f..a919d30c6 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -469,6 +469,30 @@ wchar_t *wcscasestr(const wchar_t *haystack, const wchar_t *needle) return NULL; } +gint get_wcs_len(const gchar *s) +{ + const gchar *p = s; + gint mb_len; + gint len = 0; + + if (!p) + return -1; + + while (*p != '\0') { + mb_len = mblen(p, MB_LEN_MAX); + if (mb_len == 0) + break; + else if (mb_len < 0) + return -1; + else + len++; + + p += mb_len; + } + + return len; +} + /* Examine if next block is non-ASCII string */ gboolean is_next_nonascii(const guchar *s) { @@ -2604,6 +2628,25 @@ gint uncanonicalize_file_replace(const gchar *file) return 0; } +gchar *normalize_newlines(const gchar *str) +{ + const gchar *p = str; + gchar *out, *outp; + + out = outp = g_malloc(strlen(str) + 1); + for (p = str; *p != '\0'; ++p) { + if (*p == '\r') { + if (*(p + 1) != '\n') + *outp++ = '\n'; + } else + *outp++ = *p; + } + + *outp = '\0'; + + return out; +} + gchar *get_outgoing_rfc2822_str(FILE *fp) { gchar buf[BUFFSIZE]; @@ -2881,6 +2924,33 @@ gint execute_command_line(const gchar *cmdline, gboolean async) return ret; } +gchar *get_command_output(const gchar *cmdline) +{ + gchar buf[BUFFSIZE]; + FILE *fp; + GString *str; + gchar *ret; + + g_return_val_if_fail(cmdline != NULL, NULL); + + if ((fp = popen(cmdline, "r")) == NULL) { + FILE_OP_ERROR(cmdline, "popen"); + return NULL; + } + + str = g_string_new(""); + + while (fgets(buf, sizeof(buf), fp) != NULL) + g_string_append(str, buf); + + pclose(fp); + + ret = str->str; + g_string_free(str, FALSE); + + return ret; +} + static gint is_unchanged_uri_char(char c) { switch (c) { diff --git a/src/common/utils.h b/src/common/utils.h index e4004301e..f88a86ed7 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -212,6 +212,7 @@ gint wcsncasecmp (const wchar_t *s1, size_t n); wchar_t *wcscasestr (const wchar_t *haystack, const wchar_t *needle); +gint get_wcs_len (const gchar *s); gboolean is_next_nonascii (const guchar *s); gint get_next_word_len (const gchar *s); @@ -371,6 +372,8 @@ gint uncanonicalize_file (const gchar *src, const gchar *dest); gint uncanonicalize_file_replace(const gchar *file); +gchar *normalize_newlines (const gchar *str); + gchar *get_outgoing_rfc2822_str (FILE *fp); gint change_file_mode_rw (FILE *fp, @@ -387,6 +390,7 @@ gint execute_async (gchar *const argv[]); gint execute_sync (gchar *const argv[]); gint execute_command_line (const gchar *cmdline, gboolean async); +gchar *get_command_output (const gchar *cmdline); /* open URI with external browser */ gint open_uri(const gchar *uri, const gchar *cmdline); diff --git a/src/compose.c b/src/compose.c index 7785cfa43..2b0b66840 100644 --- a/src/compose.c +++ b/src/compose.c @@ -196,11 +196,11 @@ static void compose_reply_set_entry (Compose *compose, followup_and_reply_to); static void compose_reedit_set_entry (Compose *compose, MsgInfo *msginfo); -static void compose_insert_sig (Compose *compose); +static void compose_insert_sig (Compose *compose, + gboolean replace); +static gchar *compose_get_signature_str (Compose *compose); static void compose_insert_file (Compose *compose, const gchar *file); -static void compose_insert_command_output (Compose *compose, - const gchar *cmdline); static void compose_attach_append (Compose *compose, const gchar *file, const gchar *type, @@ -213,7 +213,8 @@ static void compose_wrap_line_all_full (Compose *compose, gboolean autowrap); static void compose_set_title (Compose *compose); static void compose_select_account (Compose *compose, - PrefsAccount *account); + PrefsAccount *account, + gboolean init); static PrefsAccount *compose_current_mail_account(void); /* static gint compose_send (Compose *compose); */ @@ -325,6 +326,9 @@ static void compose_attach_cb (gpointer data, static void compose_insert_file_cb (gpointer data, guint action, GtkWidget *widget); +static void compose_insert_sig_cb (gpointer data, + guint action, + GtkWidget *widget); static void compose_close_cb (gpointer data, guint action, @@ -491,7 +495,7 @@ static GtkItemFactoryEntry compose_entries[] = {N_("/_File"), NULL, NULL, 0, ""}, {N_("/_File/_Attach file"), "M", compose_attach_cb, 0, NULL}, {N_("/_File/_Insert file"), "I", compose_insert_file_cb, 0, NULL}, - {N_("/_File/Insert si_gnature"), "G", compose_insert_sig, 0, NULL}, + {N_("/_File/Insert si_gnature"), "G", compose_insert_sig_cb, 0, NULL}, {N_("/_File/---"), NULL, NULL, 0, ""}, {N_("/_File/_Close"), "W", compose_close_cb, 0, NULL}, @@ -701,7 +705,7 @@ Compose *compose_generic_new(PrefsAccount *account, const gchar *mailto, FolderI gtk_stext_freeze(text); if (account->auto_sig) - compose_insert_sig(compose); + compose_insert_sig(compose, FALSE); gtk_editable_set_position(GTK_EDITABLE(text), 0); gtk_stext_set_point(text, 0); @@ -964,7 +968,7 @@ static void compose_generic_reply(MsgInfo *msginfo, gboolean quote, } if (account->auto_sig) - compose_insert_sig(compose); + compose_insert_sig(compose, FALSE); if (quote && prefs_common.linewrap_quote) compose_wrap_line_all(compose); @@ -1074,7 +1078,7 @@ Compose *compose_forward(PrefsAccount *account, MsgInfo *msginfo, } if (account->auto_sig) - compose_insert_sig(compose); + compose_insert_sig(compose, FALSE); if (prefs_common.linewrap_quote) compose_wrap_line_all(compose); @@ -1153,7 +1157,7 @@ Compose *compose_forward_multiple(PrefsAccount *account, GSList *msginfo_list) } if (account->auto_sig) - compose_insert_sig(compose); + compose_insert_sig(compose, FALSE); if (prefs_common.linewrap_quote) compose_wrap_line_all(compose); @@ -1435,7 +1439,7 @@ void compose_toolbar_cb(gint action, gpointer data) compose_attach_cb(compose, 0, NULL); break; case A_SIG: - compose_insert_sig(compose); + compose_insert_sig(compose, FALSE); break; case A_EXTEDITOR: compose_ext_editor_cb(compose, 0, NULL); @@ -1884,44 +1888,100 @@ static void compose_reedit_set_entry(Compose *compose, MsgInfo *msginfo) #undef SET_ENTRY #undef SET_ADDRESS -static void compose_insert_sig(Compose *compose) +static void compose_insert_sig(Compose *compose, gboolean replace) { - static gchar *default_sigfile; - gchar *sigfile = NULL; + GtkSText *text = GTK_STEXT(compose->text); + gint cur_pos; g_return_if_fail(compose->account != NULL); + cur_pos = gtk_editable_get_position(GTK_EDITABLE(text)); + + gtk_stext_freeze(text); + + if (replace && compose->sig_str) { + gchar *tmp; + gint pos; + gint len; + + if (compose->account->sig_sep) + tmp = g_strconcat(compose->account->sig_sep, "\n", + compose->sig_str, NULL); + else + tmp = g_strdup(compose->sig_str); + + pos = gtkut_stext_find(text, 0, tmp, TRUE); + if (pos != -1) { + gtk_stext_set_point(text, pos); + len = get_wcs_len(tmp); + gtk_stext_forward_delete(text, len); + } else { + len = gtk_stext_get_length(text); + gtk_stext_set_point(text, len); + } + + g_free(tmp); + } else + gtk_stext_insert(text, NULL, NULL, NULL, "\n\n", 2); + + if (compose->account->sig_sep) { + gtk_stext_insert(text, NULL, NULL, NULL, + compose->account->sig_sep, -1); + gtk_stext_insert(text, NULL, NULL, NULL, "\n", 1); + } + + g_free(compose->sig_str); + compose->sig_str = compose_get_signature_str(compose); + + gtk_stext_insert(text, NULL, NULL, NULL, compose->sig_str, -1); + + gtk_stext_thaw(text); + + if (cur_pos > gtk_stext_get_length(text)) + cur_pos = gtk_stext_get_length(text); + + gtk_editable_set_position(GTK_EDITABLE(text), cur_pos); + gtk_stext_set_point(text, cur_pos); +} + +static gchar *compose_get_signature_str(Compose *compose) +{ + static gchar *default_sigfile; + gchar *sig_file = NULL; + gchar *sig_str = NULL; + + g_return_val_if_fail(compose->account != NULL, NULL); + if (compose->account->sig_type == SIG_FILE) { if (compose->account->sig_path) - sigfile = compose->account->sig_path; + sig_file = compose->account->sig_path; else { if (!default_sigfile) default_sigfile = g_strconcat (get_home_dir(), G_DIR_SEPARATOR_S, DEFAULT_SIGNATURE, NULL); - sigfile = default_sigfile; + sig_file = default_sigfile; } - if (!is_file_or_fifo_exist(sigfile)) { - g_warning("can't open signature file: %s\n", sigfile); - return; + if (!is_file_or_fifo_exist(sig_file)) { + g_warning("can't open signature file: %s\n", sig_file); + return NULL; } } - gtk_stext_insert(GTK_STEXT(compose->text), NULL, NULL, NULL, "\n\n", 2); - if (compose->account->sig_sep) { - gtk_stext_insert(GTK_STEXT(compose->text), NULL, NULL, NULL, - compose->account->sig_sep, -1); - gtk_stext_insert(GTK_STEXT(compose->text), NULL, NULL, NULL, - "\n", 1); - } - if (compose->account->sig_type == SIG_COMMAND) { if (compose->account->sig_path) - compose_insert_command_output - (compose, compose->account->sig_path); - } else - compose_insert_file(compose, sigfile); + sig_str = get_command_output + (compose->account->sig_path); + } else { + gchar *tmp; + + tmp = file_read_to_str(sig_file); + sig_str = normalize_newlines(tmp); + g_free(tmp); + } + + return sig_str; } static void compose_insert_file(Compose *compose, const gchar *file) @@ -1957,38 +2017,6 @@ static void compose_insert_file(Compose *compose, const gchar *file) fclose(fp); } -static void compose_insert_command_output(Compose *compose, - const gchar *cmdline) -{ - GtkSText *text = GTK_STEXT(compose->text); - gchar buf[BUFFSIZE]; - gint len; - FILE *fp; - - g_return_if_fail(cmdline != NULL); - - if ((fp = popen(cmdline, "r")) == NULL) { - FILE_OP_ERROR(cmdline, "popen"); - return; - } - - gtk_stext_freeze(text); - - while (fgets(buf, sizeof(buf), fp) != NULL) { - strcrchomp(buf); - len = strlen(buf); - if (len > 0 && buf[len - 1] != '\n') { - while (--len >= 0) - if (buf[len] == '\r') buf[len] = '\n'; - } - gtk_stext_insert(text, NULL, NULL, NULL, buf, -1); - } - - gtk_stext_thaw(text); - - pclose(fp); -} - static void compose_attach_append(Compose *compose, const gchar *file, const gchar *filename, const gchar *content_type) @@ -2767,7 +2795,8 @@ compose_current_mail_account(void) return ac; } -static void compose_select_account(Compose *compose, PrefsAccount *account) +static void compose_select_account(Compose *compose, PrefsAccount *account, + gboolean init) { GtkWidget *menuitem; GtkItemFactory *ifactory; @@ -2852,6 +2881,9 @@ static void compose_select_account(Compose *compose, PrefsAccount *account) activate_gnupg_mode(compose, account); #endif /* USE_GPGME */ + + if (!init && account->auto_sig) + compose_insert_sig(compose, TRUE); } gboolean compose_check_for_valid_recipient(Compose *compose) { @@ -5027,13 +5059,15 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode) compose->to_list = NULL; compose->newsgroup_list = NULL; + compose->undostruct = undostruct; + + compose->sig_str = NULL; + compose->exteditor_file = NULL; compose->exteditor_pid = -1; compose->exteditor_readdes = -1; compose->exteditor_tag = -1; - compose->redirect_filename = NULL; - compose->undostruct = undostruct; #if USE_ASPELL menu_set_sensitive(ifactory, "/Spelling", FALSE); if (mode != COMPOSE_REDIRECT) { @@ -5066,7 +5100,7 @@ static Compose *compose_create(PrefsAccount *account, ComposeMode mode) } #endif - compose_select_account(compose, account); + compose_select_account(compose, account, TRUE); #if USE_ASPELL compose->gtkaspell = gtkaspell; @@ -5304,7 +5338,7 @@ static void compose_template_apply(Compose *compose, Template *tmpl, compose_entry_append(compose, tmpl->bcc, COMPOSE_BCC); if (replace) - gtk_stext_clear(GTK_STEXT(compose->text)); + gtkut_stext_clear(GTK_STEXT(compose->text)); if ((compose->replyinfo == NULL) && (compose->fwdinfo == NULL)) { parsed_str = compose_quote_fmt(compose, NULL, tmpl->value, @@ -5326,7 +5360,7 @@ static void compose_template_apply(Compose *compose, Template *tmpl, } if (replace && parsed_str && compose->account->auto_sig) - compose_insert_sig(compose); + compose_insert_sig(compose, FALSE); if (replace && parsed_str) { gtk_editable_set_position(GTK_EDITABLE(compose->text), 0); @@ -5375,6 +5409,10 @@ static void compose_destroy(Compose *compose) if (compose->redirect_filename) g_free(compose->redirect_filename); + if (compose->undostruct) + undo_destroy(compose->undostruct); + + g_free(compose->sig_str); g_free(compose->exteditor_file); @@ -6075,7 +6113,7 @@ static void account_activated(GtkMenuItem *menuitem, gpointer data) g_return_if_fail(ac != NULL); if (ac != compose->account) - compose_select_account(compose, ac); + compose_select_account(compose, ac, FALSE); } static void attach_selected(GtkCList *clist, gint row, gint column, @@ -6294,6 +6332,14 @@ static void compose_insert_file_cb(gpointer data, guint action, } } +static void compose_insert_sig_cb(gpointer data, guint action, + GtkWidget *widget) +{ + Compose *compose = (Compose *)data; + + compose_insert_sig(compose, FALSE); +} + static gint compose_delete_cb(GtkWidget *widget, GdkEventAny *event, gpointer data) { diff --git a/src/compose.h b/src/compose.h index da18ab9e8..640e4be45 100644 --- a/src/compose.h +++ b/src/compose.h @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 1999-2002 Hiroyuki Yamamoto + * Copyright (C) 1999-2003 Hiroyuki Yamamoto * * 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 @@ -189,6 +189,8 @@ struct _Compose UndoMain *undostruct; + gchar *sig_str; + /* external editor */ gchar *exteditor_file; pid_t exteditor_pid; diff --git a/src/gtk/gtkstext.c b/src/gtk/gtkstext.c index 1e08a3093..6df343060 100644 --- a/src/gtk/gtkstext.c +++ b/src/gtk/gtkstext.c @@ -6231,6 +6231,34 @@ guint gtk_stext_str_compare(GtkSText *text, guint start_pos, guint text_len, return result ? len : 0; } +gint gtkut_stext_find(GtkSText *text, guint start_pos, const gchar *str, + gboolean case_sens) +{ + gint pos; + wchar_t *wcs; + gint len; + gint text_len; + gint found_pos = -1; + + wcs = strdup_mbstowcs(str); + g_return_val_if_fail(wcs != NULL, -1); + len = wcslen(wcs); + text_len = gtk_stext_get_length(text); + + for (pos = start_pos; pos < text_len; pos++) { + if (text_len - pos < len) + break; + if (gtk_stext_match_string(text, pos, wcs, len, case_sens) + == TRUE) { + found_pos = pos; + break; + } + } + + g_free(wcs); + return found_pos; +} + gboolean gtk_stext_is_uri_string(GtkSText *text, guint start_pos, guint text_len) { @@ -6243,7 +6271,7 @@ gboolean gtk_stext_is_uri_string(GtkSText *text, return FALSE; } -void gtk_stext_clear(GtkSText *text) +void gtkut_stext_clear(GtkSText *text) { gtk_stext_freeze(text); gtk_stext_set_point(text, 0); diff --git a/src/gtk/gtkstext.h b/src/gtk/gtkstext.h index 4dcdf1d6e..2089c9a44 100644 --- a/src/gtk/gtkstext.h +++ b/src/gtk/gtkstext.h @@ -289,11 +289,14 @@ guint gtk_stext_str_compare (GtkSText *text, guint start_pos, guint text_len, const gchar *str); +gint gtkut_stext_find (GtkSText *text, + guint start_pos, + const gchar *str, + gboolean case_sens); gboolean gtk_stext_is_uri_string (GtkSText *text, guint start_pos, guint text_len); -void gtk_stext_clear (GtkSText *text); - +void gtkut_stext_clear (GtkSText *text); #define GTK_STEXT_INDEX(t, index) (((t)->use_wchar) \ diff --git a/src/textview.c b/src/textview.c index 06dab5f84..58deb03db 100644 --- a/src/textview.c +++ b/src/textview.c @@ -1498,42 +1498,24 @@ gboolean textview_search_string(TextView *textview, const gchar *str, gint pos; wchar_t *wcs; gint len; - gint text_len; - gboolean found = FALSE; g_return_val_if_fail(str != NULL, FALSE); - wcs = strdup_mbstowcs(str); - g_return_val_if_fail(wcs != NULL, FALSE); - len = wcslen(wcs); + len = get_wcs_len(str); + g_return_val_if_fail(len >= 0, FALSE); + pos = textview->cur_pos; if (pos < textview->body_pos) pos = textview->body_pos; - text_len = gtk_stext_get_length(text); - if (text_len - pos < len) { - g_free(wcs); - return FALSE; - } - for (; pos < text_len; pos++) { - if (text_len - pos < len) break; - if (gtk_stext_match_string(text, pos, wcs, len, case_sens) - == TRUE) { - gtk_widget_hide(GTK_WIDGET(textview->scrolledwin)); - gtk_editable_set_position(GTK_EDITABLE(text), - pos + len); - gtk_editable_select_region(GTK_EDITABLE(text), - pos, pos + len); - gtk_widget_show(GTK_WIDGET(textview->scrolledwin)); - textview_set_position(textview, pos + len); - found = TRUE; - break; - } - if (text_len - pos == len) break; + if ((pos = gtkut_stext_find(text, pos, str, case_sens)) != -1) { + gtk_editable_set_position(GTK_EDITABLE(text), pos + len); + gtk_editable_select_region(GTK_EDITABLE(text), pos, pos + len); + textview_set_position(textview, pos + len); + return TRUE; } - g_free(wcs); - return found; + return FALSE; } gboolean textview_search_string_backward(TextView *textview, const gchar *str,