Blame tests/test-completion.c

Packit a7d494
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*-
Packit a7d494
 * test-completion.c
Packit a7d494
 * This file is part of GtkSourceView
Packit a7d494
 *
Packit a7d494
 * Copyright (C) 2007 - Jesús Barbero Rodríguez <chuchiperriman@gmail.com>
Packit a7d494
 * Copyright (C) 2013 - Sébastien Wilmet <swilmet@gnome.org>
Packit a7d494
 *
Packit a7d494
 * GtkSourceView is free software; you can redistribute it and/or
Packit a7d494
 * modify it under the terms of the GNU Lesser General Public
Packit a7d494
 * License as published by the Free Software Foundation; either
Packit a7d494
 * version 2.1 of the License, or (at your option) any later version.
Packit a7d494
 *
Packit a7d494
 * GtkSourceView is distributed in the hope that it will be useful,
Packit a7d494
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit a7d494
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit a7d494
 * Lesser General Public License for more details.
Packit a7d494
 *
Packit a7d494
 * You should have received a copy of the GNU Lesser General Public
Packit a7d494
 * License along with this library; if not, write to the Free Software
Packit a7d494
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
Packit a7d494
 */
Packit a7d494
Packit a7d494
#include <gtk/gtk.h>
Packit a7d494
#include <gtksourceview/gtksource.h>
Packit a7d494
Packit a7d494
typedef struct _TestProvider TestProvider;
Packit a7d494
typedef struct _TestProviderClass TestProviderClass;
Packit a7d494
Packit a7d494
static GtkSourceCompletionWords *word_provider;
Packit a7d494
static TestProvider *fixed_provider;
Packit a7d494
static TestProvider *random_provider;
Packit a7d494
Packit a7d494
struct _TestProvider
Packit a7d494
{
Packit a7d494
	GObject parent;
Packit a7d494
Packit a7d494
	GList *proposals;
Packit a7d494
	gint priority;
Packit a7d494
	gchar *name;
Packit a7d494
Packit a7d494
	GdkPixbuf *provider_icon;
Packit a7d494
Packit a7d494
	GdkPixbuf *item_icon;
Packit a7d494
	GIcon *item_gicon;
Packit a7d494
Packit a7d494
	/* If it's a random provider, a subset of 'proposals' are choosen on
Packit a7d494
	 * each populate. Otherwise, all the proposals are shown. */
Packit a7d494
	guint is_random : 1;
Packit a7d494
};
Packit a7d494
Packit a7d494
struct _TestProviderClass
Packit a7d494
{
Packit a7d494
	GObjectClass parent_class;
Packit a7d494
};
Packit a7d494
Packit a7d494
static void test_provider_iface_init (GtkSourceCompletionProviderIface *iface);
Packit a7d494
GType test_provider_get_type (void);
Packit a7d494
Packit a7d494
G_DEFINE_TYPE_WITH_CODE (TestProvider,
Packit a7d494
			 test_provider,
Packit a7d494
			 G_TYPE_OBJECT,
Packit a7d494
			 G_IMPLEMENT_INTERFACE (GTK_SOURCE_TYPE_COMPLETION_PROVIDER,
Packit a7d494
				 		test_provider_iface_init))
Packit a7d494
Packit a7d494
static gchar *
Packit a7d494
test_provider_get_name (GtkSourceCompletionProvider *provider)
Packit a7d494
{
Packit a7d494
	return g_strdup (((TestProvider *)provider)->name);
Packit a7d494
}
Packit a7d494
Packit a7d494
static gint
Packit a7d494
test_provider_get_priority (GtkSourceCompletionProvider *provider)
Packit a7d494
{
Packit a7d494
	return ((TestProvider *)provider)->priority;
Packit a7d494
}
Packit a7d494
Packit a7d494
static GList *
Packit a7d494
select_random_proposals (GList *all_proposals)
Packit a7d494
{
Packit a7d494
	GList *selection = NULL;
Packit a7d494
	GList *prop;
Packit a7d494
Packit a7d494
	for (prop = all_proposals; prop != NULL; prop = g_list_next (prop))
Packit a7d494
	{
Packit a7d494
		if (g_random_boolean ())
Packit a7d494
		{
Packit a7d494
			selection = g_list_prepend (selection, prop->data);
Packit a7d494
		}
Packit a7d494
	}
Packit a7d494
Packit a7d494
	return selection;
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
test_provider_populate (GtkSourceCompletionProvider *completion_provider,
Packit a7d494
                        GtkSourceCompletionContext  *context)
Packit a7d494
{
Packit a7d494
	TestProvider *provider = (TestProvider *)completion_provider;
Packit a7d494
	GList *proposals;
Packit a7d494
Packit a7d494
	if (provider->is_random)
Packit a7d494
	{
Packit a7d494
		proposals = select_random_proposals (provider->proposals);
Packit a7d494
	}
Packit a7d494
	else
Packit a7d494
	{
Packit a7d494
		proposals = provider->proposals;
Packit a7d494
	}
Packit a7d494
Packit a7d494
	gtk_source_completion_context_add_proposals (context,
Packit a7d494
						     completion_provider,
Packit a7d494
						     proposals,
Packit a7d494
						     TRUE);
Packit a7d494
}
Packit a7d494
Packit a7d494
static GdkPixbuf *
Packit a7d494
test_provider_get_icon (GtkSourceCompletionProvider *provider)
Packit a7d494
{
Packit a7d494
	TestProvider *tp = (TestProvider *)provider;
Packit a7d494
Packit a7d494
	return tp->is_random ? NULL : tp->provider_icon;
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
test_provider_iface_init (GtkSourceCompletionProviderIface *iface)
Packit a7d494
{
Packit a7d494
	iface->get_name = test_provider_get_name;
Packit a7d494
	iface->populate = test_provider_populate;
Packit a7d494
	iface->get_priority = test_provider_get_priority;
Packit a7d494
	iface->get_icon = test_provider_get_icon;
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
test_provider_dispose (GObject *gobject)
Packit a7d494
{
Packit a7d494
	TestProvider *self = (TestProvider *)gobject;
Packit a7d494
Packit a7d494
	g_list_free_full (self->proposals, g_object_unref);
Packit a7d494
	self->proposals = NULL;
Packit a7d494
Packit a7d494
	g_clear_object (&self->provider_icon);
Packit a7d494
	g_clear_object (&self->item_icon);
Packit a7d494
	g_clear_object (&self->item_gicon);
Packit a7d494
Packit a7d494
	G_OBJECT_CLASS (test_provider_parent_class)->dispose (gobject);
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
test_provider_finalize (GObject *gobject)
Packit a7d494
{
Packit a7d494
	TestProvider *self = (TestProvider *)gobject;
Packit a7d494
Packit a7d494
	g_free (self->name);
Packit a7d494
	self->name = NULL;
Packit a7d494
Packit a7d494
	G_OBJECT_CLASS (test_provider_parent_class)->finalize (gobject);
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
test_provider_class_init (TestProviderClass *klass)
Packit a7d494
{
Packit a7d494
	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
Packit a7d494
Packit a7d494
	gobject_class->dispose = test_provider_dispose;
Packit a7d494
	gobject_class->finalize = test_provider_finalize;
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
test_provider_init (TestProvider *self)
Packit a7d494
{
Packit a7d494
	GtkIconTheme *theme;
Packit a7d494
	GIcon *icon;
Packit a7d494
	GIcon *emblem_icon;
Packit a7d494
	GEmblem *emblem;
Packit a7d494
Packit a7d494
	theme = gtk_icon_theme_get_default ();
Packit a7d494
	self->provider_icon = gtk_icon_theme_load_icon (theme, "dialog-information", 16, 0, NULL);
Packit a7d494
Packit a7d494
	self->item_icon = gtk_icon_theme_load_icon (theme, "trophy-gold", 16, 0, NULL);
Packit a7d494
Packit a7d494
	icon = g_themed_icon_new ("trophy-silver");
Packit a7d494
	emblem_icon = g_themed_icon_new ("emblem-urgent");
Packit a7d494
	emblem = g_emblem_new (emblem_icon);
Packit a7d494
	self->item_gicon = g_emblemed_icon_new (icon, emblem);
Packit a7d494
	g_object_unref (icon);
Packit a7d494
	g_object_unref (emblem_icon);
Packit a7d494
	g_object_unref (emblem);
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
test_provider_set_fixed (TestProvider *provider,
Packit a7d494
			 gint          nb_proposals)
Packit a7d494
{
Packit a7d494
	GtkSourceCompletionItem *item;
Packit a7d494
	GList *proposals = NULL;
Packit a7d494
	gint i;
Packit a7d494
Packit a7d494
	g_list_free_full (provider->proposals, g_object_unref);
Packit a7d494
Packit a7d494
	item = gtk_source_completion_item_new2 ();
Packit a7d494
	gtk_source_completion_item_set_markup (item, "A very long proposal. I repeat, a very long proposal!");
Packit a7d494
	gtk_source_completion_item_set_text (item, "A very long proposal. I repeat, a very long proposal!");
Packit a7d494
	gtk_source_completion_item_set_icon (item, provider->item_icon);
Packit a7d494
	gtk_source_completion_item_set_info (item, "To test the horizontal scrollbar and the markup.");
Packit a7d494
	proposals = g_list_prepend (proposals, item);
Packit a7d494
Packit a7d494
	item = gtk_source_completion_item_new2 ();
Packit a7d494
	gtk_source_completion_item_set_markup (item, "A proposal with a symbolic icon");
Packit a7d494
	gtk_source_completion_item_set_text (item, "Test setting the icon-name property");
Packit a7d494
	gtk_source_completion_item_set_icon_name (item, "face-cool-symbolic");
Packit a7d494
	proposals = g_list_prepend (proposals, item);
Packit a7d494
Packit a7d494
	item = gtk_source_completion_item_new2 ();
Packit a7d494
	gtk_source_completion_item_set_markup (item, "A proposal with an emblem GIcon");
Packit a7d494
	gtk_source_completion_item_set_text (item, "Test setting the GIcon property");
Packit a7d494
	gtk_source_completion_item_set_gicon (item, provider->item_gicon);
Packit a7d494
	proposals = g_list_prepend (proposals, item);
Packit a7d494
Packit a7d494
	for (i = nb_proposals - 1; i > 0; i--)
Packit a7d494
	{
Packit a7d494
		gchar *name = g_strdup_printf ("Proposal %d", i);
Packit a7d494
Packit a7d494
		item = gtk_source_completion_item_new2 ();
Packit a7d494
		gtk_source_completion_item_set_label (item, name);
Packit a7d494
		gtk_source_completion_item_set_text (item, name);
Packit a7d494
		gtk_source_completion_item_set_icon (item, provider->item_icon);
Packit a7d494
		gtk_source_completion_item_set_info (item, "The extra info of the proposal.\nA second line.");
Packit a7d494
		proposals = g_list_prepend (proposals, item);
Packit a7d494
Packit a7d494
		g_free (name);
Packit a7d494
	}
Packit a7d494
Packit a7d494
	provider->proposals = proposals;
Packit a7d494
	provider->is_random = 0;
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
test_provider_set_random (TestProvider *provider,
Packit a7d494
			  gint          nb_proposals)
Packit a7d494
{
Packit a7d494
	GList *proposals = NULL;
Packit a7d494
	gint i;
Packit a7d494
Packit a7d494
	g_list_free_full (provider->proposals, g_object_unref);
Packit a7d494
Packit a7d494
	for (i = 0; i < nb_proposals; i++)
Packit a7d494
	{
Packit a7d494
		GtkSourceCompletionItem *item;
Packit a7d494
		gchar *padding = g_strnfill ((i * 3) % 10, 'o');
Packit a7d494
		gchar *name = g_strdup_printf ("Propo%ssal %d", padding, i);
Packit a7d494
Packit a7d494
		item = gtk_source_completion_item_new2 ();
Packit a7d494
		gtk_source_completion_item_set_label (item, name);
Packit a7d494
		gtk_source_completion_item_set_text (item, name);
Packit a7d494
		gtk_source_completion_item_set_icon (item, provider->item_icon);
Packit a7d494
		proposals = g_list_prepend (proposals, item);
Packit a7d494
Packit a7d494
		g_free (padding);
Packit a7d494
		g_free (name);
Packit a7d494
	}
Packit a7d494
Packit a7d494
	provider->proposals = proposals;
Packit a7d494
	provider->is_random = 1;
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
add_remove_provider (GtkToggleButton             *button,
Packit a7d494
		     GtkSourceCompletion         *completion,
Packit a7d494
		     GtkSourceCompletionProvider *provider)
Packit a7d494
{
Packit a7d494
	g_return_if_fail (provider != NULL);
Packit a7d494
Packit a7d494
	if (gtk_toggle_button_get_active (button))
Packit a7d494
	{
Packit a7d494
		gtk_source_completion_add_provider (completion, provider, NULL);
Packit a7d494
	}
Packit a7d494
	else
Packit a7d494
	{
Packit a7d494
		gtk_source_completion_remove_provider (completion, provider, NULL);
Packit a7d494
	}
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
enable_word_provider_toggled_cb (GtkToggleButton     *button,
Packit a7d494
				 GtkSourceCompletion *completion)
Packit a7d494
{
Packit a7d494
	add_remove_provider (button,
Packit a7d494
			     completion,
Packit a7d494
			     GTK_SOURCE_COMPLETION_PROVIDER (word_provider));
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
enable_fixed_provider_toggled_cb (GtkToggleButton     *button,
Packit a7d494
				  GtkSourceCompletion *completion)
Packit a7d494
{
Packit a7d494
	add_remove_provider (button,
Packit a7d494
			     completion,
Packit a7d494
			     GTK_SOURCE_COMPLETION_PROVIDER (fixed_provider));
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
enable_random_provider_toggled_cb (GtkToggleButton     *button,
Packit a7d494
				   GtkSourceCompletion *completion)
Packit a7d494
{
Packit a7d494
	add_remove_provider (button,
Packit a7d494
			     completion,
Packit a7d494
			     GTK_SOURCE_COMPLETION_PROVIDER (random_provider));
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
nb_proposals_changed_cb (GtkSpinButton *spin_button,
Packit a7d494
			 TestProvider  *provider)
Packit a7d494
{
Packit a7d494
	gint nb_proposals = gtk_spin_button_get_value_as_int (spin_button);
Packit a7d494
Packit a7d494
	if (provider->is_random)
Packit a7d494
	{
Packit a7d494
		test_provider_set_random (provider, nb_proposals);
Packit a7d494
	}
Packit a7d494
	else
Packit a7d494
	{
Packit a7d494
		test_provider_set_fixed (provider, nb_proposals);
Packit a7d494
	}
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
create_completion (GtkSourceView       *source_view,
Packit a7d494
		   GtkSourceCompletion *completion)
Packit a7d494
{
Packit a7d494
	/* Words completion provider */
Packit a7d494
	word_provider = gtk_source_completion_words_new (NULL, NULL);
Packit a7d494
Packit a7d494
	gtk_source_completion_words_register (word_provider,
Packit a7d494
	                                      gtk_text_view_get_buffer (GTK_TEXT_VIEW (source_view)));
Packit a7d494
Packit a7d494
	gtk_source_completion_add_provider (completion,
Packit a7d494
	                                    GTK_SOURCE_COMPLETION_PROVIDER (word_provider),
Packit a7d494
	                                    NULL);
Packit a7d494
Packit a7d494
	g_object_set (word_provider, "priority", 10, NULL);
Packit a7d494
Packit a7d494
	/* Fixed provider: the proposals don't change */
Packit a7d494
	fixed_provider = g_object_new (test_provider_get_type (), NULL);
Packit a7d494
	test_provider_set_fixed (fixed_provider, 3);
Packit a7d494
	fixed_provider->priority = 5;
Packit a7d494
	fixed_provider->name = g_strdup ("Fixed Provider");
Packit a7d494
Packit a7d494
	gtk_source_completion_add_provider (completion,
Packit a7d494
	                                    GTK_SOURCE_COMPLETION_PROVIDER (fixed_provider),
Packit a7d494
	                                    NULL);
Packit a7d494
Packit a7d494
	/* Random provider: the proposals vary on each populate */
Packit a7d494
	random_provider = g_object_new (test_provider_get_type (), NULL);
Packit a7d494
	test_provider_set_random (random_provider, 10);
Packit a7d494
	random_provider->priority = 1;
Packit a7d494
	random_provider->name = g_strdup ("Random Provider");
Packit a7d494
Packit a7d494
	gtk_source_completion_add_provider (completion,
Packit a7d494
	                                    GTK_SOURCE_COMPLETION_PROVIDER (random_provider),
Packit a7d494
	                                    NULL);
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
create_window (void)
Packit a7d494
{
Packit a7d494
	GtkBuilder *builder;
Packit a7d494
	GError *error = NULL;
Packit a7d494
	GtkWindow *window;
Packit a7d494
	GtkSourceView *source_view;
Packit a7d494
	GtkSourceCompletion *completion;
Packit a7d494
	GtkCheckButton *remember_info_visibility;
Packit a7d494
	GtkCheckButton *select_on_show;
Packit a7d494
	GtkCheckButton *show_headers;
Packit a7d494
	GtkCheckButton *show_icons;
Packit a7d494
	GtkCheckButton *enable_word_provider;
Packit a7d494
	GtkCheckButton *enable_fixed_provider;
Packit a7d494
	GtkCheckButton *enable_random_provider;
Packit a7d494
	GtkSpinButton *nb_fixed_proposals;
Packit a7d494
	GtkSpinButton *nb_random_proposals;
Packit a7d494
Packit a7d494
	builder = gtk_builder_new ();
Packit a7d494
Packit a7d494
	gtk_builder_add_from_resource (builder,
Packit a7d494
				       "/org/gnome/gtksourceview/tests/ui/test-completion.ui",
Packit a7d494
				       &error);
Packit a7d494
Packit a7d494
	if (error != NULL)
Packit a7d494
	{
Packit a7d494
		g_error ("Impossible to load test-completion.ui: %s", error->message);
Packit a7d494
	}
Packit a7d494
Packit a7d494
	window = GTK_WINDOW (gtk_builder_get_object (builder, "window"));
Packit a7d494
	source_view = GTK_SOURCE_VIEW (gtk_builder_get_object (builder, "source_view"));
Packit a7d494
	remember_info_visibility = GTK_CHECK_BUTTON (gtk_builder_get_object (builder, "checkbutton_remember_info_visibility"));
Packit a7d494
	select_on_show = GTK_CHECK_BUTTON (gtk_builder_get_object (builder, "checkbutton_select_on_show"));
Packit a7d494
	show_headers = GTK_CHECK_BUTTON (gtk_builder_get_object (builder, "checkbutton_show_headers"));
Packit a7d494
	show_icons = GTK_CHECK_BUTTON (gtk_builder_get_object (builder, "checkbutton_show_icons"));
Packit a7d494
	enable_word_provider = GTK_CHECK_BUTTON (gtk_builder_get_object (builder, "checkbutton_word_provider"));
Packit a7d494
	enable_fixed_provider = GTK_CHECK_BUTTON (gtk_builder_get_object (builder, "checkbutton_fixed_provider"));
Packit a7d494
	enable_random_provider = GTK_CHECK_BUTTON (gtk_builder_get_object (builder, "checkbutton_random_provider"));
Packit a7d494
	nb_fixed_proposals = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "spinbutton_nb_fixed_proposals"));
Packit a7d494
	nb_random_proposals = GTK_SPIN_BUTTON (gtk_builder_get_object (builder, "spinbutton_nb_random_proposals"));
Packit a7d494
Packit a7d494
	completion = gtk_source_view_get_completion (source_view);
Packit a7d494
Packit a7d494
	g_signal_connect (window,
Packit a7d494
			  "destroy",
Packit a7d494
			  G_CALLBACK (gtk_main_quit),
Packit a7d494
			  NULL);
Packit a7d494
Packit a7d494
	g_object_bind_property (completion, "remember-info-visibility",
Packit a7d494
				remember_info_visibility, "active",
Packit a7d494
				G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
Packit a7d494
Packit a7d494
	g_object_bind_property (completion, "select-on-show",
Packit a7d494
				select_on_show, "active",
Packit a7d494
				G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
Packit a7d494
Packit a7d494
	g_object_bind_property (completion, "show-headers",
Packit a7d494
				show_headers, "active",
Packit a7d494
				G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
Packit a7d494
Packit a7d494
	g_object_bind_property (completion, "show-icons",
Packit a7d494
				show_icons, "active",
Packit a7d494
				G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL);
Packit a7d494
Packit a7d494
	create_completion (source_view, completion);
Packit a7d494
Packit a7d494
	g_signal_connect (enable_word_provider,
Packit a7d494
			  "toggled",
Packit a7d494
			  G_CALLBACK (enable_word_provider_toggled_cb),
Packit a7d494
			  completion);
Packit a7d494
Packit a7d494
	g_signal_connect (enable_fixed_provider,
Packit a7d494
			  "toggled",
Packit a7d494
			  G_CALLBACK (enable_fixed_provider_toggled_cb),
Packit a7d494
			  completion);
Packit a7d494
Packit a7d494
	g_signal_connect (enable_random_provider,
Packit a7d494
			  "toggled",
Packit a7d494
			  G_CALLBACK (enable_random_provider_toggled_cb),
Packit a7d494
			  completion);
Packit a7d494
Packit a7d494
	g_signal_connect (nb_fixed_proposals,
Packit a7d494
			  "value-changed",
Packit a7d494
			  G_CALLBACK (nb_proposals_changed_cb),
Packit a7d494
			  fixed_provider);
Packit a7d494
Packit a7d494
	g_signal_connect (nb_random_proposals,
Packit a7d494
			  "value-changed",
Packit a7d494
			  G_CALLBACK (nb_proposals_changed_cb),
Packit a7d494
			  random_provider);
Packit a7d494
Packit a7d494
	g_object_unref (builder);
Packit a7d494
}
Packit a7d494
Packit a7d494
int
Packit a7d494
main (int argc, char *argv[])
Packit a7d494
{
Packit a7d494
	gtk_init (&argc, &argv);
Packit a7d494
Packit a7d494
	create_window ();
Packit a7d494
Packit a7d494
	gtk_main ();
Packit a7d494
Packit a7d494
	/* Not really useful, except for debugging memory leaks. */
Packit a7d494
	g_object_unref (word_provider);
Packit a7d494
	g_object_unref (fixed_provider);
Packit a7d494
	g_object_unref (random_provider);
Packit a7d494
Packit a7d494
	return 0;
Packit a7d494
}