[tracker] tracker-search-bar: Make searching interactive with 300ms delay
- From: Martyn James Russell <mr src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker] tracker-search-bar: Make searching interactive with 300ms delay
- Date: Mon, 2 Nov 2009 16:48:27 +0000 (UTC)
commit 19ec7dc0751fbf1c60791683a06a9807266c1dac
Author: Martyn Russell <martyn lanedo com>
Date: Mon Nov 2 16:47:51 2009 +0000
tracker-search-bar: Make searching interactive with 300ms delay
src/tracker-search-bar/tracker-applet.c | 78 +++++++++++++++-----
src/tracker-search-bar/tracker-applet.h | 1 +
src/tracker-search-bar/tracker-results-window.c | 89 ++++++++++++++++++-----
3 files changed, 129 insertions(+), 39 deletions(-)
---
diff --git a/src/tracker-search-bar/tracker-applet.c b/src/tracker-search-bar/tracker-applet.c
index 8c9b395..1ba4cc3 100644
--- a/src/tracker-search-bar/tracker-applet.c
+++ b/src/tracker-search-bar/tracker-applet.c
@@ -78,28 +78,50 @@ applet_event_box_button_press_event_cb (GtkWidget *widget,
}
static void
-applet_entry_activate_cb (GtkEntry *entry,
- TrackerApplet *applet)
+applet_entry_start_search (TrackerApplet *applet)
{
const gchar *text;
- text = gtk_entry_get_text (entry);
- if (strlen (text) < 1) {
- return;
- }
+ text = gtk_entry_get_text (GTK_ENTRY (applet->entry));
- /* Need a better way to do this ? */
- if (applet->results) {
- gtk_widget_destroy (applet->results);
- applet->results = NULL;
+ g_print ("Searching for: '%s'\n", text);
+
+ if (!applet->results) {
+ /* gtk_widget_destroy (applet->results); */
+ /* applet->results = NULL; */
+
+ applet->results = tracker_results_window_new (applet->parent, text);
+
+ tracker_results_window_popup (TRACKER_RESULTS_WINDOW (applet->results));
+ } else {
+ g_object_set (applet->results, "query", text, NULL);
}
+}
- g_print ("Searching for: '%s'\n", text);
- applet->results = tracker_results_window_new (applet->parent, text);
+static gboolean
+applet_entry_start_search_cb (gpointer user_data)
+{
+ TrackerApplet *applet;
+
+ applet = user_data;
+
+ applet->new_search_id = 0;
+
+ applet_entry_start_search (applet);
- gtk_entry_set_text (entry, "");
+ return FALSE;
+}
+
+static void
+applet_entry_activate_cb (GtkEntry *entry,
+ TrackerApplet *applet)
+{
+ if (applet->new_search_id) {
+ g_source_remove (applet->new_search_id);
+ applet->new_search_id = 0;
+ }
- tracker_results_window_popup (TRACKER_RESULTS_WINDOW (applet->results));
+ applet_entry_start_search (applet);
}
static gboolean
@@ -117,17 +139,28 @@ applet_entry_key_press_event_cb (GtkWidget *widget,
GdkEventKey *event,
TrackerApplet *applet)
{
- if (!applet->results) {
- return FALSE;
- }
-
if (event->keyval == GDK_Escape) {
+ if (!applet->results) {
+ return FALSE;
+ }
+
gtk_widget_destroy (applet->results);
applet->results = NULL;
- }
+ } else if (event->keyval == GDK_Down) {
+ if (!applet->results) {
+ return FALSE;
+ }
- if (event->keyval == GDK_Down) {
gtk_widget_grab_focus (applet->results);
+ } else {
+ if (applet->new_search_id) {
+ g_source_remove (applet->new_search_id);
+ }
+
+ applet->new_search_id =
+ g_timeout_add (300,
+ applet_entry_start_search_cb,
+ applet);
}
return FALSE;
@@ -295,6 +328,11 @@ applet_destroy_cb (BonoboObject *object,
applet->idle_draw_id = 0;
}
+ if (applet->new_search_id) {
+ g_source_remove (applet->new_search_id);
+ applet->new_search_id = 0;
+ }
+
g_free (applet);
}
diff --git a/src/tracker-search-bar/tracker-applet.h b/src/tracker-search-bar/tracker-applet.h
index 534b543..6744179 100644
--- a/src/tracker-search-bar/tracker-applet.h
+++ b/src/tracker-search-bar/tracker-applet.h
@@ -38,6 +38,7 @@ typedef struct {
GtkWidget *image;
GtkWidget *entry;
+ guint new_search_id;
guint idle_draw_id;
GtkOrientation orient;
diff --git a/src/tracker-search-bar/tracker-results-window.c b/src/tracker-search-bar/tracker-results-window.c
index d3bc260..cc8aca5 100644
--- a/src/tracker-search-bar/tracker-results-window.c
+++ b/src/tracker-search-bar/tracker-results-window.c
@@ -35,12 +35,14 @@
#include "tracker-results-window.h"
#include "tracker-aligned-window.h"
-#define MUSIC_QUERY "SELECT ?urn ?title ?belongs WHERE { ?urn a nfo:Audio ; nfo:fileName ?title ; nfo:belongsToContainer ?belongs . ?urn fts:match \"%s*\" } ORDER BY DESC(fts:rank(?urn)) OFFSET 0 LIMIT 5"
-#define IMAGE_QUERY "SELECT ?urn ?title ?belongs WHERE { ?urn a nfo:Image ; nfo:fileName ?title ; nfo:belongsToContainer ?belongs . ?urn fts:match \"%s*\" } ORDER BY DESC(fts:rank(?urn)) OFFSET 0 LIMIT 5"
-#define VIDEO_QUERY "SELECT ?urn ?title ?belongs WHERE { ?urn a nmm:Video ; nfo:fileName ?title ; nfo:belongsToContainer ?belongs . ?urn fts:match \"%s*\" } ORDER BY DESC(fts:rank(?urn)) OFFSET 0 LIMIT 5"
-#define DOCUMENT_QUERY "SELECT ?urn ?title ?belongs WHERE { ?urn a nfo:Document ; nfo:fileName ?title ; nfo:belongsToContainer ?belongs . ?urn fts:match \"%s*\" } ORDER BY DESC(fts:rank(?urn)) OFFSET 0 LIMIT 5"
-#define FOLDER_QUERY "SELECT ?urn ?title ?belongs WHERE { ?urn a nfo:Folder ; nfo:fileName ?title ; nfo:belongsToContainer ?belongs . ?urn fts:match \"%s*\" } ORDER BY DESC(fts:rank(?urn)) OFFSET 0 LIMIT 5"
-#define APP_QUERY "SELECT ?urn ?title WHERE { ?urn a nfo:Software ; nie:title ?title . FILTER regex (?title, \"%s\") } ORDER BY ASC(?title) OFFSET 0 LIMIT 5"
+#define MAX_ITEMS 5
+
+#define MUSIC_QUERY "SELECT ?urn ?title ?belongs WHERE { ?urn a nfo:Audio ; nfo:fileName ?title ; nfo:belongsToContainer ?belongs . ?urn fts:match \"%s*\" } ORDER BY DESC(fts:rank(?urn)) OFFSET 0 LIMIT %d"
+#define IMAGE_QUERY "SELECT ?urn ?title ?belongs WHERE { ?urn a nfo:Image ; nfo:fileName ?title ; nfo:belongsToContainer ?belongs . ?urn fts:match \"%s*\" } ORDER BY DESC(fts:rank(?urn)) OFFSET 0 LIMIT %d"
+#define VIDEO_QUERY "SELECT ?urn ?title ?belongs WHERE { ?urn a nmm:Video ; nfo:fileName ?title ; nfo:belongsToContainer ?belongs . ?urn fts:match \"%s*\" } ORDER BY DESC(fts:rank(?urn)) OFFSET 0 LIMIT %d"
+#define DOCUMENT_QUERY "SELECT ?urn ?title ?belongs WHERE { ?urn a nfo:Document ; nfo:fileName ?title ; nfo:belongsToContainer ?belongs . ?urn fts:match \"%s*\" } ORDER BY DESC(fts:rank(?urn)) OFFSET 0 LIMIT %d"
+#define FOLDER_QUERY "SELECT ?urn ?title ?belongs WHERE { ?urn a nfo:Folder ; nfo:fileName ?title ; nfo:belongsToContainer ?belongs . ?urn fts:match \"%s*\" } ORDER BY DESC(fts:rank(?urn)) OFFSET 0 LIMIT %d"
+#define APP_QUERY "SELECT ?urn ?title WHERE { ?urn a nfo:Software ; nie:title ?title . FILTER regex (?title, \"%s\") } ORDER BY ASC(?title) OFFSET 0 LIMIT %d"
#define GENERAL_SEARCH "SELECT ?s ?type ?title WHERE { ?s fts:match \"%s*\" ; rdf:type ?type . OPTIONAL { ?s nie:title ?title } } OFFSET %d LIMIT %d"
@@ -60,6 +62,7 @@ typedef struct {
gchar *query;
gint queries_pending;
+ gint request_id;
} TrackerResultsWindowPrivate;
typedef enum {
@@ -87,6 +90,7 @@ typedef struct {
} ItemData;
typedef struct {
+ gint request_id;
TrackerCategory category;
TrackerResultsWindow *window;
GHashTable *results;
@@ -118,6 +122,8 @@ static void results_window_screen_changed (GtkWidget *widget,
static void model_set_up (TrackerResultsWindow *window);
static void search_get (TrackerResultsWindow *window,
TrackerCategory category);
+static void search_start (TrackerResultsWindow *window);
+
enum {
COL_CATEGORY_ID,
COL_IMAGE,
@@ -157,7 +163,7 @@ tracker_results_window_class_init (TrackerResultsWindowClass *klass)
"Query",
"Query",
NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ G_PARAM_READWRITE));
g_type_class_add_private (object_class, sizeof (TrackerResultsWindowPrivate));
}
@@ -269,18 +275,11 @@ tracker_results_window_init (TrackerResultsWindow *window)
static void
results_window_constructed (GObject *object)
{
- TrackerResultsWindowPrivate *priv;
TrackerResultsWindow *window;
window = TRACKER_RESULTS_WINDOW (object);
- priv = TRACKER_RESULTS_WINDOW_GET_PRIVATE (window);
- search_get (window, CATEGORY_IMAGE);
- search_get (window, CATEGORY_AUDIO);
- search_get (window, CATEGORY_VIDEO);
- search_get (window, CATEGORY_DOCUMENT);
- search_get (window, CATEGORY_FOLDER);
- search_get (window, CATEGORY_APPLICATION);
+ search_start (window);
}
static void
@@ -311,8 +310,12 @@ results_window_set_property (GObject *object,
switch (prop_id) {
case PROP_QUERY:
+ /* Don't do the search_start() call if the window was
+ * just set up.
+ */
g_free (priv->query);
priv->query = g_value_dup_string (value);
+ search_start (TRACKER_RESULTS_WINDOW (object));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -461,13 +464,15 @@ item_data_free (ItemData *id)
}
static SearchQuery *
-search_query_new (TrackerCategory category,
+search_query_new (gint request_id,
+ TrackerCategory category,
TrackerResultsWindow *window)
{
SearchQuery *sq;
sq = g_slice_new0 (SearchQuery);
+ sq->request_id = request_id;
sq->category = category;
sq->window = window;
sq->results = g_hash_table_new_full (g_str_hash,
@@ -743,6 +748,9 @@ model_set_up (TrackerResultsWindow *window)
priv = TRACKER_RESULTS_WINDOW_GET_PRIVATE (window);
view = GTK_TREE_VIEW (priv->treeview);
+ /* View */
+ gtk_tree_view_set_enable_search (view, FALSE);
+
/* Store */
store = gtk_list_store_new (COL_COUNT,
G_TYPE_INT, /* Category ID */
@@ -919,6 +927,15 @@ search_get_cb (GPtrArray *results,
priv = TRACKER_RESULTS_WINDOW_GET_PRIVATE (window);
priv->queries_pending--;
+ /* If request IDs don't match, data is no longer needed */
+ if (priv->request_id != sq->request_id) {
+ g_message ("Received data from request id:%d, now on request id:%d",
+ sq->request_id,
+ priv->request_id);
+ search_query_free (sq);
+ return;
+ }
+
if (error) {
g_printerr ("Could not get search results, %s\n", error->message);
g_error_free (error);
@@ -1001,15 +1018,47 @@ search_get (TrackerResultsWindow *window,
return;
}
- sq = search_query_new (category, window);
+ sq = search_query_new (priv->request_id, category, window);
- sparql = g_strdup_printf (format, priv->query);
+ sparql = g_strdup_printf (format, priv->query, MAX_ITEMS);
tracker_resources_sparql_query_async (priv->client, sparql, search_get_cb, sq);
g_free (sparql);
priv->queries_pending++;
}
+static void
+search_start (TrackerResultsWindow *window)
+{
+ TrackerResultsWindowPrivate *priv;
+ GtkTreeModel *model;
+ GtkListStore *store;
+
+ priv = TRACKER_RESULTS_WINDOW_GET_PRIVATE (window);
+
+ /* Cancel current requests */
+ priv->request_id++;
+ g_message ("Incrementing request ID to %d", priv->request_id);
+
+ /* Clear current data */
+ g_message ("Clearing previous results");
+ model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview));
+ store = GTK_LIST_STORE (model);
+ gtk_list_store_clear (store);
+
+ if (!priv->query || strlen (priv->query) < 1) {
+ return;
+ }
+
+ /* SPARQL requests */
+ search_get (window, CATEGORY_IMAGE);
+ search_get (window, CATEGORY_AUDIO);
+ search_get (window, CATEGORY_VIDEO);
+ search_get (window, CATEGORY_DOCUMENT);
+ search_get (window, CATEGORY_FOLDER);
+ search_get (window, CATEGORY_APPLICATION);
+}
+
static gboolean
grab_popup_window (TrackerResultsWindow *window)
{
@@ -1063,5 +1112,7 @@ tracker_results_window_popup (TrackerResultsWindow *window)
gtk_widget_realize (GTK_WIDGET (window));
gtk_widget_show (GTK_WIDGET (window));
- g_idle_add ((GSourceFunc) grab_popup_window, window);
+ if (0) {
+ g_idle_add ((GSourceFunc) grab_popup_window, window);
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]