From 7e05216cce2522eb4687d8c03e339b27da9c3f4e Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Wed, 3 May 2006 01:47:57 +0000 Subject: [PATCH] Patch from Eli Golovinsky. Adds generation of _() code for gettext and other tweaks. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38982 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- wxPython/wx/tools/XRCed/xrced.py | 10 ++- wxPython/wx/tools/XRCed/xrced.xrc | 26 ++++-- wxPython/wx/tools/pywxrc.py | 132 ++++++++++++++++++++++++++++-- 3 files changed, 146 insertions(+), 22 deletions(-) diff --git a/wxPython/wx/tools/XRCed/xrced.py b/wxPython/wx/tools/XRCed/xrced.py index 78b97e54b3..9fb1c03f4a 100644 --- a/wxPython/wx/tools/XRCed/xrced.py +++ b/wxPython/wx/tools/XRCed/xrced.py @@ -405,7 +405,8 @@ class Frame(wxFrame): if conf.localconf.ReadBool("autogenerate", False): pypath = conf.localconf.Read("filename") embed = conf.localconf.ReadBool("embedResource", False) - self.GeneratePython(self.dataFile, pypath, embed) + genGettext = conf.localconf.ReadBool("genGettext", False) + self.GeneratePython(self.dataFile, pypath, embed, genGettext) self.SetStatusText('Data saved') self.SaveRecent(path) @@ -422,11 +423,11 @@ class Frame(wxFrame): EVT_MENU(self, newid, self.OnRecentFile) conf.recentfiles[newid] = path - def GeneratePython(self, dataFile, pypath, embed): + def GeneratePython(self, dataFile, pypath, embed, genGettext): try: import wx.tools.pywxrc rescomp = wx.tools.pywxrc.XmlResourceCompiler() - rescomp.MakePythonModule(dataFile, pypath, embed) + rescomp.MakePythonModule(dataFile, pypath, embed, genGettext) except: inf = sys.exc_info() wxLogError(traceback.format_exception(inf[0], inf[1], None)[-1]) @@ -1280,7 +1281,8 @@ class PythonOptions(wx.Dialog): def OnGenerate(self, evt): pypath = self.FileNameTC.GetValue() embed = self.EmbedCB.GetValue() - frame.GeneratePython(self.dataFile, pypath, embed) + genGettext = self.GettextCB.GetValue() + frame.GeneratePython(self.dataFile, pypath, embed, genGettext) self.OnSaveOpts() diff --git a/wxPython/wx/tools/XRCed/xrced.xrc b/wxPython/wx/tools/XRCed/xrced.xrc index e80599b59f..9ebe7d1fdd 100644 --- a/wxPython/wx/tools/XRCed/xrced.xrc +++ b/wxPython/wx/tools/XRCed/xrced.xrc @@ -522,31 +522,38 @@ + wxBOTTOM|wxLEFT|wxRIGHT + 5 - + + wxBOTTOM|wxLEFT|wxRIGHT + 5 - 0 + wxBOTTOM|wxLEFT|wxRIGHT + 5 0 + 1 - - - 1,10 + wxBOTTOM|wxLEFT|wxRIGHT + 5 + wxALL + 5 @@ -555,17 +562,18 @@ 500,-1 - wxALIGN_CENTRE_VERTICAL - - - 5,0 + wxBOTTOM|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL + 5 + wxBOTTOM|wxRIGHT + 5 + wxEXPAND wxALL diff --git a/wxPython/wx/tools/pywxrc.py b/wxPython/wx/tools/pywxrc.py index dbec81f2ce..2930272b4f 100644 --- a/wxPython/wx/tools/pywxrc.py +++ b/wxPython/wx/tools/pywxrc.py @@ -16,12 +16,14 @@ """ pywxrc -- Python XML resource compiler + (see http://wiki.wxpython.org/index.cgi/pywxrc for more info) Usage: python pywxrc.py -h - python pywxrc.py [-e] [-o filename] + python pywxrc.py [-e] [-g] [-o filename] -h, --help show help message - -e, --embed embed resources in output file + -e, --embed embed resources in the output file + -g, --gettext embed list of translatable strings in the output file -o, --output output filename, or - for stdout """ @@ -51,7 +53,7 @@ def get_resources(): """ CLASS_HEADER = """\ -class %(windowName)sBase(wx.%(windowClass)s): +class xrc%(windowName)s(wx.%(windowClass)s): def PreCreate(self): \"\"\" This function is called during the class's initialization. @@ -74,9 +76,7 @@ class %(windowName)sBase(wx.%(windowClass)s): """ INIT_RESOURE_HEADER = """\ -# ------------------------------------------------------------- # ------------------------ Resource data ---------------------- -# ------------------------------------------------------------- def __init_resources(): """ @@ -109,6 +109,21 @@ def __init_resources(): __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 + +%(gettextStrings)s +""" + #---------------------------------------------------------------------- class XmlResourceCompiler: @@ -117,7 +132,8 @@ class XmlResourceCompiler: """This class generates Python code from XML resource files (XRC).""" - def MakePythonModule(self, resourceFilename, outputFilename, embedResources=False): + def MakePythonModule(self, resourceFilename, outputFilename, + embedResources=False, generateGetText=False): if outputFilename == "-": outputFile = sys.stdout else: @@ -135,6 +151,9 @@ class XmlResourceCompiler: else: print >>outputFile, self.GenerateInitResourcesFile(resourceFilename, resourceDocument) + if generateGetText: + print >>outputFile, self.GenerateGetText(resourceDocument) + #------------------------------------------------------------------- def GenerateClasses(self, resourceDocument): @@ -168,6 +187,15 @@ class XmlResourceCompiler: #------------------------------------------------------------------- + def GenerateGetText(self, resourceDocument): + resource = resourceDocument.firstChild + strings = self.FindStringsInNode(resource) + strings = [' _("%s")\n' % s for s in strings] + gettextStrings = "".join(strings) + return self.templates.GETTEXT_DUMMY_FUNC % locals() + + #------------------------------------------------------------------- + def GenerateInitResourcesEmbedded(self, resourceFilename, resourceDocument): outputList = [] @@ -203,6 +231,8 @@ class XmlResourceCompiler: #------------------------------------------------------------------- def GenerateInitResourcesFile(self, resourceFilename, resourceDocument): + # take only the filename portion out of resourceFilename + resourceFilename = os.path.split(resourceFilename)[1] outputList = [] outputList.append(self.templates.INIT_RESOURE_HEADER) outputList.append(self.templates.LOAD_RES_FILE % locals()) @@ -308,16 +338,97 @@ class XmlResourceCompiler: 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 + + + #--------------------------------------------------------------------------- def main(args): resourceFilename = "" outputFilename = "" embedResources = False + generateGetText = False try: - opts, args = getopt.gnu_getopt(args, "heo:", "help embed output=".split()) - except getopt.GetoptError: + opts, args = getopt.gnu_getopt(args, "hego:", "help embed gettext output=".split()) + except getopt.GetoptError, e: + print "\nError : %s\n" % str(e) print __doc__ sys.exit(1) @@ -340,13 +451,16 @@ def main(args): if opt in ["-e", "--embed"]: embedResources = True + if opt in ["-g", "--gettext"]: + generateGetText = True + if outputFilename is None or outputFilename == "": outputFilename = os.path.splitext(resourceFilename)[0] + "_xrc.py" comp = XmlResourceCompiler() try: - comp.MakePythonModule(resourceFilename, outputFilename, embedResources) + comp.MakePythonModule(resourceFilename, outputFilename, embedResources, generateGetText) except IOError, e: print >>sys.stderr, "%s." % str(e) else: -- 2.45.2