sync with 0.8.11cvs21
authorPaul Mangan <paul@claws-mail.org>
Sat, 12 Apr 2003 00:28:06 +0000 (00:28 +0000)
committerPaul Mangan <paul@claws-mail.org>
Sat, 12 Apr 2003 00:28:06 +0000 (00:28 +0000)
ChangeLog
ChangeLog.claws
ChangeLog.jp
configure.ac
src/common/utils.c
src/common/utils.h
src/compose.c
src/compose.h
src/gtk/gtkstext.c
src/gtk/gtkstext.h
src/textview.c

index 2bd1693..d34dc6a 100644 (file)
--- 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
index a1f7030..eed3b2b 100644 (file)
@@ -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
index f8b88b5..31710ac 100644 (file)
@@ -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(): ¿·µ¬¡£¥á¥Ã¥»¡¼¥¸¤Î
index 661f95d..43f0176 100644 (file)
@@ -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
index c439dc2..a919d30 100644 (file)
@@ -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) {
index e400430..f88a86e 100644 (file)
@@ -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);
index 7785cfa..2b0b668 100644 (file)
@@ -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, "<Branch>"},
        {N_("/_File/_Attach file"),             "<control>M", compose_attach_cb,      0, NULL},
        {N_("/_File/_Insert file"),             "<control>I", compose_insert_file_cb, 0, NULL},
-       {N_("/_File/Insert si_gnature"),        "<control>G", compose_insert_sig,     0, NULL},
+       {N_("/_File/Insert si_gnature"),        "<control>G", compose_insert_sig_cb,  0, NULL},
        {N_("/_File/---"),                      NULL, NULL, 0, "<Separator>"},
        {N_("/_File/_Close"),                   "<control>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)
 {
index da18ab9..640e4be 100644 (file)
@@ -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;
index 1e08a30..6df3430 100644 (file)
@@ -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);
index 4dcdf1d..2089c9a 100644 (file)
@@ -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) \
index 06dab5f..58deb03 100644 (file)
@@ -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,