]>
Commit | Line | Data |
---|---|---|
2e0ae50e RD |
1 | #---------------------------------------------------------------------- |
2 | # Name: wx.tools.pywxrc | |
3 | # Purpose: XML resource compiler | |
4 | # | |
5 | # Author: Robin Dunn | |
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 | |
9 | # | |
73b2a9a7 RD |
10 | # Massive rework by Eli Golovinsky |
11 | # | |
2e0ae50e RD |
12 | # RCS-ID: $Id$ |
13 | # Copyright: (c) 2004 by Total Control Software, 2000 Vaclav Slavik | |
14 | # Licence: wxWindows license | |
15 | #---------------------------------------------------------------------- | |
16 | ||
17 | """ | |
73b2a9a7 | 18 | pywxrc -- Python XML resource compiler |
7e05216c | 19 | (see http://wiki.wxpython.org/index.cgi/pywxrc for more info) |
73b2a9a7 RD |
20 | |
21 | Usage: python pywxrc.py -h | |
0fe9c329 | 22 | python pywxrc.py [-p] [-g] [-e] [-o filename] xrc input files... |
73b2a9a7 | 23 | |
0fe9c329 RD |
24 | -h, --help show help message |
25 | -p, --python generate python module | |
26 | -g, --gettext output list of translatable strings (may be combined with -p) | |
27 | -e, --embed embed XRC resources in the output file | |
28 | -o, --output output filename, or - for stdout | |
2e0ae50e RD |
29 | """ |
30 | ||
73b2a9a7 RD |
31 | import sys, os, getopt, glob, re |
32 | import xml.dom.minidom as minidom | |
2e0ae50e RD |
33 | import wx |
34 | import wx.xrc | |
35 | ||
2e0ae50e RD |
36 | #---------------------------------------------------------------------- |
37 | ||
73b2a9a7 RD |
38 | class PythonTemplates: |
39 | FILE_HEADER = """\ | |
40 | # This file was automatically generated by pywxrc, do not edit by hand. | |
10383fe2 | 41 | # -*- coding: UTF-8 -*- |
2e0ae50e | 42 | |
73b2a9a7 RD |
43 | import wx |
44 | import wx.xrc as xrc | |
2e0ae50e | 45 | |
73b2a9a7 | 46 | __res = None |
2e0ae50e | 47 | |
73b2a9a7 RD |
48 | def get_resources(): |
49 | \"\"\" This function provides access to the XML resources in this module.\"\"\" | |
50 | global __res | |
51 | if __res == None: | |
52 | __init_resources() | |
53 | return __res | |
2e0ae50e | 54 | |
73b2a9a7 | 55 | """ |
2e0ae50e | 56 | |
73b2a9a7 | 57 | CLASS_HEADER = """\ |
7e05216c | 58 | class xrc%(windowName)s(wx.%(windowClass)s): |
cf952100 | 59 | def PreCreate(self, pre): |
73b2a9a7 | 60 | \"\"\" This function is called during the class's initialization. |
2e0ae50e | 61 | |
73b2a9a7 RD |
62 | Override it for custom setup before the window is created usually to |
63 | set additional window styles using SetWindowStyle() and SetExtraStyle().\"\"\" | |
64 | pass | |
2e0ae50e | 65 | |
73b2a9a7 RD |
66 | def __init__(self, parent): |
67 | # Two stage creation (see http://wiki.wxpython.org/index.cgi/TwoStageCreation) | |
68 | pre = wx.Pre%(windowClass)s() | |
cf952100 | 69 | self.PreCreate(pre) |
73b2a9a7 | 70 | get_resources().LoadOn%(windowClass)s(pre, parent, "%(windowName)s") |
73b2a9a7 | 71 | self.PostCreate(pre) |
2e0ae50e | 72 | |
73b2a9a7 RD |
73 | # Define variables for the controls |
74 | """ | |
2e0ae50e | 75 | |
73b2a9a7 RD |
76 | CREATE_WIDGET_VAR = """\ |
77 | self.%(widgetName)s = xrc.XRCCTRL(self, \"%(widgetName)s\") | |
78 | """ | |
2e0ae50e | 79 | |
cffdf649 RD |
80 | MENU_CLASS_HEADER = """\ |
81 | class xrc%(windowName)s(wx.%(windowClass)s): | |
82 | def __init__(self): | |
83 | pre = get_resources().LoadMenu("%(windowName)s") | |
84 | ||
85 | # This is a copy of Robin's PostCreate voodoo magic in wx.Window that | |
86 | # relinks the self object with the menu object. | |
87 | self.this = pre.this | |
88 | self.thisown = pre.thisown | |
89 | pre.thisown = 0 | |
90 | if hasattr(self, '_setOORInfo'): | |
91 | self._setOORInfo(self) | |
92 | if hasattr(self, '_setCallbackInfo'): | |
93 | self._setCallbackInfo(self, self.__class__) | |
94 | ||
95 | # Define variables for the menu items | |
96 | """ | |
97 | ||
98 | CREATE_MENUITEM_VAR = """\ | |
99 | self.%(widgetName)s = self.FindItemById(xrc.XRCID(\"%(widgetName)s\")) | |
100 | """ | |
101 | ||
73b2a9a7 | 102 | INIT_RESOURE_HEADER = """\ |
73b2a9a7 | 103 | # ------------------------ Resource data ---------------------- |
2e0ae50e | 104 | |
73b2a9a7 | 105 | def __init_resources(): |
0fe9c329 RD |
106 | global __res |
107 | __res = xrc.EmptyXmlResource() | |
73b2a9a7 | 108 | """ |
2e0ae50e | 109 | |
73b2a9a7 | 110 | LOAD_RES_FILE = """\ |
0fe9c329 | 111 | __res.Load('%(resourceFilename)s')""" |
2e0ae50e | 112 | |
73b2a9a7 RD |
113 | FILE_AS_STRING = """\ |
114 | %(filename)s = '''\\ | |
115 | %(fileData)s''' | |
2e0ae50e | 116 | |
73b2a9a7 | 117 | """ |
2e0ae50e | 118 | |
73b2a9a7 | 119 | PREPARE_MEMFS = """\ |
73b2a9a7 RD |
120 | wx.FileSystem.AddHandler(wx.MemoryFSHandler()) |
121 | """ | |
2e0ae50e | 122 | |
73b2a9a7 RD |
123 | ADD_FILE_TO_MEMFS = """\ |
124 | wx.MemoryFSHandler.AddFile('XRC/%(memoryPath)s/%(filename)s', %(filename)s) | |
125 | """ | |
2e0ae50e | 126 | |
73b2a9a7 | 127 | LOAD_RES_MEMFS = """\ |
73b2a9a7 RD |
128 | __res.Load('memory:XRC/%(memoryPath)s/%(resourceFilename)s') |
129 | """ | |
2e0ae50e | 130 | |
0fe9c329 | 131 | GETTEXT_DUMMY_FUNC = """ |
7e05216c RD |
132 | # ----------------------- Gettext strings --------------------- |
133 | ||
134 | def __gettext_strings(): | |
135 | # This is a dummy function that lists all the strings that are used in | |
136 | # the XRC file in the _("a string") format to be recognized by GNU | |
137 | # gettext utilities (specificaly the xgettext utility) and the | |
138 | # mki18n.py script. For more information see: | |
139 | # http://wiki.wxpython.org/index.cgi/Internationalization | |
140 | ||
141 | def _(str): pass | |
142 | ||
0fe9c329 | 143 | %s |
7e05216c RD |
144 | """ |
145 | ||
73b2a9a7 | 146 | #---------------------------------------------------------------------- |
2e0ae50e | 147 | |
73b2a9a7 RD |
148 | class XmlResourceCompiler: |
149 | ||
150 | templates = PythonTemplates() | |
2e0ae50e | 151 | |
73b2a9a7 | 152 | """This class generates Python code from XML resource files (XRC).""" |
2e0ae50e | 153 | |
0fe9c329 | 154 | def MakePythonModule(self, inputFiles, outputFilename, |
7e05216c | 155 | embedResources=False, generateGetText=False): |
2e0ae50e | 156 | |
0fe9c329 RD |
157 | outputFile = self._OpenOutputFile(outputFilename) |
158 | ||
159 | classes = [] | |
160 | resources = [] | |
161 | gettextStrings = [] | |
162 | ||
163 | # process all the inputFiles, collecting the output data | |
164 | for inFile in inputFiles: | |
165 | resourceDocument = minidom.parse(inFile) | |
166 | classes.append(self.GenerateClasses(resourceDocument)) | |
167 | ||
168 | if embedResources: | |
169 | res = self.GenerateInitResourcesEmbedded(inFile, resourceDocument) | |
170 | else: | |
171 | res = self.GenerateInitResourcesFile(inFile, resourceDocument) | |
172 | resources.append(res) | |
173 | ||
174 | if generateGetText: | |
175 | gettextStrings += self.FindStringsInNode(resourceDocument.firstChild) | |
176 | ||
177 | # now write it all out | |
73b2a9a7 | 178 | print >>outputFile, self.templates.FILE_HEADER |
10383fe2 RD |
179 | |
180 | # Note: Technically it is not legal to have anything other | |
181 | # than ascii for class and variable names, but since the user | |
182 | # can create the XML with non-ascii names we'll go ahead and | |
183 | # allow for it here, and then let Python complain about it | |
184 | # later when they try to run the program. | |
185 | classes = u"\n".join(classes) | |
186 | print >>outputFile, classes.encode("UTF-8") | |
0fe9c329 RD |
187 | |
188 | print >>outputFile, self.templates.INIT_RESOURE_HEADER | |
73b2a9a7 | 189 | if embedResources: |
0fe9c329 | 190 | print >>outputFile, self.templates.PREPARE_MEMFS |
10383fe2 RD |
191 | resources = u"\n".join(resources) |
192 | print >>outputFile, resources.encode("UTF-8") | |
2e0ae50e | 193 | |
7e05216c | 194 | if generateGetText: |
10383fe2 | 195 | # These have already been converted to utf-8... |
0fe9c329 RD |
196 | gettextStrings = [' _("%s")' % s for s in gettextStrings] |
197 | gettextStrings = "\n".join(gettextStrings) | |
198 | print >>outputFile, self.templates.GETTEXT_DUMMY_FUNC % gettextStrings | |
199 | ||
200 | #------------------------------------------------------------------- | |
201 | ||
202 | def MakeGetTextOutput(self, inputFiles, outputFilename): | |
203 | """ | |
204 | Just output the gettext strings by themselves, with no other | |
205 | code generation. | |
206 | """ | |
207 | outputFile = self._OpenOutputFile(outputFilename) | |
208 | for inFile in inputFiles: | |
209 | resourceDocument = minidom.parse(inFile) | |
210 | resource = resourceDocument.firstChild | |
211 | strings = self.FindStringsInNode(resource) | |
212 | strings = ['_("%s");' % s for s in strings] | |
213 | print >>outputFile, "\n".join(strings) | |
7e05216c | 214 | |
73b2a9a7 | 215 | #------------------------------------------------------------------- |
2e0ae50e | 216 | |
73b2a9a7 RD |
217 | def GenerateClasses(self, resourceDocument): |
218 | outputList = [] | |
219 | ||
220 | resource = resourceDocument.firstChild | |
221 | topWindows = [e for e in resource.childNodes | |
222 | if e.nodeType == e.ELEMENT_NODE and e.tagName == "object"] | |
223 | ||
224 | # Generate a class for each top-window object (Frame, Panel, Dialog, etc.) | |
225 | for topWindow in topWindows: | |
226 | windowClass = topWindow.getAttribute("class") | |
227 | windowClass = re.sub("^wx", "", windowClass) | |
228 | windowName = topWindow.getAttribute("name") | |
cffdf649 | 229 | |
93894584 | 230 | if windowClass in ["Menu", "MenuItem"]: |
cffdf649 RD |
231 | outputList.append(self.templates.MENU_CLASS_HEADER % locals()) |
232 | else: | |
233 | outputList.append(self.templates.CLASS_HEADER % locals()) | |
2e0ae50e | 234 | |
73b2a9a7 RD |
235 | # Generate a variable for each control, and standard event handlers |
236 | # for standard controls. | |
237 | for widget in topWindow.getElementsByTagName("object"): | |
238 | widgetClass = widget.getAttribute("class") | |
239 | widgetClass = re.sub("^wx", "", widgetClass) | |
240 | widgetName = widget.getAttribute("name") | |
cffdf649 RD |
241 | if (widgetName != "" and widgetClass != ""): |
242 | if widgetClass == "MenuItem": | |
243 | outputList.append(self.templates.CREATE_MENUITEM_VAR % locals()) | |
244 | elif widgetClass not in \ | |
245 | ['tool', 'unknown', 'notebookpage', 'separator', 'sizeritem']: | |
246 | outputList.append(self.templates.CREATE_WIDGET_VAR % locals()) | |
73b2a9a7 | 247 | outputList.append('\n\n') |
2e0ae50e | 248 | |
73b2a9a7 | 249 | return "".join(outputList) |
2e0ae50e | 250 | |
73b2a9a7 | 251 | #------------------------------------------------------------------- |
2e0ae50e | 252 | |
73b2a9a7 RD |
253 | def GenerateInitResourcesEmbedded(self, resourceFilename, resourceDocument): |
254 | outputList = [] | |
73b2a9a7 | 255 | files = [] |
2e0ae50e | 256 | |
73b2a9a7 RD |
257 | resourcePath = os.path.split(resourceFilename)[0] |
258 | memoryPath = self.GetMemoryFilename(os.path.splitext(os.path.split(resourceFilename)[1])[0]) | |
259 | resourceFilename = self.GetMemoryFilename(os.path.split(resourceFilename)[1]) | |
260 | ||
261 | self.ReplaceFilenamesInXRC(resourceDocument.firstChild, files, resourcePath) | |
262 | ||
263 | filename = resourceFilename | |
cffdf649 | 264 | fileData = resourceDocument.toxml() # what about this? encoding=resourceDocument.encoding) |
73b2a9a7 | 265 | outputList.append(self.templates.FILE_AS_STRING % locals()) |
2e0ae50e | 266 | |
73b2a9a7 RD |
267 | for f in files: |
268 | filename = self.GetMemoryFilename(f) | |
269 | fileData = self.FileToString(os.path.join(resourcePath, f)) | |
270 | outputList.append(self.templates.FILE_AS_STRING % locals()) | |
2e0ae50e | 271 | |
73b2a9a7 RD |
272 | for f in [resourceFilename] + files: |
273 | filename = self.GetMemoryFilename(f) | |
274 | outputList.append(self.templates.ADD_FILE_TO_MEMFS % locals()) | |
275 | ||
276 | outputList.append(self.templates.LOAD_RES_MEMFS % locals()) | |
2e0ae50e | 277 | |
73b2a9a7 RD |
278 | return "".join(outputList) |
279 | ||
280 | #------------------------------------------------------------------- | |
2e0ae50e | 281 | |
73b2a9a7 | 282 | def GenerateInitResourcesFile(self, resourceFilename, resourceDocument): |
7e05216c RD |
283 | # take only the filename portion out of resourceFilename |
284 | resourceFilename = os.path.split(resourceFilename)[1] | |
73b2a9a7 | 285 | outputList = [] |
73b2a9a7 RD |
286 | outputList.append(self.templates.LOAD_RES_FILE % locals()) |
287 | return "".join(outputList) | |
2e0ae50e | 288 | |
73b2a9a7 | 289 | #------------------------------------------------------------------- |
2e0ae50e | 290 | |
73b2a9a7 RD |
291 | def GetMemoryFilename(self, filename): |
292 | # Remove special chars from the filename | |
293 | return re.sub(r"[^A-Za-z0-9_]", "_", filename) | |
2e0ae50e | 294 | |
73b2a9a7 | 295 | #------------------------------------------------------------------- |
2e0ae50e | 296 | |
73b2a9a7 RD |
297 | def FileToString(self, filename): |
298 | outputList = [] | |
299 | ||
2e0ae50e | 300 | buffer = open(filename, "rb").read() |
73b2a9a7 | 301 | fileLen = len(buffer) |
2e0ae50e RD |
302 | |
303 | linelng = 0 | |
73b2a9a7 | 304 | for i in xrange(fileLen): |
2e0ae50e RD |
305 | s = buffer[i] |
306 | c = ord(s) | |
307 | if s == '\n': | |
308 | tmp = s | |
309 | linelng = 0 | |
310 | elif c < 32 or c > 127 or s == "'": | |
311 | tmp = "\\x%02x" % c | |
312 | elif s == "\\": | |
313 | tmp = "\\\\" | |
314 | else: | |
315 | tmp = s | |
316 | ||
317 | if linelng > 70: | |
318 | linelng = 0 | |
73b2a9a7 RD |
319 | outputList.append("\\\n") |
320 | ||
321 | outputList.append(tmp) | |
2e0ae50e | 322 | linelng += len(tmp) |
73b2a9a7 RD |
323 | |
324 | return "".join(outputList) | |
325 | ||
326 | #------------------------------------------------------------------- | |
2e0ae50e | 327 | |
73b2a9a7 RD |
328 | def NodeContainsFilename(self, node): |
329 | """ Does 'node' contain filename information at all? """ | |
2e0ae50e | 330 | |
73b2a9a7 RD |
331 | # Any bitmaps: |
332 | if node.nodeName == "bitmap": | |
333 | return True | |
2e0ae50e | 334 | |
73b2a9a7 RD |
335 | if node.nodeName == "icon": |
336 | return True | |
2e0ae50e | 337 | |
73b2a9a7 RD |
338 | # URLs in wxHtmlWindow: |
339 | if node.nodeName == "url": | |
340 | return True | |
2e0ae50e | 341 | |
73b2a9a7 RD |
342 | # wxBitmapButton: |
343 | parent = node.parentNode | |
344 | if parent.__class__ != minidom.Document and \ | |
345 | parent.getAttribute("class") == "wxBitmapButton" and \ | |
346 | (node.nodeName == "focus" or node.nodeName == "disabled" or | |
347 | node.nodeName == "selected"): | |
348 | return True | |
2e0ae50e | 349 | |
73b2a9a7 RD |
350 | # wxBitmap or wxIcon toplevel resources: |
351 | if node.nodeName == "object": | |
352 | klass = node.getAttribute("class") | |
353 | if klass == "wxBitmap" or klass == "wxIcon": | |
354 | return True | |
2e0ae50e | 355 | |
73b2a9a7 | 356 | return False |
2e0ae50e | 357 | |
73b2a9a7 | 358 | #------------------------------------------------------------------- |
2e0ae50e | 359 | |
73b2a9a7 RD |
360 | def ReplaceFilenamesInXRC(self, node, files, resourcePath): |
361 | """ Finds all files mentioned in resource file, e.g. <bitmap>filename</bitmap> | |
362 | and replaces them with the memory filenames. | |
363 | ||
364 | Fills a list of the filenames found.""" | |
2e0ae50e | 365 | |
73b2a9a7 RD |
366 | # Is 'node' XML node element? |
367 | if node is None: return | |
368 | if node.nodeType != minidom.Document.ELEMENT_NODE: return | |
2e0ae50e | 369 | |
73b2a9a7 | 370 | containsFilename = self.NodeContainsFilename(node); |
2e0ae50e | 371 | |
73b2a9a7 | 372 | for n in node.childNodes: |
2e0ae50e | 373 | |
73b2a9a7 RD |
374 | if (containsFilename and |
375 | (n.nodeType == minidom.Document.TEXT_NODE or | |
376 | n.nodeType == minidom.Document.CDATA_SECTION_NODE)): | |
2e0ae50e | 377 | |
73b2a9a7 RD |
378 | filename = n.nodeValue |
379 | memoryFilename = self.GetMemoryFilename(filename) | |
380 | n.nodeValue = memoryFilename | |
381 | ||
382 | if filename not in files: | |
383 | files.append(filename) | |
384 | ||
385 | # Recurse into children | |
386 | if n.nodeType == minidom.Document.ELEMENT_NODE: | |
387 | self.ReplaceFilenamesInXRC(n, files, resourcePath); | |
2e0ae50e | 388 | |
7e05216c RD |
389 | #------------------------------------------------------------------- |
390 | ||
391 | def FindStringsInNode(self, parent): | |
392 | def is_number(st): | |
393 | try: | |
394 | i = int(st) | |
395 | return True | |
396 | except ValueError: | |
397 | return False | |
398 | ||
399 | strings = [] | |
400 | if parent is None: | |
401 | return strings; | |
402 | ||
403 | for child in parent.childNodes: | |
404 | if ((parent.nodeType == parent.ELEMENT_NODE) and | |
405 | # parent is an element, i.e. has subnodes... | |
406 | (child.nodeType == child.TEXT_NODE or | |
407 | child.nodeType == child.CDATA_SECTION_NODE) and | |
408 | # ...it is textnode... | |
409 | ( | |
410 | parent.tagName == "label" or | |
411 | (parent.tagName == "value" and | |
412 | not is_number(child.nodeValue)) or | |
413 | parent.tagName == "help" or | |
414 | parent.tagName == "longhelp" or | |
415 | parent.tagName == "tooltip" or | |
416 | parent.tagName == "htmlcode" or | |
417 | parent.tagName == "title" or | |
418 | parent.tagName == "item" | |
419 | )): | |
420 | # ...and known to contain translatable string | |
421 | if (parent.getAttribute("translate") != "0"): | |
422 | strings.append(self.ConvertText(child.nodeValue)) | |
423 | ||
424 | # subnodes: | |
425 | if child.nodeType == child.ELEMENT_NODE: | |
426 | strings += self.FindStringsInNode(child) | |
427 | ||
428 | return strings | |
429 | ||
430 | #------------------------------------------------------------------- | |
431 | ||
432 | def ConvertText(self, st): | |
433 | st2 = "" | |
434 | dt = list(st) | |
435 | ||
436 | skipNext = False | |
437 | for i in range(len(dt)): | |
438 | if skipNext: | |
439 | skipNext = False | |
440 | continue | |
441 | ||
442 | if dt[i] == '_': | |
443 | if dt[i+1] == '_': | |
444 | st2 += '_' | |
445 | skipNext = True | |
446 | else: | |
447 | st2 += '&' | |
448 | elif dt[i] == '\n': | |
449 | st2 += '\\n' | |
450 | elif dt[i] == '\t': | |
451 | st2 += '\\t' | |
452 | elif dt[i] == '\r': | |
453 | st2 += '\\r' | |
454 | elif dt[i] == '\\': | |
455 | if dt[i+1] not in ['n', 't', 'r']: | |
456 | st2 += '\\\\' | |
457 | else: | |
458 | st2 += '\\' | |
459 | elif dt[i] == '"': | |
460 | st2 += '\\"' | |
461 | else: | |
462 | st2 += dt[i] | |
463 | ||
10383fe2 | 464 | return st2.encode("UTF-8") |
7e05216c RD |
465 | |
466 | ||
0fe9c329 RD |
467 | #------------------------------------------------------------------- |
468 | ||
469 | def _OpenOutputFile(self, outputFilename): | |
470 | if outputFilename == "-": | |
471 | outputFile = sys.stdout | |
472 | else: | |
473 | try: | |
474 | outputFile = open(outputFilename, "wt") | |
475 | except IOError: | |
476 | raise IOError("Can't write output to '%s'" % outputFilename) | |
477 | return outputFile | |
478 | ||
479 | ||
480 | ||
481 | ||
7e05216c | 482 | |
2e0ae50e RD |
483 | #--------------------------------------------------------------------------- |
484 | ||
73b2a9a7 RD |
485 | def main(args): |
486 | resourceFilename = "" | |
0fe9c329 | 487 | outputFilename = None |
73b2a9a7 | 488 | embedResources = False |
7e05216c | 489 | generateGetText = False |
0fe9c329 | 490 | generatePython = False |
73b2a9a7 RD |
491 | |
492 | try: | |
0fe9c329 RD |
493 | opts, args = getopt.gnu_getopt(args, |
494 | "hpgeo:", | |
495 | "help python gettext embed output=".split()) | |
7e05216c RD |
496 | except getopt.GetoptError, e: |
497 | print "\nError : %s\n" % str(e) | |
73b2a9a7 RD |
498 | print __doc__ |
499 | sys.exit(1) | |
2e0ae50e | 500 | |
73b2a9a7 | 501 | # If there is no input file argument, show help and exit |
0fe9c329 | 502 | if not args: |
73b2a9a7 | 503 | print __doc__ |
0fe9c329 | 504 | print "No xrc input file was specified." |
73b2a9a7 RD |
505 | sys.exit(1) |
506 | ||
507 | # Parse options and arguments | |
508 | for opt, val in opts: | |
509 | if opt in ["-h", "--help"]: | |
510 | print __doc__ | |
511 | sys.exit(1) | |
512 | ||
0fe9c329 RD |
513 | if opt in ["-p", "--python"]: |
514 | generatePython = True | |
515 | ||
73b2a9a7 RD |
516 | if opt in ["-o", "--output"]: |
517 | outputFilename = val | |
518 | ||
519 | if opt in ["-e", "--embed"]: | |
520 | embedResources = True | |
521 | ||
7e05216c RD |
522 | if opt in ["-g", "--gettext"]: |
523 | generateGetText = True | |
524 | ||
0fe9c329 RD |
525 | |
526 | # check for and expand any wildcards in the list of input files | |
527 | inputFiles = [] | |
528 | for arg in args: | |
529 | inputFiles += glob.glob(arg) | |
530 | ||
73b2a9a7 RD |
531 | |
532 | comp = XmlResourceCompiler() | |
533 | ||
534 | try: | |
0fe9c329 RD |
535 | if generatePython: |
536 | if not outputFilename: | |
537 | outputFilename = os.path.splitext(args[0])[0] + "_xrc.py" | |
538 | comp.MakePythonModule(inputFiles, outputFilename, | |
539 | embedResources, generateGetText) | |
540 | ||
541 | elif generateGetText: | |
542 | if not outputFilename: | |
543 | outputFilename = '-' | |
544 | comp.MakeGetTextOutput(inputFiles, outputFilename) | |
545 | ||
546 | else: | |
547 | print __doc__ | |
548 | print "One or both of -p, -g must be specified." | |
549 | sys.exit(1) | |
550 | ||
551 | ||
73b2a9a7 RD |
552 | except IOError, e: |
553 | print >>sys.stderr, "%s." % str(e) | |
554 | else: | |
555 | if outputFilename != "-": | |
556 | print >>sys.stderr, "Resources written to %s." % outputFilename | |
2e0ae50e RD |
557 | |
558 | if __name__ == "__main__": | |
73b2a9a7 | 559 | main(sys.argv[1:]) |
2e0ae50e | 560 |