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
This commit is contained in:
@@ -405,7 +405,8 @@ class Frame(wxFrame):
|
|||||||
if conf.localconf.ReadBool("autogenerate", False):
|
if conf.localconf.ReadBool("autogenerate", False):
|
||||||
pypath = conf.localconf.Read("filename")
|
pypath = conf.localconf.Read("filename")
|
||||||
embed = conf.localconf.ReadBool("embedResource", False)
|
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.SetStatusText('Data saved')
|
||||||
self.SaveRecent(path)
|
self.SaveRecent(path)
|
||||||
@@ -422,11 +423,11 @@ class Frame(wxFrame):
|
|||||||
EVT_MENU(self, newid, self.OnRecentFile)
|
EVT_MENU(self, newid, self.OnRecentFile)
|
||||||
conf.recentfiles[newid] = path
|
conf.recentfiles[newid] = path
|
||||||
|
|
||||||
def GeneratePython(self, dataFile, pypath, embed):
|
def GeneratePython(self, dataFile, pypath, embed, genGettext):
|
||||||
try:
|
try:
|
||||||
import wx.tools.pywxrc
|
import wx.tools.pywxrc
|
||||||
rescomp = wx.tools.pywxrc.XmlResourceCompiler()
|
rescomp = wx.tools.pywxrc.XmlResourceCompiler()
|
||||||
rescomp.MakePythonModule(dataFile, pypath, embed)
|
rescomp.MakePythonModule(dataFile, pypath, embed, genGettext)
|
||||||
except:
|
except:
|
||||||
inf = sys.exc_info()
|
inf = sys.exc_info()
|
||||||
wxLogError(traceback.format_exception(inf[0], inf[1], None)[-1])
|
wxLogError(traceback.format_exception(inf[0], inf[1], None)[-1])
|
||||||
@@ -1280,7 +1281,8 @@ class PythonOptions(wx.Dialog):
|
|||||||
def OnGenerate(self, evt):
|
def OnGenerate(self, evt):
|
||||||
pypath = self.FileNameTC.GetValue()
|
pypath = self.FileNameTC.GetValue()
|
||||||
embed = self.EmbedCB.GetValue()
|
embed = self.EmbedCB.GetValue()
|
||||||
frame.GeneratePython(self.dataFile, pypath, embed)
|
genGettext = self.GettextCB.GetValue()
|
||||||
|
frame.GeneratePython(self.dataFile, pypath, embed, genGettext)
|
||||||
self.OnSaveOpts()
|
self.OnSaveOpts()
|
||||||
|
|
||||||
|
|
||||||
|
@@ -522,31 +522,38 @@
|
|||||||
<object class="wxCheckBox" name="AutoGenerateCB">
|
<object class="wxCheckBox" name="AutoGenerateCB">
|
||||||
<label>Autogenerate Python module when saving XRC</label>
|
<label>Autogenerate Python module when saving XRC</label>
|
||||||
</object>
|
</object>
|
||||||
|
<flag>wxBOTTOM|wxLEFT|wxRIGHT</flag>
|
||||||
|
<border>5</border>
|
||||||
</object>
|
</object>
|
||||||
<object class="sizeritem">
|
<object class="sizeritem">
|
||||||
<object class="wxCheckBox" name="EmbedCB">
|
<object class="wxCheckBox" name="EmbedCB">
|
||||||
<label>Embed resource in python module</label>
|
<label>Embed resources in the Python module</label>
|
||||||
</object>
|
</object>
|
||||||
|
<flag>wxBOTTOM|wxLEFT|wxRIGHT</flag>
|
||||||
|
<border>5</border>
|
||||||
</object>
|
</object>
|
||||||
<object class="sizeritem">
|
<object class="sizeritem">
|
||||||
<object class="wxCheckBox" name="GettextCB">
|
<object class="wxCheckBox" name="GettextCB">
|
||||||
<label>Generate gettext strings</label>
|
<label>Generate gettext strings</label>
|
||||||
<enabled>0</enabled>
|
|
||||||
</object>
|
</object>
|
||||||
|
<flag>wxBOTTOM|wxLEFT|wxRIGHT</flag>
|
||||||
|
<border>5</border>
|
||||||
</object>
|
</object>
|
||||||
<object class="sizeritem">
|
<object class="sizeritem">
|
||||||
<object class="wxCheckBox" name="MakeXRSFileCB">
|
<object class="wxCheckBox" name="MakeXRSFileCB">
|
||||||
<label>Generate and use compressed XRS file</label>
|
<label>Generate and use compressed XRS file</label>
|
||||||
<enabled>0</enabled>
|
<enabled>0</enabled>
|
||||||
|
<hidden>1</hidden>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
<flag>wxBOTTOM|wxLEFT|wxRIGHT</flag>
|
||||||
<object class="spacer">
|
<border>5</border>
|
||||||
<size>1,10</size>
|
|
||||||
</object>
|
</object>
|
||||||
<object class="sizeritem">
|
<object class="sizeritem">
|
||||||
<object class="wxStaticText">
|
<object class="wxStaticText">
|
||||||
<label>Filename:</label>
|
<label>Filename:</label>
|
||||||
</object>
|
</object>
|
||||||
|
<flag>wxALL</flag>
|
||||||
|
<border>5</border>
|
||||||
</object>
|
</object>
|
||||||
<object class="sizeritem">
|
<object class="sizeritem">
|
||||||
<object class="wxBoxSizer">
|
<object class="wxBoxSizer">
|
||||||
@@ -555,17 +562,18 @@
|
|||||||
<object class="wxTextCtrl" name="FileNameTC">
|
<object class="wxTextCtrl" name="FileNameTC">
|
||||||
<size>500,-1</size>
|
<size>500,-1</size>
|
||||||
</object>
|
</object>
|
||||||
<flag>wxALIGN_CENTRE_VERTICAL</flag>
|
<flag>wxBOTTOM|wxLEFT|wxRIGHT|wxALIGN_CENTRE_VERTICAL</flag>
|
||||||
</object>
|
<border>5</border>
|
||||||
<object class="spacer">
|
|
||||||
<size>5,0</size>
|
|
||||||
</object>
|
</object>
|
||||||
<object class="sizeritem">
|
<object class="sizeritem">
|
||||||
<object class="wxButton" name="BrowseBtn">
|
<object class="wxButton" name="BrowseBtn">
|
||||||
<label>Browse...</label>
|
<label>Browse...</label>
|
||||||
</object>
|
</object>
|
||||||
|
<flag>wxBOTTOM|wxRIGHT</flag>
|
||||||
|
<border>5</border>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
|
<flag>wxEXPAND</flag>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
<flag>wxALL</flag>
|
<flag>wxALL</flag>
|
||||||
|
@@ -16,12 +16,14 @@
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
pywxrc -- Python XML resource compiler
|
pywxrc -- Python XML resource compiler
|
||||||
|
(see http://wiki.wxpython.org/index.cgi/pywxrc for more info)
|
||||||
|
|
||||||
Usage: python pywxrc.py -h
|
Usage: python pywxrc.py -h
|
||||||
python pywxrc.py <resource.xrc> [-e] [-o filename]
|
python pywxrc.py <resource.xrc> [-e] [-g] [-o filename]
|
||||||
|
|
||||||
-h, --help show help message
|
-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
|
-o, --output output filename, or - for stdout
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -51,7 +53,7 @@ def get_resources():
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
CLASS_HEADER = """\
|
CLASS_HEADER = """\
|
||||||
class %(windowName)sBase(wx.%(windowClass)s):
|
class xrc%(windowName)s(wx.%(windowClass)s):
|
||||||
def PreCreate(self):
|
def PreCreate(self):
|
||||||
\"\"\" This function is called during the class's initialization.
|
\"\"\" This function is called during the class's initialization.
|
||||||
|
|
||||||
@@ -74,9 +76,7 @@ class %(windowName)sBase(wx.%(windowClass)s):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
INIT_RESOURE_HEADER = """\
|
INIT_RESOURE_HEADER = """\
|
||||||
# -------------------------------------------------------------
|
|
||||||
# ------------------------ Resource data ----------------------
|
# ------------------------ Resource data ----------------------
|
||||||
# -------------------------------------------------------------
|
|
||||||
|
|
||||||
def __init_resources():
|
def __init_resources():
|
||||||
"""
|
"""
|
||||||
@@ -109,6 +109,21 @@ def __init_resources():
|
|||||||
__res.Load('memory:XRC/%(memoryPath)s/%(resourceFilename)s')
|
__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:
|
class XmlResourceCompiler:
|
||||||
@@ -117,7 +132,8 @@ class XmlResourceCompiler:
|
|||||||
|
|
||||||
"""This class generates Python code from XML resource files (XRC)."""
|
"""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 == "-":
|
if outputFilename == "-":
|
||||||
outputFile = sys.stdout
|
outputFile = sys.stdout
|
||||||
else:
|
else:
|
||||||
@@ -135,6 +151,9 @@ class XmlResourceCompiler:
|
|||||||
else:
|
else:
|
||||||
print >>outputFile, self.GenerateInitResourcesFile(resourceFilename, resourceDocument)
|
print >>outputFile, self.GenerateInitResourcesFile(resourceFilename, resourceDocument)
|
||||||
|
|
||||||
|
if generateGetText:
|
||||||
|
print >>outputFile, self.GenerateGetText(resourceDocument)
|
||||||
|
|
||||||
#-------------------------------------------------------------------
|
#-------------------------------------------------------------------
|
||||||
|
|
||||||
def GenerateClasses(self, 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):
|
def GenerateInitResourcesEmbedded(self, resourceFilename, resourceDocument):
|
||||||
outputList = []
|
outputList = []
|
||||||
|
|
||||||
@@ -203,6 +231,8 @@ class XmlResourceCompiler:
|
|||||||
#-------------------------------------------------------------------
|
#-------------------------------------------------------------------
|
||||||
|
|
||||||
def GenerateInitResourcesFile(self, resourceFilename, resourceDocument):
|
def GenerateInitResourcesFile(self, resourceFilename, resourceDocument):
|
||||||
|
# take only the filename portion out of resourceFilename
|
||||||
|
resourceFilename = os.path.split(resourceFilename)[1]
|
||||||
outputList = []
|
outputList = []
|
||||||
outputList.append(self.templates.INIT_RESOURE_HEADER)
|
outputList.append(self.templates.INIT_RESOURE_HEADER)
|
||||||
outputList.append(self.templates.LOAD_RES_FILE % locals())
|
outputList.append(self.templates.LOAD_RES_FILE % locals())
|
||||||
@@ -308,16 +338,97 @@ class XmlResourceCompiler:
|
|||||||
if n.nodeType == minidom.Document.ELEMENT_NODE:
|
if n.nodeType == minidom.Document.ELEMENT_NODE:
|
||||||
self.ReplaceFilenamesInXRC(n, files, resourcePath);
|
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):
|
def main(args):
|
||||||
resourceFilename = ""
|
resourceFilename = ""
|
||||||
outputFilename = ""
|
outputFilename = ""
|
||||||
embedResources = False
|
embedResources = False
|
||||||
|
generateGetText = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.gnu_getopt(args, "heo:", "help embed output=".split())
|
opts, args = getopt.gnu_getopt(args, "hego:", "help embed gettext output=".split())
|
||||||
except getopt.GetoptError:
|
except getopt.GetoptError, e:
|
||||||
|
print "\nError : %s\n" % str(e)
|
||||||
print __doc__
|
print __doc__
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
@@ -340,13 +451,16 @@ def main(args):
|
|||||||
if opt in ["-e", "--embed"]:
|
if opt in ["-e", "--embed"]:
|
||||||
embedResources = True
|
embedResources = True
|
||||||
|
|
||||||
|
if opt in ["-g", "--gettext"]:
|
||||||
|
generateGetText = True
|
||||||
|
|
||||||
if outputFilename is None or outputFilename == "":
|
if outputFilename is None or outputFilename == "":
|
||||||
outputFilename = os.path.splitext(resourceFilename)[0] + "_xrc.py"
|
outputFilename = os.path.splitext(resourceFilename)[0] + "_xrc.py"
|
||||||
|
|
||||||
comp = XmlResourceCompiler()
|
comp = XmlResourceCompiler()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
comp.MakePythonModule(resourceFilename, outputFilename, embedResources)
|
comp.MakePythonModule(resourceFilename, outputFilename, embedResources, generateGetText)
|
||||||
except IOError, e:
|
except IOError, e:
|
||||||
print >>sys.stderr, "%s." % str(e)
|
print >>sys.stderr, "%s." % str(e)
|
||||||
else:
|
else:
|
||||||
|
Reference in New Issue
Block a user