Poodletooth-iLand/panda/python/Lib/site-packages/wx/tools/pywxrc.py
2015-03-06 06:11:40 -06:00

933 lines
33 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
#
# Massive rework by Eli Golovinsky
#
# Editable blocks by Roman Rolinsky
#
# Copyright: (c) 2004 by Total Control Software, 2000 Vaclav Slavik
# Licence: wxWindows license
# Tags: phoenix-port
#----------------------------------------------------------------------
"""
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
from wx.lib.six import print_
#----------------------------------------------------------------------
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_(self.templates.FILE_HEADER, file=outputFile)
# 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_(subclasses.encode("UTF-8"), file=outputFile)
if classes:
classes = self.ReplaceBlocks(u"\n".join(classes))
print_(classes.encode("UTF-8"), file=outputFile)
print_(self.templates.INIT_RESOURE_HEADER, file=outputFile)
if embedResources:
print_(self.templates.PREPARE_MEMFS, file=outputFile)
resources = u"\n".join(resources)
print_(resources.encode("UTF-8"), file=outputFile)
if generateGetText:
# These have already been converted to utf-8...
gettextStrings = [' _("%s")' % s for s in gettextStrings]
gettextStrings = "\n".join(gettextStrings)
print_(self.templates.GETTEXT_DUMMY_FUNC % gettextStrings, file=outputFile)
#-------------------------------------------------------------------
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_("\n".join(strings), file=outputFile)
#-------------------------------------------------------------------
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 as exc:
print("\nError : %s\n" % str(exc))
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 as exc:
print_("%s." % str(exc), file=sys.stderr)
else:
if outputFilename != "-":
print_("Resources written to %s." % outputFilename, file=outputFilename)
if __name__ == "__main__":
main(sys.argv[1:])