#-----------------------------------------------------------------------------
# Name: I18NWrap.plug-in.py
# Purpose:
#
# Author: Riaan Booysen
#
# Created: 2006/11/01
# RCS-ID: $Id: I18NUtils.plug-in.py,v 1.2 2007/07/02 15:01:15 riaan Exp $
# Copyright: (c) 2007
# Licence: Python
#-----------------------------------------------------------------------------
# msgfmt_* written by Martin v. Lowis from Python/Tools/i18n/msgfmt.py
import os, sys, struct, array
import wx
from Models import EditorModels,Controllers
from ModRunner import ProcessModuleRunner
import Preferences
from Utils import _
Preferences.keyDefs['I18NWrap'] = (wx.ACCEL_ALT, ord('I'), 'Alt-I')
class I18NWrapViewPlugin:
def __init__(self, model, view, actions):
self.model = model
self.view = view
actions.extend( (
(_('Wrap selection with _()'), self.OnI18NWrapSelection, '-', 'I18NWrap'),
) )
def OnI18NWrapSelection(self, event):
first, last = self.view.GetSelection()
if first and last:
sel = self.view.GetText()[first:last]
self.view.ReplaceSelection('_(%s)'%sel)
wxID_POCOMPILE = wx.NewId()
class POFileController(Controllers.TextController):
Model = EditorModels.TextModel
compileBmp = 'Images/Debug/Compile.png'
def actions(self, model):
return Controllers.TextController.actions(self, model) + [
(_('Compile to MO'), self.OnCompile, '-', '')]
def OnCompile(self, event):
model = self.getModel()
if not model.savedAs:
wx.LogError(_('Cannot compile an unsaved module'))
return
filename = model.assertLocalFile()
outfile = os.path.splitext(filename)[0] + '.mo'
MESSAGES = {}
if msgfmt_make(filename, outfile, MESSAGES):
wx.LogMessage(_('%s created')%outfile)
else:
wx.LogError(_('MO file not created'))
def msgfmt_add(id, str, fuzzy, MESSAGES):
"""Add a non-fuzzy translation to the dictionary."""
if not fuzzy and str:
MESSAGES[id] = str
def msgfmt_generate(MESSAGES):
"Return the generated output."
keys = MESSAGES.keys()
# the keys are sorted in the .mo file
keys.sort()
offsets = []
ids = strs = ''
for id in keys:
# For each string, we need size and file offset. Each string is NUL
# terminated; the NUL does not count into the size.
offsets.append((len(ids), len(id), len(strs), len(MESSAGES[id])))
ids += id + '\0'
strs += MESSAGES[id] + '\0'
output = ''
# The header is 7 32-bit unsigned integers. We don't use hash tables, so
# the keys start right after the index tables.
# translated string.
keystart = 7*4+16*len(keys)
# and the values start after the keys
valuestart = keystart + len(ids)
koffsets = []
voffsets = []
# The string table first has the list of keys, then the list of values.
# Each entry has first the size of the string, then the file offset.
for o1, l1, o2, l2 in offsets:
koffsets += [l1, o1+keystart]
voffsets += [l2, o2+valuestart]
offsets = koffsets + voffsets
output = struct.pack("Iiiiiii",
0x950412deL, # Magic
0, # Version
len(keys), # # of entries
7*4, # start of key index
7*4+len(keys)*8, # start of value index
0, 0) # size and offset of hash table
output += array.array("i", offsets).tostring()
output += ids
output += strs
return output
def msgfmt_make(filename, outfile, MESSAGES):
ID = 1
STR = 2
# Compute .mo name from .po name and arguments
if filename.endswith('.po'):
infile = filename
else:
infile = filename + '.po'
if outfile is None:
outfile = os.path.splitext(infile)[0] + '.mo'
lines = open(infile).readlines()
section = None
fuzzy = 0
# Parse the catalog
lno = 0
for l in lines:
lno += 1
# If we get a comment line after a msgstr, this is a new entry
if l[0] == '#' and section == STR:
msgfmt_add(msgid, msgstr, fuzzy, MESSAGES)
section = None
fuzzy = 0
# Record a fuzzy mark
if l[:2] == '#,' and l.find('fuzzy'):
fuzzy = 1
# Skip comments
if l[0] == '#':
continue
# Now we are in a msgid section, output previous section
if l.startswith('msgid'):
if section == STR:
msgfmt_add(msgid, msgstr, fuzzy, MESSAGES)
section = ID
l = l[5:]
msgid = msgstr = ''
# Now we are in a msgstr section
elif l.startswith('msgstr'):
section = STR
l = l[6:]
# Skip empty lines
l = l.strip()
if not l:
continue
# XXX: Does this always follow Python escape semantics?
l = eval(l)
if section == ID:
msgid += l
elif section == STR:
msgstr += l
else:
print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), \
'before:'
print >> sys.stderr, l
return
# Add last entry
if section == STR:
msgfmt_add(msgid, msgstr, fuzzy, MESSAGES)
# Compute output
output = msgfmt_generate(MESSAGES)
try:
open(outfile,"wb").write(output)
except IOError,msg:
print >> sys.stderr, msg
return False
else:
return True
Plugins.registerFileType(POFileController, aliasExts=('.po'))
from Views import PySourceView
PySourceView.PythonSourceView.plugins += (I18NWrapViewPlugin,)
###-------------------------------------------------------------------------------
##def showGeneratePOTFromSourceDlg(editor):
## dlg = wx.DirDialog(editor,
## _('Select directory to recursively scan source for strings'),
## _('Generate POT from source'))
## try:
## if dlg.ShowModal() == wx.ID_OK:
## dir = dlg.GetPath()
## # Your code
## finally:
## dlg.Destroy()
##
##Plugins.registerTool(_('Generate POT from source'), showGeneratePOTFromSourceDlg)
|