Blame gtksourceview/gtksourcestyleschemechooserwidget.c

Packit a7d494
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*-
Packit a7d494
 *
Packit a7d494
 * This file is part of GtkSourceView
Packit a7d494
 *
Packit a7d494
 * Copyright (C) 2014 - Christian Hergert
Packit a7d494
 * Copyright (C) 2014 - Ignacio Casal Quinteiro
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 License
Packit a7d494
 * along with GtkSourceView. If not, see <http://www.gnu.org/licenses/>.
Packit a7d494
 */
Packit a7d494
Packit a7d494
#ifdef HAVE_CONFIG_H
Packit a7d494
#include <config.h>
Packit a7d494
#endif
Packit a7d494
Packit a7d494
#include "gtksourcestyleschemechooserwidget.h"
Packit a7d494
#include "gtksourcestyleschemechooser.h"
Packit a7d494
#include "gtksourcestylescheme.h"
Packit a7d494
#include "gtksourcestyleschememanager.h"
Packit a7d494
#include "gtksourcelanguage.h"
Packit a7d494
#include "gtksourcelanguagemanager.h"
Packit a7d494
#include "gtksourcebuffer.h"
Packit a7d494
#include "gtksourceview.h"
Packit a7d494
Packit a7d494
/**
Packit a7d494
 * SECTION:styleschemechooserwidget
Packit a7d494
 * @Short_description: A widget for choosing style schemes
Packit a7d494
 * @Title: GtkSourceStyleSchemeChooserWidget
Packit a7d494
 * @See_also: #GtkSourceStyleSchemeChooserButton
Packit a7d494
 *
Packit a7d494
 * The #GtkSourceStyleSchemeChooserWidget widget lets the user select a
Packit a7d494
 * style scheme. By default, the chooser presents a predefined list
Packit a7d494
 * of style schemes.
Packit a7d494
 *
Packit a7d494
 * To change the initially selected style scheme,
Packit a7d494
 * use gtk_source_style_scheme_chooser_set_style_scheme().
Packit a7d494
 * To get the selected style scheme
Packit a7d494
 * use gtk_source_style_scheme_chooser_get_style_scheme().
Packit a7d494
 *
Packit a7d494
 * Since: 3.16
Packit a7d494
 */
Packit a7d494
Packit a7d494
typedef struct
Packit a7d494
{
Packit a7d494
	GtkListBox *list_box;
Packit a7d494
	GtkSourceStyleScheme *scheme;
Packit a7d494
} GtkSourceStyleSchemeChooserWidgetPrivate;
Packit a7d494
Packit a7d494
static void gtk_source_style_scheme_chooser_widget_style_scheme_chooser_interface_init (GtkSourceStyleSchemeChooserInterface *iface);
Packit a7d494
Packit a7d494
G_DEFINE_TYPE_WITH_CODE (GtkSourceStyleSchemeChooserWidget,
Packit a7d494
                         gtk_source_style_scheme_chooser_widget,
Packit a7d494
                         GTK_TYPE_BIN,
Packit a7d494
                         G_ADD_PRIVATE (GtkSourceStyleSchemeChooserWidget)
Packit a7d494
                         G_IMPLEMENT_INTERFACE (GTK_SOURCE_TYPE_STYLE_SCHEME_CHOOSER,
Packit a7d494
                                                gtk_source_style_scheme_chooser_widget_style_scheme_chooser_interface_init))
Packit a7d494
Packit a7d494
#define GET_PRIV(o) gtk_source_style_scheme_chooser_widget_get_instance_private (o)
Packit a7d494
Packit a7d494
enum
Packit a7d494
{
Packit a7d494
	PROP_0,
Packit a7d494
	PROP_STYLE_SCHEME
Packit a7d494
};
Packit a7d494
Packit a7d494
static void
Packit a7d494
gtk_source_style_scheme_chooser_widget_dispose (GObject *object)
Packit a7d494
{
Packit a7d494
	GtkSourceStyleSchemeChooserWidget *widget = GTK_SOURCE_STYLE_SCHEME_CHOOSER_WIDGET (object);
Packit a7d494
	GtkSourceStyleSchemeChooserWidgetPrivate *priv = GET_PRIV (widget);
Packit a7d494
Packit a7d494
	g_clear_object (&priv->scheme);
Packit a7d494
Packit a7d494
	G_OBJECT_CLASS (gtk_source_style_scheme_chooser_widget_parent_class)->dispose (object);
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
gtk_source_style_scheme_chooser_widget_get_property (GObject    *object,
Packit a7d494
                                                     guint       prop_id,
Packit a7d494
                                                     GValue     *value,
Packit a7d494
                                                     GParamSpec *pspec)
Packit a7d494
{
Packit a7d494
	switch (prop_id)
Packit a7d494
	{
Packit a7d494
		case PROP_STYLE_SCHEME:
Packit a7d494
			g_value_set_object (value,
Packit a7d494
			                    gtk_source_style_scheme_chooser_get_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (object)));
Packit a7d494
			break;
Packit a7d494
Packit a7d494
		default:
Packit a7d494
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit a7d494
	}
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
gtk_source_style_scheme_chooser_widget_set_property (GObject      *object,
Packit a7d494
                                                     guint         prop_id,
Packit a7d494
                                                     const GValue *value,
Packit a7d494
                                                     GParamSpec   *pspec)
Packit a7d494
{
Packit a7d494
	switch (prop_id)
Packit a7d494
	{
Packit a7d494
		case PROP_STYLE_SCHEME:
Packit a7d494
			gtk_source_style_scheme_chooser_set_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (object),
Packit a7d494
			                                                  g_value_get_object (value));
Packit a7d494
			break;
Packit a7d494
Packit a7d494
		default:
Packit a7d494
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit a7d494
	}
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
gtk_source_style_scheme_chooser_widget_class_init (GtkSourceStyleSchemeChooserWidgetClass *klass)
Packit a7d494
{
Packit a7d494
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit a7d494
Packit a7d494
	object_class->dispose = gtk_source_style_scheme_chooser_widget_dispose;
Packit a7d494
	object_class->get_property = gtk_source_style_scheme_chooser_widget_get_property;
Packit a7d494
	object_class->set_property = gtk_source_style_scheme_chooser_widget_set_property;
Packit a7d494
Packit a7d494
	g_object_class_override_property (object_class, PROP_STYLE_SCHEME, "style-scheme");
Packit a7d494
}
Packit a7d494
Packit a7d494
static GtkWidget *
Packit a7d494
make_row (GtkSourceStyleScheme *scheme,
Packit a7d494
          GtkSourceLanguage    *language)
Packit a7d494
{
Packit a7d494
	GtkWidget *row;
Packit a7d494
	AtkObject *accessible;
Packit a7d494
	GtkWidget *event;
Packit a7d494
	GtkSourceBuffer *buffer;
Packit a7d494
	GtkWidget *view;
Packit a7d494
	gchar *text;
Packit a7d494
Packit a7d494
	row = gtk_list_box_row_new ();
Packit a7d494
	accessible = gtk_widget_get_accessible (row);
Packit a7d494
	atk_object_set_name (accessible,
Packit a7d494
	                     gtk_source_style_scheme_get_name (scheme));
Packit a7d494
	gtk_widget_show (row);
Packit a7d494
Packit a7d494
	g_object_set_data (G_OBJECT (row), "scheme", scheme);
Packit a7d494
Packit a7d494
	event = gtk_event_box_new ();
Packit a7d494
	gtk_event_box_set_above_child (GTK_EVENT_BOX (event), TRUE);
Packit a7d494
	gtk_widget_show (event);
Packit a7d494
	gtk_container_add (GTK_CONTAINER (row), event);
Packit a7d494
Packit a7d494
	buffer = gtk_source_buffer_new_with_language (language);
Packit a7d494
	gtk_source_buffer_set_highlight_matching_brackets (buffer, FALSE);
Packit a7d494
	gtk_source_buffer_set_style_scheme (buffer, scheme);
Packit a7d494
Packit a7d494
	text = g_strdup_printf ("/* %s */\n#include <gtksourceview/gtksource.h>",
Packit a7d494
	                        gtk_source_style_scheme_get_name (scheme));
Packit a7d494
	gtk_text_buffer_set_text (GTK_TEXT_BUFFER (buffer), text, -1);
Packit a7d494
	g_free (text);
Packit a7d494
Packit a7d494
	view = g_object_new (GTK_SOURCE_TYPE_VIEW,
Packit a7d494
	                     "buffer", buffer,
Packit a7d494
	                     "can-focus", FALSE,
Packit a7d494
	                     "cursor-visible", FALSE,
Packit a7d494
	                     "editable", FALSE,
Packit a7d494
	                     "visible", TRUE,
Packit a7d494
	                     "show-line-numbers", TRUE,
Packit a7d494
	                     "right-margin-position", 30,
Packit a7d494
	                     "show-right-margin", TRUE,
Packit a7d494
	                     "margin", 2,
Packit a7d494
	                     NULL);
Packit a7d494
	gtk_container_add (GTK_CONTAINER (event), view);
Packit a7d494
Packit a7d494
	return row;
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
on_row_selected (GtkListBox                        *list_box,
Packit a7d494
                 GtkListBoxRow                     *row,
Packit a7d494
                 GtkSourceStyleSchemeChooserWidget *widget)
Packit a7d494
{
Packit a7d494
	GtkSourceStyleSchemeChooserWidgetPrivate *priv = GET_PRIV (widget);
Packit a7d494
Packit a7d494
	if (row != NULL)
Packit a7d494
	{
Packit a7d494
		GtkSourceStyleScheme *scheme;
Packit a7d494
Packit a7d494
		scheme = g_object_get_data (G_OBJECT (row), "scheme");
Packit a7d494
Packit a7d494
		if (g_set_object (&priv->scheme, scheme))
Packit a7d494
		{
Packit a7d494
			g_object_notify (G_OBJECT (widget), "style-scheme");
Packit a7d494
		}
Packit a7d494
	}
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
gtk_source_style_scheme_chooser_widget_populate (GtkSourceStyleSchemeChooserWidget *widget)
Packit a7d494
{
Packit a7d494
	GtkSourceStyleSchemeChooserWidgetPrivate *priv = GET_PRIV (widget);
Packit a7d494
	GtkSourceLanguageManager *lm;
Packit a7d494
	GtkSourceLanguage *lang;
Packit a7d494
	GtkSourceStyleSchemeManager *manager;
Packit a7d494
	const gchar * const *scheme_ids;
Packit a7d494
	guint i;
Packit a7d494
	gboolean row_selected = FALSE;
Packit a7d494
Packit a7d494
	g_signal_handlers_block_by_func (priv->list_box, on_row_selected, widget);
Packit a7d494
Packit a7d494
	gtk_container_foreach (GTK_CONTAINER (priv->list_box),
Packit a7d494
	                       (GtkCallback)gtk_widget_destroy,
Packit a7d494
	                       NULL);
Packit a7d494
Packit a7d494
	manager = gtk_source_style_scheme_manager_get_default ();
Packit a7d494
	scheme_ids = gtk_source_style_scheme_manager_get_scheme_ids (manager);
Packit a7d494
Packit a7d494
	lm = gtk_source_language_manager_get_default ();
Packit a7d494
	lang = gtk_source_language_manager_get_language (lm, "c");
Packit a7d494
Packit a7d494
	for (i = 0; scheme_ids [i]; i++)
Packit a7d494
	{
Packit a7d494
		GtkWidget *row;
Packit a7d494
		GtkSourceStyleScheme *scheme;
Packit a7d494
Packit a7d494
		scheme = gtk_source_style_scheme_manager_get_scheme (manager, scheme_ids [i]);
Packit a7d494
		row = make_row (scheme, lang);
Packit a7d494
		gtk_container_add (GTK_CONTAINER (priv->list_box), GTK_WIDGET (row));
Packit a7d494
Packit a7d494
		if (scheme == priv->scheme)
Packit a7d494
		{
Packit a7d494
			gtk_list_box_select_row (priv->list_box, GTK_LIST_BOX_ROW (row));
Packit a7d494
Packit a7d494
			row_selected = TRUE;
Packit a7d494
		}
Packit a7d494
	}
Packit a7d494
Packit a7d494
	g_signal_handlers_unblock_by_func (priv->list_box, on_row_selected, widget);
Packit a7d494
Packit a7d494
	/* The current scheme may have been removed so select the default one */
Packit a7d494
	if (!row_selected)
Packit a7d494
	{
Packit a7d494
		gtk_source_style_scheme_chooser_set_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (widget),
Packit a7d494
		                                                  _gtk_source_style_scheme_get_default ());
Packit a7d494
	}
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
on_scheme_ids_changed (GtkSourceStyleSchemeManager       *manager,
Packit a7d494
                       GParamSpec                        *pspec,
Packit a7d494
                       GtkSourceStyleSchemeChooserWidget *widget)
Packit a7d494
{
Packit a7d494
	gtk_source_style_scheme_chooser_widget_populate (widget);
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
gtk_source_style_scheme_chooser_widget_init (GtkSourceStyleSchemeChooserWidget *widget)
Packit a7d494
{
Packit a7d494
	GtkSourceStyleSchemeChooserWidgetPrivate *priv = GET_PRIV (widget);
Packit a7d494
	GtkSourceStyleSchemeManager *manager;
Packit a7d494
Packit a7d494
	priv->list_box = GTK_LIST_BOX (gtk_list_box_new ());
Packit a7d494
	gtk_list_box_set_selection_mode (priv->list_box, GTK_SELECTION_BROWSE);
Packit a7d494
	gtk_widget_show (GTK_WIDGET (priv->list_box));
Packit a7d494
	gtk_container_add (GTK_CONTAINER (widget), GTK_WIDGET (priv->list_box));
Packit a7d494
Packit a7d494
	manager = gtk_source_style_scheme_manager_get_default ();
Packit a7d494
	g_signal_connect (manager,
Packit a7d494
	                  "notify::scheme-ids",
Packit a7d494
	                  G_CALLBACK (on_scheme_ids_changed),
Packit a7d494
	                  widget);
Packit a7d494
Packit a7d494
	gtk_source_style_scheme_chooser_widget_populate (widget);
Packit a7d494
Packit a7d494
	gtk_source_style_scheme_chooser_set_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (widget),
Packit a7d494
	                                                  _gtk_source_style_scheme_get_default ());
Packit a7d494
Packit a7d494
	g_signal_connect (priv->list_box,
Packit a7d494
	                  "row-selected",
Packit a7d494
	                  G_CALLBACK (on_row_selected),
Packit a7d494
	                  widget);
Packit a7d494
}
Packit a7d494
Packit a7d494
static GtkSourceStyleScheme *
Packit a7d494
gtk_source_style_scheme_chooser_widget_get_style_scheme (GtkSourceStyleSchemeChooser *chooser)
Packit a7d494
{
Packit a7d494
	GtkSourceStyleSchemeChooserWidget *widget = GTK_SOURCE_STYLE_SCHEME_CHOOSER_WIDGET (chooser);
Packit a7d494
	GtkSourceStyleSchemeChooserWidgetPrivate *priv = GET_PRIV (widget);
Packit a7d494
Packit a7d494
	return priv->scheme;
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
gtk_source_style_scheme_chooser_widget_set_style_scheme (GtkSourceStyleSchemeChooser *chooser,
Packit a7d494
                                                         GtkSourceStyleScheme        *scheme)
Packit a7d494
{
Packit a7d494
	GtkSourceStyleSchemeChooserWidget *widget = GTK_SOURCE_STYLE_SCHEME_CHOOSER_WIDGET (chooser);
Packit a7d494
	GtkSourceStyleSchemeChooserWidgetPrivate *priv = GET_PRIV (widget);
Packit a7d494
Packit a7d494
	if (g_set_object (&priv->scheme, scheme))
Packit a7d494
	{
Packit a7d494
		GList *children;
Packit a7d494
		GList *l;
Packit a7d494
Packit a7d494
		children = gtk_container_get_children (GTK_CONTAINER (priv->list_box));
Packit a7d494
Packit a7d494
		for (l = children; l != NULL; l = g_list_next (l))
Packit a7d494
		{
Packit a7d494
			GtkListBoxRow *row = l->data;
Packit a7d494
			GtkSourceStyleScheme *cur;
Packit a7d494
Packit a7d494
			cur = g_object_get_data (G_OBJECT (row), "scheme");
Packit a7d494
Packit a7d494
			if (cur == scheme)
Packit a7d494
			{
Packit a7d494
				g_signal_handlers_block_by_func (priv->list_box, on_row_selected, widget);
Packit a7d494
				gtk_list_box_select_row (priv->list_box, row);
Packit a7d494
				g_signal_handlers_unblock_by_func (priv->list_box, on_row_selected, widget);
Packit a7d494
				break;
Packit a7d494
			}
Packit a7d494
		}
Packit a7d494
Packit a7d494
		g_list_free (children);
Packit a7d494
Packit a7d494
		g_object_notify (G_OBJECT (chooser), "style-scheme");
Packit a7d494
	}
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
gtk_source_style_scheme_chooser_widget_style_scheme_chooser_interface_init (GtkSourceStyleSchemeChooserInterface *iface)
Packit a7d494
{
Packit a7d494
	iface->get_style_scheme = gtk_source_style_scheme_chooser_widget_get_style_scheme;
Packit a7d494
	iface->set_style_scheme = gtk_source_style_scheme_chooser_widget_set_style_scheme;
Packit a7d494
}
Packit a7d494
Packit a7d494
/**
Packit a7d494
 * gtk_source_style_scheme_chooser_widget_new:
Packit a7d494
 *
Packit a7d494
 * Creates a new #GtkSourceStyleSchemeChooserWidget.
Packit a7d494
 *
Packit a7d494
 * Returns: a new  #GtkSourceStyleSchemeChooserWidget.
Packit a7d494
 *
Packit a7d494
 * Since: 3.16
Packit a7d494
 */
Packit a7d494
GtkWidget *
Packit a7d494
gtk_source_style_scheme_chooser_widget_new (void)
Packit a7d494
{
Packit a7d494
	return g_object_new (GTK_SOURCE_TYPE_STYLE_SCHEME_CHOOSER_WIDGET, NULL);
Packit a7d494
}