]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/tools/pywxrc.py
1 #----------------------------------------------------------------------
2 # Name: wx.tools.pywxrc
3 # Purpose: XML resource compiler
6 # Based on wxrc.cpp by Vaclav Slavik, Eduardo Marques
7 # Ported to Python in order to not require yet another
8 # binary in wxPython distributions
10 # Massive rework by Eli Golovinsky
13 # Copyright: (c) 2004 by Total Control Software, 2000 Vaclav Slavik
14 # Licence: wxWindows license
15 #----------------------------------------------------------------------
18 pywxrc -- Python XML resource compiler
20 Usage: python pywxrc.py -h
21 python pywxrc.py <resource.xrc> [-e] [-o filename]
23 -h, --help show help message
24 -e, --embed embed resources in output file
25 -o, --output output filename, or - for stdout
28 import sys
, os
, getopt
, glob
, re
29 import xml
.dom
.minidom
as minidom
33 #----------------------------------------------------------------------
35 class PythonTemplates
:
37 # This file was automatically generated by pywxrc, do not edit by hand.
45 \"\"\" This function provides access to the XML resources in this module.\"\"\"
54 class %(windowName)sBase(wx.%(windowClass)s):
56 \"\"\" This function is called during the class's initialization.
58 Override it for custom setup before the window is created usually to
59 set additional window styles using SetWindowStyle() and SetExtraStyle().\"\"\"
62 def __init__(self, parent):
63 # Two stage creation (see http://wiki.wxpython.org/index.cgi/TwoStageCreation)
64 pre = wx.Pre%(windowClass)s()
65 get_resources().LoadOn%(windowClass)s(pre, parent, "%(windowName)s")
69 # Define variables for the controls
72 CREATE_WIDGET_VAR
= """\
73 self.%(widgetName)s = xrc.XRCCTRL(self, \"%(widgetName)s\")
76 INIT_RESOURE_HEADER
= """\
77 # -------------------------------------------------------------
78 # ------------------------ Resource data ----------------------
79 # -------------------------------------------------------------
81 def __init_resources():
86 __res = xrc.XmlResource('%(resourceFilename)s')
97 # Load all the strings as memory files
99 wx.FileSystem.AddHandler(wx.MemoryFSHandler())
102 ADD_FILE_TO_MEMFS
= """\
103 wx.MemoryFSHandler.AddFile('XRC/%(memoryPath)s/%(filename)s', %(filename)s)
106 LOAD_RES_MEMFS
= """\
108 __res = xrc.EmptyXmlResource()
109 __res.Load('memory:XRC/%(memoryPath)s/%(resourceFilename)s')
112 #----------------------------------------------------------------------
114 class XmlResourceCompiler
:
116 templates
= PythonTemplates()
118 """This class generates Python code from XML resource files (XRC)."""
120 def MakePythonModule(self
, resourceFilename
, outputFilename
, embedResources
=False):
121 if outputFilename
== "-":
122 outputFile
= sys
.stdout
125 outputFile
= open(outputFilename
, "wt")
127 raise IOError("Can't write output to '%s'" % outputFilename
)
129 resourceDocument
= minidom
.parse(resourceFilename
)
130 print >>outputFile
, self
.templates
.FILE_HEADER
131 print >>outputFile
, self
.GenerateClasses(resourceDocument
)
134 print >>outputFile
, self
.GenerateInitResourcesEmbedded(resourceFilename
, resourceDocument
)
136 print >>outputFile
, self
.GenerateInitResourcesFile(resourceFilename
, resourceDocument
)
138 #-------------------------------------------------------------------
140 def GenerateClasses(self
, resourceDocument
):
143 resource
= resourceDocument
.firstChild
144 topWindows
= [e
for e
in resource
.childNodes
145 if e
.nodeType
== e
.ELEMENT_NODE
and e
.tagName
== "object"]
147 # Generate a class for each top-window object (Frame, Panel, Dialog, etc.)
148 for topWindow
in topWindows
:
149 windowClass
= topWindow
.getAttribute("class")
150 windowClass
= re
.sub("^wx", "", windowClass
)
151 windowName
= topWindow
.getAttribute("name")
152 outputList
.append(self
.templates
.CLASS_HEADER
% locals())
154 # Generate a variable for each control, and standard event handlers
155 # for standard controls.
156 for widget
in topWindow
.getElementsByTagName("object"):
157 widgetClass
= widget
.getAttribute("class")
158 widgetClass
= re
.sub("^wx", "", widgetClass
)
159 widgetName
= widget
.getAttribute("name")
160 if (widgetName
!= "" and widgetClass
!= "" and
162 ['tool', 'unknown', 'notebookpage',
163 'separator', 'sizeritem', 'MenuItem']):
164 outputList
.append(self
.templates
.CREATE_WIDGET_VAR
% locals())
165 outputList
.append('\n\n')
167 return "".join(outputList
)
169 #-------------------------------------------------------------------
171 def GenerateInitResourcesEmbedded(self
, resourceFilename
, resourceDocument
):
174 outputList
.append(self
.templates
.INIT_RESOURE_HEADER
)
178 resourcePath
= os
.path
.split(resourceFilename
)[0]
179 memoryPath
= self
.GetMemoryFilename(os
.path
.splitext(os
.path
.split(resourceFilename
)[1])[0])
180 resourceFilename
= self
.GetMemoryFilename(os
.path
.split(resourceFilename
)[1])
182 self
.ReplaceFilenamesInXRC(resourceDocument
.firstChild
, files
, resourcePath
)
184 filename
= resourceFilename
185 fileData
= resourceDocument
.toxml()
186 outputList
.append(self
.templates
.FILE_AS_STRING
% locals())
189 filename
= self
.GetMemoryFilename(f
)
190 fileData
= self
.FileToString(os
.path
.join(resourcePath
, f
))
191 outputList
.append(self
.templates
.FILE_AS_STRING
% locals())
193 outputList
.append(self
.templates
.PREPARE_MEMFS
% locals())
195 for f
in [resourceFilename
] + files
:
196 filename
= self
.GetMemoryFilename(f
)
197 outputList
.append(self
.templates
.ADD_FILE_TO_MEMFS
% locals())
199 outputList
.append(self
.templates
.LOAD_RES_MEMFS
% locals())
201 return "".join(outputList
)
203 #-------------------------------------------------------------------
205 def GenerateInitResourcesFile(self
, resourceFilename
, resourceDocument
):
207 outputList
.append(self
.templates
.INIT_RESOURE_HEADER
)
208 outputList
.append(self
.templates
.LOAD_RES_FILE
% locals())
209 return "".join(outputList
)
211 #-------------------------------------------------------------------
213 def GetMemoryFilename(self
, filename
):
214 # Remove special chars from the filename
215 return re
.sub(r
"[^A-Za-z0-9_]", "_", filename
)
217 #-------------------------------------------------------------------
219 def FileToString(self
, filename
):
222 buffer = open(filename
, "rb").read()
223 fileLen
= len(buffer)
226 for i
in xrange(fileLen
):
232 elif c
< 32 or c
> 127 or s
== "'":
241 outputList
.append("\\\n")
243 outputList
.append(tmp
)
246 return "".join(outputList
)
248 #-------------------------------------------------------------------
250 def NodeContainsFilename(self
, node
):
251 """ Does 'node' contain filename information at all? """
254 if node
.nodeName
== "bitmap":
257 if node
.nodeName
== "icon":
260 # URLs in wxHtmlWindow:
261 if node
.nodeName
== "url":
265 parent
= node
.parentNode
266 if parent
.__class
__ != minidom
.Document
and \
267 parent
.getAttribute("class") == "wxBitmapButton" and \
268 (node
.nodeName
== "focus" or node
.nodeName
== "disabled" or
269 node
.nodeName
== "selected"):
272 # wxBitmap or wxIcon toplevel resources:
273 if node
.nodeName
== "object":
274 klass
= node
.getAttribute("class")
275 if klass
== "wxBitmap" or klass
== "wxIcon":
280 #-------------------------------------------------------------------
282 def ReplaceFilenamesInXRC(self
, node
, files
, resourcePath
):
283 """ Finds all files mentioned in resource file, e.g. <bitmap>filename</bitmap>
284 and replaces them with the memory filenames.
286 Fills a list of the filenames found."""
288 # Is 'node' XML node element?
289 if node
is None: return
290 if node
.nodeType
!= minidom
.Document
.ELEMENT_NODE
: return
292 containsFilename
= self
.NodeContainsFilename(node
);
294 for n
in node
.childNodes
:
296 if (containsFilename
and
297 (n
.nodeType
== minidom
.Document
.TEXT_NODE
or
298 n
.nodeType
== minidom
.Document
.CDATA_SECTION_NODE
)):
300 filename
= n
.nodeValue
301 memoryFilename
= self
.GetMemoryFilename(filename
)
302 n
.nodeValue
= memoryFilename
304 if filename
not in files
:
305 files
.append(filename
)
307 # Recurse into children
308 if n
.nodeType
== minidom
.Document
.ELEMENT_NODE
:
309 self
.ReplaceFilenamesInXRC(n
, files
, resourcePath
);
311 #---------------------------------------------------------------------------
314 resourceFilename
= ""
316 embedResources
= False
319 opts
, args
= getopt
.gnu_getopt(args
, "heo:", "help embed output=".split())
320 except getopt
.GetoptError
:
324 # If there is no input file argument, show help and exit
326 resourceFilename
= args
[0]
331 # Parse options and arguments
332 for opt
, val
in opts
:
333 if opt
in ["-h", "--help"]:
337 if opt
in ["-o", "--output"]:
340 if opt
in ["-e", "--embed"]:
341 embedResources
= True
343 if outputFilename
is None or outputFilename
== "":
344 outputFilename
= os
.path
.splitext(resourceFilename
)[0] + "_xrc.py"
346 comp
= XmlResourceCompiler()
349 comp
.MakePythonModule(resourceFilename
, outputFilename
, embedResources
)
351 print >>sys
.stderr
, "%s." % str(e
)
353 if outputFilename
!= "-":
354 print >>sys
.stderr
, "Resources written to %s." % outputFilename
356 if __name__
== "__main__":