gtk+ r19407 - in branches/gtk-2-12: . docs/reference docs/reference/gtk/tmpl gtk tests
- From: johan svn gnome org
- To: svn-commits-list gnome org
- Subject: gtk+ r19407 - in branches/gtk-2-12: . docs/reference docs/reference/gtk/tmpl gtk tests
- Date: Fri, 25 Jan 2008 19:52:16 +0000 (GMT)
Author: johan
Date: Fri Jan 25 19:52:15 2008
New Revision: 19407
URL: http://svn.gnome.org/viewvc/gtk+?rev=19407&view=rev
Log:
2008-01-25 Johan Dahlin <johan gnome org>
Merge from trunk:
* gtk/gtk-builder-convert
(GtkBuilderConverter._convert_adjustment): Handle the case where
there is no child text node.
(GtkBuilderConverter): Allow xml comments in most places.
* gtk/gtk-builder-convert
(GtkBuilderConverter._convert_combobox_items): Remove the items
even if there are no items set.
(GtkBuilderConverter._add_action_from_menuitem): Convert toggled
signals and tooltips for all menu items subclasses and
GtkImageMenuItem:label.
Makes it possible to fully convert and run Jokosher.glade.
* gtk/gtkwidget.c: (gtk_widget_buildable_interface_init),
(gtk_widget_buildable_get_internal_child), (free_action),
(free_relation), (gtk_widget_buildable_parser_finished),
(accessibility_start_element),
(gtk_widget_buildable_custom_tag_start),
(gtk_widget_buildable_custom_finished):
Implement accessible support, fixes #454653.
* gtk/gtk-builder-convert:
Add support for migrating old glade files
* tests/buildertest.c: (test_widget), (test_file):
Add accessible tests and imprve the test_file function to display
toplevels and run dialogs.
Modified:
branches/gtk-2-12/ChangeLog
branches/gtk-2-12/docs/reference/ChangeLog
branches/gtk-2-12/docs/reference/gtk/tmpl/gtkwidget.sgml
branches/gtk-2-12/gtk/gtk-builder-convert
branches/gtk-2-12/gtk/gtkwidget.c
branches/gtk-2-12/tests/buildertest.c
Modified: branches/gtk-2-12/docs/reference/gtk/tmpl/gtkwidget.sgml
==============================================================================
--- branches/gtk-2-12/docs/reference/gtk/tmpl/gtkwidget.sgml (original)
+++ branches/gtk-2-12/docs/reference/gtk/tmpl/gtkwidget.sgml Fri Jan 25 19:52:15 2008
@@ -37,6 +37,31 @@
</object>
]]></programlisting>
</example>
+In addition to accelerators, <structname>GtkWidget</structname> also support a
+custom <accessible> element, which supports actions and relations.
+Properties on the accessible implementation of an object can be set by accessing the
+internal child "accessible" of a <structname>GtkWidget</structname>.
+<example>
+<title>A UI definition fragment specifying an accessible</title>
+<programlisting><![CDATA[
+<object class="GtkButton" id="label1"/>
+ <property name="label">I am a Label for a Button</property>
+</object>
+<object class="GtkButton" id="button1">
+ <accessibility>
+ <action action_name="click" description="Click the button."/>
+ <relation target="label1" type="labelled-by"/>
+ </accessibility>
+ <child internal-child="accessible">
+ <object class="AtkObject" id="a11y-button1">
+ <property name="AtkObject::name">Clickable Button</property>
+ </object>
+ </child>
+</object>
+]]></programlisting>
+</example>
+
+
</refsect2>
<!-- ##### SECTION See_Also ##### -->
Modified: branches/gtk-2-12/gtk/gtk-builder-convert
==============================================================================
--- branches/gtk-2-12/gtk/gtk-builder-convert (original)
+++ branches/gtk-2-12/gtk/gtk-builder-convert Fri Jan 25 19:52:15 2008
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright (C) 2006-2007 Async Open Source
+# Copyright (C) 2006-2008 Async Open Source
# Henrique Romano <henrique async com br>
# Johan Dahlin <jdahlin async com br>
#
@@ -58,7 +58,7 @@
assert node.tagName == 'object'
nodes = []
for child in node.childNodes:
- if child.nodeType == Node.TEXT_NODE:
+ if child.nodeType != Node.ELEMENT_NODE:
continue
if child.tagName != 'child':
continue
@@ -69,7 +69,7 @@
assert node.tagName == 'object'
properties = {}
for child in node.childNodes:
- if child.nodeType == Node.TEXT_NODE:
+ if child.nodeType != Node.ELEMENT_NODE:
continue
if child.tagName != 'property':
continue
@@ -86,7 +86,7 @@
assert node.tagName == 'object'
properties = {}
for child in node.childNodes:
- if child.nodeType == Node.TEXT_NODE:
+ if child.nodeType != Node.ELEMENT_NODE:
continue
if child.tagName != 'property':
continue
@@ -97,7 +97,7 @@
assert node.tagName == 'object'
signals = []
for child in node.childNodes:
- if child.nodeType == Node.TEXT_NODE:
+ if child.nodeType != Node.ELEMENT_NODE:
continue
if child.tagName == 'signal':
signals.append(child)
@@ -107,8 +107,9 @@
assert node.tagName == 'object'
properties = []
for child in node.childNodes:
- if child.nodeType == Node.TEXT_NODE:
+ if child.nodeType != Node.ELEMENT_NODE:
continue
+ # FIXME: handle comments
if child.tagName == 'property':
properties.append(child)
return properties
@@ -117,17 +118,17 @@
assert node.tagName == 'object'
accelerators = []
for child in node.childNodes:
- if child.nodeType == Node.TEXT_NODE:
+ if child.nodeType != Node.ELEMENT_NODE:
continue
if child.tagName == 'accelerator':
accelerators.append(child)
return accelerators
def get_object_node(child_node):
- assert child_node.tagName == 'child'
+ assert child_node.tagName == 'child', child_node
nodes = []
for node in child_node.childNodes:
- if node.nodeType == Node.TEXT_NODE:
+ if node.nodeType != Node.ELEMENT_NODE:
continue
if node.tagName == 'object':
nodes.append(node)
@@ -178,7 +179,7 @@
return [w for w in self._dom.getElementsByTagName("object")
if w.getAttribute(attribute) == value]
- def _create_object(self, obj_class, obj_id, template=None, **properties):
+ def _create_object(self, obj_class, obj_id, template=None, properties=None):
"""
Creates a new <object> tag.
Optionally a name template can be provided which will be used
@@ -207,22 +208,23 @@
obj = self._dom.createElement('object')
obj.setAttribute('class', obj_class)
obj.setAttribute('id', obj_id)
- for name, value in properties.items():
- if isinstance(value, Node):
- # Reuse the node, so translatable and context still will be
- # set when converting nodes. See also #509153
- prop = value
- else:
- prop = self._dom.createElement('property')
- prop.appendChild(self._dom.createTextNode(value))
+ if properties:
+ for name, value in properties.items():
+ if isinstance(value, Node):
+ # Reuse the node, so translatable and context still will be
+ # set when converting nodes. See also #509153
+ prop = value
+ else:
+ prop = self._dom.createElement('property')
+ prop.appendChild(self._dom.createTextNode(value))
- prop.setAttribute('name', name)
- obj.appendChild(prop)
+ prop.setAttribute('name', str(name))
+ obj.appendChild(prop)
self.objects[obj_id] = obj
return obj
- def _create_root_object(self, obj_class, template, **properties):
- obj = self._create_object(obj_class, None, template, **properties)
+ def _create_root_object(self, obj_class, template, properties=None):
+ obj = self._create_object(obj_class, None, template, properties)
self.root_objects.append(obj)
return obj
@@ -261,6 +263,10 @@
for node in self._dom.getElementsByTagName("ui"):
self._convert_ui(node)
+ # Convert accessibility tag
+ for node in self._dom.getElementsByTagName("accessibility"):
+ self._convert_accessibility(node)
+
# Output the newly created root objects and sort them
# by attribute id
for obj in sorted(self.root_objects,
@@ -376,7 +382,7 @@
return menu
def _menuitem_to_action(self, node, properties):
- copy_properties(node, ['label'], properties)
+ copy_properties(node, ['label', 'tooltip'], properties)
def _togglemenuitem_to_action(self, node, properties):
self._menuitem_to_action(node, properties)
@@ -408,6 +414,7 @@
child = get_property_node(image, 'stock')
if child is not None:
properties['stock_id'] = child
+ self._menuitem_to_action(node, properties)
elif object_class == 'GtkSeparatorMenuItem':
return
else:
@@ -421,11 +428,11 @@
properties['name'] = object_id
action = self._create_object(name,
object_id,
- **properties)
+ properties=properties)
for signal in get_signal_nodes(node):
signal_name = signal.getAttribute('name')
- if signal_name == 'activate':
+ if signal_name in ['activate', 'toggled']:
action.appendChild(signal)
else:
print 'Unhandled signal %s::%s' % (node.getAttribute('class'),
@@ -494,7 +501,7 @@
# 2) Get dialogs action-widgets tag, create if not found
for child in dialog.childNodes:
- if child.nodeType == Node.TEXT_NODE:
+ if child.nodeType != Node.ELEMENT_NODE:
continue
if child.tagName == 'action-widgets':
actions = child
@@ -510,20 +517,28 @@
actions.appendChild(action)
def _convert_adjustment(self, prop):
- data = prop.childNodes[0].data
- value, lower, upper, step, page, page_size = data.split(' ')
+ properties = {}
+ if prop.childNodes:
+ data = prop.childNodes[0].data
+ value, lower, upper, step, page, page_size = data.split(' ')
+ properties.update(value=value,
+ lower=lower,
+ upper=upper,
+ step_increment=step,
+ page_increment=page,
+ page_size=page_size)
+ else:
+ prop.appendChild(self._dom.createTextNode(""))
+
adj = self._create_root_object("GtkAdjustment",
template='adjustment',
- value=value,
- lower=lower,
- upper=upper,
- step_increment=step,
- page_increment=page,
- page_size=page_size)
+ properties=properties)
prop.childNodes[0].data = adj.getAttribute('id')
def _convert_combobox_items(self, node, prop):
+ parent = prop.parentNode
if not prop.childNodes:
+ parent.removeChild(prop)
return
value = prop.childNodes[0].data
model = self._create_root_object("GtkListStore",
@@ -548,7 +563,6 @@
col.appendChild(self._dom.createTextNode(item))
row.appendChild(col)
- parent = prop.parentNode
model_prop = self._dom.createElement('property')
model_prop.setAttribute('name', 'model')
model_prop.appendChild(
@@ -581,7 +595,7 @@
prop.removeAttribute('translatable')
tbuffer = self._create_root_object("GtkTextBuffer",
template='textbuffer',
- text=data)
+ properties=dict(text=data))
prop.childNodes[0].data = tbuffer.getAttribute('id')
def _packing_prop_to_child_attr(self, node, prop_name, prop_val,
@@ -623,6 +637,35 @@
widget.getAttributeNode("constructor").value = parent_id
node.removeAttribute("id")
+ def _convert_accessibility(self, node):
+ objectNode = node.parentNode
+ parent_id = objectNode.getAttribute("id")
+
+ properties = {}
+ for node in node.childNodes:
+ if node.nodeName == 'atkproperty':
+ node.tagName = 'property'
+ properties[node.getAttribute('name')] = node
+ node.parentNode.removeChild(node)
+ elif node.nodeName == 'atkrelation':
+ node.tagName = 'relation'
+ relation_type = node.getAttribute('type')
+ relation_type = relation_type.replace('_', '-')
+ node.setAttribute('type', relation_type)
+ elif node.nodeName == 'atkaction':
+ node.tagName = 'action'
+
+ if properties:
+ child = self._dom.createElement('child')
+ child.setAttribute("internal-child", "accessible")
+
+ atkobject = self._create_object(
+ "AtkObject", None,
+ template='a11y-%s' % (parent_id,),
+ properties=properties)
+ child.appendChild(atkobject)
+ objectNode.appendChild(child)
+
def _strip_root(self, root_name):
for widget in self._dom.getElementsByTagName("widget"):
if widget.getAttribute('id') == root_name:
Modified: branches/gtk-2-12/gtk/gtkwidget.c
==============================================================================
--- branches/gtk-2-12/gtk/gtkwidget.c (original)
+++ branches/gtk-2-12/gtk/gtkwidget.c Fri Jan 25 19:52:15 2008
@@ -251,6 +251,9 @@
static void gtk_widget_buildable_set_name (GtkBuildable *buildable,
const gchar *name);
static const gchar * gtk_widget_buildable_get_name (GtkBuildable *buildable);
+static GObject * gtk_widget_buildable_get_internal_child (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ const gchar *childname);
static void gtk_widget_buildable_set_buildable_property (GtkBuildable *buildable,
GtkBuilder *builder,
const gchar *name,
@@ -8847,17 +8850,20 @@
/*
* GtkBuildable implementation
*/
-static GQuark quark_builder_has_default = 0;
-static GQuark quark_builder_has_focus = 0;
+static GQuark quark_builder_has_default = 0;
+static GQuark quark_builder_has_focus = 0;
+static GQuark quark_builder_atk_relations = 0;
static void
gtk_widget_buildable_interface_init (GtkBuildableIface *iface)
{
quark_builder_has_default = g_quark_from_static_string ("gtk-builder-has-default");
quark_builder_has_focus = g_quark_from_static_string ("gtk-builder-has-focus");
+ quark_builder_atk_relations = g_quark_from_static_string ("gtk-builder-atk-relations");
iface->set_name = gtk_widget_buildable_set_name;
iface->get_name = gtk_widget_buildable_get_name;
+ iface->get_internal_child = gtk_widget_buildable_get_internal_child;
iface->set_buildable_property = gtk_widget_buildable_set_buildable_property;
iface->parser_finished = gtk_widget_buildable_parser_finished;
iface->custom_tag_start = gtk_widget_buildable_custom_tag_start;
@@ -8877,6 +8883,17 @@
return gtk_widget_get_name (GTK_WIDGET (buildable));
}
+static GObject *
+gtk_widget_buildable_get_internal_child (GtkBuildable *buildable,
+ GtkBuilder *builder,
+ const gchar *childname)
+{
+ if (strcmp (childname, "accessible") == 0)
+ return G_OBJECT (gtk_widget_get_accessible (GTK_WIDGET (buildable)));
+
+ return NULL;
+}
+
static void
gtk_widget_buildable_set_buildable_property (GtkBuildable *buildable,
GtkBuilder *builder,
@@ -8893,17 +8910,224 @@
g_object_set_property (G_OBJECT (buildable), name, value);
}
+typedef struct {
+ gchar *action_name;
+ gchar *description;
+} AtkActionData;
+
+typedef struct {
+ gchar *target;
+ gchar *type;
+} AtkRelationData;
+
+static void
+free_action (AtkActionData *data, gpointer user_data)
+{
+ g_free (data->action_name);
+ g_free (data->description);
+ g_slice_free (AtkActionData, data);
+}
+
+static void
+free_relation (AtkRelationData *data, gpointer user_data)
+{
+ g_free (data->target);
+ g_free (data->type);
+ g_slice_free (AtkRelationData, data);
+}
+
static void
gtk_widget_buildable_parser_finished (GtkBuildable *buildable,
GtkBuilder *builder)
{
+ GSList *atk_relations;
+
if (g_object_get_qdata (G_OBJECT (buildable), quark_builder_has_default))
gtk_widget_grab_default (GTK_WIDGET (buildable));
if (g_object_get_qdata (G_OBJECT (buildable), quark_builder_has_focus))
gtk_widget_grab_focus (GTK_WIDGET (buildable));
+
+ atk_relations = g_object_get_qdata (G_OBJECT (buildable),
+ quark_builder_atk_relations);
+ if (atk_relations)
+ {
+ AtkObject *accessible;
+ AtkRelationSet *relation_set;
+ GSList *l;
+ GObject *target;
+ AtkRelationType relation_type;
+ AtkObject *target_accessible;
+
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (buildable));
+ relation_set = atk_object_ref_relation_set (accessible);
+
+ for (l = atk_relations; l; l = l->next)
+ {
+ AtkRelationData *relation = (AtkRelationData*)l->data;
+
+ target = gtk_builder_get_object (builder, relation->target);
+ if (!target)
+ {
+ g_warning ("Target object %s in <relation> does not exist",
+ relation->target);
+ continue;
+ }
+ target_accessible = gtk_widget_get_accessible (GTK_WIDGET (target));
+ g_assert (target_accessible != NULL);
+
+ relation_type = atk_relation_type_for_name (relation->type);
+ if (relation_type == ATK_RELATION_NULL)
+ {
+ g_warning ("<relation> type %s not found",
+ relation->type);
+ continue;
+ }
+ atk_relation_set_add_relation_by_type (relation_set, relation_type,
+ target_accessible);
+ }
+ g_object_unref (relation_set);
+
+ g_slist_foreach (atk_relations, (GFunc)free_relation, NULL);
+ g_slist_free (atk_relations);
+ g_object_set_qdata (G_OBJECT (buildable), quark_builder_atk_relations,
+ NULL);
+ }
+
}
typedef struct {
+ GSList *actions;
+ GSList *relations;
+} AccessibilitySubParserData;
+
+static void
+accessibility_start_element (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **names,
+ const gchar **values,
+ gpointer user_data,
+ GError **error)
+{
+ AccessibilitySubParserData *data = (AccessibilitySubParserData*)user_data;
+ guint i;
+ gint line_number, char_number;
+
+ if (strcmp (element_name, "relation") == 0)
+ {
+ gchar *target = NULL;
+ gchar *type = NULL;
+ AtkRelationData *relation;
+
+ for (i = 0; names[i]; i++)
+ {
+ if (strcmp (names[i], "target") == 0)
+ target = g_strdup (values[i]);
+ else if (strcmp (names[i], "type") == 0)
+ type = g_strdup (values[i]);
+ else
+ {
+ g_markup_parse_context_get_position (context,
+ &line_number,
+ &char_number);
+ g_set_error (error,
+ GTK_BUILDER_ERROR,
+ GTK_BUILDER_ERROR_INVALID_ATTRIBUTE,
+ "%s:%d:%d '%s' is not a valid attribute of <%s>",
+ "<input>",
+ line_number, char_number, names[i], "relation");
+ g_free (target);
+ g_free (type);
+ return;
+ }
+ }
+
+ if (!target || !type)
+ {
+ g_markup_parse_context_get_position (context,
+ &line_number,
+ &char_number);
+ g_set_error (error,
+ GTK_BUILDER_ERROR,
+ GTK_BUILDER_ERROR_MISSING_ATTRIBUTE,
+ "%s:%d:%d <%s> requires attribute \"%s\"",
+ "<input>",
+ line_number, char_number, "relation",
+ type ? "target" : "type");
+ g_free (target);
+ g_free (type);
+ return;
+ }
+
+ relation = g_slice_new (AtkRelationData);
+ relation->target = target;
+ relation->type = type;
+
+ data->relations = g_slist_prepend (data->relations, relation);
+ }
+ else if (strcmp (element_name, "action") == 0)
+ {
+ gchar *action_name = NULL;
+ gchar *description = NULL;
+ AtkActionData *action;
+
+ for (i = 0; names[i]; i++)
+ {
+ if (strcmp (names[i], "action_name") == 0)
+ action_name = g_strdup (values[i]);
+ else if (strcmp (names[i], "description") == 0)
+ description = g_strdup (values[i]);
+ else
+ {
+ g_markup_parse_context_get_position (context,
+ &line_number,
+ &char_number);
+ g_set_error (error,
+ GTK_BUILDER_ERROR,
+ GTK_BUILDER_ERROR_INVALID_ATTRIBUTE,
+ "%s:%d:%d '%s' is not a valid attribute of <%s>",
+ "<input>",
+ line_number, char_number, names[i], "action");
+ g_free (action_name);
+ g_free (description);
+ return;
+ }
+ }
+
+ if (!action_name || !description)
+ {
+ g_markup_parse_context_get_position (context,
+ &line_number,
+ &char_number);
+ g_set_error (error,
+ GTK_BUILDER_ERROR,
+ GTK_BUILDER_ERROR_MISSING_ATTRIBUTE,
+ "%s:%d:%d <%s> requires attribute \"%s\"",
+ "<input>",
+ line_number, char_number, "action",
+ description ? "action_name" : "description");
+ g_free (action_name);
+ g_free (description);
+ return;
+ }
+
+ action = g_slice_new (AtkActionData);
+ action->action_name = action_name;
+ action->description = description;
+
+ data->actions = g_slist_prepend (data->actions, action);
+ }
+ else if (strcmp (element_name, "accessibility") == 0)
+ ;
+ else
+ g_warning ("Unsupported tag for GtkWidget: %s\n", element_name);
+}
+
+static const GMarkupParser accessibility_parser =
+ {
+ accessibility_start_element,
+ };
+
+typedef struct {
GObject *object;
guint key;
guint modifiers;
@@ -8955,12 +9179,6 @@
accel_group_start_element,
};
-static const GMarkupParser accessibility_parser =
- {
- NULL,
- };
-
-
static gboolean
gtk_widget_buildable_custom_tag_start (GtkBuildable *buildable,
GtkBuilder *builder,
@@ -8969,31 +9187,25 @@
GMarkupParser *parser,
gpointer *data)
{
- AccelGroupParserData *parser_data;
-
g_assert (buildable);
if (strcmp (tagname, "accelerator") == 0)
{
+ AccelGroupParserData *parser_data;
+
parser_data = g_slice_new0 (AccelGroupParserData);
parser_data->object = g_object_ref (buildable);
*parser = accel_group_parser;
*data = parser_data;
return TRUE;
}
- else if (strcmp (tagname, "accessibility") == 0)
+ if (strcmp (tagname, "accessibility") == 0)
{
- static gboolean warning_showed = FALSE;
-
- if (!warning_showed)
- {
- g_warning ("<accessibility> is being ignored,\n"
- "see http://bugzilla.gnome.org/show_bug.cgi?id=454653\n");
- warning_showed = TRUE;
- }
+ AccessibilitySubParserData *parser_data;
+ parser_data = g_slice_new0 (AccessibilitySubParserData);
*parser = accessibility_parser;
- *data = NULL;
+ *data = parser_data;
return TRUE;
}
return FALSE;
@@ -9006,17 +9218,18 @@
const gchar *tagname,
gpointer user_data)
{
- AccelGroupParserData *data;
+ AccelGroupParserData *accel_data;
+ AccessibilitySubParserData *a11y_data;
GtkWidget *toplevel;
GSList *accel_groups;
GtkAccelGroup *accel_group;
if (strcmp (tagname, "accelerator") == 0)
{
- data = (AccelGroupParserData*)user_data;
- g_assert (data->object);
+ accel_data = (AccelGroupParserData*)user_data;
+ g_assert (accel_data->object);
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (data->object));
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (accel_data->object));
accel_groups = gtk_accel_groups_from_object (G_OBJECT (toplevel));
if (g_slist_length (accel_groups) == 0)
{
@@ -9028,15 +9241,56 @@
g_assert (g_slist_length (accel_groups) == 1);
accel_group = g_slist_nth_data (accel_groups, 0);
}
- gtk_widget_add_accelerator (GTK_WIDGET(data->object),
- data->signal,
+ gtk_widget_add_accelerator (GTK_WIDGET (accel_data->object),
+ accel_data->signal,
accel_group,
- data->key,
- data->modifiers,
+ accel_data->key,
+ accel_data->modifiers,
GTK_ACCEL_VISIBLE);
- g_object_unref (data->object);
- g_free (data->signal);
- g_slice_free (AccelGroupParserData, data);
+ g_object_unref (accel_data->object);
+ g_free (accel_data->signal);
+ g_slice_free (AccelGroupParserData, accel_data);
+ }
+ else if (strcmp (tagname, "accessibility") == 0)
+ {
+ a11y_data = (AccessibilitySubParserData*)user_data;
+
+ if (a11y_data->actions)
+ {
+ AtkObject *accessible;
+ AtkAction *action;
+ gint i, n_actions;
+ GSList *l;
+
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (buildable));
+
+ action = ATK_ACTION (accessible);
+ n_actions = atk_action_get_n_actions (action);
+
+ for (l = a11y_data->actions; l; l = l->next)
+ {
+ AtkActionData *action_data = (AtkActionData*)l->data;
+
+ for (i = 0; i < n_actions; i++)
+ if (strcmp (atk_action_get_name (action, i),
+ action_data->action_name) == 0)
+ break;
+
+ if (i < n_actions)
+ atk_action_set_description (action, i,
+ action_data->description);
+ }
+
+ g_slist_foreach (a11y_data->actions, (GFunc)free_action, NULL);
+ g_slist_free (a11y_data->actions);
+ }
+
+ if (a11y_data->relations)
+ g_object_set_qdata (G_OBJECT (buildable), quark_builder_atk_relations,
+ a11y_data->relations);
+
+ g_slice_free (AccessibilitySubParserData, a11y_data);
+
}
}
Modified: branches/gtk-2-12/tests/buildertest.c
==============================================================================
--- branches/gtk-2-12/tests/buildertest.c (original)
+++ branches/gtk-2-12/tests/buildertest.c Fri Jan 25 19:52:15 2008
@@ -1485,14 +1485,37 @@
gchar *buffer3 =
"<interface>"
" <object class=\"GtkWindow\" id=\"window1\">"
- " <accessibility>"
- " <atkproperty name=\"AtkObject::accessible_name\" translatable=\"yes\">Contacts</atkproperty>"
- " <atkrelation target=\"button1\" type=\"labelled-by\"/>"
- " </accessibility>"
+ " <child>"
+ " <object class=\"GtkVBox\" id=\"vbox1\">"
+ " <child>"
+ " <object class=\"GtkLabel\" id=\"label1\">"
+ " <child internal-child=\"accessible\">"
+ " <object class=\"AtkObject\" id=\"a11y-label1\">"
+ " <property name=\"AtkObject::accessible-name\">A Label</property>"
+ " </object>"
+ " </child>"
+ " <accessibility>"
+ " <relation target=\"button1\" type=\"label-for\"/>"
+ " </accessibility>"
+ " </object>"
+ " </child>"
+ " <child>"
+ " <object class=\"GtkButton\" id=\"button1\">"
+ " <accessibility>"
+ " <action action_name=\"click\" description=\"Sliff\"/>"
+ " </accessibility>"
+ " </object>"
+ " </child>"
+ " </object>"
+ " </child>"
" </object>"
- "</interface>";
+ "</interface>";
GtkBuilder *builder;
- GObject *window1, *button1;
+ GObject *window1, *button1, *label1;
+ AtkObject *accessible;
+ AtkRelationSet *relation_set;
+ AtkRelation *relation;
+ char *name;
builder = builder_new_from_string (buffer, -1, NULL);
button1 = gtk_builder_get_object (builder, "button1");
@@ -1510,7 +1533,26 @@
g_return_val_if_fail (GTK_WIDGET_RECEIVES_DEFAULT (GTK_WIDGET (button1)), FALSE);
+ g_object_unref (builder);
+
+ builder = builder_new_from_string (buffer3, -1, NULL);
+
window1 = gtk_builder_get_object (builder, "window1");
+ label1 = gtk_builder_get_object (builder, "label1");
+
+ accessible = gtk_widget_get_accessible (GTK_WIDGET (label1));
+ relation_set = atk_object_ref_relation_set (accessible);
+ g_return_if_fail (atk_relation_set_get_n_relations (relation_set) == 1);
+ relation = atk_relation_set_get_relation (relation_set, 0);
+ g_return_if_fail (relation != NULL);
+ g_return_if_fail (ATK_IS_RELATION (relation));
+ g_return_if_fail (atk_relation_get_relation_type (relation) != ATK_RELATION_LABELLED_BY);
+ g_object_unref (relation_set);
+
+ g_object_get (G_OBJECT (accessible), "accessible-name", &name, NULL);
+ g_return_if_fail (strcmp (name, "A Label") == 0);
+ g_free (name);
+
gtk_widget_destroy (GTK_WIDGET (window1));
g_object_unref (builder);
@@ -1762,18 +1804,43 @@
{
GtkBuilder *builder;
GError *error = NULL;
+ GSList *l, *objects;
builder = gtk_builder_new ();
if (!gtk_builder_add_from_file (builder, filename, &error))
{
- g_print ("%s\n", error->message);
+ g_error (error->message);
g_error_free (error);
+ return;
+ }
+
+ objects = gtk_builder_get_objects (builder);
+ for (l = objects; l; l = l->next)
+ {
+ GObject *obj = (GObject*)l->data;
+
+ if (GTK_IS_DIALOG (obj))
+ {
+ int response;
+
+ g_print ("Running dialog %s.\n",
+ gtk_widget_get_name (GTK_WIDGET (obj)));
+ response = gtk_dialog_run (GTK_DIALOG (obj));
+ }
+ else if (GTK_IS_WINDOW (obj))
+ {
+ g_signal_connect (obj, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+ g_print ("Showing %s.\n",
+ gtk_widget_get_name (GTK_WIDGET (obj)));
+ gtk_widget_show_all (GTK_WIDGET (obj));
+ }
}
+ gtk_main ();
+
g_object_unref (builder);
builder = NULL;
-
}
int
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]