Index: gtk/gtk-builder-convert
===================================================================
--- gtk/gtk-builder-convert	(revisão 0)
+++ gtk/gtk-builder-convert	(revisão 0)
@@ -0,0 +1,246 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2006-2007 Async Open Source
+#                         Henrique Romano <henrique@async.com.br>
+#                         Johan Dahlin <jdahlin@async.com.br>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser 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 Lesser General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+""" A simple Gazpacho/Glade to GtkBuilder XML format converter. """
+import sys
+
+from xml.dom.minidom import Element
+from xml.dom import minidom
+
+class GtkBuilderConverter:
+    def __init__(self):
+        self._dom = None
+
+    #
+    # Public API
+    #
+
+    def parse_file(self, file):
+        self._dom = minidom.parse(file)
+
+    def parse_buffer(self, buffer):
+        self._dom = minidom.parseString(buffer)
+
+    def to_xml(self):
+        return self._dom.toprettyxml("", "")
+
+    def convert(self):
+        if self._dom is None:
+            raise ValueError("You must specify a buffer or filename")
+
+        glade_iface = self._dom.getElementsByTagName("glade-interface")
+        assert glade_iface, ("Bad formed XML, there are "
+                             "no <glade-interface> tag.")
+        glade_iface[0].tagName = 'interface'
+
+        # Strip requires
+        requires = self._dom.getElementsByTagName("requires")
+        for require in requires:
+            require.parentNode.childNodes.remove(require)
+
+        for node in self._dom.getElementsByTagName("widget"):
+            node.tagName = "object"
+            self._convert(node.getAttribute("class"), node)
+        for node in self._dom.getElementsByTagName("ui"):
+            self._convert_ui(node)
+
+    #
+    # Private
+    #
+
+    def _get_widgets_by_attr(self, doc, attr_name, attr_val, tagname="object"):
+        return [widget for widget in doc.getElementsByTagName(tagname)
+                    if widget.getAttribute(attr_name) == attr_val]
+
+    def _get_widget(self, doc, name):
+        """ It is helper method to get a widget given its ID. Remember that
+        we can't use minidom's getElementById, since it requires special
+        magic to be added in the XML header.
+        """
+        result = self._get_widgets_by_attr(doc, "id", name)
+        if len(result) > 1:
+            raise ValueError("It is not possible to have more than one "
+                             "widget with the same id (`%s')" % name)
+        elif len(result) == 1:
+            return result[0]
+        return None
+
+    def _get_widgets_by_class(self, doc, klass):
+        return self._get_widgets_by_attr(doc, "class", klass)
+
+    def _packing_prop_to_child_attr(self, node, prop_name, prop_val,
+                                    attr_name=None, attr_val=None):
+        for child in node.getElementsByTagName("child"):
+            packing_props = [p for p in child.childNodes if p.nodeName == "packing"]
+            if not packing_props:
+                continue
+            assert len(packing_props) == 1
+            packing_prop = packing_props[0]
+            properties = packing_prop.getElementsByTagName("property")
+            for prop in properties:
+                if (prop.getAttribute("name") != prop_name
+                    or prop.childNodes[0].data != prop_val):
+                    continue
+                packing_prop.removeChild(prop)
+                child.setAttribute(attr_name or prop_name, attr_val or prop_val)
+            if len(properties) == 1:
+                child.removeChild(packing_prop)
+
+    def _widget_prop_to_container_obj(self, node, prop, obj_class, obj_id,
+                                      members_tag, member_tag, member_attrs):
+        """ Given a widget property, move it to a container object specified
+        by obj_class and obj_id parameters. Eg:
+
+        prop = <property name='sizegroup'>sizegroup1</property>
+
+        _widget_prop_to_container_obj(node, prop, 'GtkSizeGroup', 'sizegroup1',
+                                      'widgets', 'widget', attrs)
+
+        resultant XML:
+
+        <object class='GtkSizeGroup' id='sizegroup1'>
+          <widgets>
+            <widget attrs/>
+          </widgets>
+        </object>
+
+        Where 'attrs' is a list of 2-sized tuples,  with the first item being
+        the attribute name and the last its value.
+
+        The 'obj_id' parameter is only used if no nodes with attribute 'class'
+        equals to obj_class is found in the document, otherwise the ID of the
+        last node found will be used.
+        """
+        obj_name = prop.childNodes[0].data
+        node.removeChild(prop)
+        doc = node.ownerDocument
+        obj = self._get_widget(doc, obj_name)
+        if obj is None:
+            widgets = self._get_widgets_by_class(doc, obj_class)
+            if widgets:
+                obj = widgets[-1]
+            else:
+                obj = doc.createElement("object")
+                obj.setAttribute("class", obj_class)
+                obj.setAttribute("id", obj_id)
+                glade_iface = doc.getElementsByTagName("glade-interface")
+                assert glade_iface, ("Bad formed XML, there are "
+                                     "no <glade-interface> tag.")
+                glade_iface = glade_iface[0]
+                glade_iface.insertBefore(obj, glade_iface.childNodes[0])
+        members = obj.getElementsByTagName(members_tag)
+        if not members:
+            members = doc.createElement(members_tag)
+            obj.appendChild(members)
+        else:
+            assert len(members) == 1
+            members = members[0]
+        member = doc.createElement(member_tag)
+        for name, value in member_attrs:
+            member.setAttribute(name, value)
+        members.appendChild(member)
+
+    def _convert_ui(self, node):
+        cdata = node.childNodes[0]
+        data = cdata.toxml().strip()
+        if not data.startswith("<![CDATA[") or not data.endswith("]]>"):
+            return
+        data = data[9:-3]
+        child = minidom.parseString(data).childNodes[0]
+        nodes = child.childNodes[:]
+        for child_node in nodes:
+            node.appendChild(child_node)
+        node.removeChild(cdata)
+        if not node.hasAttribute("id"):
+            return
+        # Updating references made by widgets
+        parent_id = node.parentNode.getAttribute("id")
+        for widget in self._get_widgets_by_attr(node.ownerDocument,
+                                                "constructor",
+                                                node.getAttribute("id")):
+            widget.getAttributeNode("constructor").value = parent_id
+        node.removeAttribute("id")
+
+    def _convert(self, klass, node):
+        func = getattr(self, "_object_" + klass, None)
+        if func:
+            func(node)
+        self._default_widget_converter(node)
+
+    def _default_widget_converter(self, node):
+        klass = node.getAttribute("class")
+        for prop in node.getElementsByTagName("property"):
+            if not prop.parentNode is node:
+                continue
+            prop_name = prop.getAttribute("name")
+            if prop_name == "sizegroup":
+                attrs = [("name", node.getAttribute("id")), ]
+                self._widget_prop_to_container_obj(
+                    node, prop, "GtkSizeGroup", "sizegroup1", "widgets",
+                    "widget", attrs)
+            elif prop_name == "tooltip" and not klass == "GtkAction":
+                attrs = [("name", node.getAttribute("id")),
+                         ("text", prop.childNodes[0].data)]
+                self._widget_prop_to_container_obj(
+                    node, prop, "GtkTooltips", "tooltips1", "tooltips",
+                    "tooltip", attrs)
+
+    def _object_GtkNotebook(self, node):
+        self._packing_prop_to_child_attr(node, "type", "tab")
+
+    def _object_GtkExpander(self, node):
+        self._packing_prop_to_child_attr(node, "type", "label_item",
+                                         attr_val="label")
+
+    def _object_GtkFrame(self, node):
+        self._packing_prop_to_child_attr(node, "type", "label_item",
+                                         attr_val="label")
+
+def test():
+    doc = ("<glade-interface>"
+           "  <widget class=\"GtkSizeGroup\" id=\"s1\">"
+           "    <property name=\"mode\">horizontal</property>"
+           "  </widget>"
+           "  <widget class=\"GtkWindow\" id=\"window1\">"
+           "    <child>"
+           "      <widget class=\"GtkLabel\" id=\"label1\">"
+           "        <property name=\"label\">Test</property>"
+           "        <property name=\"sizegroup\">s1</property>"
+           "        <property name=\"tooltip\">tooltip text</property>"
+           "      </widget>"
+           "    </child>"
+           "  </widget>"
+           "</glade-interface>")
+    conv = GtkBuilderConverter()
+    conv.parse_buffer(doc)
+    conv.convert()
+    print conv.to_xml()
+
+def main():
+    if not len(sys.argv) > 1:
+        print "You must specify a filename"
+        return
+    conv = GtkBuilderConverter()
+    conv.parse_file(sys.argv[1])
+    conv.convert()
+    print conv.to_xml()
+
+if __name__ == "__main__":
+    main()

Mudanças de propriedades em: gtk/gtk-builder-convert
___________________________________________________________________
Nome: svn:executable
   + *

Index: gtk/Makefile.am
===================================================================
--- gtk/Makefile.am	(revisão 18145)
+++ gtk/Makefile.am	(cópia de trabalho)
@@ -878,7 +878,10 @@
 #
 # Installed tools
 #
-bin_PROGRAMS = gtk-query-immodules-2.0 gtk-update-icon-cache
+bin_PROGRAMS = \
+	gtk-builder-convert	\
+	gtk-query-immodules-2.0 \
+	gtk-update-icon-cache
 
 gtk_query_immodules_2_0_DEPENDENCIES = $(DEPS)
 gtk_query_immodules_2_0_LDADD = $(LDADDS)
