git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30439 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			715 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			715 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#----------------------------------------------------------------------
 | 
						|
# 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
 | 
						|
#
 | 
						|
# RCS-ID:      $Id$
 | 
						|
# Copyright:   (c) 2004 by Total Control Software, 2000 Vaclav Slavik
 | 
						|
# Licence:     wxWindows license
 | 
						|
#----------------------------------------------------------------------
 | 
						|
 | 
						|
"""
 | 
						|
pywxrc -- XML resource compiler
 | 
						|
 | 
						|
Usage: wxrc [-h] [-v] [-e] [-c] [-p] [-g] [-n <str>] [-o <str>] input file(s)...
 | 
						|
  -h, --help            show help message
 | 
						|
  -v, --verbose         be verbose
 | 
						|
  -e, --extra-cpp-code  output C++ header file with XRC derived classes
 | 
						|
  -c, --cpp-code        output C++ source rather than .xrs file
 | 
						|
  -p, --python-code     output wxPython source rather than .rsc file
 | 
						|
  -g, --gettext         output list of translatable strings (to stdout or file if -o used)
 | 
						|
  -n, --function str    C++/Python function name (with -c or -p) [InitXmlResource]
 | 
						|
  -o, --output str      output file [resource.xrs/cpp/py]
 | 
						|
"""
 | 
						|
 | 
						|
import sys, os, getopt, glob
 | 
						|
import wx
 | 
						|
import wx.xrc
 | 
						|
 | 
						|
 | 
						|
#----------------------------------------------------------------------
 | 
						|
 | 
						|
class XRCWidgetData:
 | 
						|
    def __init__(self, vname, vclass):
 | 
						|
        self.name = vname
 | 
						|
        self.klass = vclass
 | 
						|
    def GetName(self):
 | 
						|
        return self.name
 | 
						|
    def GetClass(self):
 | 
						|
        return self.klass
 | 
						|
 | 
						|
 | 
						|
#----------------------------------------------------------------------
 | 
						|
 | 
						|
class XRCWndClassData:
 | 
						|
    def __init__(self, className, parentClassName, node):
 | 
						|
        self.className = className
 | 
						|
        self.parentClassName = parentClassName
 | 
						|
        self.BrowseXmlNode(node.GetChildren())
 | 
						|
        self.wdata = []
 | 
						|
 | 
						|
 | 
						|
    def BrowseXmlNode(self, node):
 | 
						|
        while node:
 | 
						|
            if node.GetName() == "object" and node.HasProp("class") and node.HasProp("name"):
 | 
						|
                classVal = node.GetPropVal("class", "")
 | 
						|
                nameVal  = node.GetPropVal("name", "")
 | 
						|
                self.wdata.append(XRCWidgetData(nameVal, classVal))
 | 
						|
            children = node.GetChildren()
 | 
						|
            if children:
 | 
						|
                    self.BrowseXmlNode(children)
 | 
						|
            node = node.GetNext()
 | 
						|
 | 
						|
            
 | 
						|
    def GetWidgetData(self):
 | 
						|
        return self.wdata
 | 
						|
 | 
						|
    
 | 
						|
    def IsRealClass(self, name):
 | 
						|
        if name in ['tool', 'unknown', 'notebookpage', 'separator',
 | 
						|
                    'sizeritem', 'wxMenuItem']:
 | 
						|
            return False
 | 
						|
        else:
 | 
						|
            return True
 | 
						|
 | 
						|
 | 
						|
    def GenerateHeaderCode(self, file):
 | 
						|
        file.write("class %s : public %s {\nprotected:\n" % (self.className, self.parentClassName))
 | 
						|
 | 
						|
        for w in self.wdata:
 | 
						|
            if not self.IsRealClass(w.GetClass()):
 | 
						|
                continue
 | 
						|
            if not w.GetName():
 | 
						|
                continue
 | 
						|
            file.write(" " + w.GetClass() + "* " + w.GetName() + ";\n")
 | 
						|
        
 | 
						|
        file.write("\nprivate:\n void InitWidgetsFromXRC(){\n",
 | 
						|
                   + "  wxXmlResource::Get()->LoadObject(this,NULL,\""
 | 
						|
                   +  self.className
 | 
						|
                   +  "\",\""
 | 
						|
                   +  self.parentClassName
 | 
						|
                   +  "\");\n");
 | 
						|
            
 | 
						|
        for w in self.wdata:
 | 
						|
            if not self.IsRealClass(w.GetClass()):
 | 
						|
                continue
 | 
						|
            if not w.GetName():
 | 
						|
                continue
 | 
						|
            file.write( "  "
 | 
						|
                        + w.GetName()
 | 
						|
                        + " = XRCCTRL(*this,\""
 | 
						|
                        + w.GetName()
 | 
						|
                        + "\","
 | 
						|
                        + w.GetClass()
 | 
						|
                        + ");\n")
 | 
						|
 
 | 
						|
        file.write(" }\n")
 | 
						|
        file.write("public:\n"
 | 
						|
                   + self.className
 | 
						|
                   + "::"
 | 
						|
                   + self.className
 | 
						|
                   + "(){\n"
 | 
						|
                   + "  InitWidgetsFromXRC();\n"
 | 
						|
                   + " }\n"
 | 
						|
                   + "};\n")
 | 
						|
                
 | 
						|
 | 
						|
 | 
						|
#----------------------------------------------------------------------
 | 
						|
 | 
						|
 | 
						|
class XmlResApp:
 | 
						|
    def __init__(self):
 | 
						|
        self.flagVerbose = False
 | 
						|
        self.flagCPP = False
 | 
						|
        self.flagH = False
 | 
						|
        self.flagPython = False
 | 
						|
        self.flagGettext = False
 | 
						|
        self.parOutput = ""
 | 
						|
        self.parFuncname = "InitXmlResource"
 | 
						|
        self.parFiles = []
 | 
						|
        self.aXRCWndClassData = []
 | 
						|
        
 | 
						|
 | 
						|
    #--------------------------------------------------
 | 
						|
    def main(self, args):
 | 
						|
        try:
 | 
						|
            opts, args = getopt.getopt(args, "hvecpgn:o:",
 | 
						|
                 "help verbose extra-cpp-code cpp-code python-code gettext function= output=".split())
 | 
						|
        except getopt.GetoptError:
 | 
						|
            print __doc__
 | 
						|
            sys.exit(1)
 | 
						|
 | 
						|
        for opt, val in opts:
 | 
						|
            if opt in ["-h", "--help"]:
 | 
						|
                print __doc__
 | 
						|
                sys.exit(1)
 | 
						|
 | 
						|
            if opt in ["-v", "--verbose"]:
 | 
						|
                self.flagVerbose = True
 | 
						|
 | 
						|
            if opt in ["-e", "--extra-cpp-code"]:
 | 
						|
                self.flagH = True
 | 
						|
 | 
						|
            if opt in ["-c", "--cpp-code"]:
 | 
						|
                self.flagCPP = True
 | 
						|
 | 
						|
            if opt in ["-p", "--python-code"]:
 | 
						|
                self.flagPython = True
 | 
						|
 | 
						|
            if opt in ["-g", "--gettext"]:
 | 
						|
                self.flagGettext = True
 | 
						|
 | 
						|
            if opt in ["-n", "--function"]:
 | 
						|
                self.parFuncname = val
 | 
						|
 | 
						|
            if opt in ["-o", "--output"]:
 | 
						|
                self.parOutput = val
 | 
						|
 | 
						|
        if self.flagCPP + self.flagPython + self.flagGettext == 0:
 | 
						|
            print __doc__
 | 
						|
            print "\nYou must specify one of -c, -p or -g!\n"
 | 
						|
            sys.exit(1)
 | 
						|
 | 
						|
        if self.flagCPP + self.flagPython + self.flagGettext > 1:
 | 
						|
            print __doc__
 | 
						|
            print "\n-c, -p and -g are mutually exclusive, specify only 1!\n"
 | 
						|
            sys.exit(1)
 | 
						|
            
 | 
						|
 | 
						|
        if self.parOutput:
 | 
						|
            self.parOutput = os.path.normpath(self.parOutput)
 | 
						|
            self.parOutputPath = os.path.split(self.parOutput)[0]
 | 
						|
        else:
 | 
						|
            self.parOutputPath = "."
 | 
						|
            if self.flagCPP:
 | 
						|
                self.parOutput = "resource.cpp"
 | 
						|
            elif self.flagPython:
 | 
						|
                self.parOutput = "resource.py"
 | 
						|
            elif self.flagGettext:
 | 
						|
                self.parOutput = ""
 | 
						|
            else:
 | 
						|
                self.parOutput = "resource.xrs"
 | 
						|
 | 
						|
        if not args:
 | 
						|
            print __doc__
 | 
						|
            sys.exit(1)
 | 
						|
        for arg in args:
 | 
						|
            self.parFiles += glob.glob(arg)
 | 
						|
 | 
						|
        self.retCode = 0
 | 
						|
        if self.flagGettext:
 | 
						|
            self.OutputGettext()
 | 
						|
        else:
 | 
						|
            self.CompileRes()
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    #--------------------------------------------------
 | 
						|
    def CompileRes(self):
 | 
						|
        files = self.PrepareTempFiles()
 | 
						|
        try:
 | 
						|
            os.unlink(self.parOutput)
 | 
						|
        except OSError:
 | 
						|
            pass
 | 
						|
 | 
						|
        if not self.retCode:
 | 
						|
            if self.flagCPP:
 | 
						|
                self.MakePackageCPP(files)
 | 
						|
                if self.flagH:
 | 
						|
                    self.GenCPPHeader()
 | 
						|
 | 
						|
            elif self.flagPython:
 | 
						|
                self.MakePackagePython(files)
 | 
						|
 | 
						|
            else:
 | 
						|
                self.MakePackageZIP(files)
 | 
						|
 | 
						|
        self.DeleteTempFiles(files)
 | 
						|
 | 
						|
 | 
						|
    #--------------------------------------------------
 | 
						|
    def OutputGettext(self):
 | 
						|
        pass
 | 
						|
    
 | 
						|
 | 
						|
    #--------------------------------------------------
 | 
						|
    def GetInternalFileName(self, name, flist):
 | 
						|
        name2 = name;
 | 
						|
        name2 = name2.replace(":", "_")
 | 
						|
        name2 = name2.replace("/", "_")
 | 
						|
        name2 = name2.replace("\\", "_")
 | 
						|
        name2 = name2.replace("*", "_")
 | 
						|
        name2 = name2.replace("?", "_")
 | 
						|
 | 
						|
        s = os.path.split(self.parOutput)[1] + "$" + name2
 | 
						|
 | 
						|
        if os.path.exists(s) and s not in flist:
 | 
						|
            i = 0
 | 
						|
            while True:
 | 
						|
                s = os.path.split(self.parOutput)[1] + ("$%s%03d" % (name2, i))
 | 
						|
                if not os.path.exists(s) or s in flist:
 | 
						|
                    break
 | 
						|
        return s;
 | 
						|
   
 | 
						|
 | 
						|
    #--------------------------------------------------
 | 
						|
    def PrepareTempFiles(self):
 | 
						|
        flist = []
 | 
						|
        for f in self.parFiles:
 | 
						|
            if self.flagVerbose:
 | 
						|
                print "processing %s..." % f
 | 
						|
 | 
						|
            doc = wx.xrc.EmptyXmlDocument()
 | 
						|
            
 | 
						|
            if not doc.Load(f):
 | 
						|
                print "Error parsing file", f
 | 
						|
                self.retCode = 1
 | 
						|
                continue
 | 
						|
 | 
						|
            path, name = os.path.split(f)
 | 
						|
            name, ext = os.path.splitext(name)
 | 
						|
 | 
						|
            self.FindFilesInXML(doc.GetRoot(), flist, path)
 | 
						|
            if self.flagH:
 | 
						|
                node = doc.GetRoot().GetChildren()
 | 
						|
                while node:
 | 
						|
                    if node.GetName() == "object" and node.HasProp("class") and node.HasProp("name"):
 | 
						|
                        classVal = node.GetPropVal("class", "")
 | 
						|
                        nameVal  = node.GetPropVal("name", "")
 | 
						|
                        self.aXRCWndClassData.append(XRCWidgetData(nameVal, classVal))
 | 
						|
                    node = node.GetNext()
 | 
						|
            internalName = self.GetInternalFileName(f, flist)
 | 
						|
 | 
						|
            doc.Save(os.path.join(self.parOutputPath, internalName))
 | 
						|
            flist.append(internalName)
 | 
						|
 | 
						|
        return flist
 | 
						|
    
 | 
						|
    
 | 
						|
    #--------------------------------------------------
 | 
						|
    # Does 'node' contain filename information at all?
 | 
						|
    def NodeContainsFilename(self, node):
 | 
						|
        # Any bitmaps:
 | 
						|
        if node.GetName() == "bitmap":
 | 
						|
            return True
 | 
						|
 | 
						|
        if node.GetName() == "icon":
 | 
						|
            return True
 | 
						|
 | 
						|
        # URLs in wxHtmlWindow:
 | 
						|
        if node.GetName() == "url":
 | 
						|
            return True
 | 
						|
 | 
						|
        # wxBitmapButton:
 | 
						|
        parent = node.GetParent()
 | 
						|
        if parent != None and \
 | 
						|
           parent.GetPropVal("class", "") == "wxBitmapButton" and \
 | 
						|
           (node.GetName() == "focus" or node.etName() == "disabled" or
 | 
						|
            node.GetName() == "selected"):
 | 
						|
            return True
 | 
						|
 | 
						|
        # wxBitmap or wxIcon toplevel resources:
 | 
						|
        if node.GetName() == "object":
 | 
						|
            klass = node.GetPropVal("class", "")
 | 
						|
            if klass == "wxBitmap" or klass == "wxIcon":
 | 
						|
                return True
 | 
						|
 | 
						|
        return False
 | 
						|
 | 
						|
    #--------------------------------------------------
 | 
						|
    # find all files mentioned in structure, e.g. <bitmap>filename</bitmap>
 | 
						|
    def FindFilesInXML(self, node, flist, inputPath):
 | 
						|
        # Is 'node' XML node element?
 | 
						|
        if node is None: return
 | 
						|
        if node.GetType() != wx.xrc.XML_ELEMENT_NODE: return
 | 
						|
 | 
						|
        containsFilename = self.NodeContainsFilename(node);
 | 
						|
 | 
						|
        n = node.GetChildren()
 | 
						|
        while n:
 | 
						|
            if (containsFilename and
 | 
						|
                (n.GetType() == wx.xrc.XML_TEXT_NODE or
 | 
						|
                 n.GetType() == wx.xrc.XML_CDATA_SECTION_NODE)):
 | 
						|
                
 | 
						|
                if os.path.isabs(n.GetContent()) or inputPath == "":
 | 
						|
                    fullname = n.GetContent()
 | 
						|
                else:
 | 
						|
                    fullname = os.path.join(inputPath, n.GetContent())
 | 
						|
 | 
						|
                if self.flagVerbose:
 | 
						|
                    print "adding     %s..." % fullname
 | 
						|
 | 
						|
                filename = self.GetInternalFileName(n.GetContent(), flist)
 | 
						|
                n.SetContent(filename)
 | 
						|
 | 
						|
                if filename not in flist:
 | 
						|
                    flist.append(filename)
 | 
						|
                    
 | 
						|
                inp = open(fullname)
 | 
						|
                out = open(os.path.join(self.parOutputPath, filename), "w")
 | 
						|
                out.write(inp.read())
 | 
						|
 | 
						|
            # subnodes:
 | 
						|
            if n.GetType() == wx.xrc.XML_ELEMENT_NODE:
 | 
						|
                self.FindFilesInXML(n, flist, inputPath);
 | 
						|
 | 
						|
            n = n.GetNext()
 | 
						|
    
 | 
						|
 | 
						|
 | 
						|
    #--------------------------------------------------
 | 
						|
    def DeleteTempFiles(self, flist):
 | 
						|
        for f in flist:
 | 
						|
            os.unlink(os.path.join(self.parOutputPath, f))
 | 
						|
 | 
						|
 | 
						|
    #--------------------------------------------------
 | 
						|
    def MakePackageZIP(self, flist):
 | 
						|
        files = " ".join(flist)
 | 
						|
 | 
						|
        if self.flagVerbose:
 | 
						|
            print "compressing %s..." % self.parOutput
 | 
						|
 | 
						|
        cwd = os.getcwd()
 | 
						|
        os.chdir(self.parOutputPath)
 | 
						|
        cmd = "zip -9 -j "
 | 
						|
        if not self.flagVerbose:
 | 
						|
            cmd += "-q "
 | 
						|
        cmd += self.parOutput + " " + files
 | 
						|
 | 
						|
        from distutils.spawn import spawn
 | 
						|
        try:
 | 
						|
            spawn(cmd.split())
 | 
						|
            success = True
 | 
						|
        except:
 | 
						|
            success = False
 | 
						|
            
 | 
						|
        os.chdir(cwd)
 | 
						|
    
 | 
						|
        if not success:
 | 
						|
            print "Unable to execute zip program. Make sure it is in the path."
 | 
						|
            print "You can download it at http://www.cdrom.com/pub/infozip/"
 | 
						|
            self.retCode = 1
 | 
						|
    
 | 
						|
 | 
						|
    #--------------------------------------------------
 | 
						|
    def FileToCppArray(self, filename, num):
 | 
						|
        output = []
 | 
						|
        buffer = open(filename, "rb").read()
 | 
						|
        lng = len(buffer)
 | 
						|
 | 
						|
        output.append("static size_t xml_res_size_%d = %d;\n" % (num, lng))
 | 
						|
        output.append("static unsigned char xml_res_file_%d[] = {\n" % num)
 | 
						|
        # we cannot use string literals because MSVC is dumb wannabe compiler
 | 
						|
        # with arbitrary limitation to 2048 strings :(
 | 
						|
 | 
						|
        linelng = 0
 | 
						|
        for i in xrange(lng):
 | 
						|
            tmp = "%i" % ord(buffer[i])
 | 
						|
            if i != 0: output.append(',')
 | 
						|
            if linelng > 70:
 | 
						|
                linelng = 0
 | 
						|
                output.append("\n")
 | 
						|
        
 | 
						|
            output.append(tmp)
 | 
						|
            linelng += len(tmp)+1
 | 
						|
 | 
						|
        output.append("};\n\n")
 | 
						|
 | 
						|
        return "".join(output)
 | 
						|
 | 
						|
 | 
						|
    
 | 
						|
    #--------------------------------------------------
 | 
						|
    def MakePackageCPP(self, flist):
 | 
						|
        file = open(self.parOutput, "wt")
 | 
						|
 | 
						|
        if self.flagVerbose:
 | 
						|
            print "creating C++ source file %s..." % self.parOutput
 | 
						|
 | 
						|
        file.write("""\
 | 
						|
//
 | 
						|
// This file was automatically generated by wxrc, do not edit by hand.
 | 
						|
//
 | 
						|
 | 
						|
#include <wx/wxprec.h>
 | 
						|
 | 
						|
#ifdef __BORLANDC__
 | 
						|
    #pragma hdrstop
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef WX_PRECOMP
 | 
						|
    #include <wx/wx.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include <wx/filesys.h>
 | 
						|
#include <wx/fs_mem.h>
 | 
						|
#include <wx/xrc/xmlres.h>
 | 
						|
#include <wx/xrc/xh_all.h>
 | 
						|
 | 
						|
""")
 | 
						|
 | 
						|
        num = 0
 | 
						|
        for f in flist:
 | 
						|
            file.write(self.FileToCppArray(os.path.join(self.parOutputPath, f), num))
 | 
						|
            num += 1
 | 
						|
              
 | 
						|
 | 
						|
        file.write("void " + self.parFuncname + "()\n")
 | 
						|
        file.write("""\
 | 
						|
{
 | 
						|
 | 
						|
    // Check for memory FS. If not present, load the handler:
 | 
						|
    {
 | 
						|
        wxMemoryFSHandler::AddFile(wxT(\"XRC_resource/dummy_file\"), wxT(\"dummy one\"));
 | 
						|
        wxFileSystem fsys;
 | 
						|
        wxFSFile *f = fsys.OpenFile(wxT(\"memory:XRC_resource/dummy_file\"));
 | 
						|
        wxMemoryFSHandler::RemoveFile(wxT(\"XRC_resource/dummy_file\"));
 | 
						|
        if (f) delete f;
 | 
						|
        else wxFileSystem::AddHandler(new wxMemoryFSHandler);
 | 
						|
    }
 | 
						|
""");
 | 
						|
 | 
						|
        for i in range(len(flist)):
 | 
						|
            file.write("    wxMemoryFSHandler::AddFile(wxT(\"XRC_resource/" + flist[i])
 | 
						|
            file.write("\"), xml_res_file_%i, xml_res_size_%i);\n" %(i, i))
 | 
						|
 | 
						|
 | 
						|
        for i in range(len(self.parFiles)):
 | 
						|
            file.write("    wxXmlResource::Get()->Load(wxT(\"memory:XRC_resource/" +
 | 
						|
                       self.GetInternalFileName(self.parFiles[i], flist) +
 | 
						|
                       "\"));\n")
 | 
						|
    
 | 
						|
        file.write("}\n")
 | 
						|
        
 | 
						|
    
 | 
						|
    #--------------------------------------------------
 | 
						|
    def GenCPPHeader(self):
 | 
						|
        path, name = os.path.split(self.parOutput)
 | 
						|
        name, ext = os.path.splitext(name)
 | 
						|
        heaFileName = name+'.h'
 | 
						|
 | 
						|
        file = open(heaFileName, "wt")
 | 
						|
        file.write("""\
 | 
						|
//
 | 
						|
// This file was automatically generated by wxrc, do not edit by hand.
 | 
						|
//
 | 
						|
""");
 | 
						|
        file.write("#ifndef __"  + name + "_h__\n")
 | 
						|
        file.write("#define __"  + name + "_h__\n")
 | 
						|
 | 
						|
        for data in self.aXRCWndClassData:
 | 
						|
            data.GenerateHeaderCode(file)
 | 
						|
 | 
						|
        file.write("\nvoid \n" + self.parFuncname + "();\n#endif\n")
 | 
						|
        
 | 
						|
 | 
						|
    #--------------------------------------------------
 | 
						|
    def FileToPythonArray(self, filename, num):
 | 
						|
        output = []
 | 
						|
        buffer = open(filename, "rb").read()
 | 
						|
        lng = len(buffer)
 | 
						|
 | 
						|
        output.append("    xml_res_file_%d = '''\\\n" % num)
 | 
						|
 | 
						|
        linelng = 0
 | 
						|
        for i in xrange(lng):
 | 
						|
            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
 | 
						|
                output.append("\\\n")
 | 
						|
 | 
						|
            output.append(tmp)
 | 
						|
            linelng += len(tmp)
 | 
						|
 | 
						|
        output.append("'''\n\n")
 | 
						|
 | 
						|
        return "".join(output)
 | 
						|
 | 
						|
    #--------------------------------------------------
 | 
						|
    def MakePackagePython(self, flist):
 | 
						|
        file = open(self.parOutput, "wt")
 | 
						|
 | 
						|
        if self.flagVerbose:
 | 
						|
            print "creating Python source file %s..." % self.parOutput
 | 
						|
        
 | 
						|
        file.write("""\
 | 
						|
#
 | 
						|
# This file was automatically generated by wxrc, do not edit by hand.
 | 
						|
#
 | 
						|
 | 
						|
import wx
 | 
						|
import wx.xrc
 | 
						|
 | 
						|
""")
 | 
						|
        file.write("def " + self.parFuncname + "():\n")
 | 
						|
        
 | 
						|
        num = 0
 | 
						|
        for f in flist:
 | 
						|
            file.write(self.FileToPythonArray(os.path.join(self.parOutputPath, f), num))
 | 
						|
            num += 1
 | 
						|
 | 
						|
        file.write("""
 | 
						|
        
 | 
						|
    # check if the memory filesystem handler has been loaded yet, and load it if not
 | 
						|
    wx.MemoryFSHandler.AddFile('XRC_resource/dummy_file', 'dummy value')
 | 
						|
    fsys = wx.FileSystem()
 | 
						|
    f = fsys.OpenFile('memory:XRC_resource/dummy_file')
 | 
						|
    wx.MemoryFSHandler.RemoveFile('XRC_resource/dummy_file')
 | 
						|
    if f is not None:
 | 
						|
        f.Destroy()
 | 
						|
    else:
 | 
						|
        wx.FileSystem.AddHandler(wx.MemoryFSHandler())
 | 
						|
 | 
						|
    # load all the strings as memory files and load into XmlRes
 | 
						|
""")
 | 
						|
        
 | 
						|
        for i in range(len(flist)):
 | 
						|
            file.write("    wx.MemoryFSHandler.AddFile('XRC_resource/" + flist[i] +
 | 
						|
                       "', xml_res_file_%i)\n" % i)
 | 
						|
 | 
						|
        for pf in self.parFiles:
 | 
						|
            file.write("    wx.xrc.XmlResource.Get().Load('memory:XRC_resource/" +
 | 
						|
                       self.GetInternalFileName(pf, flist) + "')\n")
 | 
						|
            
 | 
						|
        
 | 
						|
    #--------------------------------------------------
 | 
						|
    def OutputGettext(self):
 | 
						|
        strings = self.FindStrings()
 | 
						|
 | 
						|
        if not self.parOutput:
 | 
						|
            out = sys.stdout
 | 
						|
        else:
 | 
						|
            out = open(self.parOutput, "wt")
 | 
						|
 | 
						|
        for st in strings:
 | 
						|
            out.write("_(\"%s\")\n" % st)
 | 
						|
            
 | 
						|
 | 
						|
        
 | 
						|
    #--------------------------------------------------
 | 
						|
    def FindStrings(self):
 | 
						|
        strings = []
 | 
						|
        for pf in self.parFiles:
 | 
						|
            if self.flagVerbose:
 | 
						|
                print "processing %s..." % pf
 | 
						|
 | 
						|
            doc = wx.xrc.EmptyXmlDocument()
 | 
						|
            if not doc.Load(pf):
 | 
						|
                print "Error parsing file", pf
 | 
						|
                self.retCode = 1
 | 
						|
                continue
 | 
						|
 | 
						|
            strings += self.FindStringsInNode(doc.GetRoot())
 | 
						|
 | 
						|
        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                
 | 
						|
             
 | 
						|
                
 | 
						|
    
 | 
						|
    #--------------------------------------------------
 | 
						|
    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;
 | 
						|
        child = parent.GetChildren()
 | 
						|
 | 
						|
        while child:
 | 
						|
            if ((parent.GetType() == wx.xrc.XML_ELEMENT_NODE) and
 | 
						|
                # parent is an element, i.e. has subnodes...
 | 
						|
                (child.GetType() == wx.xrc.XML_TEXT_NODE or
 | 
						|
                child.GetType() == wx.xrc.XML_CDATA_SECTION_NODE) and
 | 
						|
                # ...it is textnode...
 | 
						|
                (
 | 
						|
                    parent.GetName() == "label" or
 | 
						|
                    (parent.GetName() == "value" and
 | 
						|
                                   not is_number(child.GetContent())) or
 | 
						|
                    parent.GetName() == "help" or
 | 
						|
                    parent.GetName() == "longhelp" or
 | 
						|
                    parent.GetName() == "tooltip" or
 | 
						|
                    parent.GetName() == "htmlcode" or
 | 
						|
                    parent.GetName() == "title" or
 | 
						|
                    parent.GetName() == "item"
 | 
						|
                )):
 | 
						|
                # ...and known to contain translatable string
 | 
						|
                if (not self.flagGettext or
 | 
						|
                    parent.GetPropVal("translate", "1") != "0"):
 | 
						|
 | 
						|
                    strings.append(self.ConvertText(child.GetContent()))
 | 
						|
 | 
						|
            # subnodes:
 | 
						|
            if child.GetType() == wx.xrc.XML_ELEMENT_NODE:
 | 
						|
                strings += self.FindStringsInNode(child)
 | 
						|
 | 
						|
            child = child.GetNext()
 | 
						|
 | 
						|
        return strings
 | 
						|
 | 
						|
#---------------------------------------------------------------------------
 | 
						|
 | 
						|
def main():
 | 
						|
    XmlResApp().main(sys.argv[1:])
 | 
						|
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    main()
 | 
						|
 |