mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
+ added ngettext support
* updated russian translation git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@164 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
parent
7601a8a27d
commit
f704ddd02b
41 changed files with 2294 additions and 1632 deletions
2
Makefile
2
Makefile
|
@ -29,7 +29,7 @@ rules:
|
||||||
|
|
||||||
pot:
|
pot:
|
||||||
./scripts/all_games.py gettext > po/games.pot
|
./scripts/all_games.py gettext > po/games.pot
|
||||||
pygettext.py -k n_ -o po/pysol-1.pot $(PYSOLLIB_FILES)
|
./scripts/pygettext.py -k n_ --ngettext-keyword ungettext -o po/pysol-1.pot $(PYSOLLIB_FILES)
|
||||||
xgettext -L C --keyword=N_ -o po/pysol-2.pot data/glade-translations
|
xgettext -L C --keyword=N_ -o po/pysol-2.pot data/glade-translations
|
||||||
msgcat po/pysol-1.pot po/pysol-2.pot > po/pysol.pot
|
msgcat po/pysol-1.pot po/pysol-2.pot > po/pysol.pot
|
||||||
rm -f po/pysol-1.pot po/pysol-2.pot
|
rm -f po/pysol-1.pot po/pysol-2.pot
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PySol 0.0.1\n"
|
"Project-Id-Version: PySol 0.0.1\n"
|
||||||
"POT-Creation-Date: Thu May 10 14:22:52 2007\n"
|
"POT-Creation-Date: Fri May 11 22:05:05 2007\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -741,7 +741,7 @@ msgstr ""
|
||||||
msgid "Die Bildgallerie"
|
msgid "Die Bildgallerie"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Die Königsbergerin"
|
msgid "Die Koenigsbergerin"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Die Russische"
|
msgid "Die Russische"
|
||||||
|
@ -750,10 +750,7 @@ msgstr ""
|
||||||
msgid "Die Schlange"
|
msgid "Die Schlange"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Die böse Sieben"
|
msgid "Die boese Sieben"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Die große Harfe"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Die kleine Harfe"
|
msgid "Die kleine Harfe"
|
||||||
|
|
1395
po/pysol.pot
1395
po/pysol.pot
File diff suppressed because it is too large
Load diff
|
@ -5,8 +5,8 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PySol 0.0.1\n"
|
"Project-Id-Version: PySol 0.0.1\n"
|
||||||
"POT-Creation-Date: Thu May 10 14:22:52 2007\n"
|
"POT-Creation-Date: Fri May 11 22:05:05 2007\n"
|
||||||
"PO-Revision-Date: 2007-03-05 18:01+0300\n"
|
"PO-Revision-Date: 2007-05-11 17:25+0400\n"
|
||||||
"Last-Translator: Скоморох <skomoroh@gmail.com>\n"
|
"Last-Translator: Скоморох <skomoroh@gmail.com>\n"
|
||||||
"Language-Team: Russian <ru@li.org>\n"
|
"Language-Team: Russian <ru@li.org>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
|
@ -211,16 +211,14 @@ msgstr "Баланс"
|
||||||
msgid "Balarama"
|
msgid "Balarama"
|
||||||
msgstr "Баларама"
|
msgstr "Баларама"
|
||||||
|
|
||||||
#, fuzzy
|
|
||||||
msgid "Banner"
|
msgid "Banner"
|
||||||
msgstr "Баланс"
|
msgstr "Флаг"
|
||||||
|
|
||||||
msgid "Baroness"
|
msgid "Baroness"
|
||||||
msgstr "Баронесса"
|
msgstr "Баронесса"
|
||||||
|
|
||||||
#, fuzzy
|
|
||||||
msgid "Barrier"
|
msgid "Barrier"
|
||||||
msgstr "Причудливый"
|
msgstr "Барьер"
|
||||||
|
|
||||||
msgid "Bastille Day"
|
msgid "Bastille Day"
|
||||||
msgstr "День Бастилии"
|
msgstr "День Бастилии"
|
||||||
|
@ -250,7 +248,7 @@ msgid "Beatle"
|
||||||
msgstr "Жук"
|
msgstr "Жук"
|
||||||
|
|
||||||
msgid "Bebop"
|
msgid "Bebop"
|
||||||
msgstr ""
|
msgstr "Бибоп"
|
||||||
|
|
||||||
msgid "Beetle"
|
msgid "Beetle"
|
||||||
msgstr "Жук"
|
msgstr "Жук"
|
||||||
|
@ -663,7 +661,7 @@ msgid "Crossroads"
|
||||||
msgstr "Перекрестки"
|
msgstr "Перекрестки"
|
||||||
|
|
||||||
msgid "Crown"
|
msgid "Crown"
|
||||||
msgstr "Венец"
|
msgstr "Корона"
|
||||||
|
|
||||||
msgid "Cruel"
|
msgid "Cruel"
|
||||||
msgstr "Изнурительный"
|
msgstr "Изнурительный"
|
||||||
|
@ -729,9 +727,8 @@ msgstr "Der letzte Monarch"
|
||||||
msgid "Deuces"
|
msgid "Deuces"
|
||||||
msgstr "Двойки"
|
msgstr "Двойки"
|
||||||
|
|
||||||
#, fuzzy
|
|
||||||
msgid "Devil's Solitaire"
|
msgid "Devil's Solitaire"
|
||||||
msgstr "Китайский пасьянс"
|
msgstr "Дьявольский пасьянс"
|
||||||
|
|
||||||
msgid "Dhanpati"
|
msgid "Dhanpati"
|
||||||
msgstr "Dhanpati"
|
msgstr "Dhanpati"
|
||||||
|
@ -748,8 +745,8 @@ msgstr "Алмазный рудник"
|
||||||
msgid "Die Bildgallerie"
|
msgid "Die Bildgallerie"
|
||||||
msgstr "Die Bildgallerie"
|
msgstr "Die Bildgallerie"
|
||||||
|
|
||||||
msgid "Die Königsbergerin"
|
msgid "Die Koenigsbergerin"
|
||||||
msgstr "Die Königsbergerin"
|
msgstr "Die Koenigsbergerin"
|
||||||
|
|
||||||
msgid "Die Russische"
|
msgid "Die Russische"
|
||||||
msgstr "Die Russische"
|
msgstr "Die Russische"
|
||||||
|
@ -757,11 +754,8 @@ msgstr "Die Russische"
|
||||||
msgid "Die Schlange"
|
msgid "Die Schlange"
|
||||||
msgstr "Die Schlange"
|
msgstr "Die Schlange"
|
||||||
|
|
||||||
msgid "Die böse Sieben"
|
msgid "Die boese Sieben"
|
||||||
msgstr "Die böse Sieben"
|
msgstr "Die boese Sieben"
|
||||||
|
|
||||||
msgid "Die große Harfe"
|
|
||||||
msgstr "Die große Harfe"
|
|
||||||
|
|
||||||
msgid "Die kleine Harfe"
|
msgid "Die kleine Harfe"
|
||||||
msgstr "Die kleine Harfe"
|
msgstr "Die kleine Harfe"
|
||||||
|
@ -2581,11 +2575,10 @@ msgid "Napoleon"
|
||||||
msgstr "Наполеон"
|
msgstr "Наполеон"
|
||||||
|
|
||||||
msgid "Napoleon Leaves Moscow"
|
msgid "Napoleon Leaves Moscow"
|
||||||
msgstr ""
|
msgstr "Наполеон бежит из Москвы"
|
||||||
|
|
||||||
#, fuzzy
|
|
||||||
msgid "Napoleon Takes Moscow"
|
msgid "Napoleon Takes Moscow"
|
||||||
msgstr "Гробница Наполеона"
|
msgstr "Наполеон идет на Москву"
|
||||||
|
|
||||||
msgid "Napoleon at St.Helena"
|
msgid "Napoleon at St.Helena"
|
||||||
msgstr "Наполеон на острове св.Елена"
|
msgstr "Наполеон на острове св.Елена"
|
||||||
|
@ -2825,13 +2818,11 @@ msgstr "Перпетуум-мобиле"
|
||||||
msgid "Perseverance"
|
msgid "Perseverance"
|
||||||
msgstr "Настойчивость"
|
msgstr "Настойчивость"
|
||||||
|
|
||||||
#, fuzzy
|
|
||||||
msgid "Persian Patience"
|
msgid "Persian Patience"
|
||||||
msgstr "Алжирский пасьянс"
|
msgstr "Персидский пасьянс"
|
||||||
|
|
||||||
#, fuzzy
|
|
||||||
msgid "Phalanx"
|
msgid "Phalanx"
|
||||||
msgstr "Реглан"
|
msgstr "Фаланга"
|
||||||
|
|
||||||
msgid "Phantom Blockade"
|
msgid "Phantom Blockade"
|
||||||
msgstr "Призрачная блокада"
|
msgstr "Призрачная блокада"
|
||||||
|
@ -3019,9 +3010,8 @@ msgstr "Свита"
|
||||||
msgid "Right Triangle"
|
msgid "Right Triangle"
|
||||||
msgstr "Правый треугольник"
|
msgstr "Правый треугольник"
|
||||||
|
|
||||||
#, fuzzy
|
|
||||||
msgid "Right and Left"
|
msgid "Right and Left"
|
||||||
msgstr "Верхний и нижний"
|
msgstr "Справа и слева"
|
||||||
|
|
||||||
msgid "Rings"
|
msgid "Rings"
|
||||||
msgstr "Круги"
|
msgstr "Круги"
|
||||||
|
@ -3139,7 +3129,7 @@ msgid "Scheidungsgrund"
|
||||||
msgstr "Scheidungsgrund"
|
msgstr "Scheidungsgrund"
|
||||||
|
|
||||||
msgid "School"
|
msgid "School"
|
||||||
msgstr ""
|
msgstr "Школьный"
|
||||||
|
|
||||||
msgid "Scorpion"
|
msgid "Scorpion"
|
||||||
msgstr "Скорпион"
|
msgstr "Скорпион"
|
||||||
|
@ -3602,22 +3592,20 @@ msgstr "Тринадцать вверх"
|
||||||
msgid "Thirteens"
|
msgid "Thirteens"
|
||||||
msgstr "По тринадцать"
|
msgstr "По тринадцать"
|
||||||
|
|
||||||
#, fuzzy
|
|
||||||
msgid "Thirty"
|
msgid "Thirty"
|
||||||
msgstr "Тридцать шесть"
|
msgstr "Тридцать"
|
||||||
|
|
||||||
msgid "Thirty Six"
|
msgid "Thirty Six"
|
||||||
msgstr "Тридцать шесть"
|
msgstr "Тридцать шесть"
|
||||||
|
|
||||||
msgid "Thirty Two Cards"
|
msgid "Thirty Two Cards"
|
||||||
msgstr ""
|
msgstr "Тридцать две карты"
|
||||||
|
|
||||||
msgid "Three Blind Mice"
|
msgid "Three Blind Mice"
|
||||||
msgstr "Три слепые мышки"
|
msgstr "Три слепые мышки"
|
||||||
|
|
||||||
#, fuzzy
|
|
||||||
msgid "Three Fir-trees"
|
msgid "Three Fir-trees"
|
||||||
msgstr "Три пирата"
|
msgstr "Три елки"
|
||||||
|
|
||||||
msgid "Three Peaks"
|
msgid "Three Peaks"
|
||||||
msgstr "Три вершины"
|
msgstr "Три вершины"
|
||||||
|
@ -3692,9 +3680,8 @@ msgstr "Маджонг Traditional Reviewed"
|
||||||
msgid "Trapdoor"
|
msgid "Trapdoor"
|
||||||
msgstr "Люк"
|
msgstr "Люк"
|
||||||
|
|
||||||
#, fuzzy
|
|
||||||
msgid "Trapdoor Spider"
|
msgid "Trapdoor Spider"
|
||||||
msgstr "Люк"
|
msgstr "Люк Паука"
|
||||||
|
|
||||||
msgid "Treasure Trove"
|
msgid "Treasure Trove"
|
||||||
msgstr "Клад"
|
msgstr "Клад"
|
||||||
|
@ -3976,9 +3963,3 @@ msgstr "Зигзагообразный курс"
|
||||||
|
|
||||||
msgid "Zodiac"
|
msgid "Zodiac"
|
||||||
msgstr "Зодиак"
|
msgstr "Зодиак"
|
||||||
|
|
||||||
#~ msgid "Alternations"
|
|
||||||
#~ msgstr "Чередования"
|
|
||||||
|
|
||||||
#~ msgid "Mahjongg Hurricane"
|
|
||||||
#~ msgstr "Маджонг Ураган"
|
|
||||||
|
|
1440
po/ru_pysol.po
1440
po/ru_pysol.po
File diff suppressed because it is too large
Load diff
|
@ -66,7 +66,6 @@ from pysoltk import create_find_card_dialog
|
||||||
from pysoltk import create_solver_dialog
|
from pysoltk import create_solver_dialog
|
||||||
from help import help_about, help_html
|
from help import help_about, help_html
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // menubar
|
# // menubar
|
||||||
|
@ -582,7 +581,7 @@ class PysolMenubarActions:
|
||||||
else:
|
else:
|
||||||
player = self.app.opt.player
|
player = self.app.opt.player
|
||||||
p0, p1, p2 = player, "", _(" for ") + player
|
p0, p1, p2 = player, "", _(" for ") + player
|
||||||
n = gettext(self.game.gameinfo.short_name)
|
n = _(self.game.gameinfo.short_name)
|
||||||
#
|
#
|
||||||
if mode == 100:
|
if mode == 100:
|
||||||
d = Status_StatsDialog(self.top, game=self.game)
|
d = Status_StatsDialog(self.top, game=self.game)
|
||||||
|
|
|
@ -75,7 +75,6 @@ from pysoltk import destroy_solver_dialog
|
||||||
from pysoltk import connect_game_solver_dialog
|
from pysoltk import connect_game_solver_dialog
|
||||||
from help import help_about, destroy_help_html
|
from help import help_about, destroy_help_html
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // Options
|
# // Options
|
||||||
|
@ -1350,12 +1349,12 @@ Please select a %s type %s.
|
||||||
def getGameTitleName(self, id):
|
def getGameTitleName(self, id):
|
||||||
gi = self.gdb.get(id)
|
gi = self.gdb.get(id)
|
||||||
if gi is None: return None
|
if gi is None: return None
|
||||||
return gettext(gi.name)
|
return _(gi.name)
|
||||||
|
|
||||||
def getGameMenuitemName(self, id):
|
def getGameMenuitemName(self, id):
|
||||||
gi = self.gdb.get(id)
|
gi = self.gdb.get(id)
|
||||||
if gi is None: return None
|
if gi is None: return None
|
||||||
return gettext(gi.short_name)
|
return _(gi.short_name)
|
||||||
|
|
||||||
def getGameRulesFilename(self, id):
|
def getGameRulesFilename(self, id):
|
||||||
gi = self.gdb.get(id)
|
gi = self.gdb.get(id)
|
||||||
|
|
|
@ -30,8 +30,6 @@ from hint import AbstractHint, DefaultHint, CautiousDefaultHint, Yukon_Hint
|
||||||
from wizardutil import WizardWidgets
|
from wizardutil import WizardWidgets
|
||||||
|
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
|
@ -42,8 +42,6 @@ from mfxutil import Struct
|
||||||
from resource import CSI
|
from resource import CSI
|
||||||
from settings import CHECK_GAMES
|
from settings import CHECK_GAMES
|
||||||
|
|
||||||
gettext = _
|
|
||||||
n_ = lambda x: x
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // constants
|
# // constants
|
||||||
|
@ -563,13 +561,13 @@ class GameManager:
|
||||||
if self.__games_by_name is None:
|
if self.__games_by_name is None:
|
||||||
l1, l2, l3 = [], [], []
|
l1, l2, l3 = [], [], []
|
||||||
for id, gi in self.__games.items():
|
for id, gi in self.__games.items():
|
||||||
name = gettext(gi.name).lower()
|
name = _(gi.name).lower()
|
||||||
l1.append((name, id))
|
l1.append((name, id))
|
||||||
if gi.name != gi.short_name:
|
if gi.name != gi.short_name:
|
||||||
name = gettext(gi.short_name).lower()
|
name = _(gi.short_name).lower()
|
||||||
l2.append((name, id))
|
l2.append((name, id))
|
||||||
for n in gi.altnames:
|
for n in gi.altnames:
|
||||||
name = gettext(n).lower()
|
name = _(n).lower()
|
||||||
l3.append((name, id, n))
|
l3.append((name, id, n))
|
||||||
l1.sort()
|
l1.sort()
|
||||||
l2.sort()
|
l2.sort()
|
||||||
|
|
|
@ -124,5 +124,5 @@ class DieBoeseSieben(Game):
|
||||||
registerGame(GameInfo(120, DieBoeseSieben, "Bad Seven",
|
registerGame(GameInfo(120, DieBoeseSieben, "Bad Seven",
|
||||||
GI.GT_2DECK_TYPE, 2, 1, GI.SL_MOSTLY_LUCK,
|
GI.GT_2DECK_TYPE, 2, 1, GI.SL_MOSTLY_LUCK,
|
||||||
ranks=(0, 6, 7, 8, 9, 10, 11, 12),
|
ranks=(0, 6, 7, 8, 9, 10, 11, 12),
|
||||||
altnames=("Die böse Sieben",) ))
|
altnames=("Die boese Sieben",) ))
|
||||||
|
|
||||||
|
|
|
@ -978,7 +978,7 @@ registerGame(GameInfo(65, Giant, "Giant",
|
||||||
GI.GT_GYPSY, 2, 0, GI.SL_MOSTLY_SKILL))
|
GI.GT_GYPSY, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||||
registerGame(GameInfo(3, Irmgard, "Irmgard",
|
registerGame(GameInfo(3, Irmgard, "Irmgard",
|
||||||
GI.GT_GYPSY, 2, 0, GI.SL_MOSTLY_SKILL))
|
GI.GT_GYPSY, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||||
registerGame(GameInfo(119, DieKoenigsbergerin, "Die Königsbergerin",
|
registerGame(GameInfo(119, DieKoenigsbergerin, "Die Koenigsbergerin",
|
||||||
GI.GT_GYPSY, 2, 0, GI.SL_MOSTLY_SKILL))
|
GI.GT_GYPSY, 2, 0, GI.SL_MOSTLY_SKILL))
|
||||||
registerGame(GameInfo(174, DieRussische, "Russian Patience",
|
registerGame(GameInfo(174, DieRussische, "Russian Patience",
|
||||||
GI.GT_2DECK_TYPE | GI.GT_OPEN, 2, 0, GI.SL_MOSTLY_SKILL,
|
GI.GT_2DECK_TYPE | GI.GT_OPEN, 2, 0, GI.SL_MOSTLY_SKILL,
|
||||||
|
|
|
@ -347,8 +347,7 @@ registerGame(GameInfo(28, DoubleKlondikeByThrees, "Double Klondike by Threes",
|
||||||
registerGame(GameInfo(25, Gargantua, "Gargantua",
|
registerGame(GameInfo(25, Gargantua, "Gargantua",
|
||||||
GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED))
|
GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED))
|
||||||
registerGame(GameInfo(15, BigHarp, "Big Harp",
|
registerGame(GameInfo(15, BigHarp, "Big Harp",
|
||||||
GI.GT_KLONDIKE, 2, 0, GI.SL_BALANCED,
|
GI.GT_KLONDIKE, 2, 0, GI.SL_BALANCED))
|
||||||
altnames=("Die große Harfe",) ))
|
|
||||||
registerGame(GameInfo(51, Steps, "Steps",
|
registerGame(GameInfo(51, Steps, "Steps",
|
||||||
GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED))
|
GI.GT_KLONDIKE, 2, 1, GI.SL_BALANCED))
|
||||||
registerGame(GameInfo(273, TripleKlondike, "Triple Klondike",
|
registerGame(GameInfo(273, TripleKlondike, "Triple Klondike",
|
||||||
|
|
|
@ -29,7 +29,34 @@ import settings
|
||||||
# // init
|
# // init
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
|
||||||
|
def fix_gettext():
|
||||||
|
def ugettext(message):
|
||||||
|
# unicoded gettext
|
||||||
|
domain = gettext._current_domain
|
||||||
|
try:
|
||||||
|
t = gettext.translation(domain,
|
||||||
|
gettext._localedirs.get(domain, None))
|
||||||
|
except IOError:
|
||||||
|
return message
|
||||||
|
return t.ugettext(message)
|
||||||
|
gettext.ugettext = ugettext
|
||||||
|
def ungettext(msgid1, msgid2, n):
|
||||||
|
# unicoded ngettext
|
||||||
|
domain = gettext._current_domain
|
||||||
|
try:
|
||||||
|
t = gettext.translation(domain,
|
||||||
|
gettext._localedirs.get(domain, None))
|
||||||
|
except IOError:
|
||||||
|
if n == 1:
|
||||||
|
return msgid1
|
||||||
|
else:
|
||||||
|
return msgid2
|
||||||
|
return t.ungettext(msgid1, msgid2, n)
|
||||||
|
gettext.ungettext = ungettext
|
||||||
|
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
|
fix_gettext()
|
||||||
|
|
||||||
if os.name == 'nt' and 'LANG' not in os.environ:
|
if os.name == 'nt' and 'LANG' not in os.environ:
|
||||||
try:
|
try:
|
||||||
|
@ -39,6 +66,7 @@ def init():
|
||||||
pass
|
pass
|
||||||
##locale.setlocale(locale.LC_ALL, '')
|
##locale.setlocale(locale.LC_ALL, '')
|
||||||
|
|
||||||
|
## install gettext
|
||||||
##locale_dir = 'locale'
|
##locale_dir = 'locale'
|
||||||
locale_dir = None
|
locale_dir = None
|
||||||
if os.path.isdir(sys.path[0]):
|
if os.path.isdir(sys.path[0]):
|
||||||
|
@ -49,8 +77,14 @@ def init():
|
||||||
if os.path.exists(d) and os.path.isdir(d):
|
if os.path.exists(d) and os.path.isdir(d):
|
||||||
locale_dir = d
|
locale_dir = d
|
||||||
##if locale_dir: locale_dir = os.path.normpath(locale_dir)
|
##if locale_dir: locale_dir = os.path.normpath(locale_dir)
|
||||||
gettext.install('pysol', locale_dir, unicode=True)
|
#gettext.install('pysol', locale_dir, unicode=True) # ngettext don't work
|
||||||
# debug
|
gettext.bindtextdomain('pysol', locale_dir)
|
||||||
|
gettext.textdomain('pysol')
|
||||||
|
import __builtin__
|
||||||
|
__builtin__.__dict__['_'] = gettext.ugettext # use unicode
|
||||||
|
__builtin__.__dict__['n_'] = lambda x: x
|
||||||
|
|
||||||
|
## debug
|
||||||
if 'PYSOL_CHECK_GAMES' in os.environ or \
|
if 'PYSOL_CHECK_GAMES' in os.environ or \
|
||||||
'PYSOL_DEBUG' in os.environ:
|
'PYSOL_DEBUG' in os.environ:
|
||||||
settings.CHECK_GAMES = True
|
settings.CHECK_GAMES = True
|
||||||
|
@ -61,6 +95,7 @@ def init():
|
||||||
except:
|
except:
|
||||||
settings.DEBUG = 1
|
settings.DEBUG = 1
|
||||||
print 'PySol debugging: set DEBUG to', settings.DEBUG
|
print 'PySol debugging: set DEBUG to', settings.DEBUG
|
||||||
|
|
||||||
## init toolkit
|
## init toolkit
|
||||||
if '--gtk' in sys.argv:
|
if '--gtk' in sys.argv:
|
||||||
settings.TOOLKIT = 'gtk'
|
settings.TOOLKIT = 'gtk'
|
||||||
|
|
|
@ -27,12 +27,6 @@ import gtk, gobject, pango
|
||||||
import gtk.glade
|
import gtk.glade
|
||||||
from gtk import gdk
|
from gtk import gdk
|
||||||
|
|
||||||
# PySol imports
|
|
||||||
|
|
||||||
# Toolkit imports
|
|
||||||
|
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
|
@ -125,5 +119,5 @@ class ColorsDialog:
|
||||||
'label79',
|
'label79',
|
||||||
):
|
):
|
||||||
w = self.widgets_tree.get_widget(n)
|
w = self.widgets_tree.get_widget(n)
|
||||||
w.set_text(gettext(w.get_text()))
|
w.set_text(_(w.get_text()))
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,8 @@ import gtk, gobject, pango
|
||||||
import gtk.glade
|
import gtk.glade
|
||||||
|
|
||||||
# PySol imports
|
# PySol imports
|
||||||
|
|
||||||
from tkutil import create_pango_font_desc
|
from tkutil import create_pango_font_desc
|
||||||
|
|
||||||
# Toolkit imports
|
|
||||||
|
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
|
@ -144,7 +139,7 @@ class FontsDialog:
|
||||||
'label75',
|
'label75',
|
||||||
):
|
):
|
||||||
w = self.widgets_tree.get_widget(n)
|
w = self.widgets_tree.get_widget(n)
|
||||||
w.set_text(gettext(w.get_text()))
|
w.set_text(_(w.get_text()))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,11 +50,9 @@ from selecttile import SelectTileDialogWithPreview
|
||||||
from selectgame import SelectGameDialogWithPreview
|
from selectgame import SelectGameDialogWithPreview
|
||||||
from findcarddialog import connect_game_find_card_dialog, destroy_find_card_dialog
|
from findcarddialog import connect_game_find_card_dialog, destroy_find_card_dialog
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
def ltk2gtk(s):
|
def ltk2gtk(s):
|
||||||
# label tk to gtk
|
# label tk to gtk
|
||||||
return gettext(s).replace('&', '_')
|
return _(s).replace('&', '_')
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
|
@ -499,7 +497,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
label = gi.short_name
|
label = gi.short_name
|
||||||
else:
|
else:
|
||||||
label = gi.name
|
label = gi.name
|
||||||
label = gettext(label)
|
label = _(label)
|
||||||
menu_item = gtk.MenuItem(label)
|
menu_item = gtk.MenuItem(label)
|
||||||
menu_item.set_data('user_data', gi.id)
|
menu_item.set_data('user_data', gi.id)
|
||||||
menu_item.connect('activate', self.mSelectGame)
|
menu_item.connect('activate', self.mSelectGame)
|
||||||
|
@ -521,7 +519,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
break
|
break
|
||||||
m = min(n+d-1, len(games)-1)
|
m = min(n+d-1, len(games)-1)
|
||||||
n1, n2 = games[n].name, games[m].name
|
n1, n2 = games[n].name, games[m].name
|
||||||
n1, n2 = gettext(n1), gettext(n2)
|
n1, n2 = _(n1), _(n2)
|
||||||
label = n1[:3]+' - '+n2[:3]
|
label = n1[:3]+' - '+n2[:3]
|
||||||
submenu = self._createSubMenu(menu, label=label)
|
submenu = self._createSubMenu(menu, label=label)
|
||||||
self._addGamesSubMenu(games[n:n+d], submenu)
|
self._addGamesSubMenu(games[n:n+d], submenu)
|
||||||
|
@ -566,7 +564,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
#
|
#
|
||||||
games = {}
|
games = {}
|
||||||
for gi in mahjongg_games:
|
for gi in mahjongg_games:
|
||||||
c = gettext(gi.short_name).strip()[0]
|
c = _(gi.short_name).strip()[0]
|
||||||
if c in games:
|
if c in games:
|
||||||
games[c].append(gi)
|
games[c].append(gi)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -116,7 +116,7 @@ class SelectCardsetDialogWithPreview(MfxDialog):
|
||||||
store.set(iter, 0, root_label, 1, -1)
|
store.set(iter, 0, root_label, 1, -1)
|
||||||
for index, name in cardsets:
|
for index, name in cardsets:
|
||||||
child_iter = store.append(iter)
|
child_iter = store.append(iter)
|
||||||
##~ name = gettext(name)
|
##~ name = _(name)
|
||||||
store.set(child_iter, 0, name, 1, index)
|
store.set(child_iter, 0, name, 1, index)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -54,8 +54,6 @@ from tkwidget import MfxDialog
|
||||||
from tkcanvas import MfxCanvas, MfxCanvasText
|
from tkcanvas import MfxCanvas, MfxCanvasText
|
||||||
from pysoltree import PysolTreeView
|
from pysoltree import PysolTreeView
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // Dialog
|
# // Dialog
|
||||||
|
@ -197,7 +195,7 @@ class SelectGameDialogWithPreview(MfxDialog):
|
||||||
iter = store.append(root_iter)
|
iter = store.append(root_iter)
|
||||||
store.set(iter, 0, root_label, 1, -1)
|
store.set(iter, 0, root_label, 1, -1)
|
||||||
for label, games in gl:
|
for label, games in gl:
|
||||||
label = gettext(label)
|
label = _(label)
|
||||||
label = label.replace("&", "")
|
label = label.replace("&", "")
|
||||||
self._addGames(store, iter, label, games)
|
self._addGames(store, iter, label, games)
|
||||||
|
|
||||||
|
@ -209,7 +207,7 @@ class SelectGameDialogWithPreview(MfxDialog):
|
||||||
store.set(iter, 0, root_label, 1, -1)
|
store.set(iter, 0, root_label, 1, -1)
|
||||||
for id, name in games:
|
for id, name in games:
|
||||||
child_iter = store.append(iter)
|
child_iter = store.append(iter)
|
||||||
name = gettext(name)
|
name = _(name)
|
||||||
store.set(child_iter, 0, name, 1, id)
|
store.set(child_iter, 0, name, 1, id)
|
||||||
|
|
||||||
|
|
||||||
|
@ -294,7 +292,7 @@ class SelectGameDialogWithPreview(MfxDialog):
|
||||||
data = []
|
data = []
|
||||||
for label, vg in GI.GAMES_BY_COMPATIBILITY:
|
for label, vg in GI.GAMES_BY_COMPATIBILITY:
|
||||||
selecter = lambda gi, vg=vg: gi.id in vg
|
selecter = lambda gi, vg=vg: gi.id in vg
|
||||||
label = gettext(label)
|
label = _(label)
|
||||||
data.append((label, selecter))
|
data.append((label, selecter))
|
||||||
self._addGamesFromData(data, store, root_iter,
|
self._addGamesFromData(data, store, root_iter,
|
||||||
_("by Compatibility"), all_games)
|
_("by Compatibility"), all_games)
|
||||||
|
@ -475,12 +473,12 @@ class SelectGameDialogWithPreview(MfxDialog):
|
||||||
def updateInfo(self, gameid):
|
def updateInfo(self, gameid):
|
||||||
gi = self.app.gdb.get(gameid)
|
gi = self.app.gdb.get(gameid)
|
||||||
# info
|
# info
|
||||||
name = gettext(gi.name)
|
name = _(gi.name)
|
||||||
altnames = '\n'.join([gettext(n) for n in gi.altnames])
|
altnames = '\n'.join([_(n) for n in gi.altnames])
|
||||||
category = gettext(CSI.TYPE[gi.category])
|
category = _(CSI.TYPE[gi.category])
|
||||||
type = ''
|
type = ''
|
||||||
if gi.si.game_type in GI.TYPE_NAMES:
|
if gi.si.game_type in GI.TYPE_NAMES:
|
||||||
type = gettext(GI.TYPE_NAMES[gi.si.game_type])
|
type = _(GI.TYPE_NAMES[gi.si.game_type])
|
||||||
sl = {
|
sl = {
|
||||||
GI.SL_LUCK: _('Luck only'),
|
GI.SL_LUCK: _('Luck only'),
|
||||||
GI.SL_MOSTLY_LUCK: _('Mostly luck'),
|
GI.SL_MOSTLY_LUCK: _('Mostly luck'),
|
||||||
|
|
|
@ -30,8 +30,6 @@ from gtk import glade
|
||||||
# Toolkit imports
|
# Toolkit imports
|
||||||
from tkwidget import MfxDialog
|
from tkwidget import MfxDialog
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
|
@ -149,7 +147,7 @@ class SoundOptionsDialog:
|
||||||
'label78',
|
'label78',
|
||||||
):
|
):
|
||||||
w = self.widgets_tree.get_widget(n)
|
w = self.widgets_tree.get_widget(n)
|
||||||
w.set_text(gettext(w.get_text()))
|
w.set_text(_(w.get_text()))
|
||||||
w = self.widgets_tree.get_widget('enable_checkbutton')
|
w = self.widgets_tree.get_widget('enable_checkbutton')
|
||||||
w.set_label(gettext(w.get_label()))
|
w.set_label(_(w.get_label()))
|
||||||
|
|
||||||
|
|
|
@ -26,12 +26,6 @@ __all__ = ['TimeoutsDialog']
|
||||||
import gtk, gobject, pango
|
import gtk, gobject, pango
|
||||||
import gtk.glade
|
import gtk.glade
|
||||||
|
|
||||||
# PySol imports
|
|
||||||
|
|
||||||
# Toolkit imports
|
|
||||||
|
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
|
@ -102,5 +96,5 @@ class TimeoutsDialog:
|
||||||
'label30',
|
'label30',
|
||||||
):
|
):
|
||||||
w = self.widgets_tree.get_widget(n)
|
w = self.widgets_tree.get_widget(n)
|
||||||
w.set_text(gettext(w.get_text()))
|
w.set_text(_(w.get_text()))
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,6 @@ from pysollib.stats import PysolStatsFormatter
|
||||||
# Toolkit imports
|
# Toolkit imports
|
||||||
from tkwidget import MfxDialog, MfxMessageDialog
|
from tkwidget import MfxDialog, MfxMessageDialog
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
|
@ -50,7 +48,7 @@ class StatsFormatter(PysolStatsFormatter):
|
||||||
for result in self.getStatResults(player, sort_by):
|
for result in self.getStatResults(player, sort_by):
|
||||||
iter = self.store.append(None)
|
iter = self.store.append(None)
|
||||||
self.store.set(iter,
|
self.store.set(iter,
|
||||||
0, gettext(result[0]),
|
0, _(result[0]),
|
||||||
1, result[1],
|
1, result[1],
|
||||||
2, result[2],
|
2, result[2],
|
||||||
3, result[3],
|
3, result[3],
|
||||||
|
@ -88,7 +86,7 @@ class LogFormatter(PysolStatsFormatter):
|
||||||
for result in self.getLogResults(player, prev_games):
|
for result in self.getLogResults(player, prev_games):
|
||||||
iter = self.store.append(None)
|
iter = self.store.append(None)
|
||||||
self.store.set(iter,
|
self.store.set(iter,
|
||||||
0, gettext(result[0]),
|
0, _(result[0]),
|
||||||
1, result[1],
|
1, result[1],
|
||||||
2, result[2],
|
2, result[2],
|
||||||
3, result[3],
|
3, result[3],
|
||||||
|
@ -189,7 +187,7 @@ class Game_StatsDialog:
|
||||||
'label18',
|
'label18',
|
||||||
):
|
):
|
||||||
w = self.widgets_tree.get_widget(n)
|
w = self.widgets_tree.get_widget(n)
|
||||||
w.set_text_with_mnemonic(gettext(w.get_label()))
|
w.set_text_with_mnemonic(_(w.get_label()))
|
||||||
# simple
|
# simple
|
||||||
for n in (
|
for n in (
|
||||||
'label5',
|
'label5',
|
||||||
|
@ -198,7 +196,7 @@ class Game_StatsDialog:
|
||||||
'label14'
|
'label14'
|
||||||
):
|
):
|
||||||
w = self.widgets_tree.get_widget(n)
|
w = self.widgets_tree.get_widget(n)
|
||||||
w.set_text(gettext(w.get_text()))
|
w.set_text(_(w.get_text()))
|
||||||
# markup
|
# markup
|
||||||
for n in (
|
for n in (
|
||||||
'label8',
|
'label8',
|
||||||
|
@ -215,7 +213,7 @@ class Game_StatsDialog:
|
||||||
'label24',
|
'label24',
|
||||||
):
|
):
|
||||||
w = self.widgets_tree.get_widget(n)
|
w = self.widgets_tree.get_widget(n)
|
||||||
s = gettext(w.get_label())
|
s = _(w.get_label())
|
||||||
w.set_markup('<b>%s</b>' % s)
|
w.set_markup('<b>%s</b>' % s)
|
||||||
|
|
||||||
|
|
||||||
|
@ -231,7 +229,7 @@ class Game_StatsDialog:
|
||||||
current = 0
|
current = 0
|
||||||
for id in self.games_id:
|
for id in self.games_id:
|
||||||
gi = self.app.gdb.get(id)
|
gi = self.app.gdb.get(id)
|
||||||
combo.append_text(gettext(gi.name))
|
combo.append_text(_(gi.name))
|
||||||
if id == self.gameid:
|
if id == self.gameid:
|
||||||
current = n
|
current = n
|
||||||
n += 1
|
n += 1
|
||||||
|
|
|
@ -41,7 +41,6 @@ import os, glob
|
||||||
from mfxutil import Struct, KwStruct, EnvError
|
from mfxutil import Struct, KwStruct, EnvError
|
||||||
from settings import DEBUG
|
from settings import DEBUG
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // Abstract
|
# // Abstract
|
||||||
|
|
|
@ -1517,10 +1517,10 @@ class Stack:
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def getNumCards(self):
|
def getNumCards(self):
|
||||||
|
from gettext import ungettext
|
||||||
n = len(self.cards)
|
n = len(self.cards)
|
||||||
if n == 0 : return _('No cards')
|
if n == 0 : return _('No cards')
|
||||||
elif n == 1 : return _('1 card')
|
else: return ungettext('%d card', '%d cards', n) % n
|
||||||
else : return str(n)+_(' cards')
|
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
|
@ -1795,11 +1795,12 @@ class TalonStack(Stack,
|
||||||
return self.game.app.gimages.redeal
|
return self.game.app.gimages.redeal
|
||||||
|
|
||||||
def getHelp(self):
|
def getHelp(self):
|
||||||
|
from gettext import ungettext
|
||||||
if self.max_rounds == -2: nredeals = _('Variable redeals.')
|
if self.max_rounds == -2: nredeals = _('Variable redeals.')
|
||||||
elif self.max_rounds == -1: nredeals = _('Unlimited redeals.')
|
elif self.max_rounds == -1: nredeals = _('Unlimited redeals.')
|
||||||
elif self.max_rounds == 1: nredeals = _('No redeals.')
|
else:
|
||||||
elif self.max_rounds == 2: nredeals = _('One redeal.')
|
n = self.max_rounds-1
|
||||||
else: nredeals = str(self.max_rounds-1)+_(' redeals.')
|
nredeals = ungettext('%d readeal', '%d redeals', n) % n
|
||||||
##round = _('Round #%d.') % self.round
|
##round = _('Round #%d.') % self.round
|
||||||
return _('Talon.')+' '+nredeals ##+' '+round
|
return _('Talon.')+' '+nredeals ##+' '+round
|
||||||
|
|
||||||
|
|
|
@ -68,9 +68,6 @@ from tkwidget import MfxMessageDialog
|
||||||
#from toolbar import TOOLBAR_BUTTONS
|
#from toolbar import TOOLBAR_BUTTONS
|
||||||
from tkconst import TOOLBAR_BUTTONS
|
from tkconst import TOOLBAR_BUTTONS
|
||||||
|
|
||||||
gettext = _
|
|
||||||
n_ = lambda x: x
|
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
|
@ -120,7 +117,7 @@ def createToolbarMenu(menubar, menu):
|
||||||
menu.add_separator()
|
menu.add_separator()
|
||||||
submenu = MfxMenu(menu, label=n_('Visible buttons'), tearoff=tearoff)
|
submenu = MfxMenu(menu, label=n_('Visible buttons'), tearoff=tearoff)
|
||||||
for w in TOOLBAR_BUTTONS:
|
for w in TOOLBAR_BUTTONS:
|
||||||
submenu.add_checkbutton(label=gettext(w.capitalize()),
|
submenu.add_checkbutton(label=_(w.capitalize()),
|
||||||
variable=menubar.tkopt.toolbar_vars[w],
|
variable=menubar.tkopt.toolbar_vars[w],
|
||||||
command=lambda m=menubar, w=w: m.mOptToolbarConfig(w))
|
command=lambda m=menubar, w=w: m.mOptToolbarConfig(w))
|
||||||
|
|
||||||
|
@ -141,7 +138,7 @@ class MfxMenubar(Tkinter.Menu):
|
||||||
def labeltoname(self, label):
|
def labeltoname(self, label):
|
||||||
#print label, type(label)
|
#print label, type(label)
|
||||||
name = re.sub(r"[^0-9a-zA-Z]", "", label).lower()
|
name = re.sub(r"[^0-9a-zA-Z]", "", label).lower()
|
||||||
label = gettext(label)
|
label = _(label)
|
||||||
underline = label.find('&')
|
underline = label.find('&')
|
||||||
if underline >= 0:
|
if underline >= 0:
|
||||||
label = label.replace('&', '')
|
label = label.replace('&', '')
|
||||||
|
@ -705,7 +702,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
|
|
||||||
games = {}
|
games = {}
|
||||||
for gi in mahjongg_games:
|
for gi in mahjongg_games:
|
||||||
c = gettext(gi.short_name).strip()[0]
|
c = _(gi.short_name).strip()[0]
|
||||||
if c in games:
|
if c in games:
|
||||||
games[c].append(gi)
|
games[c].append(gi)
|
||||||
else:
|
else:
|
||||||
|
@ -773,7 +770,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
if not games[n:n+d]:
|
if not games[n:n+d]:
|
||||||
break
|
break
|
||||||
m = min(n+d-1, len(games)-1)
|
m = min(n+d-1, len(games)-1)
|
||||||
label = gettext(games[n].name)[:3]+' - '+gettext(games[m].name)[:3]
|
label = _(games[n].name)[:3]+' - '+_(games[m].name)[:3]
|
||||||
submenu = MfxMenu(menu, label=label, name=None)
|
submenu = MfxMenu(menu, label=label, name=None)
|
||||||
self._addSelectGameSubSubMenu(games[n:n+d], submenu,
|
self._addSelectGameSubSubMenu(games[n:n+d], submenu,
|
||||||
command, variable)
|
command, variable)
|
||||||
|
@ -790,9 +787,9 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
gi = games[i]
|
gi = games[i]
|
||||||
columnbreak = i > 0 and (i % cb) == 0
|
columnbreak = i > 0 and (i % cb) == 0
|
||||||
if short_name:
|
if short_name:
|
||||||
label = gettext(gi.short_name)
|
label = _(gi.short_name)
|
||||||
else:
|
else:
|
||||||
label = gettext(gi.name)
|
label = _(gi.name)
|
||||||
## menu.add_radiobutton(command=command, variable=variable,
|
## menu.add_radiobutton(command=command, variable=variable,
|
||||||
## columnbreak=columnbreak,
|
## columnbreak=columnbreak,
|
||||||
## value=gi.id, label=label, name=None)
|
## value=gi.id, label=label, name=None)
|
||||||
|
@ -809,7 +806,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
if len(games) == 0:
|
if len(games) == 0:
|
||||||
menu.add_radiobutton(label='<none>', name=None, state='disabled')
|
menu.add_radiobutton(label='<none>', name=None, state='disabled')
|
||||||
elif len(games) > self.__cb_max*4:
|
elif len(games) > self.__cb_max*4:
|
||||||
games.sort(lambda a, b: cmp(gettext(a.name), gettext(b.name)))
|
games.sort(lambda a, b: cmp(_(a.name), _(b.name)))
|
||||||
self._addSelectAllGameSubMenu(games, menu,
|
self._addSelectAllGameSubMenu(games, menu,
|
||||||
command=self.mSelectGame,
|
command=self.mSelectGame,
|
||||||
variable=self.tkopt.gameid)
|
variable=self.tkopt.gameid)
|
||||||
|
|
|
@ -53,7 +53,6 @@ from tkcanvas import MfxCanvasText
|
||||||
from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode
|
from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode
|
||||||
from selecttree import SelectDialogTreeData, SelectDialogTreeCanvas
|
from selecttree import SelectDialogTreeData, SelectDialogTreeCanvas
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // Nodes
|
# // Nodes
|
||||||
|
@ -70,7 +69,7 @@ class SelectGameNode(SelectDialogTreeNode):
|
||||||
# key/value pairs
|
# key/value pairs
|
||||||
for id, name in self.select_func:
|
for id, name in self.select_func:
|
||||||
if id and name:
|
if id and name:
|
||||||
name = gettext(name) # name of game
|
name = _(name) # name of game
|
||||||
node = SelectGameLeaf(self.tree, self, name, key=id)
|
node = SelectGameLeaf(self.tree, self, name, key=id)
|
||||||
contents.append(node)
|
contents.append(node)
|
||||||
else:
|
else:
|
||||||
|
@ -79,12 +78,12 @@ class SelectGameNode(SelectDialogTreeNode):
|
||||||
# All games
|
# All games
|
||||||
##name = '%s (%s)' % (gi.name, CSI.TYPE_NAME[gi.category])
|
##name = '%s (%s)' % (gi.name, CSI.TYPE_NAME[gi.category])
|
||||||
name = gi.name
|
name = gi.name
|
||||||
name = gettext(name) # name of game
|
name = _(name) # name of game
|
||||||
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
|
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
|
||||||
contents.append(node)
|
contents.append(node)
|
||||||
elif gi and self.select_func(gi):
|
elif gi and self.select_func(gi):
|
||||||
name = gi.name
|
name = gi.name
|
||||||
name = gettext(name) # name of game
|
name = _(name) # name of game
|
||||||
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
|
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
|
||||||
contents.append(node)
|
contents.append(node)
|
||||||
return contents or self.tree.data.no_games
|
return contents or self.tree.data.no_games
|
||||||
|
@ -112,7 +111,7 @@ class SelectGameData(SelectDialogTreeData):
|
||||||
for name, select_func in data:
|
for name, select_func in data:
|
||||||
if name is None or not filter(select_func, self.all_games_gi):
|
if name is None or not filter(select_func, self.all_games_gi):
|
||||||
continue
|
continue
|
||||||
name = gettext(name)
|
name = _(name)
|
||||||
name = name.replace("&", "")
|
name = name.replace("&", "")
|
||||||
gg.append(SelectGameNode(None, name, select_func))
|
gg.append(SelectGameNode(None, name, select_func))
|
||||||
g.append(gg)
|
g.append(gg)
|
||||||
|
@ -139,7 +138,7 @@ class SelectGameData(SelectDialogTreeData):
|
||||||
select_func = lambda gi, games=games: gi.id in games
|
select_func = lambda gi, games=games: gi.id in games
|
||||||
if name is None or not filter(select_func, self.all_games_gi):
|
if name is None or not filter(select_func, self.all_games_gi):
|
||||||
continue
|
continue
|
||||||
name = gettext(name)
|
name = _(name)
|
||||||
gg.append(SelectGameNode(None, name, select_func))
|
gg.append(SelectGameNode(None, name, select_func))
|
||||||
if 1 and gg:
|
if 1 and gg:
|
||||||
s_by_compatibility = SelectGameNode(None, _("by Compatibility"), tuple(gg))
|
s_by_compatibility = SelectGameNode(None, _("by Compatibility"), tuple(gg))
|
||||||
|
@ -514,12 +513,12 @@ class SelectGameDialogWithPreview(SelectGameDialog):
|
||||||
def updateInfo(self, gameid):
|
def updateInfo(self, gameid):
|
||||||
gi = self.app.gdb.get(gameid)
|
gi = self.app.gdb.get(gameid)
|
||||||
# info
|
# info
|
||||||
name = gettext(gi.name)
|
name = _(gi.name)
|
||||||
altnames = '\n'.join([gettext(n) for n in gi.altnames])
|
altnames = '\n'.join([_(n) for n in gi.altnames])
|
||||||
category = gettext(CSI.TYPE[gi.category])
|
category = _(CSI.TYPE[gi.category])
|
||||||
type = ''
|
type = ''
|
||||||
if gi.si.game_type in GI.TYPE_NAMES:
|
if gi.si.game_type in GI.TYPE_NAMES:
|
||||||
type = gettext(GI.TYPE_NAMES[gi.si.game_type])
|
type = _(GI.TYPE_NAMES[gi.si.game_type])
|
||||||
sl = {
|
sl = {
|
||||||
GI.SL_LUCK: _('Luck only'),
|
GI.SL_LUCK: _('Luck only'),
|
||||||
GI.SL_MOSTLY_LUCK: _('Mostly luck'),
|
GI.SL_MOSTLY_LUCK: _('Mostly luck'),
|
||||||
|
|
|
@ -42,8 +42,6 @@ from tkwidget import MfxDialog
|
||||||
from tkwidget import PysolScale
|
from tkwidget import PysolScale
|
||||||
from tkutil import bind, unbind_destroy
|
from tkutil import bind, unbind_destroy
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
|
@ -82,7 +80,7 @@ class SolverDialog(MfxDialog):
|
||||||
gamenames = ['']
|
gamenames = ['']
|
||||||
for id in games:
|
for id in games:
|
||||||
name = app.getGameTitleName(id)
|
name = app.getGameTitleName(id)
|
||||||
name = gettext(name)
|
name = _(name)
|
||||||
gamenames.append(name)
|
gamenames.append(name)
|
||||||
self.games[name] = id
|
self.games[name] = id
|
||||||
gamenames.sort()
|
gamenames.sort()
|
||||||
|
@ -238,7 +236,7 @@ class SolverDialog(MfxDialog):
|
||||||
|
|
||||||
def connectGame(self, game):
|
def connectGame(self, game):
|
||||||
name = self.app.getGameTitleName(game.id)
|
name = self.app.getGameTitleName(game.id)
|
||||||
name = gettext(name)
|
name = _(name)
|
||||||
if name in self.gamenames:
|
if name in self.gamenames:
|
||||||
self.start_button.config(state='normal')
|
self.start_button.config(state='normal')
|
||||||
i = self.gamenames.index(name)
|
i = self.gamenames.index(name)
|
||||||
|
|
|
@ -59,9 +59,6 @@ import sys, os
|
||||||
import traceback
|
import traceback
|
||||||
import Tkinter
|
import Tkinter
|
||||||
|
|
||||||
# Toolkit imports
|
|
||||||
|
|
||||||
n_ = lambda x: x
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // constants
|
# // constants
|
||||||
|
|
|
@ -60,8 +60,6 @@ from tkutil import bind, unbind_destroy, loadImage
|
||||||
from tkwidget import MfxDialog, MfxMessageDialog
|
from tkwidget import MfxDialog, MfxMessageDialog
|
||||||
from tkwidget import MfxScrolledCanvas
|
from tkwidget import MfxScrolledCanvas
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
|
@ -376,7 +374,7 @@ class TreeFormatter(PysolStatsFormatter):
|
||||||
for result in self.getStatResults(player, sort_by):
|
for result in self.getStatResults(player, sort_by):
|
||||||
# result == [name, won+lost, won, lost, time, moves, perc, id]
|
# result == [name, won+lost, won, lost, time, moves, perc, id]
|
||||||
t1, t2, t3, t4, t5, t6, t7, t8 = result
|
t1, t2, t3, t4, t5, t6, t7, t8 = result
|
||||||
t1=gettext(t1) # game name
|
t1 = _(t1) # game name
|
||||||
id = self.tree.insert(None, "end", text=t1,
|
id = self.tree.insert(None, "end", text=t1,
|
||||||
values=(t2, t3, t4, t5, t6, t7))
|
values=(t2, t3, t4, t5, t6, t7))
|
||||||
self.parent_window.tree_items.append(id)
|
self.parent_window.tree_items.append(id)
|
||||||
|
@ -395,7 +393,7 @@ class TreeFormatter(PysolStatsFormatter):
|
||||||
num_rows = 0
|
num_rows = 0
|
||||||
for result in self.getLogResults(player, prev_games):
|
for result in self.getLogResults(player, prev_games):
|
||||||
t1, t2, t3, t4, t5, t6 = result
|
t1, t2, t3, t4, t5, t6 = result
|
||||||
t1=gettext(t1) # game name
|
t1 = _(t1) # game name
|
||||||
id = self.tree.insert(None, "end", text=t1, values=(t2, t3, t4))
|
id = self.tree.insert(None, "end", text=t1, values=(t2, t3, t4))
|
||||||
self.parent_window.tree_items.append(id)
|
self.parent_window.tree_items.append(id)
|
||||||
num_rows += 1
|
num_rows += 1
|
||||||
|
|
|
@ -52,9 +52,6 @@ from tkconst import EVENT_HANDLED, EVENT_PROPAGATE
|
||||||
from tkwidget import MfxTooltip
|
from tkwidget import MfxTooltip
|
||||||
from menubar import createToolbarMenu, MfxMenu
|
from menubar import createToolbarMenu, MfxMenu
|
||||||
|
|
||||||
gettext = _
|
|
||||||
n_ = lambda x: x
|
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
|
@ -288,7 +285,7 @@ class PysolToolbar(PysolToolbarActions):
|
||||||
'toolbar_name' : name,
|
'toolbar_name' : name,
|
||||||
'command' : command,
|
'command' : command,
|
||||||
'takefocus' : 0,
|
'takefocus' : 0,
|
||||||
'text' : gettext(label),
|
'text' : _(label),
|
||||||
}
|
}
|
||||||
if image:
|
if image:
|
||||||
kw['image'] = image
|
kw['image'] = image
|
||||||
|
|
|
@ -35,8 +35,6 @@ from tkwidget import MfxDialog
|
||||||
from tkwidget import PysolScale
|
from tkwidget import PysolScale
|
||||||
|
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
@ -68,8 +66,8 @@ class WizardDialog(MfxDialog):
|
||||||
if w.widget == 'preset':
|
if w.widget == 'preset':
|
||||||
if w.variable is None:
|
if w.variable is None:
|
||||||
w.variable = StringVar()
|
w.variable = StringVar()
|
||||||
values = [gettext(v) for v in w.values]
|
values = [_(v) for v in w.values]
|
||||||
default = gettext(w.default)
|
default = _(w.default)
|
||||||
values.remove(default)
|
values.remove(default)
|
||||||
values.sort()
|
values.sort()
|
||||||
values.insert(0, default)
|
values.insert(0, default)
|
||||||
|
@ -87,7 +85,7 @@ class WizardDialog(MfxDialog):
|
||||||
elif w.widget == 'menu':
|
elif w.widget == 'menu':
|
||||||
if w.variable is None:
|
if w.variable is None:
|
||||||
w.variable = StringVar()
|
w.variable = StringVar()
|
||||||
values = [gettext(v) for v in w.values]
|
values = [_(v) for v in w.values]
|
||||||
cb = Combobox(frame, values=tuple(values),
|
cb = Combobox(frame, values=tuple(values),
|
||||||
textvariable=w.variable,
|
textvariable=w.variable,
|
||||||
state='readonly', width=32)
|
state='readonly', width=32)
|
||||||
|
@ -116,7 +114,7 @@ class WizardDialog(MfxDialog):
|
||||||
else:
|
else:
|
||||||
v = w.current_value
|
v = w.current_value
|
||||||
if w.widget in ('menu', 'preset'):
|
if w.widget in ('menu', 'preset'):
|
||||||
v = gettext(v)
|
v = _(v)
|
||||||
w.variable.set(v)
|
w.variable.set(v)
|
||||||
|
|
||||||
row += 1
|
row += 1
|
||||||
|
@ -136,8 +134,8 @@ class WizardDialog(MfxDialog):
|
||||||
v = p[w.var_name]
|
v = p[w.var_name]
|
||||||
else:
|
else:
|
||||||
v = w.default
|
v = w.default
|
||||||
if w.widget in ('menu', 'preset'):
|
if w.widget in ('menu', 'preset', 'entry'):
|
||||||
v = gettext(v)
|
v = _(v)
|
||||||
w.variable.set(v)
|
w.variable.set(v)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -66,9 +66,6 @@ from tkwrap import MfxRadioMenuItem, MfxCheckMenuItem, StringVar
|
||||||
#from toolbar import TOOLBAR_BUTTONS
|
#from toolbar import TOOLBAR_BUTTONS
|
||||||
from tkconst import TOOLBAR_BUTTONS
|
from tkconst import TOOLBAR_BUTTONS
|
||||||
|
|
||||||
gettext = _
|
|
||||||
n_ = lambda x: x
|
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
|
@ -119,7 +116,7 @@ def createToolbarMenu(menubar, menu):
|
||||||
menu.add_separator()
|
menu.add_separator()
|
||||||
submenu = MfxMenu(menu, label=n_('Visible buttons'), tearoff=tearoff)
|
submenu = MfxMenu(menu, label=n_('Visible buttons'), tearoff=tearoff)
|
||||||
for w in TOOLBAR_BUTTONS:
|
for w in TOOLBAR_BUTTONS:
|
||||||
submenu.add_checkbutton(label=gettext(w.capitalize()),
|
submenu.add_checkbutton(label=_(w.capitalize()),
|
||||||
variable=menubar.tkopt.toolbar_vars[w],
|
variable=menubar.tkopt.toolbar_vars[w],
|
||||||
command=lambda m=menubar, w=w: m.mOptToolbarConfig(w))
|
command=lambda m=menubar, w=w: m.mOptToolbarConfig(w))
|
||||||
|
|
||||||
|
@ -140,7 +137,7 @@ class MfxMenubar(Tkinter.Menu):
|
||||||
def labeltoname(self, label):
|
def labeltoname(self, label):
|
||||||
#print label, type(label)
|
#print label, type(label)
|
||||||
name = re.sub(r"[^0-9a-zA-Z]", "", label).lower()
|
name = re.sub(r"[^0-9a-zA-Z]", "", label).lower()
|
||||||
label = gettext(label)
|
label = _(label)
|
||||||
underline = label.find('&')
|
underline = label.find('&')
|
||||||
if underline >= 0:
|
if underline >= 0:
|
||||||
label = label.replace('&', '')
|
label = label.replace('&', '')
|
||||||
|
@ -709,7 +706,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
|
|
||||||
games = {}
|
games = {}
|
||||||
for gi in mahjongg_games:
|
for gi in mahjongg_games:
|
||||||
c = gettext(gi.short_name).strip()[0]
|
c = _(gi.short_name).strip()[0]
|
||||||
if c in games:
|
if c in games:
|
||||||
games[c].append(gi)
|
games[c].append(gi)
|
||||||
else:
|
else:
|
||||||
|
@ -777,7 +774,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
if not games[n:n+d]:
|
if not games[n:n+d]:
|
||||||
break
|
break
|
||||||
m = min(n+d-1, len(games)-1)
|
m = min(n+d-1, len(games)-1)
|
||||||
label = gettext(games[n].name)[:3]+' - '+gettext(games[m].name)[:3]
|
label = _(games[n].name)[:3]+' - '+_(games[m].name)[:3]
|
||||||
submenu = MfxMenu(menu, label=label, name=None)
|
submenu = MfxMenu(menu, label=label, name=None)
|
||||||
self._addSelectGameSubSubMenu(games[n:n+d], submenu,
|
self._addSelectGameSubSubMenu(games[n:n+d], submenu,
|
||||||
command, variable)
|
command, variable)
|
||||||
|
@ -794,9 +791,9 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
gi = games[i]
|
gi = games[i]
|
||||||
columnbreak = i > 0 and (i % cb) == 0
|
columnbreak = i > 0 and (i % cb) == 0
|
||||||
if short_name:
|
if short_name:
|
||||||
label = gettext(gi.short_name)
|
label = _(gi.short_name)
|
||||||
else:
|
else:
|
||||||
label = gettext(gi.name)
|
label = _(gi.name)
|
||||||
## menu.add_radiobutton(command=command, variable=variable,
|
## menu.add_radiobutton(command=command, variable=variable,
|
||||||
## columnbreak=columnbreak,
|
## columnbreak=columnbreak,
|
||||||
## value=gi.id, label=label, name=None)
|
## value=gi.id, label=label, name=None)
|
||||||
|
@ -813,7 +810,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
if len(games) == 0:
|
if len(games) == 0:
|
||||||
menu.add_radiobutton(label='<none>', name=None, state='disabled')
|
menu.add_radiobutton(label='<none>', name=None, state='disabled')
|
||||||
elif len(games) > self.__cb_max*4:
|
elif len(games) > self.__cb_max*4:
|
||||||
games.sort(lambda a, b: cmp(gettext(a.name), gettext(b.name)))
|
games.sort(lambda a, b: cmp(_(a.name), _(b.name)))
|
||||||
self._addSelectAllGameSubMenu(games, menu,
|
self._addSelectAllGameSubMenu(games, menu,
|
||||||
command=self.mSelectGame,
|
command=self.mSelectGame,
|
||||||
variable=self.tkopt.gameid)
|
variable=self.tkopt.gameid)
|
||||||
|
|
|
@ -52,7 +52,6 @@ from tkcanvas import MfxCanvasText
|
||||||
from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode
|
from selecttree import SelectDialogTreeLeaf, SelectDialogTreeNode
|
||||||
from selecttree import SelectDialogTreeData, SelectDialogTreeCanvas
|
from selecttree import SelectDialogTreeData, SelectDialogTreeCanvas
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // Nodes
|
# // Nodes
|
||||||
|
@ -69,7 +68,7 @@ class SelectGameNode(SelectDialogTreeNode):
|
||||||
# key/value pairs
|
# key/value pairs
|
||||||
for id, name in self.select_func:
|
for id, name in self.select_func:
|
||||||
if id and name:
|
if id and name:
|
||||||
name = gettext(name) # name of game
|
name = _(name) # name of game
|
||||||
node = SelectGameLeaf(self.tree, self, name, key=id)
|
node = SelectGameLeaf(self.tree, self, name, key=id)
|
||||||
contents.append(node)
|
contents.append(node)
|
||||||
else:
|
else:
|
||||||
|
@ -78,12 +77,12 @@ class SelectGameNode(SelectDialogTreeNode):
|
||||||
# All games
|
# All games
|
||||||
##name = '%s (%s)' % (gi.name, CSI.TYPE_NAME[gi.category])
|
##name = '%s (%s)' % (gi.name, CSI.TYPE_NAME[gi.category])
|
||||||
name = gi.name
|
name = gi.name
|
||||||
name = gettext(name) # name of game
|
name = _(name) # name of game
|
||||||
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
|
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
|
||||||
contents.append(node)
|
contents.append(node)
|
||||||
elif gi and self.select_func(gi):
|
elif gi and self.select_func(gi):
|
||||||
name = gi.name
|
name = gi.name
|
||||||
name = gettext(name) # name of game
|
name = _(name) # name of game
|
||||||
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
|
node = SelectGameLeaf(self.tree, self, name, key=gi.id)
|
||||||
contents.append(node)
|
contents.append(node)
|
||||||
return contents or self.tree.data.no_games
|
return contents or self.tree.data.no_games
|
||||||
|
@ -111,7 +110,7 @@ class SelectGameData(SelectDialogTreeData):
|
||||||
for name, select_func in data:
|
for name, select_func in data:
|
||||||
if name is None or not filter(select_func, self.all_games_gi):
|
if name is None or not filter(select_func, self.all_games_gi):
|
||||||
continue
|
continue
|
||||||
name = gettext(name)
|
name = _(name)
|
||||||
name = name.replace("&", "")
|
name = name.replace("&", "")
|
||||||
gg.append(SelectGameNode(None, name, select_func))
|
gg.append(SelectGameNode(None, name, select_func))
|
||||||
g.append(gg)
|
g.append(gg)
|
||||||
|
@ -138,7 +137,7 @@ class SelectGameData(SelectDialogTreeData):
|
||||||
select_func = lambda gi, games=games: gi.id in games
|
select_func = lambda gi, games=games: gi.id in games
|
||||||
if name is None or not filter(select_func, self.all_games_gi):
|
if name is None or not filter(select_func, self.all_games_gi):
|
||||||
continue
|
continue
|
||||||
name = gettext(name)
|
name = _(name)
|
||||||
gg.append(SelectGameNode(None, name, select_func))
|
gg.append(SelectGameNode(None, name, select_func))
|
||||||
if 1 and gg:
|
if 1 and gg:
|
||||||
s_by_compatibility = SelectGameNode(None, _("by Compatibility"), tuple(gg))
|
s_by_compatibility = SelectGameNode(None, _("by Compatibility"), tuple(gg))
|
||||||
|
@ -523,12 +522,12 @@ class SelectGameDialogWithPreview(SelectGameDialog):
|
||||||
def updateInfo(self, gameid):
|
def updateInfo(self, gameid):
|
||||||
gi = self.app.gdb.get(gameid)
|
gi = self.app.gdb.get(gameid)
|
||||||
# info
|
# info
|
||||||
name = gettext(gi.name)
|
name = _(gi.name)
|
||||||
altnames = '\n'.join([gettext(n) for n in gi.altnames])
|
altnames = '\n'.join([_(n) for n in gi.altnames])
|
||||||
category = gettext(CSI.TYPE[gi.category])
|
category = _(CSI.TYPE[gi.category])
|
||||||
type = ''
|
type = ''
|
||||||
if gi.si.game_type in GI.TYPE_NAMES:
|
if gi.si.game_type in GI.TYPE_NAMES:
|
||||||
type = gettext(GI.TYPE_NAMES[gi.si.game_type])
|
type = _(GI.TYPE_NAMES[gi.si.game_type])
|
||||||
sl = {
|
sl = {
|
||||||
GI.SL_LUCK: _('Luck only'),
|
GI.SL_LUCK: _('Luck only'),
|
||||||
GI.SL_MOSTLY_LUCK: _('Mostly luck'),
|
GI.SL_MOSTLY_LUCK: _('Mostly luck'),
|
||||||
|
|
|
@ -41,8 +41,6 @@ from tkconst import EVENT_HANDLED, EVENT_PROPAGATE
|
||||||
from tkwidget import MfxDialog
|
from tkwidget import MfxDialog
|
||||||
from tkutil import bind, unbind_destroy
|
from tkutil import bind, unbind_destroy
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
|
@ -81,7 +79,7 @@ class SolverDialog(MfxDialog):
|
||||||
gamenames = ['']
|
gamenames = ['']
|
||||||
for id in games:
|
for id in games:
|
||||||
name = app.getGameTitleName(id)
|
name = app.getGameTitleName(id)
|
||||||
name = gettext(name)
|
name = _(name)
|
||||||
gamenames.append(name)
|
gamenames.append(name)
|
||||||
self.games[name] = id
|
self.games[name] = id
|
||||||
gamenames.sort()
|
gamenames.sort()
|
||||||
|
@ -241,7 +239,7 @@ class SolverDialog(MfxDialog):
|
||||||
|
|
||||||
def connectGame(self, game):
|
def connectGame(self, game):
|
||||||
name = self.app.getGameTitleName(game.id)
|
name = self.app.getGameTitleName(game.id)
|
||||||
name = gettext(name)
|
name = _(name)
|
||||||
if name in self.gamenames:
|
if name in self.gamenames:
|
||||||
self.start_button.config(state='normal')
|
self.start_button.config(state='normal')
|
||||||
i = self.gamenames.index(name)
|
i = self.gamenames.index(name)
|
||||||
|
|
|
@ -58,9 +58,6 @@ __all__ = ['tkversion',
|
||||||
import sys, os
|
import sys, os
|
||||||
import Tkinter
|
import Tkinter
|
||||||
|
|
||||||
# Toolkit imports
|
|
||||||
|
|
||||||
n_ = lambda x: x
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // constants
|
# // constants
|
||||||
|
|
|
@ -59,8 +59,6 @@ from tkutil import bind, unbind_destroy, loadImage
|
||||||
from tkwidget import MfxDialog, MfxMessageDialog
|
from tkwidget import MfxDialog, MfxMessageDialog
|
||||||
from tkwidget import MfxScrolledCanvas
|
from tkwidget import MfxScrolledCanvas
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
|
|
||||||
# FIXME - this file a quick hack and needs a rewrite
|
# FIXME - this file a quick hack and needs a rewrite
|
||||||
|
|
||||||
|
@ -413,7 +411,7 @@ class CanvasFormatter(PysolStatsFormatter):
|
||||||
y += 2*self.h
|
y += 2*self.h
|
||||||
for result in self.getStatResults(player, sort_by):
|
for result in self.getStatResults(player, sort_by):
|
||||||
gameid = result.pop()
|
gameid = result.pop()
|
||||||
result[0]=gettext(result[0]) # game name
|
result[0] = _(result[0]) # game name
|
||||||
self.pstats(y, result, gameid)
|
self.pstats(y, result, gameid)
|
||||||
y += self.h
|
y += self.h
|
||||||
#
|
#
|
||||||
|
@ -434,7 +432,7 @@ class CanvasFormatter(PysolStatsFormatter):
|
||||||
if not player or not prev_games:
|
if not player or not prev_games:
|
||||||
return 0
|
return 0
|
||||||
for result in self.getLogResults(player, prev_games):
|
for result in self.getLogResults(player, prev_games):
|
||||||
result[0]=gettext(result[0]) # game name
|
result[0] = _(result[0]) # game name
|
||||||
s = "%-25s %-20s %-17s %s" % tuple(result[:4])
|
s = "%-25s %-20s %-17s %s" % tuple(result[:4])
|
||||||
id = self.canvas.create_text(1, y, text=s, anchor="nw",
|
id = self.canvas.create_text(1, y, text=s, anchor="nw",
|
||||||
font=self.font, fill=self.fg)
|
font=self.font, fill=self.fg)
|
||||||
|
|
|
@ -52,9 +52,6 @@ from tkconst import EVENT_HANDLED, EVENT_PROPAGATE
|
||||||
from tkwidget import MfxTooltip
|
from tkwidget import MfxTooltip
|
||||||
from menubar import createToolbarMenu, MfxMenu
|
from menubar import createToolbarMenu, MfxMenu
|
||||||
|
|
||||||
gettext = _
|
|
||||||
n_ = lambda x: x
|
|
||||||
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
|
@ -319,7 +316,7 @@ class PysolToolbar(PysolToolbarActions):
|
||||||
'toolbar_name' : name,
|
'toolbar_name' : name,
|
||||||
'command' : command,
|
'command' : command,
|
||||||
'takefocus' : 0,
|
'takefocus' : 0,
|
||||||
'text' : gettext(label),
|
'text' : _(label),
|
||||||
'bd' : bd,
|
'bd' : bd,
|
||||||
'relief' : button_relief,
|
'relief' : button_relief,
|
||||||
'padx' : padx,
|
'padx' : padx,
|
||||||
|
|
|
@ -35,8 +35,6 @@ from pysollib.wizardpresets import presets
|
||||||
from tkwidget import MfxDialog
|
from tkwidget import MfxDialog
|
||||||
|
|
||||||
|
|
||||||
gettext = _
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
# ************************************************************************/
|
# ************************************************************************/
|
||||||
|
@ -69,8 +67,8 @@ class WizardDialog(MfxDialog):
|
||||||
if w.widget == 'preset':
|
if w.widget == 'preset':
|
||||||
if w.variable is None:
|
if w.variable is None:
|
||||||
w.variable = StringVar()
|
w.variable = StringVar()
|
||||||
values = [gettext(v) for v in w.values]
|
values = [_(v) for v in w.values]
|
||||||
default = gettext(w.default)
|
default = _(w.default)
|
||||||
values.remove(default)
|
values.remove(default)
|
||||||
values.sort()
|
values.sort()
|
||||||
values.insert(0, default)
|
values.insert(0, default)
|
||||||
|
@ -86,7 +84,7 @@ class WizardDialog(MfxDialog):
|
||||||
elif w.widget == 'menu':
|
elif w.widget == 'menu':
|
||||||
if w.variable is None:
|
if w.variable is None:
|
||||||
w.variable = StringVar()
|
w.variable = StringVar()
|
||||||
values = [gettext(v) for v in w.values]
|
values = [_(v) for v in w.values]
|
||||||
om = OptionMenu(frame, w.variable, *values)
|
om = OptionMenu(frame, w.variable, *values)
|
||||||
om.grid(row=row, column=1, sticky='ew', padx=2)
|
om.grid(row=row, column=1, sticky='ew', padx=2)
|
||||||
elif w.widget == 'spin':
|
elif w.widget == 'spin':
|
||||||
|
@ -107,8 +105,8 @@ class WizardDialog(MfxDialog):
|
||||||
v = w.default
|
v = w.default
|
||||||
else:
|
else:
|
||||||
v = w.current_value
|
v = w.current_value
|
||||||
if w.widget in ('menu', 'preset'):
|
if w.widget in ('menu', 'preset', 'entry'):
|
||||||
v = gettext(v)
|
v = _(v)
|
||||||
w.variable.set(v)
|
w.variable.set(v)
|
||||||
|
|
||||||
row += 1
|
row += 1
|
||||||
|
@ -130,7 +128,7 @@ class WizardDialog(MfxDialog):
|
||||||
else:
|
else:
|
||||||
v = w.default
|
v = w.default
|
||||||
if w.widget in ('menu', 'preset'):
|
if w.widget in ('menu', 'preset'):
|
||||||
v = gettext(v)
|
v = _(v)
|
||||||
w.variable.set(v)
|
w.variable.set(v)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
##
|
##
|
||||||
##---------------------------------------------------------------------------##
|
##---------------------------------------------------------------------------##
|
||||||
|
|
||||||
n_ = lambda x: x
|
|
||||||
|
|
||||||
presets = {
|
presets = {
|
||||||
'None': {
|
'None': {
|
||||||
'preset': 'None',
|
'preset': 'None',
|
||||||
|
|
|
@ -27,8 +27,6 @@ from stack import *
|
||||||
from layout import Layout
|
from layout import Layout
|
||||||
from wizardpresets import presets
|
from wizardpresets import presets
|
||||||
|
|
||||||
gettext = _
|
|
||||||
n_ = lambda x: x
|
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# //
|
# //
|
||||||
|
@ -45,13 +43,13 @@ class WizSetting:
|
||||||
self.values = []
|
self.values = []
|
||||||
for k, v in self.values_map:
|
for k, v in self.values_map:
|
||||||
self.values.append(k)
|
self.values.append(k)
|
||||||
self.translation_map[gettext(k)] = k
|
self.translation_map[_(k)] = k
|
||||||
assert self.default in self.values
|
assert self.default in self.values
|
||||||
elif widget == 'preset':
|
elif widget == 'preset':
|
||||||
self.values = []
|
self.values = []
|
||||||
for v in self.values_map:
|
for v in self.values_map:
|
||||||
self.values.append(v)
|
self.values.append(v)
|
||||||
self.translation_map[gettext(v)] = v
|
self.translation_map[_(v)] = v
|
||||||
assert self.default in self.values
|
assert self.default in self.values
|
||||||
else:
|
else:
|
||||||
self.values = self.values_map
|
self.values = self.values_map
|
||||||
|
@ -71,7 +69,7 @@ WizardPresets = WizSetting(
|
||||||
)
|
)
|
||||||
GameName = WizSetting(
|
GameName = WizSetting(
|
||||||
values_map = (),
|
values_map = (),
|
||||||
default = 'My Game',
|
default = _('My Game'),
|
||||||
widget = 'entry',
|
widget = 'entry',
|
||||||
label = _('Name:'),
|
label = _('Name:'),
|
||||||
var_name = 'name',
|
var_name = 'name',
|
||||||
|
@ -186,7 +184,7 @@ FoundMaxMove = WizSetting(
|
||||||
FoundEqual = WizSetting(
|
FoundEqual = WizSetting(
|
||||||
values_map = (0, 1),
|
values_map = (0, 1),
|
||||||
default = 1,
|
default = 1,
|
||||||
label = _('First card sets base rank:'),
|
label = _('First card sets base cards:'),
|
||||||
var_name = 'found_equal',
|
var_name = 'found_equal',
|
||||||
widget = 'check',
|
widget = 'check',
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,8 +6,9 @@ import sys, os, re, time
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
|
||||||
os.environ['LANG'] = 'C'
|
os.environ['LANG'] = 'C'
|
||||||
import gettext
|
import __builtin__
|
||||||
gettext.install('pysol', 'locale', unicode=True)
|
__builtin__.__dict__['_'] = lambda x: x
|
||||||
|
__builtin__.__dict__['n_'] = lambda x: x
|
||||||
|
|
||||||
pysollib_path = os.path.join(sys.path[0], '..')
|
pysollib_path = os.path.join(sys.path[0], '..')
|
||||||
sys.path[0] = os.path.normpath(pysollib_path)
|
sys.path[0] = os.path.normpath(pysollib_path)
|
||||||
|
|
715
scripts/pygettext.py
Normal file
715
scripts/pygettext.py
Normal file
|
@ -0,0 +1,715 @@
|
||||||
|
#! /usr/bin/env python
|
||||||
|
# -*- coding: iso-8859-1 -*-
|
||||||
|
# Originally written by Barry Warsaw <barry@zope.com>
|
||||||
|
#
|
||||||
|
# Minimally patched to make it even more xgettext compatible
|
||||||
|
# by Peter Funk <pf@artcom-gmbh.de>
|
||||||
|
#
|
||||||
|
# 2002-11-22 Jürgen Hermann <jh@web.de>
|
||||||
|
# Added checks that _() only contains string literals, and
|
||||||
|
# command line args are resolved to module lists, i.e. you
|
||||||
|
# can now pass a filename, a module or package name, or a
|
||||||
|
# directory (including globbing chars, important for Win32).
|
||||||
|
# Made docstring fit in 80 chars wide displays using pydoc.
|
||||||
|
#
|
||||||
|
# 2007-05-11 Scomoroh <scomoroh@gmail.com>
|
||||||
|
# Added very simple support for ngettext
|
||||||
|
#
|
||||||
|
|
||||||
|
# for selftesting
|
||||||
|
try:
|
||||||
|
import fintl
|
||||||
|
_ = fintl.gettext
|
||||||
|
except ImportError:
|
||||||
|
_ = lambda s: s
|
||||||
|
|
||||||
|
__doc__ = _("""pygettext -- Python equivalent of xgettext(1)
|
||||||
|
|
||||||
|
Many systems (Solaris, Linux, Gnu) provide extensive tools that ease the
|
||||||
|
internationalization of C programs. Most of these tools are independent of
|
||||||
|
the programming language and can be used from within Python programs.
|
||||||
|
Martin von Loewis' work[1] helps considerably in this regard.
|
||||||
|
|
||||||
|
There's one problem though; xgettext is the program that scans source code
|
||||||
|
looking for message strings, but it groks only C (or C++). Python
|
||||||
|
introduces a few wrinkles, such as dual quoting characters, triple quoted
|
||||||
|
strings, and raw strings. xgettext understands none of this.
|
||||||
|
|
||||||
|
Enter pygettext, which uses Python's standard tokenize module to scan
|
||||||
|
Python source code, generating .pot files identical to what GNU xgettext[2]
|
||||||
|
generates for C and C++ code. From there, the standard GNU tools can be
|
||||||
|
used.
|
||||||
|
|
||||||
|
A word about marking Python strings as candidates for translation. GNU
|
||||||
|
xgettext recognizes the following keywords: gettext, dgettext, dcgettext,
|
||||||
|
and gettext_noop. But those can be a lot of text to include all over your
|
||||||
|
code. C and C++ have a trick: they use the C preprocessor. Most
|
||||||
|
internationalized C source includes a #define for gettext() to _() so that
|
||||||
|
what has to be written in the source is much less. Thus these are both
|
||||||
|
translatable strings:
|
||||||
|
|
||||||
|
gettext("Translatable String")
|
||||||
|
_("Translatable String")
|
||||||
|
|
||||||
|
Python of course has no preprocessor so this doesn't work so well. Thus,
|
||||||
|
pygettext searches only for _() by default, but see the -k/--keyword flag
|
||||||
|
below for how to augment this.
|
||||||
|
|
||||||
|
[1] http://www.python.org/workshops/1997-10/proceedings/loewis.html
|
||||||
|
[2] http://www.gnu.org/software/gettext/gettext.html
|
||||||
|
|
||||||
|
NOTE: pygettext attempts to be option and feature compatible with GNU
|
||||||
|
xgettext where ever possible. However some options are still missing or are
|
||||||
|
not fully implemented. Also, xgettext's use of command line switches with
|
||||||
|
option arguments is broken, and in these cases, pygettext just defines
|
||||||
|
additional switches.
|
||||||
|
|
||||||
|
Usage: pygettext [options] inputfile ...
|
||||||
|
|
||||||
|
Options:
|
||||||
|
|
||||||
|
-a
|
||||||
|
--extract-all
|
||||||
|
Extract all strings.
|
||||||
|
|
||||||
|
-d name
|
||||||
|
--default-domain=name
|
||||||
|
Rename the default output file from messages.pot to name.pot.
|
||||||
|
|
||||||
|
-E
|
||||||
|
--escape
|
||||||
|
Replace non-ASCII characters with octal escape sequences.
|
||||||
|
|
||||||
|
-D
|
||||||
|
--docstrings
|
||||||
|
Extract module, class, method, and function docstrings. These do
|
||||||
|
not need to be wrapped in _() markers, and in fact cannot be for
|
||||||
|
Python to consider them docstrings. (See also the -X option).
|
||||||
|
|
||||||
|
-h
|
||||||
|
--help
|
||||||
|
Print this help message and exit.
|
||||||
|
|
||||||
|
-k word
|
||||||
|
--keyword=word
|
||||||
|
Keywords to look for in addition to the default set, which are:
|
||||||
|
%(DEFAULTKEYWORDS)s
|
||||||
|
|
||||||
|
You can have multiple -k flags on the command line.
|
||||||
|
|
||||||
|
-K
|
||||||
|
--no-default-keywords
|
||||||
|
Disable the default set of keywords (see above). Any keywords
|
||||||
|
explicitly added with the -k/--keyword option are still recognized.
|
||||||
|
|
||||||
|
--no-location
|
||||||
|
Do not write filename/lineno location comments.
|
||||||
|
|
||||||
|
-n
|
||||||
|
--add-location
|
||||||
|
Write filename/lineno location comments indicating where each
|
||||||
|
extracted string is found in the source. These lines appear before
|
||||||
|
each msgid. The style of comments is controlled by the -S/--style
|
||||||
|
option. This is the default.
|
||||||
|
|
||||||
|
-o filename
|
||||||
|
--output=filename
|
||||||
|
Rename the default output file from messages.pot to filename. If
|
||||||
|
filename is `-' then the output is sent to standard out.
|
||||||
|
|
||||||
|
-p dir
|
||||||
|
--output-dir=dir
|
||||||
|
Output files will be placed in directory dir.
|
||||||
|
|
||||||
|
-S stylename
|
||||||
|
--style stylename
|
||||||
|
Specify which style to use for location comments. Two styles are
|
||||||
|
supported:
|
||||||
|
|
||||||
|
Solaris # File: filename, line: line-number
|
||||||
|
GNU #: filename:line
|
||||||
|
|
||||||
|
The style name is case insensitive. GNU style is the default.
|
||||||
|
|
||||||
|
-v
|
||||||
|
--verbose
|
||||||
|
Print the names of the files being processed.
|
||||||
|
|
||||||
|
-V
|
||||||
|
--version
|
||||||
|
Print the version of pygettext and exit.
|
||||||
|
|
||||||
|
-w columns
|
||||||
|
--width=columns
|
||||||
|
Set width of output to columns.
|
||||||
|
|
||||||
|
-x filename
|
||||||
|
--exclude-file=filename
|
||||||
|
Specify a file that contains a list of strings that are not be
|
||||||
|
extracted from the input files. Each string to be excluded must
|
||||||
|
appear on a line by itself in the file.
|
||||||
|
|
||||||
|
-X filename
|
||||||
|
--no-docstrings=filename
|
||||||
|
Specify a file that contains a list of files (one per line) that
|
||||||
|
should not have their docstrings extracted. This is only useful in
|
||||||
|
conjunction with the -D option above.
|
||||||
|
|
||||||
|
If `inputfile' is -, standard input is read.
|
||||||
|
""")
|
||||||
|
|
||||||
|
import os
|
||||||
|
import imp
|
||||||
|
import sys
|
||||||
|
import glob
|
||||||
|
import time
|
||||||
|
import getopt
|
||||||
|
import token
|
||||||
|
import tokenize
|
||||||
|
import operator
|
||||||
|
|
||||||
|
__version__ = '1.6con'
|
||||||
|
|
||||||
|
default_keywords = ['_']
|
||||||
|
DEFAULTKEYWORDS = ', '.join(default_keywords)
|
||||||
|
default_ngettext_keywords = ['ngettext']
|
||||||
|
|
||||||
|
EMPTYSTRING = ''
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# The normal pot-file header. msgmerge and Emacs's po-mode work better if it's
|
||||||
|
# there.
|
||||||
|
pot_header = _('''\
|
||||||
|
# SOME DESCRIPTIVE TITLE.
|
||||||
|
# Copyright (C) YEAR ORGANIZATION
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: PACKAGE VERSION\\n"
|
||||||
|
"POT-Creation-Date: %(time)s\\n"
|
||||||
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
|
||||||
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
|
||||||
|
"Language-Team: LANGUAGE <LL@li.org>\\n"
|
||||||
|
"MIME-Version: 1.0\\n"
|
||||||
|
"Content-Type: text/plain; charset=CHARSET\\n"
|
||||||
|
"Content-Transfer-Encoding: ENCODING\\n"
|
||||||
|
"Generated-By: pygettext.py %(version)s\\n"
|
||||||
|
|
||||||
|
''')
|
||||||
|
|
||||||
|
|
||||||
|
def usage(code, msg=''):
|
||||||
|
print >> sys.stderr, __doc__ % globals()
|
||||||
|
if msg:
|
||||||
|
print >> sys.stderr, msg
|
||||||
|
sys.exit(code)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
escapes = []
|
||||||
|
|
||||||
|
def make_escapes(pass_iso8859):
|
||||||
|
global escapes
|
||||||
|
if pass_iso8859:
|
||||||
|
# Allow iso-8859 characters to pass through so that e.g. 'msgid
|
||||||
|
# "Höhe"' would result not result in 'msgid "H\366he"'. Otherwise we
|
||||||
|
# escape any character outside the 32..126 range.
|
||||||
|
mod = 128
|
||||||
|
else:
|
||||||
|
mod = 256
|
||||||
|
for i in range(256):
|
||||||
|
if 32 <= (i % mod) <= 126:
|
||||||
|
escapes.append(chr(i))
|
||||||
|
else:
|
||||||
|
escapes.append("\\%03o" % i)
|
||||||
|
escapes[ord('\\')] = '\\\\'
|
||||||
|
escapes[ord('\t')] = '\\t'
|
||||||
|
escapes[ord('\r')] = '\\r'
|
||||||
|
escapes[ord('\n')] = '\\n'
|
||||||
|
escapes[ord('\"')] = '\\"'
|
||||||
|
|
||||||
|
|
||||||
|
def escape(s):
|
||||||
|
global escapes
|
||||||
|
s = list(s)
|
||||||
|
for i in range(len(s)):
|
||||||
|
s[i] = escapes[ord(s[i])]
|
||||||
|
return EMPTYSTRING.join(s)
|
||||||
|
|
||||||
|
|
||||||
|
def safe_eval(s):
|
||||||
|
# unwrap quotes, safely
|
||||||
|
return eval(s, {'__builtins__':{}}, {})
|
||||||
|
|
||||||
|
|
||||||
|
def normalize(s):
|
||||||
|
# This converts the various Python string types into a format that is
|
||||||
|
# appropriate for .po files, namely much closer to C style.
|
||||||
|
lines = s.split('\n')
|
||||||
|
if len(lines) == 1:
|
||||||
|
s = '"' + escape(s) + '"'
|
||||||
|
else:
|
||||||
|
if not lines[-1]:
|
||||||
|
del lines[-1]
|
||||||
|
lines[-1] = lines[-1] + '\n'
|
||||||
|
for i in range(len(lines)):
|
||||||
|
lines[i] = escape(lines[i])
|
||||||
|
lineterm = '\\n"\n"'
|
||||||
|
s = '""\n"' + lineterm.join(lines) + '"'
|
||||||
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
def containsAny(str, set):
|
||||||
|
"""Check whether 'str' contains ANY of the chars in 'set'"""
|
||||||
|
return 1 in [c in str for c in set]
|
||||||
|
|
||||||
|
|
||||||
|
def _visit_pyfiles(list, dirname, names):
|
||||||
|
"""Helper for getFilesForName()."""
|
||||||
|
# get extension for python source files
|
||||||
|
if not globals().has_key('_py_ext'):
|
||||||
|
global _py_ext
|
||||||
|
_py_ext = [triple[0] for triple in imp.get_suffixes()
|
||||||
|
if triple[2] == imp.PY_SOURCE][0]
|
||||||
|
|
||||||
|
# don't recurse into CVS directories
|
||||||
|
if 'CVS' in names:
|
||||||
|
names.remove('CVS')
|
||||||
|
|
||||||
|
# add all *.py files to list
|
||||||
|
list.extend(
|
||||||
|
[os.path.join(dirname, file) for file in names
|
||||||
|
if os.path.splitext(file)[1] == _py_ext]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_modpkg_path(dotted_name, pathlist=None):
|
||||||
|
"""Get the filesystem path for a module or a package.
|
||||||
|
|
||||||
|
Return the file system path to a file for a module, and to a directory for
|
||||||
|
a package. Return None if the name is not found, or is a builtin or
|
||||||
|
extension module.
|
||||||
|
"""
|
||||||
|
# split off top-most name
|
||||||
|
parts = dotted_name.split('.', 1)
|
||||||
|
|
||||||
|
if len(parts) > 1:
|
||||||
|
# we have a dotted path, import top-level package
|
||||||
|
try:
|
||||||
|
file, pathname, description = imp.find_module(parts[0], pathlist)
|
||||||
|
if file: file.close()
|
||||||
|
except ImportError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# check if it's indeed a package
|
||||||
|
if description[2] == imp.PKG_DIRECTORY:
|
||||||
|
# recursively handle the remaining name parts
|
||||||
|
pathname = _get_modpkg_path(parts[1], [pathname])
|
||||||
|
else:
|
||||||
|
pathname = None
|
||||||
|
else:
|
||||||
|
# plain name
|
||||||
|
try:
|
||||||
|
file, pathname, description = imp.find_module(
|
||||||
|
dotted_name, pathlist)
|
||||||
|
if file:
|
||||||
|
file.close()
|
||||||
|
if description[2] not in [imp.PY_SOURCE, imp.PKG_DIRECTORY]:
|
||||||
|
pathname = None
|
||||||
|
except ImportError:
|
||||||
|
pathname = None
|
||||||
|
|
||||||
|
return pathname
|
||||||
|
|
||||||
|
|
||||||
|
def getFilesForName(name):
|
||||||
|
"""Get a list of module files for a filename, a module or package name,
|
||||||
|
or a directory.
|
||||||
|
"""
|
||||||
|
if not os.path.exists(name):
|
||||||
|
# check for glob chars
|
||||||
|
if containsAny(name, "*?[]"):
|
||||||
|
files = glob.glob(name)
|
||||||
|
list = []
|
||||||
|
for file in files:
|
||||||
|
list.extend(getFilesForName(file))
|
||||||
|
return list
|
||||||
|
|
||||||
|
# try to find module or package
|
||||||
|
name = _get_modpkg_path(name)
|
||||||
|
if not name:
|
||||||
|
return []
|
||||||
|
|
||||||
|
if os.path.isdir(name):
|
||||||
|
# find all python files in directory
|
||||||
|
list = []
|
||||||
|
os.path.walk(name, _visit_pyfiles, list)
|
||||||
|
return list
|
||||||
|
elif os.path.exists(name):
|
||||||
|
# a single file
|
||||||
|
return [name]
|
||||||
|
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
class TokenEater:
|
||||||
|
def __init__(self, options):
|
||||||
|
self.__options = options
|
||||||
|
self.__messages = {}
|
||||||
|
self.__state = self.__waiting
|
||||||
|
self.__data = []
|
||||||
|
self.__lineno = -1
|
||||||
|
self.__freshmodule = 1
|
||||||
|
self.__curfile = None
|
||||||
|
self.__ngettext = False
|
||||||
|
|
||||||
|
def __call__(self, ttype, tstring, stup, etup, line):
|
||||||
|
# dispatch
|
||||||
|
## import token
|
||||||
|
## print >> sys.stderr, 'ttype:', token.tok_name[ttype], \
|
||||||
|
## 'tstring:', tstring
|
||||||
|
self.__state(ttype, tstring, stup[0])
|
||||||
|
|
||||||
|
def __waiting(self, ttype, tstring, lineno):
|
||||||
|
opts = self.__options
|
||||||
|
# Do docstring extractions, if enabled
|
||||||
|
if opts.docstrings and not opts.nodocstrings.get(self.__curfile):
|
||||||
|
# module docstring?
|
||||||
|
if self.__freshmodule:
|
||||||
|
if ttype == tokenize.STRING:
|
||||||
|
self.__addentry(safe_eval(tstring), lineno, isdocstring=1)
|
||||||
|
self.__freshmodule = 0
|
||||||
|
elif ttype not in (tokenize.COMMENT, tokenize.NL):
|
||||||
|
self.__freshmodule = 0
|
||||||
|
return
|
||||||
|
# class docstring?
|
||||||
|
if ttype == tokenize.NAME and tstring in ('class', 'def'):
|
||||||
|
self.__state = self.__suiteseen
|
||||||
|
return
|
||||||
|
if ttype == tokenize.NAME and tstring in opts.keywords:
|
||||||
|
self.__state = self.__keywordseen
|
||||||
|
self.__ngettext = tstring in opts.ngettext_keywords
|
||||||
|
|
||||||
|
def __suiteseen(self, ttype, tstring, lineno):
|
||||||
|
# ignore anything until we see the colon
|
||||||
|
if ttype == tokenize.OP and tstring == ':':
|
||||||
|
self.__state = self.__suitedocstring
|
||||||
|
|
||||||
|
def __suitedocstring(self, ttype, tstring, lineno):
|
||||||
|
# ignore any intervening noise
|
||||||
|
if ttype == tokenize.STRING:
|
||||||
|
self.__addentry(safe_eval(tstring), lineno, isdocstring=1)
|
||||||
|
self.__state = self.__waiting
|
||||||
|
elif ttype not in (tokenize.NEWLINE, tokenize.INDENT,
|
||||||
|
tokenize.COMMENT):
|
||||||
|
# there was no class docstring
|
||||||
|
self.__state = self.__waiting
|
||||||
|
|
||||||
|
def __keywordseen(self, ttype, tstring, lineno):
|
||||||
|
if ttype == tokenize.OP and tstring == '(':
|
||||||
|
self.__data = []
|
||||||
|
self.__lineno = lineno
|
||||||
|
self.__state = self.__openseen
|
||||||
|
else:
|
||||||
|
self.__state = self.__waiting
|
||||||
|
|
||||||
|
def __openseen(self, ttype, tstring, lineno):
|
||||||
|
if ttype == tokenize.OP and tstring == ')':
|
||||||
|
# We've seen the last of the translatable strings. Record the
|
||||||
|
# line number of the first line of the strings and update the list
|
||||||
|
# of messages seen. Reset state for the next batch. If there
|
||||||
|
# were no strings inside _(), then just ignore this entry.
|
||||||
|
if self.__data:
|
||||||
|
if self.__ngettext:
|
||||||
|
data = []
|
||||||
|
msg = []
|
||||||
|
for s in self.__data:
|
||||||
|
if s is not None:
|
||||||
|
msg.append(s)
|
||||||
|
else:
|
||||||
|
data.append(EMPTYSTRING.join(msg))
|
||||||
|
msg = []
|
||||||
|
if len(data) == 2 and data[0] and data[1]:
|
||||||
|
self.__addentry(tuple(data))
|
||||||
|
elif self.__options.verbose:
|
||||||
|
print >> sys.stderr, _(
|
||||||
|
'*** %(file)s:%(lineno)s: incorrect ngettext format'
|
||||||
|
) % {
|
||||||
|
'file': self.__curfile,
|
||||||
|
'lineno': self.__lineno
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
self.__addentry(EMPTYSTRING.join(self.__data))
|
||||||
|
self.__state = self.__waiting
|
||||||
|
elif ttype == tokenize.STRING:
|
||||||
|
self.__data.append(safe_eval(tstring))
|
||||||
|
elif ttype not in [tokenize.COMMENT, token.INDENT, token.DEDENT,
|
||||||
|
token.NEWLINE, tokenize.NL]:
|
||||||
|
if self.__ngettext and ttype == tokenize.OP and tstring == ',':
|
||||||
|
self.__data.append(None)
|
||||||
|
elif self.__ngettext: # and ttype == tokenize.NUMBER:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# warn if we see anything else than STRING or whitespace
|
||||||
|
if self.__options.verbose:
|
||||||
|
print >> sys.stderr, _(
|
||||||
|
'*** %(file)s:%(lineno)s: Seen unexpected token "%(token)s"'
|
||||||
|
) % {
|
||||||
|
'token': tstring,
|
||||||
|
'file': self.__curfile,
|
||||||
|
'lineno': self.__lineno
|
||||||
|
}
|
||||||
|
self.__state = self.__waiting
|
||||||
|
|
||||||
|
def __addentry(self, msg, lineno=None, isdocstring=0):
|
||||||
|
if lineno is None:
|
||||||
|
lineno = self.__lineno
|
||||||
|
if not msg in self.__options.toexclude:
|
||||||
|
entry = (self.__curfile, lineno)
|
||||||
|
self.__messages.setdefault(msg, {})[entry] = isdocstring
|
||||||
|
|
||||||
|
def set_filename(self, filename):
|
||||||
|
self.__curfile = filename
|
||||||
|
self.__freshmodule = 1
|
||||||
|
|
||||||
|
def write(self, fp):
|
||||||
|
options = self.__options
|
||||||
|
timestamp = time.ctime(time.time())
|
||||||
|
# The time stamp in the header doesn't have the same format as that
|
||||||
|
# generated by xgettext...
|
||||||
|
print >> fp, pot_header % {'time': timestamp, 'version': __version__}
|
||||||
|
# Sort the entries. First sort each particular entry's keys, then
|
||||||
|
# sort all the entries by their first item.
|
||||||
|
reverse = {}
|
||||||
|
for k, v in self.__messages.items():
|
||||||
|
keys = v.keys()
|
||||||
|
keys.sort()
|
||||||
|
reverse.setdefault(tuple(keys), []).append((k, v))
|
||||||
|
rkeys = reverse.keys()
|
||||||
|
rkeys.sort()
|
||||||
|
for rkey in rkeys:
|
||||||
|
rentries = reverse[rkey]
|
||||||
|
rentries.sort()
|
||||||
|
for k, v in rentries:
|
||||||
|
isdocstring = 0
|
||||||
|
# If the entry was gleaned out of a docstring, then add a
|
||||||
|
# comment stating so. This is to aid translators who may wish
|
||||||
|
# to skip translating some unimportant docstrings.
|
||||||
|
if reduce(operator.__add__, v.values()):
|
||||||
|
isdocstring = 1
|
||||||
|
# k is the message string, v is a dictionary-set of (filename,
|
||||||
|
# lineno) tuples. We want to sort the entries in v first by
|
||||||
|
# file name and then by line number.
|
||||||
|
v = v.keys()
|
||||||
|
v.sort()
|
||||||
|
if not options.writelocations:
|
||||||
|
pass
|
||||||
|
# location comments are different b/w Solaris and GNU:
|
||||||
|
elif options.locationstyle == options.SOLARIS:
|
||||||
|
for filename, lineno in v:
|
||||||
|
d = {'filename': filename, 'lineno': lineno}
|
||||||
|
print >>fp, _(
|
||||||
|
'# File: %(filename)s, line: %(lineno)d') % d
|
||||||
|
elif options.locationstyle == options.GNU:
|
||||||
|
# fit as many locations on one line, as long as the
|
||||||
|
# resulting line length doesn't exceeds 'options.width'
|
||||||
|
locline = '#:'
|
||||||
|
for filename, lineno in v:
|
||||||
|
d = {'filename': filename, 'lineno': lineno}
|
||||||
|
s = _(' %(filename)s:%(lineno)d') % d
|
||||||
|
if len(locline) + len(s) <= options.width:
|
||||||
|
locline = locline + s
|
||||||
|
else:
|
||||||
|
print >> fp, locline
|
||||||
|
locline = "#:" + s
|
||||||
|
if len(locline) > 2:
|
||||||
|
print >> fp, locline
|
||||||
|
if isdocstring:
|
||||||
|
print >> fp, '#, docstring'
|
||||||
|
if isinstance(k, basestring):
|
||||||
|
print >> fp, 'msgid', normalize(k)
|
||||||
|
print >> fp, 'msgstr ""\n'
|
||||||
|
else:
|
||||||
|
# ngettext
|
||||||
|
assert isinstance(k, tuple)
|
||||||
|
assert len(k) == 2
|
||||||
|
print >> fp, 'msgid', normalize(k[0])
|
||||||
|
print >> fp, 'msgid_plural', normalize(k[1])
|
||||||
|
print >> fp, 'msgstr[0] ""'
|
||||||
|
print >> fp, 'msgstr[1] ""\n'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
global default_keywords
|
||||||
|
try:
|
||||||
|
opts, args = getopt.getopt(
|
||||||
|
sys.argv[1:],
|
||||||
|
'ad:DEhk:Kno:p:S:Vvw:x:X:',
|
||||||
|
['extract-all', 'default-domain=', 'escape', 'help',
|
||||||
|
'keyword=', 'no-default-keywords', 'ngettext-keyword=',
|
||||||
|
'add-location', 'no-location', 'output=', 'output-dir=',
|
||||||
|
'style=', 'verbose', 'version', 'width=', 'exclude-file=',
|
||||||
|
'docstrings', 'no-docstrings',
|
||||||
|
])
|
||||||
|
except getopt.error, msg:
|
||||||
|
usage(1, msg)
|
||||||
|
|
||||||
|
# for holding option values
|
||||||
|
class Options:
|
||||||
|
# constants
|
||||||
|
GNU = 1
|
||||||
|
SOLARIS = 2
|
||||||
|
# defaults
|
||||||
|
extractall = 0 # FIXME: currently this option has no effect at all.
|
||||||
|
escape = 0
|
||||||
|
keywords = []
|
||||||
|
ngettext_keywords = []
|
||||||
|
outpath = ''
|
||||||
|
outfile = 'messages.pot'
|
||||||
|
writelocations = 1
|
||||||
|
locationstyle = GNU
|
||||||
|
verbose = 0
|
||||||
|
width = 78
|
||||||
|
excludefilename = ''
|
||||||
|
docstrings = 0
|
||||||
|
nodocstrings = {}
|
||||||
|
|
||||||
|
options = Options()
|
||||||
|
locations = {'gnu' : options.GNU,
|
||||||
|
'solaris' : options.SOLARIS,
|
||||||
|
}
|
||||||
|
|
||||||
|
# parse options
|
||||||
|
for opt, arg in opts:
|
||||||
|
if opt in ('-h', '--help'):
|
||||||
|
usage(0)
|
||||||
|
elif opt in ('-a', '--extract-all'):
|
||||||
|
options.extractall = 1
|
||||||
|
elif opt in ('-d', '--default-domain'):
|
||||||
|
options.outfile = arg + '.pot'
|
||||||
|
elif opt in ('-E', '--escape'):
|
||||||
|
options.escape = 1
|
||||||
|
elif opt in ('-D', '--docstrings'):
|
||||||
|
options.docstrings = 1
|
||||||
|
elif opt in ('-k', '--keyword'):
|
||||||
|
options.keywords.append(arg)
|
||||||
|
elif opt in ('--ngettext-keyword'):
|
||||||
|
options.ngettext_keywords.append(arg)
|
||||||
|
elif opt in ('-K', '--no-default-keywords'):
|
||||||
|
default_keywords = []
|
||||||
|
elif opt in ('-n', '--add-location'):
|
||||||
|
options.writelocations = 1
|
||||||
|
elif opt in ('--no-location',):
|
||||||
|
options.writelocations = 0
|
||||||
|
elif opt in ('-S', '--style'):
|
||||||
|
options.locationstyle = locations.get(arg.lower())
|
||||||
|
if options.locationstyle is None:
|
||||||
|
usage(1, _('Invalid value for --style: %s') % arg)
|
||||||
|
elif opt in ('-o', '--output'):
|
||||||
|
options.outfile = arg
|
||||||
|
elif opt in ('-p', '--output-dir'):
|
||||||
|
options.outpath = arg
|
||||||
|
elif opt in ('-v', '--verbose'):
|
||||||
|
options.verbose = 1
|
||||||
|
elif opt in ('-V', '--version'):
|
||||||
|
print _('pygettext.py (xgettext for Python) %s') % __version__
|
||||||
|
sys.exit(0)
|
||||||
|
elif opt in ('-w', '--width'):
|
||||||
|
try:
|
||||||
|
options.width = int(arg)
|
||||||
|
except ValueError:
|
||||||
|
usage(1, _('--width argument must be an integer: %s') % arg)
|
||||||
|
elif opt in ('-x', '--exclude-file'):
|
||||||
|
options.excludefilename = arg
|
||||||
|
elif opt in ('-X', '--no-docstrings'):
|
||||||
|
fp = open(arg)
|
||||||
|
try:
|
||||||
|
while 1:
|
||||||
|
line = fp.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
options.nodocstrings[line[:-1]] = 1
|
||||||
|
finally:
|
||||||
|
fp.close()
|
||||||
|
|
||||||
|
# calculate escapes
|
||||||
|
make_escapes(options.escape)
|
||||||
|
|
||||||
|
# calculate all keywords
|
||||||
|
options.keywords.extend(default_keywords)
|
||||||
|
|
||||||
|
options.ngettext_keywords.extend(default_ngettext_keywords)
|
||||||
|
options.keywords.extend(options.ngettext_keywords)
|
||||||
|
|
||||||
|
# initialize list of strings to exclude
|
||||||
|
if options.excludefilename:
|
||||||
|
try:
|
||||||
|
fp = open(options.excludefilename)
|
||||||
|
options.toexclude = fp.readlines()
|
||||||
|
fp.close()
|
||||||
|
except IOError:
|
||||||
|
print >> sys.stderr, _(
|
||||||
|
"Can't read --exclude-file: %s") % options.excludefilename
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
options.toexclude = []
|
||||||
|
|
||||||
|
# resolve args to module lists
|
||||||
|
expanded = []
|
||||||
|
for arg in args:
|
||||||
|
if arg == '-':
|
||||||
|
expanded.append(arg)
|
||||||
|
else:
|
||||||
|
expanded.extend(getFilesForName(arg))
|
||||||
|
args = expanded
|
||||||
|
|
||||||
|
# slurp through all the files
|
||||||
|
eater = TokenEater(options)
|
||||||
|
for filename in args:
|
||||||
|
if filename == '-':
|
||||||
|
if options.verbose:
|
||||||
|
print _('Reading standard input')
|
||||||
|
fp = sys.stdin
|
||||||
|
closep = 0
|
||||||
|
else:
|
||||||
|
if options.verbose:
|
||||||
|
print _('Working on %s') % filename
|
||||||
|
fp = open(filename)
|
||||||
|
closep = 1
|
||||||
|
try:
|
||||||
|
eater.set_filename(filename)
|
||||||
|
try:
|
||||||
|
tokenize.tokenize(fp.readline, eater)
|
||||||
|
except tokenize.TokenError, e:
|
||||||
|
print >> sys.stderr, '%s: %s, line %d, column %d' % (
|
||||||
|
e[0], filename, e[1][0], e[1][1])
|
||||||
|
finally:
|
||||||
|
if closep:
|
||||||
|
fp.close()
|
||||||
|
|
||||||
|
# write the output
|
||||||
|
if options.outfile == '-':
|
||||||
|
fp = sys.stdout
|
||||||
|
closep = 0
|
||||||
|
else:
|
||||||
|
if options.outpath:
|
||||||
|
options.outfile = os.path.join(options.outpath, options.outfile)
|
||||||
|
fp = open(options.outfile, 'w')
|
||||||
|
closep = 1
|
||||||
|
try:
|
||||||
|
eater.write(fp)
|
||||||
|
finally:
|
||||||
|
if closep:
|
||||||
|
fp.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
# some more test strings
|
||||||
|
_(u'a unicode string')
|
||||||
|
# this one creates a warning
|
||||||
|
_('*** Seen unexpected token "%(token)s"') % {'token': 'test'}
|
||||||
|
_('more' 'than' 'one' 'string')
|
Loading…
Add table
Reference in a new issue