]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/wx/tools/pywxrc.py
fix building/running of tex2rtf
[wxWidgets.git] / wxPython / wx / tools / pywxrc.py
index 2930272b4f349650e5ed1fb42bb982d97b8fadbb..9093b2e12591a64e78414a82f24c2b0a7b3e07e7 100644 (file)
@@ -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
           (see http://wiki.wxpython.org/index.cgi/pywxrc for more info)
 
 Usage: python pywxrc.py -h
-       python pywxrc.py <resource.xrc> [-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
 """
 
 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.
 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
 
 import wx
 import wx.xrc as xrc
@@ -54,7 +56,7 @@ def get_resources():
 
     CLASS_HEADER = """\
 class xrc%(windowName)s(wx.%(windowClass)s):
 
     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
         \"\"\" 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()
     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")
         get_resources().LoadOn%(windowClass)s(pre, parent, "%(windowName)s")
-        self.PreCreate()
         self.PostCreate(pre)
 
         # Define variables for the controls
         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\")
 """
 
         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():
     INIT_RESOURE_HEADER = """\
 # ------------------------ Resource data ----------------------
 
 def __init_resources():
+    global __res
+    __res = xrc.EmptyXmlResource()
 """
 
     LOAD_RES_FILE = """\
 """
 
     LOAD_RES_FILE = """\
-    global __res
-    __res = xrc.XmlResource('%(resourceFilename)s')
-"""
+    __res.Load('%(resourceFilename)s')"""
 
     FILE_AS_STRING = """\
     %(filename)s = '''\\
 %(fileData)s'''
 
 
     FILE_AS_STRING = """\
     %(filename)s = '''\\
 %(fileData)s'''
 
-
 """
 
     PREPARE_MEMFS = """\
 """
 
     PREPARE_MEMFS = """\
-    # Load all the strings as memory files
-    
     wx.FileSystem.AddHandler(wx.MemoryFSHandler())
 """
 
     wx.FileSystem.AddHandler(wx.MemoryFSHandler())
 """
 
@@ -104,12 +125,10 @@ def __init_resources():
 """
 
     LOAD_RES_MEMFS = """\
 """
 
     LOAD_RES_MEMFS = """\
-    global __res
-    __res = xrc.EmptyXmlResource()
     __res.Load('memory:XRC/%(memoryPath)s/%(resourceFilename)s')
 """
 
     __res.Load('memory:XRC/%(memoryPath)s/%(resourceFilename)s')
 """
 
-    GETTEXT_DUMMY_FUNC = """\
+    GETTEXT_DUMMY_FUNC = """
 # ----------------------- Gettext strings ---------------------
 
 def __gettext_strings():
 # ----------------------- Gettext strings ---------------------
 
 def __gettext_strings():
@@ -121,7 +140,7 @@ def __gettext_strings():
     
     def _(str): pass
     
     
     def _(str): pass
     
-%(gettextStrings)s
+%s
 """
 
 #----------------------------------------------------------------------
 """
 
 #----------------------------------------------------------------------
@@ -132,27 +151,66 @@ class XmlResourceCompiler:
 
     """This class generates Python code from XML resource files (XRC)."""
 
 
     """This class generates Python code from XML resource files (XRC)."""
 
-    def MakePythonModule(self, resourceFilename, outputFilename,
+    def MakePythonModule(self, inputFiles, outputFilename,
                          embedResources=False, generateGetText=False):
                          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.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:
         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:
 
         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")
             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.
             
             # 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")
                 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)
 
     #-------------------------------------------------------------------
 
             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 = []
     def GenerateInitResourcesEmbedded(self, resourceFilename, resourceDocument):
         outputList = []
-
-        outputList.append(self.templates.INIT_RESOURE_HEADER)
-
         files = []
 
         resourcePath = os.path.split(resourceFilename)[0]
         files = []
 
         resourcePath = os.path.split(resourceFilename)[0]
@@ -210,7 +261,7 @@ class XmlResourceCompiler:
         self.ReplaceFilenamesInXRC(resourceDocument.firstChild, files, resourcePath)
         
         filename = resourceFilename
         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:
         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())
 
             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())
         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 = []
         # 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)
 
         outputList.append(self.templates.LOAD_RES_FILE % locals())
         return "".join(outputList)
 
@@ -413,7 +461,22 @@ class XmlResourceCompiler:
             else:            
                 st2 += dt[i]
 
             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 = ""
 
 def main(args):
     resourceFilename = ""
-    outputFilename = ""
+    outputFilename = None
     embedResources = False
     generateGetText = False
     embedResources = False
     generateGetText = False
+    generatePython = False
 
     try:
 
     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
     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 __doc__
+        print "No xrc input file was specified."
         sys.exit(1)
 
     # Parse options and arguments
         sys.exit(1)
 
     # Parse options and arguments
@@ -445,6 +510,9 @@ def main(args):
             print __doc__
             sys.exit(1)
 
             print __doc__
             sys.exit(1)
 
+        if opt in ["-p", "--python"]:
+            generatePython = True
+
         if opt in ["-o", "--output"]:
             outputFilename = val
             
         if opt in ["-o", "--output"]:
             outputFilename = val
             
@@ -454,13 +522,33 @@ def main(args):
         if opt in ["-g", "--gettext"]:
             generateGetText = True
 
         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 = 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:
     except IOError, e:
         print >>sys.stderr, "%s." % str(e)
     else: