gtksourceview r2241 - in branches/gtksourcecompletion: . gtksourceview



Author: icq
Date: Tue Apr  7 15:28:05 2009
New Revision: 2241
URL: http://svn.gnome.org/viewvc/gtksourceview?rev=2241&view=rev

Log:
2009-04-07  Ignacio Casal Quinteiro  <nacho resa gmail com>

        * gtksourceview/gtksourceview-marshal.list:
        * gtksourceview/gtksourcecompletion.c:
        * gtksourceview/gtksourcecompletion.h:
        * gtksourceview/gtksourcecompletionprovider.c:
        * gtksourceview/gtksourcecompletioninfo.c:
        * gtksourceview/gtksourcecompletionproposal.c:
        * gtksourceview/gtksourcecompletionprovider.h:
        * gtksourceview/gtksourcecompletioninfo.h:
        * gtksourceview/gtksourcecompletionutils.c:
        * gtksourceview/gtksourcecompletiontrigger.c:
        * gtksourceview/gtksourcecompletionproposal.h:
        * gtksourceview/gtksourcecompletionutils.h:
        * gtksourceview/Makefile.am:
        * gtksourceview/gtksourcecompletiontrigger.h:
        Added gtksourcecompletion files. (The port start).



Added:
   branches/gtksourcecompletion/gtksourceview/gtksourcecompletion.c
   branches/gtksourcecompletion/gtksourceview/gtksourcecompletion.h
   branches/gtksourcecompletion/gtksourceview/gtksourcecompletioninfo.c
   branches/gtksourcecompletion/gtksourceview/gtksourcecompletioninfo.h
   branches/gtksourcecompletion/gtksourceview/gtksourcecompletionproposal.c
   branches/gtksourcecompletion/gtksourceview/gtksourcecompletionproposal.h
   branches/gtksourcecompletion/gtksourceview/gtksourcecompletionprovider.c
   branches/gtksourcecompletion/gtksourceview/gtksourcecompletionprovider.h
   branches/gtksourcecompletion/gtksourceview/gtksourcecompletiontrigger.c
   branches/gtksourcecompletion/gtksourceview/gtksourcecompletiontrigger.h
   branches/gtksourcecompletion/gtksourceview/gtksourcecompletionutils.c
   branches/gtksourcecompletion/gtksourceview/gtksourcecompletionutils.h
Modified:
   branches/gtksourcecompletion/ChangeLog
   branches/gtksourcecompletion/gtksourceview/Makefile.am
   branches/gtksourcecompletion/gtksourceview/gtksourceview-marshal.list

Modified: branches/gtksourcecompletion/gtksourceview/Makefile.am
==============================================================================
--- branches/gtksourcecompletion/gtksourceview/Makefile.am	(original)
+++ branches/gtksourcecompletion/gtksourceview/Makefile.am	Tue Apr  7 15:28:05 2009
@@ -27,7 +27,11 @@
 	gtksourcestyleschememanager.h		\
 	gtksourcestylescheme.h			\
 	gtksourcemark.h				\
-	gtksourceprintcompositor.h
+	gtksourceprintcompositor.h		\
+	gtksourcecompletion.h			\
+	gtksourcecompletionproposal.h		\
+	gtksourcecompletionprovider.h		\
+	gtksourcecompletiontrigger.h
 
 libgtksourceview_2_0_la_SOURCES = 	\
 	gtksourcebuffer.c 		\
@@ -56,6 +60,14 @@
 	gtksourcecontextengine.c	\
 	gtksourcemark.c			\
 	gtksourceprintcompositor.c      \
+	gtksourcecompletion.c		\
+	gtksourcecompletioninfo.c	\
+	gtksourcecompletioninfo.h	\
+	gtksourcecompletionproposal.c	\
+	gtksourcecompletionprovider.c	\
+	gtksourcecompletiontrigger.c	\
+	gtksourcecompletionutils.c	\
+	gtksourcecompletionutils.h	\
 	$(libgtksourceview_headers)
 
 # do not distribute generated files

Added: branches/gtksourcecompletion/gtksourceview/gtksourcecompletion.c
==============================================================================
--- (empty file)
+++ branches/gtksourcecompletion/gtksourceview/gtksourcecompletion.c	Tue Apr  7 15:28:05 2009
@@ -0,0 +1,2195 @@
+/*
+ * gtksourcecompletion.c
+ * This file is part of gtksourcecompletion
+ *
+ * Copyright (C) 2007 -2009 JesÃs Barbero RodrÃguez <chuchiperriman gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA.
+ */
+ 
+/**
+ * SECTION:gtksourcecompletion
+ * @title: GtkSourceCompletion
+ * @short_description: Main Completion Object
+ *
+ * This is the main completion object. It manages all providers (#GtkSourceProvider) and 
+ * triggers (#GtkSourceTrigger) for a #GtkTextView.
+ */
+
+#include <gdk/gdkkeysyms.h> 
+#include "gtksourcecompletionutils.h"
+#include "gtksourceview-marshal.h"
+#include "gtksourcecompletion.h"
+#include <string.h>
+
+static gboolean lib_initialized = FALSE;
+
+#define WINDOW_WIDTH 350
+#define WINDOW_HEIGHT 200
+
+#define GTK_SOURCE_COMPLETION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object),\
+						  GTK_TYPE_SOURCE_COMPLETION,           \
+						  GtkSourceCompletionPriv))
+
+enum
+{
+	COLUMN_PIXBUF,
+	COLUMN_NAME,
+	COLUMN_DATA,
+	N_COLUMNS
+};
+
+/* Signals */
+enum
+{
+	PROPOSAL_SELECTED,
+	DISPLAY_INFO,
+	LAST_SIGNAL
+};
+
+enum
+{
+	PROP_0,
+	PROP_MANAGE_KEYS,
+	PROP_REMEMBER_INFO_VISIBILITY,
+	PROP_SELECT_ON_SHOW,
+	PROP_ACTIVE
+};
+
+enum
+{
+	TEXT_VIEW_KP,
+	TEXT_VIEW_DESTROY,
+	TEXT_VIEW_FOCUS_OUT,
+	TEXT_VIEW_BUTTON_PRESS,
+	LAST_EXTERNAL_SIGNAL
+};
+
+typedef struct 
+{
+	GtkSourceCompletionTrigger *trigger;
+	GtkSourceCompletionProvider *provider;
+} PTPair;
+
+typedef struct _GtkSourceCompletionPage GtkSourceCompletionPage;
+struct _GtkSourceCompletionPage
+{
+	gchar *name;
+	
+	GtkScrolledWindow *scroll;
+	GtkTreeView *treeview;
+	GtkListStore *list_store;
+	GtkTreeModelFilter *model_filter;
+	
+	gboolean filter_active;
+	gpointer filter_data;
+	GtkSourceCompletionFilterFunc filter_func;
+};
+
+struct _GtkSourceCompletionPriv
+{
+	/* Widget and popup variables*/
+	GtkWidget *info_window;
+	GtkWidget *info_button;
+	GtkWidget *notebook;
+	GtkWidget *tab_label;
+	GtkWidget *next_page_button;
+	GtkWidget *prev_page_button;
+	GtkWidget *bottom_bar;
+	
+	GList *pages;
+	GtkSourceCompletionPage *active_page;
+	gboolean destroy_has_run;
+	gboolean manage_keys;
+	gboolean remember_info_visibility;
+	gboolean info_visible;
+	gboolean select_on_show;
+	
+	/* Completion management */
+	GtkTextView *view;
+	GList *triggers;
+	GList *prov_trig;
+	GtkSourceCompletionTrigger *active_trigger;
+	
+	/*TRUE if the completion mechanism is active*/
+	gboolean active;
+	gulong signals_ids[LAST_EXTERNAL_SIGNAL];
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE(GtkSourceCompletion, gtk_source_completion, GTK_TYPE_WINDOW);
+
+/* **************** GtkTextView-GtkSourceCompletion Control *********** */
+
+/*
+ * We save a map with a GtkTextView and his GtkSourceCompletion. If you 
+ * call twice to gtk_source_completion_proposal_new, the second time it returns
+ * the previous created GtkSourceCompletion, not creates a new one
+ *
+ * FIXME We will remove this functions when we will integrate 
+ * Gsc in GtkSourceView
+ */
+
+static GHashTable *gsccompletion_map = NULL;
+
+static GtkSourceCompletion* 
+completion_control_get_completion (GtkTextView *view)
+{
+	if (gsccompletion_map == NULL)
+		gsccompletion_map = g_hash_table_new (g_direct_hash,
+						      g_direct_equal);
+
+	return g_hash_table_lookup (gsccompletion_map, view);
+}
+
+static void 
+completion_control_add_completion (GtkTextView *view,
+				   GtkSourceCompletion *comp)
+{
+	if (gsccompletion_map == NULL)
+		gsccompletion_map = g_hash_table_new (g_direct_hash,
+						      g_direct_equal);
+	g_hash_table_insert (gsccompletion_map, view, comp);
+}
+
+static void 
+completion_control_remove_completion (GtkTextView *view)
+{
+	if (gsccompletion_map == NULL)
+		gsccompletion_map = g_hash_table_new (g_direct_hash,
+						      g_direct_equal);
+	g_hash_table_remove (gsccompletion_map, view);
+}
+/* ********************************************************************* */
+
+static gboolean
+get_selected_proposal (GtkSourceCompletionPage *page,
+		       GtkSourceCompletionProposal **proposal)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+	GtkTreeSelection *selection;
+	
+	selection = gtk_tree_view_get_selection (page->treeview);
+	
+	if (gtk_tree_selection_get_selected (selection, NULL, &iter))
+	{
+		model = gtk_tree_view_get_model (page->treeview);
+		
+		gtk_tree_model_get (model, &iter,
+				    COLUMN_DATA,
+				    proposal, -1);
+		
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+static gboolean
+select_current_proposal (GtkSourceCompletion *self)
+{
+	gboolean selected = TRUE;
+	GtkSourceCompletionProposal *prop = NULL;
+	
+	if (get_selected_proposal (self->priv->active_page, &prop))
+	{
+		g_signal_emit (G_OBJECT (self), signals[PROPOSAL_SELECTED],
+			       0, prop, &selected);
+		selected = TRUE;
+	}
+	else
+	{
+		selected = FALSE;
+	}
+	
+	return selected;
+}
+
+static gboolean
+select_first_proposal (GtkSourceCompletionPage *page)
+{
+	GtkTreeIter iter;
+	GtkTreePath* path;
+	GtkTreeModel* model;
+	GtkTreeSelection* selection;
+	
+	selection = gtk_tree_view_get_selection (page->treeview);
+
+	if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_NONE)
+		return FALSE;
+
+	model = gtk_tree_view_get_model (page->treeview);
+		
+	if (gtk_tree_model_get_iter_first (model, &iter))
+	{
+		gtk_tree_selection_select_iter (selection, &iter);
+		path = gtk_tree_model_get_path (model, &iter);
+		gtk_tree_view_scroll_to_cell (page->treeview,
+					      path, 
+					      NULL, 
+					      FALSE, 
+					      0, 
+					      0);
+		gtk_tree_path_free (path);
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+static gboolean 
+select_last_proposal (GtkSourceCompletionPage *page)
+{
+	GtkTreeIter iter;
+	GtkTreeModel* model;
+	GtkTreeSelection* selection;
+	GtkTreePath* path;
+	gint children;
+	
+	if (!GTK_WIDGET_VISIBLE (page->treeview))
+		return FALSE;
+	
+	selection = gtk_tree_view_get_selection (page->treeview);
+	model = gtk_tree_view_get_model (page->treeview);
+	
+	if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_NONE)
+		return FALSE;
+	
+	children = gtk_tree_model_iter_n_children (model, NULL);
+	if (children > 0)
+	{
+		gtk_tree_model_iter_nth_child (model, &iter,
+					       NULL, children - 1);
+	
+		gtk_tree_selection_select_iter (selection, &iter);
+		path = gtk_tree_model_get_path (model, &iter);
+		gtk_tree_view_scroll_to_cell (page->treeview,
+					      path, 
+					      NULL, 
+					      FALSE, 
+					      0, 
+					      0);
+		gtk_tree_path_free (path);
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+static gboolean
+select_previous_proposal (GtkSourceCompletionPage *page,
+			  gint rows)
+{
+	GtkTreeIter iter;
+	GtkTreePath* path;
+	GtkTreeModel* model;
+	GtkTreeSelection* selection;
+	
+	if (!GTK_WIDGET_VISIBLE (page->treeview))
+		return FALSE;
+	
+	selection = gtk_tree_view_get_selection (page->treeview);
+	
+	if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_NONE)
+		return FALSE;
+	
+	if (gtk_tree_selection_get_selected (selection, &model, &iter))
+	{
+		gint i;
+		
+		path = gtk_tree_model_get_path (model, &iter);
+		
+		for (i=0; i  < rows; i++)
+			gtk_tree_path_prev (path);
+		
+		if (gtk_tree_model_get_iter(model, &iter, path))
+		{
+			gtk_tree_selection_select_iter (selection, &iter);
+			gtk_tree_view_scroll_to_cell (page->treeview,
+						      path, 
+						      NULL, 
+						      FALSE, 
+						      0, 
+						      0);
+		}
+		gtk_tree_path_free (path);
+	}
+	else
+	{
+		return select_first_proposal (page);
+	}
+	
+	return TRUE;
+}
+
+static gboolean
+select_next_proposal (GtkSourceCompletionPage *page,
+		      gint rows)
+{
+	GtkTreeIter iter;
+	GtkTreeModel* model;
+	GtkTreeSelection* selection;
+	
+	if (!GTK_WIDGET_VISIBLE (page->treeview))
+		return FALSE;
+	
+	selection = gtk_tree_view_get_selection (page->treeview);
+	if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_NONE)
+		return FALSE;
+	
+	if (gtk_tree_selection_get_selected (selection, &model, &iter))
+	{
+		GtkTreePath* path;
+		gint i;
+		
+		for (i = 0; i < rows; i++)
+		{
+			if (!gtk_tree_model_iter_next (model, &iter))
+				return select_last_proposal (page);
+		}
+		gtk_tree_selection_select_iter (selection, &iter);
+		path = gtk_tree_model_get_path (model, &iter);
+		gtk_tree_view_scroll_to_cell (page->treeview,
+					      path, 
+					      NULL, 
+					      FALSE, 
+					      0, 
+					      0);
+		gtk_tree_path_free (path);
+	}
+	else
+	{
+		return select_first_proposal (page);
+	}
+	
+	return TRUE;
+}
+
+static void
+update_info_pos (GtkSourceCompletion *self)
+{
+	GtkSourceCompletionProposal *proposal = NULL;
+	gint y, x, sw, sh;
+	
+	if (get_selected_proposal (self->priv->active_page, &proposal))
+	{
+		gboolean ret = TRUE;
+		g_signal_emit (self, signals[DISPLAY_INFO], 0, proposal, &ret);
+	}
+	
+	gtk_window_get_position (GTK_WINDOW (self), &x, &y);
+	sw = gdk_screen_width ();
+	sh = gdk_screen_height ();
+	x += WINDOW_WIDTH;
+
+	if (x + WINDOW_WIDTH >= sw)
+	{
+		x -= (WINDOW_WIDTH * 2);
+	}
+	gtk_window_move (GTK_WINDOW (self->priv->info_window), x, y);
+	gtk_window_set_transient_for (GTK_WINDOW (self->priv->info_window),
+				      gtk_window_get_transient_for (GTK_WINDOW (self)));
+}
+
+static gboolean
+filter_func (GtkTreeModel *model,
+	     GtkTreeIter *iter,
+	     gpointer data)
+{
+	GtkSourceCompletionPage *page = (GtkSourceCompletionPage *)data;
+	GtkSourceCompletionProposal *proposal = NULL;
+	
+	if (!page->filter_active || !page->filter_func)
+		return TRUE;
+		
+	gtk_tree_model_get (model,
+			    iter,
+			    COLUMN_DATA,
+			    &proposal,
+			    -1);
+	
+	if (proposal == NULL)
+		return TRUE;
+	
+	return page->filter_func (proposal, page->filter_data);
+}
+
+static void
+row_activated_cb (GtkTreeView *tree_view,
+		  GtkTreePath *path,
+		  GtkTreeViewColumn *column,
+		  GtkSourceCompletion *self)
+{
+	select_current_proposal (self);
+}
+
+static void 
+selection_changed_cd (GtkTreeSelection *selection, 
+		      GtkSourceCompletion *self)
+{
+	if (GTK_WIDGET_VISIBLE (self->priv->info_window))
+	{
+		update_info_pos (self);
+	}
+}
+
+static void
+add_proposal (GtkSourceCompletionPage *page,
+	      GtkSourceCompletionProposal *data)
+{
+	GtkTreeIter iter;
+
+	g_assert (data != NULL);
+	
+	gtk_list_store_append (page->list_store, &iter);
+			
+	gtk_list_store_set (page->list_store, 
+			    &iter,
+			    COLUMN_PIXBUF, gtk_source_completion_proposal_get_icon (data),
+			    COLUMN_NAME, gtk_source_completion_proposal_get_label (data),
+			    COLUMN_DATA, data,
+			    -1);
+}
+
+static void
+clear_treeview (GtkSourceCompletionPage *page)
+{
+	GtkTreeModel *model = GTK_TREE_MODEL (page->list_store);
+	GtkTreeIter iter;
+	GtkSourceCompletionProposal *data;
+	
+	if (gtk_tree_model_get_iter_first (model, &iter))
+	{
+		do
+		{
+			gtk_tree_model_get (model, &iter,
+					    COLUMN_DATA, &data, -1);
+			g_object_unref (data);
+		} while (gtk_tree_model_iter_next (model, &iter));
+	}
+	
+	gtk_list_store_clear (page->list_store);
+}
+
+static gint 
+get_num_proposals (GtkSourceCompletionPage *page)
+{
+	GtkTreeModel *model = gtk_tree_view_get_model (page->treeview);
+	
+	return gtk_tree_model_iter_n_children (model, NULL);
+}
+
+static void
+filter_visible (GtkSourceCompletionPage *page,
+		GtkSourceCompletionFilterFunc func,
+		gpointer user_data)
+{
+	page->filter_active = TRUE;
+	page->filter_data = user_data;
+	page->filter_func = func;
+	gtk_tree_model_filter_refilter (page->model_filter);
+	page->filter_active = FALSE;
+	page->filter_data = NULL;
+	page->filter_func = NULL;
+}
+
+static void
+free_pair (gpointer data)
+{
+	PTPair *ptp = (PTPair *)data;
+	g_object_unref (ptp->provider);
+	g_slice_free (PTPair, ptp);
+}
+
+static void
+end_completion (GtkSourceCompletion *self)
+{
+	if (GTK_WIDGET_VISIBLE (self))
+	{
+		gtk_widget_hide (GTK_WIDGET (self));
+		/*
+		* We are connected to the hide signal too. Then end_completion 
+		* will be called again but the popup will not be visible
+		*/
+	}
+	else
+	{
+		GList *l;
+		
+		for (l = self->priv->prov_trig; l != NULL; l = g_list_next (l))
+		{
+			PTPair *ptp = (PTPair *)l->data;
+			if (ptp->trigger == self->priv->active_trigger)
+				gtk_source_completion_provider_finish (GTK_SOURCE_COMPLETION_PROVIDER (ptp->provider));
+		}
+		
+		self->priv->active_trigger = NULL;
+	}
+}
+
+static void
+gtk_source_completion_clear (GtkSourceCompletion *self)
+{
+	GList *l;
+	
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION (self));
+	
+	for (l = self->priv->pages; l != NULL; l = g_list_next (l))
+	{
+		GtkSourceCompletionPage *page = (GtkSourceCompletionPage *)l->data;
+		
+		clear_treeview (page);
+	}
+}
+
+static gboolean
+update_pages_visibility (GtkSourceCompletion *self)
+{
+	GList *l;
+	gboolean first_set = FALSE;
+	guint num_pages_with_data = 0;
+	gint i = 0;
+	GtkAdjustment *ad;
+	
+	for (l = self->priv->pages; l != NULL; l = g_list_next (l))
+	{
+		GtkSourceCompletionPage *page = (GtkSourceCompletionPage *)l->data;
+		
+		if (get_num_proposals (page) > 0)
+		{
+			/*Selects the first page with data*/
+			if (!first_set)
+			{
+				gtk_notebook_set_current_page (GTK_NOTEBOOK (self->priv->notebook),
+							       i);
+				ad = gtk_tree_view_get_vadjustment (page->treeview);
+				gtk_adjustment_set_value (ad, 0);
+				ad = gtk_tree_view_get_hadjustment (page->treeview);
+				gtk_adjustment_set_value (ad, 0);
+				first_set = TRUE;
+			}
+			num_pages_with_data++;
+		}
+		i++;
+	}
+	if (num_pages_with_data > 1)
+	{
+		gtk_widget_show (self->priv->next_page_button);
+		gtk_widget_show (self->priv->prev_page_button);
+	}
+	else
+	{
+		gtk_widget_hide (self->priv->next_page_button);
+		gtk_widget_hide (self->priv->prev_page_button);
+	}
+	
+	return num_pages_with_data > 0;
+}
+
+static void
+gtk_source_completion_show_or_update (GtkWidget *widget)
+{
+	gboolean data;
+	
+	/*Only show the popup, the positions is set before this function*/
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (widget);
+	
+	data = update_pages_visibility (self);
+	
+	if (data && !GTK_WIDGET_VISIBLE (self))
+	{
+		GTK_WIDGET_CLASS (gtk_source_completion_parent_class)->show (widget);
+		
+		if (!self->priv->remember_info_visibility)
+			self->priv->info_visible = FALSE;
+		
+		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->info_button),
+					      self->priv->info_visible);
+	}
+}
+
+static void
+gtk_source_completion_page_next (GtkSourceCompletion *self)
+{
+	gint pages;
+	gint current_page;
+	gint page;
+	GtkSourceCompletionPage *popup_page;
+	
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION (self));
+
+	pages = g_list_length (self->priv->pages);
+	current_page = g_list_index (self->priv->pages, self->priv->active_page);
+	page = current_page;
+	
+	do
+	{
+		if (page == pages - 1)
+		{
+			page = 0;
+		}
+		else
+		{
+			page++;
+		}
+		popup_page = (GtkSourceCompletionPage *)g_list_nth_data (self->priv->pages, page);
+	}
+	while (get_num_proposals (popup_page) == 0 &&
+	       page != current_page);
+
+	if (page != current_page)
+	{
+		gtk_notebook_set_current_page (GTK_NOTEBOOK (self->priv->notebook),
+					       page);
+	
+		/*
+		 * After setting the page the active_page was updated
+		 * so we can update the tree
+		 */
+		select_first_proposal (popup_page);
+	
+		if (GTK_WIDGET_VISIBLE (self->priv->info_window))
+		{
+			update_info_pos (self);
+		}
+	}
+}
+
+static void
+gtk_source_completion_page_previous (GtkSourceCompletion *self)
+{
+	gint pages;
+	gint current_page;
+	gint page;
+	GtkSourceCompletionPage *popup_page;
+	
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION (self));
+	
+	pages = g_list_length (self->priv->pages);
+	current_page = g_list_index (self->priv->pages,
+				     self->priv->active_page);
+	page = current_page;
+	
+	do
+	{
+		if (page == 0)
+		{
+			page = pages - 1;
+		}
+		else
+		{
+			page--;
+		}
+		popup_page = (GtkSourceCompletionPage *)g_list_nth_data (self->priv->pages,
+									 page);
+	}
+	while (get_num_proposals (popup_page) == 0 &&
+	       page != current_page);
+	
+	if (page != current_page)
+	{
+		gtk_notebook_set_current_page (GTK_NOTEBOOK (self->priv->notebook),
+					       page);
+	
+		/*
+		 * After setting the page the active_page was updated
+		 * so we can update the tree
+		 */
+		select_first_proposal (popup_page);
+	
+		if (GTK_WIDGET_VISIBLE (self->priv->info_window))
+		{
+			update_info_pos (self);
+		}
+	}
+}
+
+static GtkSourceCompletionPage *
+gtk_source_completion_page_new (GtkSourceCompletion *self,
+				const gchar *tree_name)
+{
+	/*Creates the new trees*/
+	GtkSourceCompletionPage *page;
+	GtkCellRenderer *renderer;
+	GtkTreeViewColumn *column;
+	GtkCellRenderer* renderer_pixbuf;
+	GtkTreeViewColumn* column_pixbuf;
+	GtkTreeModel *model;
+	GtkTreeSelection *selection;
+	GtkWidget *label;
+	
+	page = g_slice_new (GtkSourceCompletionPage);
+	
+	page->name = g_strdup (tree_name);
+	
+	page->treeview = GTK_TREE_VIEW (gtk_tree_view_new ());
+	gtk_widget_show (GTK_WIDGET (page->treeview));
+	
+	page->filter_data = NULL;
+	page->filter_active = FALSE;
+	page->filter_func = NULL;
+
+	g_object_set (page->treeview, "can-focus", FALSE, NULL);
+	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (page->treeview),
+					   FALSE);
+	
+	/* Create the Tree */
+	renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
+	column_pixbuf = gtk_tree_view_column_new_with_attributes ("Pixbuf",
+								  renderer_pixbuf, 
+								  "pixbuf", 
+								  COLUMN_PIXBUF, 
+								  NULL);
+	
+	column = gtk_tree_view_column_new ();
+	renderer = gtk_cell_renderer_text_new ();
+	gtk_tree_view_column_pack_start (column, renderer, FALSE);
+	gtk_tree_view_column_set_attributes (column, renderer,
+					     "text", COLUMN_NAME, NULL);
+
+	gtk_tree_view_append_column (page->treeview, column_pixbuf);
+	gtk_tree_view_append_column (page->treeview, column);
+	
+	/* Create the model */
+	page->list_store = gtk_list_store_new (N_COLUMNS,
+					       GDK_TYPE_PIXBUF, 
+					       G_TYPE_STRING, 
+					       G_TYPE_POINTER);
+	
+	model = gtk_tree_model_filter_new (GTK_TREE_MODEL (page->list_store),
+					   NULL);
+
+	page->model_filter = GTK_TREE_MODEL_FILTER (model);
+	
+	gtk_tree_model_filter_set_visible_func (page->model_filter,
+						filter_func,
+						page,
+						NULL);
+
+	gtk_tree_view_set_model (page->treeview,
+				 model);
+	
+	g_signal_connect (page->treeview,
+			  "row-activated",
+			  G_CALLBACK (row_activated_cb),
+			  self);
+	
+	selection = gtk_tree_view_get_selection (page->treeview);
+	g_signal_connect (selection,
+			  "changed",
+			  G_CALLBACK (selection_changed_cd),
+			  self);
+	
+	self->priv->pages = g_list_append (self->priv->pages,
+					   page);
+	
+	page->scroll = GTK_SCROLLED_WINDOW (gtk_scrolled_window_new (NULL, NULL));
+	gtk_widget_show (GTK_WIDGET (page->scroll));
+	
+	gtk_scrolled_window_set_policy (page->scroll,
+					GTK_POLICY_AUTOMATIC,
+					GTK_POLICY_AUTOMATIC);
+	
+	gtk_container_add (GTK_CONTAINER (page->scroll),
+			   GTK_WIDGET (page->treeview));
+	
+	label = gtk_label_new (tree_name);
+	
+	gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook),
+				  GTK_WIDGET (page->scroll),
+				  label);
+	
+	return page;
+}
+
+static GtkSourceCompletionPage *
+get_page_by_name (GtkSourceCompletion *self,
+		  const gchar* tree_name)
+{
+	GtkSourceCompletionPage *page;
+	GList *l;
+	
+	for (l = self->priv->pages; l != NULL; l = g_list_next (l))
+	{
+		page = (GtkSourceCompletionPage *)l->data;
+	
+		if (strcmp (page->name, tree_name) == 0)
+			return page;
+	}
+	
+	page = gtk_source_completion_page_new (self, tree_name);
+
+	return page;
+}
+
+static void
+info_toggled_cb (GtkToggleButton *widget,
+		 gpointer user_data)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (user_data);
+	
+	if (gtk_toggle_button_get_active (widget))
+	{
+		gtk_widget_show (self->priv->info_window);
+	}
+	else
+	{
+		gtk_widget_hide (self->priv->info_window);
+	}
+}
+
+static void
+next_page_cb (GtkWidget *widget,
+	      gpointer user_data)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (user_data);
+	
+	gtk_source_completion_page_next (self);
+}
+
+static void
+prev_page_cb (GtkWidget *widget,
+	      gpointer user_data)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (user_data);
+	
+	gtk_source_completion_page_previous (self);
+}
+
+static gboolean
+switch_page_cb (GtkNotebook *notebook, 
+		GtkNotebookPage *n_page,
+		gint page_num, 
+		gpointer user_data)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (user_data);
+	
+	/* Update the active page */
+	self->priv->active_page = (GtkSourceCompletionPage *)g_list_nth_data (self->priv->pages,
+									      page_num);
+	
+	gtk_label_set_label (GTK_LABEL (self->priv->tab_label),
+			     self->priv->active_page->name);
+
+	return FALSE;
+}
+
+static void
+show_info_cb (GtkWidget *widget,
+	      gpointer user_data)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (user_data);
+	
+	g_return_if_fail (GTK_WIDGET_VISIBLE (GTK_WIDGET (self)));
+	
+	update_info_pos (self);
+	self->priv->info_visible = TRUE;
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->info_button),
+				      TRUE);
+}
+
+static void
+hide_info_cb (GtkWidget *widget,
+	      gpointer user_data)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (user_data);
+	
+	self->priv->info_visible = FALSE;
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->info_button),
+				      FALSE);
+}
+
+static gboolean
+gtk_source_completion_display_info_default (GtkSourceCompletion *self,
+					    GtkSourceCompletionProposal *proposal)
+{
+	if (proposal)
+	{
+		const gchar *info;
+		
+		info = gtk_source_completion_proposal_get_info (proposal);
+		
+		if (info != NULL)
+		{
+			gtk_source_completion_info_set_markup (GTK_SOURCE_COMPLETION_INFO (self->priv->info_window),
+							       info);
+		}
+		else
+		{
+			gtk_source_completion_info_set_markup (GTK_SOURCE_COMPLETION_INFO (self->priv->info_window),
+							       _("There is no info for the current proposal"));
+		}
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+static gboolean
+gtk_source_completion_proposal_selected_default (GtkSourceCompletion *self,
+						 GtkSourceCompletionProposal *proposal)
+{
+	gtk_source_completion_proposal_apply (proposal, self->priv->view);
+	end_completion (self);
+	
+	return FALSE;
+}
+
+static void
+gtk_source_completion_hide (GtkWidget *widget)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (widget);
+	gboolean info_visible = self->priv->info_visible;
+	
+	GTK_WIDGET_CLASS (gtk_source_completion_parent_class)->hide (widget);
+	
+	//setting to FALSE, hide the info window
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->info_button),
+				      FALSE);
+	
+	self->priv->info_visible = info_visible;
+}
+
+static void
+gtk_source_completion_realize (GtkWidget *widget)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (widget);
+	
+	gtk_container_set_border_width (GTK_CONTAINER (self), 1);
+	gtk_widget_set_size_request (GTK_WIDGET (self),
+				     WINDOW_WIDTH, WINDOW_HEIGHT);
+	gtk_window_set_resizable (GTK_WINDOW (self), TRUE);
+	
+	GTK_WIDGET_CLASS (gtk_source_completion_parent_class)->realize (widget);
+}
+
+static gboolean
+gtk_source_completion_delete_event_cb (GtkWidget *widget,
+				       GdkEvent  *event,
+				       gpointer   user_data) 
+{
+	/*Prevent the alt+F4 keys*/
+	return TRUE;
+}
+
+static void
+free_page (gpointer data,
+	   gpointer user_data)
+{
+	GtkSourceCompletionPage *page = (GtkSourceCompletionPage *)data;
+	
+	g_free (page->name);
+	g_slice_free (GtkSourceCompletionPage, page);
+}
+
+static gboolean
+gtk_source_completion_configure_event (GtkWidget *widget,
+				       GdkEventConfigure *event)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (widget);
+	gboolean ret;
+	
+	ret = GTK_WIDGET_CLASS (gtk_source_completion_parent_class)->configure_event (widget, event);
+	
+	if (GTK_WIDGET_VISIBLE (self->priv->info_window))
+		update_info_pos (self);
+	
+	return ret;
+}
+
+static void
+gtk_source_completion_finalize (GObject *object)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (object);
+	
+	if (self->priv->active)
+		gtk_source_completion_set_active (self, FALSE);
+	
+	g_list_foreach (self->priv->pages, (GFunc) free_page, NULL);
+	g_list_free (self->priv->pages);
+	
+	if (self->priv->triggers != NULL)
+	{
+		g_list_foreach (self->priv->triggers, (GFunc) g_object_unref,
+				NULL);
+		g_list_free (self->priv->triggers);
+	}
+	
+	if (self->priv->prov_trig != NULL)
+	{
+		g_list_foreach (self->priv->prov_trig, (GFunc) free_pair,
+				NULL);
+		g_list_free (self->priv->prov_trig);
+	}
+	
+	completion_control_remove_completion(self->priv->view);
+	
+	G_OBJECT_CLASS (gtk_source_completion_parent_class)->finalize (object);
+}
+
+static void
+gtk_source_completion_destroy (GtkObject *object)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (object);
+	
+	if (!self->priv->destroy_has_run)
+	{
+		gtk_source_completion_clear (self);
+		self->priv->destroy_has_run = TRUE;
+	}
+	GTK_OBJECT_CLASS (gtk_source_completion_parent_class)->destroy (object);
+}
+
+static gboolean
+view_key_press_event_cb (GtkWidget *view,
+			 GdkEventKey *event, 
+			 gpointer user_data)
+{
+	gboolean ret = FALSE;
+	GtkSourceCompletion *self;
+	
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION (user_data), FALSE);
+	
+	self = GTK_SOURCE_COMPLETION (user_data);
+	
+	if (!GTK_WIDGET_VISIBLE (self))
+		return FALSE;
+	
+	switch (event->keyval)
+ 	{
+		case GDK_Escape:
+		{
+			gtk_widget_hide (GTK_WIDGET (self));
+			ret = TRUE;
+			break;
+		}
+ 		case GDK_Down:
+		{
+			ret = select_next_proposal (self->priv->active_page, 1);
+			break;
+		}
+		case GDK_Page_Down:
+		{
+			ret = select_next_proposal (self->priv->active_page, 5);
+			break;
+		}
+		case GDK_Up:
+		{
+			ret = select_previous_proposal (self->priv->active_page, 1);
+			if (!ret)
+				ret = select_first_proposal (self->priv->active_page);
+			break;
+		}
+		case GDK_Page_Up:
+		{
+			ret = select_previous_proposal (self->priv->active_page, 5);
+			break;
+		}
+		case GDK_Home:
+		{
+			ret = select_first_proposal (self->priv->active_page);
+			break;
+		}
+		case GDK_End:
+		{
+			ret = select_last_proposal (self->priv->active_page);
+			break;
+		}
+		case GDK_Return:
+		case GDK_Tab:
+		{
+			ret = select_current_proposal (self);
+			gtk_widget_hide (GTK_WIDGET (self));
+			break;
+		}
+		case GDK_Right:
+		{
+			gtk_source_completion_page_next (self);
+			ret = TRUE;
+			break;
+		}
+		case GDK_Left:
+		{
+			gtk_source_completion_page_previous (self);
+			ret = TRUE;
+			break;
+		}
+		case GDK_i:
+		{
+			if ((event->state & GDK_CONTROL_MASK) != 0)
+			{
+				gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->info_button),
+					!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->priv->info_button)));
+				ret = TRUE;
+			}
+		}
+	}
+	return ret;
+}
+
+static void
+set_manage_keys (GtkSourceCompletion *self)
+{
+	if (self->priv->manage_keys && self->priv->signals_ids[TEXT_VIEW_KP] == 0)
+	{
+		self->priv->signals_ids[TEXT_VIEW_KP] = 
+			g_signal_connect (self->priv->view,
+					  "key-press-event",
+					  G_CALLBACK (view_key_press_event_cb),
+					  self);
+	}
+	
+	if (!self->priv->manage_keys && self->priv->signals_ids[TEXT_VIEW_KP] != 0)
+	{
+		g_signal_handler_disconnect (self->priv->view,
+					     self->priv->signals_ids[TEXT_VIEW_KP]);
+		self->priv->signals_ids[TEXT_VIEW_KP] = 0;
+	}
+}
+
+static void
+gtk_source_completion_get_property (GObject    *object,
+				    guint       prop_id,
+				    GValue     *value,
+				    GParamSpec *pspec)
+{
+	GtkSourceCompletion *self;
+	
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION (object));
+	
+	self = GTK_SOURCE_COMPLETION (object);
+
+	switch (prop_id)
+	{
+		case PROP_MANAGE_KEYS:
+			g_value_set_boolean (value, self->priv->manage_keys);
+			break;
+		case PROP_REMEMBER_INFO_VISIBILITY:
+			g_value_set_boolean (value, self->priv->remember_info_visibility);
+			break;
+		case PROP_SELECT_ON_SHOW:
+			g_value_set_boolean (value, self->priv->select_on_show);
+			break;
+		case PROP_ACTIVE:
+			g_value_set_boolean (value, self->priv->active);
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
+gtk_source_completion_set_property (GObject      *object,
+				    guint         prop_id,
+				    const GValue *value,
+				    GParamSpec   *pspec)
+{
+	GtkSourceCompletion *self;
+	
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION (object));
+	
+	self = GTK_SOURCE_COMPLETION (object);
+
+	switch (prop_id)
+	{
+		case PROP_MANAGE_KEYS:
+			self->priv->manage_keys = g_value_get_boolean (value);
+			set_manage_keys (self);
+			break;
+		case PROP_REMEMBER_INFO_VISIBILITY:
+			self->priv->remember_info_visibility = g_value_get_boolean (value);
+			break;
+		case PROP_SELECT_ON_SHOW:
+			self->priv->select_on_show = g_value_get_boolean (value);
+			break;
+		case PROP_ACTIVE:
+			gtk_source_completion_set_active (self, g_value_get_boolean (value));
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
+gtk_source_completion_class_init (GtkSourceCompletionClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+	
+	g_type_class_add_private (klass, sizeof (GtkSourceCompletionPriv));
+	
+	object_class->get_property = gtk_source_completion_get_property;
+	object_class->set_property = gtk_source_completion_set_property;
+	object_class->finalize = gtk_source_completion_finalize;
+	gtkobject_class->destroy = gtk_source_completion_destroy;
+	widget_class->show = gtk_source_completion_show_or_update;
+	widget_class->hide = gtk_source_completion_hide;
+	widget_class->realize = gtk_source_completion_realize;
+	widget_class->configure_event = gtk_source_completion_configure_event;
+	klass->display_info = gtk_source_completion_display_info_default;
+	klass->proposal_selected = gtk_source_completion_proposal_selected_default;
+	
+	/**
+	 * GtkSourceCompletion:manage-completion-keys:
+	 *
+	 * %TRUE if this object must control the completion keys pressed into the
+	 * #GtkTextView associated (up next proposal, down previous proposal etc.)
+	 */
+	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"),
+							      TRUE,
+							      G_PARAM_READWRITE));
+	/**
+	 * GtkSourceCompletion:remember-info-visibility:
+	 *
+	 * %TRUE if the completion must remember the last info state
+	 * (visible or hidden)
+	 */
+	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)"),
+							      FALSE,
+							      G_PARAM_READWRITE));
+	/**
+	 * GtkSourceCompletion:select-on-show:
+	 *
+	 * %TRUE if the completion must to mark as selected the first proposal
+	 * on show (and when the filter is updated)
+	 */
+	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,
+							      G_PARAM_READWRITE));
+	/**
+	 * GtkSourceCompletion:active:
+	 *
+	 * %TRUE if the completion mechanism is active. 
+	 */
+	g_object_class_install_property (object_class,
+					 PROP_ACTIVE,
+					 g_param_spec_boolean ("active",
+							      _("Set or get if the completion mechanism is active"),
+							      _("Set or get if the completion mechanism is active"),
+							      FALSE,
+							      G_PARAM_READWRITE));
+	/**
+	 * GtkSourceCompletion::proposal-selected:
+	 * @completion: The #GtkSourceCompletion who emits the signal
+	 * @proposal: The selected #GtkSourceCompletionProposal
+	 *
+	 * When the user selects a proposal
+	 **/
+	signals[PROPOSAL_SELECTED] =
+		g_signal_new ("proposal-selected",
+			      G_TYPE_FROM_CLASS (klass),
+			      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+			      G_STRUCT_OFFSET (GtkSourceCompletionClass, proposal_selected),
+			      g_signal_accumulator_true_handled, 
+			      NULL,
+			      gtksourcecompletion_marshal_BOOLEAN__POINTER, 
+			      G_TYPE_BOOLEAN,
+			      1,
+			      GTK_TYPE_POINTER);
+	
+	/**
+	 * GtkSourceCompletion::display-info:
+	 * @completion: The #GtkSourceCompletion who emits the signal
+	 * @proposal: The #GtkSourceCompletionProposal the user wants to see the information
+	 *
+	 * When the user want to see the information of a proposal
+	 **/	      
+	signals[DISPLAY_INFO] =
+		g_signal_new ("display-info",
+			      G_TYPE_FROM_CLASS (klass),
+			      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+			      G_STRUCT_OFFSET (GtkSourceCompletionClass, display_info),
+			      g_signal_accumulator_true_handled, 
+			      NULL,
+			      gtksourcecompletion_marshal_BOOLEAN__POINTER,
+			      G_TYPE_BOOLEAN,
+			      1,
+			      GTK_TYPE_POINTER);
+}
+
+static void
+gtk_source_completion_init (GtkSourceCompletion *self)
+{
+	GtkWidget *info_icon;
+	GtkWidget *info_button;
+	GtkWidget *next_page_icon;
+	GtkWidget *prev_page_icon;
+	GtkWidget *vbox;
+
+	if (!lib_initialized)
+	{
+		bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
+		bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+		lib_initialized = TRUE;
+	}
+
+	self->priv = GTK_SOURCE_COMPLETION_GET_PRIVATE (self);
+	self->priv->destroy_has_run = FALSE;
+	self->priv->active_trigger = NULL;
+	self->priv->active = FALSE;
+	self->priv->manage_keys = TRUE;
+	self->priv->remember_info_visibility = FALSE;
+	self->priv->info_visible = FALSE;
+	self->priv->select_on_show = FALSE;
+
+	gtk_window_set_type_hint (GTK_WINDOW (self),
+				  GDK_WINDOW_TYPE_HINT_NORMAL);
+	gtk_window_set_focus_on_map (GTK_WINDOW (self), FALSE);
+	gtk_widget_set_size_request (GTK_WIDGET (self),
+				     WINDOW_WIDTH,WINDOW_HEIGHT);
+	gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
+	
+	/*Notebook*/
+	self->priv->notebook = gtk_notebook_new ();
+	gtk_widget_show (self->priv->notebook);
+	g_object_set (G_OBJECT (self->priv->notebook), "can-focus",
+		      FALSE, NULL);
+	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (self->priv->notebook), FALSE);
+	gtk_notebook_set_show_border (GTK_NOTEBOOK (self->priv->notebook),
+				      FALSE);
+	
+	/* Add default page */
+	self->priv->active_page = gtk_source_completion_page_new (self, DEFAULT_PAGE);
+	
+	/*Icon list*/
+	info_icon = gtk_image_new_from_stock (GTK_STOCK_INFO,
+					      GTK_ICON_SIZE_SMALL_TOOLBAR);
+	gtk_widget_show (info_icon);
+	gtk_widget_set_tooltip_text (info_icon, _("Show Proposal Info"));
+	
+	info_button = gtk_toggle_button_new ();
+	gtk_widget_show (info_button);
+	g_object_set (G_OBJECT (info_button), "can-focus", FALSE, NULL);
+	
+	self->priv->info_button = info_button;
+	gtk_button_set_focus_on_click (GTK_BUTTON (info_button), FALSE);
+	gtk_container_add (GTK_CONTAINER (info_button), info_icon);
+	g_signal_connect (G_OBJECT (info_button),
+			  "toggled",
+			  G_CALLBACK (info_toggled_cb),
+			  self);
+
+	self->priv->bottom_bar = gtk_hbox_new (FALSE, 1);
+	gtk_widget_show (self->priv->bottom_bar);
+	gtk_box_pack_start (GTK_BOX (self->priv->bottom_bar), info_button,
+			    FALSE, FALSE, 0);
+
+	/*Next/Previous page buttons*/
+	
+	next_page_icon = gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD,
+						   GTK_ICON_SIZE_SMALL_TOOLBAR);
+	gtk_widget_show (next_page_icon);
+	prev_page_icon = gtk_image_new_from_stock (GTK_STOCK_GO_BACK,
+						   GTK_ICON_SIZE_SMALL_TOOLBAR);
+	gtk_widget_show (prev_page_icon);
+	
+	self->priv->next_page_button = gtk_button_new ();
+	gtk_widget_show (self->priv->next_page_button);
+	g_object_set (G_OBJECT (self->priv->next_page_button),
+		      "can-focus", FALSE,
+		      "focus-on-click", FALSE,
+		      NULL);
+	gtk_widget_set_tooltip_text (self->priv->next_page_button,
+				     _("Next page"));
+	gtk_container_add (GTK_CONTAINER (self->priv->next_page_button),
+			   next_page_icon);
+	g_signal_connect (G_OBJECT (self->priv->next_page_button),
+			  "clicked",
+			  G_CALLBACK (next_page_cb),
+			  self);
+	
+	self->priv->prev_page_button = gtk_button_new ();
+	gtk_widget_show (self->priv->prev_page_button);
+	g_object_set (G_OBJECT (self->priv->prev_page_button),
+		      "can-focus", FALSE,
+		      "focus-on-click", FALSE,
+		      NULL);
+	gtk_widget_set_tooltip_text (self->priv->prev_page_button,
+				     _("Previous page"));
+	gtk_container_add (GTK_CONTAINER (self->priv->prev_page_button),
+			   prev_page_icon);
+	g_signal_connect (G_OBJECT (self->priv->prev_page_button),
+			  "clicked",
+			  G_CALLBACK (prev_page_cb),
+			  self);
+
+	gtk_box_pack_end (GTK_BOX (self->priv->bottom_bar),
+			  self->priv->next_page_button,
+			  FALSE, FALSE, 1);
+	gtk_box_pack_end (GTK_BOX (self->priv->bottom_bar),
+			  self->priv->prev_page_button,
+			  FALSE, FALSE, 1);
+	/*Page label*/
+	self->priv->tab_label = gtk_label_new (DEFAULT_PAGE);
+	gtk_widget_show (self->priv->tab_label);
+	gtk_box_pack_end (GTK_BOX (self->priv->bottom_bar),
+			  self->priv->tab_label,
+			  FALSE, TRUE, 10);
+	
+	/*Main vbox*/
+	vbox = gtk_vbox_new (FALSE, 1);
+	gtk_widget_show (vbox);
+	gtk_box_pack_start (GTK_BOX (vbox), self->priv->notebook,
+			    TRUE, TRUE, 0);
+
+	gtk_box_pack_end (GTK_BOX (vbox), self->priv->bottom_bar,
+			  FALSE, FALSE, 0);
+
+	gtk_container_add (GTK_CONTAINER (self), vbox);
+
+	/*Info window*/
+	self->priv->info_window = GTK_WIDGET (gtk_source_completion_info_new ());
+
+	/* Connect signals */
+			
+	g_signal_connect (self->priv->notebook, 
+			  "switch-page",
+			  G_CALLBACK (switch_page_cb),
+			  self);
+			
+	g_signal_connect (self,
+			  "delete-event",
+			  G_CALLBACK (gtk_source_completion_delete_event_cb),
+			  NULL);
+
+	g_signal_connect (self->priv->info_window,
+			  "show-info",
+			  G_CALLBACK (show_info_cb),
+			  self);
+			  
+	g_signal_connect (self->priv->info_window,
+			  "hide",
+			  G_CALLBACK (hide_info_cb),
+			  self);
+
+	self->priv->triggers = NULL;
+	self->priv->prov_trig = NULL;
+}
+
+static void
+view_destroy_event_cb (GtkWidget *widget,
+		       gpointer user_data)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (user_data);
+	
+	g_object_unref (self);
+}
+
+static gboolean
+view_focus_out_event_cb (GtkWidget *widget,
+			 GdkEventFocus *event,
+			 gpointer user_data)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (user_data);
+	
+	if (GTK_WIDGET_VISIBLE (self)
+	    && !GTK_WIDGET_HAS_FOCUS (self))
+		end_completion (self);
+	
+	return FALSE;
+}
+
+static gboolean
+view_button_press_event_cb (GtkWidget *widget,
+			    GdkEventButton *event,
+			    gpointer user_data)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (user_data);
+	
+	if (GTK_WIDGET_VISIBLE (self))
+		end_completion (self);
+
+	return FALSE;
+}
+
+/**
+ * gtk_source_completion_new:
+ *
+ * Returns The new #GtkSourceCompletion
+ */
+GtkWidget*
+gtk_source_completion_new (GtkTextView *view)
+{
+	GtkSourceCompletion *self = GTK_SOURCE_COMPLETION (g_object_new (GTK_TYPE_SOURCE_COMPLETION,
+									 "type", GTK_WINDOW_POPUP,
+									 NULL));
+	self->priv->view = view;
+	
+	completion_control_add_completion (view, self);
+	
+	return GTK_WIDGET (self);
+}
+
+/**
+ * gtk_source_completion_register_trigger:
+ * @self: The #GtkSourceCompletion
+ * @trigger: The trigger to register
+ *
+ * This function register a completion trigger. If the completion is actived
+ * then this method activate the trigger. This function reference the trigger
+ * object
+ *
+ * Returns: %TRUE if the trigger has been registered
+ */
+gboolean
+gtk_source_completion_register_trigger (GtkSourceCompletion *self,
+					GtkSourceCompletionTrigger *trigger)
+{
+	GList *l;
+	
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION (self), FALSE);
+	
+	l = g_list_find (self->priv->triggers, trigger);
+	/*Only register the trigger if it has not been registered yet*/
+	if (l == NULL)
+	{
+	
+		self->priv->triggers = g_list_append (self->priv->triggers,
+						      trigger);
+		g_object_ref (trigger);
+		
+		if (self->priv->active)
+		{
+			gtk_source_completion_trigger_activate (trigger);
+		}
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+/**
+ * gtk_source_completion_register_provider:
+ * @self: the #GtkSourceCompletion
+ * @provider: The #GtkSourceCompletionProvider.
+ * @trigger_name: The trigger name what you want to register this provider
+ *
+ * This function register the provider into the completion and reference it. When 
+ * an event is raised, completion call to the provider to get the data. When the user
+ * select a proposal, it call the provider to tell it this action and the provider do
+ * that it want (normally inserts some text)
+ * 
+ * Returns: %TRUE if it was registered or %FALSE if not (because it has been already registered,
+ * or the trigger doesn't exists)
+ *
+ **/
+gboolean
+gtk_source_completion_register_provider (GtkSourceCompletion *self,
+					 GtkSourceCompletionProvider *provider,
+					 GtkSourceCompletionTrigger *trigger)
+{
+	PTPair *ptp;
+	GList *l;
+	
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION (self), FALSE);
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (provider), FALSE);
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_TRIGGER (trigger), FALSE);
+	g_return_val_if_fail (g_list_find (self->priv->triggers, trigger) != NULL,
+			      FALSE);
+
+	/*Check if the provider-trigger pair has been registered*/
+	for (l = self->priv->prov_trig; l != NULL; l = g_list_next (l))
+	{
+		ptp = (PTPair *)l->data;
+		if (ptp->trigger == trigger && ptp->provider == provider)
+			return FALSE;
+	}
+
+	ptp = g_slice_new (PTPair);
+	ptp->provider = provider;
+	ptp->trigger = trigger;
+	self->priv->prov_trig = g_list_append (self->priv->prov_trig, ptp);
+	
+	g_object_ref (provider);
+
+	return TRUE;
+}
+
+/**
+ * gtk_source_completion_unregister_trigger:
+ * @self: The #GtkSourceCompletion
+ * @trigger: The trigger to unregister
+ *
+ * This function unregister a completion trigger. If the completion is actived
+ * then this method deactivate the trigger. This function unreference the trigger
+ * object
+ *
+ * Returns: %TRUE if the trigger has been unregistered or %FALSE if not (because
+ * the trigger has not been registered)
+ */
+gboolean
+gtk_source_completion_unregister_trigger (GtkSourceCompletion *self,
+					  GtkSourceCompletionTrigger *trigger)
+{
+	GList *l;
+	
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION (self), FALSE);
+	g_return_val_if_fail (g_list_find (self->priv->triggers, trigger) != NULL,
+			      FALSE);
+	
+	self->priv->triggers = g_list_remove (self->priv->triggers, trigger);
+	
+	if (self->priv->active)
+	{
+		gtk_source_completion_trigger_deactivate (trigger);
+	}
+	
+	for (l = self->priv->prov_trig; l != NULL; l = g_list_next (l))
+	{
+		PTPair *ptp = (PTPair *)l->data;
+		
+		if (ptp->trigger == trigger)
+		{
+			free_pair (ptp);
+			self->priv->prov_trig = g_list_remove_link (self->priv->prov_trig, l);
+			//TODO we need start the list again
+		}
+	}
+
+	g_object_unref (trigger);
+	return TRUE;
+}
+
+/**
+ * gtk_source_completion_unregister_provider:
+ * @self: the #GtkSourceCompletion
+ * @provider: The #GtkSourceCompletionProvider.
+ * @trigger: The trigger what you want to unregister this provider
+ *
+ * This function unregister the provider.
+ * 
+ * Returns TRUE if it was unregistered or FALSE if not (because it doesn't exists,
+ * or the trigger don't exists)
+ * 
+ **/
+gboolean
+gtk_source_completion_unregister_provider (GtkSourceCompletion *self,
+					   GtkSourceCompletionProvider *provider,
+					   GtkSourceCompletionTrigger *trigger)
+{
+	GList *l;
+	gboolean ret = FALSE;
+	
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION (self), FALSE);
+	g_return_val_if_fail (g_list_find (self->priv->triggers, trigger) != NULL,
+			      FALSE);
+	
+	for (l = self->priv->prov_trig; l != NULL; l = g_list_next (l))
+	{
+		PTPair *ptp = (PTPair *)l->data;
+		
+		if (ptp->provider == provider)
+		{
+			free_pair (ptp);
+			self->priv->prov_trig = g_list_remove_link (self->priv->prov_trig, l);
+			//TODO we need start the list again
+			ret = TRUE;
+		}
+	}
+		
+	return ret;
+}
+
+/**
+ * gtk_source_completion_get_active_trigger:
+ * @self: The #GtkSourceCompletion
+ *
+ * This function return the active trigger. The active trigger is the last
+ * trigger raised if the completion is active. If the completion is not visible then
+ * there is no an active trigger.
+ *
+ * Returns: The trigger or NULL if completion is not active
+ */
+GtkSourceCompletionTrigger*
+gtk_source_completion_get_active_trigger (GtkSourceCompletion *self)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION (self), NULL);
+
+	return self->priv->active_trigger;
+}
+
+
+/**
+ * gtk_source_completion_get_view:
+ * @self: The #GtkSourceCompletion
+ *
+ * Returns: The view associated with this completion.
+ */
+GtkTextView*
+gtk_source_completion_get_view (GtkSourceCompletion *self)
+{
+	g_return_val_if_fail (GTK_SOURCE_COMPLETION (self), NULL);
+	
+	return self->priv->view;
+}
+
+/**
+ * gtk_source_completion_trigger_event:
+ * @self: the #GtkSourceCompletion
+ * @trigger: The trigger who trigger the event
+ *
+ * Calling this function, the completion call to all providers to get data and, if 
+ * they return data, it shows the completion to the user. 
+ *
+ * Returns: %TRUE if the event has been triggered, %FALSE if not
+ * 
+ **/
+gboolean 
+gtk_source_completion_trigger_event (GtkSourceCompletion *self,
+				     GtkSourceCompletionTrigger *trigger)
+{
+	GList *l;
+	GList *data_list;
+	GList *final_list = NULL;
+	GtkSourceCompletionProposal *last_proposal = NULL;
+	gint x, y;
+
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION (self), FALSE);
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_TRIGGER (trigger), FALSE);
+	g_return_val_if_fail (self->priv->active, FALSE);
+	
+	/*
+	 * If the completion is visble and there is a trigger active, you cannot
+	 * raise a different trigger until the current trigger finish o_O
+	 */
+	if (GTK_WIDGET_VISIBLE (self)
+	    && self->priv->active_trigger != trigger)
+	{
+		return FALSE;
+	}
+	
+	end_completion (self);
+	gtk_source_completion_clear (self);
+	
+	for (l = self->priv->prov_trig; l != NULL; l = g_list_next (l))
+	{
+		PTPair *ptp = (PTPair *)l->data;
+		
+		if (ptp->trigger == trigger)
+		{
+			data_list = gtk_source_completion_provider_get_proposals (ptp->provider,
+										  trigger);
+			if (data_list != NULL)
+			{
+				final_list = g_list_concat (final_list,
+							    data_list);
+			}
+		}
+	}
+	
+	if (final_list == NULL)
+	{
+		if (GTK_WIDGET_VISIBLE (self))
+			end_completion (self);
+		return FALSE;
+	}
+	
+	data_list = final_list;
+	/* Insert the data into the model */
+	do
+	{
+		GtkSourceCompletionPage *page;
+		
+		last_proposal = GTK_SOURCE_COMPLETION_PROPOSAL (data_list->data);
+		page = get_page_by_name (self,
+					 gtk_source_completion_proposal_get_page_name (last_proposal));
+		
+		add_proposal (page,
+			      last_proposal);
+	} while ((data_list = g_list_next (data_list)) != NULL);
+	
+	g_list_free (final_list);
+	
+	if (!GTK_WIDGET_HAS_FOCUS (self->priv->view))
+		return FALSE;
+	
+	/*
+	 *FIXME Do it supports only cursor position? We can 
+	 *add a new "position-type": cursor, center_screen,
+	 *center_window, custom etc.
+	 */
+	gtk_source_completion_utils_get_pos_at_cursor (GTK_WINDOW (self),
+						       self->priv->view,
+						       &x, &y, NULL);
+
+	gtk_window_move (GTK_WINDOW (self),
+			 x, y);
+	
+	/*
+	* We must call to gtk_widget_show and not to gsc_completion_show_or_update
+	* because if we don't call to gtk_widget_show, the show signal is not emitted
+	*/
+	gtk_widget_show (GTK_WIDGET (self));
+
+	gtk_widget_grab_focus (GTK_WIDGET (self->priv->view));
+
+	self->priv->active_trigger = trigger;
+	
+	if (self->priv->select_on_show)
+		select_first_proposal (self->priv->active_page);
+
+	return TRUE;
+}
+
+/**
+ * gtk_source_completion_finish_completion:
+ * @self: The #GtkSourceCompletion
+ *
+ * This function finish the completion if it is active (visible).
+ */
+void
+gtk_source_completion_finish_completion (GtkSourceCompletion *self)
+{
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION (self));
+
+	if (GTK_WIDGET_VISIBLE (self))
+	{
+		end_completion (self);
+	}
+}
+
+/**
+ * gtk_source_completion_filter_proposals:
+ * @self: the #GtkSourceCompletion
+ * @func: function to filter the proposals visibility
+ * @user_data: user data to pass to func
+ *
+ * This function call to @func for all proposal of all pages. @func must
+ * return %TRUE if the proposal is visible or %FALSE if the completion must to 
+ * hide the proposal.
+ * 
+ **/
+void
+gtk_source_completion_filter_proposals (GtkSourceCompletion *self,
+					GtkSourceCompletionFilterFunc func,
+					gpointer user_data)
+{
+	GList *l;
+	
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION (self));
+	g_return_if_fail (func);
+	
+	if (!GTK_WIDGET_VISIBLE (self))
+		return;
+	
+	for (l = self->priv->pages; l != NULL; l = g_list_next (l))
+	{
+		GtkSourceCompletionPage *page = (GtkSourceCompletionPage *)l->data;
+		if (get_num_proposals (page) > 0)
+		{
+			filter_visible (page,
+					(GtkSourceCompletionFilterFunc) func,
+					user_data);
+		}
+	}
+
+	if (!update_pages_visibility (self))
+	{
+		end_completion (self);
+	}
+	else
+	{
+		if (self->priv->select_on_show)
+			select_first_proposal (self->priv->active_page);
+	}
+}
+
+/**
+ * gtk_source_completion_set_active:
+ * @self: The #GtkSourceCompletion
+ * @active: %TRUE if you want to activate the completion mechanism.
+ *
+ * This function activate/deactivate the completion mechanism. The completion
+ * connects/disconnect all signals and activate/deactivate all registered triggers.
+ */
+void
+gtk_source_completion_set_active (GtkSourceCompletion *self,
+				  gboolean active)
+{
+	GList *l;
+	GtkSourceCompletionTrigger *trigger;
+	gint i;
+	
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION (self));
+	
+	if (active)
+	{
+		if (self->priv->active)
+			return;
+
+		self->priv->signals_ids[TEXT_VIEW_DESTROY] = 
+				g_signal_connect (self->priv->view,
+						  "destroy",
+						  G_CALLBACK (view_destroy_event_cb),
+						  self);
+		self->priv->signals_ids[TEXT_VIEW_FOCUS_OUT] = 
+				g_signal_connect (self->priv->view,
+						  "focus-out-event",
+						  G_CALLBACK (view_focus_out_event_cb),
+						  self);
+		self->priv->signals_ids[TEXT_VIEW_BUTTON_PRESS] = 
+				g_signal_connect (self->priv->view,
+						  "button-press-event",
+						  G_CALLBACK (view_button_press_event_cb),
+						  self);
+	
+		set_manage_keys (self);
+	
+		/* We activate the triggers */
+		for (l = self->priv->triggers; l != NULL; l = g_list_next (l))
+		{
+			trigger =  GTK_SOURCE_COMPLETION_TRIGGER (l->data);
+		
+			gtk_source_completion_trigger_activate (trigger);
+		}
+	}
+	else
+	{
+		for (i = 0; i < LAST_EXTERNAL_SIGNAL; i++)
+		{
+			if (g_signal_handler_is_connected (self->priv->view, 
+							   self->priv->signals_ids[i]))
+			{
+				g_signal_handler_disconnect (self->priv->view,
+							     self->priv->signals_ids[i]);
+			}
+			self->priv->signals_ids[i] = 0;
+		}
+	
+		for (l = self->priv->triggers; l != NULL; l = g_list_next (l))
+		{
+			trigger =  GTK_SOURCE_COMPLETION_TRIGGER (l->data);
+		
+			gtk_source_completion_trigger_deactivate (trigger);
+		}
+	}
+	self->priv->active = active;
+}
+
+/**
+ * gtk_source_completion_get_active:
+ * @self: The #GtkSourceCompletion
+ *
+ * Returns: %TRUE if the completion mechanism is active, %FALSE if not.
+ */
+gboolean
+gtk_source_completion_get_active (GtkSourceCompletion *self)
+{
+	return self->priv->active;
+}
+
+/**
+ * gtk_source_completion_get_bottom_bar:
+ * @self: The #GtkSourceCompletion
+ *
+ * The bottom bar is the widgetwith the info button, the page name etc.
+ *
+ * Returns: The bottom bar widget (it is a #GtkBox by now)
+ */
+GtkWidget*
+gtk_source_completion_get_bottom_bar (GtkSourceCompletion *self)
+{
+	return self->priv->bottom_bar;
+}
+
+/**
+ * gtk_source_completion_get_info_widget:
+ * @self: The #GtkSourceCompletion
+ *
+ * The info widget is the window where the completion shows the
+ * proposal info or help. DO NOT USE IT (only to connect to some signal
+ * or set the content in a custom widget).
+ *
+ * Returns: The internal #GtkSourceCompletionInfo widget.
+ */
+GtkSourceCompletionInfo *
+gtk_source_completion_get_info_widget (GtkSourceCompletion *self)
+{
+	return GTK_SOURCE_COMPLETION_INFO (self->priv->info_window);
+}
+
+/**
+ * gtk_source_completion_get_trigger:
+ * @self: The #GtkSourceCompletion
+ * @trigger_name: The trigger name to find
+ *
+ * Returns: The #GtkSourceCompletionTrigger registered with @trigger_name, %NULL if it cannot
+ * be found
+ */
+GtkSourceCompletionTrigger*
+gtk_source_completion_get_trigger (GtkSourceCompletion *self,
+				   const gchar *trigger_name)
+{
+
+	GList *l;
+	GtkSourceCompletionTrigger *trigger;
+	
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION (self), NULL);
+
+	for (l = self->priv->triggers; l != NULL; l = g_list_next (l))
+	{
+		trigger =  GTK_SOURCE_COMPLETION_TRIGGER (l->data);
+		
+		if (g_strcmp0 (gtk_source_completion_trigger_get_name (trigger), trigger_name) == 0)
+			return trigger;
+	}
+	
+	return NULL;
+}
+
+/**
+ * gtk_source_completion_get_provider:
+ * @self: The #GtkSourceCompletion
+ * @prov_name: The provider name to find
+ *
+ * Returns: The #GtkSourceCompletionProvider registered with @prov_name
+ */
+GtkSourceCompletionProvider*
+gtk_source_completion_get_provider (GtkSourceCompletion *self,
+				    const gchar *prov_name)
+{
+
+	GList *l;
+	
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION (self), NULL);
+
+	for (l = self->priv->prov_trig; l != NULL; l = g_list_next (l))
+	{
+		PTPair *ptp = (PTPair *)l->data;
+		if (g_strcmp0 (gtk_source_completion_provider_get_name (ptp->provider), prov_name) == 0)
+			return ptp->provider;
+	}
+		
+	return NULL;
+}
+
+/**
+ * gtk_source_completion_get_from_view:
+ * @view: The #GtkTextView associated with a #GtkSourceCompletion
+ *
+ * Returns: The #GtkSourceCompletion associated with a @view or %NULL.
+ */
+GtkSourceCompletion*
+gtk_source_completion_get_from_view (GtkTextView *view)
+{
+	return completion_control_get_completion (view);
+}
+
+/**
+ * gtk_source_completion_get_page_pos:
+ * @self: The #GtkSourceCompletion
+ * @page_name: The page name to search
+ *
+ * Search the page position with the given name
+ *
+ * Returns: the page position or -1 if it is not found
+ */
+gint
+gtk_source_completion_get_page_pos (GtkSourceCompletion *self,
+				    const gchar *page_name)
+{
+	GList *l;
+	gint pos = 0;
+	
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION (self), -1);
+	
+	for (l = self->priv->pages; l != NULL; l = g_list_next (l))
+	{
+		GtkSourceCompletionPage *page = (GtkSourceCompletionPage *)l->data;
+		if (g_strcmp0 (page_name, page->name) == 0)
+			return pos;
+		
+		pos++;
+	}
+	
+	return -1;
+}
+
+/**
+ * gtk_source_completion_get_n_pages:
+ * @self: The #GtkSourceCompletion
+ * 
+ * Returns: The number of pages
+ */
+gint
+gtk_source_completion_get_n_pages (GtkSourceCompletion *self)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION (self), -1);
+	
+	return g_list_length (self->priv->pages);
+}
+
+/**
+ * gtk_source_completion_set_page_pos:
+ * @self: The #GtkSourceCompletion
+ * @page_name: The page name you want to set the position (stating by 1 because 
+ * 0 is the default page)
+ * @position: The new position of the page. If this is negative, or is larger
+ * than the number of elements in the list, the new element is added on to
+ * the end of the list
+ * 
+ */
+void
+gtk_source_completion_set_page_pos (GtkSourceCompletion *self,
+				    const gchar *page_name,
+				    gint position)
+{
+	GList *l;
+	GtkSourceCompletionPage *page;
+	
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION (self));
+
+	for (l = self->priv->pages; l != NULL; l = g_list_next (l))
+	{
+		page = (GtkSourceCompletionPage *)l->data;
+		if (g_strcmp0 (page_name, page->name) == 0)
+		{
+			break;
+		}
+		page = NULL;
+	}
+	
+	if (page == NULL)
+	{
+		page = gtk_source_completion_page_new (self, page_name);
+	}
+	
+	self->priv->pages = g_list_remove (self->priv->pages, page);
+	self->priv->pages = g_list_insert (self->priv->pages, page, position);
+	gtk_notebook_reorder_child (GTK_NOTEBOOK (self->priv->notebook),
+				    GTK_WIDGET (page->scroll),
+				    position);
+	if (GTK_WIDGET_VISIBLE (self))
+		update_pages_visibility (self);
+}
+

Added: branches/gtksourcecompletion/gtksourceview/gtksourcecompletion.h
==============================================================================
--- (empty file)
+++ branches/gtksourcecompletion/gtksourceview/gtksourcecompletion.h	Tue Apr  7 15:28:05 2009
@@ -0,0 +1,145 @@
+/*
+ * gtksourcecompletion.h
+ * This file is part of gtksourcecompletion
+ *
+ * Copyright (C) 2007 -2009 JesÃs Barbero RodrÃguez <chuchiperriman gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA.
+ */
+ 
+#ifndef GTK_SOURCE_COMPLETION_H
+#define GTK_SOURCE_COMPLETION_H
+
+#include <gtk/gtk.h>
+#include "gtksourcecompletionprovider.h"
+#include "gtksourcecompletioninfo.h"
+
+G_BEGIN_DECLS
+
+/*
+ * FIXME: And this here?
+ */
+#define USER_REQUEST_TRIGGER_NAME "user-request"
+
+/*
+ * Type checking and casting macros
+ */
+#define GTK_TYPE_SOURCE_COMPLETION              (gtk_source_completion_get_type())
+#define GTK_SOURCE_COMPLETION(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), GTK_TYPE_SOURCE_COMPLETION, GtkSourceCompletion))
+#define GTK_SOURCE_COMPLETION_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), GTK_TYPE_SOURCE_COMPLETION, GtkSourceCompletionClass))
+#define GTK_IS_SOURCE_COMPLETION(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), GTK_TYPE_SOURCE_COMPLETION))
+#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 DEFAULT_PAGE "Default"
+
+typedef gboolean (* GtkSourceCompletionFilterFunc) (GtkSourceCompletionProposal *proposal,
+						    gpointer     user_data);
+
+typedef struct _GtkSourceCompletionPriv GtkSourceCompletionPriv;
+typedef struct _GtkSourceCompletion GtkSourceCompletion;
+typedef struct _GtkSourceCompletionClass GtkSourceCompletionClass;
+
+struct _GtkSourceCompletion
+{
+	GtkWindow parent;
+
+	GtkSourceCompletionPriv *priv;
+};
+
+struct _GtkSourceCompletionClass
+{
+	GtkWindowClass parent_class;
+
+	gboolean (* proposal_selected)(GtkSourceCompletion *completion,
+				       GtkSourceCompletionProposal *proposal);
+	gboolean (* display_info)     (GtkSourceCompletion *completion,
+				       GtkSourceCompletionProposal *proposal);
+};
+
+/* ********************* Control Functions ******************** */
+/* 
+ * FIXME This functions will be deleted when we insert GtkSourceCompletion
+ * into GtkSourceView. These functions store the relationship between the
+ * GtkSourceCompletions and the GtkTextView.
+ */
+
+GtkSourceCompletion	*gtk_source_completion_get_from_view	(GtkTextView *view);
+
+/* ************************************************************* */
+
+GType		 gtk_source_completion_get_type			(void) G_GNUC_CONST;
+
+GtkWidget	*gtk_source_completion_new			(GtkTextView *view);
+
+GtkTextView	*gtk_source_completion_get_view			(GtkSourceCompletion *self);
+
+GtkSourceCompletionTrigger
+		*gtk_source_completion_get_trigger		(GtkSourceCompletion *self,
+								 const gchar *trigger_name);
+
+GtkSourceCompletionProvider
+		*gtk_source_completion_get_provider		(GtkSourceCompletion *self,
+								 const gchar *prov_name);
+
+gboolean	 gtk_source_completion_register_provider	(GtkSourceCompletion *self,
+								 GtkSourceCompletionProvider *provider,
+								 GtkSourceCompletionTrigger *trigger);
+
+gboolean	 gtk_source_completion_unregister_provider	(GtkSourceCompletion *self,
+								 GtkSourceCompletionProvider *provider,
+								 GtkSourceCompletionTrigger *trigger);
+
+gboolean	 gtk_source_completion_register_trigger		(GtkSourceCompletion *self,
+								 GtkSourceCompletionTrigger *trigger);
+
+gboolean	 gtk_source_completion_unregister_trigger	(GtkSourceCompletion *self,
+								 GtkSourceCompletionTrigger *trigger);
+
+GtkSourceCompletionTrigger
+		*gtk_source_completion_get_active_trigger	(GtkSourceCompletion *self);
+
+gboolean	 gtk_source_completion_trigger_event		(GtkSourceCompletion *self,
+								 GtkSourceCompletionTrigger *trigger);
+
+void		 gtk_source_completion_finish_completion	(GtkSourceCompletion *self);
+
+void		 gtk_source_completion_filter_proposals		(GtkSourceCompletion *self,
+								 GtkSourceCompletionFilterFunc func,
+								 gpointer user_data);
+
+void		 gtk_source_completion_set_active 		(GtkSourceCompletion *self,
+								 gboolean active);
+
+gboolean	 gtk_source_completion_get_active 		(GtkSourceCompletion *self);
+
+GtkWidget	*gtk_source_completion_get_bottom_bar		(GtkSourceCompletion *self);
+
+GtkSourceCompletionInfo
+		*gtk_source_completion_get_info_widget		(GtkSourceCompletion *self);
+
+gint		gtk_source_completion_get_page_pos		(GtkSourceCompletion *self,
+								 const gchar *page_name);
+
+gint		gtk_source_completion_get_n_pages		(GtkSourceCompletion *self);
+
+void	gtk_source_completion_set_page_pos		(GtkSourceCompletion *self,
+								 const gchar *page_name,
+								 gint position);
+
+G_END_DECLS
+
+#endif 

Added: branches/gtksourcecompletion/gtksourceview/gtksourcecompletioninfo.c
==============================================================================
--- (empty file)
+++ branches/gtksourcecompletion/gtksourceview/gtksourcecompletioninfo.c	Tue Apr  7 15:28:05 2009
@@ -0,0 +1,439 @@
+/*
+ * gtksourcecompletioninfo.c
+ * This file is part of gtksourcecompletion
+ *
+ * Copyright (C) 2007 -2009 JesÃs Barbero RodrÃguez <chuchiperriman gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:gsc-info
+ * @title: GtkSourceCompletionInfo
+ * @short_description: Calltips object
+ *
+ * This object can be used to show a calltip or help. 
+ */
+  
+#include "gtksourcecompletioninfo.h"
+#include "gtksourcecompletionutils.h"
+#include "gtksourcecompletioni18n.h"
+
+struct _GtkSourceCompletionInfoPrivate
+{
+	GtkWidget *box;
+	GtkWidget *info_scroll;
+	GtkWidget *label;
+	GtkWidget *custom_widget;
+	
+	gboolean adjust_height;
+	gboolean adjust_width;
+	gint max_height;
+	gint max_width;
+};
+
+/* Signals */
+enum
+{
+	SHOW_INFO,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+/*Type definition*/
+G_DEFINE_TYPE(GtkSourceCompletionInfo, gtk_source_completion_info, GTK_TYPE_WINDOW);
+
+#define GTK_SOURCE_COMPLETION_INFO_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GTK_TYPE_SOURCE_COMPLETION_INFO, GtkSourceCompletionInfoPrivate))
+#define WINDOW_WIDTH 350
+#define WINDOW_HEIGHT 200
+
+
+static void
+get_max_size (GtkSourceCompletionInfo *self,
+	      GtkWidget *widget,
+	      gint *w,
+	      gint *h)
+{
+	GtkRequisition req;
+	
+	gtk_widget_size_request (widget, &req);
+
+	if (self->priv->adjust_height)
+	{
+		if (req.height > self->priv->max_height)
+		{
+			*h = self->priv->max_height;
+		}
+		else
+		{
+			*h = req.height;
+		}
+	}
+	else
+	{
+		*h = WINDOW_HEIGHT;
+	}
+	
+	if (self->priv->adjust_width)
+	{
+		if (req.width > self->priv->max_width)
+		{
+			*w = self->priv->max_width;
+		}
+		else
+		{
+			*w = req.width;
+		}
+	}
+	else
+	{
+		*w = WINDOW_WIDTH;
+	}
+}
+
+static void
+adjust_resize (GtkSourceCompletionInfo *self)
+{
+	gint w, h;
+	
+	if (!self->priv->custom_widget)
+	{
+		/* Default widget */
+		get_max_size (self, self->priv->label, &w, &h);
+		w = w + 5 + GTK_WIDGET (self->priv->info_scroll)->style->ythickness * 2;
+		h = h + 5 + GTK_WIDGET (self->priv->info_scroll)->style->xthickness * 2;
+	}
+	else
+	{
+		/* Custom widget */
+		get_max_size (self, self->priv->custom_widget, &w, &h);
+	}
+	
+	gtk_window_resize (GTK_WINDOW (self), w, h);
+}
+
+static void
+show (GtkWidget *widget)
+{
+	GtkSourceCompletionInfo *self = GTK_SOURCE_COMPLETION_INFO (widget);
+	
+	g_signal_emit (self, signals[SHOW_INFO], 0);
+	
+	GTK_WIDGET_CLASS (gtk_source_completion_info_parent_class)->show (GTK_WIDGET (self));
+	
+	gtk_label_select_region (GTK_LABEL (self->priv->label), 0, 0);
+}
+
+static void
+hide (GtkWidget *widget)
+{
+	GtkSourceCompletionInfo *self = GTK_SOURCE_COMPLETION_INFO (widget);
+	
+	gtk_label_set_label (GTK_LABEL (self->priv->label), "");
+	
+	GTK_WIDGET_CLASS (gtk_source_completion_info_parent_class)->hide (GTK_WIDGET (self));
+}
+
+static void
+gtk_source_completion_info_init (GtkSourceCompletionInfo *self)
+{
+	self->priv = GTK_SOURCE_COMPLETION_INFO_GET_PRIVATE (self);
+	self->priv->adjust_height = FALSE;
+	self->priv->adjust_width = FALSE;
+	self->priv->max_height = WINDOW_HEIGHT;
+	self->priv->max_width = WINDOW_WIDTH;
+	self->priv->custom_widget = NULL;
+	
+	/*
+	 * Make it look like a tooltip
+	 */
+	gtk_widget_set_name (GTK_WIDGET (self), "gtk-tooltip");
+	gtk_widget_ensure_style (GTK_WIDGET (self));
+	
+	gtk_window_set_type_hint (GTK_WINDOW (self),
+				  GDK_WINDOW_TYPE_HINT_NORMAL);
+	gtk_window_set_decorated (GTK_WINDOW (self), FALSE);
+	gtk_window_set_default_size (GTK_WINDOW (self),
+				     WINDOW_WIDTH, WINDOW_HEIGHT);
+
+	self->priv->info_scroll = gtk_scrolled_window_new (NULL, NULL);
+
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self->priv->info_scroll),
+					GTK_POLICY_AUTOMATIC,
+					GTK_POLICY_AUTOMATIC);
+	gtk_widget_show (self->priv->info_scroll);
+
+	self->priv->label = gtk_label_new (" ");
+	/*Top left position*/
+	gtk_misc_set_alignment (GTK_MISC (self->priv->label), 0, 0.5);
+	gtk_misc_set_padding (GTK_MISC (self->priv->label), 5, 5);
+	gtk_label_set_selectable (GTK_LABEL (self->priv->label), TRUE);
+	
+	gtk_widget_show (self->priv->label);
+
+	gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (self->priv->info_scroll),
+					       self->priv->label);
+
+	self->priv->box = gtk_vbox_new (FALSE, 1);
+	
+	gtk_widget_show (self->priv->box);
+	gtk_box_pack_start (GTK_BOX (self->priv->box),
+			    self->priv->info_scroll,
+			    TRUE, TRUE, 0);
+	
+	gtk_container_add (GTK_CONTAINER (self), 
+			   self->priv->box);
+}
+
+static void
+gtk_source_completion_info_finalize (GObject *object)
+{
+	/*GtkSourceCompletionInfo *self = GTK_SOURCE_COMPLETION_INFO(object);*/
+	
+	G_OBJECT_CLASS (gtk_source_completion_info_parent_class)->finalize (object);
+}
+
+static void
+gtk_source_completion_info_class_init (GtkSourceCompletionInfoClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+	g_type_class_add_private (object_class, sizeof (GtkSourceCompletionInfoPrivate));
+
+	object_class->finalize = gtk_source_completion_info_finalize;
+	widget_class->show = show;
+	widget_class->hide = hide;
+	
+	/**
+	 * GtkSourceCompletionInfo::show-info:
+	 * @info: The #GscInf who emits the signal
+	 *
+	 * This signal is emited before any "show" management. You can connect
+	 * to this signal if you want to change some properties or position
+	 * before to so the real "show".
+	 **/
+	signals[SHOW_INFO] =
+		g_signal_new ("show-info",
+			      G_TYPE_FROM_CLASS (klass),
+			      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+			      0,
+			      NULL, 
+			      NULL,
+			      g_cclosure_marshal_VOID__VOID, 
+			      G_TYPE_NONE,
+			      0);
+}
+
+/**
+ * gtk_source_completion_info_new:
+ *
+ * Returns: The new GtkSourceCompletionInfo.
+ *
+ */
+GtkSourceCompletionInfo*
+gtk_source_completion_info_new (void)
+{
+	GtkSourceCompletionInfo *self = GTK_SOURCE_COMPLETION_INFO (g_object_new (GTK_TYPE_SOURCE_COMPLETION_INFO,
+										  "type", GTK_WINDOW_POPUP,
+										  NULL));
+	return self;
+}
+
+/**
+ * gtk_source_completion_info_move_to_cursor:
+ * @self: The #GtkSourceCompletionInfo
+ * @view: The current GtkTextView where we want to show the info
+ *
+ * Moves the #GtkSourceCompletionInfo to under the @view cursor. If it cannot be shown down,
+ * it will be shown up
+ *
+ */
+void
+gtk_source_completion_info_move_to_cursor (GtkSourceCompletionInfo* self,
+					   GtkTextView *view)
+{
+	int x,y;
+	gboolean resized = FALSE;
+	
+	g_return_if_fail  (GTK_IS_SOURCE_COMPLETION_INFO (self));
+
+	adjust_resize (self);
+	
+	gtk_source_completion_utils_get_pos_at_cursor (GTK_WINDOW (self),
+						       view,
+						       &x,
+						       &y,
+						       &resized);
+	if (resized)
+	{
+		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self->priv->info_scroll),
+						GTK_POLICY_ALWAYS,
+						GTK_POLICY_ALWAYS);
+	}
+	else
+	{
+		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self->priv->info_scroll),
+						GTK_POLICY_NEVER,
+						GTK_POLICY_NEVER);
+	}
+	gtk_window_move (GTK_WINDOW (self), x, y);
+}
+
+/**
+ * gtk_source_completion_info_set_markup:
+ * @self: The #GtkSourceCompletionInfo
+ * @markup: Text markup to be shown (see <link 
+ * linkend="PangoMarkupFormat">Pango markup format</link>). 
+ *
+ * Sets the text markup to be shown into the GtkSourceCompletionInfo window.
+ *
+ */
+void
+gtk_source_completion_info_set_markup (GtkSourceCompletionInfo* self,
+				       const gchar* markup)
+{
+	g_return_if_fail  (GTK_IS_SOURCE_COMPLETION_INFO (self));
+
+	gtk_label_set_markup (GTK_LABEL (self->priv->label), markup);
+}
+
+/**
+ * gtk_source_completion_info_set_adjust_height:
+ * @self: The #GtkSourceCompletionInfo
+ * @adjust: TRUE to adjust height to content, FALSE to fixed height
+ * @max_height: if adjust = TRUE, set the max height. -1 to preserve the 
+ * current value
+ *
+ * %TRUE adjust height to the content. If the content is only a line, the info
+ * will be small and if there are a lot of lines, the info will be large to the 
+ * max_height
+ *
+ */
+void
+gtk_source_completion_info_set_adjust_height (GtkSourceCompletionInfo* self,
+					      gboolean adjust,
+					      gint max_height)
+{
+	g_return_if_fail  (GTK_IS_SOURCE_COMPLETION_INFO (self));
+
+	self->priv->adjust_height = adjust;
+	
+	if (max_height > 0)
+	{
+		self->priv->max_height = max_height;
+	}
+}
+
+/**
+ * gtk_source_completion_info_set_adjust_width:
+ * @self: The #GtkSourceCompletionInfo
+ * @adjust: TRUE to adjust width to content, FALSE to fixed width
+ * @max_width: if adjust = TRUE, set the max height. -1 to preserve the 
+ * current value
+ *
+ * %TRUE adjust width to the content. If the content is only a line, the info
+ * will be small and if there are a lot of lines, the info will be large to the 
+ * max_width
+ *
+ */
+void
+gtk_source_completion_info_set_adjust_width (GtkSourceCompletionInfo* self,
+					     gboolean adjust,
+					     gint max_width)
+{
+	g_return_if_fail  (GTK_IS_SOURCE_COMPLETION_INFO (self));
+	
+	self->priv->adjust_width = adjust;
+	
+	if (max_width > 0)
+	{
+		self->priv->max_width = max_width;
+	}
+}
+
+/**
+ * gtk_source_completion_info_set_custom:
+ * @self: The #GtkSourceCompletionInfo
+ * @custom_widget: A #GtkWidget
+ *
+ * Replaces the widget packed into the window with custom_widget. By default a
+ * box with a #GtkScrolledWindow and a #GtkLabel is embedded in the window.
+ *
+ */
+void
+gtk_source_completion_info_set_custom (GtkSourceCompletionInfo* self,
+				       GtkWidget *custom_widget)
+{
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION_INFO (self));
+	
+	if (self->priv->custom_widget == custom_widget)
+		return;
+		
+	if (custom_widget)
+	{
+		g_return_if_fail (GTK_IS_WIDGET (custom_widget));
+		
+		if (self->priv->custom_widget)
+		{
+			gtk_container_remove (GTK_CONTAINER (self->priv->box),
+					      self->priv->custom_widget);
+			g_object_unref (self->priv->custom_widget);
+			self->priv->custom_widget = NULL;
+		}
+		else
+		{
+			gtk_widget_hide (self->priv->info_scroll);
+		}
+		
+		self->priv->custom_widget = g_object_ref (custom_widget);
+		gtk_container_add (GTK_CONTAINER (self->priv->box),
+				   custom_widget);
+		gtk_widget_show (self->priv->custom_widget);
+	}
+	else
+	{
+
+		if (self->priv->custom_widget)
+		{
+			gtk_container_remove (GTK_CONTAINER (self->priv->box),
+					      self->priv->custom_widget);
+			g_object_unref (self->priv->custom_widget);
+			self->priv->custom_widget = NULL;
+			gtk_widget_show (self->priv->info_scroll);
+		}
+		
+	}
+}
+
+/**
+ * gtk_source_completion_info_get_custom:
+ * @self: The #GtkSourceCompletionInfo
+ *
+ * Returns: The custom widget setted or NULL.
+ *
+ */
+GtkWidget*
+gtk_source_completion_info_get_custom (GtkSourceCompletionInfo* self)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_INFO (self), NULL);
+
+	return self->priv->custom_widget;
+}
+
+
+

Added: branches/gtksourcecompletion/gtksourceview/gtksourcecompletioninfo.h
==============================================================================
--- (empty file)
+++ branches/gtksourcecompletion/gtksourceview/gtksourcecompletioninfo.h	Tue Apr  7 15:28:05 2009
@@ -0,0 +1,83 @@
+/*
+ * gtksourcecompletioninfo.h
+ * This file is part of gtksourcecompletion
+ *
+ * Copyright (C) 2007 -2009 JesÃs Barbero RodrÃguez <chuchiperriman gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _GTK_SOURCE_COMPLETION_INFO_H
+#define _GTK_SOURCE_COMPLETION_INFO_H
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_SOURCE_COMPLETION_INFO             (gtk_source_completion_info_get_type ())
+#define GTK_SOURCE_COMPLETION_INFO(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SOURCE_COMPLETION_INFO, GtkSourceCompletionInfo))
+#define GTK_SOURCE_COMPLETION_INFO_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SOURCE_COMPLETION_INFO, GtkSourceCompletionInfoClass)
+#define GTK_IS_SOURCE_COMPLETION_INFO(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SOURCE_COMPLETION_INFO))
+#define GTK_SOURCE_COMPLETION_IS_INFO_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SOURCE_COMPLETION_INFO))
+#define GTK_SOURCE_COMPLETION_INFO_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SOURCE_COMPLETION_INFO, GtkSourceCompletionInfoClass))
+
+typedef struct _GtkSourceCompletionInfoPrivate GtkSourceCompletionInfoPrivate;
+
+typedef struct _GtkSourceCompletionInfo GtkSourceCompletionInfo;
+
+struct _GtkSourceCompletionInfo
+{
+	GtkWindow parent;
+	
+	GtkSourceCompletionInfoPrivate *priv;
+};
+
+typedef struct _GtkSourceCompletionInfoClass GtkSourceCompletionInfoClass;
+
+struct _GtkSourceCompletionInfoClass
+{
+	GtkWindowClass parent_class;
+};
+
+GType		 gtk_source_completion_info_get_type		(void) G_GNUC_CONST;
+
+GtkSourceCompletionInfo
+		*gtk_source_completion_info_new			(void);
+
+void		 gtk_source_completion_info_move_to_cursor	(GtkSourceCompletionInfo* self,
+								 GtkTextView *view);
+
+void		 gtk_source_completion_info_set_markup		(GtkSourceCompletionInfo* self,
+								 const gchar* markup);
+
+void		 gtk_source_completion_info_set_adjust_height	(GtkSourceCompletionInfo* self,
+								 gboolean adjust,
+								 gint max_height);
+
+void		 gtk_source_completion_info_set_adjust_width	(GtkSourceCompletionInfo* self,
+								 gboolean adjust,
+								 gint max_width);
+
+void		 gtk_source_completion_info_set_custom		(GtkSourceCompletionInfo* self,
+								 GtkWidget *custom_widget);
+
+GtkWidget	*gtk_source_completion_info_get_custom		(GtkSourceCompletionInfo* self);
+
+G_END_DECLS
+
+#endif

Added: branches/gtksourcecompletion/gtksourceview/gtksourcecompletionproposal.c
==============================================================================
--- (empty file)
+++ branches/gtksourcecompletion/gtksourceview/gtksourcecompletionproposal.c	Tue Apr  7 15:28:05 2009
@@ -0,0 +1,383 @@
+/*
+ * gtksourcecompletionproposal.c
+ * This file is part of gtksourcecompletion
+ *
+ * Copyright (C) 2007 -2009 JesÃs Barbero RodrÃguez <chuchiperriman gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:gtksourcecompletionproposal
+ * @title: GtkSourceCompletionProposal
+ * @short_description: Completion proposal object
+ *
+ * Every proposal is an item into the popup. It controls the label to be
+ * shown, the help (info) and the apply when the user selects the proposal.
+ */
+  
+#include "gtksourcecompletionproposal.h"
+#include "gtksourcecompletionutils.h"
+#include "gtksourcecompletionmarshal.h"
+#include "gtksourcecompletioni18n.h"
+
+#define GTK_SOURCE_COMPLETION_PROPOSAL_DEFAULT_PAGE _("Default")
+#define GTK_SOURCE_COMPLETION_PROPOSAL_DEFAULT_PRIORITY 10
+
+#define GTK_SOURCE_COMPLETION_PROPOSAL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
+							   GTK_TYPE_SOURCE_COMPLETION_PROPOSAL, GtkSourceCompletionProposalPrivate))
+
+G_DEFINE_TYPE(GtkSourceCompletionProposal, gtk_source_completion_proposal, G_TYPE_OBJECT);
+
+struct _GtkSourceCompletionProposalPrivate
+{
+	gchar *label;
+	gchar *info;
+	GdkPixbuf *icon;
+	gchar *page_name;
+};
+
+/* Properties */
+enum
+{
+	PROP_0,
+	PROP_LABEL,
+	PROP_INFO,
+	PROP_ICON,
+	PROP_PAGE_NAME
+};
+
+static gboolean
+gtk_source_completion_proposal_apply_default (GtkSourceCompletionProposal *self,
+					      GtkTextView *view)
+{
+	gtk_source_completion_utils_replace_current_word (view,
+							  self->priv->label);
+	return FALSE;
+}
+
+static const gchar *
+gtk_source_completion_proposal_get_info_default (GtkSourceCompletionProposal *self)
+{
+	return self->priv->info;
+}
+
+static void
+gtk_source_completion_proposal_init (GtkSourceCompletionProposal *self)
+{
+	self->priv = GTK_SOURCE_COMPLETION_PROPOSAL_GET_PRIVATE (self);
+	
+	self->priv->label = NULL;
+	self->priv->info = NULL;
+	self->priv->icon = NULL;
+	self->priv->page_name = g_strdup (GTK_SOURCE_COMPLETION_PROPOSAL_DEFAULT_PAGE);
+}
+
+static void
+gtk_source_completion_proposal_finalize (GObject *object)
+{
+	GtkSourceCompletionProposal *self = GTK_SOURCE_COMPLETION_PROPOSAL (object);
+	
+	g_free (self->priv->label);
+	g_free (self->priv->info);
+	g_free (self->priv->page_name);
+	
+	if (self->priv->icon != NULL)
+		g_object_unref(self->priv->icon);
+	
+	G_OBJECT_CLASS (gtk_source_completion_proposal_parent_class)->finalize (object);
+}
+
+static void
+gtk_source_completion_proposal_get_property (GObject    *object,
+					     guint       prop_id,
+					     GValue     *value,
+					     GParamSpec *pspec)
+{
+	GtkSourceCompletionProposal *self;
+
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION_PROPOSAL (object));
+
+	self = GTK_SOURCE_COMPLETION_PROPOSAL (object);
+
+	switch (prop_id)
+	{
+			
+		case PROP_LABEL:
+			g_value_set_string (value,self->priv->label);
+			break;
+		case PROP_INFO:
+			g_value_set_string (value,
+					    self->priv->info);
+			break;
+		case PROP_ICON:
+			g_value_set_pointer (value,
+					     (gpointer)self->priv->icon);
+			break;
+		case PROP_PAGE_NAME:
+			g_value_set_string (value,
+					    self->priv->page_name);
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
+gtk_source_completion_proposal_set_property (GObject      *object,
+					     guint         prop_id,
+					     const GValue *value,
+					     GParamSpec   *pspec)
+{
+	GtkSourceCompletionProposal *self;
+
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION_PROPOSAL (object));
+
+	self = GTK_SOURCE_COMPLETION_PROPOSAL (object);
+
+	switch (prop_id)
+	{
+		case PROP_LABEL:
+			self->priv->label = g_value_dup_string (value);
+			break;
+		case PROP_INFO:
+			self->priv->info = g_value_dup_string (value);
+			break;
+		case PROP_ICON:
+			if (self->priv->icon != NULL)
+				g_object_unref (self->priv->icon);
+
+			self->priv->icon = g_object_ref ((GdkPixbuf*)g_value_get_pointer (value));
+			break;
+		case PROP_PAGE_NAME:
+			self->priv->page_name = g_value_dup_string (value);
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
+gtk_source_completion_proposal_class_init (GtkSourceCompletionProposalClass *klass)
+{
+	GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+	object_class->get_property = gtk_source_completion_proposal_get_property;
+	object_class->set_property = gtk_source_completion_proposal_set_property;
+	object_class->finalize = gtk_source_completion_proposal_finalize;
+
+	g_type_class_add_private (object_class, sizeof (GtkSourceCompletionProposalPrivate));
+	
+	klass->apply = gtk_source_completion_proposal_apply_default;
+	klass->get_info = gtk_source_completion_proposal_get_info_default;
+	
+	/* Proposal properties */
+	
+	/**
+	 * GtkSourceCompletionProposal:label:
+	 *
+	 * Label to be shown for this proposal
+	 */
+	g_object_class_install_property (object_class,
+					 PROP_LABEL,
+					 g_param_spec_string ("label",
+							      _("Label to be shown for this proposal"),
+							      _("Label to be shown for this proposal"),
+							      NULL,
+							      G_PARAM_READWRITE));
+	/**
+	 * GtkSourceCompletionProposal:info:
+	 *
+	 * Info to be shown for this proposal
+	 */
+	g_object_class_install_property (object_class,
+					 PROP_INFO,
+					 g_param_spec_string ("info",
+							      _("Info to be shown for this proposal"),
+							      _("Info to be shown for this proposal"),
+							      NULL,
+							      G_PARAM_READWRITE));
+	/**
+	 * GtkSourceCompletionProposal:icon:
+	 *
+	 * Icon to be shown for this proposal
+	 */
+	g_object_class_install_property (object_class,
+					 PROP_ICON,
+					 g_param_spec_pointer ("icon",
+							      _("Icon to be shown for this proposal"),
+							      _("Icon to be shown for this proposal"),
+							      G_PARAM_READWRITE));
+
+	/**
+	 * GtkSourceCompletionProposal:page-name:
+	 *
+	 * Page name for this proposal
+	 */
+	g_object_class_install_property (object_class,
+					 PROP_PAGE_NAME,
+					 g_param_spec_string ("page-name",
+							      _("Page name for this proposal"),
+							      _("Page name for this proposal"),
+							      NULL,
+							      G_PARAM_READWRITE));
+}
+
+/**
+ * gtk_source_completion_proposal_new:
+ * @label: Item label that will be shown in the completion popup. 
+ * @info: Item info markup that will be shown when the user select to view the item info.
+ * @icon: Item icon that will be shown in the completion popup
+ *
+ * This function creates a new #GtkSourceCompletionProposal. By default, when the user selects 
+ * the proposal, the proposal label will be inserted into the GtkTextView.
+ * You can overwrite the apply and disply-info functions to overwrite the default.
+ *
+ * Returns: A new #GtkSourceCompletionProposal
+ */
+GtkSourceCompletionProposal *
+gtk_source_completion_proposal_new (const gchar *label,
+				    const gchar *info,
+				    GdkPixbuf *icon)
+{
+	GtkSourceCompletionProposal *self;
+	
+	self = GTK_SOURCE_COMPLETION_PROPOSAL (g_object_new (GTK_TYPE_SOURCE_COMPLETION_PROPOSAL, NULL));
+	
+	self->priv->label = g_strdup (label);
+	self->priv->info = g_strdup (info);
+	if (icon != NULL)
+	{
+		self->priv->icon = g_object_ref (icon);
+	}
+	else
+	{
+		self->priv->icon = NULL;
+	}
+	
+	return self;
+}
+
+/**
+ * gtk_source_completion_proposal_get_label:
+ * @self: The #GtkSourceCompletionProposal
+ *
+ * Returns: The proposal label that will be shown into the popup
+ */
+const gchar *
+gtk_source_completion_proposal_get_label (GtkSourceCompletionProposal *self)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROPOSAL (self), NULL);
+	
+	return self->priv->label;
+}
+
+/**
+ * gtk_source_completion_proposal_get_icon:
+ * @self: The #GtkSourceCompletionProposal
+ *
+ * Gets the icon of this @proposal that will be shown into the popup.
+ *
+ * Returns: the icon of this @proposal that will be shown into the popup
+ */
+const GdkPixbuf *
+gtk_source_completion_proposal_get_icon (GtkSourceCompletionProposal *self)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROPOSAL (self), NULL);
+
+	return self->priv->icon;
+}
+
+/**
+ * gtk_source_completion_proposal_set_page_name:
+ * @self: The #GtkSourceCompletionProposal
+ * @page_name: The name for the page
+ *
+ * Sets the name of the page where this proposal will be shown.
+ * If @page_name is %NULL the default page will be used.
+ */
+void
+gtk_source_completion_proposal_set_page_name (GtkSourceCompletionProposal *self,
+					      const gchar *page_name)
+{
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION_PROPOSAL (self));
+
+	g_free (self->priv->page_name);
+	
+	if (page_name == NULL)
+	{
+		self->priv->page_name = g_strdup (GTK_SOURCE_COMPLETION_PROPOSAL_DEFAULT_PAGE);
+	}
+	else
+	{
+		self->priv->page_name = g_strdup (page_name);
+	}
+}
+
+/**
+ * gtk_source_completion_proposal_get_page_name:
+ * @self: The #GtkSourceCompletionProposal
+ *
+ * Gets the page name where the @proposal will be placed.
+ *
+ * Returns: the page name where the @proposal will be placed.
+ */
+const gchar *
+gtk_source_completion_proposal_get_page_name (GtkSourceCompletionProposal *self)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROPOSAL (self), NULL);
+	
+	return self->priv->page_name;
+}
+
+/**
+ * gtk_source_completion_proposal_get_info:
+ * @self: The #GtkSourceCompletionProposal
+ *
+ * The completion calls this function when the user wants to see the proposal info.
+ * You can overwrite this function if you need to change the default mechanism.
+ *
+ * Returns: The proposal info markup asigned for this proposal or NULL;
+ */
+const gchar *
+gtk_source_completion_proposal_get_info (GtkSourceCompletionProposal *self)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROPOSAL (self), NULL);
+
+	return GTK_SOURCE_COMPLETION_PROPOSAL_GET_CLASS (self)->get_info (self);
+}
+
+/**
+ * gtk_source_completion_proposal_apply:
+ * @self: The #GtkSourceCompletionProposal
+ * @view: The #GtkTextView
+ * 
+ * The completion calls this function when the user selects the proposal. 
+ * The default handler insert the proposal label into the view. 
+ * You can overwrite this function.
+ */
+void
+gtk_source_completion_proposal_apply (GtkSourceCompletionProposal *self,
+				      GtkTextView *view)
+{
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION_PROPOSAL (self));
+	
+	GTK_SOURCE_COMPLETION_PROPOSAL_GET_CLASS (self)->apply (self, view);
+}
+
+

Added: branches/gtksourcecompletion/gtksourceview/gtksourcecompletionproposal.h
==============================================================================
--- (empty file)
+++ branches/gtksourcecompletion/gtksourceview/gtksourcecompletionproposal.h	Tue Apr  7 15:28:05 2009
@@ -0,0 +1,83 @@
+/*
+ * gtksourcecompletionproposal.h
+ * This file is part of gtksourcecompletion
+ *
+ * Copyright (C) 2007 -2009 JesÃs Barbero RodrÃguez <chuchiperriman gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA.
+ */
+ 
+#ifndef _GTK_SOURCE_COMPLETION_PROPOSAL_H
+#define _GTK_SOURCE_COMPLETION_PROPOSAL_H
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_SOURCE_COMPLETION_PROPOSAL             (gtk_source_completion_proposal_get_type ())
+#define GTK_SOURCE_COMPLETION_PROPOSAL(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SOURCE_COMPLETION_PROPOSAL, GtkSourceCompletionProposal))
+#define GTK_SOURCE_COMPLETION_PROPOSAL_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_SOURCE_COMPLETION_PROPOSAL, GtkSourceCompletionProposalClass))
+#define GTK_IS_SOURCE_COMPLETION_PROPOSAL(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SOURCE_COMPLETION_PROPOSAL))
+#define GTK_IS_SOURCE_COMPLETION_PROPOSAL_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_SOURCE_COMPLETION_PROPOSAL))
+#define GTK_SOURCE_COMPLETION_PROPOSAL_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_SOURCE_COMPLETION_PROPOSAL, GtkSourceCompletionProposalClass))
+
+typedef struct _GtkSourceCompletionProposalPrivate GtkSourceCompletionProposalPrivate;
+typedef struct _GtkSourceCompletionProposalClass GtkSourceCompletionProposalClass;
+typedef struct _GtkSourceCompletionProposal GtkSourceCompletionProposal;
+
+struct _GtkSourceCompletionProposal
+{
+	GObject parent_instance;
+	
+	GtkSourceCompletionProposalPrivate *priv;
+};
+
+struct _GtkSourceCompletionProposalClass
+{
+	GObjectClass parent_class;
+	
+	gboolean     (*apply)    (GtkSourceCompletionProposal *proposal,
+				  GtkTextView *view);
+	const gchar* (*get_info) (GtkSourceCompletionProposal *proposal);
+};
+
+GType			 gtk_source_completion_proposal_get_type	(void) G_GNUC_CONST;
+
+GtkSourceCompletionProposal
+			*gtk_source_completion_proposal_new		(const gchar *label,
+									 const gchar *info,
+									 GdkPixbuf *icon);
+
+const gchar		*gtk_source_completion_proposal_get_label	(GtkSourceCompletionProposal *proposal);
+
+const GdkPixbuf		*gtk_source_completion_proposal_get_icon	(GtkSourceCompletionProposal *proposal);
+
+
+void			 gtk_source_completion_proposal_set_page_name	(GtkSourceCompletionProposal *self,
+									 const gchar *page_name);
+
+const gchar		*gtk_source_completion_proposal_get_page_name	(GtkSourceCompletionProposal *proposal);
+
+const gchar		*gtk_source_completion_proposal_get_info	(GtkSourceCompletionProposal *proposal);
+
+void			 gtk_source_completion_proposal_apply		(GtkSourceCompletionProposal *proposal,
+									 GtkTextView *view);
+
+G_END_DECLS
+
+#endif

Added: branches/gtksourcecompletion/gtksourceview/gtksourcecompletionprovider.c
==============================================================================
--- (empty file)
+++ branches/gtksourcecompletion/gtksourceview/gtksourcecompletionprovider.c	Tue Apr  7 15:28:05 2009
@@ -0,0 +1,148 @@
+/*
+ * gtksourcecompletionprovider.c
+ * This file is part of gtksourcecompletion
+ *
+ * Copyright (C) 2007 -2009 JesÃs Barbero RodrÃguez <chuchiperriman gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+/**
+ * SECTION:gtk_source_completion-provider
+ * @title: GtkSourceCompletionProvider
+ * @short_description: Completion provider interface
+ *
+ * You must implement this interface to provide proposals to #GscCompletion
+ * 
+ */
+
+
+#include "gtksourcecompletionprovider.h"
+
+/**
+ * gtk_source_completion_provider_get_name:
+ * @self: The #GtkSourceCompletionProvider
+ *
+ * The provider name. By example: "Document word completion provider"
+ *
+ * Returns: The provider's name 
+ */
+const gchar*
+gtk_source_completion_provider_get_name (GtkSourceCompletionProvider *self)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (self), NULL);
+	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (self)->get_name (self);
+}
+
+/* Default implementation */
+static const gchar *
+gtk_source_completion_provider_get_name_default (GtkSourceCompletionProvider *self)
+{
+	g_return_val_if_reached (NULL);
+}
+
+/**
+ * gtk_source_completion_provider_get_proposals:
+ * @self: The #GtkSourceCompletionProvider
+ * @trigger: The #GscTrigger that raise the event
+ *
+ * The completion call this function when an event is raised.
+ * This function may return a list of #GscProposal to be shown
+ * in the popup to the user.
+ *
+ * Returns: a list of #GscProposal or NULL if there are no proposals
+ */
+GList* 
+gtk_source_completion_provider_get_proposals (GtkSourceCompletionProvider* self,
+					      GtkSourceCompletionTrigger *trigger)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (self), NULL);
+	return GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (self)->get_proposals (self, trigger);
+}
+
+/* Default implementation */
+static GList *
+gtk_source_completion_provider_get_proposals_default (GtkSourceCompletionProvider *self,
+						      GtkSourceCompletionTrigger *trigger)
+{
+	g_return_val_if_reached (NULL);
+}
+
+/**
+ * gtk_source_completion_provider_finish:
+ * @self: The #GtkSourceCompletionProvider
+ *
+ * The completion call this function when it is going to hide the popup (The 
+ * user selects a proposal or hide the completion popup)
+ */
+void
+gtk_source_completion_provider_finish (GtkSourceCompletionProvider* self)
+{
+	g_return_if_fail (GTK_IS_SOURCE_COMPLETION_PROVIDER (self));
+	GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE (self)->finish (self);
+}
+
+/* Default implementation */
+static void
+gtk_source_completion_provider_finish_default (GtkSourceCompletionProvider *self)
+{
+	g_return_if_reached ();
+}
+
+static void 
+gtk_source_completion_provider_base_init (GtkSourceCompletionProviderIface * iface)
+{
+	static gboolean initialized = FALSE;
+	
+	iface->get_name = gtk_source_completion_provider_get_name_default;
+	iface->get_proposals = gtk_source_completion_provider_get_proposals_default;
+	iface->finish = gtk_source_completion_provider_finish_default;
+	
+	if (!initialized) {
+		initialized = TRUE;
+	}
+}
+
+
+GType 
+gtk_source_completion_provider_get_type ()
+{
+	static GType gtk_source_completion_provider_type_id = 0;
+	if (!gtk_source_completion_provider_type_id) {
+		static const GTypeInfo g_define_type_info = 
+		{ 
+			sizeof (GtkSourceCompletionProviderIface), 
+			(GBaseInitFunc) gtk_source_completion_provider_base_init, 
+			(GBaseFinalizeFunc) NULL, 
+			(GClassInitFunc) NULL, 
+			(GClassFinalizeFunc) NULL, 
+			NULL, 
+			0, 
+			0, 
+			(GInstanceInitFunc) NULL 
+		};
+						
+		gtk_source_completion_provider_type_id = 
+				g_type_register_static (G_TYPE_INTERFACE, 
+							"GtkSourceCompletionProvider", 
+							&g_define_type_info, 
+							0);
+	}
+	return gtk_source_completion_provider_type_id;
+}
+
+

Added: branches/gtksourcecompletion/gtksourceview/gtksourcecompletionprovider.h
==============================================================================
--- (empty file)
+++ branches/gtksourcecompletion/gtksourceview/gtksourcecompletionprovider.h	Tue Apr  7 15:28:05 2009
@@ -0,0 +1,65 @@
+/*
+ * gtksourcecompletionprovider.h
+ * This file is part of gtksourcecompletion
+ *
+ * Copyright (C) 2007 -2009 JesÃs Barbero RodrÃguez <chuchiperriman gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_SOURCE_COMPLETION_PROVIDER_H__
+#define __GTK_SOURCE_COMPLETION_PROVIDER_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "gtksourcecompletionproposal.h"
+#include "gtksourcecompletiontrigger.h"
+
+G_BEGIN_DECLS
+
+
+#define GTK_TYPE_SOURCE_COMPLETION_PROVIDER (gtk_source_completion_provider_get_type ())
+#define GTK_SOURCE_COMPLETION_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SOURCE_COMPLETION_PROVIDER, GtkSourceCompletionProvider))
+#define GTK_IS_SOURCE_COMPLETION_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SOURCE_COMPLETION_PROVIDER))
+#define GTK_SOURCE_COMPLETION_PROVIDER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_SOURCE_COMPLETION_PROVIDER, GtkSourceCompletionProviderIface))
+
+typedef struct _GtkSourceCompletionProvider GtkSourceCompletionProvider;
+typedef struct _GtkSourceCompletionProviderIface GtkSourceCompletionProviderIface;
+
+struct _GtkSourceCompletionProviderIface
+{
+	GTypeInterface g_iface;
+	
+	const gchar* (*get_name)       (GtkSourceCompletionProvider *self);
+	GList*       (*get_proposals)  (GtkSourceCompletionProvider *self,
+				        GtkSourceCompletionTrigger *trigger);
+	void         (*finish)         (GtkSourceCompletionProvider *self);
+};
+
+GType		 gtk_source_completion_provider_get_type	(void);
+
+
+const gchar	*gtk_source_completion_provider_get_name	(GtkSourceCompletionProvider *self);
+
+GList		*gtk_source_completion_provider_get_proposals	(GtkSourceCompletionProvider *self, 
+								 GtkSourceCompletionTrigger  *trigger);
+				
+void		 gtk_source_completion_provider_finish		(GtkSourceCompletionProvider *self);
+
+G_END_DECLS
+
+#endif

Added: branches/gtksourcecompletion/gtksourceview/gtksourcecompletiontrigger.c
==============================================================================
--- (empty file)
+++ branches/gtksourcecompletion/gtksourceview/gtksourcecompletiontrigger.c	Tue Apr  7 15:28:05 2009
@@ -0,0 +1,141 @@
+/*
+ * gtksourcecompletiontrigger.c
+ * This file is part of gtksourcecompletion
+ *
+ * Copyright (C) 2007 -2009 JesÃs Barbero RodrÃguez <chuchiperriman gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:gsc-trigger
+ * @title: GtkSourceCompletionTrigger
+ * @short_description: Completion trigger interface
+ *
+ * You must implement this interface to trigger completion events with #GscCompletion
+ * 
+ */
+ 
+#include "gtksourcecompletiontrigger.h"
+
+/**
+ * gtk_source_completion_trigger_get_name:
+ * @self: The #GtkSourceCompletionTrigger
+ *
+ * The trigger name. By example: "C autocompletion trigger".
+ *
+ * Returns: The trigger's name
+ */
+const gchar*
+gtk_source_completion_trigger_get_name (GtkSourceCompletionTrigger *self)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_TRIGGER (self), NULL);
+	return GTK_SOURCE_COMPLETION_TRIGGER_GET_INTERFACE (self)->get_name (self);
+}
+
+/* Default implementation */
+static const gchar *
+gtk_source_completion_trigger_get_name_default (GtkSourceCompletionTrigger *self)
+{
+	g_return_val_if_reached (NULL);
+}
+
+/**
+ * gtk_source_completion_trigger_activate:
+ * @self: The #GtkSourceCompletionTrigger
+ *
+ * Activate the completion trigger.
+ *
+ * Returns: %TRUE if the activation was OK, %FALSE if not.
+ */
+gboolean
+gtk_source_completion_trigger_activate (GtkSourceCompletionTrigger *self)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_TRIGGER (self), FALSE);
+	return GTK_SOURCE_COMPLETION_TRIGGER_GET_INTERFACE (self)->activate (self);
+}
+
+/* Default implementation */
+static gboolean
+gtk_source_completion_trigger_activate_default (GtkSourceCompletionTrigger *self)
+{
+	g_return_val_if_reached (FALSE);
+}
+
+/**
+ * gtk_source_completion_trigger_deactivate:
+ * @self: The #GtkSourceCompletionTrigger
+ *
+ * Deactive the completion trigger
+ *
+ * Returns: TRUE if the deactivation was OK, FALSE if not.
+ */
+gboolean
+gtk_source_completion_trigger_deactivate (GtkSourceCompletionTrigger* self)
+{
+	g_return_val_if_fail (GTK_IS_SOURCE_COMPLETION_TRIGGER (self), FALSE);
+	return GTK_SOURCE_COMPLETION_TRIGGER_GET_INTERFACE (self)->deactivate (self);
+}
+
+/* Default implementation */
+static gboolean
+gtk_source_completion_trigger_deactivate_default (GtkSourceCompletionTrigger *self)
+{
+	g_return_val_if_reached (FALSE);
+}
+
+static void 
+gtk_source_completion_trigger_base_init (GtkSourceCompletionTriggerIface *iface)
+{
+	static gboolean initialized = FALSE;
+	
+	iface->get_name = gtk_source_completion_trigger_get_name_default;
+	iface->activate = gtk_source_completion_trigger_activate_default;
+	iface->deactivate = gtk_source_completion_trigger_deactivate_default;
+	
+	if (!initialized) {
+		initialized = TRUE;
+	}
+}
+
+GType
+gtk_source_completion_trigger_get_type ()
+{
+	static GType gtk_source_completion_trigger_type_id = 0;
+	if (!gtk_source_completion_trigger_type_id) {
+		static const GTypeInfo g_define_type_info = 
+		{ 
+			sizeof (GtkSourceCompletionTriggerIface), 
+			(GBaseInitFunc) gtk_source_completion_trigger_base_init, 
+			(GBaseFinalizeFunc) NULL, 
+			(GClassInitFunc) NULL, 
+			(GClassFinalizeFunc) NULL, 
+			NULL, 
+			0, 
+			0, 
+			(GInstanceInitFunc) NULL 
+		};
+							
+		gtk_source_completion_trigger_type_id = 
+			g_type_register_static (G_TYPE_INTERFACE, 
+						"GtkSourceCompletionTrigger", 
+						&g_define_type_info, 
+						0);
+	}
+	return gtk_source_completion_trigger_type_id;
+}
+
+

Added: branches/gtksourcecompletion/gtksourceview/gtksourcecompletiontrigger.h
==============================================================================
--- (empty file)
+++ branches/gtksourcecompletion/gtksourceview/gtksourcecompletiontrigger.h	Tue Apr  7 15:28:05 2009
@@ -0,0 +1,59 @@
+/*
+ * gtksourcecompletiontrigger.h
+ * This file is part of gtksourcecompletion
+ *
+ * Copyright (C) 2007 -2009 JesÃs Barbero RodrÃguez <chuchiperriman gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA.
+ */
+  
+#ifndef __GTK_SOURCE_COMPLETION_TRIGGER_H__
+#define __GTK_SOURCE_COMPLETION_TRIGGER_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+
+#define GTK_TYPE_SOURCE_COMPLETION_TRIGGER (gtk_source_completion_trigger_get_type ())
+#define GTK_SOURCE_COMPLETION_TRIGGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_SOURCE_COMPLETION_TRIGGER, GtkSourceCompletionTrigger))
+#define GTK_IS_SOURCE_COMPLETION_TRIGGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_SOURCE_COMPLETION_TRIGGER))
+#define GTK_SOURCE_COMPLETION_TRIGGER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_SOURCE_COMPLETION_TRIGGER, GtkSourceCompletionTriggerIface))
+
+typedef struct _GtkSourceCompletionTrigger GtkSourceCompletionTrigger;
+typedef struct _GtkSourceCompletionTriggerIface GtkSourceCompletionTriggerIface;
+
+struct _GtkSourceCompletionTriggerIface {
+	GTypeInterface parent;
+	
+	const gchar* (*get_name)   (GtkSourceCompletionTrigger *self);
+	gboolean     (*activate)   (GtkSourceCompletionTrigger* self);
+	gboolean     (*deactivate) (GtkSourceCompletionTrigger* self);
+};
+
+GType		 gtk_source_completion_trigger_get_type		(void);
+
+const gchar	*gtk_source_completion_trigger_get_name		(GtkSourceCompletionTrigger *self);
+
+gboolean	 gtk_source_completion_trigger_activate		(GtkSourceCompletionTrigger *self);
+				
+gboolean	 gtk_source_completion_trigger_deactivate	(GtkSourceCompletionTrigger *self);
+
+G_END_DECLS
+
+#endif

Added: branches/gtksourcecompletion/gtksourceview/gtksourcecompletionutils.c
==============================================================================
--- (empty file)
+++ branches/gtksourcecompletion/gtksourceview/gtksourcecompletionutils.c	Tue Apr  7 15:28:05 2009
@@ -0,0 +1,301 @@
+/*
+ * gtksourcecompletionutils.c
+ * This file is part of gtksourcecompletion
+ *
+ * Copyright (C) 2007 -2009 JesÃs Barbero RodrÃguez <chuchiperriman gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:gsc-utils
+ * @title: Gsc Utils
+ * @short_description: Useful functions
+ *
+ */
+ 
+#include <string.h> 
+#include "gtksourcecompletionutils.h"
+
+/**
+ * gsc_utils_char_is_separator:
+ * @ch: The character to check
+ *
+ * A separator is a character like (, an space etc. An _ is not a separator
+ *
+ * Returns TRUE if the ch is a separator
+ */
+gboolean
+gtk_source_completion_utils_is_separator(const gunichar ch)
+{
+	if (g_unichar_isprint(ch) && 
+	    (g_unichar_isalnum(ch) || ch == g_utf8_get_char("_")))
+	{
+		return FALSE;
+	}
+	
+	return TRUE;
+}
+
+/**
+* gsc_utils_view_get_last_word_and_iter:
+* @text_view: The #GtkTextView
+* @start_word: if != NULL then assign it the start position of the word
+* @end_word: if != NULL then assing it the end position of the word
+* 
+* Returns: the last word written in the #GtkTextView or ""
+*
+**/
+gchar*
+gtk_source_completion_utils_get_word_iter(GtkTextView *text_view, 
+				      GtkTextIter *start_word, 
+				      GtkTextIter *end_word)
+{
+	GtkTextMark* insert_mark;
+	GtkTextBuffer* text_buffer;
+	GtkTextIter actual,temp;
+	GtkTextIter *start_iter;
+	gchar* text;
+	gunichar ch;
+	gboolean found, no_doc_start;
+	
+	if (start_word != NULL)
+	{
+		start_iter = start_word;
+	}
+	else
+	{
+		start_iter = &temp;
+	}
+	
+	text_buffer = gtk_text_view_get_buffer(text_view);
+	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;
+	}
+	
+	found = FALSE;
+	while ((no_doc_start = gtk_text_iter_backward_char(start_iter)) == TRUE)
+	{
+		ch = gtk_text_iter_get_char(start_iter);
+		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);
+	}
+	else
+	{
+	
+		if (found)
+		{
+			gtk_text_iter_forward_char(start_iter);
+			text = gtk_text_iter_get_text (start_iter, &actual);
+		}
+		else
+		{
+			*start_iter = actual;
+			/*FIXME dup this var?*/
+			text = "";
+		}
+	}
+	
+	return text;
+}
+
+/**
+ * gsc_utils_view_get_last_word:
+ * @text_view: The #GtkTextView
+ *
+ * Returns: the last word written in the #GtkTextView or ""
+ */
+gchar*
+gtk_source_completion_utils_get_word(GtkTextView *text_view)
+{
+	return gtk_source_completion_utils_get_word_iter (text_view, NULL, NULL);
+}
+
+/** 
+ * gsc_utils_view_get_cursor_pos:
+ * @text_view: The #GtkTextView
+ * @x: Assign the x position of the cursor
+ * @y: Assign the y position of the cursor
+ *
+ * Gets the cursor position on the screen.
+ */
+void
+gtk_source_completion_utils_get_cursor_pos(GtkTextView *text_view, 
+			      gint *x, 
+			      gint *y)
+{
+	GdkWindow *win;
+	GtkTextMark* insert_mark;
+	GtkTextBuffer* text_buffer;
+	GtkTextIter start;
+	GdkRectangle location;
+	gint win_x, win_y;
+	gint xx, yy;
+
+	text_buffer = gtk_text_view_get_buffer(text_view);
+	insert_mark = gtk_text_buffer_get_insert(text_buffer);
+	gtk_text_buffer_get_iter_at_mark(text_buffer,&start,insert_mark);
+	gtk_text_view_get_iter_location(text_view,
+					&start,
+					&location );
+	gtk_text_view_buffer_to_window_coords (text_view,
+						GTK_TEXT_WINDOW_WIDGET,
+						location.x, 
+						location.y,
+						&win_x, 
+						&win_y);
+
+	win = gtk_text_view_get_window (text_view, 
+	                                GTK_TEXT_WINDOW_WIDGET);
+	gdk_window_get_origin (win, &xx, &yy);
+	
+	*x = win_x + xx;
+	*y = win_y + yy + location.height;
+}
+
+/**
+ * gsc_utils_view_replace_current_word:
+ * @text_view: The #GtkTextView
+ * @text: The text to be inserted instead of the current word
+ * 
+ * Replaces the current word in the #GtkTextView with the new word
+ *
+ */
+void
+gtk_source_completion_utils_replace_current_word(GtkTextView *text_view, 
+				    const gchar* text)
+{
+	GtkTextBuffer *buffer;
+	GtkTextIter word_start, word_end;
+	
+	buffer = gtk_text_view_get_buffer(text_view);
+	gtk_text_buffer_begin_user_action(buffer);
+	
+	gtk_source_completion_utils_get_word_iter (text_view,&word_start, &word_end);
+
+	GtkTextMark *mark = gtk_text_buffer_create_mark(buffer,
+							"temp_replace",
+							&word_start,
+							TRUE);
+	gtk_text_buffer_delete(buffer,&word_start,&word_end);
+	gtk_text_buffer_get_iter_at_mark(buffer,&word_start,mark);
+	gtk_text_buffer_insert(buffer, &word_start, text,-1);
+	gtk_text_buffer_delete_mark(buffer,mark);
+	gtk_text_buffer_end_user_action(buffer);
+}
+
+/**
+ * gsc_utils_window_get_position_at_cursor:
+ * @window: Window to set
+ * @view: Parent view where we get the cursor position
+ * @x: The returned x position
+ * @y: The returned y position
+ *
+ * Returns: TRUE if the position is over the text and FALSE if 
+ * the position is under the text.
+ */
+gboolean 
+gtk_source_completion_utils_get_pos_at_cursor(GtkWindow *window,
+					GtkTextView *view,
+					gint *x,
+					gint *y,
+					gboolean *resized)
+{
+	gint w, h, xtext, ytext, ytemp;
+	gint sw = gdk_screen_width();
+	gint sh = gdk_screen_height();
+	gboolean resize = FALSE;
+	gboolean up = FALSE;
+	gtk_source_completion_utils_get_cursor_pos (view,x,y);
+	
+	gtk_window_get_size(window, &w, &h);
+	
+	/* Processing x position and width */
+	if (w > (sw - 8))
+	{
+		/* Resize to view all the window */
+		resize = TRUE;
+		w = sw -8;
+	}
+	
+	/* Move position to view all the window */
+	if ((*x + w) > (sw - 4))
+	{
+		*x = sw - w -4;
+	}
+
+	/* Processing y position and height */
+	
+	/* 
+	If we cannot show it down, we show it up and if we cannot show it up, we
+	show the window at the largest position 
+	*/
+	if ((*y + h) > sh)
+	{
+		PangoLayout* layout = 
+			gtk_widget_create_pango_layout(GTK_WIDGET(view), NULL);
+		pango_layout_get_pixel_size(layout,&xtext,&ytext);
+		ytemp = *y - ytext;
+		/* Cabe arriba? */
+		if ((ytemp - h) >= 4)
+		{
+			*y = ytemp - h;
+			up = TRUE;
+		}
+		else
+		{
+			/* 
+			Si no cabe arriba, lo ponemos donde haya mÃs espacio
+			y redimensionamos la ventana
+			*/
+			if ((sh - *y) > ytemp)
+			{
+				h = sh - *y - 4;
+			}
+			else
+			{
+				*y = 4;
+				h = ytemp -4;
+				up = TRUE;
+			}
+			resize = TRUE;
+		}
+		g_object_unref(layout);
+	}
+	
+	if (resize)
+		gtk_window_resize(window, w, h);
+
+	if (resized != NULL)
+		*resized = resize;
+	
+	return up;
+}
+

Added: branches/gtksourcecompletion/gtksourceview/gtksourcecompletionutils.h
==============================================================================
--- (empty file)
+++ branches/gtksourcecompletion/gtksourceview/gtksourcecompletionutils.h	Tue Apr  7 15:28:05 2009
@@ -0,0 +1,49 @@
+/*
+ * gtksourcecompletion-utils.h
+ * This file is part of gtksourcecompletion
+ *
+ * Copyright (C) 2007 -2009 JesÃs Barbero RodrÃguez <chuchiperriman gmail com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA.
+ */
+ 
+#ifndef GTK_SOURCE_COMPLETION_UTILS_H
+#define GTK_SOURCE_COMPLETION_UTILS_H
+
+#include <gtk/gtk.h>
+
+gboolean	gtk_source_completion_utils_is_separator		(gunichar ch);
+
+gchar		*gtk_source_completion_utils_get_word_iter		(GtkTextView *text_view, 
+									 GtkTextIter *start_word, 
+									 GtkTextIter *end_word);
+
+gchar		*gtk_source_completion_utils_get_word			(GtkTextView *text_view);
+
+void		gtk_source_completion_utils_get_cursor_pos		(GtkTextView *text_view, 
+									 gint *x, 
+									 gint *y);
+
+void		gtk_source_completion_utils_replace_current_word	(GtkTextView *text_view, 
+									 const gchar* text);
+
+gboolean	gtk_source_completion_utils_get_pos_at_cursor		(GtkWindow *window,
+									 GtkTextView *view,
+									 gint *x,
+									 gint *y,
+									 gboolean *resized);
+
+#endif 

Modified: branches/gtksourcecompletion/gtksourceview/gtksourceview-marshal.list
==============================================================================
--- branches/gtksourcecompletion/gtksourceview/gtksourceview-marshal.list	(original)
+++ branches/gtksourcecompletion/gtksourceview/gtksourceview-marshal.list	Tue Apr  7 15:28:05 2009
@@ -4,3 +4,5 @@
 VOID:BOXED,BOXED
 VOID:INT,INT
 VOID:STRING
+BOOLEAN:POINTER
+BOOLEAN:VOID



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