gboolean deferred_free;
FolderItem *root_folder_item;
gboolean is_fast;
+ gboolean in_typing;
+ guint press_timeout_id;
};
static void quicksearch_set_running(QuickSearch *quicksearch, gboolean run);
return;
}
} else {
+ quicksearch->is_fast = TRUE;
g_free(quicksearch->search_string);
quicksearch->search_string = g_strdup(search_string);
}
}
}
-static gboolean searchbar_focus_evt(GtkWidget *widget, GdkEventFocus *event,
- QuickSearch *quicksearch)
+static gboolean searchbar_focus_evt_in(GtkWidget *widget, GdkEventFocus *event,
+ QuickSearch *qs)
+{
+ qs->has_focus = TRUE;
+ return FALSE;
+}
+
+static gboolean searchbar_focus_evt_out(GtkWidget *widget, GdkEventFocus *event,
+ QuickSearch *qs)
{
- quicksearch->has_focus = (event && event->in);
+ qs->has_focus = FALSE;
+ qs->in_typing = FALSE;
return FALSE;
}
return quicksearch->has_focus;
}
-static void searchbar_run(QuickSearch *quicksearch)
+static void searchbar_run(QuickSearch *quicksearch, gboolean run_only_if_fast)
{
const gchar *search_string = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(quicksearch->search_string_entry)->entry));
- if (search_string && strlen(search_string) != 0) {
- prefs_common.summary_quicksearch_history =
- add_history(prefs_common.summary_quicksearch_history,
- search_string);
- gtk_combo_set_popdown_strings(GTK_COMBO(quicksearch->search_string_entry),
- prefs_common.summary_quicksearch_history);
+ /* add to history */
+ if (!quicksearch->in_typing && search_string && strlen(search_string) != 0) {
+ /* only if there's no syntax error */
+ if (quicksearch->matcher_list != NULL ||
+ prefs_common.summary_quicksearch_type != QUICK_SEARCH_EXTENDED) {
+ prefs_common.summary_quicksearch_history =
+ add_history(prefs_common.summary_quicksearch_history,
+ search_string);
+ gtk_combo_set_popdown_strings(GTK_COMBO(quicksearch->search_string_entry),
+ prefs_common.summary_quicksearch_history);
+ }
}
prepare_matcher(quicksearch);
-
+ if (run_only_if_fast && !quicksearch->is_fast)
+ return;
+ if (quicksearch->matcher_list == NULL &&
+ prefs_common.summary_quicksearch_type == QUICK_SEARCH_EXTENDED)
+ return;
quicksearch_set_running(quicksearch, TRUE);
if (quicksearch->callback != NULL)
quicksearch->callback(quicksearch, quicksearch->callback_data);
quicksearch_set_running(quicksearch, FALSE);
}
+static int searchbar_changed_timeout(void *data)
+{
+ QuickSearch *qs = (QuickSearch *)data;
+ if (qs && prefs_common.summary_quicksearch_dynamic) {
+ qs->in_typing = TRUE;
+ searchbar_run(qs, TRUE);
+ }
+ return FALSE;
+}
+
+static gboolean searchbar_changed_cb(GtkWidget *widget, QuickSearch *qs)
+{
+ if (prefs_common.summary_quicksearch_dynamic) {
+ if (qs->press_timeout_id != -1) {
+ gtk_timeout_remove(qs->press_timeout_id);
+ }
+ qs->press_timeout_id = gtk_timeout_add(500,
+ searchbar_changed_timeout, qs);
+ }
+
+ return FALSE;
+}
+
static gboolean searchbar_pressed(GtkWidget *widget, GdkEventKey *event,
QuickSearch *quicksearch)
{
if (event != NULL && event->keyval == GDK_Escape) {
- quicksearch_set(quicksearch, prefs_common.summary_quicksearch_type, "");
+
+ const gchar *str;
+
+ quicksearch->in_typing = FALSE;
+
+ str = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(quicksearch->search_string_entry)->entry));
+ g_return_val_if_fail(str != NULL, TRUE);
+
+ /* If the string entry is empty -> hide quicksearch bar. If not -> empty it */
+ if (!*str) {
+ quicksearch_hide(quicksearch);
+ } else {
+ quicksearch_set(quicksearch, prefs_common.summary_quicksearch_type, "");
+ gtk_widget_grab_focus(
+ GTK_WIDGET(GTK_COMBO(quicksearch->search_string_entry)->entry));
+ }
+
return TRUE;
}
if (event != NULL && event->keyval == GDK_Return) {
+ quicksearch->in_typing = FALSE;
/* add expression to history list and exec quicksearch */
- searchbar_run(quicksearch);
+ searchbar_run(quicksearch, FALSE);
g_signal_stop_emission_by_name(G_OBJECT(widget), "key_press_event");
return TRUE;
return TRUE;
}
+static gboolean searchtype_dynamic_changed(GtkMenuItem *widget, gpointer data)
+{
+ QuickSearch *quicksearch = (QuickSearch *)data;
+ gboolean checked = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
+
+ prefs_common.summary_quicksearch_dynamic = checked;
+
+ /* reselect the search type */
+ gtk_option_menu_set_history(GTK_OPTION_MENU(quicksearch->search_type_opt),
+ prefs_common.summary_quicksearch_type);
+
+ return TRUE;
+}
+
/*
* Strings describing how to use Extended Search
*
g_free(str);
/* add expression to history list and exec quicksearch */
- searchbar_run(mainwindow_get_mainwindow()->summaryview->quicksearch);
+ searchbar_run(mainwindow_get_mainwindow()->summaryview->quicksearch, FALSE);
}
}
G_CALLBACK(searchtype_sticky_changed),
quicksearch);
+ menuitem = gtk_check_menu_item_new_with_label(_("Type-ahead"));
+ gtk_menu_shell_append(GTK_MENU_SHELL(search_type), menuitem);
+
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
+ prefs_common.summary_quicksearch_dynamic);
+
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(searchtype_dynamic_changed),
+ quicksearch);
+
gtk_option_menu_set_menu(GTK_OPTION_MENU(search_type_opt), search_type);
gtk_option_menu_set_history(GTK_OPTION_MENU(search_type_opt), prefs_common.summary_quicksearch_type);
"key_press_event",
G_CALLBACK(searchbar_pressed),
quicksearch);
+
+ g_signal_connect(G_OBJECT(GTK_COMBO(search_string_entry)->entry),
+ "changed",
+ G_CALLBACK(searchbar_changed_cb),
+ quicksearch);
+
g_signal_connect(G_OBJECT(GTK_COMBO(search_string_entry)->entry),
"focus_in_event",
- G_CALLBACK(searchbar_focus_evt),
+ G_CALLBACK(searchbar_focus_evt_in),
quicksearch);
g_signal_connect(G_OBJECT(GTK_COMBO(search_string_entry)->entry),
"focus_out_event",
- G_CALLBACK(searchbar_focus_evt),
+ G_CALLBACK(searchbar_focus_evt_out),
quicksearch);
quicksearch->hbox_search = hbox_search;
quicksearch->active = FALSE;
quicksearch->running = FALSE;
quicksearch->clear_search = clear_search;
+ quicksearch->in_typing = FALSE;
+ quicksearch->press_timeout_id = -1;
update_extended_buttons(quicksearch);
{
gtk_option_menu_set_history(GTK_OPTION_MENU(quicksearch->search_type_opt),
type);
+
+ g_signal_handlers_block_by_func(G_OBJECT(GTK_COMBO(quicksearch->search_string_entry)->entry),
+ G_CALLBACK(searchbar_changed_cb), quicksearch);
gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(quicksearch->search_string_entry)->entry),
matchstring);
+ g_signal_handlers_unblock_by_func(G_OBJECT(GTK_COMBO(quicksearch->search_string_entry)->entry),
+ G_CALLBACK(searchbar_changed_cb), quicksearch);
+
prefs_common.summary_quicksearch_type = type;
prepare_matcher(quicksearch);
FolderItem *cur = NULL;
GNode *node = folder_item->node->children;
- if (!prefs_common.summary_quicksearch_recurse)
+ if (!prefs_common.summary_quicksearch_recurse
+ || quicksearch->in_typing == TRUE)
return;
for (; node != NULL; node = node->next) {
quicksearch->root_folder_item = NULL;
}
+
+gboolean quicksearch_is_in_typing(QuickSearch *quicksearch)
+{
+ return quicksearch->in_typing;
+}
gboolean summary_show(SummaryView *summaryview, FolderItem *item)
{
GtkCTree *ctree = GTK_CTREE(summaryview->ctree);
- GtkCTreeNode *node;
+ GtkCTreeNode *node = NULL;
GSList *mlist = NULL;
gchar *buf;
gboolean is_refresh;
}
if (is_refresh) {
- summaryview->last_displayed = summaryview->displayed;
- summaryview->displayed =
- summary_find_msg_by_msgnum(summaryview,
- displayed_msgnum);
- if (!summaryview->displayed)
- messageview_clear(summaryview->messageview);
- summary_unlock(summaryview);
- summary_select_by_msgnum(summaryview, selected_msgnum);
- summary_lock(summaryview);
- if (!summaryview->selected) {
- /* no selected message - select first unread
- message, but do not display it */
- node = summary_find_next_flagged_msg(summaryview, NULL,
- MSG_UNREAD, FALSE);
- if (node == NULL && GTK_CLIST(ctree)->row_list != NULL)
+ if (!quicksearch_is_in_typing(summaryview->quicksearch)) {
+ summaryview->last_displayed = summaryview->displayed;
+ summaryview->displayed =
+ summary_find_msg_by_msgnum(summaryview,
+ displayed_msgnum);
+ if (!summaryview->displayed)
+ messageview_clear(summaryview->messageview);
+ summary_unlock(summaryview);
+ summary_select_by_msgnum(summaryview, selected_msgnum);
+ summary_lock(summaryview);
+ if (!summaryview->selected) {
+ /* no selected message - select first unread
+ message, but do not display it */
+ node = summary_find_next_flagged_msg(summaryview, NULL,
+ MSG_UNREAD, FALSE);
+ if (node == NULL && GTK_CLIST(ctree)->row_list != NULL)
+ node = gtk_ctree_node_nth
+ (ctree,
+ item->sort_type == SORT_DESCENDING
+ ? 0 : GTK_CLIST(ctree)->rows - 1);
+ summary_unlock(summaryview);
+ summary_select_node(summaryview, node, FALSE, TRUE);
+ summary_lock(summaryview);
+ }
+ } else {
+ /* just select first/last */
+ if (GTK_CLIST(ctree)->row_list != NULL)
node = gtk_ctree_node_nth
(ctree,
item->sort_type == SORT_DESCENDING
? 0 : GTK_CLIST(ctree)->rows - 1);
- summary_unlock(summaryview);
- summary_select_node(summaryview, node, FALSE, TRUE);
- summary_lock(summaryview);
+ gtk_sctree_select(GTK_SCTREE(ctree), node);
+ gtk_ctree_node_moveto(ctree, node, 0, 0.5, 0);
}
} else {
switch (prefs_common.select_on_entry) {