X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=blobdiff_plain;f=src%2Fgtk%2Fquicksearch.c;h=33c883ed29c2e6e2a943c331e0e9399a11dfaa7b;hp=b32db512a274c0614f2dbee87629c85452ead868;hb=2af61e1324d616b7039e95ef0a220998c69df487;hpb=583e26a12e65ec7a29594a63332c11f402491723;ds=sidebyside diff --git a/src/gtk/quicksearch.c b/src/gtk/quicksearch.c index b32db512a..33c883ed2 100644 --- a/src/gtk/quicksearch.c +++ b/src/gtk/quicksearch.c @@ -1,7 +1,6 @@ /* * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 1999-2011 Colin Leroy - * and the Claws Mail team + * Copyright (C) 1999-2018 Colin Leroy and the Claws Mail team * * 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 @@ -15,11 +14,11 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * */ #ifdef HAVE_CONFIG_H # include "config.h" +#include "claws-features.h" #endif #include @@ -29,7 +28,9 @@ #include #include +#if !GTK_CHECK_VERSION(3, 0, 0) #include "gtkcmoptionmenu.h" +#endif #include "utils.h" #include "combobox.h" #include "menu.h" @@ -43,13 +44,13 @@ #include "prefs_matcher.h" #include "claws.h" #include "statusbar.h" +#include "advsearch.h" +#include "alertpanel.h" struct _QuickSearchRequest { - QuickSearchType type; + AdvancedSearchType type; gchar *matchstring; - FolderItem *folderItem; - gboolean recursive; }; typedef struct _QuickSearchRequest QuickSearchRequest; @@ -57,7 +58,9 @@ struct _QuickSearch { GtkWidget *hbox_search; GtkWidget *search_type; +#if !GTK_CHECK_VERSION(3, 0, 0) GtkWidget *search_type_opt; +#endif GtkWidget *search_string_entry; GtkWidget *search_condition_expression; GtkWidget *search_description; @@ -65,17 +68,12 @@ struct _QuickSearch gboolean active; gchar *search_string; - MatcherList *matcher_list; - QuickSearchRequest *request; + QuickSearchRequest request; QuickSearchExecuteCallback callback; gpointer callback_data; gboolean running; gboolean has_focus; - gboolean matching; - gboolean deferred_free; - FolderItem *root_folder_item; - gboolean is_fast; gboolean in_typing; guint press_timeout_id; @@ -86,48 +84,157 @@ struct _QuickSearch GtkWidget *dynamic_menuitem; GtkWidget *autorun_menuitem; - gboolean gui; + AdvancedSearch *asearch; + gboolean want_reexec; + gboolean want_history; +}; + +static GdkColor qs_active_bgcolor = { + (gulong)0, + (gushort)0, + (gushort)0, + (gushort)0 +}; + +static GdkColor qs_active_color = { + (gulong)0, + (gushort)0, + (gushort)0, + (gushort)0 +}; + +static GdkColor qs_error_bgcolor = { + (gulong)0, + (gushort)0, + (gushort)0, + (gushort)0 +}; + +static GdkColor qs_error_color = { + (gulong)0, + (gushort)0, + (gushort)0, + (gushort)0 }; +void quicksearch_set_on_progress_cb(QuickSearch* search, + gboolean (*cb)(gpointer data, guint at, guint matched, guint total), gpointer data) +{ + advsearch_set_on_progress_cb(search->asearch, cb, data); +} + static void quicksearch_set_running(QuickSearch *quicksearch, gboolean run); static void quicksearch_set_matchstring(QuickSearch *quicksearch, const gchar *matchstring); static void quicksearch_set_active(QuickSearch *quicksearch, gboolean active); -static void quicksearch_reset_folder_items(QuickSearch *quicksearch, FolderItem *folder_item); -static gchar *expand_search_string(const gchar *str); -static gchar *expand_tag_search_string(const gchar *str); +static void quicksearch_set_popdown_strings(QuickSearch *quicksearch); -static gboolean quicksearch_from_gui(QuickSearch *quicksearch) +static void quicksearch_add_to_history(QuickSearch* quicksearch) { - return quicksearch->gui; + gchar* search_string = quicksearch->request.matchstring; + + /* add to history, for extended search add only correct matching rules */ + if (quicksearch->want_history && !quicksearch->in_typing && search_string && strlen(search_string) != 0) { + switch (prefs_common.summary_quicksearch_type) { + case ADVANCED_SEARCH_EXTENDED: + if (advsearch_has_proper_predicate(quicksearch->asearch)) { + quicksearch->extended_search_strings = + add_history(quicksearch->extended_search_strings, + search_string); + prefs_common.summary_quicksearch_history = + add_history(prefs_common.summary_quicksearch_history, + search_string); + } + break; + default: + quicksearch->normal_search_strings = + add_history(quicksearch->normal_search_strings, + search_string); + prefs_common.summary_quicksearch_history = + add_history(prefs_common.summary_quicksearch_history, + search_string); + break; + } + + quicksearch_set_popdown_strings(quicksearch); + } + + quicksearch->want_history = FALSE; } -gboolean quicksearch_is_fast(QuickSearch *quicksearch) +static void quicksearch_invoke_execute(QuickSearch *quicksearch, gboolean run_only_if_fast) +{ + if (quicksearch->running) { + quicksearch->want_reexec = TRUE; + advsearch_abort(quicksearch->asearch); + return; + } + + do { + gboolean active = quicksearch->request.matchstring != NULL + && g_strcmp0(quicksearch->request.matchstring, ""); + advsearch_set(quicksearch->asearch, quicksearch->request.type, + quicksearch->request.matchstring); + + if (run_only_if_fast && !advsearch_is_fast(quicksearch->asearch)) + return; + + quicksearch_add_to_history(quicksearch); + + quicksearch_set_active(quicksearch, active); + + quicksearch->want_reexec = FALSE; + quicksearch_set_running(quicksearch, TRUE); + if (quicksearch->callback != NULL) + quicksearch->callback(quicksearch, quicksearch->callback_data); + quicksearch_set_running(quicksearch, FALSE); + } while (quicksearch->want_reexec); +} + +gboolean quicksearch_run_on_folder(QuickSearch* quicksearch, FolderItem *folderItem, MsgInfoList **result) { - return quicksearch->is_fast; + if (quicksearch_has_sat_predicate(quicksearch)) { + gboolean was_running = quicksearch_is_running(quicksearch); + gboolean searchres; + + if (!was_running) + quicksearch_set_running(quicksearch, TRUE); + + main_window_cursor_wait(mainwindow_get_mainwindow()); + searchres = advsearch_search_msgs_in_folders(quicksearch->asearch, result, folderItem, FALSE); + main_window_cursor_normal(mainwindow_get_mainwindow()); + + if (!was_running) + quicksearch_set_running(quicksearch, FALSE); + + if (quicksearch->want_reexec) { + advsearch_set(quicksearch->asearch, quicksearch->request.type, ""); + } + return searchres; + } else + return FALSE; } -void quicksearch_set_recursive(QuickSearch *quicksearch, gboolean recursive) +gboolean quicksearch_is_fast(QuickSearch *quicksearch) { - quicksearch->request->recursive = recursive; + return advsearch_is_fast(quicksearch->asearch); } static void quicksearch_set_type(QuickSearch *quicksearch, gint type) { +#if !GTK_CHECK_VERSION(3, 0, 0) gint index; - quicksearch->request->type = type; - if (quicksearch->gui == FALSE) - return; + quicksearch->request.type = type; index = menu_find_option_menu_index(GTK_CMOPTION_MENU(quicksearch->search_type_opt), GINT_TO_POINTER(type), NULL); gtk_cmoption_menu_set_history(GTK_CMOPTION_MENU(quicksearch->search_type_opt), index); +#endif } static gchar *quicksearch_get_text(QuickSearch * quicksearch) { gchar *search_string = gtk_editable_get_chars(GTK_EDITABLE(gtk_bin_get_child(GTK_BIN((quicksearch->search_string_entry)))), 0, -1); - g_strstrip(search_string); return search_string; } @@ -135,82 +242,15 @@ static void quicksearch_set_popdown_strings(QuickSearch *quicksearch) { GtkWidget *search_string_entry = quicksearch->search_string_entry; - combobox_unset_popdown_strings(GTK_COMBO_BOX(search_string_entry)); - - if (prefs_common.summary_quicksearch_type == QUICK_SEARCH_EXTENDED) - combobox_set_popdown_strings(GTK_COMBO_BOX(search_string_entry), + combobox_unset_popdown_strings(GTK_COMBO_BOX_TEXT(search_string_entry)); + if (prefs_common.summary_quicksearch_type == ADVANCED_SEARCH_EXTENDED) + combobox_set_popdown_strings(GTK_COMBO_BOX_TEXT(search_string_entry), quicksearch->extended_search_strings); else - combobox_set_popdown_strings(GTK_COMBO_BOX(search_string_entry), + combobox_set_popdown_strings(GTK_COMBO_BOX_TEXT(search_string_entry), quicksearch->normal_search_strings); } -static void prepare_matcher(QuickSearch *quicksearch) -{ - /* param search_string is "matchstring" */ - const gchar *search_string; - QuickSearchType quicksearch_type; - - if (quicksearch == NULL) - return; - - /* When called from the GUI, reset type and matchstring */ - if (quicksearch_from_gui(quicksearch)) { - gchar *s = quicksearch_get_text(quicksearch); - quicksearch_set_matchstring(quicksearch, s); - g_free(s); - quicksearch->request->type = prefs_common.summary_quicksearch_type; - } - quicksearch_type = quicksearch->request->type; - search_string = quicksearch->request->matchstring; - - if (search_string == NULL || search_string[0] == '\0') { - quicksearch_set_active(quicksearch, FALSE); - } - - if (quicksearch->matcher_list != NULL) { - if (quicksearch->matching) { - quicksearch->deferred_free = TRUE; - return; - } - quicksearch->deferred_free = FALSE; - matcherlist_free(quicksearch->matcher_list); - quicksearch->matcher_list = NULL; - } - - if (search_string == NULL || search_string[0] == '\0') { - return; - } - if (quicksearch_type == QUICK_SEARCH_EXTENDED) { - char *newstr = NULL; - - newstr = expand_search_string(search_string); - if (newstr && newstr[0] != '\0') { - quicksearch->matcher_list = matcher_parser_get_cond(newstr, &quicksearch->is_fast); - g_free(newstr); - } else { - quicksearch->matcher_list = NULL; - quicksearch_set_active(quicksearch, FALSE); - return; - } - } else if (quicksearch_type == QUICK_SEARCH_TAG) { - char *newstr = expand_tag_search_string(search_string); - quicksearch->matcher_list = matcher_parser_get_cond(newstr, &quicksearch->is_fast); - g_free(newstr); - } else if (quicksearch_type == QUICK_SEARCH_MIXED) { - char *newstr = expand_tag_search_string(search_string); - quicksearch->matcher_list = matcher_parser_get_cond(newstr, &quicksearch->is_fast); - g_free(newstr); - g_free(quicksearch->search_string); - quicksearch->search_string = g_utf8_casefold(search_string, -1); - } else { - quicksearch->is_fast = TRUE; - g_free(quicksearch->search_string); - quicksearch->search_string = g_utf8_casefold(search_string, -1); - } - quicksearch_set_active(quicksearch, TRUE); -} - static void update_extended_buttons (QuickSearch *quicksearch) { GtkWidget *expr_btn = quicksearch->search_condition_expression; @@ -219,7 +259,7 @@ static void update_extended_buttons (QuickSearch *quicksearch) cm_return_if_fail(expr_btn != NULL); cm_return_if_fail(ext_btn != NULL); - if (prefs_common.summary_quicksearch_type == QUICK_SEARCH_EXTENDED) { + if (prefs_common.summary_quicksearch_type == ADVANCED_SEARCH_EXTENDED) { gtk_widget_show(expr_btn); gtk_widget_show(ext_btn); } else { @@ -252,50 +292,11 @@ static void searchbar_run(QuickSearch *quicksearch, gboolean run_only_if_fast) { gchar *search_string = quicksearch_get_text(quicksearch); quicksearch_set_matchstring(quicksearch, search_string); - prepare_matcher(quicksearch); - - /* add to history, for extended search add only correct matching rules */ - if (!quicksearch->in_typing && search_string && strlen(search_string) != 0) { - switch (prefs_common.summary_quicksearch_type) { - case QUICK_SEARCH_EXTENDED: - if (quicksearch->matcher_list) { - quicksearch->extended_search_strings = - add_history(quicksearch->extended_search_strings, - g_strdup(search_string)); - prefs_common.summary_quicksearch_history = - add_history(prefs_common.summary_quicksearch_history, - g_strdup(search_string)); - } - break; - default: - quicksearch->normal_search_strings = - add_history(quicksearch->normal_search_strings, - g_strdup(search_string)); - prefs_common.summary_quicksearch_history = - add_history(prefs_common.summary_quicksearch_history, - g_strdup(search_string)); - break; - } - - quicksearch_set_popdown_strings(quicksearch); + g_free(search_string); - } + quicksearch->want_history = TRUE; - if (run_only_if_fast && !quicksearch->is_fast) { - g_free(search_string); - return; - } - if (quicksearch->matcher_list == NULL && - prefs_common.summary_quicksearch_type == QUICK_SEARCH_EXTENDED && - search_string && strlen(search_string) != 0) { - g_free(search_string); - return; - } - quicksearch_set_running(quicksearch, TRUE); - if (quicksearch->callback != NULL) - quicksearch->callback(quicksearch, quicksearch->callback_data); - quicksearch_set_running(quicksearch, FALSE); - g_free(search_string); + quicksearch_invoke_execute(quicksearch, run_only_if_fast); } static int searchbar_changed_timeout(void *data) @@ -317,7 +318,7 @@ static void searchbar_changed_cb(GtkWidget *widget, QuickSearch *qs) } if (prefs_common.summary_quicksearch_dynamic) { - if (qs->press_timeout_id != -1) { + if (qs->press_timeout_id != 0) { g_source_remove(qs->press_timeout_id); } qs->press_timeout_id = g_timeout_add(500, @@ -331,7 +332,18 @@ static void searchbar_changed_cb(GtkWidget *widget, QuickSearch *qs) static gboolean searchbar_pressed(GtkWidget *widget, GdkEventKey *event, QuickSearch *quicksearch) { - if (event && (event->keyval == GDK_KEY_Escape)) { + if (event != NULL && (event->keyval == GDK_KEY_ISO_Left_Tab)) { + /* Shift+Tab moves focus "back" */ + gtk_widget_grab_focus(quicksearch->search_type_opt); + return TRUE; + } + if (event != NULL && (event->keyval == GDK_KEY_Tab)) { + /* Just Tab moves focus "forwards" */ + gtk_widget_grab_focus(quicksearch->clear_search); + return TRUE; + } + + if (event != NULL && (event->keyval == GDK_KEY_Escape)) { gchar *str; quicksearch->in_typing = FALSE; @@ -354,9 +366,9 @@ static gboolean searchbar_pressed(GtkWidget *widget, GdkEventKey *event, } if (event != NULL && (event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter)) { - if (quicksearch->press_timeout_id != -1) { + if (quicksearch->press_timeout_id != 0) { g_source_remove(quicksearch->press_timeout_id); - quicksearch->press_timeout_id = -1; + quicksearch->press_timeout_id = 0; } quicksearch->in_typing = FALSE; /* add expression to history list and exec quicksearch */ @@ -379,29 +391,19 @@ static gboolean searchbar_pressed(GtkWidget *widget, GdkEventKey *event, static gboolean searchtype_changed(GtkMenuItem *widget, gpointer data) { QuickSearch *quicksearch = (QuickSearch *)data; - gchar *search_string = quicksearch_get_text(quicksearch); - quicksearch_set_matchstring(quicksearch, search_string); prefs_common.summary_quicksearch_type = GPOINTER_TO_INT(g_object_get_data( G_OBJECT(GTK_MENU_ITEM(gtk_menu_get_active( GTK_MENU(quicksearch->search_type)))), MENU_VAL_ID)); + quicksearch->request.type = prefs_common.summary_quicksearch_type; /* Show extended search description button, only when Extended is selected */ update_extended_buttons(quicksearch); quicksearch_set_popdown_strings(quicksearch); - if (!search_string || *(search_string) == 0) { - g_free(search_string); - return TRUE; - } - - prepare_matcher(quicksearch); + quicksearch_invoke_execute(quicksearch, FALSE); + gtk_widget_grab_focus(quicksearch->search_string_entry); - quicksearch_set_running(quicksearch, TRUE); - if (quicksearch->callback != NULL) - quicksearch->callback(quicksearch, quicksearch->callback_data); - quicksearch_set_running(quicksearch, FALSE); - g_free(search_string); return TRUE; } @@ -409,28 +411,14 @@ static gboolean searchtype_recursive_changed(GtkMenuItem *widget, gpointer data) { QuickSearch *quicksearch = (QuickSearch *)data; gboolean checked = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)); - gchar *search_string = quicksearch_get_text(quicksearch); - /* not needed to quicksearch_set_matchstring(search_string); - wait for prepare_matcher() */ prefs_common.summary_quicksearch_recurse = checked; - quicksearch_set_recursive(quicksearch, checked); /* reselect the search type */ quicksearch_set_type(quicksearch, prefs_common.summary_quicksearch_type); - if (!search_string || *(search_string) == 0) { - g_free(search_string); - return TRUE; - } - - prepare_matcher(quicksearch); + quicksearch_invoke_execute(quicksearch, FALSE); - quicksearch_set_running(quicksearch, TRUE); - if (quicksearch->callback != NULL) - quicksearch->callback(quicksearch, quicksearch->callback_data); - quicksearch_set_running(quicksearch, FALSE); - g_free(search_string); return TRUE; } @@ -488,18 +476,22 @@ static gboolean searchtype_autorun_changed(GtkMenuItem *widget, gpointer data) */ static gchar *search_descr_strings[] = { "a", N_("all messages"), - "ag #", N_("messages whose age is greater than #"), - "al #", N_("messages whose age is less than #"), + "ag #", N_("messages whose age is greater than # days"), + "al #", N_("messages whose age is less than # days"), + "agh #", N_("messages whose age is greater than # hours"), + "alh #", N_("messages whose age is less than # hours"), "b S", N_("messages which contain S in the message body"), "B S", N_("messages which contain S in the whole message"), "c S", N_("messages carbon-copied to S"), - "C S", N_("message is either to: or cc: to S"), + "C S", N_("message is either To: or Cc: to S"), "D", N_("deleted messages"), /** how I can filter deleted messages **/ "e S", N_("messages which contain S in the Sender field"), "E S", N_("true if execute \"S\" succeeds"), "f S", N_("messages originating from user S"), "F", N_("forwarded messages"), - "h S", N_("messages which contain header S"), + "ha", N_("messages which have attachments"), + "h S", N_("messages which contain S in any header name or value"), + "H S", N_("messages which contain S in the value of any header"), "i S", N_("messages which contain S in Message-ID header"), "I S", N_("messages which contain S in In-Reply-To header"), "k #", N_("messages which are marked with color #"), @@ -508,15 +500,15 @@ static gchar *search_descr_strings[] = { "N", N_("new messages"), "O", N_("old messages"), "p", N_("incomplete messages (not entirely downloaded)"), - "r", N_("messages which have been replied to"), + "r", N_("messages which you have replied to"), "R", N_("read messages"), "s S", N_("messages which contain S in subject"), - "se #", N_("messages whose score is equal to #"), - "sg #", N_("messages whose score is greater than #"), - "sl #", N_("messages whose score is lower than #"), - "Se #", N_("messages whose size is equal to #"), - "Sg #", N_("messages whose size is greater than #"), - "Ss #", N_("messages whose size is smaller than #"), + "se #", N_("messages whose score is equal to # points"), + "sg #", N_("messages whose score is greater than # points"), + "sl #", N_("messages whose score is lower than # points"), + "Se #", N_("messages whose size is equal to # bytes"), + "Sg #", N_("messages whose size is greater than # bytes"), + "Ss #", N_("messages whose size is smaller than # bytes"), "t S", N_("messages which have been sent to S"), "tg S", N_("messages which tags contain S"), "tagged",N_("messages which have tag(s)"), @@ -530,14 +522,17 @@ static gchar *search_descr_strings[] = { "|", N_("logical OR operator"), "! or ~", N_("logical NOT operator"), "%", N_("case sensitive search"), + "#", N_("match using regular expressions instead of substring search"), "", "" , - " ", N_("all filtering expressions are allowed"), + " ", N_("all filtering expressions are allowed, but cannot be mixed " + "through logical operators with the expressions above"), NULL, NULL }; static DescriptionWindow search_descr = { NULL, NULL, + FALSE, 2, N_("Extended Search"), N_("Extended Search allows the user to define criteria that messages must " @@ -548,6 +543,7 @@ static DescriptionWindow search_descr = { static void search_description_cb(GtkWidget *widget) { + search_descr.parent = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "description_window"); description_window_create(&search_descr); }; @@ -637,41 +633,9 @@ static void quicksearch_set_button(GtkButton *button, const gchar *icon, const g gtk_widget_show_all(box); } -/* - * Builds a new QuickSearchRequest - */ -static QuickSearchRequest *quicksearchrequest_new(void) +static void quicksearch_error(gpointer data) { - QuickSearchRequest *request; - request = g_new0(QuickSearchRequest, 1); - return request; -} - -/* - * Builds a new QuickSearch object independent from the GUI - */ -QuickSearch *quicksearch_new_nogui(void) -{ - QuickSearch *quicksearch; - QuickSearchRequest *request; - - request = quicksearchrequest_new(); - quicksearch = g_new0(QuickSearch, 1); - quicksearch->request = request; - quicksearch->gui = FALSE; - - /* init. values initally found in quicksearch_new(). - There's no need to init. all pointers to NULL since we use g_new0 - */ - quicksearch->matcher_list = NULL; - quicksearch->active = FALSE; - quicksearch->running = FALSE; - quicksearch->in_typing = FALSE; - quicksearch->press_timeout_id = -1; - quicksearch->normal_search_strings = NULL; - quicksearch->extended_search_strings = NULL; - - return quicksearch; + alertpanel_error(_("Something went wrong during search. Please check your logs.")); } QuickSearch *quicksearch_new() @@ -679,7 +643,9 @@ QuickSearch *quicksearch_new() QuickSearch *quicksearch; GtkWidget *hbox_search; +#if !GTK_CHECK_VERSION(3, 0, 0) GtkWidget *search_type_opt; +#endif GtkWidget *search_type; GtkWidget *search_string_entry; GtkWidget *search_hbox; @@ -687,46 +653,59 @@ QuickSearch *quicksearch_new() GtkWidget *clear_search; GtkWidget *search_condition_expression; GtkWidget *menuitem; - CLAWS_TIP_DECL(); GtkWidget *vbox; - quicksearch = quicksearch_new_nogui(); - quicksearch->gui = TRUE; + quicksearch = g_new0(QuickSearch, 1); + + quicksearch->asearch = advsearch_new(); + advsearch_set_on_error_cb(quicksearch->asearch, quicksearch_error, NULL); + + /* init. values initally found in quicksearch_new(). + There's no need to init. all pointers to NULL since we use g_new0 + */ + quicksearch->active = FALSE; + quicksearch->running = FALSE; + quicksearch->in_typing = FALSE; + quicksearch->press_timeout_id = 0; + quicksearch->normal_search_strings = NULL; + quicksearch->extended_search_strings = NULL; /* quick search */ hbox_search = gtk_hbox_new(FALSE, 0); +#if !GTK_CHECK_VERSION(3, 0, 0) search_type_opt = gtk_cmoption_menu_new(); gtk_widget_show(search_type_opt); gtk_box_pack_start(GTK_BOX(hbox_search), search_type_opt, FALSE, FALSE, 0); +#endif search_type = gtk_menu_new(); MENUITEM_ADD (search_type, menuitem, - prefs_common_translated_header_name("Subject"), QUICK_SEARCH_SUBJECT); + prefs_common_translated_header_name("Subject"), ADVANCED_SEARCH_SUBJECT); g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(searchtype_changed), quicksearch); MENUITEM_ADD (search_type, menuitem, - prefs_common_translated_header_name("From"), QUICK_SEARCH_FROM); + prefs_common_translated_header_name("From"), ADVANCED_SEARCH_FROM); g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(searchtype_changed), quicksearch); MENUITEM_ADD (search_type, menuitem, - prefs_common_translated_header_name("To"), QUICK_SEARCH_TO); + prefs_common_translated_header_name("To"), ADVANCED_SEARCH_TO); g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(searchtype_changed), quicksearch); MENUITEM_ADD (search_type, menuitem, - prefs_common_translated_header_name("Tag"), QUICK_SEARCH_TAG); + prefs_common_translated_header_name("Tag"), ADVANCED_SEARCH_TAG); g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(searchtype_changed), quicksearch); MENUITEM_ADD (search_type, menuitem, - _("From/To/Subject/Tag"), QUICK_SEARCH_MIXED); + _("From/To/Cc/Subject/Tag"), ADVANCED_SEARCH_MIXED); g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(searchtype_changed), quicksearch); - MENUITEM_ADD (search_type, menuitem, _("Extended"), QUICK_SEARCH_EXTENDED); + MENUITEM_ADD (search_type, menuitem, _("Extended"), ADVANCED_SEARCH_EXTENDED); g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(searchtype_changed), quicksearch); @@ -738,7 +717,6 @@ QuickSearch *quicksearch_new() gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), prefs_common.summary_quicksearch_recurse); - quicksearch_set_recursive(quicksearch, prefs_common.summary_quicksearch_recurse); g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(searchtype_recursive_changed), quicksearch); @@ -777,14 +755,16 @@ QuickSearch *quicksearch_new() G_CALLBACK(searchtype_autorun_changed), quicksearch); +#if !GTK_CHECK_VERSION(3, 0, 0) gtk_cmoption_menu_set_menu(GTK_CMOPTION_MENU(search_type_opt), search_type); quicksearch->search_type_opt = search_type_opt; +#endif quicksearch_set_type(quicksearch, prefs_common.summary_quicksearch_type); gtk_widget_show(search_type); - search_string_entry = gtk_combo_box_entry_new_text (); + search_string_entry = gtk_combo_box_text_new_with_entry (); gtk_combo_box_set_active(GTK_COMBO_BOX(search_string_entry), -1); vbox = gtk_vbox_new(TRUE, 0); @@ -850,21 +830,29 @@ QuickSearch *quicksearch_new() quicksearch->search_string_entry = search_string_entry; quicksearch->search_condition_expression = search_condition_expression; quicksearch->search_description = search_description; - quicksearch->matcher_list = NULL; quicksearch->active = FALSE; quicksearch->running = FALSE; quicksearch->clear_search = clear_search; quicksearch->in_typing = FALSE; - quicksearch->press_timeout_id = -1; + quicksearch->press_timeout_id = 0; quicksearch->normal_search_strings = NULL; quicksearch->extended_search_strings = NULL; quicksearch_set_button(GTK_BUTTON(quicksearch->search_description), GTK_STOCK_INFO, _("_Information")); - quicksearch_set_button(GTK_BUTTON(quicksearch->search_condition_expression), GTK_STOCK_EDIT, _("_Edit")); + quicksearch_set_button(GTK_BUTTON(quicksearch->search_condition_expression), GTK_STOCK_EDIT, _("E_dit")); quicksearch_set_button(GTK_BUTTON(quicksearch->clear_search), GTK_STOCK_CLEAR, _("C_lear")); update_extended_buttons(quicksearch); + gtkut_convert_int_to_gdk_color(prefs_common.color[COL_QS_ACTIVE_BG], + &qs_active_bgcolor); + gtkut_convert_int_to_gdk_color(prefs_common.color[COL_QS_ACTIVE], + &qs_active_color); + gtkut_convert_int_to_gdk_color(prefs_common.color[COL_QS_ERROR_BG], + &qs_error_bgcolor); + gtkut_convert_int_to_gdk_color(prefs_common.color[COL_QS_ERROR], + &qs_error_color); + return quicksearch; } @@ -875,7 +863,7 @@ void quicksearch_relayout(QuickSearch *quicksearch) case WIDE_LAYOUT: case WIDE_MSGLIST_LAYOUT: quicksearch_set_button(GTK_BUTTON(quicksearch->search_description), GTK_STOCK_INFO, _("_Information")); - quicksearch_set_button(GTK_BUTTON(quicksearch->search_condition_expression), GTK_STOCK_EDIT, _("_Edit")); + quicksearch_set_button(GTK_BUTTON(quicksearch->search_condition_expression), GTK_STOCK_EDIT, _("E_dit")); quicksearch_set_button(GTK_BUTTON(quicksearch->clear_search), GTK_STOCK_CLEAR, _("C_lear")); break; case SMALL_LAYOUT: @@ -892,17 +880,18 @@ GtkWidget *quicksearch_get_widget(QuickSearch *quicksearch) return quicksearch->hbox_search; } +GtkWidget *quicksearch_get_entry(QuickSearch *quicksearch) +{ + return gtk_bin_get_child(GTK_BIN(quicksearch->search_string_entry)); +} + void quicksearch_show(QuickSearch *quicksearch) { MainWindow *mainwin = mainwindow_get_mainwindow(); GtkWidget *ctree = NULL; - prepare_matcher(quicksearch); gtk_widget_show(quicksearch->hbox_search); update_extended_buttons(quicksearch); - gtk_widget_grab_focus( - GTK_WIDGET(gtk_bin_get_child(GTK_BIN((quicksearch->search_string_entry))))); - - GTK_EVENTS_FLUSH(); + gtk_widget_grab_focus(quicksearch->search_string_entry); if (!mainwin || !mainwin->summaryview) { return; @@ -918,7 +907,7 @@ void quicksearch_show(QuickSearch *quicksearch) void quicksearch_hide(QuickSearch *quicksearch) { - if (quicksearch_is_active(quicksearch)) { + if (quicksearch_has_sat_predicate(quicksearch)) { quicksearch_set(quicksearch, prefs_common.summary_quicksearch_type, ""); quicksearch_set_active(quicksearch, FALSE); } @@ -934,12 +923,11 @@ void quicksearch_hide(QuickSearch *quicksearch) static void quicksearch_set_matchstring(QuickSearch *quicksearch, const gchar *matchstring) { - g_free(quicksearch->request->matchstring); - quicksearch->request->matchstring = g_strdup(matchstring); + g_free(quicksearch->request.matchstring); + quicksearch->request.matchstring = g_strdup(matchstring); } -void quicksearch_set(QuickSearch *quicksearch, QuickSearchType type, - const gchar *matchstring) +void quicksearch_set(QuickSearch *quicksearch, AdvancedSearchType type, const gchar *matchstring) { quicksearch_set_type(quicksearch, type); @@ -947,12 +935,6 @@ void quicksearch_set(QuickSearch *quicksearch, QuickSearchType type, quicksearch->in_typing = FALSE; quicksearch_set_matchstring(quicksearch, matchstring); - - if (!quicksearch_from_gui(quicksearch)) { - prepare_matcher(quicksearch); - /* no callback */ - return; - } g_signal_handlers_block_by_func(G_OBJECT(gtk_bin_get_child(GTK_BIN((quicksearch->search_string_entry)))), G_CALLBACK(searchbar_changed_cb), quicksearch); @@ -963,75 +945,45 @@ void quicksearch_set(QuickSearch *quicksearch, QuickSearchType type, prefs_common.summary_quicksearch_type = type; - prepare_matcher(quicksearch); - - quicksearch_set_running(quicksearch, TRUE); - if (quicksearch->callback != NULL) - quicksearch->callback(quicksearch, quicksearch->callback_data); - quicksearch_set_running(quicksearch, FALSE); + quicksearch_invoke_execute(quicksearch, FALSE); } -gboolean quicksearch_is_active(QuickSearch *quicksearch) +gboolean quicksearch_has_sat_predicate(QuickSearch *quicksearch) { - return quicksearch->active && - (prefs_common.summary_quicksearch_type != QUICK_SEARCH_EXTENDED - || quicksearch->matcher_list != NULL); + return quicksearch->active && advsearch_has_proper_predicate(quicksearch->asearch); } static void quicksearch_set_active(QuickSearch *quicksearch, gboolean active) { - static GdkColor yellow; - static GdkColor red; - static GdkColor black; - static gboolean colors_initialised = FALSE; gboolean error = FALSE; - quicksearch->active = active; - if (quicksearch->gui == FALSE) - return; - - if (!colors_initialised) { - gdk_color_parse("#f5f6be", &yellow); - gdk_color_parse("#000000", &black); - gdk_color_parse("#ff7070", &red); - colors_initialised = gdk_colormap_alloc_color( - gdk_colormap_get_system(), &yellow, FALSE, TRUE); - colors_initialised &= gdk_colormap_alloc_color( - gdk_colormap_get_system(), &black, FALSE, TRUE); - colors_initialised &= gdk_colormap_alloc_color( - gdk_colormap_get_system(), &red, FALSE, TRUE); - } if (active && - (prefs_common.summary_quicksearch_type == QUICK_SEARCH_EXTENDED - && quicksearch->matcher_list == NULL)) + (prefs_common.summary_quicksearch_type == ADVANCED_SEARCH_EXTENDED + && !advsearch_has_proper_predicate(quicksearch->asearch))) error = TRUE; if (active) { gtk_widget_set_sensitive(quicksearch->clear_search, TRUE); - if (colors_initialised) { gtk_widget_modify_base( gtk_bin_get_child(GTK_BIN((quicksearch->search_string_entry))), - GTK_STATE_NORMAL, error ? &red : &yellow); + GTK_STATE_NORMAL, error ? &qs_error_bgcolor : &qs_active_bgcolor); gtk_widget_modify_text( gtk_bin_get_child(GTK_BIN((quicksearch->search_string_entry))), - GTK_STATE_NORMAL, &black); - } + GTK_STATE_NORMAL, error ? &qs_error_color : &qs_active_color); } else { gtk_widget_set_sensitive(quicksearch->clear_search, FALSE); - if (colors_initialised) { gtk_widget_modify_base( gtk_bin_get_child(GTK_BIN((quicksearch->search_string_entry))), GTK_STATE_NORMAL, NULL); gtk_widget_modify_text( gtk_bin_get_child(GTK_BIN((quicksearch->search_string_entry))), GTK_STATE_NORMAL, NULL); - } } if (!active) { - quicksearch_reset_cur_folder_item(quicksearch); + advsearch_abort(quicksearch->asearch); } } @@ -1043,290 +995,6 @@ void quicksearch_set_execute_callback(QuickSearch *quicksearch, quicksearch->callback_data = data; } -gboolean quicksearch_match(QuickSearch *quicksearch, MsgInfo *msginfo) -{ - gchar *searched_header = NULL; - gboolean result = FALSE; - gchar *to = NULL, *from = NULL, *subject = NULL; - QuickSearchType quicksearch_type; - - if (!quicksearch->active) - return TRUE; - - quicksearch_type = quicksearch->request->type; - - switch (quicksearch_type) { - case QUICK_SEARCH_SUBJECT: - if (msginfo->subject) - searched_header = g_utf8_casefold(msginfo->subject, -1); - else - return FALSE; - break; - case QUICK_SEARCH_FROM: - if (msginfo->from) - searched_header = g_utf8_casefold(msginfo->from, -1); - else - return FALSE; - break; - case QUICK_SEARCH_TO: - if (msginfo->to) - searched_header = g_utf8_casefold(msginfo->to, -1); - else - return FALSE; - break; - case QUICK_SEARCH_MIXED: - if (msginfo->to) - to = g_utf8_casefold(msginfo->to, -1); - if (msginfo->from) - from = g_utf8_casefold(msginfo->from, -1); - if (msginfo->subject) - subject = g_utf8_casefold(msginfo->subject, -1); - break; - case QUICK_SEARCH_EXTENDED: - break; - default: - debug_print("unknown search type (%d)\n", quicksearch_type); - break; - } - - quicksearch->matching = TRUE; - if (quicksearch_type != QUICK_SEARCH_EXTENDED && - quicksearch_type != QUICK_SEARCH_MIXED && - quicksearch_type != QUICK_SEARCH_TAG && - quicksearch->search_string && - searched_header && strstr(searched_header, quicksearch->search_string) != NULL) - result = TRUE; - else if (quicksearch_type == QUICK_SEARCH_MIXED && - quicksearch->search_string && ( - (to && strstr(to, quicksearch->search_string) != NULL) || - (from && strstr(from, quicksearch->search_string) != NULL) || - (subject && strstr(subject, quicksearch->search_string) != NULL) || - ((quicksearch->matcher_list != NULL) && - matcherlist_match(quicksearch->matcher_list, msginfo)) )) - result = TRUE; - else if ((quicksearch->matcher_list != NULL) && - matcherlist_match(quicksearch->matcher_list, msginfo)) - result = TRUE; - - quicksearch->matching = FALSE; - if (quicksearch_from_gui(quicksearch)==TRUE && quicksearch->deferred_free) { - /* Ref. http://lists.claws-mail.org/pipermail/users/2010-August/003063.html - See also 2.0.0cvs140 ChangeLog entry - and comment in search_msgs_in_folder() */ - prepare_matcher(quicksearch); - } - - g_free(to); - g_free(from); - g_free(subject); - g_free(searched_header); - - return result; -} - -/* allow Mutt-like patterns in quick search */ -static gchar *expand_search_string(const gchar *search_string) -{ - int i = 0; - gchar term_char, save_char; - gchar *cmd_start, *cmd_end; - GString *matcherstr; - gchar *returnstr = NULL; - gchar *copy_str; - gboolean casesens, dontmatch; - /* list of allowed pattern abbreviations */ - struct { - gchar *abbreviated; /* abbreviation */ - gchar *command; /* actual matcher command */ - gint numparams; /* number of params for cmd */ - gboolean qualifier; /* do we append regexpcase */ - gboolean quotes; /* do we need quotes */ - } - cmds[] = { - { "a", "all", 0, FALSE, FALSE }, - { "ag", "age_greater", 1, FALSE, FALSE }, - { "al", "age_lower", 1, FALSE, FALSE }, - { "b", "body_part", 1, TRUE, TRUE }, - { "B", "message", 1, TRUE, TRUE }, - { "c", "cc", 1, TRUE, TRUE }, - { "C", "to_or_cc", 1, TRUE, TRUE }, - { "D", "deleted", 0, FALSE, FALSE }, - { "e", "header \"Sender\"", 1, TRUE, TRUE }, - { "E", "execute", 1, FALSE, TRUE }, - { "f", "from", 1, TRUE, TRUE }, - { "F", "forwarded", 0, FALSE, FALSE }, - { "h", "headers_part", 1, TRUE, TRUE }, - { "i", "header \"Message-ID\"", 1, TRUE, TRUE }, - { "I", "inreplyto", 1, TRUE, TRUE }, - { "k", "colorlabel", 1, FALSE, FALSE }, - { "L", "locked", 0, FALSE, FALSE }, - { "n", "newsgroups", 1, TRUE, TRUE }, - { "N", "new", 0, FALSE, FALSE }, - { "O", "~new", 0, FALSE, FALSE }, - { "r", "replied", 0, FALSE, FALSE }, - { "R", "~unread", 0, FALSE, FALSE }, - { "s", "subject", 1, TRUE, TRUE }, - { "se", "score_equal", 1, FALSE, FALSE }, - { "sg", "score_greater", 1, FALSE, FALSE }, - { "sl", "score_lower", 1, FALSE, FALSE }, - { "Se", "size_equal", 1, FALSE, FALSE }, - { "Sg", "size_greater", 1, FALSE, FALSE }, - { "Ss", "size_smaller", 1, FALSE, FALSE }, - { "t", "to", 1, TRUE, TRUE }, - { "tg", "tag", 1, TRUE, TRUE }, - { "T", "marked", 0, FALSE, FALSE }, - { "U", "unread", 0, FALSE, FALSE }, - { "x", "header \"References\"", 1, TRUE, TRUE }, - { "X", "test", 1, FALSE, FALSE }, - { "y", "header \"X-Label\"", 1, TRUE, TRUE }, - { "&", "&", 0, FALSE, FALSE }, - { "|", "|", 0, FALSE, FALSE }, - { "p", "partial", 0, FALSE, FALSE }, - { NULL, NULL, 0, FALSE, FALSE } - }; - - if (search_string == NULL) - return NULL; - - copy_str = g_strdup(search_string); - - matcherstr = g_string_sized_new(16); - cmd_start = copy_str; - while (cmd_start && *cmd_start) { - /* skip all white spaces */ - while (*cmd_start && isspace((guchar)*cmd_start)) - cmd_start++; - cmd_end = cmd_start; - - /* extract a command */ - while (*cmd_end && !isspace((guchar)*cmd_end)) - cmd_end++; - - /* save character */ - save_char = *cmd_end; - *cmd_end = '\0'; - - dontmatch = FALSE; - casesens = FALSE; - - /* ~ and ! mean logical NOT */ - if (*cmd_start == '~' || *cmd_start == '!') - { - dontmatch = TRUE; - cmd_start++; - } - /* % means case sensitive match */ - if (*cmd_start == '%') - { - casesens = TRUE; - cmd_start++; - } - - /* find matching abbreviation */ - for (i = 0; cmds[i].command; i++) { - if (!strcmp(cmd_start, cmds[i].abbreviated)) { - /* restore character */ - *cmd_end = save_char; - - /* copy command */ - if (matcherstr->len > 0) { - g_string_append(matcherstr, " "); - } - if (dontmatch) - g_string_append(matcherstr, "~"); - g_string_append(matcherstr, cmds[i].command); - g_string_append(matcherstr, " "); - - /* stop if no params required */ - if (cmds[i].numparams == 0) - break; - - /* extract a parameter, allow quotes */ - while (*cmd_end && isspace((guchar)*cmd_end)) - cmd_end++; - - cmd_start = cmd_end; - if (*cmd_start == '"') { - term_char = '"'; - cmd_end++; - } - else - term_char = ' '; - - /* extract actual parameter */ - while ((*cmd_end) && (*cmd_end != term_char)) - cmd_end++; - - if (*cmd_end == '"') - cmd_end++; - - save_char = *cmd_end; - *cmd_end = '\0'; - - if (cmds[i].qualifier) { - if (casesens) - g_string_append(matcherstr, "regexp "); - else - g_string_append(matcherstr, "regexpcase "); - } - - /* do we need to add quotes ? */ - if (cmds[i].quotes && term_char != '"') - g_string_append(matcherstr, "\""); - - /* copy actual parameter */ - g_string_append(matcherstr, cmd_start); - - /* do we need to add quotes ? */ - if (cmds[i].quotes && term_char != '"') - g_string_append(matcherstr, "\""); - - /* restore original character */ - *cmd_end = save_char; - - break; - } - } - - if (*cmd_end) - cmd_end++; - cmd_start = cmd_end; - } - - g_free(copy_str); - - /* return search string if no match is found to allow - all available filtering expressions in quicksearch */ - if (matcherstr->len > 0) returnstr = matcherstr->str; - else returnstr = g_strdup(search_string); - g_string_free(matcherstr, FALSE); - return returnstr; -} - -static gchar *expand_tag_search_string(const gchar *search_string) -{ - gchar *newstr = NULL; - gchar **words = search_string ? g_strsplit(search_string, " ", -1):NULL; - gint i = 0; - while (words && words[i] && *words[i]) { - g_strstrip(words[i]); - if (!newstr) { - newstr = g_strdup_printf("tag regexpcase \"%s\"", words[i]); - } else { - gint o_len = strlen(newstr); - gint s_len = 18; /* strlen("|tag regexpcase \"\"") */ - gint n_len = s_len + strlen(words[i]); - newstr = g_realloc(newstr,o_len+n_len+1); - strcpy(newstr+o_len, "|tag regexpcase \""); - strcpy(newstr+o_len+(s_len-1), words[i]); - strcpy(newstr+o_len+(n_len-1), "\""); - } - i++; - } - g_strfreev(words); - return newstr; -} - static void quicksearch_set_running(QuickSearch *quicksearch, gboolean run) { quicksearch->running = run; @@ -1337,155 +1005,6 @@ gboolean quicksearch_is_running(QuickSearch *quicksearch) return quicksearch->running; } -void quicksearch_pass_key(QuickSearch *quicksearch, guint val, GdkModifierType mod) -{ - GtkEntry *entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN((quicksearch->search_string_entry)))); - glong curpos = gtk_editable_get_position(GTK_EDITABLE(entry)); - guint32 c; - char *str = g_strdup(gtk_entry_get_text(entry)); - char *begin = str; - char *end = NULL; - char *new = NULL; - char key[7] = ""; - guint char_len = 0; - - if (gtk_editable_get_selection_bounds(GTK_EDITABLE(entry), NULL, NULL)) { - /* remove selection */ - gtk_editable_delete_selection(GTK_EDITABLE(entry)); - curpos = gtk_editable_get_position(GTK_EDITABLE(entry)); - /* refresh string */ - g_free(str); - str = g_strdup(gtk_entry_get_text(entry)); - begin = str; - } - - if (!(c = gdk_keyval_to_unicode(val))) { - g_free(str); - return; - } - char_len = g_unichar_to_utf8(c, key); - if (char_len < 0) - return; - key[char_len] = '\0'; - if (curpos < g_utf8_strlen(str, -1)) { - gchar *stop = g_utf8_offset_to_pointer(begin, curpos); - end = g_strdup(g_utf8_offset_to_pointer(str, curpos)); - *stop = '\0'; - new = g_strdup_printf("%s%s%s", begin, key, end); - gtk_entry_set_text(entry, new); - g_free(end); - } else { - new = g_strdup_printf("%s%s", begin, key); - gtk_entry_set_text(entry, new); - } - g_free(str); - g_free(new); - gtk_editable_set_position(GTK_EDITABLE(entry), curpos+1); - -} - -static gboolean quicksearch_match_subfolder(QuickSearch *quicksearch, - FolderItem *src) -{ - GSList *msglist = NULL; - GSList *cur; - gboolean result = FALSE; - gint num = 0, total = 0; - gint interval = quicksearch_is_fast(quicksearch) ? 5000:100; - - statusbar_print_all(_("Searching in %s... \n"), - src->path ? src->path : "(null)"); - - msglist = folder_item_get_msg_list(src); - total = src->total_msgs; - folder_item_update_freeze(); - for (cur = msglist; cur != NULL; cur = cur->next) { - MsgInfo *msg = (MsgInfo *)cur->data; - statusbar_progress_all(num++,total, interval); - if (quicksearch_match(quicksearch, msg)) { - result = TRUE; - break; - } - if (num % interval == 0) - GTK_EVENTS_FLUSH(); - if (!quicksearch_is_active(quicksearch)) - break; - } - folder_item_update_thaw(); - statusbar_progress_all(0,0,0); - statusbar_pop_all(); - - procmsg_msg_list_free(msglist); - return result; -} - -gboolean quicksearch_is_in_subfolder(QuickSearch *quicksearch, FolderItem *cur) -{ - if (quicksearch->root_folder_item == NULL) - return FALSE; - - while (cur) { - if (cur == quicksearch->root_folder_item) { - return TRUE; - } - cur = folder_item_parent(cur); - } - return FALSE; -} - -void quicksearch_search_subfolders(QuickSearch *quicksearch, - FolderView *folderview, - FolderItem *folder_item) -{ - FolderItem *cur = NULL; - GNode *node = folder_item->node->children; - - if (!prefs_common.summary_quicksearch_recurse - || quicksearch->in_typing == TRUE) - return; - - for (; node != NULL; node = node->next) { - cur = FOLDER_ITEM(node->data); - if (quicksearch_match_subfolder(quicksearch, cur)) { - folderview_update_search_icon(cur, TRUE); - } else { - folderview_update_search_icon(cur, FALSE); - } - if (cur->node->children) - quicksearch_search_subfolders(quicksearch, - folderview, - cur); - } - quicksearch->root_folder_item = folder_item; - if (!quicksearch_is_active(quicksearch)) - quicksearch_reset_cur_folder_item(quicksearch); -} - -static void quicksearch_reset_folder_items(QuickSearch *quicksearch, - FolderItem *folder_item) -{ - FolderItem *cur = NULL; - GNode *node = (folder_item && folder_item->node) ? - folder_item->node->children : NULL; - - for (; node != NULL; node = node->next) { - cur = FOLDER_ITEM(node->data); - folderview_update_search_icon(cur, FALSE); - if (cur->node->children) - quicksearch_reset_folder_items(quicksearch, - cur); - } -} - -void quicksearch_reset_cur_folder_item(QuickSearch *quicksearch) -{ - if (quicksearch->root_folder_item) - quicksearch_reset_folder_items(quicksearch, - quicksearch->root_folder_item); - - quicksearch->root_folder_item = NULL; -} - gboolean quicksearch_is_in_typing(QuickSearch *quicksearch) { return quicksearch->in_typing; @@ -1503,32 +1022,30 @@ void quicksearch_set_search_strings(QuickSearch *quicksearch) matcher_parser_disable_warnings(TRUE); do { - newstr = expand_search_string((gchar *) strings->data); + newstr = advsearch_expand_search_string((gchar *) strings->data); if (newstr && newstr[0] != '\0') { if (!strchr(newstr, ' ')) { quicksearch->normal_search_strings = g_list_append( quicksearch->normal_search_strings, g_strdup(strings->data)); - g_free(newstr); - continue; - } + } else { + matcher_list = matcher_parser_get_cond(newstr, FALSE); - matcher_list = matcher_parser_get_cond(newstr, FALSE); - g_free(newstr); - - if (matcher_list) { - quicksearch->extended_search_strings = - g_list_prepend( - quicksearch->extended_search_strings, - g_strdup(strings->data)); - matcherlist_free(matcher_list); - } else - quicksearch->normal_search_strings = - g_list_prepend( - quicksearch->normal_search_strings, - g_strdup(strings->data)); + if (matcher_list) { + quicksearch->extended_search_strings = + g_list_prepend( + quicksearch->extended_search_strings, + g_strdup(strings->data)); + matcherlist_free(matcher_list); + } else + quicksearch->normal_search_strings = + g_list_prepend( + quicksearch->normal_search_strings, + g_strdup(strings->data)); + } } + g_free(newstr); } while ((strings = g_list_next(strings)) != NULL); @@ -1540,98 +1057,3 @@ void quicksearch_set_search_strings(QuickSearch *quicksearch) quicksearch_set_popdown_strings(quicksearch); } -/* - * Searches in the supplied folderItem the messages (MessageInfo) matching a - * QuickSearchType + search string (ex.: QUICK_SEARCH_FROM and "foo@bar.com"). - * - * Found messages are appended to the array 'messages' and their ref.counts - * are incremented by 1 --so they need to be released (procmsg_msginfo_free()) - * before the array 'messages' is freed. - */ -void search_msgs_in_folder(GSList **messages, QuickSearch* quicksearch, - FolderItem* folderItem) -{ - /* from quicksearch_match_subfolder */ - GSList *msglist = NULL; - GSList *cur; - - /* The list is built w/ MsgInfo items whose ref.counts are incremented, - but they are decremented when the list is freed by - procmsg_msg_list_free(): we'll ask for a new ref., below - */ - msglist = folder_item_get_msg_list(folderItem); - - for (cur = msglist; cur != NULL; cur = cur->next) { - MsgInfo *msg = (MsgInfo *)cur->data; - if (quicksearch_match(quicksearch, msg)) { - /*debug_print("found: %s from:%s\n",procmsg_get_message_file_path(msg),msg->from);*/ - *messages = g_slist_prepend(*messages, procmsg_msginfo_new_ref(msg)); - } - /* See 2.0.0cvs140 ChangeLog entry for details - see also comments in quicksearch_match() */ - if (quicksearch_from_gui(quicksearch)==TRUE - && !quicksearch_is_active(quicksearch)) - break; - } - procmsg_msg_list_free(msglist); -} - -/* - * Searches within the folderItem and its sub-folders (if recursive is TRUE) - * the messages matching the search request. - * - * NB: search within a Folder can be done this way: - * search_msg_in_folders(messages, quicksearch, searchType, - * FOLDER_ITEM(folder->node->data), TRUE); - */ -void search_msgs_in_folders(GSList **messages, QuickSearch* quicksearch, - FolderItem* folderItem) -{ - FolderItem *cur = NULL; - - search_msgs_in_folder(messages, quicksearch, folderItem); - if (quicksearch->request->recursive == FALSE) - return; - - GNode *node = folderItem->node->children; - for (; node != NULL; node = node->next) { - cur = FOLDER_ITEM(node->data); - debug_print("in: %s\n",cur->path); - if (cur->node->children) - search_msgs_in_folders(messages, quicksearch, cur); - else - search_msgs_in_folder(messages, quicksearch, cur); - } - *messages = g_slist_reverse(*messages); -} - - /* - * Returns the QuickSearchType associated to the supplied string. - */ -QuickSearchType quicksearch_type(const gchar* type) -{ - QuickSearchType searchType = QUICK_SEARCH_EXTENDED; - if (!type) - return searchType; - switch(toupper(*type)) { - case 'S': - searchType = QUICK_SEARCH_SUBJECT; - break; - case 'F': - searchType = QUICK_SEARCH_FROM; - break; - case 'T': - searchType = QUICK_SEARCH_TO; - break; - case 'E': - searchType = QUICK_SEARCH_EXTENDED; - break; - case 'M': - searchType = QUICK_SEARCH_MIXED; - break; - case 'G': - searchType = QUICK_SEARCH_TAG; - break; - } - return searchType; -}