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