From: Paul Mangan Date: Fri, 27 May 2005 07:24:34 +0000 (+0000) Subject: 2005-05-27 [paul] 1.9.11cvs16 X-Git-Tag: rel_1_9_12~93 X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=commitdiff_plain;h=6984c4f189c42d9a677e5d364063010a87efce8f 2005-05-27 [paul] 1.9.11cvs16 sync with main: * src/main.c app_will_exit(): cleanup tmp directory when exit * src/message_search.c improved the interface and made code cleanup. removed Clear button * src/send_message.c send_message_local(): use GSpawn, and detect errors * src/summary_search.c improved the interface and made code cleanup * src/textview.c textview_write_link(): also skip non-ascii space at the head of link strings (phishing check didn't work at the case) * src/common/utils.c get_command_output(): use g_spawn_command_line_sync() instead of popen() --- diff --git a/ChangeLog-gtk2.claws b/ChangeLog-gtk2.claws index c72b1aaeb..9edc87846 100644 --- a/ChangeLog-gtk2.claws +++ b/ChangeLog-gtk2.claws @@ -1,3 +1,24 @@ +2005-05-27 [paul] 1.9.11cvs16 + + sync with main: + + * src/main.c + app_will_exit(): cleanup tmp directory when exit + * src/message_search.c + improved the interface and made code cleanup. + removed Clear button + * src/send_message.c + send_message_local(): use GSpawn, and detect errors + * src/summary_search.c + improved the interface and made code cleanup + * src/textview.c + textview_write_link(): also skip non-ascii space + at the head of link strings (phishing check + didn't work at the case) + * src/common/utils.c + get_command_output(): use g_spawn_command_line_sync() + instead of popen() + 2005-05-26 [colin] 1.9.11cvs15 * src/folder.c diff --git a/PATCHSETS b/PATCHSETS index 585e190d1..a3c57025b 100644 --- a/PATCHSETS +++ b/PATCHSETS @@ -504,3 +504,4 @@ ( cvs diff -u -r 1.1.2.6 -r 1.1.2.7 src/plugins/pgpmime/passphrase.c; ) > 1.9.11cvs13.patchset ( cvs diff -u -r 1.6.2.5 -r 1.6.2.6 src/common/nntp.c; ) > 1.9.11cvs14.patchset ( cvs diff -u -r 1.213.2.27 -r 1.213.2.28 src/folder.c; ) > 1.9.11cvs15.patchset +( cvs diff -u -r 1.115.2.33 -r 1.115.2.34 src/main.c; cvs diff -u -r 1.3.12.8 -r 1.3.12.9 src/message_search.c; cvs diff -u -r 1.17.2.10 -r 1.17.2.11 src/send_message.c; cvs diff -u -r 1.15.2.14 -r 1.15.2.15 src/summary_search.c; cvs diff -u -r 1.96.2.54 -r 1.96.2.55 src/textview.c; cvs diff -u -r 1.36.2.29 -r 1.36.2.30 src/common/utils.c; ) > 1.9.11cvs16.patchset diff --git a/configure.ac b/configure.ac index 3a61453e8..d23d174ac 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ MINOR_VERSION=9 MICRO_VERSION=11 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=15 +EXTRA_VERSION=16 EXTRA_RELEASE= EXTRA_GTK2_VERSION= diff --git a/src/common/utils.c b/src/common/utils.c index 30f0fd52a..369fe169c 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -3190,39 +3190,18 @@ gint execute_command_line(const gchar *cmdline, gboolean async) gchar *get_command_output(const gchar *cmdline) { - gchar buf[BUFFSIZE]; - FILE *fp; - GString *str; - gchar *ret; + gchar *child_stdout; + gint status; g_return_val_if_fail(cmdline != NULL, NULL); - if ((fp = popen(cmdline, "r")) == NULL) { - FILE_OP_ERROR(cmdline, "popen"); + if (g_spawn_command_line_sync(cmdline, &child_stdout, NULL, &status, + NULL) == FALSE) { + g_warning("Can't execute command: %s\n", cmdline); 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); - - if (!g_utf8_validate(ret, -1, NULL)) { - const gchar *src_codeset, *dest_codeset; - gchar *tmp = NULL; - src_codeset = conv_get_locale_charset_str(); - dest_codeset = CS_UTF_8; - tmp = conv_codeset_strdup(ret, src_codeset, dest_codeset); - g_free(ret); - ret = tmp; - } - - return ret; + return child_stdout; } static gint is_unchanged_uri_char(char c) diff --git a/src/main.c b/src/main.c index 743f980c9..7c6378e47 100644 --- a/src/main.c +++ b/src/main.c @@ -484,6 +484,7 @@ static void exit_sylpheed(MainWindow *mainwin) g_free(filename); /* delete temporary files */ + remove_all_files(get_tmp_dir()); remove_all_files(get_mime_tmp_dir()); close_log_file(); diff --git a/src/message_search.c b/src/message_search.c index bfe370c8e..70776d5f5 100644 --- a/src/message_search.c +++ b/src/message_search.c @@ -49,39 +49,59 @@ #include "manage_window.h" #include "alertpanel.h" -static GtkWidget *window; -static GtkWidget *body_entry; -static GtkWidget *case_checkbtn; -static GtkWidget *backward_checkbtn; -static GtkWidget *search_btn; -static GtkWidget *clear_btn; -static GtkWidget *close_btn; - -static void message_search_create(MessageView *summaryview); -static void message_search_execute(GtkButton *button, gpointer data); -static void message_search_clear(GtkButton *button, gpointer data); -static void body_activated(void); -static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data); +static struct MessageSearchWindow { + GtkWidget *window; + GtkWidget *body_entry; + GtkWidget *case_checkbtn; + GtkWidget *prev_btn; + GtkWidget *next_btn; + GtkWidget *close_btn; + + MessageView *messageview; +} search_window; + +static void message_search_create (void); +static void message_search_execute (gboolean backward); + +static void message_search_prev_clicked (GtkButton *button, + gpointer data); +static void message_search_next_clicked (GtkButton *button, + gpointer data); +static void body_activated (void); +static gboolean key_pressed (GtkWidget *widget, + GdkEventKey *event, + gpointer data); void message_search(MessageView *messageview) { - if (!window) - message_search_create(messageview); + if (!search_window.window) + message_search_create(); else - gtk_widget_hide(window); + gtk_widget_hide(search_window.window); - gtk_widget_grab_focus(search_btn); - gtk_widget_grab_focus(body_entry); - gtk_widget_show(window); + search_window.messageview = messageview; + + gtk_widget_grab_focus(search_window.next_btn); + gtk_widget_grab_focus(search_window.body_entry); + gtk_widget_show(search_window.window); } -static void message_search_create(MessageView *messageview) +static void message_search_create(void) { + GtkWidget *window; + GtkWidget *vbox1; GtkWidget *hbox1; GtkWidget *body_label; + GtkWidget *body_entry; + GtkWidget *checkbtn_hbox; + GtkWidget *case_checkbtn; + GtkWidget *confirm_area; + GtkWidget *prev_btn; + GtkWidget *next_btn; + GtkWidget *close_btn; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_title (GTK_WINDOW (window), @@ -111,7 +131,7 @@ static void message_search_create(MessageView *messageview) gtk_widget_show (body_entry); gtk_box_pack_start (GTK_BOX (hbox1), body_entry, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(body_entry), "activate", - G_CALLBACK(body_activated), messageview); + G_CALLBACK(body_activated), NULL); checkbtn_hbox = gtk_hbox_new (FALSE, 8); gtk_widget_show (checkbtn_hbox); @@ -122,50 +142,45 @@ static void message_search_create(MessageView *messageview) gtk_widget_show (case_checkbtn); gtk_box_pack_start (GTK_BOX (checkbtn_hbox), case_checkbtn, FALSE, FALSE, 0); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(case_checkbtn), FALSE); - - backward_checkbtn = - gtk_check_button_new_with_label (_("Backward search")); - gtk_widget_show (backward_checkbtn); - gtk_box_pack_start (GTK_BOX (checkbtn_hbox), backward_checkbtn, - FALSE, FALSE, 0); gtkut_stock_button_set_create(&confirm_area, - &search_btn, GTK_STOCK_FIND, - &clear_btn, GTK_STOCK_CLEAR, + &prev_btn, GTK_STOCK_GO_BACK, + &next_btn, GTK_STOCK_GO_FORWARD, &close_btn, GTK_STOCK_CLOSE); gtk_widget_show (confirm_area); gtk_box_pack_start (GTK_BOX (vbox1), confirm_area, FALSE, FALSE, 0); - gtk_widget_grab_default(search_btn); - - g_signal_connect(G_OBJECT(search_btn), "clicked", - G_CALLBACK(message_search_execute), - messageview); - g_signal_connect(G_OBJECT(clear_btn), "clicked", - G_CALLBACK(message_search_clear), - messageview); + gtk_widget_grab_default(next_btn); + + g_signal_connect(G_OBJECT(prev_btn), "clicked", + G_CALLBACK(message_search_prev_clicked), NULL); + g_signal_connect(G_OBJECT(next_btn), "clicked", + G_CALLBACK(message_search_next_clicked), NULL); g_signal_connect_closure (G_OBJECT(close_btn), "clicked", g_cclosure_new_swap(G_CALLBACK(gtk_widget_hide), window, NULL), FALSE); + + search_window.window = window; + search_window.body_entry = body_entry; + search_window.case_checkbtn = case_checkbtn; + search_window.prev_btn = prev_btn; + search_window.next_btn = next_btn; + search_window.close_btn = close_btn; } -static void message_search_execute(GtkButton *button, gpointer data) +static void message_search_execute(gboolean backward) { - MessageView *messageview = data; + MessageView *messageview = search_window.messageview; gboolean case_sens; - gboolean backward; gboolean all_searched = FALSE; const gchar *body_str; - body_str = gtk_entry_get_text(GTK_ENTRY(body_entry)); + body_str = gtk_entry_get_text(GTK_ENTRY(search_window.body_entry)); if (*body_str == '\0') return; case_sens = gtk_toggle_button_get_active - (GTK_TOGGLE_BUTTON(case_checkbtn)); - backward = gtk_toggle_button_get_active - (GTK_TOGGLE_BUTTON(backward_checkbtn)); + (GTK_TOGGLE_BUTTON(search_window.case_checkbtn)); for (;;) { gchar *str; @@ -182,8 +197,11 @@ static void message_search_execute(GtkButton *button, gpointer data) } if (all_searched) { - alertpanel_notice - (_("Search string not found.")); + alertpanel_with_type + (_("Search failed"), + _("Search string not found."), + NULL, NULL, NULL, NULL, + ALERT_WARNING); break; } @@ -199,7 +217,8 @@ static void message_search_execute(GtkButton *button, gpointer data) val = alertpanel(_("Search finished"), str, GTK_STOCK_YES, GTK_STOCK_NO, NULL); if (G_ALERTDEFAULT == val) { - manage_window_focus_in(window, NULL, NULL); + manage_window_focus_in(search_window.window, + NULL, NULL); messageview_set_position(messageview, backward ? -1 : 0); } else @@ -207,19 +226,25 @@ static void message_search_execute(GtkButton *button, gpointer data) } } -static void message_search_clear(GtkButton *button, gpointer data) +static void message_search_prev_clicked(GtkButton *button, gpointer data) +{ + message_search_execute(TRUE); +} + +static void message_search_next_clicked(GtkButton *button, gpointer data) { - gtk_editable_delete_text(GTK_EDITABLE(body_entry), 0, -1); + message_search_execute(FALSE); } static void body_activated(void) { - gtk_button_clicked(GTK_BUTTON(search_btn)); + gtk_button_clicked(GTK_BUTTON(search_window.next_btn)); } -static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data) +static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, + gpointer data) { if (event && event->keyval == GDK_Escape) - gtk_widget_hide(window); + gtk_widget_hide(search_window.window); return FALSE; } diff --git a/src/send_message.c b/src/send_message.c index 353ab7044..512d02423 100644 --- a/src/send_message.c +++ b/src/send_message.c @@ -46,6 +46,7 @@ #include "inputdialog.h" #include "alertpanel.h" #include "manage_window.h" +#include "socket.h" #include "utils.h" #include "gtkutils.h" #include "inc.h" @@ -117,39 +118,54 @@ enum gint send_message_local(const gchar *command, FILE *fp) { - FILE *pipefp; + gchar **argv; + GPid pid; + gint child_stdin; gchar buf[BUFFSIZE]; - int r; - sigset_t osig, mask; + gboolean err = FALSE; g_return_val_if_fail(command != NULL, -1); g_return_val_if_fail(fp != NULL, -1); - pipefp = popen(command, "w"); - if (!pipefp) { - g_warning("Can't execute external command: %s\n", command); + log_message(_("Sending message using command: %s\n"), command); + + argv = strsplit_with_quote(command, " ", 0); + + if (g_spawn_async_with_pipes(NULL, argv, NULL, 0, NULL, NULL, &pid, + &child_stdin, NULL, NULL, NULL) == FALSE) { + g_snprintf(buf, sizeof(buf), + _("Can't execute command: %s"), command); + log_warning("%s\n", buf); + alertpanel_error("%s", buf); + g_strfreev(argv); return -1; } + g_strfreev(argv); while (fgets(buf, sizeof(buf), fp) != NULL) { strretchomp(buf); - fputs(buf, pipefp); - fputc('\n', pipefp); + if (buf[0] == '.' && buf[1] == '\0') { + if (fd_write_all(child_stdin, ".", 1) < 0) { + err = TRUE; + break; + } + } + if (fd_write_all(child_stdin, buf, strlen(buf)) < 0 || + fd_write_all(child_stdin, "\n", 1) < 0) { + err = TRUE; + break; + } } - /* we need to block SIGCHLD, otherwise pspell's handler will wait() - * the pipecommand away and pclose will return -1 because of its - * failed wait4(). - */ - sigemptyset(&mask); - sigaddset(&mask, SIGCHLD); - sigprocmask(SIG_BLOCK, &mask, &osig); - - r = pclose(pipefp); + fd_close(child_stdin); + g_spawn_close_pid(pid); - sigprocmask(SIG_SETMASK, &osig, NULL); - if (r != 0) { - g_warning("external command `%s' failed with code `%i'\n", command, r); + if (err) { + g_snprintf(buf, sizeof(buf), + _("Error occurred while executing command: %s"), + command); + log_warning("%s\n", buf); + alertpanel_error("%s", buf); return -1; } diff --git a/src/summary_search.c b/src/summary_search.c index 31573b089..eacead625 100644 --- a/src/summary_search.c +++ b/src/summary_search.c @@ -53,61 +53,99 @@ #include "manage_window.h" #include "alertpanel.h" -static GtkWidget *window; -static GtkWidget *bool_optmenu; -static GtkWidget *from_entry; -static GtkWidget *to_entry; -static GtkWidget *subject_entry; -static GtkWidget *body_entry; -static GtkWidget *case_checkbtn; -static GtkWidget *backward_checkbtn; -static GtkWidget *all_checkbtn; -static GtkWidget *and_checkbtn; -static GtkWidget *search_btn; -static GtkWidget *clear_btn; -static GtkWidget *close_btn; - -static void summary_search_create(SummaryView *summaryview); -static void summary_search_execute(GtkButton *button, gpointer data); -static void summary_search_clear(GtkButton *button, gpointer data); -static void from_activated(void); -static void to_activated(void); -static void subject_activated(void); -static void body_activated(void); -static gboolean all_clicked(GtkButton *button); -static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data); +static struct SummarySearchWindow { + GtkWidget *window; + + GtkWidget *bool_optmenu; + + GtkWidget *from_entry; + GtkWidget *to_entry; + GtkWidget *subject_entry; + GtkWidget *body_entry; + + GtkWidget *case_checkbtn; + + GtkWidget *clear_btn; + GtkWidget *all_btn; + GtkWidget *prev_btn; + GtkWidget *next_btn; + GtkWidget *close_btn; + + SummaryView *summaryview; +} search_window; + +static void summary_search_create (void); + +static void summary_search_execute (gboolean backward, + gboolean search_all); + +static void summary_search_clear (GtkButton *button, + gpointer data); +static void summary_search_prev_clicked (GtkButton *button, + gpointer data); +static void summary_search_next_clicked (GtkButton *button, + gpointer data); +static void summary_search_all_clicked (GtkButton *button, + gpointer data); + +static void from_activated (void); +static void to_activated (void); +static void subject_activated (void); +static void body_activated (void); + +static gboolean key_pressed (GtkWidget *widget, + GdkEventKey *event, + gpointer data); + void summary_search(SummaryView *summaryview) { - if (!window) - summary_search_create(summaryview); + if (!search_window.window) + summary_search_create(); else - gtk_widget_hide(window); + gtk_widget_hide(search_window.window); + + search_window.summaryview = summaryview; - gtk_widget_grab_focus(search_btn); - gtk_widget_grab_focus(subject_entry); - gtk_widget_show(window); + gtk_widget_grab_focus(search_window.next_btn); + gtk_widget_grab_focus(search_window.subject_entry); + gtk_widget_show(search_window.window); } -static void summary_search_create(SummaryView *summaryview) +static void summary_search_create(void) { + GtkWidget *window; GtkWidget *vbox1; GtkWidget *bool_hbox; + GtkWidget *bool_optmenu; GtkWidget *bool_menu; GtkWidget *menuitem; + GtkWidget *clear_btn; + GtkWidget *table1; GtkWidget *from_label; + GtkWidget *from_entry; GtkWidget *to_label; + GtkWidget *to_entry; GtkWidget *subject_label; + GtkWidget *subject_entry; GtkWidget *body_label; + GtkWidget *body_entry; + GtkWidget *checkbtn_hbox; - GtkWidget *confirm_area; + GtkWidget *case_checkbtn; - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (window), _("Search messages")); - gtk_widget_set_size_request (window, 450, -1); - gtk_window_set_resizable(GTK_WINDOW(window), TRUE); - gtk_container_set_border_width (GTK_CONTAINER (window), 8); + GtkWidget *confirm_area; + GtkWidget *all_btn; + GtkWidget *prev_btn; + GtkWidget *next_btn; + GtkWidget *close_btn; + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(GTK_WINDOW (window), _("Search messages")); + gtk_widget_set_size_request(window, 450, -1); + gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, TRUE); + gtk_container_set_border_width(GTK_CONTAINER (window), 8); g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(gtk_widget_hide_on_delete), NULL); g_signal_connect(G_OBJECT(window), "key_press_event", @@ -131,6 +169,10 @@ static void summary_search_create(SummaryView *summaryview) MENUITEM_ADD(bool_menu, menuitem, _("Match all of the following"), 1); gtk_option_menu_set_menu(GTK_OPTION_MENU(bool_optmenu), bool_menu); + clear_btn = gtk_button_new_from_stock(GTK_STOCK_CLEAR); + gtk_widget_show(clear_btn); + gtk_box_pack_end(GTK_BOX(bool_hbox), clear_btn, FALSE, FALSE, 0); + table1 = gtk_table_new (4, 3, FALSE); gtk_widget_show (table1); gtk_box_pack_start (GTK_BOX (vbox1), table1, TRUE, TRUE, 0); @@ -143,28 +185,28 @@ static void summary_search_create(SummaryView *summaryview) gtk_table_attach (GTK_TABLE (table1), from_entry, 1, 3, 0, 1, GTK_EXPAND|GTK_FILL, 0, 0, 0); g_signal_connect(G_OBJECT(from_entry), "activate", - G_CALLBACK(from_activated), summaryview); + G_CALLBACK(from_activated), NULL); to_entry = gtk_entry_new (); gtk_widget_show (to_entry); gtk_table_attach (GTK_TABLE (table1), to_entry, 1, 3, 1, 2, GTK_EXPAND|GTK_FILL, 0, 0, 0); g_signal_connect(G_OBJECT(to_entry), "activate", - G_CALLBACK(to_activated), summaryview); + G_CALLBACK(to_activated), NULL); subject_entry = gtk_entry_new (); gtk_widget_show (subject_entry); gtk_table_attach (GTK_TABLE (table1), subject_entry, 1, 3, 2, 3, GTK_EXPAND|GTK_FILL, 0, 0, 0); g_signal_connect(G_OBJECT(subject_entry), "activate", - G_CALLBACK(subject_activated), summaryview); + G_CALLBACK(subject_activated), NULL); body_entry = gtk_entry_new (); gtk_widget_show (body_entry); gtk_table_attach (GTK_TABLE (table1), body_entry, 1, 3, 3, 4, GTK_EXPAND|GTK_FILL, 0, 0, 0); g_signal_connect(G_OBJECT(body_entry), "activate", - G_CALLBACK(body_activated), summaryview); + G_CALLBACK(body_activated), NULL); from_label = gtk_label_new (_("From:")); gtk_widget_show (from_label); @@ -200,84 +242,100 @@ static void summary_search_create(SummaryView *summaryview) gtk_container_set_border_width (GTK_CONTAINER (checkbtn_hbox), 8); case_checkbtn = gtk_check_button_new_with_label (_("Case sensitive")); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(case_checkbtn), FALSE); gtk_widget_show (case_checkbtn); gtk_box_pack_start (GTK_BOX (checkbtn_hbox), case_checkbtn, FALSE, FALSE, 0); - backward_checkbtn = - gtk_check_button_new_with_label (_("Backward search")); - gtk_widget_show (backward_checkbtn); - gtk_box_pack_start (GTK_BOX (checkbtn_hbox), backward_checkbtn, - FALSE, FALSE, 0); - - all_checkbtn = - gtk_check_button_new_with_label (_("Select all matched")); - gtk_widget_show (all_checkbtn); - gtk_box_pack_start (GTK_BOX (checkbtn_hbox), all_checkbtn, - FALSE, FALSE, 0); - g_signal_connect(G_OBJECT(all_checkbtn), "clicked", - G_CALLBACK(all_clicked), summaryview); - - gtkut_stock_button_set_create(&confirm_area, - &search_btn, GTK_STOCK_FIND, - &clear_btn, GTK_STOCK_CLEAR, - &close_btn, GTK_STOCK_CLOSE); + confirm_area = gtk_hbutton_box_new(); gtk_widget_show (confirm_area); + gtk_button_box_set_layout(GTK_BUTTON_BOX(confirm_area), + GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(confirm_area), 5); + + all_btn = gtk_button_new_from_stock(_("Find all")); + GTK_WIDGET_SET_FLAGS(all_btn, GTK_CAN_DEFAULT); + gtk_box_pack_start(GTK_BOX(confirm_area), all_btn, TRUE, TRUE, 0); + gtk_widget_show(all_btn); + + prev_btn = gtk_button_new_from_stock(GTK_STOCK_GO_BACK); + GTK_WIDGET_SET_FLAGS(prev_btn, GTK_CAN_DEFAULT); + gtk_box_pack_start(GTK_BOX(confirm_area), prev_btn, TRUE, TRUE, 0); + gtk_widget_show(prev_btn); + + next_btn = gtk_button_new_from_stock(GTK_STOCK_GO_FORWARD); + GTK_WIDGET_SET_FLAGS(next_btn, GTK_CAN_DEFAULT); + gtk_box_pack_start(GTK_BOX(confirm_area), next_btn, TRUE, TRUE, 0); + gtk_widget_show(next_btn); + + close_btn = gtk_button_new_from_stock(GTK_STOCK_CLOSE); + GTK_WIDGET_SET_FLAGS(close_btn, GTK_CAN_DEFAULT); + gtk_box_pack_start(GTK_BOX(confirm_area), close_btn, TRUE, TRUE, 0); + gtk_widget_show(close_btn); + gtk_box_pack_start (GTK_BOX (vbox1), confirm_area, FALSE, FALSE, 0); - gtk_widget_grab_default(search_btn); + gtk_widget_grab_default(next_btn); - g_signal_connect(G_OBJECT(search_btn), "clicked", - G_CALLBACK(summary_search_execute), - summaryview); g_signal_connect(G_OBJECT(clear_btn), "clicked", - G_CALLBACK(summary_search_clear), - summaryview); + G_CALLBACK(summary_search_clear), NULL); + g_signal_connect(G_OBJECT(all_btn), "clicked", + G_CALLBACK(summary_search_all_clicked), NULL); + g_signal_connect(G_OBJECT(prev_btn), "clicked", + G_CALLBACK(summary_search_prev_clicked), NULL); + g_signal_connect(G_OBJECT(next_btn), "clicked", + G_CALLBACK(summary_search_next_clicked), NULL); g_signal_connect_closure (G_OBJECT(close_btn), "clicked", g_cclosure_new_swap(G_CALLBACK(gtk_widget_hide), window, NULL), FALSE); + + search_window.window = window; + search_window.bool_optmenu = bool_optmenu; + search_window.from_entry = from_entry; + search_window.to_entry = to_entry; + search_window.subject_entry = subject_entry; + search_window.body_entry = body_entry; + search_window.case_checkbtn = case_checkbtn; + search_window.clear_btn = clear_btn; + search_window.all_btn = all_btn; + search_window.prev_btn = prev_btn; + search_window.next_btn = next_btn; + search_window.close_btn = close_btn; } -static void summary_search_execute(GtkButton *button, gpointer data) +static void summary_search_execute(gboolean backward, gboolean search_all) { - SummaryView *summaryview = data; + SummaryView *summaryview = search_window.summaryview; GtkCTree *ctree = GTK_CTREE(summaryview->ctree); GtkCTreeNode *node; MsgInfo *msginfo; gboolean bool_and; gboolean case_sens; - gboolean backward; - gboolean search_all; gboolean all_searched = FALSE; gboolean matched; gboolean body_matched; const gchar *from_str, *to_str, *subject_str, *body_str; StrFindFunc str_find_func; + gboolean valid; if (summary_is_locked(summaryview)) return; summary_lock(summaryview); bool_and = GPOINTER_TO_INT (menu_get_option_menu_active_user_data - (GTK_OPTION_MENU(bool_optmenu))); + (GTK_OPTION_MENU(search_window.bool_optmenu))); case_sens = gtk_toggle_button_get_active - (GTK_TOGGLE_BUTTON(case_checkbtn)); - backward = gtk_toggle_button_get_active - (GTK_TOGGLE_BUTTON(backward_checkbtn)); - search_all = gtk_toggle_button_get_active - (GTK_TOGGLE_BUTTON(all_checkbtn)); + (GTK_TOGGLE_BUTTON(search_window.case_checkbtn)); if (case_sens) str_find_func = str_find; else str_find_func = str_case_find; - from_str = gtk_entry_get_text(GTK_ENTRY(from_entry)); - to_str = gtk_entry_get_text(GTK_ENTRY(to_entry)); - subject_str = gtk_entry_get_text(GTK_ENTRY(subject_entry)); - body_str = gtk_entry_get_text(GTK_ENTRY(body_entry)); + from_str = gtk_entry_get_text(GTK_ENTRY(search_window.from_entry)); + to_str = gtk_entry_get_text(GTK_ENTRY(search_window.to_entry)); + subject_str = gtk_entry_get_text(GTK_ENTRY(search_window.subject_entry)); + body_str = gtk_entry_get_text(GTK_ENTRY(search_window.body_entry)); if (search_all) { gtk_clist_freeze(GTK_CLIST(ctree)); @@ -317,8 +375,11 @@ static void summary_search_execute(GtkButton *button, gpointer data) } if (all_searched) { - alertpanel_notice - (_("Search string not found.")); + alertpanel_with_type + (_("Search failed"), + _("Search string not found."), + NULL, NULL, NULL, NULL, + ALERT_WARNING); break; } @@ -339,7 +400,7 @@ static void summary_search_execute(GtkButton *button, gpointer data) all_searched = TRUE; - manage_window_focus_in(window, NULL, NULL); + manage_window_focus_in(search_window.window, NULL, NULL); } else break; } @@ -433,44 +494,55 @@ static void summary_search_execute(GtkButton *button, gpointer data) static void summary_search_clear(GtkButton *button, gpointer data) { - gtk_editable_delete_text(GTK_EDITABLE(from_entry), 0, -1); - gtk_editable_delete_text(GTK_EDITABLE(to_entry), 0, -1); - gtk_editable_delete_text(GTK_EDITABLE(subject_entry), 0, -1); - gtk_editable_delete_text(GTK_EDITABLE(body_entry), 0, -1); + gtk_editable_delete_text(GTK_EDITABLE(search_window.from_entry), + 0, -1); + gtk_editable_delete_text(GTK_EDITABLE(search_window.to_entry), + 0, -1); + gtk_editable_delete_text(GTK_EDITABLE(search_window.subject_entry), + 0, -1); + gtk_editable_delete_text(GTK_EDITABLE(search_window.body_entry), + 0, -1); +} + +static void summary_search_prev_clicked(GtkButton *button, gpointer data) +{ + summary_search_execute(TRUE, FALSE); +} + +static void summary_search_next_clicked(GtkButton *button, gpointer data) +{ + summary_search_execute(FALSE, FALSE); +} + +static void summary_search_all_clicked(GtkButton *button, gpointer data) +{ + summary_search_execute(FALSE, TRUE); } static void from_activated(void) { - gtk_widget_grab_focus(to_entry); + gtk_widget_grab_focus(search_window.to_entry); } static void to_activated(void) { - gtk_widget_grab_focus(subject_entry); + gtk_widget_grab_focus(search_window.subject_entry); } static void subject_activated(void) { - gtk_button_clicked(GTK_BUTTON(search_btn)); + gtk_button_clicked(GTK_BUTTON(search_window.next_btn)); } static void body_activated(void) { - gtk_button_clicked(GTK_BUTTON(search_btn)); -} - -static gboolean all_clicked(GtkButton *button) -{ - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) - gtk_widget_set_sensitive(backward_checkbtn, FALSE); - else - gtk_widget_set_sensitive(backward_checkbtn, TRUE); - return FALSE; + gtk_button_clicked(GTK_BUTTON(search_window.next_btn)); } -static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data) +static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event, + gpointer data) { if (event && event->keyval == GDK_Escape) - gtk_widget_hide(window); + gtk_widget_hide(search_window.window); return FALSE; } diff --git a/src/textview.c b/src/textview.c index 5c3111f0f..86b49b23f 100644 --- a/src/textview.c +++ b/src/textview.c @@ -1340,7 +1340,9 @@ void textview_write_link(TextView *textview, const gchar *str, gchar *bufp; RemoteURI *r_uri; - if (*str == '\0') + if (!str || *str == '\0') + return; + if (!uri) return; text = GTK_TEXT_VIEW(textview->text); @@ -1352,12 +1354,23 @@ void textview_write_link(TextView *textview, const gchar *str, else if (conv_convert(conv, buf, sizeof(buf), str) < 0) conv_utf8todisp(buf, sizeof(buf), str); + if (g_utf8_validate(buf, -1, NULL) == FALSE) { + g_free(buf); + return; + } + strcrchomp(buf); gtk_text_buffer_get_end_iter(buffer, &iter); + for (bufp = buf; *bufp != '\0'; bufp = g_utf8_next_char(bufp)) { + gunichar ch; - for (bufp = buf; isspace(*(guchar *)bufp); bufp++) - gtk_text_buffer_insert(buffer, &iter, bufp, 1); + ch = g_utf8_get_char(bufp); + if (!g_unichar_isspace(ch)) + break; + } + if (bufp > buf) + gtk_text_buffer_insert(buffer, &iter, buf, bufp - buf); if (prefs_common.enable_color) { link_color = &uri_color;