[gtksourceview/gtksourcecompletion] Implemented asynchronous filtering
- From: Jesse van den Kieboom <jessevdk src gnome org>
- To: svn-commits-list gnome org
- Subject: [gtksourceview/gtksourcecompletion] Implemented asynchronous filtering
- Date: Tue, 21 Apr 2009 18:03:15 -0400 (EDT)
commit e1fc74f4a460002d1eeeffaca3827d44f2e14f0b
Author: Jesse van den Kieboom <jesse icecrew nl>
Date: Wed Apr 22 00:00:59 2009 +0200
Implemented asynchronous filtering
---
gtksourceview/gtksourcecompletion.c | 19 ++--
gtksourceview/gtksourcecompletionmodel.c | 151 ++++++++++++++++++++++++------
gtksourceview/gtksourcecompletionmodel.h | 3 +-
3 files changed, 134 insertions(+), 39 deletions(-)
diff --git a/gtksourceview/gtksourcecompletion.c b/gtksourceview/gtksourcecompletion.c
index cbe42c6..ec99cb6 100644
--- a/gtksourceview/gtksourcecompletion.c
+++ b/gtksourceview/gtksourcecompletion.c
@@ -76,7 +76,6 @@ enum
TEXT_VIEW_BUTTON_PRESS,
TEXT_BUFFER_DELETE_RANGE,
TEXT_BUFFER_INSERT_TEXT,
- ROW_INSERTED,
LAST_EXTERNAL_SIGNAL
};
@@ -120,7 +119,6 @@ struct _GtkSourceCompletionPrivate
gchar *filter_criteria;
gboolean inserting_data;
-
gulong signals_ids[LAST_EXTERNAL_SIGNAL];
};
@@ -1701,9 +1699,11 @@ on_row_inserted_cb (GtkTreeModel *tree_model,
completion->priv->info_visible);
g_signal_emit (completion, signals[SHOW], 0);
-
- g_signal_handler_disconnect (tree_model, completion->priv->signals_ids[ROW_INSERTED]);
}
+
+ gtk_tree_view_scroll_to_point (GTK_TREE_VIEW (completion->priv->tree_view_proposals),
+ 0,
+ 0);
}
static void
@@ -1741,6 +1741,11 @@ initialize_proposals_ui (GtkSourceCompletion *completion)
completion->priv->show_headers);
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (completion->priv->model_proposals));
completion->priv->tree_view_proposals = tree_view;
+
+ g_signal_connect_after (completion->priv->model_proposals,
+ "row-inserted",
+ G_CALLBACK (on_row_inserted_cb),
+ completion);
gtk_tree_view_set_show_expanders (GTK_TREE_VIEW (tree_view), FALSE);
@@ -2029,12 +2034,6 @@ gtk_source_completion_show (GtkSourceCompletion *completion,
completion->priv->active_providers =
g_list_reverse (completion->priv->active_providers);
- completion->priv->signals_ids[ROW_INSERTED] =
- g_signal_connect (completion->priv->model_proposals,
- "row-inserted",
- G_CALLBACK (on_row_inserted_cb),
- completion);
-
return TRUE;
}
diff --git a/gtksourceview/gtksourcecompletionmodel.c b/gtksourceview/gtksourcecompletionmodel.c
index 9c68c31..284d56a 100644
--- a/gtksourceview/gtksourcecompletionmodel.c
+++ b/gtksourceview/gtksourcecompletionmodel.c
@@ -23,6 +23,7 @@
#include "gtksourcecompletionmodel.h"
#define ITEMS_PER_CALLBACK 500
+#define FILTER_PER_CALLBACK 1000
#define GTK_SOURCE_COMPLETION_MODEL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GTK_TYPE_SOURCE_COMPLETION_MODEL, GtkSourceCompletionModelPrivate))
@@ -60,12 +61,18 @@ struct _GtkSourceCompletionModelPrivate
guint idle_id;
GQueue *item_queue;
+
+ guint idle_filter_id;
+
+ GList *next_filter_item;
+ GtkTreeRowReference *next_filter_path;
};
/* Signals */
enum
{
ITEMS_ADDED,
+ FILTER_DONE,
LAST_SIGNAL
};
@@ -441,35 +448,67 @@ free_node (ProposalNode *node)
}
static void
-gtk_source_completion_model_dispose (GObject *object)
+cancel_append (GtkSourceCompletionModel *model)
{
- GtkSourceCompletionModel *model = GTK_SOURCE_COMPLETION_MODEL (object);
-
+ if (model->priv->item_queue != NULL)
+ {
+ g_queue_foreach (model->priv->item_queue,
+ (GFunc)free_node, NULL);
+ g_queue_clear (model->priv->item_queue);
+ }
+
if (model->priv->idle_id != 0)
{
g_source_remove (model->priv->idle_id);
model->priv->idle_id = 0;
+ }
+}
+
+static void
+cancel_refilter (GtkSourceCompletionModel *model)
+{
+ if (model->priv->next_filter_path != NULL)
+ {
+ gtk_tree_row_reference_free (model->priv->next_filter_path);
+ model->priv->next_filter_path = NULL;
}
- if (model->priv->item_queue != NULL)
+ if (model->priv->idle_filter_id != 0)
{
- g_queue_foreach (model->priv->item_queue,
- (GFunc)free_node, NULL);
- g_queue_free (model->priv->item_queue);
+ g_source_remove (model->priv->idle_filter_id);
+ model->priv->idle_filter_id = 0;
- model->priv->item_queue = NULL;
+ g_signal_emit (model, signals[FILTER_DONE], 0);
}
-
- G_OBJECT_CLASS (gtk_source_completion_model_parent_class)->dispose (object);
}
static void
-gtk_source_completion_model_finalize (GObject *object)
+gtk_source_completion_model_dispose (GObject *object)
{
GtkSourceCompletionModel *model = GTK_SOURCE_COMPLETION_MODEL (object);
+
+ cancel_append (model);
+ cancel_refilter (model);
+
+ g_queue_free (model->priv->item_queue);
+ model->priv->item_queue = NULL;
+
+ if (model->priv->num_per_provider != NULL)
+ {
+ g_hash_table_destroy (model->priv->num_per_provider);
+ model->priv->num_per_provider = NULL;
+ }
- g_hash_table_destroy (model->priv->num_per_provider);
+ g_list_foreach (model->priv->store, (GFunc)free_node, NULL);
+ g_list_free (model->priv->store);
+ model->priv->store = NULL;
+ G_OBJECT_CLASS (gtk_source_completion_model_parent_class)->dispose (object);
+}
+
+static void
+gtk_source_completion_model_finalize (GObject *object)
+{
G_OBJECT_CLASS (gtk_source_completion_model_parent_class)->finalize (object);
}
@@ -493,6 +532,18 @@ gtk_source_completion_model_class_init (GtkSourceCompletionModelClass *klass)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
+
+ signals[FILTER_DONE] =
+ g_signal_new ("filter-done",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkSourceCompletionModelClass, filter_done),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
}
static void
@@ -879,10 +930,8 @@ gtk_source_completion_model_clear (GtkSourceCompletionModel *model)
g_return_if_fail (GTK_IS_SOURCE_COMPLETION_MODEL (model));
/* Clear the queue of missing elements to append */
- g_queue_foreach (model->priv->item_queue,
- (GFunc)free_node, NULL);
- g_queue_clear (model->priv->item_queue);
- model->priv->idle_id = 0;
+ cancel_append (model);
+ cancel_refilter (model);
path = gtk_tree_path_new_first ();
list = model->priv->store;
@@ -918,24 +967,31 @@ gtk_source_completion_model_clear (GtkSourceCompletionModel *model)
g_hash_table_remove_all (model->priv->num_per_provider);
}
-void
-gtk_source_completion_model_refilter (GtkSourceCompletionModel *model)
+static gboolean
+idle_refilter (GtkSourceCompletionModel *model)
{
- GList *item;
- GtkSourceCompletionModelFilterFlag filtered;
- ProposalNode *node;
+ guint i = 0;
GtkTreePath *path;
GtkTreeIter iter;
+ ProposalNode *node;
+ GtkSourceCompletionModelFilterFlag filtered;
- g_return_if_fail (GTK_IS_SOURCE_COMPLETION_MODEL (model));
-
- path = gtk_tree_path_new_first ();
+ if (model->priv->next_filter_path)
+ {
+ path = gtk_tree_row_reference_get_path (model->priv->next_filter_path);
+ gtk_tree_row_reference_free (model->priv->next_filter_path);
+ model->priv->next_filter_path = NULL;
+ }
+ else
+ {
+ path = gtk_tree_path_new_first ();
+ }
- for (item = model->priv->store; item != NULL; item = g_list_next (item))
+ while (i < FILTER_PER_CALLBACK && model->priv->next_filter_item != NULL)
{
- iter.user_data = item;
+ iter.user_data = model->priv->next_filter_item;
- node = (ProposalNode *)item->data;
+ node = (ProposalNode *)model->priv->next_filter_item->data;
filtered = node_update_filter_state (model, node);
if ((filtered != 0) == (node->filtered != 0))
@@ -970,10 +1026,49 @@ gtk_source_completion_model_refilter (GtkSourceCompletionModel *model)
gtk_tree_model_row_deleted (GTK_TREE_MODEL (model),
path);
}
+
+ model->priv->next_filter_item = g_list_next (model->priv->next_filter_item);
+ ++i;
}
- gtk_tree_path_free (path);
refilter_headers (model);
+
+ if (model->priv->next_filter_item == NULL)
+ {
+ model->priv->idle_filter_id = 0;
+ gtk_tree_path_free (path);
+
+ g_signal_emit (model, signals[FILTER_DONE], 0);
+
+ return FALSE;
+ }
+
+ if (gtk_tree_path_prev (path))
+ {
+ model->priv->next_filter_path = gtk_tree_row_reference_new (GTK_TREE_MODEL (model),
+ path);
+ }
+
+ gtk_tree_path_free (path);
+
+ return TRUE;
+}
+
+void
+gtk_source_completion_model_refilter (GtkSourceCompletionModel *model)
+{
+ g_return_if_fail (GTK_IS_SOURCE_COMPLETION_MODEL (model));
+
+ /* Cancel any running filter */
+ cancel_refilter (model);
+
+ model->priv->next_filter_item = model->priv->store;
+
+ if (idle_refilter (model))
+ {
+ model->priv->idle_filter_id = g_idle_add ((GSourceFunc)idle_refilter,
+ model);
+ }
}
gboolean
diff --git a/gtksourceview/gtksourcecompletionmodel.h b/gtksourceview/gtksourcecompletionmodel.h
index 5844b5c..b62b3f0 100644
--- a/gtksourceview/gtksourcecompletionmodel.h
+++ b/gtksourceview/gtksourcecompletionmodel.h
@@ -50,7 +50,8 @@ struct _GtkSourceCompletionModel {
struct _GtkSourceCompletionModelClass {
GObjectClass parent_class;
- void (*items_added) (GtkSourceCompletionModel *model);
+ void (*items_added) (GtkSourceCompletionModel *model);
+ void (*filter_done) (GtkSourceCompletionModel *model);
};
typedef enum
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]