GitLab repository storage has been migrated to hashed layout. Please contact Infrastructure team if you notice any issues with repositories or hooks.

Commit 363fd783 authored by Juan Pablo Ugarte's avatar Juan Pablo Ugarte Committed by Juan Pablo Ugarte

Add initial implementation of Automatic Templates

parent 2ddc72f7
......@@ -167,6 +167,13 @@ LIBS=$GTK_LIBS
AC_CHECK_FUNCS(gtk_print_unix_dialog_new,[have_unix_print=yes]; break,[have_unix_print=no])
AM_CONDITIONAL(HAVE_GTK_UNIX_PRINT, test x"$have_unix_print" = "xyes")
dnl ================================================================
dnl Check for _gtk_widget_class_template_unset_only_for_glade() in gtk+
dnl ================================================================
LIBS=$GTK_LIBS
AC_CHECK_FUNCS(_gtk_widget_class_template_unset_only_for_glade,[have_template_unset=yes]; break,[have_template_unset=no])
AM_CONDITIONAL(HAVE_GTK_TEMPLATE_UNSET, test x"$have_template_unset" = "xyes")
dnl ================================================================
dnl Python for optional python dev libs
dnl ================================================================
......
......@@ -125,6 +125,7 @@ libgladeui_2_la_SOURCES = \
glade-signal-class.c \
glade-signal-editor.c \
glade-signal-model.c \
glade-template.c \
glade-tsort.c \
glade-utils.c \
glade-widget.c \
......
......@@ -45,6 +45,8 @@ struct _GladeCatalog
gchar *name; /* Symbolic catalog name */
gchar *prefix; /* Catalog path prefix */
gchar *dep_catalog; /* Symbolic name of the catalog that
* this catalog depends on */
......@@ -108,6 +110,7 @@ catalog_allocate (void)
catalog->library = NULL;
catalog->name = NULL;
catalog->prefix = NULL;
catalog->dep_catalog = NULL;
catalog->domain = NULL;
catalog->book = NULL;
......@@ -201,6 +204,7 @@ catalog_open (const gchar *filename)
catalog = catalog_allocate ();
catalog->context = context;
catalog->name = name;
catalog->prefix = g_path_get_dirname (filename);
glade_xml_get_property_version (root, GLADE_TAG_VERSION,
&catalog->major_version,
......@@ -726,6 +730,20 @@ glade_catalog_get_name (GladeCatalog *catalog)
return catalog->name;
}
/**
* glade_catalog_get_prefix:
* @catalog: a catalog object
*
* Returns: The catalog path prefix.
*/
G_CONST_RETURN gchar *
glade_catalog_get_prefix (GladeCatalog *catalog)
{
g_return_val_if_fail (GLADE_IS_CATALOG (catalog), NULL);
return catalog->prefix;
}
/**
* glade_catalog_get_book:
* @catalog: a catalog object
......
......@@ -59,6 +59,7 @@ const GList *glade_catalog_get_extra_paths (void);
const GList *glade_catalog_load_all (void);
G_CONST_RETURN gchar *glade_catalog_get_name (GladeCatalog *catalog);
G_CONST_RETURN gchar *glade_catalog_get_prefix (GladeCatalog *catalog);
G_CONST_RETURN gchar *glade_catalog_get_icon_prefix(GladeCatalog *catalog);
G_CONST_RETURN gchar *glade_catalog_get_domain (GladeCatalog *catalog);
G_CONST_RETURN gchar *glade_catalog_get_book (GladeCatalog *catalog);
......
......@@ -94,6 +94,11 @@ gchar *_glade_util_file_get_relative_path (GFile *target,
void _glade_xml_error_reset_last (void);
gchar *_glade_xml_error_get_last_message (void);
/* glade-template.c */
GType _glade_template_generate_type_from_file (GladeCatalog *catalog,
const gchar *parent,
const gchar *filename);
G_END_DECLS
#endif /* __GLADE_PRIVATE_H__ */
/*
* glade-template.c:
*
* Copyright (C) 2017-2018 Juan Pablo Ugarte.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Authors:
* Juan Pablo Ugarte <juanpablougarte@gmail.com>
*/
#include "glade-private.h"
#include "glade-utils.h"
#if HAVE_GTK_TEMPLATE_UNSET
extern void
_gtk_widget_class_template_unset_only_for_glade (GtkWidgetClass *widget_class);
#else
#define _gtk_widget_class_template_unset_only_for_glade(void)
#endif
static GHashTable *templates = NULL;
static void
glade_template_instance_init (GTypeInstance *instance, gpointer g_class)
{
/* Reset class template */
_gtk_widget_class_template_unset_only_for_glade (GTK_WIDGET_GET_CLASS (instance));
gtk_widget_class_set_template (GTK_WIDGET_GET_CLASS (instance),
g_hash_table_lookup (templates,
G_OBJECT_TYPE_NAME (instance)));
/* Regular template initialization*/
gtk_widget_init_template ((GtkWidget *)instance);
}
typedef struct {
gchar *class;
gchar *parent;
} ParserData;
static void
start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error)
{
ParserData *data = user_data;
gint i;
if (!g_str_equal (element_name, "template"))
return;
for (i = 0; attribute_names[i]; i++)
if (g_str_equal (attribute_names[i], "class"))
data->class = g_strdup (attribute_values[i]);
else if (g_str_equal (attribute_names[i], "parent"))
data->parent = g_strdup (attribute_values[i]);
}
GType
_glade_template_generate_type_from_file (GladeCatalog *catalog,
const gchar *name,
const gchar *filename)
{
GMarkupParser parser = { start_element, NULL, };
GMarkupParseContext *context;
ParserData data = { 0, };
GType parent_type;
GTypeQuery query;
GTypeInfo *info;
gchar *template = NULL;
gsize len = 0;
GError *error = NULL;
g_return_val_if_fail (name != NULL, 0);
g_return_val_if_fail (filename != NULL, 0);
if (g_path_is_absolute (filename))
g_file_get_contents (filename, &template, &len, &error);
else
{
gchar *fullpath = g_build_filename (glade_catalog_get_prefix (catalog),
filename, NULL);
g_file_get_contents (fullpath, &template, &len, &error);
g_free (fullpath);
}
if (error)
{
g_warning ("Error loading template file %s for %s class - %s", filename, name, error->message);
return G_TYPE_INVALID;
}
context = g_markup_parse_context_new (&parser, 0, &data, NULL);
g_markup_parse_context_parse (context, template, -1, NULL);
g_markup_parse_context_end_parse (context, NULL);
if (!g_str_equal (name, data.class))
{
g_warning ("Template %s is for class %s, not %s", filename, data.class, name);
return G_TYPE_INVALID;
}
parent_type = glade_util_get_type_from_name (data.parent, FALSE);
g_return_val_if_fail (parent_type != 0, 0);
g_type_query (parent_type, &query);
g_return_val_if_fail (query.type != 0, 0);
if (g_once_init_enter (&templates))
{
GHashTable *table = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) g_bytes_unref);
g_once_init_leave (&templates, table);
}
/* Add template to global hash table */
g_hash_table_insert (templates, g_strdup (name), g_bytes_new_take (template, len));
info = g_new0 (GTypeInfo, 1);
info->class_size = query.class_size;
info->instance_size = query.instance_size;
info->instance_init = glade_template_instance_init;
g_free (data.class);
g_free (data.parent);
return g_type_register_static (parent_type, name, info, 0);
}
......@@ -2694,7 +2694,7 @@ glade_widget_adaptor_from_catalog (GladeCatalog *catalog,
{
GladeWidgetAdaptor *adaptor = NULL;
gchar *name, *generic_name, *icon_name, *adaptor_icon_name, *adaptor_name,
*func_name;
*func_name, *template;
gchar *title, *translated_title, *parent_name;
GType object_type, adaptor_type, parent_type;
gchar *missing_icon = NULL;
......@@ -2716,6 +2716,7 @@ glade_widget_adaptor_from_catalog (GladeCatalog *catalog,
* - Autosubclassing a specified parent type (a fake widget class)
* - parsing the _get_type() function directly from the catalog
* - deriving foo_bar_get_type() from the name FooBar and loading that.
* - setting a template ui definition
*/
if ((parent_name =
glade_xml_get_property_string (class_node, GLADE_TAG_PARENT)) != NULL)
......@@ -2739,6 +2740,13 @@ glade_widget_adaptor_from_catalog (GladeCatalog *catalog,
object_type = glade_util_get_type_from_name (func_name, TRUE);
g_free (func_name);
}
else if ((template =
glade_xml_get_property_string (class_node,
GLADE_XML_TAG_TEMPLATE)) != NULL)
{
object_type = _glade_template_generate_type_from_file (catalog, name, template);
g_free (template);
}
else
{
GType type_iter;
......
......@@ -185,6 +185,7 @@ typedef struct _GladeProject GladeProject;
#define GLADE_TAG_ICON_NAME "icon-name"
#define GLADE_TAG_IMPORTANT "important"
#define GLADE_TAG_CREATE_TYPE "create-type"
#define GLADE_TAG_TEMPLATE_PREFIX "template-prefix"
/* search child */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment