restrict child-properties to widgets for which child_property_applies

2004-02-28  Joaquin Cuenca Abela  <e98cuenc@yahoo.com>

	* src/glade-editor.c: restrict child-properties to widgets for which
	child_property_applies returns TRUE, not only direct children.
	* src/glade-gtk.c: implement a child_property_applies for
	GtkDialog.
	* src/glade-widget-class.[ch]: read child_property_applies_function_name
	and customized child-properties under the ChildProperties tag.
	* src/glade-widget.c: restrict child-properties to widgets for which
	child_property_applies returns TRUE, not only direct children.
	* src/glade.h: add the ChildProperties and ChildPropertyApplies tags.
	* widgets/gtkdialog.xml: add a ChildPropertyApplies function, and
	add a new ChildProperty ("response-id").
This commit is contained in:
Joaquin Cuenca Abela 2004-02-28 15:25:13 +00:00 committed by Joaquín Cuenca Abela
parent 0f3b34080b
commit d1677f668a
8 changed files with 212 additions and 58 deletions

View File

@ -1,3 +1,17 @@
2004-02-28 Joaquin Cuenca Abela <e98cuenc@yahoo.com>
* src/glade-editor.c: restrict child-properties to widgets for which
child_property_applies returns TRUE, not only direct children.
* src/glade-gtk.c: implement a child_property_applies for
GtkDialog.
* src/glade-widget-class.[ch]: read child_property_applies_function_name
and customized child-properties under the ChildProperties tag.
* src/glade-widget.c: restrict child-properties to widgets for which
child_property_applies returns TRUE, not only direct children.
* src/glade.h: add the ChildProperties and ChildPropertyApplies tags.
* widgets/gtkdialog.xml: add a ChildPropertyApplies function, and
add a new ChildProperty ("response-id").
2004-02-12 Paolo Borelli <pborelli@katamail.com>
* src/glade-project-window.c: implement open by drag&drop.

View File

@ -1365,6 +1365,7 @@ glade_editor_load_packing_page (GladeEditor *editor, GladeWidget *widget)
GladeEditorTable *table;
GladePropertyClass *property_class;
GladeWidget *parent;
GladeWidget *ancestor;
GtkContainer *container;
GList *list;
@ -1400,13 +1401,19 @@ glade_editor_load_packing_page (GladeEditor *editor, GladeWidget *widget)
table->common = FALSE;
table->packing = TRUE;
for (list = parent->class->child_properties; list; list = list->next)
for (ancestor = parent; ancestor != NULL; ancestor = glade_widget_get_parent (ancestor))
{
property_class = list->data;
g_assert (property_class->packing == TRUE);
editor_property = glade_editor_table_append_item (table, property_class);
old_props = g_list_prepend (old_props, editor_property);
glade_editor_property_load (editor_property, widget);
for (list = ancestor->class->child_properties; list; list = list->next)
{
property_class = list->data;
if (!ancestor->class->child_property_applies (ancestor->widget, widget->widget, property_class->id))
continue;
g_assert (property_class->packing == TRUE);
editor_property = glade_editor_table_append_item (table, property_class);
old_props = g_list_prepend (old_props, editor_property);
glade_editor_property_load (editor_property, widget);
}
}
gtk_widget_show_all (table->table_widget);

View File

@ -765,3 +765,22 @@ glade_gtk_dialog_get_internal_child (GtkWidget *dialog,
*child = child_widget;
}
int GLADEGTK_API
glade_gtk_dialog_child_property_applies (GtkWidget *ancestor,
GtkWidget *widget,
const char *property_id)
{
g_return_val_if_fail (GTK_IS_DIALOG (ancestor), FALSE);
if (strcmp(property_id, "response-id") == 0)
{
if (GTK_IS_HBUTTON_BOX (widget->parent) && GTK_IS_VBOX (widget->parent->parent) &&
widget->parent->parent->parent == ancestor)
return TRUE;
}
else if (widget->parent == ancestor)
return TRUE;
return FALSE;
}

View File

@ -190,14 +190,18 @@ glade_widget_class_list_child_properties (GladeWidgetClass *class)
{
spec = specs[i];
property_class = glade_property_class_new_from_spec (spec);
if (!property_class)
continue;
/* We only use the writable properties */
if (spec->flags & G_PARAM_WRITABLE)
{
property_class = glade_property_class_new_from_spec (spec);
if (!property_class)
continue;
property_class->optional = FALSE;
property_class->packing = TRUE;
property_class->optional = FALSE;
property_class->packing = TRUE;
list = g_list_prepend (list, property_class);
list = g_list_prepend (list, property_class);
}
}
list = g_list_reverse (list);
@ -258,10 +262,11 @@ glade_widget_class_create_icon (GladeWidgetClass *class)
static void
glade_widget_class_update_properties_from_node (GladeXmlNode *node,
GladeWidgetClass *widget_class)
GladeWidgetClass *widget_class,
GList **pproperties)
{
GladeXmlNode *child;
GList *properties = widget_class->properties;
GList *properties = *pproperties;
child = glade_xml_node_get_children (node);
for (; child; child = glade_xml_node_next (child))
@ -311,6 +316,8 @@ glade_widget_class_update_properties_from_node (GladeXmlNode *node,
g_free (id);
}
*pproperties = properties;
}
/**
@ -334,6 +341,8 @@ glade_widget_class_extend_with_file (GladeWidgetClass *widget_class, const char
char *post_create_function_name;
char *fill_empty_function_name;
char *get_internal_child_function_name;
char *child_property_applies_function_name;
GList *tmp;
g_return_val_if_fail (filename != NULL, FALSE);
@ -378,12 +387,33 @@ glade_widget_class_extend_with_file (GladeWidgetClass *widget_class, const char
}
g_free (get_internal_child_function_name);
child_property_applies_function_name = glade_xml_get_value_string (node, GLADE_TAG_CHILD_PROPERTY_APPLIES_FUNCTION);
if (child_property_applies_function_name && widget_class->module)
{
if (!g_module_symbol (widget_class->module, child_property_applies_function_name, (void **) &widget_class->child_property_applies))
g_warning ("Could not find %s\n", child_property_applies_function_name);
}
g_free (child_property_applies_function_name);
/* if we found a <properties> tag on the xml file, we add the properties
* that we read from the xml file to the class.
*/
properties = glade_xml_search_child (node, GLADE_TAG_PROPERTIES);
if (properties)
glade_widget_class_update_properties_from_node (properties, widget_class);
glade_widget_class_update_properties_from_node (properties, widget_class, &widget_class->properties);
/* if we found a <ChildProperties> tag on the xml file, we add the properties
* that we read from the xml file to the class.
*/
properties = glade_xml_search_child (node, GLADE_TAG_CHILD_PROPERTIES);
if (properties)
glade_widget_class_update_properties_from_node (properties, widget_class, &widget_class->child_properties);
for (tmp = widget_class->child_properties; tmp != NULL; tmp = tmp->next)
{
GladePropertyClass *property_class = tmp->data;
property_class->packing = TRUE;
}
return TRUE;
}
@ -408,6 +438,52 @@ glade_widget_class_get_by_name (const char *name)
return NULL;
}
/**
* glade_widget_class_merge_properties:
* @widget_properties: Pointer to the list of properties in the widget.
* @parent_class: List of properties in the parent.
*
* Merges the properties found in the parent_properties list with the
* properties found in the widget_properties list.
* The properties in the parent_properties will be prepended to widget_properties.
**/
static void
glade_widget_class_merge_properties (GList **widget_properties, GList *parent_properties)
{
GList *list;
GList *list2;
for (list = parent_properties; list; list = list->next)
{
GladePropertyClass *parent_p_class = list->data;
GladePropertyClass *child_p_class;
/* search the child's properties for one with the same id */
for (list2 = *widget_properties; list2; list2 = list2->next)
{
child_p_class = list2->data;
if (strcmp (parent_p_class->id, child_p_class->id) == 0)
break;
}
/* if not found, prepend a clone of the parent's one; if found
* but the parent one was modified substitute it.
*/
if (!list2)
{
GladePropertyClass *property_class;
property_class = glade_property_class_clone (parent_p_class);
*widget_properties = g_list_prepend (*widget_properties, property_class);
}
else if (parent_p_class->is_modified)
{
glade_property_class_free (child_p_class);
list2->data = glade_property_class_clone (parent_p_class);
}
}
}
/**
* glade_widget_class_merge:
* @widget_class: main class.
@ -421,9 +497,6 @@ static void
glade_widget_class_merge (GladeWidgetClass *widget_class,
GladeWidgetClass *parent_class)
{
GList *list;
GList *list2;
g_return_if_fail (GLADE_IS_WIDGET_CLASS (widget_class));
g_return_if_fail (GLADE_IS_WIDGET_CLASS (parent_class));
@ -439,36 +512,12 @@ glade_widget_class_merge (GladeWidgetClass *widget_class,
if (widget_class->fill_empty == NULL)
widget_class->fill_empty = parent_class->fill_empty;
/* merge the parent's properties */
for (list = parent_class->properties; list; list = list->next)
{
GladePropertyClass *parent_p_class = list->data;
GladePropertyClass *child_p_class;
if (widget_class->child_property_applies == NULL)
widget_class->child_property_applies = parent_class->child_property_applies;
/* search the child's properties for one with the same id */
for (list2 = widget_class->properties; list2; list2 = list2->next)
{
child_p_class = list2->data;
if (strcmp (parent_p_class->id, child_p_class->id) == 0)
break;
}
/* if not found, prepend a clone of the parent's one; if found
* but the parent one was modified substitute it.
*/
if (!list2)
{
GladePropertyClass *property_class;
property_class = glade_property_class_clone (parent_p_class);
widget_class->properties = g_list_prepend (widget_class->properties, property_class);
}
else if (parent_p_class->is_modified)
{
glade_property_class_free (child_p_class);
list2->data = glade_property_class_clone (parent_p_class);
}
}
/* merge the parent's properties & child-properties */
glade_widget_class_merge_properties (&widget_class->properties, parent_class->properties);
glade_widget_class_merge_properties (&widget_class->child_properties, parent_class->child_properties);
}
/**
@ -520,6 +569,15 @@ glade_widget_class_load_library (const gchar *library_name)
return module;
}
static gboolean
glade_widget_class_direct_children (GtkWidget *ancestor, GtkWidget *widget, const char *property_id)
{
if (ancestor != NULL && widget->parent == ancestor)
return TRUE;
return FALSE;
}
/**
* glade_widget_class_new:
* @name: name of the widget class (for instance: GtkButton)
@ -601,6 +659,7 @@ glade_widget_class_new (const char *name,
widget_class->properties = glade_widget_class_list_properties (widget_class);
widget_class->child_properties = glade_widget_class_list_child_properties (widget_class);
widget_class->signals = glade_widget_class_list_signals (widget_class);
widget_class->child_property_applies = glade_widget_class_direct_children;
/* is the widget a toplevel? TODO: We're going away from this flag, and
* just doing this test each time that we want to know if it's a toplevel */

View File

@ -101,6 +101,12 @@ struct _GladeWidgetClass
void (*get_internal_child) (GtkWidget *parent,
const gchar *name,
GtkWidget **child);
/* Is property_class of ancestor applicable to the widget? Usually property_class only
* applies to direct children of a given ancestor */
gboolean (*child_property_applies) (GtkWidget *ancestor,
GtkWidget *widget,
const char *property_id);
};

View File

@ -54,7 +54,7 @@ glade_widget_new_name (GladeProject *project, GladeWidgetClass *class)
return glade_project_new_widget_name (project, class->generic_name);
}
/**
/**
* Returns a list of GladeProperties from a list of
* GladePropertyClass.
*/
@ -65,7 +65,8 @@ glade_widget_properties_from_list (GList *list, GladeWidget *widget)
GladeProperty *property;
GList *new_list = NULL;
for (; list; list = list->next) {
for (; list; list = list->next)
{
property_class = list->data;
property = glade_property_new (property_class, widget);
if (!property)
@ -79,6 +80,44 @@ glade_widget_properties_from_list (GList *list, GladeWidget *widget)
return new_list;
}
/**
* Returns a list of GladeProperties from a list of
* GladePropertyClass.
*/
static GList *
glade_widget_create_packing_properties (GladeWidget *container, GladeWidget *widget)
{
GladePropertyClass *property_class;
GladeProperty *property;
GList *list = container->class->child_properties;
GList *new_list = NULL;
GList *ancestor_list;
for (; list; list = list->next)
{
property_class = list->data;
if (!container->class->child_property_applies (container->widget, widget->widget, property_class->id))
continue;
property = glade_property_new (property_class, widget);
if (!property)
continue;
new_list = g_list_prepend (new_list, property);
}
new_list = g_list_reverse (new_list);
if (container->widget->parent != NULL)
{
ancestor_list = glade_widget_create_packing_properties (glade_widget_get_from_gtk_widget (container->widget->parent),
widget);
new_list = g_list_concat (new_list, ancestor_list);
}
return new_list;
}
static void
glade_widget_free_signals (gpointer value)
{
@ -541,7 +580,7 @@ glade_widget_set_packing_properties (GladeWidget *widget,
g_list_foreach(widget->packing_properties, (GFunc) glade_property_free, NULL);
g_list_free (widget->packing_properties);
widget->packing_properties = glade_widget_properties_from_list (container->class->child_properties, widget);
widget->packing_properties = glade_widget_create_packing_properties (container, widget);
/* update the values of the properties to the ones we get from gtk */
for (list = widget->packing_properties; list; list = list->next)
@ -549,10 +588,11 @@ glade_widget_set_packing_properties (GladeWidget *widget,
GladeProperty *property = list->data;
g_value_reset (property->value);
gtk_container_child_get_property (GTK_CONTAINER (container->widget),
widget->widget,
property->class->id,
property->value);
if (gtk_container_class_find_child_property (G_OBJECT_GET_CLASS (container->widget), property->class->id))
gtk_container_child_get_property (GTK_CONTAINER (container->widget),
widget->widget,
property->class->id,
property->value);
}
}
@ -1395,7 +1435,7 @@ glade_widget_new_from_node_real (GladeXmlNode *node,
/* create the packing_properties list, without setting them */
if (parent)
widget->packing_properties = glade_widget_properties_from_list (parent->class->child_properties, widget);
widget->packing_properties = glade_widget_create_packing_properties (parent, widget);
glade_widget_fill_from_node (node, widget);

View File

@ -51,7 +51,7 @@
#define GLADE_TAG_PLACEHOLDER "Placeholder"
#define GLADE_TAG_ICON "Icon"
#define GLADE_TAG_PROPERTIES "Properties"
#define GLADE_TAG_PACKING_PROPERTIES "PackingProperties"
#define GLADE_TAG_CHILD_PROPERTIES "ChildProperties"
#define GLADE_TAG_CONTAINER "Container"
#define GLADE_TAG_PROPERTY "Property"
#define GLADE_TAG_COMMON "Common"
@ -97,6 +97,7 @@
#define GLADE_TAG_CATALOG "GladeCatalog"
#define GLADE_TAG_GLADE_WIDGET "GladeWidget"
#define GLADE_TAG_CHILD_PROPERTY_APPLIES_FUNCTION "ChildPropertyApplies"
#define GLADE_WIDGET_DATA_TAG "GladeWidgetDataTag"

View File

@ -3,9 +3,9 @@
<PostCreateFunction>glade_gtk_dialog_post_create</PostCreateFunction>
<FillEmptyFunction>glade_gtk_dialog_fill_empty</FillEmptyFunction>
<GetInternalChildFunction>glade_gtk_dialog_get_internal_child</GetInternalChildFunction>
<ChildPropertyApplies>glade_gtk_dialog_child_property_applies</ChildPropertyApplies>
<Properties>
<Property Id="modal">
<SetFunction>ignore</SetFunction>
</Property>
@ -16,7 +16,15 @@
<SetFunction>ignore</SetFunction>
<GetFunction>ignore</GetFunction>
</Property>
</Properties>
<ChildProperties>
<Property Id="response-id" Name="Response ID" Default="0" Common="False">
<Type>Integer</Type>
<Tooltip>The response ID of this button in the dialog</Tooltip>
<SetFunction>ignore</SetFunction>
<GetFunction>ignore</GetFunction>
</Property>
</ChildProperties>
</GladeWidgetClass>