diff options
Diffstat (limited to 'lib/python2.7/site-packages/wx-3.0-msw/wx/tools/pywxrc.py')
-rw-r--r-- | lib/python2.7/site-packages/wx-3.0-msw/wx/tools/pywxrc.py | 933 |
1 files changed, 933 insertions, 0 deletions
diff --git a/lib/python2.7/site-packages/wx-3.0-msw/wx/tools/pywxrc.py b/lib/python2.7/site-packages/wx-3.0-msw/wx/tools/pywxrc.py new file mode 100644 index 00000000..9b1a9b6c --- /dev/null +++ b/lib/python2.7/site-packages/wx-3.0-msw/wx/tools/pywxrc.py @@ -0,0 +1,933 @@ +#---------------------------------------------------------------------- +# Name: wx.tools.pywxrc +# Purpose: XML resource compiler +# +# Author: Robin Dunn +# Based on wxrc.cpp by Vaclav Slavik, Eduardo Marques +# Ported to Python in order to not require yet another +# binary in wxPython distributions +# +# Massive rework by Eli Golovinsky +# +# Editable blocks by Roman Rolinsky +# +# RCS-ID: $Id$ +# Copyright: (c) 2004 by Total Control Software, 2000 Vaclav Slavik +# Licence: wxWindows license +#---------------------------------------------------------------------- + +""" +pywxrc -- Python XML resource compiler + (see http://wiki.wxpython.org/index.cgi/pywxrc for more info) + +Usage: python pywxrc.py -h + python pywxrc.py [-p] [-g] [-e] [-v] [-o filename] xrc input files... + + -h, --help show help message + -p, --python generate python module + -g, --gettext output list of translatable strings (may be combined with -p) + -e, --embed embed XRC resources in the output file + -v, --novar suppress default assignment of variables + -o, --output output filename, or - for stdout +""" + +import sys, os, getopt, glob, re, cPickle +import xml.dom.minidom as minidom +import wx +import wx.xrc + +#---------------------------------------------------------------------- + +reBeginBlock = re.compile(r'^#!XRCED:begin-block:(\S+)') +reEndBlock = re.compile(r'^#!XRCED:end-block:(\S+)') + +class PythonTemplates: + FILE_HEADER = """\ +# This file was automatically generated by pywxrc. +# -*- coding: UTF-8 -*- + +import wx +import wx.xrc as xrc + +__res = None + +def get_resources(): + \"\"\" This function provides access to the XML resources in this module.\"\"\" + global __res + if __res == None: + __init_resources() + return __res + +""" + + CLASS_HEADER = """\ +class xrc%(windowName)s(wx.%(windowClass)s): +#!XRCED:begin-block:xrc%(windowName)s.PreCreate + def PreCreate(self, pre): + \"\"\" This function is called during the class's initialization. + + Override it for custom setup before the window is created usually to + set additional window styles using SetWindowStyle() and SetExtraStyle(). + \"\"\" + pass + +#!XRCED:end-block:xrc%(windowName)s.PreCreate + + def __init__(self, parent): + # Two stage creation (see http://wiki.wxpython.org/index.cgi/TwoStageCreation) + pre = wx.Pre%(windowClass)s() + self.PreCreate(pre) + get_resources().LoadOn%(windowClass)s(pre, parent, "%(windowName)s") + self.PostCreate(pre) + + # Define variables for the controls, bind event handlers +""" + + SUBCLASS_HEADER = """\ +class %(subclass)s(wx.%(windowClass)s): + def __init__(self): + # Two stage creation (see http://wiki.wxpython.org/index.cgi/TwoStageCreation) + pre = wx.Pre%(windowClass)s() + self.PostCreate(pre) + self.Bind(wx.EVT_WINDOW_CREATE, self.OnCreate) + +#!XRCED:begin-block:%(subclass)s._PostInit + def _PostInit(self): + \"\"\" This function is called after the subclassed object is created. + + Override it for custom setup before the window is created usually to + set additional window styles using SetWindowStyle() and SetExtraStyle(). + \"\"\" + pass +#!XRCED:end-block:%(subclass)s._PostInit + + def OnCreate(self, evt): + self.Unbind(wx.EVT_WINDOW_CREATE) + self._PostInit() +""" + + CREATE_WIDGET_VAR = """\ + self.%(widgetName)s = xrc.XRCCTRL(self, \"%(widgetName)s\") +""" + + FRAME_MENUBAR_VAR = """\ + self.%(widgetName)s = self.GetMenuBar() +""" + + FRAME_MENUBAR_MENUITEM_VAR = """\ + self.%(widgetName)s = self.GetMenuBar().FindItemById(xrc.XRCID(\"%(widgetName)s\")) +""" + + FRAME_MENUBAR_MENU_VAR = """\ + idx = self.GetMenuBar().FindMenu(\"%(label)s\") + if idx != wx.NOT_FOUND: + self.%(widgetName)s = self.GetMenuBar().GetMenu(idx) + else: + self.%(widgetName)s = self.GetMenuBar().FindItemById(xrc.XRCID(\"%(widgetName)s\")).GetSubMenu() +""" + + + MENUBAR_MENUITEM_VAR = """\ + self.%(widgetName)s = self.FindItemById(xrc.XRCID(\"%(widgetName)s\")) +""" + + MENUBAR_MENU_VAR = """\ + idx = self.FindMenu(\"%(label)s\") + if idx != wx.NOT_FOUND: + self.%(widgetName)s = self.GetMenu(idx) + else: + self.%(widgetName)s = self.FindItemById(xrc.XRCID(\"%(widgetName)s\")).GetSubMenu() +""" + + MENU_MENUITEM_VAR = """\ + self.%(widgetName)s = self.FindItemById(xrc.XRCID(\"%(widgetName)s\")) +""" + + MENU_MENU_VAR = """\ + self.%(widgetName)s = self.FindItemById(xrc.XRCID(\"%(widgetName)s\")).GetSubMenu() +""" + + FRAME_TOOLBAR_VAR = """\ + self.%(widgetName)s = self.GetToolBar() +""" + + FRAME_TOOLBAR_TOOL_VAR = """\ + self.%(widgetName)s = self.GetToolBar().FindById(xrc.XRCID(\"%(widgetName)s\")) +""" + + TOOLBAR_TOOL_VAR = """\ + self.%(widgetName)s = self.FindById(xrc.XRCID(\"%(widgetName)s\")) +""" + + BIND_WIDGET_EVENT = """\ + self.Bind(wx.%(event)s, self.%(eventHandler)s, %(eventObject)s) +""" + + BIND_EVENT = """\ + self.Bind(wx.%(event)s, self.%(eventHandler)s) +""" + + CREATE_EVENT_HANDLER = """\ +#!XRCED:begin-block:xrc%(windowName)s.%(eventHandler)s + def %(eventHandler)s(self, evt): + # Replace with event handler code + print \"%(eventHandler)s()\" +#!XRCED:end-block:xrc%(windowName)s.%(eventHandler)s +""" + + MENU_CLASS_HEADER = """\ +class xrc%(windowName)s(wx.%(windowClass)s): + def __init__(self): + pre = get_resources().LoadMenu("%(windowName)s") + + # This is a copy of Robin's PostCreate voodoo magic in wx.Window that + # relinks the self object with the menu object. + self.this = pre.this + self.thisown = pre.thisown + pre.thisown = 0 + if hasattr(self, '_setOORInfo'): + self._setOORInfo(self) + + # Define variables for the menu items +""" + + MENUBAR_CLASS_HEADER = """\ +class xrc%(windowName)s(wx.%(windowClass)s): + def __init__(self): + pre = get_resources().LoadMenuBar("%(windowName)s") + self.PostCreate(pre) + + # Define variables for the menu items +""" + + TOOLBAR_CLASS_HEADER = """\ +class xrc%(windowName)s(wx.%(windowClass)s): + def __init__(self, parent): + pre = get_resources().LoadToolBar(parent, "%(windowName)s") + self.PostCreate(pre) + + # Define variables for the toolbar items +""" + + INIT_RESOURE_HEADER = """\ +# ------------------------ Resource data ---------------------- + +def __init_resources(): + global __res + __res = xrc.EmptyXmlResource() +""" + + LOAD_RES_FILE = """\ + __res.Load('%(resourceFilename)s')""" + + FILE_AS_STRING = """\ + %(filename)s = '''\\ +%(fileData)s''' + +""" + + PREPARE_MEMFS = """\ + wx.FileSystem.AddHandler(wx.MemoryFSHandler()) +""" + + ADD_FILE_TO_MEMFS = """\ + wx.MemoryFSHandler.AddFile('XRC/%(memoryPath)s/%(filename)s', %(filename)s) +""" + + LOAD_RES_MEMFS = """\ + __res.Load('memory:XRC/%(memoryPath)s/%(resourceFilename)s') +""" + + GETTEXT_DUMMY_FUNC = """ +# ----------------------- Gettext strings --------------------- + +def __gettext_strings(): + # This is a dummy function that lists all the strings that are used in + # the XRC file in the _("a string") format to be recognized by GNU + # gettext utilities (specificaly the xgettext utility) and the + # mki18n.py script. For more information see: + # http://wiki.wxpython.org/index.cgi/Internationalization + + def _(str): pass + +%s +""" + +#---------------------------------------------------------------------- + +class XmlResourceCompiler: + + templates = PythonTemplates() + + """This class generates Python code from XML resource files (XRC).""" + + def MakePythonModule(self, inputFiles, outputFilename, + embedResources=False, generateGetText=False, + assignVariables=True): + + self.blocks = {} + self.outputFilename = outputFilename + outputFile = self._OpenOutputFile(outputFilename) + self.assignVariables = assignVariables + + classes = [] + subclasses = [] + resources = [] + gettextStrings = [] + + # process all the inputFiles, collecting the output data + for inFile in inputFiles: + resourceDocument = minidom.parse(inFile) + subclasses.append(self.GenerateSubclasses(resourceDocument)) + classes.append(self.GenerateClasses(resourceDocument)) + + if embedResources: + res = self.GenerateInitResourcesEmbedded(inFile, resourceDocument) + else: + res = self.GenerateInitResourcesFile(inFile, resourceDocument) + resources.append(res) + + if generateGetText: + gettextStrings += self.FindStringsInNode(resourceDocument.firstChild) + + # now write it all out + print >>outputFile, self.templates.FILE_HEADER + + # Note: Technically it is not legal to have anything other + # than ascii for class and variable names, but since the user + # can create the XML with non-ascii names we'll go ahead and + # allow for it here, and then let Python complain about it + # later when they try to run the program. + if subclasses: + subclasses = self.ReplaceBlocks(u"\n".join(subclasses)) + print >>outputFile, subclasses.encode("UTF-8") + if classes: + classes = self.ReplaceBlocks(u"\n".join(classes)) + print >>outputFile, classes.encode("UTF-8") + + print >>outputFile, self.templates.INIT_RESOURE_HEADER + if embedResources: + print >>outputFile, self.templates.PREPARE_MEMFS + resources = u"\n".join(resources) + print >>outputFile, resources.encode("UTF-8") + + if generateGetText: + # These have already been converted to utf-8... + gettextStrings = [' _("%s")' % s for s in gettextStrings] + gettextStrings = "\n".join(gettextStrings) + print >>outputFile, self.templates.GETTEXT_DUMMY_FUNC % gettextStrings + + #------------------------------------------------------------------- + + def MakeGetTextOutput(self, inputFiles, outputFilename): + """ + Just output the gettext strings by themselves, with no other + code generation. + """ + outputFile = self._OpenOutputFile(outputFilename) + for inFile in inputFiles: + resourceDocument = minidom.parse(inFile) + resource = resourceDocument.firstChild + strings = self.FindStringsInNode(resource) + strings = ['_("%s");' % s for s in strings] + print >>outputFile, "\n".join(strings) + + #------------------------------------------------------------------- + + def GenerateClasses(self, resourceDocument): + outputList = [] + + resource = resourceDocument.firstChild + topWindows = [e for e in resource.childNodes + if e.nodeType == e.ELEMENT_NODE and e.tagName == "object" \ + and not e.getAttribute('subclass')] + + # Generate a class for each top-window object (Frame, Panel, Dialog, etc.) + for topWindow in topWindows: + windowClass = topWindow.getAttribute("class") + windowClass = re.sub("^wx", "", windowClass) + windowName = topWindow.getAttribute("name") + if not windowName: continue + + if windowClass in ["MenuBar"]: + genfunc = self.GenerateMenuBarClass + elif windowClass in ["Menu"]: + genfunc = self.GenerateMenuClass + elif windowClass in ["ToolBar"]: + genfunc = self.GenerateToolBarClass + else: + genfunc = self.GenerateWidgetClass + + vars = [] + outputList += genfunc(windowClass, windowName, topWindow, vars) + outputList.append('\n') + + outputList += self.GenerateEventHandlers(windowClass, windowName, topWindow, vars) + + return "".join(outputList) + + #------------------------------------------------------------------- + + def CheckAssignVar(self, widget): + if self.assignVariables: return True # assign_var override mode + assign_var = False + for node in widget.getElementsByTagName("XRCED"): + if node.parentNode is widget: + try: + elem = node.getElementsByTagName("assign_var")[0] + except IndexError: + continue + if elem.childNodes: + ch = elem.childNodes[0] + if ch.nodeType == ch.TEXT_NODE and bool(ch.nodeValue): + assign_var = True + return assign_var + + + def GenerateMenuBarClass(self, windowClass, windowName, topWindow, vars): + outputList = [] + + # output the header + outputList.append(self.templates.MENUBAR_CLASS_HEADER % locals()) + + # create an attribute for menus and menu items that have names + for widget in topWindow.getElementsByTagName("object"): + if not self.CheckAssignVar(widget): continue + widgetClass = widget.getAttribute("class") + widgetClass = re.sub("^wx", "", widgetClass) + widgetName = widget.getAttribute("name") + if widgetName != "" and widgetClass != "": + vars.append(widgetName) + if widgetClass == "MenuItem": + outputList.append(self.templates.MENUBAR_MENUITEM_VAR % locals()) + elif widgetClass == "Menu": + label = widget.getElementsByTagName("label")[0] + label = label.childNodes[0].data + outputList.append(self.templates.MENUBAR_MENU_VAR % locals()) + else: + raise RuntimeError("Unexpected widgetClass for MenuBar: %s" % widgetClass) + + return outputList + + + def GenerateMenuClass(self, windowClass, windowName, topWindow, vars): + outputList = [] + + # output the header + outputList.append(self.templates.MENU_CLASS_HEADER % locals()) + for widget in topWindow.getElementsByTagName("object"): + if not self.CheckAssignVar(widget): continue + widgetClass = widget.getAttribute("class") + widgetClass = re.sub("^wx", "", widgetClass) + widgetName = widget.getAttribute("name") + if widgetName != "" and widgetClass != "": + vars.append(widgetName) + if widgetClass == "MenuItem": + outputList.append(self.templates.MENU_MENUITEM_VAR % locals()) + elif widgetClass == "Menu": + label = widget.getElementsByTagName("label")[0] + label = label.childNodes[0].data + outputList.append(self.templates.MENU_MENU_VAR % locals()) + else: + raise RuntimeError("Unexpected widgetClass for Menu: %s" % widgetClass) + + return outputList + + + def GenerateToolBarClass(self, windowClass, windowName, topWindow, vars): + outputList = [] + + # output the header + outputList.append(self.templates.TOOLBAR_CLASS_HEADER % locals()) + + # create an attribute for menus and menu items that have names + for widget in topWindow.getElementsByTagName("object"): + if not self.CheckAssignVar(widget): continue + widgetClass = widget.getAttribute("class") + widgetClass = re.sub("^wx", "", widgetClass) + widgetName = widget.getAttribute("name") + if widgetName != "" and widgetClass != "": + vars.append(widgetName) + if widgetClass == "tool": + outputList.append(self.templates.TOOLBAR_TOOL_VAR % locals()) + else: + raise RuntimeError("Unexpected widgetClass for ToolBar: %s" % widgetClass) + + return outputList + + + def GenerateWidgetClass(self, windowClass, windowName, topWindow, vars): + outputList = [] + + # output the header + outputList.append(self.templates.CLASS_HEADER % locals()) + + # Generate an attribute for each named item in the container + for widget in topWindow.getElementsByTagName("object"): + if not self.CheckAssignVar(widget): continue + widgetClass = widget.getAttribute("class") + widgetClass = re.sub("^wx", "", widgetClass) + widgetName = widget.getAttribute("name") + if widgetName != "" and widgetClass != "": + vars.append(widgetName) + if widgetClass not in \ + ['tool', 'unknown', 'notebookpage', 'separator', + 'sizeritem', 'Menu', 'MenuBar', 'MenuItem']: + outputList.append(self.templates.CREATE_WIDGET_VAR % locals()) + elif widgetClass == "MenuBar": + outputList.append(self.templates.FRAME_MENUBAR_VAR % locals()) + elif widgetClass == "MenuItem": + outputList.append(self.templates.FRAME_MENUBAR_MENUITEM_VAR % locals()) + elif widgetClass == "Menu": + label = widget.getElementsByTagName("label")[0] + label = label.childNodes[0].data + outputList.append(self.templates.FRAME_MENUBAR_MENU_VAR % locals()) + elif widgetClass == "ToolBar": + outputList.append(self.templates.FRAME_TOOLBAR_VAR % locals()) + elif widgetClass == "tool": + outputList.append(self.templates.FRAME_TOOLBAR_TOOL_VAR % locals()) + + return outputList + + #------------------------------------------------------------------- + + def GenerateSubclasses(self, resourceDocument): + outputList = [] + + objectNodes = resourceDocument.getElementsByTagName("object") + subclasses = set() + bases = {} + baseName = os.path.splitext(self.outputFilename)[0] + for node in objectNodes: + subclass = node.getAttribute('subclass') + if subclass: + module = subclass[:subclass.find('.')] + if module != baseName: continue + klass = node.getAttribute("class") + if subclass not in subclasses: + subclasses.add(subclass) + bases[subclass] = klass + else: + if klass != bases[subclass]: + print 'pywxrc: error: conflicting base classes for subclass %(subclass)s' \ + % subclass + + # Generate subclasses + for subclass in subclasses: + windowClass = bases[subclass] + subclass = re.sub("^\S+\.", "", subclass) + windowClass = re.sub("^wx", "", windowClass) + outputList.append(self.templates.SUBCLASS_HEADER % locals()) + outputList.append('\n') + + return "".join(outputList) + + #------------------------------------------------------------------- + + def GenerateEventHandlers(self, windowClass, windowName, topWindow, vars): + outputList = [] + + # Generate child event handlers + eventHandlers = [] + for elem in topWindow.getElementsByTagName("XRCED"): + try: + eventNode = elem.getElementsByTagName("events")[0] + except IndexError: + continue + events = eventNode.childNodes[0].data.split('|') + for event in events: + if elem.parentNode is topWindow: + eventHandler = "On%s" % event[4:].capitalize() + outputList.append(self.templates.BIND_EVENT % locals()) + eventHandlers.append(eventHandler) + else: + widget = elem.parentNode + widgetClass = widget.getAttribute("class") + widgetClass = re.sub("^wx", "", widgetClass) + widgetName = widget.getAttribute("name") + if not widgetName or not widgetClass: continue + eventObject = None + if widgetClass == "MenuItem" and windowClass != "MenuBar": + if widgetName[:2] == "wx": + eventObject = 'id=wx.%s' % re.sub("^wx", "", widgetName) + eventHandler = "On%s_%s" % (event[4:].capitalize(), widgetName) + if widgetName in vars: eventObject = "self.%s" % widgetName + else: + eventHandler = "On%s_%s" % (event[4:].capitalize(), widgetName) + if widgetName in vars: eventObject = "self.%s" % widgetName + if not eventObject: + eventObject = "id=xrc.XRCID('%s')" % widgetName + outputList.append(self.templates.BIND_WIDGET_EVENT % locals()) + eventHandlers.append(eventHandler) + outputList.append("\n") + + for eventHandler in eventHandlers: + block = "xrc%(windowName)s.%(eventHandler)s" % locals() + try: + outputList.append(self.blocks[block]) + except KeyError: + outputList.append(self.templates.CREATE_EVENT_HANDLER % locals()) + outputList.append("\n") + + outputList.append("\n") + return "".join(outputList) + + #------------------------------------------------------------------- + + def GenerateInitResourcesEmbedded(self, resourceFilename, resourceDocument): + outputList = [] + files = [] + + resourcePath = os.path.split(resourceFilename)[0] + memoryPath = self.GetMemoryFilename(os.path.splitext(os.path.split(resourceFilename)[1])[0]) + resourceFilename = self.GetMemoryFilename(os.path.split(resourceFilename)[1]) + + self.ReplaceFilenamesInXRC(resourceDocument.firstChild, files, resourcePath) + + filename = resourceFilename + fileData = resourceDocument.toxml() # what about this? encoding=resourceDocument.encoding) + outputList.append(self.templates.FILE_AS_STRING % locals()) + + for f in files: + filename = self.GetMemoryFilename(f) + fileData = self.FileToString(os.path.join(resourcePath, f)) + outputList.append(self.templates.FILE_AS_STRING % locals()) + + for f in [resourceFilename] + files: + filename = self.GetMemoryFilename(f) + outputList.append(self.templates.ADD_FILE_TO_MEMFS % locals()) + + outputList.append(self.templates.LOAD_RES_MEMFS % locals()) + + return "".join(outputList) + + #------------------------------------------------------------------- + + def GenerateInitResourcesFile(self, resourceFilename, resourceDocument): + # take only the filename portion out of resourceFilename + resourceFilename = os.path.split(resourceFilename)[1] + outputList = [] + outputList.append(self.templates.LOAD_RES_FILE % locals()) + return "".join(outputList) + + #------------------------------------------------------------------- + + def GetMemoryFilename(self, filename): + # Remove special chars from the filename + return re.sub(r"[^A-Za-z0-9_]", "_", filename) + + #------------------------------------------------------------------- + + def FileToString(self, filename): + outputList = [] + + buffer = open(filename, "rb").read() + fileLen = len(buffer) + + linelng = 0 + for i in xrange(fileLen): + s = buffer[i] + c = ord(s) + if s == '\n': + tmp = s + linelng = 0 + elif c < 32 or c > 127 or s == "'": + tmp = "\\x%02x" % c + elif s == "\\": + tmp = "\\\\" + else: + tmp = s + + if linelng > 70: + linelng = 0 + outputList.append("\\\n") + + outputList.append(tmp) + linelng += len(tmp) + + return "".join(outputList) + + #------------------------------------------------------------------- + + def NodeContainsFilename(self, node): + """ Does 'node' contain filename information at all? """ + + # Any bitmaps: + if node.nodeName == "bitmap": + return True + + if node.nodeName == "icon": + return True + + # URLs in wxHtmlWindow: + if node.nodeName == "url": + return True + + # wxBitmapButton: + parent = node.parentNode + if parent.__class__ != minidom.Document and \ + parent.getAttribute("class") == "wxBitmapButton" and \ + (node.nodeName == "focus" or node.nodeName == "disabled" or + node.nodeName == "selected"): + return True + + # wxBitmap or wxIcon toplevel resources: + if node.nodeName == "object": + klass = node.getAttribute("class") + if klass == "wxBitmap" or klass == "wxIcon": + return True + + return False + + #------------------------------------------------------------------- + + def ReplaceFilenamesInXRC(self, node, files, resourcePath): + """ Finds all files mentioned in resource file, e.g. <bitmap>filename</bitmap> + and replaces them with the memory filenames. + + Fills a list of the filenames found.""" + + # Is 'node' XML node element? + if node is None: return + if node.nodeType != minidom.Document.ELEMENT_NODE: return + + containsFilename = self.NodeContainsFilename(node); + + for n in node.childNodes: + + if (containsFilename and + (n.nodeType == minidom.Document.TEXT_NODE or + n.nodeType == minidom.Document.CDATA_SECTION_NODE)): + + filename = n.nodeValue + memoryFilename = self.GetMemoryFilename(filename) + n.nodeValue = memoryFilename + + if filename not in files: + files.append(filename) + + # Recurse into children + if n.nodeType == minidom.Document.ELEMENT_NODE: + self.ReplaceFilenamesInXRC(n, files, resourcePath); + + #------------------------------------------------------------------- + + def FindStringsInNode(self, parent): + def is_number(st): + try: + i = int(st) + return True + except ValueError: + return False + + strings = [] + if parent is None: + return strings; + + for child in parent.childNodes: + if ((parent.nodeType == parent.ELEMENT_NODE) and + # parent is an element, i.e. has subnodes... + (child.nodeType == child.TEXT_NODE or + child.nodeType == child.CDATA_SECTION_NODE) and + # ...it is textnode... + ( + parent.tagName == "label" or + (parent.tagName == "value" and + not is_number(child.nodeValue)) or + parent.tagName == "help" or + parent.tagName == "longhelp" or + parent.tagName == "tooltip" or + parent.tagName == "htmlcode" or + parent.tagName == "title" or + parent.tagName == "item" + )): + # ...and known to contain translatable string + if (parent.getAttribute("translate") != "0"): + strings.append(self.ConvertText(child.nodeValue)) + + # subnodes: + if child.nodeType == child.ELEMENT_NODE: + strings += self.FindStringsInNode(child) + + return strings + + #------------------------------------------------------------------- + + def ConvertText(self, st): + st2 = "" + dt = list(st) + + skipNext = False + for i in range(len(dt)): + if skipNext: + skipNext = False + continue + + if dt[i] == '_': + if dt[i+1] == '_': + st2 += '_' + skipNext = True + else: + st2 += '&' + elif dt[i] == '\n': + st2 += '\\n' + elif dt[i] == '\t': + st2 += '\\t' + elif dt[i] == '\r': + st2 += '\\r' + elif dt[i] == '\\': + if dt[i+1] not in ['n', 't', 'r']: + st2 += '\\\\' + else: + st2 += '\\' + elif dt[i] == '"': + st2 += '\\"' + else: + st2 += dt[i] + + return st2.encode("UTF-8") + + #------------------------------------------------------------------- + + # Replace editable block contents with previous + def ReplaceBlocks(self, input): + output = [] + block = None + blockLines = [] + for l in input.split('\n'): + if not block: + mo = reBeginBlock.match(l) + if mo and mo.groups()[0] in self.blocks: + block = mo.groups()[0] + output.append(self.blocks[block]) + else: + output.append(l + '\n') + else: + mo = reEndBlock.match(l) + if mo: + if mo.groups()[0] != block: + print "pywxrc: error: block mismatch: %s != %s" % (block, mo.groups()[0]) + block = None + return ''.join(output) + + #------------------------------------------------------------------- + + def _OpenOutputFile(self, outputFilename): + if outputFilename == "-": + outputFile = sys.stdout + else: + # Parse existing file to collect editable blocks + if os.path.isfile(outputFilename): + outputFile = open(outputFilename) + block = None + blockLines = [] + for l in outputFile.readlines(): + if not block: + mo = reBeginBlock.match(l) + if mo: + block = mo.groups()[0] + blockLines = [l] + else: + blockLines.append(l) + mo = reEndBlock.match(l) + if mo: + if mo.groups()[0] != block: + print "pywxrc: error: block mismatch: %s != %s" % (block, mo.groups()[0]) + self.blocks[block] = "".join(blockLines) + block = None + + try: + outputFile = open(outputFilename, "wt") + except IOError: + raise IOError("Can't write output to '%s'" % outputFilename) + return outputFile + + + + + +#--------------------------------------------------------------------------- + +def main(args=None): + if not args: + args = sys.argv[1:] + + resourceFilename = "" + outputFilename = None + embedResources = False + generateGetText = False + assignVariables = True + generatePython = False + + try: + opts, args = getopt.gnu_getopt(args, + "hpgevo:", + "help python gettext embed novar output=".split()) + except getopt.GetoptError, e: + print "\nError : %s\n" % str(e) + print __doc__ + sys.exit(1) + + # If there is no input file argument, show help and exit + if not args: + print __doc__ + print "No xrc input file was specified." + sys.exit(1) + + # Parse options and arguments + for opt, val in opts: + if opt in ["-h", "--help"]: + print __doc__ + sys.exit(1) + + if opt in ["-p", "--python"]: + generatePython = True + + if opt in ["-o", "--output"]: + outputFilename = val + + if opt in ["-e", "--embed"]: + embedResources = True + + if opt in ["-v", "--novar"]: + assignVariables = False + + if opt in ["-g", "--gettext"]: + generateGetText = True + + + # check for and expand any wildcards in the list of input files + inputFiles = [] + for arg in args: + inputFiles += glob.glob(arg) + + + comp = XmlResourceCompiler() + + try: + if generatePython: + if not outputFilename: + outputFilename = os.path.splitext(args[0])[0] + "_xrc.py" + comp.MakePythonModule(inputFiles, outputFilename, + embedResources, generateGetText, + assignVariables) + + elif generateGetText: + if not outputFilename: + outputFilename = '-' + comp.MakeGetTextOutput(inputFiles, outputFilename) + + else: + print __doc__ + print "One or both of -p, -g must be specified." + sys.exit(1) + + + except IOError, e: + print >>sys.stderr, "%s." % str(e) + else: + if outputFilename != "-": + print >>sys.stderr, "Resources written to %s." % outputFilename + +if __name__ == "__main__": + main(sys.argv[1:]) |