X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7e05216cce2522eb4687d8c03e339b27da9c3f4e..30e24d9dd5a5abf1c9a375ea259eb239b122b7f7:/wxPython/wx/tools/pywxrc.py?ds=sidebyside diff --git a/wxPython/wx/tools/pywxrc.py b/wxPython/wx/tools/pywxrc.py index 2930272b4f..9093b2e125 100644 --- a/wxPython/wx/tools/pywxrc.py +++ b/wxPython/wx/tools/pywxrc.py @@ -19,12 +19,13 @@ pywxrc -- Python XML resource compiler (see http://wiki.wxpython.org/index.cgi/pywxrc for more info) Usage: python pywxrc.py -h - python pywxrc.py [-e] [-g] [-o filename] + python pywxrc.py [-p] [-g] [-e] [-o filename] xrc input files... - -h, --help show help message - -e, --embed embed resources in the output file - -g, --gettext embed list of translatable strings in the output file - -o, --output output filename, or - for stdout + -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 + -o, --output output filename, or - for stdout """ import sys, os, getopt, glob, re @@ -37,6 +38,7 @@ import wx.xrc class PythonTemplates: FILE_HEADER = """\ # This file was automatically generated by pywxrc, do not edit by hand. +# -*- coding: UTF-8 -*- import wx import wx.xrc as xrc @@ -54,7 +56,7 @@ def get_resources(): CLASS_HEADER = """\ class xrc%(windowName)s(wx.%(windowClass)s): - def PreCreate(self): + 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 @@ -64,8 +66,8 @@ class xrc%(windowName)s(wx.%(windowClass)s): 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.PreCreate() self.PostCreate(pre) # Define variables for the controls @@ -75,27 +77,46 @@ class xrc%(windowName)s(wx.%(windowClass)s): self.%(widgetName)s = xrc.XRCCTRL(self, \"%(widgetName)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) + if hasattr(self, '_setCallbackInfo'): + self._setCallbackInfo(self, self.__class__) + + # Define variables for the menu items +""" + + CREATE_MENUITEM_VAR = """\ + self.%(widgetName)s = self.FindItemById(xrc.XRCID(\"%(widgetName)s\")) +""" + INIT_RESOURE_HEADER = """\ # ------------------------ Resource data ---------------------- def __init_resources(): + global __res + __res = xrc.EmptyXmlResource() """ LOAD_RES_FILE = """\ - global __res - __res = xrc.XmlResource('%(resourceFilename)s') -""" + __res.Load('%(resourceFilename)s')""" FILE_AS_STRING = """\ %(filename)s = '''\\ %(fileData)s''' - """ PREPARE_MEMFS = """\ - # Load all the strings as memory files - wx.FileSystem.AddHandler(wx.MemoryFSHandler()) """ @@ -104,12 +125,10 @@ def __init_resources(): """ LOAD_RES_MEMFS = """\ - global __res - __res = xrc.EmptyXmlResource() __res.Load('memory:XRC/%(memoryPath)s/%(resourceFilename)s') """ - GETTEXT_DUMMY_FUNC = """\ + GETTEXT_DUMMY_FUNC = """ # ----------------------- Gettext strings --------------------- def __gettext_strings(): @@ -121,7 +140,7 @@ def __gettext_strings(): def _(str): pass -%(gettextStrings)s +%s """ #---------------------------------------------------------------------- @@ -132,27 +151,66 @@ class XmlResourceCompiler: """This class generates Python code from XML resource files (XRC).""" - def MakePythonModule(self, resourceFilename, outputFilename, + def MakePythonModule(self, inputFiles, outputFilename, embedResources=False, generateGetText=False): - if outputFilename == "-": - outputFile = sys.stdout - else: - try: - outputFile = open(outputFilename, "wt") - except IOError: - raise IOError("Can't write output to '%s'" % outputFilename) - resourceDocument = minidom.parse(resourceFilename) + outputFile = self._OpenOutputFile(outputFilename) + + classes = [] + resources = [] + gettextStrings = [] + + # process all the inputFiles, collecting the output data + for inFile in inputFiles: + resourceDocument = minidom.parse(inFile) + 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 - print >>outputFile, self.GenerateClasses(resourceDocument) - + + # 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. + classes = u"\n".join(classes) + print >>outputFile, classes.encode("UTF-8") + + print >>outputFile, self.templates.INIT_RESOURE_HEADER if embedResources: - print >>outputFile, self.GenerateInitResourcesEmbedded(resourceFilename, resourceDocument) - else: - print >>outputFile, self.GenerateInitResourcesFile(resourceFilename, resourceDocument) + print >>outputFile, self.templates.PREPARE_MEMFS + resources = u"\n".join(resources) + print >>outputFile, resources.encode("UTF-8") if generateGetText: - print >>outputFile, self.GenerateGetText(resourceDocument) + # 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) #------------------------------------------------------------------- @@ -168,7 +226,11 @@ class XmlResourceCompiler: windowClass = topWindow.getAttribute("class") windowClass = re.sub("^wx", "", windowClass) windowName = topWindow.getAttribute("name") - outputList.append(self.templates.CLASS_HEADER % locals()) + + if windowClass in ["Menu", "MenuItem"]: + outputList.append(self.templates.MENU_CLASS_HEADER % locals()) + else: + outputList.append(self.templates.CLASS_HEADER % locals()) # Generate a variable for each control, and standard event handlers # for standard controls. @@ -176,31 +238,20 @@ class XmlResourceCompiler: widgetClass = widget.getAttribute("class") widgetClass = re.sub("^wx", "", widgetClass) widgetName = widget.getAttribute("name") - if (widgetName != "" and widgetClass != "" and - widgetClass not in - ['tool', 'unknown', 'notebookpage', - 'separator', 'sizeritem', 'MenuItem']): - outputList.append(self.templates.CREATE_WIDGET_VAR % locals()) + if (widgetName != "" and widgetClass != ""): + if widgetClass == "MenuItem": + outputList.append(self.templates.CREATE_MENUITEM_VAR % locals()) + elif widgetClass not in \ + ['tool', 'unknown', 'notebookpage', 'separator', 'sizeritem']: + outputList.append(self.templates.CREATE_WIDGET_VAR % locals()) outputList.append('\n\n') return "".join(outputList) #------------------------------------------------------------------- - def GenerateGetText(self, resourceDocument): - resource = resourceDocument.firstChild - strings = self.FindStringsInNode(resource) - strings = [' _("%s")\n' % s for s in strings] - gettextStrings = "".join(strings) - return self.templates.GETTEXT_DUMMY_FUNC % locals() - - #------------------------------------------------------------------- - def GenerateInitResourcesEmbedded(self, resourceFilename, resourceDocument): outputList = [] - - outputList.append(self.templates.INIT_RESOURE_HEADER) - files = [] resourcePath = os.path.split(resourceFilename)[0] @@ -210,7 +261,7 @@ class XmlResourceCompiler: self.ReplaceFilenamesInXRC(resourceDocument.firstChild, files, resourcePath) filename = resourceFilename - fileData = resourceDocument.toxml() + fileData = resourceDocument.toxml() # what about this? encoding=resourceDocument.encoding) outputList.append(self.templates.FILE_AS_STRING % locals()) for f in files: @@ -218,8 +269,6 @@ class XmlResourceCompiler: fileData = self.FileToString(os.path.join(resourcePath, f)) outputList.append(self.templates.FILE_AS_STRING % locals()) - outputList.append(self.templates.PREPARE_MEMFS % locals()) - for f in [resourceFilename] + files: filename = self.GetMemoryFilename(f) outputList.append(self.templates.ADD_FILE_TO_MEMFS % locals()) @@ -234,7 +283,6 @@ class XmlResourceCompiler: # take only the filename portion out of resourceFilename resourceFilename = os.path.split(resourceFilename)[1] outputList = [] - outputList.append(self.templates.INIT_RESOURE_HEADER) outputList.append(self.templates.LOAD_RES_FILE % locals()) return "".join(outputList) @@ -413,7 +461,22 @@ class XmlResourceCompiler: else: st2 += dt[i] - return st2 + return st2.encode("UTF-8") + + + #------------------------------------------------------------------- + + def _OpenOutputFile(self, outputFilename): + if outputFilename == "-": + outputFile = sys.stdout + else: + try: + outputFile = open(outputFilename, "wt") + except IOError: + raise IOError("Can't write output to '%s'" % outputFilename) + return outputFile + + @@ -421,22 +484,24 @@ class XmlResourceCompiler: def main(args): resourceFilename = "" - outputFilename = "" + outputFilename = None embedResources = False generateGetText = False + generatePython = False try: - opts, args = getopt.gnu_getopt(args, "hego:", "help embed gettext output=".split()) + opts, args = getopt.gnu_getopt(args, + "hpgeo:", + "help python gettext embed 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 args: - resourceFilename = args[0] - else: + if not args: print __doc__ + print "No xrc input file was specified." sys.exit(1) # Parse options and arguments @@ -445,6 +510,9 @@ def main(args): print __doc__ sys.exit(1) + if opt in ["-p", "--python"]: + generatePython = True + if opt in ["-o", "--output"]: outputFilename = val @@ -454,13 +522,33 @@ def main(args): if opt in ["-g", "--gettext"]: generateGetText = True - if outputFilename is None or outputFilename == "": - outputFilename = os.path.splitext(resourceFilename)[0] + "_xrc.py" + + # check for and expand any wildcards in the list of input files + inputFiles = [] + for arg in args: + inputFiles += glob.glob(arg) + comp = XmlResourceCompiler() try: - comp.MakePythonModule(resourceFilename, outputFilename, embedResources, generateGetText) + if generatePython: + if not outputFilename: + outputFilename = os.path.splitext(args[0])[0] + "_xrc.py" + comp.MakePythonModule(inputFiles, outputFilename, + embedResources, generateGetText) + + 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: