[gtksourceview/gtksourcecompletion] Implemented latest provider API



commit e8cb2d2d43dc7fc202d2e2f5cd61c60dcaac4e69
Author: Jesse van den Kieboom <jesse icecrew nl>
Date:   Fri Apr 24 22:04:28 2009 +0200

    Implemented latest provider API
---
 gtksourceview/gtksourcecompletion.c         |  226 +++++++++++++-------------
 gtksourceview/gtksourcecompletion.h         |   23 ++-
 gtksourceview/gtksourcecompletioninfo.c     |   10 ++
 gtksourceview/gtksourcecompletionprovider.c |   43 +++---
 gtksourceview/gtksourcecompletionprovider.h |   14 ++-
 gtksourceview/gtksourcecompletionutils.c    |  116 ++++++++------
 gtksourceview/gtksourcecompletionutils.h    |    6 +
 tests/completion-simple.c                   |    6 +-
 tests/gsc-provider-devhelp.c                |    6 +-
 tests/gsc-provider-test.c                   |    6 +-
 10 files changed, 254 insertions(+), 202 deletions(-)

diff --git a/gtksourceview/gtksourcecompletion.c b/gtksourceview/gtksourcecompletion.c
index 22cb284..daa6b24 100644
--- a/gtksourceview/gtksourcecompletion.c
+++ b/gtksourceview/gtksourcecompletion.c
@@ -41,7 +41,6 @@
 
 #define WINDOW_WIDTH 350
 #define WINDOW_HEIGHT 200
-#define GTK_SOURCE_COMPLETION_PROVIDER_KEY "GtkSourceCompletionProviderKey"
 
 #define GTK_SOURCE_COMPLETION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object),\
 						  GTK_TYPE_SOURCE_COMPLETION,           \
@@ -50,7 +49,6 @@
 /* Signals */
 enum
 {
-	PROPOSAL_ACTIVATED,
 	SHOW,
 	HIDE,
 	LAST_SIGNAL
@@ -156,33 +154,58 @@ get_selected_proposal (GtkSourceCompletion          *completion,
 	return FALSE;
 }
 
+static void
+get_iter_at_insert (GtkSourceCompletion *completion,
+                    GtkTextIter         *iter)
+{
+	GtkTextBuffer *buffer;
+
+	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (completion->priv->view));
+	gtk_text_buffer_get_iter_at_mark (buffer,
+	                                  iter,
+	                                  gtk_text_buffer_get_insert (buffer));
+}
+
 static gboolean
 activate_current_proposal (GtkSourceCompletion *completion)
 {
-	gboolean activated = FALSE;
+	gboolean activated;
 	GtkTreeIter iter;
+	GtkTextIter titer;
 	GtkSourceCompletionProposal *proposal = NULL;
 	GtkSourceCompletionProvider *provider = NULL;
+	GtkTextBuffer *buffer;
 	
-	if (get_selected_proposal (completion, &iter, &proposal))
+	if (!get_selected_proposal (completion, &iter, &proposal))
 	{
-		gtk_tree_model_get (GTK_TREE_MODEL (completion->priv->model_proposals),
-		                    &iter,
-		                    GTK_SOURCE_COMPLETION_MODEL_COLUMN_PROVIDER, &provider,
-		                    -1);
-		                    
-		g_signal_emit (G_OBJECT (completion), 
-		               signals[PROPOSAL_ACTIVATED],
-			       0, 
-			       provider, 
-			       proposal, 
-			       &activated);
-		
-		g_object_unref (provider);
-		g_object_unref (proposal);
+		gtk_source_completion_hide (completion);
+		return TRUE;
 	}
 	
-	return activated;
+	gtk_tree_model_get (GTK_TREE_MODEL (completion->priv->model_proposals),
+	                    &iter,
+	                    GTK_SOURCE_COMPLETION_MODEL_COLUMN_PROVIDER, &provider,
+	                    -1);
+	
+	/* Get insert iter */
+	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (completion->priv->view));
+	get_iter_at_insert (completion, &titer);
+
+	activated = gtk_source_completion_provider_activate_proposal (provider, proposal, &titer);
+
+	if (!activated)
+	{
+		gtk_source_completion_utils_replace_current_word (GTK_SOURCE_BUFFER (buffer),
+				                                  gtk_source_completion_proposal_get_label (proposal),
+				                                  -1);
+	}
+
+	g_object_unref (provider);
+	g_object_unref (proposal);
+	
+	gtk_source_completion_hide (completion);
+
+	return TRUE;
 }
 
 typedef gboolean (*ProposalSelector)(GtkSourceCompletion *completion,
@@ -677,6 +700,7 @@ proposals_filter_func (GtkSourceCompletionModel    *model,
 	GtkSourceCompletionModelFilterFlag ret = GTK_SOURCE_COMPLETION_MODEL_NONE;
 	gboolean visible;
 	gboolean count;
+	GtkTextIter iter;
 	
 	/* Filter on provider */
 	if (completion->priv->filter_provider != NULL && completion->priv->filter_provider != provider)
@@ -693,6 +717,7 @@ proposals_filter_func (GtkSourceCompletionModel    *model,
 	{
 		visible = gtk_source_completion_provider_filter_proposal (provider,
 	                                                                  proposal,
+	                                                                  &iter,
 	                                                                  completion->priv->filter_criteria);
 
 		count = FALSE;
@@ -729,6 +754,9 @@ update_proposal_info_real (GtkSourceCompletion         *completion,
 	const gchar *text;
 	gboolean prov_update_info = FALSE;
 	
+	gtk_source_completion_info_set_sizing (GTK_SOURCE_COMPLETION_INFO (completion->priv->info_window),
+	                                       -1, -1, TRUE, TRUE);
+
 	if (proposal == NULL)
 	{
 		/* Set to default widget */
@@ -757,12 +785,6 @@ update_proposal_info_real (GtkSourceCompletion         *completion,
 	gtk_source_completion_info_set_widget (GTK_SOURCE_COMPLETION_INFO (completion->priv->info_window),
 	                                       info_widget);
 
-	if (info_widget == completion->priv->default_info)
-	{
-		gtk_source_completion_info_set_sizing (GTK_SOURCE_COMPLETION_INFO (completion->priv->info_window),
-		                                       -1, -1, TRUE, TRUE);
-	}
-
 	if (prov_update_info)
 	{
 		gtk_source_completion_provider_update_info (provider, 
@@ -854,18 +876,6 @@ hide_info_cb (GtkWidget *widget,
 				      FALSE);
 }
 
-static gboolean
-gtk_source_completion_proposal_activated_default (GtkSourceCompletion         *completion,
-						  GtkSourceCompletionProvider *provider,
-						  GtkSourceCompletionProposal *proposal)
-{
-	gboolean ret;
-	
-	ret = gtk_source_completion_provider_activate_proposal (provider, proposal); 
-	gtk_source_completion_hide (completion);
-	return ret;
-}
-
 static void
 gtk_source_completion_realize (GtkWidget *widget,
 			       GtkSourceCompletion *completion)
@@ -1045,7 +1055,6 @@ static gboolean
 show_auto_completion (GtkSourceCompletion *completion)
 {
 	GtkTextBuffer *buffer;
-	GtkTextMark *insert_mark;
 	GtkTextIter iter;
 	GtkTextIter word_start;
 	gchar *word;
@@ -1053,10 +1062,9 @@ show_auto_completion (GtkSourceCompletion *completion)
 	completion->priv->show_timed_out_id = 0;
 
 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (completion->priv->view));
-	insert_mark = gtk_text_buffer_get_insert (buffer);
 
 	/* Check if the user has changed the cursor position.If yes, we don't complete */
-	gtk_text_buffer_get_iter_at_mark (buffer, &iter, insert_mark);
+	get_iter_at_insert (completion, &iter);
 	
 	if ((gtk_text_iter_get_line (&iter) != completion->priv->typing_line))
 	{
@@ -1237,20 +1245,14 @@ gtk_source_completion_dispose (GObject *object)
 		g_object_unref (completion->priv->view);
 		
 		completion->priv->view = NULL;
+		
+		g_list_foreach (completion->priv->providers, (GFunc)g_object_unref, NULL);
 	}
 	
 	G_OBJECT_CLASS (gtk_source_completion_parent_class)->dispose (object);
 }
 
 static void
-remove_provider (GtkSourceCompletionProvider *provider)
-{
-	g_object_set_data (G_OBJECT (provider), 
-	                   GTK_SOURCE_COMPLETION_PROVIDER_KEY, 
-	                   NULL);
-}
-
-static void
 gtk_source_completion_finalize (GObject *object)
 {
 	GtkSourceCompletion *completion = GTK_SOURCE_COMPLETION (object);
@@ -1262,8 +1264,6 @@ gtk_source_completion_finalize (GObject *object)
 	
 	g_list_free (completion->priv->automatic_providers);
 	g_list_free (completion->priv->interactive_providers);
-	
-	g_list_foreach (completion->priv->providers, (GFunc)remove_provider, NULL);
 	g_list_free (completion->priv->providers);
 	
 	g_free (completion->priv->filter_criteria);
@@ -1406,7 +1406,6 @@ gtk_source_completion_class_init (GtkSourceCompletionClass *klass)
 	object_class->finalize = gtk_source_completion_finalize;
 	object_class->dispose = gtk_source_completion_dispose;
 
-	klass->proposal_activated = gtk_source_completion_proposal_activated_default;
 	klass->show = gtk_source_completion_show_default;
 	klass->hide = gtk_source_completion_hide_default;
 
@@ -1419,7 +1418,7 @@ gtk_source_completion_class_init (GtkSourceCompletionClass *klass)
 	g_object_class_install_property (object_class,
 					 PROP_VIEW,
 					 g_param_spec_object ("view",
-							      _("The completion view"),
+							      _("View"),
 							      _("The GtkSourceView bound to the completion"),
 							      GTK_TYPE_SOURCE_VIEW,
 							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
@@ -1433,8 +1432,8 @@ gtk_source_completion_class_init (GtkSourceCompletionClass *klass)
 	g_object_class_install_property (object_class,
 					 PROP_MANAGE_KEYS,
 					 g_param_spec_boolean ("manage-completion-keys",
-							      _("Manage Up, Down etc. keys when the completion is visible"),
-							      _("Manage Up, Down etc. keys when the completion is visible"),
+							      _("Manage Completion Keys"),
+							      _("Manage keys to navigate proposal selection"),
 							      TRUE,
 							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 	/**
@@ -1446,8 +1445,8 @@ gtk_source_completion_class_init (GtkSourceCompletionClass *klass)
 	g_object_class_install_property (object_class,
 					 PROP_REMEMBER_INFO_VISIBILITY,
 					 g_param_spec_boolean ("remember-info-visibility",
-							      _("Remember the last info state (visible or hidden)"),
-							      _("Remember the last info state (visible or hidden)"),
+							      _("Remeber Info Visibility"),
+							      _("Remember the last info window visibility state"),
 							      FALSE,
 							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 	/**
@@ -1459,9 +1458,9 @@ gtk_source_completion_class_init (GtkSourceCompletionClass *klass)
 	g_object_class_install_property (object_class,
 					 PROP_SELECT_ON_SHOW,
 					 g_param_spec_boolean ("select-on-show",
-							      _("Completion mark as selected the first proposal on show"),
-							      _("Completion mark as selected the first proposal on show"),
-							      FALSE,
+							      _("Select on Show"),
+							      _("Select first proposal when completion is shown"),
+							      TRUE,
 							      G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
 	/**
@@ -1501,33 +1500,13 @@ gtk_source_completion_class_init (GtkSourceCompletionClass *klass)
 					 PROP_MINIMUM_AUTO_COMPLETE_LENGTH,
 					 g_param_spec_uint ("minimum-auto-complete-length",
 							    _("Minimum Auto Complete Length"),
-							    _("Minimum word length to initiate auto completion"),
+							    _("Minimum word length to initiate interactive completion"),
 							    0,
 							    G_MAXUINT,
 							    3,
 							    G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
 	/**
-	 * GtkSourceCompletion::proposal-selected:
-	 * @completion: The #GtkSourceCompletion who emits the signal
-	 * @proposal: The selected #GtkSourceCompletionProposal
-	 *
-	 * When the user selects a proposal
-	 **/
-	signals[PROPOSAL_ACTIVATED] =
-		g_signal_new ("proposal-activated",
-			      G_TYPE_FROM_CLASS (klass),
-			      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-			      G_STRUCT_OFFSET (GtkSourceCompletionClass, proposal_activated),
-			      g_signal_accumulator_true_handled, 
-			      NULL,
-			      _gtksourceview_marshal_BOOLEAN__OBJECT_OBJECT, 
-			      G_TYPE_BOOLEAN,
-			      2,
-			      G_TYPE_OBJECT,
-			      G_TYPE_OBJECT);
-
-	/**
 	 * GtkSourceCompletion::show:
 	 * @completion: The #GtkSourceCompletion who emits the signal
 	 *
@@ -1551,7 +1530,7 @@ gtk_source_completion_class_init (GtkSourceCompletionClass *klass)
 	 * @completion: The #GtkSourceCompletion who emits the signal
 	 *
 	 * Emitted when the completion window is popped up. The default handler
-	 * will actually show the window.
+	 * will actually hide the window.
 	 **/
 	signals[HIDE] =
 		g_signal_new ("hide",
@@ -1920,11 +1899,6 @@ initialize_ui (GtkSourceCompletion *completion)
 
 	/* Info window */
 	completion->priv->info_window = GTK_WIDGET (gtk_source_completion_info_new ());
-	gtk_source_completion_info_set_sizing (GTK_SOURCE_COMPLETION_INFO (completion->priv->info_window),
-	                                       WINDOW_WIDTH,
-	                                       WINDOW_HEIGHT,
-	                                       TRUE,
-	                                       TRUE);
 	                             
 	g_signal_connect (completion->priv->window, 
 	                  "notify::transient-for",
@@ -1988,8 +1962,11 @@ add_proposals (GtkSourceCompletion         *completion,
 	GList *proposals;
 	GList *item;
 	GtkSourceCompletionProposal *proposal;
+	GtkTextIter iter;
 
-	proposals = gtk_source_completion_provider_get_proposals (provider);
+	get_iter_at_insert (completion, &iter);
+	
+	proposals = gtk_source_completion_provider_get_proposals (provider, &iter);
 	
 	completion->priv->inserting_data = TRUE;
 	
@@ -2082,6 +2059,19 @@ gtk_source_completion_show (GtkSourceCompletion *completion,
 	return TRUE;
 }
 
+GQuark
+gtk_source_completion_error_quark (void)
+{
+	static GQuark quark = 0;
+
+	if (G_UNLIKELY (quark) == 0)
+	{
+		quark = g_quark_from_static_string ("gtk-source-completion-error-quark");
+	}
+	
+	return quark;
+}
+
 /**
  * gtk_source_completion_new:
  * @view: the #GtkSourceView to create the completion for
@@ -2113,23 +2103,28 @@ gtk_source_completion_new (GtkSourceView *view)
  *          if @provider was already added to @completion before
  **/
 gboolean
-gtk_source_completion_add_provider (GtkSourceCompletion         *completion,
-				    GtkSourceCompletionProvider *provider)
+gtk_source_completion_add_provider (GtkSourceCompletion          *completion,
+				    GtkSourceCompletionProvider  *provider,
+				    GError                      **error)
 {
-	GtkSourceCompletion *other;
-	
 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION (completion), FALSE);
 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), FALSE);
 	
-	other = gtk_source_completion_get_from_provider	(provider);
-
-	if (other != NULL)
+	if (g_list_find (completion->priv->providers, provider) != NULL)
 	{
+		if (error)
+		{
+			g_set_error (error, 
+			             GTK_SOURCE_COMPLETION_ERROR, 
+			             GTK_SOURCE_COMPLETION_ERROR_ALREADY_BOUND,
+			             "Provider is already bound to this completion object");
+		}
+
 		return FALSE;
 	}
 
 	completion->priv->providers = g_list_append (completion->priv->providers, 
-	                                              g_object_ref (provider));
+	                                             g_object_ref (provider));
 
 	if (gtk_source_completion_provider_get_interactive (provider))
 	{
@@ -2144,10 +2139,12 @@ gtk_source_completion_add_provider (GtkSourceCompletion         *completion,
 			g_list_append (completion->priv->automatic_providers,
 			               provider);
 	}
-	
-	g_object_set_data (G_OBJECT (provider), 
-	                   GTK_SOURCE_COMPLETION_PROVIDER_KEY, 
-	                   completion);
+
+	if (error)
+	{
+		*error = NULL;
+	}
+
 	return TRUE;
 }
 
@@ -2161,8 +2158,9 @@ gtk_source_completion_add_provider (GtkSourceCompletion         *completion,
  * Returns: %TRUE if @provider was successfully removed
  **/
 gboolean
-gtk_source_completion_remove_provider (GtkSourceCompletion         *completion,
-				       GtkSourceCompletionProvider *provider)
+gtk_source_completion_remove_provider (GtkSourceCompletion          *completion,
+				       GtkSourceCompletionProvider  *provider,
+				       GError                      **error)
 {
 	GList *item;
 	
@@ -2188,16 +2186,25 @@ gtk_source_completion_remove_provider (GtkSourceCompletion         *completion,
 		}
 
 		completion->priv->providers = g_list_remove_link (completion->priv->providers, item);
-		
-		g_object_set_data (G_OBJECT (provider), 
-		                   GTK_SOURCE_COMPLETION_PROVIDER_KEY, 
-		                   NULL);
 		g_object_unref (provider);
 
+		if (error)
+		{
+			*error = NULL;
+		}
+
 		return TRUE;
 	}
 	else
-	{		
+	{
+		if (error)
+		{
+			g_set_error (error,
+			             GTK_SOURCE_COMPLETION_ERROR,
+			             GTK_SOURCE_COMPLETION_ERROR_NOT_BOUND,
+			             "Provider is not bound to this completion object");
+		}
+		
 		return FALSE;
 	}
 }
@@ -2236,13 +2243,6 @@ gtk_source_completion_get_info_window (GtkSourceCompletion *completion)
 	return GTK_SOURCE_COMPLETION_INFO (completion->priv->info_window);
 }
 
-GtkSourceCompletion *
-gtk_source_completion_get_from_provider	(GtkSourceCompletionProvider *provider)
-{
-	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), NULL);
-	return g_object_get_data (G_OBJECT (provider), GTK_SOURCE_COMPLETION_PROVIDER_KEY);
-}
-
 GtkSourceView *
 gtk_source_completion_get_view (GtkSourceCompletion *completion)
 {
diff --git a/gtksourceview/gtksourcecompletion.h b/gtksourceview/gtksourcecompletion.h
index b9c4989..4b1ef41 100644
--- a/gtksourceview/gtksourcecompletion.h
+++ b/gtksourceview/gtksourcecompletion.h
@@ -39,10 +39,18 @@ G_BEGIN_DECLS
 #define GTK_IS_SOURCE_COMPLETION_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SOURCE_COMPLETION))
 #define GTK_SOURCE_COMPLETION_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_SOURCE_COMPLETION, GtkSourceCompletionClass))
 
+#define GTK_SOURCE_COMPLETION_ERROR		(gtk_source_completion_error_quark ())
+
 typedef struct _GtkSourceCompletionPrivate GtkSourceCompletionPrivate;
 typedef struct _GtkSourceCompletion GtkSourceCompletion;
 typedef struct _GtkSourceCompletionClass GtkSourceCompletionClass;
 
+typedef enum
+{
+	GTK_SOURCE_COMPLETION_ERROR_ALREADY_BOUND = 0,
+	GTK_SOURCE_COMPLETION_ERROR_NOT_BOUND,
+} GtkSourceCompletionError;
+
 /* Forward declaration of GtkSourceView */
 struct _GtkSourceView;
 
@@ -66,14 +74,18 @@ struct _GtkSourceCompletionClass
 
 GType		 gtk_source_completion_get_type			(void) G_GNUC_CONST;
 
+GQuark		 gtk_source_completion_error_quark		(void);
+
 struct _GtkSourceView *
 		 gtk_source_completion_get_view			(GtkSourceCompletion	     *completion);
 
-gboolean	 gtk_source_completion_add_provider		(GtkSourceCompletion         *completion,
-								 GtkSourceCompletionProvider *provider);
+gboolean	 gtk_source_completion_add_provider		(GtkSourceCompletion          *completion,
+								 GtkSourceCompletionProvider  *provider,
+								 GError                      **error);
 
-gboolean	 gtk_source_completion_remove_provider		(GtkSourceCompletion         *completion,
-								 GtkSourceCompletionProvider *provider);
+gboolean	 gtk_source_completion_remove_provider		(GtkSourceCompletion          *completion,
+								 GtkSourceCompletionProvider  *provider,
+								 GError                      **error);
 
 gboolean	 gtk_source_completion_show			(GtkSourceCompletion         *completion,
 								 GList                       *providers,
@@ -85,9 +97,6 @@ void		 gtk_source_completion_hide			(GtkSourceCompletion         *completion);
 GtkSourceCompletionInfo *
 		 gtk_source_completion_get_info_window		(GtkSourceCompletion         *completion);
 
-GtkSourceCompletion *
-		 gtk_source_completion_get_from_provider	(GtkSourceCompletionProvider *provider);
-
 G_END_DECLS
 
 #endif 
diff --git a/gtksourceview/gtksourcecompletioninfo.c b/gtksourceview/gtksourcecompletioninfo.c
index df01bf5..c2d8e9b 100644
--- a/gtksourceview/gtksourcecompletioninfo.c
+++ b/gtksourceview/gtksourcecompletioninfo.c
@@ -452,10 +452,20 @@ gtk_source_completion_info_set_sizing (GtkSourceCompletionInfo *self,
 {
 	g_return_if_fail  (GTK_IS_SOURCE_COMPLETION_INFO (self));
 
+	if (self->priv->max_width == width &&
+	    self->priv->max_height == height &&
+	    self->priv->shrink_width == shrink_width &&
+	    self->priv->shrink_height == shrink_height)
+	{
+		return;
+	}
+
 	self->priv->max_width = width;
 	self->priv->max_height = height;
 	self->priv->shrink_width = shrink_width;
 	self->priv->shrink_height = shrink_height;
+	
+	queue_resize (self);
 }
 
 static gboolean
diff --git a/gtksourceview/gtksourcecompletionprovider.c b/gtksourceview/gtksourcecompletionprovider.c
index 6d9a08e..f160f27 100644
--- a/gtksourceview/gtksourcecompletionprovider.c
+++ b/gtksourceview/gtksourcecompletionprovider.c
@@ -30,12 +30,13 @@
  * 
  */
 
-
+#include <gtksourceview/gtksourcecompletion.h>
 #include <gtksourceview/gtksourcecompletionprovider.h>
 #include <gtksourceview/gtksourcecompletion.h>
 #include <gtksourceview/gtksourceview.h>
 
 #include "gtksourcecompletionutils.h"
+#include "gtksourceview-i18n.h"
 
 /* Default implementations */
 static const gchar *
@@ -51,7 +52,8 @@ gtk_source_completion_provider_get_icon_default (GtkSourceCompletionProvider *pr
 }
 
 static GList *
-gtk_source_completion_provider_get_proposals_default (GtkSourceCompletionProvider *provider)
+gtk_source_completion_provider_get_proposals_default (GtkSourceCompletionProvider *provider,
+                                                      GtkTextIter                 *iter)
 {
 	return NULL;
 }
@@ -59,6 +61,7 @@ gtk_source_completion_provider_get_proposals_default (GtkSourceCompletionProvide
 static gboolean
 gtk_source_completion_provider_filter_proposal_default (GtkSourceCompletionProvider *provider,
                                                         GtkSourceCompletionProposal *proposal,
+                                                        GtkTextIter                 *iter,
                                                         const gchar                 *criteria)
 {
 	return TRUE;
@@ -92,20 +95,10 @@ gtk_source_completion_provider_update_info_default (GtkSourceCompletionProvider
 
 static gboolean
 gtk_source_completion_provider_activate_proposal_default (GtkSourceCompletionProvider *provider,
-                                                          GtkSourceCompletionProposal *proposal)
+                                                          GtkSourceCompletionProposal *proposal,
+                                                          GtkTextIter                 *iter)
 {
-	GtkSourceCompletion *completion;
-	GtkSourceView *view;
-	GtkSourceBuffer *buffer;
-	
-	completion = gtk_source_completion_get_from_provider (provider);
-	view = gtk_source_completion_get_view (completion);
-	buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
-	
-	gtk_source_completion_utils_replace_current_word (buffer,
-	                                                  gtk_source_completion_proposal_get_label (proposal),
-	                                                  -1);
-	return TRUE;
+	return FALSE;
 }
 
 static void 
@@ -197,6 +190,7 @@ gtk_source_completion_provider_get_icon (GtkSourceCompletionProvider *provider)
 /**
  * gtk_source_completion_provider_get_proposals:
  * @provider: The #GtkSourceCompletionProvider
+ * @iter: A #GtkTextIter
  *
  * Get proposals from the provider for completion
  *
@@ -205,16 +199,18 @@ gtk_source_completion_provider_get_icon (GtkSourceCompletionProvider *provider)
  *          owned by the caller and will be freed when no longer needed.
  */
 GList * 
-gtk_source_completion_provider_get_proposals (GtkSourceCompletionProvider *provider)
+gtk_source_completion_provider_get_proposals (GtkSourceCompletionProvider *provider,
+                                              GtkTextIter                 *iter)
 {
 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), NULL);
-	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_proposals (provider);
+	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->get_proposals (provider, iter);
 }
 
 /**
  * gtk_source_completion_provider_filter_proposal:
  * @provider: The #GtkSourceCompletionProvider
  * @proposal: A #GtkSourceCompletionProposal
+ * @iter: A #GtkTextIter
  * @criteria: A string representing the filter criteria
  *
  * Determines whether to filter @proposal based on @criteria. It is guaranteed
@@ -226,13 +222,17 @@ gtk_source_completion_provider_get_proposals (GtkSourceCompletionProvider *provi
 gboolean
 gtk_source_completion_provider_filter_proposal (GtkSourceCompletionProvider *provider,
                                                 GtkSourceCompletionProposal *proposal,
+                                                GtkTextIter                 *iter,
                                                 const gchar                 *criteria)
 {
 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), FALSE);
 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROPOSAL (proposal), FALSE);
 	g_return_val_if_fail (criteria != NULL, FALSE);
 
-	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->filter_proposal (provider, proposal, criteria);
+	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->filter_proposal (provider, 
+	                                                                                 proposal, 
+	                                                                                 iter, 
+	                                                                                 criteria);
 }
 
 /**
@@ -317,10 +317,13 @@ gtk_source_completion_provider_update_info (GtkSourceCompletionProvider *provide
 
 gboolean
 gtk_source_completion_provider_activate_proposal (GtkSourceCompletionProvider *provider,
-                                                  GtkSourceCompletionProposal *proposal)
+                                                  GtkSourceCompletionProposal *proposal,
+                                                  GtkTextIter                 *iter)
 {
 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), FALSE);
 	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROPOSAL (proposal), FALSE);
 	
-	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->activate_proposal (provider, proposal);
+	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (provider)->activate_proposal (provider, 
+	                                                                                   proposal,
+	                                                                                   iter);
 }
diff --git a/gtksourceview/gtksourcecompletionprovider.h b/gtksourceview/gtksourcecompletionprovider.h
index 7053f6d..8b840e6 100644
--- a/gtksourceview/gtksourcecompletionprovider.h
+++ b/gtksourceview/gtksourcecompletionprovider.h
@@ -46,9 +46,11 @@ struct _GtkSourceCompletionProviderIface
 	
 	const gchar	*(*get_name)       	(GtkSourceCompletionProvider *provider);
 	GdkPixbuf	*(*get_icon)       	(GtkSourceCompletionProvider *provider);
-	GList 		*(*get_proposals) 	(GtkSourceCompletionProvider *provider);
+	GList 		*(*get_proposals) 	(GtkSourceCompletionProvider *provider,
+						 GtkTextIter                 *iter);
 	gboolean 	 (*filter_proposal) 	(GtkSourceCompletionProvider *provider,
 						 GtkSourceCompletionProposal *proposal,
+						 GtkTextIter                 *iter,
 						 const gchar                 *criteria);
 
 	gboolean         (*get_automatic)	(GtkSourceCompletionProvider *provider);
@@ -61,7 +63,8 @@ struct _GtkSourceCompletionProviderIface
 						 GtkSourceCompletionInfo     *info);
 
 	gboolean	 (*activate_proposal)	(GtkSourceCompletionProvider *provider,
-						 GtkSourceCompletionProposal *proposal);
+						 GtkSourceCompletionProposal *proposal,
+						 GtkTextIter                 *iter);
 };
 
 GType		 gtk_source_completion_provider_get_type	(void);
@@ -71,10 +74,12 @@ const gchar	*gtk_source_completion_provider_get_name	(GtkSourceCompletionProvide
 
 GdkPixbuf	*gtk_source_completion_provider_get_icon	(GtkSourceCompletionProvider *provider);
 
-GList		*gtk_source_completion_provider_get_proposals	(GtkSourceCompletionProvider *provider);
+GList		*gtk_source_completion_provider_get_proposals	(GtkSourceCompletionProvider *provider,
+								 GtkTextIter                 *iter);
 
 gboolean	 gtk_source_completion_provider_filter_proposal	(GtkSourceCompletionProvider *provider,
 								 GtkSourceCompletionProposal *proposal,
+								 GtkTextIter                 *iter,
 								 const gchar                 *criteria);
 
 gboolean 	 gtk_source_completion_provider_get_automatic	(GtkSourceCompletionProvider *provider);
@@ -88,7 +93,8 @@ void 		 gtk_source_completion_provider_update_info	(GtkSourceCompletionProvider
 								 GtkSourceCompletionInfo     *info);
 
 gboolean	 gtk_source_completion_provider_activate_proposal (GtkSourceCompletionProvider *provider,
-								   GtkSourceCompletionProposal *proposal);
+								   GtkSourceCompletionProposal *proposal,
+								   GtkTextIter                 *iter);
 
 G_END_DECLS
 
diff --git a/gtksourceview/gtksourcecompletionutils.c b/gtksourceview/gtksourcecompletionutils.c
index 4ee1c6d..ac0926c 100644
--- a/gtksourceview/gtksourcecompletionutils.c
+++ b/gtksourceview/gtksourcecompletionutils.c
@@ -62,73 +62,49 @@ gtk_source_completion_utils_is_separator(const gunichar ch)
  */
 gchar *
 gtk_source_completion_utils_get_word_iter (GtkSourceBuffer *source_buffer, 
+                                           GtkTextIter     *current,
 					   GtkTextIter     *start_word, 
 					   GtkTextIter     *end_word)
 {
-	GtkTextMark *insert_mark;
 	GtkTextBuffer *text_buffer;
-	GtkTextIter actual;
-	GtkTextIter temp;
-	GtkTextIter *start_iter;
-	gchar *text;
 	gunichar ch;
-	gboolean found;
 	gboolean no_doc_start;
 	
-	if (start_word != NULL)
+	text_buffer = GTK_TEXT_BUFFER (source_buffer);
+	
+	if (current == NULL)
 	{
-		start_iter = start_word;
+		gtk_text_buffer_get_iter_at_mark (text_buffer,
+		                                  start_word,
+		                                  gtk_text_buffer_get_insert (text_buffer));
 	}
 	else
 	{
-		start_iter = &temp;
-	}
-	
-	text_buffer = GTK_TEXT_BUFFER (source_buffer);
-	insert_mark = gtk_text_buffer_get_insert (text_buffer);
-	gtk_text_buffer_get_iter_at_mark (text_buffer ,&actual, insert_mark);
-	
-	*start_iter = actual;
-
-	if (end_word != NULL)
-	{
-		*end_word = actual;
+		*start_word = *current;
 	}
 	
-	found = FALSE;
+	*end_word = *start_word;
 
-	while ((no_doc_start = gtk_text_iter_backward_char (start_iter)) == TRUE)
+	while ((no_doc_start = gtk_text_iter_backward_char (start_word)) == TRUE)
 	{
-		ch = gtk_text_iter_get_char (start_iter);
+		ch = gtk_text_iter_get_char (start_word);
 
 		if (gtk_source_completion_utils_is_separator (ch))
 		{
-			found = TRUE;
 			break;
 		}
 	}
 	
 	if (!no_doc_start)
 	{
-		gtk_text_buffer_get_start_iter (text_buffer, start_iter);
-		text = gtk_text_iter_get_text (start_iter, &actual);
+		gtk_text_buffer_get_start_iter (text_buffer, start_word);
+		return gtk_text_iter_get_text (start_word, end_word);
 	}
 	else
 	{
-	
-		if (found)
-		{
-			gtk_text_iter_forward_char (start_iter);
-			text = gtk_text_iter_get_text (start_iter, &actual);
-		}
-		else
-		{
-			*start_iter = actual;
-			text = g_strdup ("");
-		}
+		gtk_text_iter_forward_char (start_word);
+		return gtk_text_iter_get_text (start_word, end_word);
 	}
-	
-	return text;
 }
 
 /**
@@ -140,7 +116,10 @@ gtk_source_completion_utils_get_word_iter (GtkSourceBuffer *source_buffer,
 gchar *
 gtk_source_completion_utils_get_word (GtkSourceBuffer *source_buffer)
 {
-	return gtk_source_completion_utils_get_word_iter (source_buffer, NULL, NULL);
+	GtkTextIter start;
+	GtkTextIter end;
+	
+	return gtk_source_completion_utils_get_word_iter (source_buffer, NULL, &start, &end);
 }
 
 static void
@@ -177,6 +156,40 @@ get_iter_pos (GtkSourceView *source_view,
 	*height = location.height;
 }
 
+void
+gtk_source_completion_utils_replace_word (GtkSourceBuffer *source_buffer,
+					  GtkTextIter     *iter,
+					  const gchar     *text,
+					  gint             len)
+{
+	GtkTextBuffer *buffer;
+	gchar *word;
+	GtkTextIter word_start;
+	GtkTextIter word_end;
+	GtkTextMark *mark;
+
+	g_return_if_fail (GTK_IS_SOURCE_BUFFER (source_buffer));
+	
+	buffer = GTK_TEXT_BUFFER (source_buffer);
+	gtk_text_buffer_begin_user_action (buffer);
+	
+	mark = gtk_text_buffer_create_mark (buffer, NULL, iter, TRUE);
+	word = gtk_source_completion_utils_get_word_iter (source_buffer, iter, &word_start, &word_end);
+	g_free (word);
+
+	gtk_text_buffer_delete (buffer, &word_start, &word_end);
+	
+	if (text != NULL)
+	{
+		gtk_text_buffer_insert (buffer, &word_start, text, len);
+	}
+
+	/* Reinitialize iter */
+	gtk_text_buffer_get_iter_at_mark (buffer, iter, mark);
+	gtk_text_buffer_delete_mark (buffer, mark);
+	gtk_text_buffer_end_user_action (buffer);
+}
+
 /**
  * gsc_utils_view_replace_current_word:
  * @source_buffer: The #GtkSourceBuffer
@@ -190,21 +203,20 @@ gtk_source_completion_utils_replace_current_word (GtkSourceBuffer *source_buffer
 						  const gchar     *text,
 						  gint             len)
 {
-	GtkTextBuffer *buffer;
-	gchar *word;
-	GtkTextIter word_start;
-	GtkTextIter word_end;
+	GtkTextIter iter;
+	GtkTextMark *mark;
 	
-	buffer = GTK_TEXT_BUFFER (source_buffer);
-	gtk_text_buffer_begin_user_action (buffer);
-	
-	word = gtk_source_completion_utils_get_word_iter (source_buffer, &word_start, &word_end);
-	g_free (word);
+	g_return_if_fail (GTK_IS_SOURCE_BUFFER (source_buffer));
 
-	gtk_text_buffer_delete (buffer, &word_start, &word_end);
-	gtk_text_buffer_insert (buffer, &word_start, text, len);
+	mark = gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (source_buffer));
+	gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (source_buffer),
+	                                  &iter,
+	                                  mark);
 
-	gtk_text_buffer_end_user_action (buffer);
+	gtk_source_completion_utils_replace_word (source_buffer,
+	                                          &iter,
+	                                          text,
+	                                          len);
 }
 
 static void
diff --git a/gtksourceview/gtksourcecompletionutils.h b/gtksourceview/gtksourcecompletionutils.h
index 3e06889..8de70e1 100644
--- a/gtksourceview/gtksourcecompletionutils.h
+++ b/gtksourceview/gtksourcecompletionutils.h
@@ -30,11 +30,17 @@ G_BEGIN_DECLS
 gboolean	 gtk_source_completion_utils_is_separator		(gunichar         ch);
 
 gchar		*gtk_source_completion_utils_get_word_iter		(GtkSourceBuffer *source_buffer, 
+									 GtkTextIter     *current,
 									 GtkTextIter     *start_word, 
 									 GtkTextIter     *end_word);
 
 gchar		*gtk_source_completion_utils_get_word			(GtkSourceBuffer *text_view);
 
+void		 gtk_source_completion_utils_replace_word		(GtkSourceBuffer *source_buffer,
+									 GtkTextIter     *iter,
+									 const gchar     *text,
+									 gint             len);
+
 void		 gtk_source_completion_utils_replace_current_word	(GtkSourceBuffer *source_buffer, 
 									 const gchar     *text,
 									 gint             len);
diff --git a/tests/completion-simple.c b/tests/completion-simple.c
index c2efe0a..13ae9f0 100644
--- a/tests/completion-simple.c
+++ b/tests/completion-simple.c
@@ -192,7 +192,7 @@ create_completion(void)
 		g_object_unref (icon);
 	}
 	
-	gtk_source_completion_add_provider (comp, GTK_SOURCE_COMPLETION_PROVIDER (prov_test1));
+	gtk_source_completion_add_provider (comp, GTK_SOURCE_COMPLETION_PROVIDER (prov_test1), NULL);
 	
 	icon = get_icon_from_theme (GTK_STOCK_OPEN);
 	prov_test1 = gsc_provider_test_new ("Open Files", icon);
@@ -202,14 +202,14 @@ create_completion(void)
 		g_object_unref (icon);
 	}
 	
-	gtk_source_completion_add_provider (comp, GTK_SOURCE_COMPLETION_PROVIDER (prov_test1));
+	gtk_source_completion_add_provider (comp, GTK_SOURCE_COMPLETION_PROVIDER (prov_test1), NULL);
 
 #ifdef HAVE_DEVHELP
 	GscProviderDevhelp *prov_devhelp;
 
 	prov_devhelp = gsc_provider_devhelp_new ();
 	
-	gtk_source_completion_add_provider (comp, GTK_SOURCE_COMPLETION_PROVIDER (prov_devhelp));
+	gtk_source_completion_add_provider (comp, GTK_SOURCE_COMPLETION_PROVIDER (prov_devhelp), NULL);
 #endif
 }
 
diff --git a/tests/gsc-provider-devhelp.c b/tests/gsc-provider-devhelp.c
index e1649ff..00a9b83 100644
--- a/tests/gsc-provider-devhelp.c
+++ b/tests/gsc-provider-devhelp.c
@@ -30,7 +30,8 @@ gsc_provider_devhelp_get_name (GtkSourceCompletionProvider *self)
 }
 
 static GList * 
-gsc_provider_devhelp_get_proposals (GtkSourceCompletionProvider *provider)
+gsc_provider_devhelp_get_proposals (GtkSourceCompletionProvider *provider,
+                                    GtkTextIter                 *iter)
 {
 	GscProviderDevhelp *devhelp = GSC_PROVIDER_DEVHELP (provider);
 	
@@ -42,6 +43,7 @@ gsc_provider_devhelp_get_proposals (GtkSourceCompletionProvider *provider)
 static gboolean
 gsc_provider_devhelp_filter_proposal (GtkSourceCompletionProvider *provider,
                                       GtkSourceCompletionProposal *proposal,
+                                      GtkTextIter                 *iter,
                                       const gchar                 *criteria)
 {
 	const gchar *item;
@@ -133,6 +135,8 @@ gsc_provider_devhelp_init (GscProviderDevhelp *self)
 	
 	self->priv->view = dh_assistant_view_new ();
 	dh_assistant_view_set_base (DH_ASSISTANT_VIEW (self->priv->view), self->priv->dhbase);
+	
+	gtk_widget_set_size_request (self->priv->view, 400, 300);
 
 	self->priv->proposals = g_list_reverse (ret);
 }
diff --git a/tests/gsc-provider-test.c b/tests/gsc-provider-test.c
index a1f4d38..55c8224 100644
--- a/tests/gsc-provider-test.c
+++ b/tests/gsc-provider-test.c
@@ -18,6 +18,7 @@
  */
 
 #include "gsc-provider-test.h"
+#include <gtksourceview/gtksourcecompletion.h>
 #include <gtksourceview/gtksourcecompletionitem.h>
 
 #define GSC_PROVIDER_TEST_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), GSC_TYPE_PROVIDER_TEST, GscProviderTestPrivate))
@@ -60,7 +61,8 @@ append_item (GList *list, const gchar *name, GdkPixbuf *icon, const gchar *info)
 }
 
 static GList *
-gsc_provider_test_get_proposals (GtkSourceCompletionProvider *base)
+gsc_provider_test_get_proposals (GtkSourceCompletionProvider *base,
+                                 GtkTextIter                 *iter)
 {
 	GscProviderTest *provider = GSC_PROVIDER_TEST (base);
 	GList *list = NULL;
@@ -76,6 +78,7 @@ gsc_provider_test_get_proposals (GtkSourceCompletionProvider *base)
 static gboolean
 gsc_provider_test_filter_proposal (GtkSourceCompletionProvider *provider,
                                    GtkSourceCompletionProposal *proposal,
+                                   GtkTextIter                 *iter,
                                    const gchar                 *criteria)
 {
 	const gchar *label;
@@ -110,7 +113,6 @@ gsc_provider_test_finalize (GObject *object)
 	G_OBJECT_CLASS (gsc_provider_test_parent_class)->finalize (object);
 }
 
-
 static void 
 gsc_provider_test_class_init (GscProviderTestClass *klass)
 {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]