[gtksourceview] Implemented per provider priority handling
- From: Jesse van den Kieboom <jessevdk src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtksourceview] Implemented per provider priority handling
- Date: Fri, 1 Jan 2010 22:50:48 +0000 (UTC)
commit bc8772a38be8497c3fbac4a24af7c114242f8709
Author: Jesse van den Kieboom <jesse vandenkieboom epfl ch>
Date: Fri Jan 1 23:04:31 2010 +0100
Implemented per provider priority handling
.../words/gtksourcecompletionwords.c | 33 +++-
gtksourceview/gtksourcecompletionmodel.c | 180 ++++++++++++--------
2 files changed, 135 insertions(+), 78 deletions(-)
---
diff --git a/gtksourceview/completion-providers/words/gtksourcecompletionwords.c b/gtksourceview/completion-providers/words/gtksourcecompletionwords.c
index 905508f..33a89ce 100644
--- a/gtksourceview/completion-providers/words/gtksourcecompletionwords.c
+++ b/gtksourceview/completion-providers/words/gtksourcecompletionwords.c
@@ -44,7 +44,8 @@ enum
PROP_PROPOSALS_BATCH_SIZE,
PROP_SCAN_BATCH_SIZE,
PROP_MINIMUM_WORD_SIZE,
- PROP_INTERACTIVE_DELAY
+ PROP_INTERACTIVE_DELAY,
+ PROP_PRIORITY
};
struct _GtkSourceCompletionWordsPrivate
@@ -69,6 +70,7 @@ struct _GtkSourceCompletionWordsPrivate
GList *buffers;
gint interactive_delay;
+ gint priority;
};
typedef struct
@@ -268,8 +270,8 @@ gtk_source_completion_words_populate (GtkSourceCompletionProvider *provider,
valid_word_char,
valid_start_char,
words);
-
- if (word == NULL ||
+
+ if (word == NULL ||
g_utf8_strlen (word, -1) < words->priv->minimum_word_size)
{
g_free (word);
@@ -412,6 +414,9 @@ gtk_source_completion_words_set_property (GObject *object,
case PROP_INTERACTIVE_DELAY:
self->priv->interactive_delay = g_value_get_int (value);
break;
+ case PROP_PRIORITY:
+ self->priv->priority = g_value_get_int (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -446,6 +451,9 @@ gtk_source_completion_words_get_property (GObject *object,
case PROP_INTERACTIVE_DELAY:
g_value_set_int (value, self->priv->interactive_delay);
break;
+ case PROP_PRIORITY:
+ g_value_set_int (value, self->priv->priority);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -517,7 +525,17 @@ gtk_source_completion_words_class_init (GtkSourceCompletionWordsClass *klass)
G_MAXINT,
50,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-
+
+ g_object_class_install_property (object_class,
+ PROP_PRIORITY,
+ g_param_spec_int ("priority",
+ _("Priority"),
+ _("Provider priority"),
+ G_MININT,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
g_type_class_add_private (object_class, sizeof(GtkSourceCompletionWordsPrivate));
}
@@ -548,6 +566,12 @@ gtk_source_completion_words_get_interactive_delay (GtkSourceCompletionProvider *
return GTK_SOURCE_COMPLETION_WORDS (provider)->priv->interactive_delay;
}
+static gint
+gtk_source_completion_words_get_priority (GtkSourceCompletionProvider *provider)
+{
+ return GTK_SOURCE_COMPLETION_WORDS (provider)->priv->priority;
+}
+
static void
gtk_source_completion_words_iface_init (GtkSourceCompletionProviderIface *iface)
{
@@ -559,6 +583,7 @@ gtk_source_completion_words_iface_init (GtkSourceCompletionProviderIface *iface)
iface->get_start_iter = gtk_source_completion_words_get_start_iter;
iface->get_interactive_delay = gtk_source_completion_words_get_interactive_delay;
+ iface->get_priority = gtk_source_completion_words_get_priority;
}
static void
diff --git a/gtksourceview/gtksourcecompletionmodel.c b/gtksourceview/gtksourcecompletionmodel.c
index 0f044a3..1e0c3be 100644
--- a/gtksourceview/gtksourcecompletionmodel.c
+++ b/gtksourceview/gtksourcecompletionmodel.c
@@ -722,7 +722,7 @@ insert_node (GtkSourceCompletionModel *model,
node->provider = info->provider;
node->changed_id = 0;
node->mark = model->priv->marking;
- node->filtered = info->filtered;
+ node->filtered = info->filtered || (!proposal && !model->priv->show_headers);
if (position == NULL)
{
@@ -756,12 +756,12 @@ insert_node (GtkSourceCompletionModel *model,
item = g_list_previous (position);
- if (info->first == position)
+ if (!info->first || info->first == position)
{
info->first = item;
}
- if (info->last->next == item)
+ if (!info->last || info->last->next == item)
{
info->last = item;
}
@@ -781,34 +781,10 @@ insert_node (GtkSourceCompletionModel *model,
if (proposal != NULL)
{
- node->changed_id = g_signal_connect (node->proposal,
- "changed",
- G_CALLBACK (on_proposal_changed),
- item);
- }
-}
-
-static void
-insert_header (GtkSourceCompletionModel *model,
- ProviderInfo *info)
-{
- if (info == NULL)
- {
- return;
- }
-
- if (info->first != NULL)
- {
- /* Insert header just before 'first' */
- insert_node (model, info, info->first, NULL, NULL);
- }
- else
- {
- /* Just append the header after the last current item */
- insert_node (model, info, g_list_next (model->priv->last), NULL, NULL);
-
- info->first = model->priv->last;
- info->last = model->priv->last;
+ node->changed_id = g_signal_connect (node->proposal,
+ "changed",
+ G_CALLBACK (on_proposal_changed),
+ item);
}
}
@@ -885,7 +861,7 @@ remove_node (GtkSourceCompletionModel *model,
gtk_tree_path_free (ppath);
}
- proposal_node_free (node);
+ proposal_node_free (node);
}
static void
@@ -893,13 +869,23 @@ update_header_visibility_each (GtkSourceCompletionProvider *provider,
ProviderInfo *info,
GtkSourceCompletionModel *model)
{
+ ProposalNode *header_node = info->first->data;
+
+ /* Check if the header is already in the correct visibility state */
+ if (info->filtered || model->priv->show_headers != header_node->filtered)
+ {
+ return;
+ }
+
if (model->priv->show_headers)
{
- insert_header (model, info);
+ header_node->filtered = FALSE;
+ handle_row_inserted (model, info->first, NULL);
}
else
{
- remove_node (model, info, info->first, NULL);
+ header_node->filtered = TRUE;
+ handle_row_deleted (model, info->first, NULL);
}
}
@@ -918,35 +904,32 @@ update_provider_visibility_show_hide (GtkSourceCompletionModel *model,
{
GList *item;
GtkTreePath *path = NULL;
-
+
item = info->first;
info->filtered = !show;
-
+
while (item)
{
ProposalNode *node = (ProposalNode *)item->data;
-
- if (node->proposal != NULL || model->priv->show_headers)
- {
- node->filtered = !show;
- if (path == NULL)
- {
- path = path_from_list (model, item);
- }
+ node->filtered = !show;
- if (show)
- {
- ++model->priv->num;
+ if (path == NULL)
+ {
+ path = path_from_list (model, item);
+ }
- handle_row_inserted (model, item, &path);
- gtk_tree_path_next (path);
- }
- else
- {
- --model->priv->num;
- handle_row_deleted (model, item, &path);
- }
+ if (show)
+ {
+ ++model->priv->num;
+
+ handle_row_inserted (model, item, &path);
+ gtk_tree_path_next (path);
+ }
+ else
+ {
+ --model->priv->num;
+ handle_row_deleted (model, item, &path);
}
if (item == info->last)
@@ -1060,35 +1043,84 @@ remove_unmarked (GtkSourceCompletionModel *model,
return ret;
}
+static GList *
+insert_provider (GtkSourceCompletionModel *model,
+ GtkSourceCompletionProvider *provider)
+{
+ GList *providers = model->priv->providers;
+ gint priority;
+ GList *last = NULL;
+
+ /* We do this manually to at the same time determine the position
+ at which the new provider is inserted */
+ if (providers == NULL)
+ {
+ model->priv->providers = g_list_prepend (NULL, provider);
+ return model->priv->providers;
+ }
+
+ priority = gtk_source_completion_provider_get_priority (provider);
+
+ while (providers)
+ {
+ GtkSourceCompletionProvider *current = providers->data;
+ gint current_prio = gtk_source_completion_provider_get_priority (current);
+
+ if (priority >= current_prio)
+ {
+ /* Insert before */
+ model->priv->providers = g_list_insert_before (model->priv->providers,
+ providers,
+ provider);
+
+ return providers->prev;
+ }
+
+ last = providers;
+ providers = g_list_next (providers);
+ }
+
+ /* Insert after */
+ last = g_list_append (last, provider);
+ return last->next;
+}
+
static ProviderInfo *
add_provider_info (GtkSourceCompletionModel *model,
GtkSourceCompletionProvider *provider)
{
ProviderInfo *info;
-
+ GList *pos;
+ GList *before = NULL;
+
info = g_slice_new0 (ProviderInfo);
info->provider = provider;
- info->proposals = g_hash_table_new ((GHashFunc)gtk_source_completion_proposal_hash,
+ info->proposals = g_hash_table_new ((GHashFunc)gtk_source_completion_proposal_hash,
(GEqualFunc)gtk_source_completion_proposal_equal);
info->filtered = !provider_is_visible (model, provider);
+ info->first_batch = TRUE;
- g_hash_table_insert (model->priv->providers_info,
- g_object_ref (provider),
- info);
-
- if (model->priv->show_headers && !info->filtered)
- {
- insert_header (model, info);
- }
- else
+ g_hash_table_insert (model->priv->providers_info,
+ g_object_ref (provider),
+ info);
+
+ /* Insert the provider sorted on the priority */
+ pos = insert_provider (model, provider);
+
+ /* Insert the header node */
+ if (pos->next)
{
- info->first = info->last = NULL;
+ ProviderInfo *next = g_hash_table_lookup (model->priv->providers_info,
+ pos->next->data);
+
+ if (next)
+ {
+ before = next->first;
+ }
}
-
- model->priv->providers = g_list_append (model->priv->providers,
- provider);
+ insert_node (model, info, before, NULL, NULL);
return info;
}
@@ -1104,14 +1136,14 @@ gtk_source_completion_model_append (GtkSourceCompletionModel *model,
g_return_if_fail (GTK_IS_SOURCE_COMPLETION_MODEL (model));
g_return_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider));
-
+
if (proposals == NULL || !GTK_IS_SOURCE_COMPLETION_PROPOSAL (proposals->data))
{
return;
}
-
+
info = g_hash_table_lookup (model->priv->providers_info, provider);
-
+
if (!info)
{
/* First batch for 'provider', add provider info */
@@ -1320,7 +1352,7 @@ gtk_source_completion_model_n_proposals (GtkSourceCompletionModel *model,
void
gtk_source_completion_model_set_show_headers (GtkSourceCompletionModel *model,
- gboolean show_headers)
+ gboolean show_headers)
{
g_return_if_fail (GTK_IS_SOURCE_COMPLETION_MODEL (model));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]