Gettext: MyGUI Layout to POT file script

siondream

03-07-2011 16:09:00

Hi there!

I'm sure many of you guys know gettext, the GNU internacionalization and localization (i18n) library. In my humble opinion, it's the best free tool to translate software no matter its programming language. I'm working in a Ogre3D action/strategy game called Sion Tower and I'm creating the GUI using MyGUI. I want Sion Tower to be easyly translated so I would like to use gettext.

Gettext uses plain text .po files and their binaries equivalent .mo files with all the strings contained in a program and their translations into the desired language. The master template file is always a .pot file. In code you use something like this:


_btnPlay->setCaption(_("Play"));


"_" is a typedef for the gettext function that automatically retrieves the translation given a key string (in this case is "Play"). You could simply set every Widget's caption with the gettext function but it kills the purpose of having layout files, if you change a caption you would have to re-build the game.

The problem is that you can't extract a .pot file from a MyGUI xml layout even with the xml2po script. For this problem I have written the following Python script, hope you find it useful:


#!/usr/bin/env python
# -*- coding: utf-8 -*-

###############################################################################
# This file is part of Sion Tower. #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>;. #
# #
# Copyright (C) 2011, David Saltares Márquez, <david.saltares@gmail.com> #
###############################################################################

import os
import sys

from xml.dom import minidom
from xml.etree.ElementTree import ElementTree

def syntax():
print 'Syntax error, the correct syntax is:'
print ' python translateLayout.py file.layout file.pot'
print ''


def translateLayout(layoutFile, potFile):
# Load XML Document
print '* Loading XML document...'
doc = ElementTree()

try:
doc.parse(sys.argv[1])
except IOError:
print '* ERROR parsing MyGUI layout'
exit(1)

root = doc.getroot()

# Retrieve every "Property" elements
print '* Procesing properties...'
properties = root.findall('Widget/Property')

# Open pot file
try:
f = open(potFile, 'w')
except IOError:
print '* ERROR opening pot file'
exit(1)

# Iterate through every Property
for p in properties:
# Check if it has a Caption property
key = p.get('key')
if key == 'Caption':
# Get Caption
value = p.get('value')
print ' - Caption found: ' + value

# Write caption into pot file
f.write('msgid "' + value + '"\n')
f.write('msgstr ""\n\n')


# Save file
print '* Saving .pot file...'
f.close()


def main():
# Header
print ''
print 'MyGUI Layout - POT converter'
print '============================'
print ''

# Check arguments
if len(sys.argv) < 3:
syntax()
sys.exit(1)

translateLayout(sys.argv[1], sys.argv[2])

print ''



if __name__ == "__main__":
main()


The usage is simple:

python translateLayout.py file.layout file.pot

It will extract all Caption properties. For example, if we have:


<?xml version="1.0" encoding="UTF-8"?>
<MyGUI type="Layout">
<Widget type="Button" skin="Button" position_real="0.71875 0.430556 0.265625 0.108333" align="ALIGN_DEFAULT" layer="Main" name="btnPlay">
<Property key="Caption" value="Play"/>
<Property key="FontHeight" value="30"/>
</Widget>
<Widget type="ImageBox" skin="ImageBox" position_real="0.00390625 0.0402778 0.50625 0.165278" align="ALIGN_DEFAULT" layer="Back" name="imgTitle">
<Property key="ImageTexture" value="siontowertitle.png"/>
</Widget>
<Widget type="TextBox" skin="TextBox" position_real="0.526563 0.102778 0.48125 0.0444444" layer="Back" name="lblSubtitle">
<Property key="FontHeight" value="30"/>
<Property key="Caption" value="#ffffffA horde is comming, defend the Sacred Tower!"/>
</Widget>
<Widget type="Button" skin="Button" position_real="0.71875 0.6 0.265625 0.108333" layer="Back" name="btnCredits">
<Property key="Caption" value="Credits"/>
<Property key="FontHeight" value="30"/>
</Widget>
<Widget type="Button" skin="Button" position_real="0.71875 0.766667 0.265625 0.108333" layer="Back" name="btnExit">
<Property key="Caption" value="Exit"/>
<Property key="FontHeight" value="30"/>
</Widget>
</MyGUI>


We will get:


msgid "Play"
msgstr ""

msgid "#ffffffA horde is comming, defend the Sacred Tower!"
msgstr ""

msgid "Credits"
msgstr ""

msgid "Exit"
msgstr ""


With the following LINUX command you will be able to merge your layout pot files with the rest of your code string together:

msgcat *.pot > all.pot

Each menu layout class will have a translate function (or somethin like that) and you'll simply do:

_btnPlay->setCaption(_(_btnPlay->getCaption().asUTF8_c_str()));

Enjoy!