summaryrefslogtreecommitdiff
path: root/lib/python2.7/site-packages/wx-3.0-msw/wx/tools/pywxrc.py
diff options
context:
space:
mode:
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.py933
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:])