[glade/wip/xjuan/abstract-classes] GladeWidget: add support for abstract classes



commit 90703ee1cffa2f4ec9a4a237f963fb05e340241d
Author: Juan Pablo Ugarte <juanpablougarte gmail com>
Date:   Wed Aug 1 17:06:48 2018 -0300

    GladeWidget: add support for abstract classes
    
    In order to support templates with abstract parents glade_widget_read()
    will use a class with the GladeInstantiable prefix. So for a GtkBin
    template it  will use GladeInstantiableGtkBin which of course has to
    derive from GtkBin.
    
    In turn glade_widget_write() will ommit GladeInstantiable prefix.

 gladeui/glade-editor-table.c | 40 ++++++++++++++++++++++-----------------
 gladeui/glade-private.h      |  2 ++
 gladeui/glade-widget.c       | 45 ++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 66 insertions(+), 21 deletions(-)
---
diff --git a/gladeui/glade-editor-table.c b/gladeui/glade-editor-table.c
index b9f56b06..1a58f166 100644
--- a/gladeui/glade-editor-table.c
+++ b/gladeui/glade-editor-table.c
@@ -22,6 +22,7 @@
 #include <config.h>
 #include <glib/gi18n-lib.h>
 #include "glade.h"
+#include "glade-private.h"
 #include "gladeui-enum-types.h"
 
 #include "glade-editor-table.h"
@@ -337,7 +338,7 @@ glade_editor_table_load (GladeEditable *editable, GladeWidget *widget)
       table->priv->adaptor = glade_widget_get_adaptor (widget);
 
       if (table->priv->type == GLADE_PAGE_GENERAL)
-       append_name_field (table);
+        append_name_field (table);
 
       append_items (table, table->priv->adaptor, table->priv->type);
     }
@@ -377,26 +378,31 @@ glade_editor_table_load (GladeEditable *editable, GladeWidget *widget)
                          (GWeakNotify) widget_finalized, table);
 
       if (table->priv->composite_check)
-       {
-         GObject *object = glade_widget_get_object (table->priv->loaded_widget);
-
-         if (GTK_IS_WIDGET (object) && 
-             glade_widget_get_parent (table->priv->loaded_widget) == NULL)
-           gtk_widget_show (table->priv->composite_check);
-         else
-           gtk_widget_hide (table->priv->composite_check);
-       }
+        {
+          GObject *object = glade_widget_get_object (table->priv->loaded_widget);
+          GladeWidgetAdaptor *adaptor = glade_widget_get_adaptor (table->priv->loaded_widget);
+
+          if (GTK_IS_WIDGET (object) &&
+              glade_widget_get_parent (table->priv->loaded_widget) == NULL)
+            gtk_widget_show (table->priv->composite_check);
+          else
+            gtk_widget_hide (table->priv->composite_check);
+
+          gtk_widget_set_sensitive (table->priv->composite_check,
+                                    !g_str_has_prefix (glade_widget_adaptor_get_name (adaptor),
+                                                       GLADE_WIDGET_INSTANTIABLE_PREFIX));
+        }
 
       if (table->priv->name_entry)
-       {
-         if (glade_widget_has_name (widget))
-           gtk_entry_set_text (GTK_ENTRY (table->priv->name_entry), glade_widget_get_name (widget));
-         else
-           gtk_entry_set_text (GTK_ENTRY (table->priv->name_entry), "");
-       }
+        {
+          if (glade_widget_has_name (widget))
+            gtk_entry_set_text (GTK_ENTRY (table->priv->name_entry), glade_widget_get_name (widget));
+          else
+            gtk_entry_set_text (GTK_ENTRY (table->priv->name_entry), "");
+        }
 
       if (table->priv->name_label)
-       widget_composite_changed (widget, NULL, table);
+        widget_composite_changed (widget, NULL, table);
     }
   else if (table->priv->name_entry)
     gtk_entry_set_text (GTK_ENTRY (table->priv->name_entry), "");
diff --git a/gladeui/glade-private.h b/gladeui/glade-private.h
index d567a8cd..23af7871 100644
--- a/gladeui/glade-private.h
+++ b/gladeui/glade-private.h
@@ -33,6 +33,8 @@
 
 G_BEGIN_DECLS
 
+#define GLADE_WIDGET_INSTANTIABLE_PREFIX "GladeInstantiable"
+
 /* glade-widget.c */
 
 GList *_glade_widget_peek_prop_refs (GladeWidget *widget);
diff --git a/gladeui/glade-widget.c b/gladeui/glade-widget.c
index b9149d24..330f34f7 100644
--- a/gladeui/glade-widget.c
+++ b/gladeui/glade-widget.c
@@ -946,6 +946,10 @@ glade_widget_constructor (GType                  type,
   /* Verify support warnings to start off */
   glade_widget_verify (gwidget);
 
+  if (g_str_has_prefix (glade_widget_adaptor_get_name (gwidget->priv->adaptor),
+                        GLADE_WIDGET_INSTANTIABLE_PREFIX))
+    glade_widget_set_is_composite (gwidget, TRUE);
+
   return ret_obj;
 }
 
@@ -4008,6 +4012,13 @@ glade_widget_read_child (GladeWidget *widget, GladeXmlNode *node)
  * @parent: The parent #GladeWidget or %NULL
  * @node: a #GladeXmlNode
  *
+ * Creates a new #GladeWidget from a XML node.
+ *
+ * If node is a template and its parent class is abstract/non instantiable,
+ * Glade will use a class with the GladeInstantiable prefix instead.
+ *
+ * For example, with a GtkBin template Glade will GladeInstantiableGtkBin class
+ *
  * Returns: a new #GladeWidget for @project, based on @node
  */
 GladeWidget *
@@ -4060,6 +4071,26 @@ glade_widget_read (GladeProject *project,
            g_warning ("Loaded widget `%s' has internal glade prefix, please rename this widget", id);
        }
 
+      if (template_parent)
+        {
+          GType template_type = glade_util_get_type_from_name (template_parent, FALSE);
+
+          /* Check if there is an instantiable version for this abstract class */
+          if (G_TYPE_IS_ABSTRACT (template_type))
+            {
+              gchar *instantiable = g_strconcat (GLADE_WIDGET_INSTANTIABLE_PREFIX,
+                                                 template_parent,
+                                                 NULL);
+              if (glade_util_get_type_from_name (instantiable, FALSE))
+                {
+                  g_free (template_parent);
+                  template_parent = instantiable;
+                }
+              else
+                g_free (instantiable);
+            }
+        }
+
       type_to_use = template_parent ? template_parent : klass;
 
       /* 
@@ -4325,13 +4356,19 @@ glade_widget_write (GladeWidget     *widget,
   /* Set class and id */
   if (widget->priv->composite)
     {
+      const gchar *parent = glade_widget_adaptor_get_name (widget->priv->adaptor);
+
       widget_node = glade_xml_node_new (context, GLADE_XML_TAG_TEMPLATE);
       glade_xml_node_set_property_string (widget_node,
-                                         GLADE_XML_TAG_CLASS,
-                                         widget->priv->name);
+                                          GLADE_XML_TAG_CLASS,
+                                          widget->priv->name);
+
+      if (g_str_has_prefix (parent, GLADE_WIDGET_INSTANTIABLE_PREFIX))
+        parent += strlen (GLADE_WIDGET_INSTANTIABLE_PREFIX);
+
       glade_xml_node_set_property_string (widget_node,
-                                         GLADE_TAG_PARENT,
-                                         glade_widget_adaptor_get_name (widget->priv->adaptor));
+                                          GLADE_TAG_PARENT,
+                                          parent);
     }
   else
     {


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