sync with sylpheed 0.6.4cvs1
[claws.git] / src / textview.c
index 276ea5c2ec6fde2344324fa9bdc2333981be2506..130e4fb5ce74e3511553458c740485e326e05144 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999,2000 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2001 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
@@ -151,6 +151,8 @@ TextView *textview_create(void)
        /* create GtkText widgets for single-byte and multi-byte character */
        text_sb = gtk_text_new(NULL, NULL);
        text_mb = gtk_text_new(NULL, NULL);
+       GTK_TEXT(text_sb)->default_tab_width = 8;
+       GTK_TEXT(text_mb)->default_tab_width = 8;
        gtk_widget_show(text_sb);
        gtk_widget_show(text_mb);
        gtk_text_set_word_wrap(GTK_TEXT(text_sb), TRUE);
@@ -181,15 +183,15 @@ TextView *textview_create(void)
        gtk_signal_connect(GTK_OBJECT(text_sb), "key_press_event",
                           GTK_SIGNAL_FUNC(textview_key_pressed),
                           textview);
-       gtk_signal_connect(GTK_OBJECT(text_sb), "button_press_event",
-                          GTK_SIGNAL_FUNC(textview_button_pressed),
-                          textview);
+       gtk_signal_connect_after(GTK_OBJECT(text_sb), "button_press_event",
+                                GTK_SIGNAL_FUNC(textview_button_pressed),
+                                textview);
        gtk_signal_connect(GTK_OBJECT(text_mb), "key_press_event",
                           GTK_SIGNAL_FUNC(textview_key_pressed),
                           textview);
-       gtk_signal_connect(GTK_OBJECT(text_mb), "button_press_event",
-                          GTK_SIGNAL_FUNC(textview_button_pressed),
-                          textview);
+       gtk_signal_connect_after(GTK_OBJECT(text_mb), "button_press_event",
+                                GTK_SIGNAL_FUNC(textview_button_pressed),
+                                textview);
 
        gtk_widget_show(scrolledwin_sb);
        gtk_widget_show(scrolledwin_mb);
@@ -206,6 +208,8 @@ TextView *textview_create(void)
        textview->text_mb        = text_mb;
        textview->text_is_mb     = FALSE;
        textview->uri_list       = NULL;
+       textview->body_pos       = 0;
+       textview->cur_pos        = 0;
 
        return textview;
 }
@@ -313,7 +317,7 @@ void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
                mimeinfo = mimeinfo->sub;
        } else if (!mimeinfo->parent &&
                   mimeinfo->mime_type == MIME_MESSAGE_RFC822) {
-               if (headers) procheader_header_array_destroy(headers);   
+               if (headers) procheader_header_array_destroy(headers);
                if (!mimeinfo->sub) return;
                headers = textview_scan_header(textview, fp);
                mimeinfo = mimeinfo->sub;
@@ -331,6 +335,9 @@ void textview_show_part(TextView *textview, MimeInfo *mimeinfo, FILE *fp)
        text = GTK_TEXT(textview->text);
        gtk_text_freeze(text);
 
+       textview->body_pos = 0;
+       textview->cur_pos  = 0;
+
        if (headers) {
                textview_show_header(textview, headers);
                procheader_header_array_destroy(headers);
@@ -789,8 +796,8 @@ static void textview_write_line(TextView *textview, const gchar *str,
                textview_make_clickable_parts(textview, textview->msgfont,
                                              fg_color, &uri_color, buf);
        else
-               gtk_text_insert(text, textview->msgfont, fg_color, NULL,
-                               buf, -1);
+               textview_make_clickable_parts(textview, textview->msgfont,
+                                             fg_color, NULL, buf);
 }
 
 void textview_clear(TextView *textview)
@@ -798,7 +805,8 @@ void textview_clear(TextView *textview)
        GtkText *text = GTK_TEXT(textview->text);
 
        gtk_text_freeze(text);
-       gtk_text_backward_delete(text, gtk_text_get_length(text));
+       gtk_text_set_point(text, 0);
+       gtk_text_forward_delete(text, gtk_text_get_length(text));
        gtk_text_thaw(text);
 
        textview_uri_list_remove_all(textview->uri_list);
@@ -835,11 +843,13 @@ void textview_set_font(TextView *textview, const gchar *codeset)
        if (MB_CUR_MAX > 1) {
                if (codeset) {
                        if (!g_strncasecmp(codeset, "ISO-8859-", 9) ||
-                           !g_strncasecmp(codeset, "KOI8-", 5)     ||
-                           !g_strncasecmp(codeset, "CP", 2)        ||
-                           !g_strncasecmp(codeset, "WINDOWS-", 8)  ||
                            !g_strcasecmp(codeset, "BALTIC"))
                                use_fontset = FALSE;
+                       else if (conv_get_current_charset() != C_EUC_JP &&
+                                (!g_strncasecmp(codeset, "KOI8-", 5) ||
+                                 !g_strncasecmp(codeset, "CP", 2)    ||
+                                 !g_strncasecmp(codeset, "WINDOWS-", 8)))
+                               use_fontset = FALSE;
                }
        } else
                use_fontset = FALSE;
@@ -926,15 +936,23 @@ enum
        H_ORGANIZATION  = 11,
 };
 
+void textview_set_position(TextView *textview, gint pos)
+{
+       if (pos < 0) {
+               textview->cur_pos =
+                       gtk_text_get_length(GTK_TEXT(textview->text));
+       } else {
+               textview->cur_pos = pos;
+       }
+}
+
 static GPtrArray *textview_scan_header(TextView *textview, FILE *fp)
 {
        gchar buf[BUFFSIZE];
        GPtrArray *headers, *sorted_headers;
        GSList *disphdr_list;
        Header *header;
-       guint i;
-
-       textview = textview;
+       gint i;
 
        g_return_val_if_fail(fp != NULL, NULL);
 
@@ -985,7 +1003,7 @@ static void textview_show_header(TextView *textview, GPtrArray *headers)
 {
        GtkText *text = GTK_TEXT(textview->text);
        Header *header;
-       guint i;
+       gint i;
 
        g_return_if_fail(headers != NULL);
 
@@ -1019,14 +1037,100 @@ static void textview_show_header(TextView *textview, GPtrArray *headers)
                                                      NULL, NULL, &uri_color,
                                                      header->body);
                } else {
-                       gtk_text_insert(text, NULL, NULL, NULL,
-                                       header->body, -1);
+                       textview_make_clickable_parts(textview,
+                                                     NULL, NULL, NULL,
+                                                     header->body);
                }
                gtk_text_insert(text, textview->msgfont, NULL, NULL, "\n", 1);
        }
 
        gtk_text_insert(text, textview->msgfont, NULL, NULL, "\n", 1);
        gtk_text_thaw(text);
+       textview->body_pos = gtk_text_get_length(text);
+}
+
+gboolean textview_search_string(TextView *textview, const gchar *str,
+                               gboolean case_sens)
+{
+       GtkText *text = GTK_TEXT(textview->text);
+       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);
+       pos = textview->cur_pos;
+       if (pos < textview->body_pos)
+               pos = textview->body_pos;
+       text_len = gtk_text_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 (gtkut_text_match_string(text, pos, wcs, len, case_sens)
+                   == TRUE) {
+                       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);
+                       found = TRUE;
+                       break;
+               }
+               if (text_len - pos == len) break;
+       }
+
+       g_free(wcs);
+       return found;
+}
+
+gboolean textview_search_string_backward(TextView *textview, const gchar *str,
+                                        gboolean case_sens)
+{
+       GtkText *text = GTK_TEXT(textview->text);
+       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);
+       pos = textview->cur_pos;
+       text_len = gtk_text_get_length(text);
+       if (text_len - textview->body_pos < len) {
+               g_free(wcs);
+               return FALSE;
+       }
+       if (pos <= textview->body_pos || text_len - pos < len)
+               pos = text_len - len;
+
+       for (; pos >= textview->body_pos; pos--) {
+               if (gtkut_text_match_string(text, pos, wcs, len, case_sens)
+                   == TRUE) {
+                       gtk_editable_set_position(GTK_EDITABLE(text), pos);
+                       gtk_editable_select_region(GTK_EDITABLE(text),
+                                                  pos, pos + len);
+                       textview_set_position(textview, pos - 1);
+                       found = TRUE;
+                       break;
+               }
+               if (pos == textview->body_pos) break;
+       }
+
+       g_free(wcs);
+       return found;
 }
 
 void textview_scroll_one_line(TextView *textview, gboolean up)
@@ -1248,19 +1352,19 @@ static void textview_key_pressed(GtkWidget *widget, GdkEventKey *event,
 static void textview_button_pressed(GtkWidget *widget, GdkEventButton *event,
                                    TextView *textview)
 {
+       textview->cur_pos = 
+               gtk_editable_get_position(GTK_EDITABLE(textview->text));
+
        if (event &&
            ((event->button == 1 && event->type == GDK_2BUTTON_PRESS)
             || event->button == 2 || event->button == 3)) {
                GSList *cur;
-               guint current_pos;
-
-               current_pos = GTK_EDITABLE(textview->text)->current_pos;
 
                for (cur = textview->uri_list; cur != NULL; cur = cur->next) {
                        RemoteURI *uri = (RemoteURI *)cur->data;
 
-                       if (current_pos >= uri->start &&
-                           current_pos <  uri->end) {
+                       if (textview->cur_pos >= uri->start &&
+                           textview->cur_pos <  uri->end) {
                                if (!g_strncasecmp(uri->uri, "mailto:", 7)) {
                                        if (event->button == 3) {
                                                gchar *fromname, *fromaddress;
@@ -1270,7 +1374,8 @@ static void textview_button_pressed(GtkWidget *widget, GdkEventButton *event,
                                                fromname = procheader_get_fromname(fromaddress);
                                                extract_address(fromaddress);
                                                g_message("adding from textview %s <%s>", fromname, fromaddress);
-                                               addressbook_add_contact_by_menu(NULL, fromname, fromaddress, NULL);
+                                               // Add to address book - Match
+                                               addressbook_add_contact( fromname, fromaddress, NULL );
                                                g_free(fromaddress);
                                                g_free(fromname);
                                        } else {