/*
* Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2012 Colin Leroy <colin@colino.net>
- * and the Claws Mail team
+ * Copyright (C) 1999-2020 the Claws Mail team and Colin Leroy
*
* 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
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
*/
#ifdef HAVE_CONFIG_H
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
-#if !GTK_CHECK_VERSION(3, 0, 0)
#include "gtkcmoptionmenu.h"
-#endif
#include "utils.h"
#include "combobox.h"
#include "menu.h"
{
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;
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)
{
if (advsearch_has_proper_predicate(quicksearch->asearch)) {
quicksearch->extended_search_strings =
add_history(quicksearch->extended_search_strings,
- g_strdup(search_string));
+ search_string);
prefs_common.summary_quicksearch_history =
add_history(prefs_common.summary_quicksearch_history,
- g_strdup(search_string));
+ search_string);
}
break;
default:
quicksearch->normal_search_strings =
add_history(quicksearch->normal_search_strings,
- g_strdup(search_string));
+ search_string);
prefs_common.summary_quicksearch_history =
add_history(prefs_common.summary_quicksearch_history,
- g_strdup(search_string));
+ search_string);
break;
}
gboolean quicksearch_run_on_folder(QuickSearch* quicksearch, FolderItem *folderItem, MsgInfoList **result)
{
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, "");
}
static void quicksearch_set_type(QuickSearch *quicksearch, gint type)
{
-#if !GTK_CHECK_VERSION(3, 0, 0)
gint index;
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;
}
{
GtkWidget *search_string_entry = quicksearch->search_string_entry;
- combobox_unset_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(search_string_entry),
+ 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);
}
}
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,
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;
}
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 */
quicksearch_set_popdown_strings(quicksearch);
quicksearch_invoke_execute(quicksearch, FALSE);
+ gtk_widget_grab_focus(quicksearch->search_string_entry);
return TRUE;
}
"a", N_("all messages"),
"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 **/
+ "da \"YYYY-MM-dd HH:mm:ss\"", N_("messages whose date is after requested date "
+ "(time is optional)"),
+ "db \"YYYY-MM-dd HH:mm:ss\"", N_("messages whose date is before requested date "
+ "(time is optional)"),
"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"),
"ha", N_("messages which have attachments"),
- "h S", N_("messages which contain header S"),
+ "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 #"),
"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 # points"),
"|", N_("logical OR operator"),
"! or ~", N_("logical NOT operator"),
"%", N_("case sensitive search"),
- "#", N_("match using regular expressions instead of substring 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 "
static void search_description_cb(GtkWidget *widget)
{
- search_descr.parent = mainwindow_get_mainwindow()->window;
+ search_descr.parent = gtkut_window_new(GTK_WINDOW_TOPLEVEL, "description_window");
description_window_create(&search_descr);
};
{
QuickSearch *quicksearch = (QuickSearch *)data;
- if (!quicksearch->active)
- return TRUE;
-
quicksearch_set(quicksearch, prefs_common.summary_quicksearch_type, "");
return TRUE;
mainwindow_get_mainwindow()->summaryview->quicksearch != NULL,
FALSE);
- /* re-use the current quicksearch value if it's a condition expression,
- otherwise ignore it silently */
+ /* re-use the current quicksearch value, expanding it so it also works
+ * with extended symbols */
cond_str = quicksearch_get_text(mainwindow_get_mainwindow()->summaryview->quicksearch);
if (*cond_str != '\0') {
- matchers = matcher_parser_get_cond((gchar*)cond_str, NULL);
+ gchar *newstr = advsearch_expand_search_string(cond_str);
+
+ if (newstr && newstr[0] != '\0')
+ matchers = matcher_parser_get_cond(newstr, FALSE);
+ g_free(newstr);
}
prefs_matcher_open(matchers, search_condition_expr_done);
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;
quicksearch->active = FALSE;
quicksearch->running = FALSE;
quicksearch->in_typing = FALSE;
- quicksearch->press_timeout_id = -1;
+ 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,
G_CALLBACK(searchtype_changed),
quicksearch);
MENUITEM_ADD (search_type, menuitem,
- _("From/To/Subject/Tag"), ADVANCED_SEARCH_MIXED);
+ _("From/To/Cc/Subject/Tag"), ADVANCED_SEARCH_MIXED);
g_signal_connect(G_OBJECT(menuitem), "activate",
G_CALLBACK(searchtype_changed),
quicksearch);
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);
-#if !GTK_CHECK_VERSION(2, 24, 0)
- search_string_entry = gtk_combo_box_entry_new_text ();
-#else
search_string_entry = gtk_combo_box_text_new_with_entry ();
-#endif
gtk_combo_box_set_active(GTK_COMBO_BOX(search_string_entry), -1);
vbox = gtk_vbox_new(TRUE, 0);
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;
}
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:
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;
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_widget_grab_focus(quicksearch->search_string_entry);
if (!mainwin || !mainwin->summaryview) {
return;
static void quicksearch_set_active(QuickSearch *quicksearch, gboolean active)
{
-#if !GTK_CHECK_VERSION(3, 0, 0)
- static GdkColor yellow;
- static GdkColor red;
- static GdkColor black;
- static gboolean colors_initialised = FALSE;
-#else
- static GdkColor yellow = { (guint32)0, (guint16)0xf5, (guint16)0xf6, (guint16)0xbe };
- static GdkColor red = { (guint32)0, (guint16)0xff, (guint16)0x70, (guint16)0x70 };
- static GdkColor black = { (guint32)0, (guint16)0x0, (guint16)0x0, (guint16)0x0 };
-#endif
gboolean error = FALSE;
-
quicksearch->active = active;
-#if !GTK_CHECK_VERSION(3, 0, 0)
- 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);
- }
-#endif
-
if (active &&
(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 !GTK_CHECK_VERSION(3, 0, 0)
- if (colors_initialised) {
-#endif
- gtk_widget_modify_base(
- gtk_bin_get_child(GTK_BIN((quicksearch->search_string_entry))),
- GTK_STATE_NORMAL, error ? &red : &yellow);
- gtk_widget_modify_text(
- gtk_bin_get_child(GTK_BIN((quicksearch->search_string_entry))),
- GTK_STATE_NORMAL, &black);
-#if !GTK_CHECK_VERSION(3, 0, 0)
- }
-#endif
+ gtk_widget_modify_base(
+ gtk_bin_get_child(GTK_BIN((quicksearch->search_string_entry))),
+ 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, error ? &qs_error_color : &qs_active_color);
} else {
- gtk_widget_set_sensitive(quicksearch->clear_search, FALSE);
-#if !GTK_CHECK_VERSION(3, 0, 0)
- if (colors_initialised) {
-#endif
- 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 !GTK_CHECK_VERSION(3, 0, 0)
- }
-#endif
+ 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) {
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);
-
-}
-
gboolean quicksearch_is_in_typing(QuickSearch *quicksearch)
{
return quicksearch->in_typing;
g_list_append(
quicksearch->normal_search_strings,
g_strdup(strings->data));
- g_free(newstr);
- continue;
- }
-
- matcher_list = matcher_parser_get_cond(newstr, FALSE);
- g_free(newstr);
+ } else {
+ matcher_list = matcher_parser_get_cond(newstr, FALSE);
- 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);