#!/usr/bin/python # encoding: UTF-8 # api: python # title: glade compiler for python # description: simplistic .glade to .python tranformation, generates flat gtk.Widget creation calls # comment: I can't believe I'm doing this... # type: filter # version: 1.9 # license: public domain # # Transforms a .glade file into a list of python gtk.Widget creation calls. # # Syntax: # glc2 project.glade >> project-gui.py # # Retains the glade widget name= IDs. # Does no indendation of itself - use the editor, Luke! # # The generated code expects a pre-defined signal[] dictionary, for binding gtk # signals to callback functions. # # # import sys import os import re from xml.dom import minidom from xml.sax.saxutils import unescape as entity_decode, escape as xmlentities import gtk import pygtk ELEMENT_NODE = 1 TEXT_NODE = 3 #wTree_prefix = "wTree." # this comes down to personal preferences, wTree_prefix = "" # object IDs can just be local variables, #wTree_prefix = "self." # go in a wTree, or directly into local object # pygtk naming def gtkclass(cls): return re.sub("Gtk", "gtk.", cls) def gtkconstant(con): return re.sub("GTK_", "gtk.", con) def gtkid(id): return re.sub("-", "_", id) # looks for child tags in the current level only def subnodes(w, tag="child"): return [cn for cn in w.childNodes if cn.nodeType==ELEMENT_NODE and cn.tagName==tag] # shortcut to text content def text(w): return "".join([t.data for t in w.childNodes if t.nodeType==TEXT_NODE]) # extracts s associated to a -tree (the packaging is always sibling to the widget node) def packaging_properties(next): pack = {} for p in subnodes(next,"packing"): for prop in subnodes(p, "property"): pack[prop.getAttribute("name")] = text(prop) return pack # special handling of .pack() and .add() functions for complicated container widgets packing_handlers = { "GtkHPaned": lambda id, i, sub_id, pack: (id + ".pack" + str(i+1) + "(" + sub_id + ", resize=" + pack["resize"] + ", shrink=" + pack["shrink"] + ")"), } # additional methods for special gtk objects widget_functions = { "GtkEntry": lambda w, id: "#" + id + ".set_text(_(...))" } #-- recurse through widgets def widget(w): # basic widget attributes cls = w.getAttribute("class") obj = gtkclass(cls) id = wTree_prefix + gtkid(w.getAttribute("id")) # gladename = gtk.Widget() print "\n#", cls, '"'+id+'"' print id, "=", obj + "()" ###### print id + ".show()" ## glade-3 alreadys sets a property "visible" for all objects # properties for prop in subnodes(w, "property"): print id + ".set_property(\"" + prop.getAttribute("name") + "\", " + gtkconstant(text(prop)) + ")" # signals for sig in subnodes(w, "signal"): print id + ".connect(\"" + sig.getAttribute("name") + "\", signal[\"" + sig.getAttribute("handler") + "\"])" # extra widget features if (widget_functions.has_key(cls)): print widget_functions[cls](w, id) # child nodes childs = [] for next in subnodes(w, "child"): # sub widgets childs.append([ widget(subnodes(next, "widget")[0]), packaging_properties(next) ]) # child packing for i,row in enumerate(childs): (sub_id, pack) = row if (packing_handlers.has_key(cls)): print packing_handlers[cls](id, i, sub_id, pack) else: print id + ".add(" + sub_id + ")" # return current id to parent (for .add/.pack) return id #end widget() #-- run if __name__ == "__main__": #-- open file root = minidom.parse(sys.argv[1]).getElementsByTagName("glade-interface")[0] # preface print "#-- code generated by glc2, so sorry!" print "signals = {} # must associate signal names to actual callback functions" print (wTree_prefix,"#wTree")[not wTree_prefix or wTree_prefix=="self."], "= object() # some people seem to love wTree" print "" # start with root widget widget(subnodes(root, "widget")[0])