[gtksourceview/wip/completion: 1/4] Completion: split the code into sections
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtksourceview/wip/completion: 1/4] Completion: split the code into sections
- Date: Mon, 11 Mar 2013 18:25:40 +0000 (UTC)
commit b47b7c06cc138a858d6e7d17bb2a498ca6e2bc85
Author: Sébastien Wilmet <swilmet gnome org>
Date: Wed Feb 27 20:55:54 2013 +0100
Completion: split the code into sections
The sections:
- Utilities functions
- Show, hide and activate
- Info window
- Switch between providers
- Accelerators to activate the first proposals
- Various callbacks
- Handle population
- Properties, construction and destruction
- Public or non-static functions
A section is displayed like:
/**********
* Section
**********/
gtksourceview/gtksourcecompletion.c | 1030 ++++++++++++++++++-----------------
1 files changed, 532 insertions(+), 498 deletions(-)
---
diff --git a/gtksourceview/gtksourcecompletion.c b/gtksourceview/gtksourcecompletion.c
index 1a83e0a..f2e0160 100644
--- a/gtksourceview/gtksourcecompletion.c
+++ b/gtksourceview/gtksourcecompletion.c
@@ -126,9 +126,7 @@ enum
PROP_SHOW_HEADERS,
PROP_SHOW_ICONS,
PROP_ACCELERATORS,
-
PROP_AUTO_COMPLETE_DELAY,
-
PROP_PROVIDER_PAGE_SIZE,
PROP_PROPOSAL_PAGE_SIZE
};
@@ -205,84 +203,38 @@ static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE(GtkSourceCompletion, gtk_source_completion, G_TYPE_OBJECT)
-static void
-reset_completion (GtkSourceCompletion *completion)
-{
- if (completion->priv->show_timed_out_id != 0)
- {
- g_source_remove (completion->priv->show_timed_out_id);
- completion->priv->show_timed_out_id = 0;
- }
-
- if (completion->priv->context != NULL)
- {
- /* Inform providers of cancellation through the context */
- _gtk_source_completion_context_cancel (completion->priv->context);
-
- g_clear_object (&completion->priv->context);
- }
-
- g_list_free (completion->priv->running_providers);
- g_list_free (completion->priv->active_providers);
- completion->priv->running_providers = NULL;
- completion->priv->active_providers = NULL;
-}
+/**********************
+ * Utilities functions
+ **********************/
static void
-replace_model (GtkSourceCompletion *completion)
+scroll_to_iter (GtkSourceCompletion *completion,
+ GtkTreeIter *iter)
{
- if (completion->priv->model_proposals != NULL)
+ GtkTreePath *path;
+ GtkTreeIter prev_iter = *iter;
+
+ /* If we want to scroll to the first proposal of a provider, it's better
+ * to show the header too, if there is a header. */
+ if (gtk_source_completion_model_iter_previous (completion->priv->model_proposals, &prev_iter) &&
+ gtk_source_completion_model_iter_is_header (completion->priv->model_proposals, &prev_iter))
{
- g_object_unref (completion->priv->model_proposals);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (completion->priv->model_proposals),
+ &prev_iter);
}
-
- completion->priv->model_proposals = gtk_source_completion_model_new ();
-
- gtk_source_completion_model_set_show_headers (completion->priv->model_proposals,
- completion->priv->show_headers);
-}
-
-/* Takes ownership of @providers and @context. */
-static void
-update_completion (GtkSourceCompletion *completion,
- GList *providers,
- GtkSourceCompletionContext *context)
-{
- GList *item;
-
- /* Copy the parameters, because they can be freed by reset_completion(). */
- GList *providers_copy = g_list_copy (providers);
- GtkSourceCompletionContext *context_copy = g_object_ref_sink (context);
-
- DEBUG({
- g_print ("Update completion: %d\n", g_list_length (providers));
- });
-
- /* Make sure to first cancel any running completion */
- reset_completion (completion);
-
- completion->priv->context = context_copy;
- completion->priv->running_providers = g_list_copy (providers_copy);
- completion->priv->active_providers = g_list_copy (providers_copy);
-
- /* Create a new CompletionModel */
- gtk_tree_view_set_model (completion->priv->tree_view_proposals, NULL);
- replace_model (completion);
-
- for (item = providers_copy; item != NULL; item = g_list_next (item))
+ else
{
- GtkSourceCompletionProvider *provider = item->data;
-
- DEBUG({
- gchar *temp_name = gtk_source_completion_provider_get_name (provider);
- g_print ("Populating provider: %s\n", temp_name);
- g_free (temp_name);
- });
-
- gtk_source_completion_provider_populate (provider, context_copy);
+ path = gtk_tree_model_get_path (GTK_TREE_MODEL (completion->priv->model_proposals),
+ iter);
}
- g_list_free (providers_copy);
+ gtk_tree_view_scroll_to_cell (completion->priv->tree_view_proposals,
+ path,
+ NULL,
+ FALSE,
+ 0,
+ 0);
+ gtk_tree_path_free (path);
}
/* Returns %TRUE if a proposal is selected.
@@ -326,6 +278,28 @@ get_selected_proposal (GtkSourceCompletion *completion,
}
static void
+check_first_selected (GtkSourceCompletion *completion)
+{
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+
+ if (get_selected_proposal (completion, NULL, NULL) ||
+ !completion->priv->select_on_show)
+ {
+ return;
+ }
+
+ if (!gtk_source_completion_model_first_proposal (completion->priv->model_proposals, &iter))
+ {
+ return;
+ }
+
+ selection = gtk_tree_view_get_selection (completion->priv->tree_view_proposals);
+ gtk_tree_selection_select_iter (selection, &iter);
+ scroll_to_iter (completion, &iter);
+}
+
+static void
get_iter_at_insert (GtkSourceCompletion *completion,
GtkTextIter *iter)
{
@@ -337,6 +311,154 @@ get_iter_at_insert (GtkSourceCompletion *completion,
gtk_text_buffer_get_insert (buffer));
}
+static GList *
+select_providers (GList *providers,
+ GtkSourceCompletionContext *context)
+{
+ GList *selection = NULL;
+
+ while (providers != NULL)
+ {
+ GtkSourceCompletionProvider *provider = providers->data;
+
+ if (gtk_source_completion_provider_match (provider, context))
+ {
+ selection = g_list_prepend (selection, provider);
+ }
+
+ providers = g_list_next (providers);
+ }
+
+ return g_list_reverse (selection);
+}
+
+static gint
+minimum_auto_complete_delay (GtkSourceCompletion *completion,
+ GList *providers)
+{
+ gint min_delay = completion->priv->auto_complete_delay;
+
+ while (providers != NULL)
+ {
+ GtkSourceCompletionProvider *provider = providers->data;
+ gint delay = gtk_source_completion_provider_get_interactive_delay (provider);
+
+ if (0 <= delay && delay < min_delay)
+ {
+ min_delay = delay;
+ }
+
+ providers = g_list_next (providers);
+ }
+
+ return min_delay;
+}
+
+static void
+reset_completion (GtkSourceCompletion *completion)
+{
+ if (completion->priv->show_timed_out_id != 0)
+ {
+ g_source_remove (completion->priv->show_timed_out_id);
+ completion->priv->show_timed_out_id = 0;
+ }
+
+ if (completion->priv->context != NULL)
+ {
+ /* Inform providers of cancellation through the context */
+ _gtk_source_completion_context_cancel (completion->priv->context);
+
+ g_clear_object (&completion->priv->context);
+ }
+
+ g_list_free (completion->priv->running_providers);
+ g_list_free (completion->priv->active_providers);
+ completion->priv->running_providers = NULL;
+ completion->priv->active_providers = NULL;
+}
+
+static void
+update_window_position (GtkSourceCompletion *completion)
+{
+ GtkSourceCompletionProvider *provider;
+ GtkSourceCompletionProposal *proposal;
+
+ if (get_selected_proposal (completion, &provider, &proposal))
+ {
+ GtkTextIter iter;
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (completion->priv->view));
+
+ gtk_text_buffer_get_start_iter (buffer, &iter);
+
+ if (gtk_source_completion_provider_get_start_iter (provider,
+ completion->priv->context,
+ proposal,
+ &iter))
+ {
+ gtk_source_completion_utils_move_to_iter (completion->priv->main_window,
+ GTK_SOURCE_VIEW (completion->priv->view),
+ &iter);
+ }
+
+ g_object_unref (provider);
+ g_object_unref (proposal);
+ }
+}
+
+static void
+update_tree_view_visibility (GtkSourceCompletion *completion)
+{
+ gtk_tree_view_column_set_visible (completion->priv->tree_view_column_accelerator,
+ completion->priv->num_accelerators > 0);
+
+ g_object_set (completion->priv->cell_renderer_icon,
+ "visible", completion->priv->show_icons,
+ NULL);
+}
+
+/**************************
+ * Show, hide and activate
+ **************************/
+
+static void
+gtk_source_completion_show_default (GtkSourceCompletion *completion)
+{
+ /* Move completion window */
+ if (completion->priv->context != NULL)
+ {
+ GtkTextIter location;
+ gtk_source_completion_context_get_iter (completion->priv->context,
+ &location);
+
+ gtk_source_completion_utils_move_to_iter (completion->priv->main_window,
+ GTK_SOURCE_VIEW (completion->priv->view),
+ &location);
+ }
+
+ gtk_widget_show (GTK_WIDGET (completion->priv->main_window));
+
+ if (completion->priv->remember_info_visibility)
+ {
+ if (gtk_toggle_button_get_active (completion->priv->info_button))
+ {
+ gtk_widget_show (GTK_WIDGET (completion->priv->info_window));
+ }
+ }
+ else
+ {
+ gtk_toggle_button_set_active (completion->priv->info_button, FALSE);
+ }
+
+ gtk_widget_grab_focus (GTK_WIDGET (completion->priv->view));
+}
+
+static void
+gtk_source_completion_hide_default (GtkSourceCompletion *completion)
+{
+ gtk_widget_hide (GTK_WIDGET (completion->priv->info_window));
+ gtk_widget_hide (GTK_WIDGET (completion->priv->main_window));
+}
+
static void
gtk_source_completion_activate_proposal (GtkSourceCompletion *completion)
{
@@ -390,99 +512,113 @@ gtk_source_completion_activate_proposal (GtkSourceCompletion *completion)
g_object_unref (proposal);
}
+/**************
+ * Info window
+ **************/
+
static void
-scroll_to_iter (GtkSourceCompletion *completion,
- GtkTreeIter *iter)
+set_info_widget (GtkSourceCompletion *completion,
+ GtkWidget *new_widget)
{
- GtkTreePath *path;
- GtkTreeIter prev_iter = *iter;
+ GtkWidget *cur_widget = gtk_bin_get_child (GTK_BIN (completion->priv->info_window));
- /* If we want to scroll to the first proposal of a provider, it's better
- * to show the header too, if there is a header. */
- if (gtk_source_completion_model_iter_previous (completion->priv->model_proposals, &prev_iter) &&
- gtk_source_completion_model_iter_is_header (completion->priv->model_proposals, &prev_iter))
+ if (cur_widget == new_widget)
{
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (completion->priv->model_proposals),
- &prev_iter);
+ return;
}
- else
+
+ if (cur_widget != NULL)
{
- path = gtk_tree_model_get_path (GTK_TREE_MODEL (completion->priv->model_proposals),
- iter);
+ gtk_container_remove (GTK_CONTAINER (completion->priv->info_window), cur_widget);
}
- gtk_tree_view_scroll_to_cell (completion->priv->tree_view_proposals,
- path,
- NULL,
- FALSE,
- 0,
- 0);
- gtk_tree_path_free (path);
+ gtk_container_add (GTK_CONTAINER (completion->priv->info_window), new_widget);
}
-static gboolean
-get_previous_iter (GtkSourceCompletion *completion,
- gint num,
- GtkTreeIter *iter)
+static void
+update_info_position (GtkSourceCompletion *completion)
{
- GtkTreeSelection *selection;
- gboolean has_selection;
+ GdkScreen *screen;
+ gint x, y;
+ gint width, height;
+ gint screen_width;
+ gint info_width;
- selection = gtk_tree_view_get_selection (completion->priv->tree_view_proposals);
- has_selection = gtk_tree_selection_get_selected (selection, NULL, iter);
+ gtk_window_get_position (completion->priv->main_window, &x, &y);
+ gtk_window_get_size (completion->priv->main_window, &width, &height);
+ gtk_window_get_size (GTK_WINDOW (completion->priv->info_window), &info_width, NULL);
- if (!has_selection)
+ screen = gtk_window_get_screen (completion->priv->main_window);
+ screen_width = gdk_screen_get_width (screen);
+
+ /* Determine on which side to place it */
+ if (x + width + info_width >= screen_width)
{
- return gtk_source_completion_model_last_proposal (completion->priv->model_proposals,
- iter);
+ x -= info_width;
}
-
- while (num > 0)
+ else
{
- if (!gtk_source_completion_model_previous_proposal (completion->priv->model_proposals,
- iter))
- {
- return gtk_source_completion_model_first_proposal (completion->priv->model_proposals,
- iter);
- }
-
- num--;
+ x += width;
}
- return TRUE;
+ gtk_window_move (GTK_WINDOW (completion->priv->info_window), x, y);
}
-static gboolean
-get_next_iter (GtkSourceCompletion *completion,
- gint num,
- GtkTreeIter *iter)
+static void
+update_proposal_info (GtkSourceCompletion *completion)
{
- GtkTreeSelection *selection;
- gboolean has_selection;
-
- selection = gtk_tree_view_get_selection (completion->priv->tree_view_proposals);
- has_selection = gtk_tree_selection_get_selected (selection, NULL, iter);
+ GtkSourceCompletionProvider *provider = NULL;
+ GtkSourceCompletionProposal *proposal = NULL;
+ GtkWidget *info_widget;
- if (!has_selection)
+ if (!get_selected_proposal (completion, &provider, &proposal))
{
- return gtk_source_completion_model_first_proposal (completion->priv->model_proposals,
- iter);
+ set_info_widget (completion, GTK_WIDGET (completion->priv->default_info));
+
+ gtk_label_set_markup (completion->priv->default_info,
+ _("No extra information available"));
+
+ return;
}
- while (num > 0)
+ info_widget = gtk_source_completion_provider_get_info_widget (provider, proposal);
+
+ if (info_widget != NULL)
{
- if (!gtk_source_completion_model_next_proposal (completion->priv->model_proposals, iter))
+ set_info_widget (completion, info_widget);
+
+ gtk_source_completion_provider_update_info (provider,
+ proposal,
+ completion->priv->info_window);
+ }
+ else
+ {
+ gchar *text;
+
+ set_info_widget (completion, GTK_WIDGET (completion->priv->default_info));
+
+ text = gtk_source_completion_proposal_get_info (proposal);
+
+ if (text != NULL)
{
- return gtk_source_completion_model_last_proposal (completion->priv->model_proposals,
- iter);
+ gtk_label_set_markup (completion->priv->default_info, text);
+ g_free (text);
+ }
+ else
+ {
+ gtk_label_set_markup (completion->priv->default_info,
+ _("No extra information available"));
}
-
- num--;
}
- return TRUE;
+ g_object_unref (provider);
+ g_object_unref (proposal);
}
+/***************************
+ * Switch between providers
+ ***************************/
+
static GtkSourceCompletionProvider *
get_visible_provider (GtkSourceCompletion *completion)
{
@@ -560,170 +696,71 @@ update_selection_label (GtkSourceCompletion *completion)
gtk_label_set_markup (completion->priv->selection_label, tmp);
g_free (tmp);
}
-
- g_free (name);
-}
-
-static void
-update_info_position (GtkSourceCompletion *completion)
-{
- GdkScreen *screen;
- gint x, y;
- gint width, height;
- gint screen_width;
- gint info_width;
-
- gtk_window_get_position (completion->priv->main_window, &x, &y);
- gtk_window_get_size (completion->priv->main_window, &width, &height);
- gtk_window_get_size (GTK_WINDOW (completion->priv->info_window), &info_width, NULL);
-
- screen = gtk_window_get_screen (completion->priv->main_window);
- screen_width = gdk_screen_get_width (screen);
-
- /* Determine on which side to place it */
- if (x + width + info_width >= screen_width)
- {
- x -= info_width;
- }
- else
- {
- x += width;
- }
-
- gtk_window_move (GTK_WINDOW (completion->priv->info_window), x, y);
-}
-
-static void
-set_info_widget (GtkSourceCompletion *completion,
- GtkWidget *new_widget)
-{
- GtkWidget *cur_widget = gtk_bin_get_child (GTK_BIN (completion->priv->info_window));
-
- if (cur_widget == new_widget)
- {
- return;
- }
-
- if (cur_widget != NULL)
- {
- gtk_container_remove (GTK_CONTAINER (completion->priv->info_window), cur_widget);
- }
-
- gtk_container_add (GTK_CONTAINER (completion->priv->info_window), new_widget);
-}
-
-static void
-update_proposal_info (GtkSourceCompletion *completion)
-{
- GtkSourceCompletionProvider *provider = NULL;
- GtkSourceCompletionProposal *proposal = NULL;
- GtkWidget *info_widget;
-
- if (!get_selected_proposal (completion, &provider, &proposal))
- {
- set_info_widget (completion, GTK_WIDGET (completion->priv->default_info));
-
- gtk_label_set_markup (completion->priv->default_info,
- _("No extra information available"));
-
- return;
- }
-
- info_widget = gtk_source_completion_provider_get_info_widget (provider, proposal);
-
- if (info_widget != NULL)
- {
- set_info_widget (completion, info_widget);
-
- gtk_source_completion_provider_update_info (provider,
- proposal,
- completion->priv->info_window);
- }
- else
- {
- gchar *text;
-
- set_info_widget (completion, GTK_WIDGET (completion->priv->default_info));
-
- text = gtk_source_completion_proposal_get_info (proposal);
-
- if (text != NULL)
- {
- gtk_label_set_markup (completion->priv->default_info, text);
- g_free (text);
- }
- else
- {
- gtk_label_set_markup (completion->priv->default_info,
- _("No extra information available"));
- }
- }
-
- g_object_unref (provider);
- g_object_unref (proposal);
+
+ g_free (name);
}
-static void
-update_window_position (GtkSourceCompletion *completion)
+static gboolean
+get_next_iter (GtkSourceCompletion *completion,
+ gint num,
+ GtkTreeIter *iter)
{
- GtkSourceCompletionProvider *provider;
- GtkSourceCompletionProposal *proposal;
+ GtkTreeSelection *selection;
+ gboolean has_selection;
- if (get_selected_proposal (completion, &provider, &proposal))
- {
- GtkTextIter iter;
- GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (completion->priv->view));
+ selection = gtk_tree_view_get_selection (completion->priv->tree_view_proposals);
+ has_selection = gtk_tree_selection_get_selected (selection, NULL, iter);
- gtk_text_buffer_get_start_iter (buffer, &iter);
+ if (!has_selection)
+ {
+ return gtk_source_completion_model_first_proposal (completion->priv->model_proposals,
+ iter);
+ }
- if (gtk_source_completion_provider_get_start_iter (provider,
- completion->priv->context,
- proposal,
- &iter))
+ while (num > 0)
+ {
+ if (!gtk_source_completion_model_next_proposal (completion->priv->model_proposals, iter))
{
- gtk_source_completion_utils_move_to_iter (completion->priv->main_window,
- GTK_SOURCE_VIEW (completion->priv->view),
- &iter);
+ return gtk_source_completion_model_last_proposal (completion->priv->model_proposals,
+ iter);
}
- g_object_unref (provider);
- g_object_unref (proposal);
+ num--;
}
-}
-static void
-selection_changed_cb (GtkTreeSelection *selection,
- GtkSourceCompletion *completion)
-{
- update_proposal_info (completion);
- update_window_position (completion);
+ return TRUE;
}
static gboolean
-gtk_source_completion_configure_event (GtkWidget *widget,
- GdkEventConfigure *event,
- GtkSourceCompletion *completion)
+get_previous_iter (GtkSourceCompletion *completion,
+ gint num,
+ GtkTreeIter *iter)
{
- update_info_position (completion);
- return FALSE;
-}
+ GtkTreeSelection *selection;
+ gboolean has_selection;
-static void
-update_tree_view_visibility (GtkSourceCompletion *completion)
-{
- gtk_tree_view_column_set_visible (completion->priv->tree_view_column_accelerator,
- completion->priv->num_accelerators > 0);
+ selection = gtk_tree_view_get_selection (completion->priv->tree_view_proposals);
+ has_selection = gtk_tree_selection_get_selected (selection, NULL, iter);
- g_object_set (completion->priv->cell_renderer_icon,
- "visible", completion->priv->show_icons,
- NULL);
-}
+ if (!has_selection)
+ {
+ return gtk_source_completion_model_last_proposal (completion->priv->model_proposals,
+ iter);
+ }
-static gboolean
-hide_completion_cb (GtkSourceCompletion *completion)
-{
- gtk_source_completion_hide (completion);
- return FALSE;
+ while (num > 0)
+ {
+ if (!gtk_source_completion_model_previous_proposal (completion->priv->model_proposals,
+ iter))
+ {
+ return gtk_source_completion_model_first_proposal (completion->priv->model_proposals,
+ iter);
+ }
+
+ num--;
+ }
+
+ return TRUE;
}
static void
@@ -775,28 +812,6 @@ gtk_source_completion_move_cursor (GtkSourceCompletion *completion,
}
}
-static void
-check_first_selected (GtkSourceCompletion *completion)
-{
- GtkTreeSelection *selection;
- GtkTreeIter iter;
-
- if (get_selected_proposal (completion, NULL, NULL) ||
- !completion->priv->select_on_show)
- {
- return;
- }
-
- if (!gtk_source_completion_model_first_proposal (completion->priv->model_proposals, &iter))
- {
- return;
- }
-
- selection = gtk_tree_view_get_selection (completion->priv->tree_view_proposals);
- gtk_tree_selection_select_iter (selection, &iter);
- scroll_to_iter (completion, &iter);
-}
-
static GList *
get_last_provider (GtkSourceCompletion *completion)
{
@@ -984,6 +999,65 @@ gtk_source_completion_move_page (GtkSourceCompletion *completion,
g_list_free (visible_providers);
}
+/***********************************************
+ * Accelerators to activate the first proposals
+ ***********************************************/
+
+/* Begins at 0. Returns -1 if no accelerators available for @iter. */
+static gint
+get_accel_at_iter (GtkSourceCompletion *completion,
+ GtkTreeIter *iter)
+{
+ GtkTreeIter it;
+ gint accel;
+
+ if (gtk_source_completion_model_iter_is_header (completion->priv->model_proposals, iter))
+ {
+ return -1;
+ }
+
+ if (!gtk_source_completion_model_first_proposal (completion->priv->model_proposals, &it))
+ {
+ g_return_val_if_reached (-1);
+ }
+
+ for (accel = 0; accel < completion->priv->num_accelerators; accel++)
+ {
+ if (gtk_source_completion_model_iter_equal (completion->priv->model_proposals,
+ iter,
+ &it))
+ {
+ return accel;
+ }
+
+ if (!gtk_source_completion_model_next_proposal (completion->priv->model_proposals, &it))
+ {
+ return -1;
+ }
+ }
+
+ return -1;
+}
+
+static void
+render_proposal_accelerator_func (GtkTreeViewColumn *column,
+ GtkCellRenderer *cell,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GtkSourceCompletion *completion)
+{
+ gint accel = get_accel_at_iter (completion, iter);
+ gchar *text = NULL;
+
+ if (accel != -1)
+ {
+ text = g_strdup_printf ("<small><b>%d</b></small>", (accel + 1) % 10);
+ }
+
+ g_object_set (cell, "markup", text, NULL);
+ g_free (text);
+}
+
static gboolean
activate_by_accelerator (GtkSourceCompletion *completion,
gint num)
@@ -1024,6 +1098,34 @@ activate_by_accelerator (GtkSourceCompletion *completion,
return TRUE;
}
+/********************
+ * Various callbacks
+ ********************/
+
+static void
+selection_changed_cb (GtkTreeSelection *selection,
+ GtkSourceCompletion *completion)
+{
+ update_proposal_info (completion);
+ update_window_position (completion);
+}
+
+static gboolean
+gtk_source_completion_configure_event (GtkWidget *widget,
+ GdkEventConfigure *event,
+ GtkSourceCompletion *completion)
+{
+ update_info_position (completion);
+ return FALSE;
+}
+
+static gboolean
+hide_completion_cb (GtkSourceCompletion *completion)
+{
+ gtk_source_completion_hide (completion);
+ return FALSE;
+}
+
static gboolean
view_key_press_event_cb (GtkSourceView *view,
GdkEventKey *event,
@@ -1084,25 +1186,86 @@ view_key_press_event_cb (GtkSourceView *view,
return FALSE;
}
-static GList *
-select_providers (GList *providers,
- GtkSourceCompletionContext *context)
+static void
+buffer_mark_set_cb (GtkTextBuffer *buffer,
+ GtkTextIter *iter,
+ GtkTextMark *mark,
+ GtkSourceCompletion *completion)
{
- GList *selection = NULL;
+ if (mark == gtk_text_buffer_get_insert (buffer))
+ {
+ gtk_source_completion_hide (completion);
+ }
+}
+
+static void
+update_transient_for_info (GObject *window,
+ GParamSpec *spec,
+ GtkSourceCompletion *completion)
+{
+ gtk_window_set_transient_for (GTK_WINDOW (completion->priv->info_window),
+ gtk_window_get_transient_for (completion->priv->main_window));
+}
+
+/********************
+ * Handle population
+ ********************/
+
+static void
+replace_model (GtkSourceCompletion *completion)
+{
+ if (completion->priv->model_proposals != NULL)
+ {
+ g_object_unref (completion->priv->model_proposals);
+ }
+
+ completion->priv->model_proposals = gtk_source_completion_model_new ();
+
+ gtk_source_completion_model_set_show_headers (completion->priv->model_proposals,
+ completion->priv->show_headers);
+}
+
+/* Takes ownership of @providers and @context. */
+static void
+update_completion (GtkSourceCompletion *completion,
+ GList *providers,
+ GtkSourceCompletionContext *context)
+{
+ GList *item;
+
+ /* Copy the parameters, because they can be freed by reset_completion(). */
+ GList *providers_copy = g_list_copy (providers);
+ GtkSourceCompletionContext *context_copy = g_object_ref_sink (context);
+
+ DEBUG({
+ g_print ("Update completion: %d\n", g_list_length (providers));
+ });
+
+ /* Make sure to first cancel any running completion */
+ reset_completion (completion);
+
+ completion->priv->context = context_copy;
+ completion->priv->running_providers = g_list_copy (providers_copy);
+ completion->priv->active_providers = g_list_copy (providers_copy);
- while (providers != NULL)
+ /* Create a new CompletionModel */
+ gtk_tree_view_set_model (completion->priv->tree_view_proposals, NULL);
+ replace_model (completion);
+
+ for (item = providers_copy; item != NULL; item = g_list_next (item))
{
- GtkSourceCompletionProvider *provider = providers->data;
+ GtkSourceCompletionProvider *provider = item->data;
- if (gtk_source_completion_provider_match (provider, context))
- {
- selection = g_list_prepend (selection, provider);
- }
+ DEBUG({
+ gchar *temp_name = gtk_source_completion_provider_get_name (provider);
+ g_print ("Populating provider: %s\n", temp_name);
+ g_free (temp_name);
+ });
- providers = g_list_next (providers);
+ gtk_source_completion_provider_populate (provider, context_copy);
}
- return g_list_reverse (selection);
+ g_list_free (providers_copy);
}
static gboolean
@@ -1137,28 +1300,6 @@ auto_completion_destroy (GtkSourceCompletion *completion)
completion->priv->auto_completion_selection = NULL;
}
-static gint
-minimum_auto_complete_delay (GtkSourceCompletion *completion,
- GList *providers)
-{
- gint min_delay = completion->priv->auto_complete_delay;
-
- while (providers != NULL)
- {
- GtkSourceCompletionProvider *provider = providers->data;
- gint delay = gtk_source_completion_provider_get_interactive_delay (provider);
-
- if (0 <= delay && delay < min_delay)
- {
- min_delay = delay;
- }
-
- providers = g_list_next (providers);
- }
-
- return min_delay;
-}
-
static void
start_interactive_completion (GtkSourceCompletion *completion,
GtkTextIter *iter)
@@ -1242,15 +1383,63 @@ buffer_insert_text_cb (GtkTextBuffer *buffer,
}
static void
-buffer_mark_set_cb (GtkTextBuffer *buffer,
- GtkTextIter *iter,
- GtkTextMark *mark,
- GtkSourceCompletion *completion)
+populating_done (GtkSourceCompletion *completion,
+ GtkSourceCompletionContext *context)
{
- if (mark == gtk_text_buffer_get_insert (buffer))
+ if (gtk_source_completion_model_is_empty (completion->priv->model_proposals, TRUE))
{
+ DEBUG({
+ g_print ("Model is empty after populating\n");
+ });
+
gtk_source_completion_hide (completion);
+ return;
+ }
+
+ gtk_tree_view_set_model (completion->priv->tree_view_proposals,
+ GTK_TREE_MODEL (completion->priv->model_proposals));
+
+ update_selection_label (completion);
+
+ if (!gtk_widget_get_visible (GTK_WIDGET (completion->priv->main_window)))
+ {
+ DEBUG({
+ g_print ("Emitting show\n");
+ });
+
+ g_signal_emit (completion, signals[SHOW], 0);
+ }
+ else
+ {
+ DEBUG({
+ g_print ("Already visible\n");
+ });
}
+
+ check_first_selected (completion);
+}
+
+/*******************************************
+ * Properties, construction and destruction
+ *******************************************/
+
+static void
+gtk_source_completion_dispose (GObject *object)
+{
+ GtkSourceCompletion *completion = GTK_SOURCE_COMPLETION (object);
+
+ reset_completion (completion);
+
+ g_clear_object (&completion->priv->view);
+ g_clear_object (&completion->priv->default_info);
+
+ g_list_free (completion->priv->interactive_providers);
+ completion->priv->interactive_providers = NULL;
+
+ g_list_free_full (completion->priv->providers, g_object_unref);
+ completion->priv->providers = NULL;
+
+ G_OBJECT_CLASS (gtk_source_completion_parent_class)->dispose (object);
}
static void
@@ -1334,25 +1523,6 @@ connect_view (GtkSourceCompletion *completion)
}
static void
-gtk_source_completion_dispose (GObject *object)
-{
- GtkSourceCompletion *completion = GTK_SOURCE_COMPLETION (object);
-
- reset_completion (completion);
-
- g_clear_object (&completion->priv->view);
- g_clear_object (&completion->priv->default_info);
-
- g_list_free (completion->priv->interactive_providers);
- completion->priv->interactive_providers = NULL;
-
- g_list_free_full (completion->priv->providers, g_object_unref);
- completion->priv->providers = NULL;
-
- G_OBJECT_CLASS (gtk_source_completion_parent_class)->dispose (object);
-}
-
-static void
gtk_source_completion_get_property (GObject *object,
guint prop_id,
GValue *value,
@@ -1459,45 +1629,6 @@ gtk_source_completion_set_property (GObject *object,
}
static void
-gtk_source_completion_hide_default (GtkSourceCompletion *completion)
-{
- gtk_widget_hide (GTK_WIDGET (completion->priv->info_window));
- gtk_widget_hide (GTK_WIDGET (completion->priv->main_window));
-}
-
-static void
-gtk_source_completion_show_default (GtkSourceCompletion *completion)
-{
- /* Move completion window */
- if (completion->priv->context != NULL)
- {
- GtkTextIter location;
- gtk_source_completion_context_get_iter (completion->priv->context,
- &location);
-
- gtk_source_completion_utils_move_to_iter (completion->priv->main_window,
- GTK_SOURCE_VIEW (completion->priv->view),
- &location);
- }
-
- gtk_widget_show (GTK_WIDGET (completion->priv->main_window));
-
- if (completion->priv->remember_info_visibility)
- {
- if (gtk_toggle_button_get_active (completion->priv->info_button))
- {
- gtk_widget_show (GTK_WIDGET (completion->priv->info_window));
- }
- }
- else
- {
- gtk_toggle_button_set_active (completion->priv->info_button, FALSE);
- }
-
- gtk_widget_grab_focus (GTK_WIDGET (completion->priv->view));
-}
-
-static void
gtk_source_completion_class_init (GtkSourceCompletionClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -1915,70 +2046,6 @@ gtk_source_completion_class_init (GtkSourceCompletionClass *klass)
G_TYPE_INT, 1);
}
-static void
-update_transient_for_info (GObject *window,
- GParamSpec *spec,
- GtkSourceCompletion *completion)
-{
- gtk_window_set_transient_for (GTK_WINDOW (completion->priv->info_window),
- gtk_window_get_transient_for (completion->priv->main_window));
-}
-
-/* Begins at 0. Returns -1 if no accelerators available for @iter. */
-static gint
-get_accel_at_iter (GtkSourceCompletion *completion,
- GtkTreeIter *iter)
-{
- GtkTreeIter it;
- gint accel;
-
- if (gtk_source_completion_model_iter_is_header (completion->priv->model_proposals, iter))
- {
- return -1;
- }
-
- if (!gtk_source_completion_model_first_proposal (completion->priv->model_proposals, &it))
- {
- g_return_val_if_reached (-1);
- }
-
- for (accel = 0; accel < completion->priv->num_accelerators; accel++)
- {
- if (gtk_source_completion_model_iter_equal (completion->priv->model_proposals,
- iter,
- &it))
- {
- return accel;
- }
-
- if (!gtk_source_completion_model_next_proposal (completion->priv->model_proposals, &it))
- {
- return -1;
- }
- }
-
- return -1;
-}
-
-static void
-render_proposal_accelerator_func (GtkTreeViewColumn *column,
- GtkCellRenderer *cell,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- GtkSourceCompletion *completion)
-{
- gint accel = get_accel_at_iter (completion, iter);
- gchar *text = NULL;
-
- if (accel != -1)
- {
- text = g_strdup_printf ("<small><b>%d</b></small>", (accel + 1) % 10);
- }
-
- g_object_set (cell, "markup", text, NULL);
- g_free (text);
-}
-
static gboolean
selection_func (GtkTreeSelection *selection,
GtkTreeModel *model,
@@ -2178,42 +2245,9 @@ gtk_source_completion_init (GtkSourceCompletion *completion)
g_object_unref (builder);
}
-static void
-populating_done (GtkSourceCompletion *completion,
- GtkSourceCompletionContext *context)
-{
- if (gtk_source_completion_model_is_empty (completion->priv->model_proposals, TRUE))
- {
- DEBUG({
- g_print ("Model is empty after populating\n");
- });
-
- gtk_source_completion_hide (completion);
- return;
- }
-
- gtk_tree_view_set_model (completion->priv->tree_view_proposals,
- GTK_TREE_MODEL (completion->priv->model_proposals));
-
- update_selection_label (completion);
-
- if (!gtk_widget_get_visible (GTK_WIDGET (completion->priv->main_window)))
- {
- DEBUG({
- g_print ("Emitting show\n");
- });
-
- g_signal_emit (completion, signals[SHOW], 0);
- }
- else
- {
- DEBUG({
- g_print ("Already visible\n");
- });
- }
-
- check_first_selected (completion);
-}
+/*********************************
+ * Public or non-static functions
+ *********************************/
void
_gtk_source_completion_add_proposals (GtkSourceCompletion *completion,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]