1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00

Compare commits

...

5 commits

Author SHA1 Message Date
Juhani Numminen
ef0c45841d Update translations after string changes 2019-08-31 13:22:21 +03:00
Juhani Numminen
65b86f2d1d Improve internationalization
- More strings marked for translation
- Used format strings instead of concatinating fragments
- Removed space before '?' or '!' from sentences in English

Following the GNU gettext guidelines at
https://www.gnu.org/software/gettext/manual/gettext.html#Preparing-Strings
2019-08-31 13:22:21 +03:00
Shlomi Fish
34609fc9d2 Extract a common class/struct.
This is Refactoring / code cleanup.

See:

* https://en.wikipedia.org/wiki/God_object

* https://en.wikipedia.org/wiki/Extract_class

* https://en.wikipedia.org/wiki/Code_refactoring

* https://www.refactoring.com/

* https://www.joelonsoftware.com/2002/01/23/rub-a-dub-dub/

Some small optimisations may have slipped in as well.
2019-08-29 16:55:47 +03:00
Shlomi Fish
5bc41f5614 Add more items to "how you can contribute". 2019-08-29 15:54:34 +03:00
Shlomi Fish
a472160ca7 Extract a common class/struct.
This is Refactoring / code cleanup.

See:

* https://en.wikipedia.org/wiki/God_object

* https://en.wikipedia.org/wiki/Extract_class

* https://en.wikipedia.org/wiki/Code_refactoring

* https://www.refactoring.com/

* https://www.joelonsoftware.com/2002/01/23/rub-a-dub-dub/

Some small optimisations may have slipped in as well.
2019-08-27 21:32:20 +03:00
34 changed files with 5806 additions and 3388 deletions

View file

@ -12,6 +12,7 @@ for general guidelines for contributing to open source.
# How you can contribute # How you can contribute
- Translate PySol to a human language you know. - Translate PySol to a human language you know.
- Test the "master" branch version of the version control repository or other prereleases.
- Try to reproduce [open issues](https://github.com/shlomif/PySolFC/issues) - Try to reproduce [open issues](https://github.com/shlomif/PySolFC/issues)
- Try to fix bugs. - Try to fix bugs.
- Add new games. - Add new games.
@ -20,6 +21,7 @@ for general guidelines for contributing to open source.
- Add new features. - Add new features.
- Contribute graphics - Contribute graphics
- Improve the site - Improve the site
- Package PySol for a new package repository or OS, or update existing packages.
- Make a monetary donation. - Make a monetary donation.
- [Star](https://help.github.com/articles/about-stars/) or [Watch](https://help.github.com/articles/watching-and-unwatching-repositories/) the repository on GitHub - [Star](https://help.github.com/articles/about-stars/) or [Watch](https://help.github.com/articles/watching-and-unwatching-repositories/) the repository on GitHub

View file

@ -40,7 +40,7 @@ rules:
pot: pot:
./scripts/all_games.py gettext > po/games.pot ./scripts/all_games.py gettext > po/games.pot
xgettext --keyword=n_ -o po/pysol.pot \ xgettext --keyword=n_ --add-comments=TRANSLATORS: -o po/pysol.pot \
pysollib/*.py pysollib/*/*.py pysollib/*/*/*.py data/pysolfc.glade pysollib/*.py pysollib/*/*.py pysollib/*/*/*.py data/pysolfc.glade
set -e; \ set -e; \
for lng in ru de pl it; do \ for lng in ru de pl it; do \

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -47,7 +47,7 @@ from pysollib.pysoltk import create_find_card_dialog
from pysollib.pysoltk import create_solver_dialog from pysollib.pysoltk import create_solver_dialog
from pysollib.settings import DEBUG from pysollib.settings import DEBUG
from pysollib.settings import PACKAGE_URL, TITLE from pysollib.settings import PACKAGE_URL, TITLE
from pysollib.settings import TOP_TITLE from pysollib.settings import TOP_SIZE
from pysollib.stats import FileStatsFormatter from pysollib.stats import FileStatsFormatter
@ -381,7 +381,7 @@ class PysolMenubar(PysolMenubarTk):
if self._cancelDrag(): if self._cancelDrag():
return return
if self.changed(): if self.changed():
if not self.game.areYouSure(_("Quit ") + TITLE): if not self.game.areYouSure(_("Quit %s") % TITLE):
return return
self.game.endGame() self.game.endGame()
self.game.quitGame() self.game.quitGame()
@ -445,7 +445,7 @@ class PysolMenubar(PysolMenubarTk):
if not self.game.gsaveinfo.bookmarks: if not self.game.gsaveinfo.bookmarks:
return return
if not self.game.areYouSure(_("Clear bookmarks"), if not self.game.areYouSure(_("Clear bookmarks"),
_("Clear all bookmarks ?")): _("Clear all bookmarks?")):
return return
self.game.gsaveinfo.bookmarks = {} self.game.gsaveinfo.bookmarks = {}
self.game.updateMenus() self.game.updateMenus()
@ -457,7 +457,7 @@ class PysolMenubar(PysolMenubarTk):
return return
if self.changed(restart=1): if self.changed(restart=1):
if not self.game.areYouSure(_("Restart game"), if not self.game.areYouSure(_("Restart game"),
_("Restart this game ?")): _("Restart this game?")):
return return
self.game.restartGame() self.game.restartGame()
@ -501,10 +501,11 @@ class PysolMenubar(PysolMenubarTk):
if self._cancelDrag(break_pause=False): if self._cancelDrag(break_pause=False):
return return
game, gi = self.game, self.game.gameinfo game, gi = self.game, self.game.gameinfo
t = " " + game.getGameNumber(format=1) kw = {'game': gi.name,
cc = _("Comments for %s:\n\n") % (gi.name + t) 'id': game.getGameNumber(format=1)}
cc = _("Comments for %(game)s %(id)s:\n\n") % kw
c = game.gsaveinfo.comment or cc c = game.gsaveinfo.comment or cc
d = EditTextDialog(game.top, _("Comments for ")+t, text=c) d = EditTextDialog(game.top, _("Comments for %(id)s") % kw, text=c)
if d.status == 0 and d.button == 0: if d.status == 0 and d.button == 0:
text = d.text text = d.text
if text.strip() == cc.strip(): if text.strip() == cc.strip():
@ -525,8 +526,9 @@ class PysolMenubar(PysolMenubarTk):
text=_("Error while writing to file")) text=_("Error while writing to file"))
else: else:
d = MfxMessageDialog( d = MfxMessageDialog(
self.top, title=TITLE+_(" Info"), bitmap="info", self.top, title=_("%s Info") % TITLE, bitmap="info",
text=_("Comments were appended to\n\n") + fn) text=_("Comments were appended to\n\n%(filename)s")
% {'filename': fn})
self._setCommentMenu(bool(game.gsaveinfo.comment)) self._setCommentMenu(bool(game.gsaveinfo.comment))
# #
@ -535,10 +537,10 @@ class PysolMenubar(PysolMenubarTk):
def _mStatsSave(self, player, filename, write_method): def _mStatsSave(self, player, filename, write_method):
if player is None: if player is None:
text = _("Demo statistics") text = _("Demo statistics were appended to\n\n%(filename)s")
filename = filename + "_demo" filename = filename + "_demo"
else: else:
text = _("Your statistics") text = _("Your statistics were appended to\n\n%(filename)s")
filename = os.path.join(self.app.dn.config, filename + ".txt") filename = os.path.join(self.app.dn.config, filename + ".txt")
filename = os.path.normpath(filename) filename = os.path.normpath(filename)
try: try:
@ -549,8 +551,8 @@ class PysolMenubar(PysolMenubarTk):
text=_("Error while writing to file")) text=_("Error while writing to file"))
else: else:
MfxMessageDialog( MfxMessageDialog(
self.top, title=TITLE+_(" Info"), bitmap="info", self.top, title=_("%s Info") % TITLE, bitmap="info",
text=text + _(" were appended to\n\n") + filename) text=text % {'filename': filename})
def mPlayerStats(self, *args, **kw): def mPlayerStats(self, *args, **kw):
mode = kw.get("mode", 101) mode = kw.get("mode", 101)
@ -564,31 +566,40 @@ class PysolMenubar(PysolMenubarTk):
d = Struct(status=-1, button=-1) d = Struct(status=-1, button=-1)
if demo: if demo:
player = None player = None
p0, p1, p2 = TITLE+_(" Demo"), TITLE+_(" Demo "), ""
else: else:
player = self.app.opt.player player = self.app.opt.player
p0, p1, p2 = player, "", _(" for ") + player
n = self.game.gameinfo.name n = self.game.gameinfo.name
# translation keywords
transkw = {'app': TITLE,
'player': player,
'game': n,
'tops': TOP_SIZE}
# #
if mode == 100: if mode == 100:
d = Status_StatsDialog(self.top, game=self.game) d = Status_StatsDialog(self.top, game=self.game)
elif mode == 101: elif mode == 101:
header = p1 + _("Statistics for ") + n header = (_("%(app)s Demo Statistics for %(game)s") if demo
else _("Statistics for %(game)s")) % transkw
d = SingleGame_StatsDialog( d = SingleGame_StatsDialog(
self.top, header, self.app, player, gameid=self.game.id) self.top, header, self.app, player, gameid=self.game.id)
gameid = d.selected_game gameid = d.selected_game
elif mode == 102: elif mode == 102:
header = p1 + _("Statistics") + p2 header = (_("%(app)s Demo Statistics") if demo
else _("Statistics for %(player)s")) % transkw
d = AllGames_StatsDialog(self.top, header, self.app, player) d = AllGames_StatsDialog(self.top, header, self.app, player)
gameid = d.selected_game gameid = d.selected_game
elif mode == 103: elif mode == 103:
header = p1 + _("Full log") + p2 header = (_("%(app)s Demo Full log") if demo
else _("Full log for %(player)s")) % transkw
d = FullLog_StatsDialog(self.top, header, self.app, player) d = FullLog_StatsDialog(self.top, header, self.app, player)
elif mode == 104: elif mode == 104:
header = p1 + _("Session log") + p2 header = (_("%(app)s Demo Session log") if demo
else _("Session log for %(player)s")) % transkw
d = SessionLog_StatsDialog(self.top, header, self.app, player) d = SessionLog_StatsDialog(self.top, header, self.app, player)
elif mode == 105: elif mode == 105:
header = p1 + TOP_TITLE + _(" for ") + n # TRANSLATORS: eg. top 10 or top 5 results for a certain game
header = (_("%(app)s Demo Top %(tops)d for %(game)s") if demo
else _("Top %(tops)d for %(game)s")) % transkw
d = Top_StatsDialog( d = Top_StatsDialog(
self.top, header, self.app, player, gameid=self.game.id) self.top, header, self.app, player, gameid=self.game.id)
elif mode == 106: elif mode == 106:
@ -614,7 +625,8 @@ class PysolMenubar(PysolMenubarTk):
# reset all player stats # reset all player stats
if self.game.areYouSure( if self.game.areYouSure(
_("Reset all statistics"), _("Reset all statistics"),
_("Reset ALL statistics and logs for player\n%s ?") % p0, _("Reset ALL statistics and logs for player\n" +
"%(player)s?") % transkw,
confirm=1, default=1 confirm=1, default=1
): ):
self.app.stats.resetStats(player, 0) self.app.stats.resetStats(player, 0)
@ -624,8 +636,8 @@ class PysolMenubar(PysolMenubarTk):
# reset player stats for current game # reset player stats for current game
if self.game.areYouSure( if self.game.areYouSure(
_("Reset game statistics"), _("Reset game statistics"),
_('Reset statistics and logs ' + _('Reset statistics and logs for player\n%(player)s\n'
'for player\n%s\nand game\n%s ?') % (p0, n), 'and game\n%(game)s?') % transkw,
confirm=1, default=1 confirm=1, default=1
): ):
self.app.stats.resetStats(player, self.game.id) self.app.stats.resetStats(player, self.game.id)

View file

@ -60,7 +60,7 @@ from pysollib.resource import Tile, TileManager
from pysollib.settings import DEBUG from pysollib.settings import DEBUG
from pysollib.settings import PACKAGE, VERSION_TUPLE, WIN_SYSTEM from pysollib.settings import PACKAGE, VERSION_TUPLE, WIN_SYSTEM
from pysollib.settings import TOOLKIT from pysollib.settings import TOOLKIT
from pysollib.util import CARDSET, IMAGE_EXTENSIONS from pysollib.util import IMAGE_EXTENSIONS
from pysollib.winsystems import TkSettings from pysollib.winsystems import TkSettings
if TOOLKIT == 'tk': if TOOLKIT == 'tk':
from pysollib.ui.tktile.solverdialog import destroy_solver_dialog from pysollib.ui.tktile.solverdialog import destroy_solver_dialog
@ -329,7 +329,8 @@ class Application:
elif self.commandline.game is not None: elif self.commandline.game is not None:
gameid = self.gdb.getGameByName(self.commandline.game) gameid = self.gdb.getGameByName(self.commandline.game)
if gameid is None: if gameid is None:
print_err(_("can't find game: ") + self.commandline.game) print_err(_("can't find game: %(game)s") % {
'game': self.commandline.game})
sys.exit(-1) sys.exit(-1)
else: else:
self.nextgame.id = gameid self.nextgame.id = gameid
@ -668,7 +669,7 @@ class Application:
if progress is None: if progress is None:
self.wm_save_state() self.wm_save_state()
self.wm_withdraw() self.wm_withdraw()
title = _("Loading %s %s...") % (CARDSET, cs.name) title = _("Loading cardset %s...") % cs.name
color = self.opt.colors['table'] color = self.opt.colors['table']
if self.tabletile_index > 0: if self.tabletile_index > 0:
color = "#008200" color = "#008200"
@ -678,7 +679,7 @@ class Application:
images = Images(self.dataloader, cs) images = Images(self.dataloader, cs)
try: try:
if not images.load(app=self, progress=progress): if not images.load(app=self, progress=progress):
raise Exception("Invalid or damaged "+CARDSET) raise Exception("Invalid or damaged cardset")
simages = SubsampledImages(images) simages = SubsampledImages(images)
if self.opt.save_cardsets: if self.opt.save_cardsets:
c = self.cardsets_cache.get(cs.type) c = self.cardsets_cache.get(cs.type)
@ -710,8 +711,8 @@ class Application:
# images.destruct() # images.destruct()
destruct(images) destruct(images)
MfxExceptionDialog( MfxExceptionDialog(
self.top, ex, title=CARDSET+_(" load error"), self.top, ex, title=_("Cardset load error"),
text=_("Error while loading ")+CARDSET) text=_("Error while loading cardset"))
self.intro.progress = progress self.intro.progress = progress
if r and self.menubar is not None: if r and self.menubar is not None:
self.menubar.updateBackgroundImagesMenu() self.menubar.updateBackgroundImagesMenu()
@ -806,14 +807,14 @@ class Application:
# #
t = self.checkCompatibleCardsetType(gi, self.cardset) t = self.checkCompatibleCardsetType(gi, self.cardset)
MfxMessageDialog( MfxMessageDialog(
self.top, title=_("Incompatible ")+CARDSET, self.top, title=_("Incompatible cardset"),
bitmap="warning", bitmap="warning",
text=_('''The currently selected %s %s text=_('''The currently selected cardset %(cardset)s
is not compatible with the game is not compatible with the game
%s %(game)s
Please select a %s type %s. Please select a %(correct_type)s type cardset.
''') % (CARDSET, self.cardset.name, gi.name, t[0], CARDSET), ''') % {'cardset': self.cardset.name, 'game': gi.name, 'correct_type': t[0]},
strings=(_("&OK"),), default=0) strings=(_("&OK"),), default=0)
cs = self.__selectCardsetDialog(t) cs = self.__selectCardsetDialog(t)
if cs is None: if cs is None:
@ -852,7 +853,7 @@ Please select a %s type %s.
def __selectCardsetDialog(self, t): def __selectCardsetDialog(self, t):
cs = self.selectCardset( cs = self.selectCardset(
_("Please select a %s type %s") % (t[0], CARDSET), _("Please select a %s type cardset") % t[0],
self.cardset.index) self.cardset.index)
return cs return cs
@ -1060,7 +1061,8 @@ Please select a %s type %s.
except Exception as ex: except Exception as ex:
if DEBUG: if DEBUG:
traceback.print_exc() traceback.print_exc()
print_err(_("error loading plugin %s: %s") % (n, ex)) print_err(_("error loading plugin %(file)s: %(err)s") %
{'file': n, 'err': ex})
# #
# init cardsets # init cardsets

View file

@ -63,7 +63,7 @@ from pysollib.pysoltk import MfxExceptionDialog, MfxMessageDialog
from pysollib.pysoltk import after, after_cancel, after_idle from pysollib.pysoltk import after, after_cancel, after_idle
from pysollib.pysoltk import bind, wm_map from pysollib.pysoltk import bind, wm_map
from pysollib.settings import DEBUG from pysollib.settings import DEBUG
from pysollib.settings import PACKAGE, TITLE, TOOLKIT, TOP_TITLE from pysollib.settings import PACKAGE, TITLE, TOOLKIT, TOP_SIZE
from pysollib.settings import VERSION, VERSION_TUPLE from pysollib.settings import VERSION, VERSION_TUPLE
from pysollib.struct_new import NewStruct from pysollib.struct_new import NewStruct
@ -78,6 +78,7 @@ else:
PLAY_TIME_TIMEOUT = 200 PLAY_TIME_TIMEOUT = 200
S_PLAY = 0x40
# ************************************************************************ # ************************************************************************
# * Base class for all solitaire games # * Base class for all solitaire games
@ -430,6 +431,26 @@ class GameGlobalStatsStruct(NewStruct):
start_player = attr.ib(default=None) start_player = attr.ib(default=None)
@attr.s
class GameWinAnimation(NewStruct):
timer = attr.ib(default=None)
images = attr.ib(factory=list)
tk_images = attr.ib(factory=list) # saved tk images
saved_images = attr.ib(factory=dict) # saved resampled images
canvas_images = attr.ib(factory=list) # ids of canvas images
frame_num = attr.ib(default=0) # number of the current frame
width = attr.ib(default=0)
height = attr.ib(default=0)
@attr.s
class GameMoves(NewStruct):
current = attr.ib(factory=list)
history = attr.ib(factory=list)
index = attr.ib(default=0)
state = attr.ib(default=S_PLAY)
class Game(object): class Game(object):
# for self.gstats.updated # for self.gstats.updated
U_PLAY = _GLOBAL_U_PLAY U_PLAY = _GLOBAL_U_PLAY
@ -442,8 +463,8 @@ class Game(object):
S_DEAL = 0x10 S_DEAL = 0x10
S_FILL = 0x20 S_FILL = 0x20
S_RESTORE = 0x30 S_RESTORE = 0x30
S_PLAY = 0x40
S_UNDO = 0x50 S_UNDO = 0x50
S_PLAY = S_PLAY
S_REDO = 0x60 S_REDO = 0x60
# for loading and saving - subclasses should override if # for loading and saving - subclasses should override if
@ -698,16 +719,7 @@ class Game(object):
comment="", comment="",
) )
# some vars for win animation # some vars for win animation
self.win_animation = Struct( self.win_animation = GameWinAnimation()
timer=None,
images=[],
tk_images=[], # saved tk images
saved_images={}, # saved resampled images
canvas_images=[], # ids of canvas images
frame_num=0, # number of the current frame
width=0,
height=0,
)
def getTitleName(self): def getTitleName(self):
return self.app.getGameTitleName(self.id) return self.app.getGameTitleName(self.id)
@ -1298,7 +1310,7 @@ class Game(object):
if not title: if not title:
title = TITLE title = TITLE
if not text: if not text:
text = _("Discard current game ?") text = _("Discard current game?")
self.playSample("areyousure") self.playSample("areyousure")
d = MfxMessageDialog(self.top, title=title, text=text, d = MfxMessageDialog(self.top, title=title, text=text,
bitmap="question", bitmap="question",
@ -1919,19 +1931,24 @@ class Game(object):
if ret: if ret:
if ret[0] and ret[1]: if ret[0] and ret[1]:
top_msg = _( top_msg = _(
'''\nYou have reached\n''' + '\nYou have reached\n# %(timerank)d in the top ' +
'# %d in the %s of playing time' + '%(tops)d of playing time\nand # %(movesrank)d ' +
'\nand # %d in the %s of moves.') % \ 'in the top %(tops)d of moves.') % {
(ret[0], TOP_TITLE, ret[1], TOP_TITLE) 'timerank': ret[0],
'movesrank': ret[1],
'tops': TOP_SIZE}
elif ret[0]: # playing time elif ret[0]: # playing time
top_msg = _( top_msg = _(
'''\nYou have reached\n''' + '\nYou have reached\n# %(timerank)d in the top ' +
'''# %d in the %s of playing time.''') \ '%(tops)d of playing time.') % {
% (ret[0], TOP_TITLE) 'timerank': ret[0],
'tops': TOP_SIZE}
elif ret[1]: # moves elif ret[1]: # moves
top_msg = _( top_msg = _(
'''\nYou have reached\n''' + '\nYou have reached\n# %(movesrank)d in the top ' +
'# %d in the %s of moves.') % (ret[1], TOP_TITLE) '%(tops)s of moves.') % {
'movesrank': ret[1],
'tops': TOP_SIZE}
return top_msg return top_msg
elif not demo: elif not demo:
# only update the session log # only update the session log
@ -1963,14 +1980,14 @@ class Game(object):
self.finished = True self.finished = True
self.playSample("gameperfect", priority=1000) self.playSample("gameperfect", priority=1000)
self.winAnimation(perfect=1) self.winAnimation(perfect=1)
text = ungettext('''Your playing time is %s\nfor %d move.''', text = ungettext('Your playing time is %(time)s\nfor %(n)d move.',
'''Your playing time is %s\nfor %d moves.''', 'Your playing time is %(time)s\nfor %(n)d moves.',
self.moves.index) self.moves.index)
text = text % (time, self.moves.index) text = text % {'time': time, 'n': self.moves.index}
congrats = _('Congratulations, this\nwas a truly perfect game!')
d = MfxMessageDialog( d = MfxMessageDialog(
self.top, title=_("Game won"), self.top, title=_("Game won"),
text=_('\nCongratulations, this\nwas a truly perfect game !' + text='\n' + congrats + '\n\n' + text + '\n' + top_msg + '\n',
'\n\n%s\n%s\n') % (text, top_msg),
strings=(_("&New game"), None, _("&Cancel")), strings=(_("&New game"), None, _("&Cancel")),
image=self.app.gimages.logos[5]) image=self.app.gimages.logos[5])
elif status == 1: elif status == 1:
@ -1979,16 +1996,14 @@ class Game(object):
self.finished = True self.finished = True
self.playSample("gamewon", priority=1000) self.playSample("gamewon", priority=1000)
self.winAnimation() self.winAnimation()
text = ungettext('''Your playing time is %s\nfor %d move.''', text = ungettext('Your playing time is %(time)s\nfor %(n)d move.',
'''Your playing time is %s\nfor %d moves.''', 'Your playing time is %(time)s\nfor %(n)d moves.',
self.moves.index) self.moves.index)
text = text % (time, self.moves.index) text = text % {'time': time, 'n': self.moves.index}
congrats = _('Congratulations, you did it!')
d = MfxMessageDialog( d = MfxMessageDialog(
self.top, title=_("Game won"), self.top, title=_("Game won"),
text=( text='\n' + congrats + '\n\n' + text + '\n' + top_msg + '\n',
_('\nCongratulations, you did it !\n\n%s\n%s\n') %
(text, top_msg)
),
strings=(_("&New game"), None, _("&Cancel")), strings=(_("&New game"), None, _("&Cancel")),
image=self.app.gimages.logos[4]) image=self.app.gimages.logos[4])
elif self.gstats.updated < 0: elif self.gstats.updated < 0:
@ -2510,7 +2525,8 @@ class Game(object):
'\nGame solved in %d moves.\n', '\nGame solved in %d moves.\n',
self.moves.index) self.moves.index)
text = text % self.moves.index text = text % self.moves.index
d = MfxMessageDialog(self.top, title=TITLE+_(" Autopilot"), d = MfxMessageDialog(self.top,
title=_("%s Autopilot") % TITLE,
text=text, text=text,
image=self.app.gimages.logos[4], image=self.app.gimages.logos[4],
strings=(s,), strings=(s,),
@ -2524,7 +2540,8 @@ class Game(object):
if DEBUG: if DEBUG:
text += "\nplayer_moves: %d\ndemo_moves: %d\n" % \ text += "\nplayer_moves: %d\ndemo_moves: %d\n" % \
(self.stats.player_moves, self.stats.demo_moves) (self.stats.player_moves, self.stats.demo_moves)
d = MfxMessageDialog(self.top, title=TITLE+_(" Autopilot"), d = MfxMessageDialog(self.top,
title=_("%s Autopilot") % TITLE,
text=text, bitmap=bitmap, strings=(s,), text=text, bitmap=bitmap, strings=(s,),
padx=30, timeout=timeout) padx=30, timeout=timeout)
status = d.status status = d.status
@ -2538,7 +2555,8 @@ class Game(object):
s = self.app.miscrandom.choice( s = self.app.miscrandom.choice(
(_("&Oh well"), _("&That's life"), _("&Hmm"))) (_("&Oh well"), _("&That's life"), _("&Hmm")))
# ??? accelerators # ??? accelerators
d = MfxMessageDialog(self.top, title=TITLE+_(" Autopilot"), d = MfxMessageDialog(self.top,
title=_("%s Autopilot") % TITLE,
text=_("\nThis won't come out...\n"), text=_("\nThis won't come out...\n"),
bitmap=bitmap, strings=(s,), bitmap=bitmap, strings=(s,),
padx=30, timeout=timeout) padx=30, timeout=timeout)
@ -2760,12 +2778,7 @@ class Game(object):
# #
def startMoves(self): def startMoves(self):
self.moves = Struct( self.moves = GameMoves()
state=self.S_PLAY,
history=[], # list of lists of atomic moves
index=0,
current=[], # atomic moves for the current move
)
self.stats._reset_statistics() self.stats._reset_statistics()
def __storeMove(self, am): def __storeMove(self, am):
@ -2992,7 +3005,7 @@ class Game(object):
if confirm and self.gsaveinfo.bookmarks.get(n): if confirm and self.gsaveinfo.bookmarks.get(n):
if not self.areYouSure( if not self.areYouSure(
_("Set bookmark"), _("Set bookmark"),
_("Replace existing bookmark %d ?") % (n+1)): _("Replace existing bookmark %d?") % (n+1)):
return 0 return 0
f = BytesIO() f = BytesIO()
try: try:
@ -3014,7 +3027,7 @@ class Game(object):
confirm = self.app.opt.confirm confirm = self.app.opt.confirm
if confirm: if confirm:
if not self.areYouSure(_("Goto bookmark"), if not self.areYouSure(_("Goto bookmark"),
_("Goto bookmark %d ?") % (n+1)): _("Goto bookmark %d?") % (n+1)):
return return
try: try:
s, moves_index = bm s, moves_index = bm
@ -3136,9 +3149,9 @@ class Game(object):
version_tuple = pload(tuple) version_tuple = pload(tuple)
validate( validate(
version_tuple >= (1, 0), version_tuple >= (1, 0),
_('''Cannot load games saved with\n%s version %s''') % ( _('Cannot load games saved with\n%(app)s version %(ver)s') % {
PACKAGE, 'app': PACKAGE,
version)) 'ver': version})
game_version = 1 game_version = 1
bookmark = pload(int) bookmark = pload(int)
validate(0 <= bookmark <= 2, err_txt) validate(0 <= bookmark <= 2, err_txt)

View file

@ -120,7 +120,8 @@ class Matriarchy_Talon(WasteTalonStack):
return return
WasteTalonStack.updateText(self, update_rounds=0) WasteTalonStack.updateText(self, update_rounds=0)
# t = "Round %d" % self.round # t = "Round %d" % self.round
t = _("Round %d/%d") % (self.round, self.max_rounds) t = _("Round %(round)d/%(max_rounds)d") % {
'round': self.round, 'max_rounds': self.max_rounds}
self.texts.rounds.config(text=t) self.texts.rounds.config(text=t)
t = _("Deal %d") % self.DEAL[self.round-1] t = _("Deal %d") % self.DEAL[self.round-1]
self.texts.misc.config(text=t) self.texts.misc.config(text=t)

View file

@ -40,17 +40,18 @@ from pysollib.settings import PACKAGE_URL, TITLE, TOOLKIT, VERSION
def help_about(app, timeout=0, sound=True): def help_about(app, timeout=0, sound=True):
if sound: if sound:
app.audio.playSample("about") app.audio.playSample("about")
t = _("A Python Solitaire Game Collection\n") t = _("A Python Solitaire Game Collection")
if app.miscrandom.random() < 0.8: if app.miscrandom.random() < 0.8:
t = _("A World Domination Project\n") t = _("A World Domination Project")
strings = (_("&Nice"), _("&Credits...")) strings = (_("&Nice"), _("&Credits..."))
if timeout: if timeout:
strings = (_("&Enjoy"),) strings = (_("&Enjoy"),)
version = _("Version %s") % VERSION version = _("Version %s") % VERSION
d = PysolAboutDialog(app, app.top, title=_("About ") + TITLE, d = PysolAboutDialog(app, app.top, title=_("About %s") % TITLE,
timeout=timeout, timeout=timeout,
text=_('''PySol Fan Club edition text=_('''PySol Fan Club edition
%s%s %(description)s
%(versioninfo)s
Copyright (C) 1998 - 2003 Markus F.X.J. Oberhumer. Copyright (C) 1998 - 2003 Markus F.X.J. Oberhumer.
Copyright (C) 2003 Mt. Hood Playing Card Co. Copyright (C) 2003 Mt. Hood Playing Card Co.
@ -60,7 +61,8 @@ All Rights Reserved.
PySol is free software distributed under the terms PySol is free software distributed under the terms
of the GNU General Public License. of the GNU General Public License.
For more information about this application visit''') % (t, version), For more information about this application visit''') %
{'description': t, 'versioninfo': version},
url=PACKAGE_URL, url=PACKAGE_URL,
image=app.gimages.logos[2], image=app.gimages.logos[2],
strings=strings, default=0, strings=strings, default=0,
@ -86,7 +88,7 @@ def help_credits(app, timeout=0, sound=True):
t = "kivy" t = "kivy"
d = MfxMessageDialog( d = MfxMessageDialog(
app.top, title=_("Credits"), timeout=timeout, app.top, title=_("Credits"), timeout=timeout,
text=TITLE+_(''' credits go to: text=_('''%(app)s credits go to:
Volker Weidner for getting me into Solitaire Volker Weidner for getting me into Solitaire
Guido van Rossum for the initial example program Guido van Rossum for the initial example program
@ -95,8 +97,8 @@ Carl Larsson for the background music
The Gnome AisleRiot team for parts of the documentation The Gnome AisleRiot team for parts of the documentation
Natascha Natascha
The Python, %s, SDL & Linux crews The Python, %(gui_library)s, SDL & Linux crews
for making this program possible''') % t, for making this program possible''') % {'app': TITLE, 'gui_library': t},
image=app.gimages.logos[3], image_side="right", image=app.gimages.logos[3], image_side="right",
separator=True) separator=True)
return d.status return d.status
@ -122,8 +124,8 @@ def help_html(app, document, dir_, top=None):
document, dir_ = "index.html", "html" document, dir_ = "index.html", "html"
help_html_index = app.dataloader.findFile(document, dir_) help_html_index = app.dataloader.findFile(document, dir_)
except EnvironmentError: except EnvironmentError:
MfxMessageDialog(app.top, title=TITLE + _(" HTML Problem"), MfxMessageDialog(app.top, title=_("%s HTML Problem") % TITLE,
text=_("Cannot find help document\n") + document, text=_("Cannot find help document\n%s") % document,
bitmap="warning") bitmap="warning")
return None return None
# print doc, help_html_index # print doc, help_html_index
@ -136,7 +138,7 @@ def help_html(app, document, dir_, top=None):
viewer.display(doc, relpath=0) viewer.display(doc, relpath=0)
except Exception: except Exception:
# traceback.print_exc() # traceback.print_exc()
top = make_help_toplevel(app, title=TITLE+_(" Help")) top = make_help_toplevel(app, title=_("%s Help") % TITLE)
if top.winfo_screenwidth() < 800 or top.winfo_screenheight() < 600: if top.winfo_screenwidth() < 800 or top.winfo_screenheight() < 600:
# maximized = 1 # maximized = 1
top.wm_minsize(300, 150) top.wm_minsize(300, 150)

View file

@ -51,7 +51,6 @@ from pysollib.mygettext import _
from pysollib.pysoltk import connect_game_find_card_dialog from pysollib.pysoltk import connect_game_find_card_dialog
from pysollib.settings import SELECT_GAME_MENU from pysollib.settings import SELECT_GAME_MENU
from pysollib.settings import TITLE from pysollib.settings import TITLE
from pysollib.util import CARDSET
# ************************************************************************ # ************************************************************************
@ -177,34 +176,34 @@ class MainMenuDialog(LMenuDialog):
def buildTree(self, tv, node): def buildTree(self, tv, node):
rg = tv.add_node( rg = tv.add_node(
LTreeNode( LTreeNode(
text="File", text=_("File"),
command=self.make_game_command(self.menubar.mFileMenuDialog))) command=self.make_game_command(self.menubar.mFileMenuDialog)))
rg = tv.add_node( rg = tv.add_node(
LTreeNode( LTreeNode(
text="Games", text=_("Games"),
command=self.make_game_command( command=self.make_game_command(
self.menubar.mSelectGameDialog))) self.menubar.mSelectGameDialog)))
rg = tv.add_node( rg = tv.add_node(
LTreeNode( LTreeNode(
text="Tools", text=_("Tools"),
command=self.make_game_command(self.menubar.mEditMenuDialog))) command=self.make_game_command(self.menubar.mEditMenuDialog)))
rg = tv.add_node( rg = tv.add_node(
LTreeNode( LTreeNode(
text="Statistics", text=_("Statistics"),
command=self.make_game_command(self.menubar.mGameMenuDialog))) command=self.make_game_command(self.menubar.mGameMenuDialog)))
rg = tv.add_node( rg = tv.add_node(
LTreeNode( LTreeNode(
text="Assist", text=_("Assist"),
command=self.make_game_command( command=self.make_game_command(
self.menubar.mAssistMenuDialog))) self.menubar.mAssistMenuDialog)))
rg = tv.add_node( rg = tv.add_node(
LTreeNode( LTreeNode(
text="Options", text=_("Options"),
command=self.make_game_command( command=self.make_game_command(
self.menubar.mOptionsMenuDialog))) self.menubar.mOptionsMenuDialog)))
rg = tv.add_node( rg = tv.add_node(
LTreeNode( LTreeNode(
text="Help", text=_("Help"),
command=self.make_game_command(self.menubar.mHelpMenuDialog))) command=self.make_game_command(self.menubar.mHelpMenuDialog)))
del rg del rg
@ -225,7 +224,7 @@ class FileMenuDialog(LMenuDialog):
def buildTree(self, tv, node): def buildTree(self, tv, node):
rg = tv.add_node( rg = tv.add_node(
LTreeNode(text='Recent games')) LTreeNode(text=_('Recent games')))
# Recent Liste # Recent Liste
recids = self.app.opt.recent_gameid recids = self.app.opt.recent_gameid
# recgames = [] # recgames = []
@ -238,12 +237,12 @@ class FileMenuDialog(LMenuDialog):
LTreeNode(text=gi.name, command=command), rg) LTreeNode(text=gi.name, command=command), rg)
rg = tv.add_node( rg = tv.add_node(
LTreeNode(text='Favorite games')) LTreeNode(text=_('Favorite games')))
if rg: if rg:
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='<Add>', command=self.menubar.mAddFavor), rg) text=_('<Add>'), command=self.menubar.mAddFavor), rg)
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='<Remove>', command=self.menubar.mDelFavor), rg) text=_('<Remove>'), command=self.menubar.mDelFavor), rg)
# Recent Liste # Recent Liste
favids = self.app.opt.favorite_gameid favids = self.app.opt.favorite_gameid
@ -289,36 +288,36 @@ class EditMenuDialog(LMenuDialog): # Tools
def buildTree(self, tv, node): def buildTree(self, tv, node):
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='New game', command=self.menubar.mNewGame)) text=_('New game'), command=self.menubar.mNewGame))
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='Restart game', command=self.menubar.mRestart)) text=_('Restart game'), command=self.menubar.mRestart))
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='Undo', command=self.menubar.mUndo)) text=_('Undo'), command=self.menubar.mUndo))
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='Redo', command=self.menubar.mRedo)) text=_('Redo'), command=self.menubar.mRedo))
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='Redo all', command=self.menubar.mRedoAll)) text=_('Redo all'), command=self.menubar.mRedoAll))
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='Auto drop', command=self.menubar.mDrop)) text=_('Auto drop'), command=self.menubar.mDrop))
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='Shuffle tiles', command=self.menubar.mShuffle)) text=_('Shuffle tiles'), command=self.menubar.mShuffle))
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='Deal cards', command=self.menubar.mDeal)) text=_('Deal cards'), command=self.menubar.mDeal))
self.addCheckNode(tv, None, self.addCheckNode(tv, None,
'Pause', _('Pause'),
self.menubar.tkopt.pause, self.menubar.tkopt.pause,
self.menubar.mPause) self.menubar.mPause)
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='Load game', command=self.menubar.mOpen)) text=_('Load game'), command=self.menubar.mOpen))
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='Save game', command=self.menubar.mSaveAs)) text=_('Save game'), command=self.menubar.mSaveAs))
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='Help', command=self.menubar.mHelpRules)) text=_('Help'), command=self.menubar.mHelpRules))
# ------------------------------------------- # -------------------------------------------
# TBD ? # TBD ?
@ -369,7 +368,7 @@ class GameMenuDialog(LMenuDialog):
def buildTree(self, tv, node): def buildTree(self, tv, node):
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='Current game ...', text=_('Current game...'),
command=self.make_command(101, self.menubar.mPlayerStats)), None) command=self.make_command(101, self.menubar.mPlayerStats)), None)
# tv.add_node(LTreeNode( # tv.add_node(LTreeNode(
@ -432,16 +431,16 @@ class AssistMenuDialog(LMenuDialog):
def buildTree(self, tv, node): def buildTree(self, tv, node):
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='Hint', command=self.menubar.mHint)) text=_('Hint'), command=self.menubar.mHint))
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='Highlight piles', command=self.menubar.mHighlightPiles)) text=_('Highlight piles'), command=self.menubar.mHighlightPiles))
# tv.add_node(LTreeNode( # tv.add_node(LTreeNode(
# text='Find Card', command=self.menubar.mFindCard)) # text='Find Card', command=self.menubar.mFindCard))
tv.add_node(LTreeNode( tv.add_node(LTreeNode(
text='Demo', command=self.menubar.mDemo)) text=_('Demo'), command=self.menubar.mDemo))
# ------------------------------------------- # -------------------------------------------
# TBD. How ? # TBD. How ?
@ -507,27 +506,27 @@ class OptionsMenuDialog(LMenuDialog):
# Automatic play settings # Automatic play settings
rg = tv.add_node( rg = tv.add_node(
LTreeNode(text='Automatic play')) LTreeNode(text=_('Automatic play')))
if rg: if rg:
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Auto face up', _('Auto face up'),
self.menubar.tkopt.autofaceup, self.menubar.tkopt.autofaceup,
self.menubar.mOptAutoFaceUp) self.menubar.mOptAutoFaceUp)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Auto drop', _('Auto drop'),
self.menubar.tkopt.autodrop, self.menubar.tkopt.autodrop,
self.menubar.mOptAutoDrop) self.menubar.mOptAutoDrop)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Auto deal', _('Auto deal'),
self.menubar.tkopt.autodeal, self.menubar.tkopt.autodeal,
self.menubar.mOptAutoDeal) self.menubar.mOptAutoDeal)
# submenu.add_separator() # submenu.add_separator()
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Quick play', _('Quick play'),
self.menubar.tkopt.quickplay, self.menubar.tkopt.quickplay,
self.menubar.mOptQuickPlay) self.menubar.mOptQuickPlay)
@ -535,57 +534,57 @@ class OptionsMenuDialog(LMenuDialog):
# Player assistance # Player assistance
rg = tv.add_node( rg = tv.add_node(
LTreeNode(text='Assist level')) LTreeNode(text=_('Assist level')))
if rg: if rg:
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Enable undo', _('Enable undo'),
self.menubar.tkopt.undo, self.menubar.tkopt.undo,
self.menubar.mOptEnableUndo) self.menubar.mOptEnableUndo)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Enable bookmarks', _('Enable bookmarks'),
self.menubar.tkopt.bookmarks, self.menubar.tkopt.bookmarks,
self.menubar.mOptEnableBookmarks) self.menubar.mOptEnableBookmarks)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Enable hint', _('Enable hint'),
self.menubar.tkopt.hint, self.menubar.tkopt.hint,
self.menubar.mOptEnableHint) self.menubar.mOptEnableHint)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Enable shuffle', _('Enable shuffle'),
self.menubar.tkopt.shuffle, self.menubar.tkopt.shuffle,
self.menubar.mOptEnableShuffle) self.menubar.mOptEnableShuffle)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Enable highlight piles', _('Enable highlight piles'),
self.menubar.tkopt.highlight_piles, self.menubar.tkopt.highlight_piles,
self.menubar.mOptEnableHighlightPiles) self.menubar.mOptEnableHighlightPiles)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Enable highlight cards', _('Enable highlight cards'),
self.menubar.tkopt.highlight_cards, self.menubar.tkopt.highlight_cards,
self.menubar.mOptEnableHighlightCards) self.menubar.mOptEnableHighlightCards)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Enable highlight same rank', _('Enable highlight same rank'),
self.menubar.tkopt.highlight_samerank, self.menubar.tkopt.highlight_samerank,
self.menubar.mOptEnableHighlightSameRank) self.menubar.mOptEnableHighlightSameRank)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Highlight no matching', _('Highlight no matching'),
self.menubar.tkopt.highlight_not_matching, self.menubar.tkopt.highlight_not_matching,
self.menubar.mOptEnableHighlightNotMatching) self.menubar.mOptEnableHighlightNotMatching)
# submenu.add_separator() # submenu.add_separator()
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Show removed tiles (in Mahjongg games)', _('Show removed tiles (in Mahjongg games)'),
self.menubar.tkopt.mahjongg_show_removed, self.menubar.tkopt.mahjongg_show_removed,
self.menubar.mOptMahjonggShowRemoved) self.menubar.mOptMahjonggShowRemoved)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Show hint arrow (in Shisen-Sho games)', _('Show hint arrow (in Shisen-Sho games)'),
self.menubar.tkopt.shisen_show_hint, self.menubar.tkopt.shisen_show_hint,
self.menubar.mOptShisenShowHint) self.menubar.mOptShisenShowHint)
@ -595,154 +594,154 @@ class OptionsMenuDialog(LMenuDialog):
# Sound options # Sound options
rg = tv.add_node( rg = tv.add_node(
LTreeNode(text='Sound')) LTreeNode(text=_('Sound')))
if rg: if rg:
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Enable', _('Enable'),
self.menubar.tkopt.sound, self.menubar.tkopt.sound,
self.menubar.mOptSoundDialog) self.menubar.mOptSoundDialog)
rg1 = tv.add_node( rg1 = tv.add_node(
LTreeNode(text='Volume'), rg) LTreeNode(text=_('Volume')), rg)
if rg1: if rg1:
self.addRadioNode(tv, rg1, self.addRadioNode(tv, rg1,
'100%', _('100%'),
self.menubar.tkopt.sound_sample_volume, 100, self.menubar.tkopt.sound_sample_volume, 100,
self.menubar.mOptSoundSampleVol) self.menubar.mOptSoundSampleVol)
self.addRadioNode(tv, rg1, self.addRadioNode(tv, rg1,
'75%', _('75%'),
self.menubar.tkopt.sound_sample_volume, 75, self.menubar.tkopt.sound_sample_volume, 75,
self.menubar.mOptSoundSampleVol) self.menubar.mOptSoundSampleVol)
self.addRadioNode(tv, rg1, self.addRadioNode(tv, rg1,
'50%', _('50%'),
self.menubar.tkopt.sound_sample_volume, 50, self.menubar.tkopt.sound_sample_volume, 50,
self.menubar.mOptSoundSampleVol) self.menubar.mOptSoundSampleVol)
self.addRadioNode(tv, rg1, self.addRadioNode(tv, rg1,
'25%', _('25%'),
self.menubar.tkopt.sound_sample_volume, 25, self.menubar.tkopt.sound_sample_volume, 25,
self.menubar.mOptSoundSampleVol) self.menubar.mOptSoundSampleVol)
rg1 = tv.add_node( rg1 = tv.add_node(
LTreeNode(text='Samples'), rg) LTreeNode(text=_('Samples')), rg)
if rg1: if rg1:
key = 'areyousure' key = 'areyousure'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'are you sure', _('are you sure'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'autodrop' key = 'autodrop'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'auto drop', _('auto drop'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'autoflip' key = 'autoflip'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'auto flip', _('auto flip'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'autopilotlost' key = 'autopilotlost'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'auto pilot lost', _('auto pilot lost'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'autopilotwon' key = 'autopilotwon'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'auto pilot won', _('auto pilot won'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'deal' key = 'deal'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'deal', _('deal'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'dealwaste' key = 'dealwaste'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'deal waste', _('deal waste'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'droppair' key = 'droppair'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'drop pair', _('drop pair'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'drop' key = 'drop'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'drop', _('drop'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'flip' key = 'flip'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'flip', _('flip'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'move' key = 'move'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'move', _('move'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'nomove' key = 'nomove'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'no move', _('no move'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'redo' key = 'redo'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'redo', _('redo'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'startdrag' key = 'startdrag'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'start drag', _('start drag'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'turnwaste' key = 'turnwaste'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'turn waste', _('turn waste'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'undo' key = 'undo'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'undo', _('undo'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'gamefinished' key = 'gamefinished'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'game finished', _('game finished'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'gamelost' key = 'gamelost'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'game lost', _('game lost'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'gameperfect' key = 'gameperfect'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'game perfect', _('game perfect'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
key = 'gamewon' key = 'gamewon'
self.addCheckNode( self.addCheckNode(
tv, rg1, tv, rg1,
'game won', _('game won'),
self.menubar.tkopt.sound_sample_vars[key], self.menubar.tkopt.sound_sample_vars[key],
self.make_vars_command(self.menubar.mOptSoundSample, key)) self.make_vars_command(self.menubar.mOptSoundSample, key))
@ -750,7 +749,7 @@ class OptionsMenuDialog(LMenuDialog):
# Cardsets and card backside options # Cardsets and card backside options
rg = tv.add_node( rg = tv.add_node(
LTreeNode(text='Cardsets')) LTreeNode(text=_('Cardsets')))
if rg: if rg:
self.menubar.tkopt.cardset.set(self.app.cardset.index) self.menubar.tkopt.cardset.set(self.app.cardset.index)
@ -790,45 +789,45 @@ class OptionsMenuDialog(LMenuDialog):
# Table background settings # Table background settings
rg = tv.add_node( rg = tv.add_node(
LTreeNode(text='Table')) LTreeNode(text=_('Table')))
if rg: if rg:
rg1 = tv.add_node( rg1 = tv.add_node(
LTreeNode(text='Solid colors'), rg) LTreeNode(text=_('Solid colors')), rg)
if rg1: if rg1:
key = 'table' key = 'table'
self.addRadioNode( self.addRadioNode(
tv, rg1, tv, rg1,
'Blue', _('Blue'),
self.menubar.tkopt.color_vars[key], '#0082df', self.menubar.tkopt.color_vars[key], '#0082df',
self.menubar.mOptTableColor) self.menubar.mOptTableColor)
self.addRadioNode( self.addRadioNode(
tv, rg1, tv, rg1,
'Green', _('Green'),
self.menubar.tkopt.color_vars[key], '#008200', self.menubar.tkopt.color_vars[key], '#008200',
self.menubar.mOptTableColor) self.menubar.mOptTableColor)
self.addRadioNode( self.addRadioNode(
tv, rg1, tv, rg1,
'Navy', _('Navy'),
self.menubar.tkopt.color_vars[key], '#000086', self.menubar.tkopt.color_vars[key], '#000086',
self.menubar.mOptTableColor) self.menubar.mOptTableColor)
self.addRadioNode( self.addRadioNode(
tv, rg1, tv, rg1,
'Olive', _('Olive'),
self.menubar.tkopt.color_vars[key], '#868200', self.menubar.tkopt.color_vars[key], '#868200',
self.menubar.mOptTableColor) self.menubar.mOptTableColor)
self.addRadioNode( self.addRadioNode(
tv, rg1, tv, rg1,
'Orange', _('Orange'),
self.menubar.tkopt.color_vars[key], '#f79600', self.menubar.tkopt.color_vars[key], '#f79600',
self.menubar.mOptTableColor) self.menubar.mOptTableColor)
self.addRadioNode( self.addRadioNode(
tv, rg1, tv, rg1,
'Teal', _('Teal'),
self.menubar.tkopt.color_vars[key], '#008286', self.menubar.tkopt.color_vars[key], '#008286',
self.menubar.mOptTableColor) self.menubar.mOptTableColor)
rg1 = tv.add_node( rg1 = tv.add_node(
LTreeNode(text='Tiles and Images'), rg) LTreeNode(text=_('Tiles and Images')), rg)
if rg1: if rg1:
tm = self.app.tabletile_manager tm = self.app.tabletile_manager
@ -848,30 +847,30 @@ class OptionsMenuDialog(LMenuDialog):
# Card view options # Card view options
rg = tv.add_node( rg = tv.add_node(
LTreeNode(text='Card view')) LTreeNode(text=_('Card view')))
if rg: if rg:
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Card shadow', _('Card shadow'),
self.menubar.tkopt.shadow, self.menubar.tkopt.shadow,
self.menubar.mOptShadow) self.menubar.mOptShadow)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Shade legal moves', _('Shade legal moves'),
self.menubar.tkopt.shade, self.menubar.tkopt.shade,
self.menubar.mOptShade) self.menubar.mOptShade)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Negative cards bottom', _('Negative cards bottom'),
self.menubar.tkopt.negative_bottom, self.menubar.tkopt.negative_bottom,
self.menubar.mOptNegativeBottom) self.menubar.mOptNegativeBottom)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Shrink face-down cards', _('Shrink face-down cards'),
self.menubar.tkopt.shrink_face_down, self.menubar.tkopt.shrink_face_down,
self.menubar.mOptShrinkFaceDown) self.menubar.mOptShrinkFaceDown)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Shade filled stacks', _('Shade filled stacks'),
self.menubar.tkopt.shade_filled_stacks, self.menubar.tkopt.shade_filled_stacks,
self.menubar.mOptShadeFilledStacks) self.menubar.mOptShadeFilledStacks)
@ -879,47 +878,47 @@ class OptionsMenuDialog(LMenuDialog):
# Animation settins # Animation settins
rg = tv.add_node( rg = tv.add_node(
LTreeNode(text='Animations')) LTreeNode(text=_('Animations')))
if rg: if rg:
self.addRadioNode(tv, rg, self.addRadioNode(tv, rg,
'None', _('None'),
self.menubar.tkopt.animations, 0, self.menubar.tkopt.animations, 0,
self.menubar.mOptAnimations) self.menubar.mOptAnimations)
self.addRadioNode(tv, rg, self.addRadioNode(tv, rg,
'Very fast', _('Very fast'),
self.menubar.tkopt.animations, 1, self.menubar.tkopt.animations, 1,
self.menubar.mOptAnimations) self.menubar.mOptAnimations)
self.addRadioNode(tv, rg, self.addRadioNode(tv, rg,
'Fast', _('Fast'),
self.menubar.tkopt.animations, 2, self.menubar.tkopt.animations, 2,
self.menubar.mOptAnimations) self.menubar.mOptAnimations)
self.addRadioNode(tv, rg, self.addRadioNode(tv, rg,
'Medium', _('Medium'),
self.menubar.tkopt.animations, 3, self.menubar.tkopt.animations, 3,
self.menubar.mOptAnimations) self.menubar.mOptAnimations)
self.addRadioNode(tv, rg, self.addRadioNode(tv, rg,
'Slow', _('Slow'),
self.menubar.tkopt.animations, 4, self.menubar.tkopt.animations, 4,
self.menubar.mOptAnimations) self.menubar.mOptAnimations)
self.addRadioNode(tv, rg, self.addRadioNode(tv, rg,
'Very slow', _('Very slow'),
self.menubar.tkopt.animations, 5, self.menubar.tkopt.animations, 5,
self.menubar.mOptAnimations) self.menubar.mOptAnimations)
# submenu.add_separator() # submenu.add_separator()
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Redeal animation', _('Redeal animation'),
self.menubar.tkopt.redeal_animation, self.menubar.tkopt.redeal_animation,
self.menubar.mRedealAnimation) self.menubar.mRedealAnimation)
self.addCheckNode(tv, rg, self.addCheckNode(tv, rg,
'Winning animation', _('Winning animation'),
self.menubar.tkopt.win_animation, self.menubar.tkopt.win_animation,
self.menubar.mWinAnimation) self.menubar.mWinAnimation)
@ -927,15 +926,15 @@ class OptionsMenuDialog(LMenuDialog):
# Touch mode settings # Touch mode settings
rg = tv.add_node( rg = tv.add_node(
LTreeNode(text='Touch mode')) LTreeNode(text=_('Touch mode')))
if rg: if rg:
self.addRadioNode(tv, rg, self.addRadioNode(tv, rg,
'Drag-and-Drop', _('Drag-and-Drop'),
self.menubar.tkopt.mouse_type, 'drag-n-drop', self.menubar.tkopt.mouse_type, 'drag-n-drop',
self.menubar.mOptMouseType) self.menubar.mOptMouseType)
self.addRadioNode(tv, rg, self.addRadioNode(tv, rg,
'Point-and-Click', _('Point-and-Click'),
self.menubar.tkopt.mouse_type, 'point-n-click', self.menubar.tkopt.mouse_type, 'point-n-click',
self.menubar.mOptMouseType) self.menubar.mOptMouseType)
@ -969,10 +968,10 @@ class OptionsMenuDialog(LMenuDialog):
# Toolbar options # Toolbar options
rg = tv.add_node( rg = tv.add_node(
LTreeNode(text='Toolbar')) LTreeNode(text=_('Toolbar')))
if rg: if rg:
self.addRadioNode(tv, rg, self.addRadioNode(tv, rg,
'Hide', _('Hide'),
self.menubar.tkopt.toolbar, 0, self.menubar.tkopt.toolbar, 0,
self.menubar.mOptToolbar) self.menubar.mOptToolbar)
@ -987,11 +986,11 @@ class OptionsMenuDialog(LMenuDialog):
# self.menubar.mOptToolbar) # self.menubar.mOptToolbar)
self.addRadioNode(tv, rg, self.addRadioNode(tv, rg,
'Left', _('Left'),
self.menubar.tkopt.toolbar, 3, self.menubar.tkopt.toolbar, 3,
self.menubar.mOptToolbar) self.menubar.mOptToolbar)
self.addRadioNode(tv, rg, self.addRadioNode(tv, rg,
'Right', _('Right'),
self.menubar.tkopt.toolbar, 4, self.menubar.tkopt.toolbar, 4,
self.menubar.mOptToolbar) self.menubar.mOptToolbar)
@ -1028,12 +1027,12 @@ class OptionsMenuDialog(LMenuDialog):
# self.menubar.mOptDemoLogo) # self.menubar.mOptDemoLogo)
self.addCheckNode(tv, None, self.addCheckNode(tv, None,
'Startup splash screen', _('Startup splash screen'),
self.menubar.tkopt.splashscreen, self.menubar.tkopt.splashscreen,
self.menubar.mOptSplashscreen) self.menubar.mOptSplashscreen)
self.addCheckNode(tv, None, self.addCheckNode(tv, None,
'Winning splash', _('Winning splash'),
self.menubar.tkopt.display_win_message, self.menubar.tkopt.display_win_message,
self.menubar.mWinDialog) self.menubar.mWinDialog)
@ -1056,23 +1055,23 @@ class HelpMenuDialog(LMenuDialog):
def buildTree(self, tv, node): def buildTree(self, tv, node):
tv.add_node( tv.add_node(
LTreeNode( LTreeNode(
text='Contents', text=_('Contents'),
command=self.make_help_command(self.menubar.mHelp))) command=self.make_help_command(self.menubar.mHelp)))
tv.add_node( tv.add_node(
LTreeNode( LTreeNode(
text='How to play', text=_('How to play'),
command=self.make_help_command(self.menubar.mHelpHowToPlay))) command=self.make_help_command(self.menubar.mHelpHowToPlay)))
tv.add_node( tv.add_node(
LTreeNode( LTreeNode(
text='Rules for this game', text=_('Rules for this game'),
command=self.make_help_command(self.menubar.mHelpRules))) command=self.make_help_command(self.menubar.mHelpRules)))
tv.add_node( tv.add_node(
LTreeNode( LTreeNode(
text='License terms', text=_('License terms'),
command=self.make_help_command(self.menubar.mHelpLicense))) command=self.make_help_command(self.menubar.mHelpLicense)))
tv.add_node( tv.add_node(
LTreeNode( LTreeNode(
text='About' + TITLE + '...', text=_('About %s...') % TITLE,
command=self.make_help_command(self.menubar.mHelpAbout))) command=self.make_help_command(self.menubar.mHelpAbout)))
# tv.add_node(LTreeNode( # tv.add_node(LTreeNode(
@ -1346,7 +1345,7 @@ class PysolMenubarTk:
# LMainMenuDialog() # LMainMenuDialog()
LMenuItem(self.__menubar.menu, LMenuItem(self.__menubar.menu,
text="Menu", command=self.mMainMenuDialog) text=_("Menu"), command=self.mMainMenuDialog)
MfxMenubar.addPath = None MfxMenubar.addPath = None
@ -1574,7 +1573,8 @@ class PysolMenubarTk:
menu.delete(0, 'last') menu.delete(0, 'last')
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: cmp2(a.name, b.name)) games.sort(lambda a, b: cmp2(a.name, b.name))
self._addSelectAllGameSubMenu(games, menu, self._addSelectAllGameSubMenu(games, menu,
@ -1791,8 +1791,9 @@ class PysolMenubarTk:
# #
DEFAULTEXTENSION = ".pso" DEFAULTEXTENSION = ".pso"
FILETYPES = ((TITLE + " files", "*" + DEFAULTEXTENSION), # TRANSLATORS: Usually, 'PySol files'
("All files", "*")) FILETYPES = ((_("%s files") % TITLE, "*" + DEFAULTEXTENSION),
(_("All files"), "*"))
def mAddFavor(self, *event): def mAddFavor(self, *event):
gameid = self.app.game.id gameid = self.app.game.id
@ -2066,10 +2067,9 @@ class PysolMenubarTk:
# if os.name == "posix": # if os.name == "posix":
strings, default = (None, _("&Load"), _( strings, default = (None, _("&Load"), _(
"&Cancel"), _("&Info..."), ), 1 "&Cancel"), _("&Info..."), ), 1
t = CARDSET
key = self.app.nextgame.cardset.index key = self.app.nextgame.cardset.index
d = SelectCardsetDialogWithPreview( d = SelectCardsetDialogWithPreview(
self.top, title=_("Select ") + t, self.top, title=_("Select cardset"),
app=self.app, manager=self.app.cardset_manager, key=key, app=self.app, manager=self.app.cardset_manager, key=key,
strings=strings, default=default) strings=strings, default=default)

View file

@ -165,7 +165,7 @@ class SelectGameData(SelectDialogTreeData):
if name is None or not list(filter( if name is None or not list(filter(
select_func, self.all_games_gi)): select_func, self.all_games_gi)):
continue continue
name = _("New games in v. ") + name name = _("New games in v. %(version)s") % {'version': 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_pysol_version = SelectGameNode(None, _("by PySol version"), s_by_pysol_version = SelectGameNode(None, _("by PySol version"),

View file

@ -406,7 +406,7 @@ class HTMLViewer:
# self.defcursor = 'xterm' # self.defcursor = 'xterm'
self.handcursor = "hand2" self.handcursor = "hand2"
self.title = "Browser" self.title = _("Browser")
self.window = None self.window = None
self.running = False self.running = False
@ -431,11 +431,11 @@ class HTMLViewer:
# BoxLayout(orientation='horizontal', size_hint=(1.0, 0.1)) # BoxLayout(orientation='horizontal', size_hint=(1.0, 0.1))
# create buttons # create buttons
self.homeButton = HTMLButton(text="Index", on_release=self.goHome) self.homeButton = HTMLButton(text=_("Index"), on_release=self.goHome)
self.backButton = HTMLButton(text="Back", on_release=self.goBack) self.backButton = HTMLButton(text=_("Back"), on_release=self.goBack)
self.forwardButton = HTMLButton( self.forwardButton = HTMLButton(
text="Forward", on_release=self.goForward) text=_("Forward"), on_release=self.goForward)
self.closeButton = HTMLButton(text="Close", on_release=self.goHome) self.closeButton = HTMLButton(text=_("Close"), on_release=self.goHome)
''' '''
buttonline.add_widget(self.homeButton) buttonline.add_widget(self.homeButton)
@ -683,7 +683,8 @@ class HTMLViewer:
self.display(self.home, relpath=0) self.display(self.home, relpath=0)
def errorDialog(self, msg): def errorDialog(self, msg):
MfxMessageDialog(self.parent, title=TITLE + " HTML Problem", MfxMessageDialog(self.parent,
title=_("%s HTML Problem") % TITLE,
text=msg, text=msg,
# bitmap="warning" # bitmap="warning"
# FIXME: this interp don't have images # FIXME: this interp don't have images

View file

@ -172,8 +172,11 @@ class SingleGame_StatsDialog(MfxDialog):
print('Stats(p): won=%s, lost=%s' % (won, lost)) print('Stats(p): won=%s, lost=%s' % (won, lost))
text1 = 'Total:\n won: %s ... %s%%\n lost: %s ... %s%%\n\n' % ( text1 = _('Total:\n' +
won, int(round(100.0 * pwon)), lost, int(round(100.0 * plost))) ' won: %(won)s ... %(percentwon)s%%\n' +
' lost: %(lost)s ... %(percentlost)s%%\n\n') % dict(
won=won, percentwon=int(round(100.0 * pwon)),
lost=lost, percentlost=int(round(100.0 * plost)))
# createChart(app, won, lost, _("Total")) # createChart(app, won, lost, _("Total"))
won, lost = app.stats.getSessionStats(player, gameid) won, lost = app.stats.getSessionStats(player, gameid)
@ -181,9 +184,11 @@ class SingleGame_StatsDialog(MfxDialog):
print('Stats(s): won=%s, lost=%s' % (won, lost)) print('Stats(s): won=%s, lost=%s' % (won, lost))
text2 = \ text2 = _('Current Session:\n' +
'Current Session:\n won: %s ... %s%%\n lost: %s ... %s%%\n' % \ ' won: %(won)s ... %(percentwon)s%%\n' +
(won, int(round(100.0 * pwon)), lost, int(round(100.0 * plost))) ' lost: %(lost)s ... %(percentlost)s%%\n') % dict(
won=won, percentwon=(round(100.0 * pwon)),
lost=lost, percentlost=int(round(100.0 * plost)))
# text2 = 'Current Session:\n won=%s, lost=%s\n' % (won, lost) # text2 = 'Current Session:\n won=%s, lost=%s\n' % (won, lost)
# createChart(app, won, lost, _("Current session")) # createChart(app, won, lost, _("Current session"))

View file

@ -167,10 +167,10 @@ class MfxMessageDialog(MfxDialog):
# LB # LB
# nicht automatisch ein neues spiel laden. # nicht automatisch ein neues spiel laden.
if (title == "Game won"): if (title == _("Game won")):
self.status = 1 self.status = 1
# self.button = 0 # self.button = 0
if (title == "Game finished"): if (title == _("Game finished")):
self.status = 1 self.status = 1
# self.button = # self.button =
@ -180,7 +180,7 @@ class MfxMessageDialog(MfxDialog):
class MfxExceptionDialog(MfxMessageDialog): class MfxExceptionDialog(MfxMessageDialog):
def __init__(self, parent, ex, title="Error", **kw): def __init__(self, parent, ex, title=_("Error"), **kw):
kw = KwStruct(kw, bitmap="error") kw = KwStruct(kw, bitmap="error")
text = kw.get("text", "") text = kw.get("text", "")
if not text.endswith("\n"): if not text.endswith("\n"):

View file

@ -203,7 +203,7 @@ class PysolToolbarTk(BoxLayout):
# (n_("Statistics"), self.mPlayerStats, _("View statistics")), # (n_("Statistics"), self.mPlayerStats, _("View statistics")),
(n_("Rules"), self.mHelpRules, _("Rules for this game")), (n_("Rules"), self.mHelpRules, _("Rules for this game")),
(None, None, None), (None, None, None),
(n_("Quit"), self.mHoldAndQuit, _("Quit ") + TITLE), (n_("Quit"), self.mHoldAndQuit, _("Quit %s") % TITLE),
): ):
if label is None: if label is None:
# sep = self._createSeparator() # sep = self._createSeparator()

View file

@ -56,25 +56,25 @@ if TOOLKIT == 'kivy':
def fatal_no_cardsets(app): def fatal_no_cardsets(app):
app.wm_withdraw() app.wm_withdraw()
MfxMessageDialog(app.top, title=_("%s installation error") % TITLE, MfxMessageDialog(app.top, title=_("%s installation error") % TITLE,
text=_('''No cardsets were found !!! text=_('''No cardsets were found!!!
Cardsets should be installed into: Cardsets should be installed into:
%s/cardsets/ %(dir)s
Please check your %s installation. Please check your %(app)s installation.
''') % (getprefdir(PACKAGE), TITLE), ''') % {'dir': getprefdir(PACKAGE) + '/cardsets/', 'app': TITLE},
bitmap="error", strings=(_("&Quit"),)) bitmap="error", strings=(_("&Quit"),))
else: else:
def fatal_no_cardsets(app): def fatal_no_cardsets(app):
app.wm_withdraw() app.wm_withdraw()
MfxMessageDialog(app.top, title=_("%s installation error") % TITLE, MfxMessageDialog(app.top, title=_("%s installation error") % TITLE,
text=_('''No cardsets were found !!! text=_('''No cardsets were found!!!
Main data directory is: Main data directory is:
%s %(dir)s
Please check your %s installation. Please check your %(app)s installation.
''') % (app.dataloader.dir, TITLE), ''') % {'dir': app.dataloader.dir, 'app': TITLE},
bitmap="error", strings=(_("&Quit"),)) bitmap="error", strings=(_("&Quit"),))
@ -93,8 +93,8 @@ def parse_option(argv):
"sound-mod=", "sound-mod=",
"help"]) "help"])
except getopt.GetoptError as err: except getopt.GetoptError as err:
print_err(_("%s\ntry %s --help for more information") % print_err(err + "\n" + _("try %s --help for more information") %
(err, prog_name), 0) prog_name, 0)
return None return None
opts = {"help": False, opts = {"help": False,
"deal": None, "deal": None,
@ -303,13 +303,14 @@ def pysol_init(app, args):
app.intro.progress.destroy() app.intro.progress.destroy()
d = MfxMessageDialog(top, title=_("%s installation error") % TITLE, d = MfxMessageDialog(top, title=_("%s installation error") % TITLE,
text=_(''' text=_('''
No games were found !!! No games were found!!!
Main data directory is: Main data directory is:
%s %(dir)s
Please check your %s installation. Please check your %(app)s installation.
''') % (app.dataloader.dir, TITLE), bitmap="error", strings=(_("&Quit"),)) ''') % {'dir': app.dataloader.dir, 'app': TITLE},
bitmap="error", strings=(_("&Quit"),))
return 1 return 1
# init cardsets # init cardsets

View file

@ -290,7 +290,7 @@ class SelectGameDialogWithPreview(MfxDialog):
for version, vg in GI.GAMES_BY_PYSOL_VERSION: for version, vg in GI.GAMES_BY_PYSOL_VERSION:
def selecter(gi, vg=vg): def selecter(gi, vg=vg):
return gi.id in vg return gi.id in vg
label = _("New games in v. ") + version label = _("New games in v. %(version)s") % {'version': version}
data.append((label, selecter)) data.append((label, selecter))
self._addGamesFromData(data, store, None, self._addGamesFromData(data, store, None,
_("by PySol version"), all_games) _("by PySol version"), all_games)
@ -423,7 +423,7 @@ class SelectGameDialogWithPreview(MfxDialog):
# self.top.wm_title( # self.top.wm_title(
# "Select Game - " + self.app.getGameTitleName(gameid)) # "Select Game - " + self.app.getGameTitleName(gameid))
title = self.app.getGameTitleName(gameid) title = self.app.getGameTitleName(gameid)
self.set_title(_("Playable Preview - ") + title) self.set_title(_("Playable Preview - %(game)s") % {'game': title})
# #
self.preview_game = gi.gameclass(gi) self.preview_game = gi.gameclass(gi)
self.preview_game.createPreview(self.preview_app) self.preview_game.createPreview(self.preview_app)

View file

@ -434,13 +434,13 @@ class HTMLViewer:
for p in REMOTE_PROTOCOLS: for p in REMOTE_PROTOCOLS:
if url.startswith(p): if url.startswith(p):
if not openURL(url): if not openURL(url):
self.errorDialog(TITLE + _('''HTML limitation: self.errorDialog(_('''%(app)s HTML limitation:
The %s protocol is not supported yet. The %(protocol)s protocol is not supported yet.
Please use your standard web browser Please use your standard web browser
to open the following URL: to open the following URL:
%s %(url)s
''') % (p, url)) ''') % {'app': TITLE, 'protocol': p, 'url': url})
return return
# locate the file relative to the current url # locate the file relative to the current url

View file

@ -67,7 +67,8 @@ class StatsFormatter(PysolStatsFormatter):
6, result[6], 6, result[6],
7, result[7]) 7, result[7])
total, played, won, lost, time, moves, perc = self.getStatSummary() total, played, won, lost, time, moves, perc = self.getStatSummary()
text = _("Total (%d out of %d games)") % (played, total) text = _("Total (%(played)d out of %(total)d games)") % {
'played': played, 'total': total}
iter = self.store.append(None) iter = self.store.append(None)
self.store.set(iter, self.store.set(iter,
0, text, 0, text,

View file

@ -1945,7 +1945,7 @@ class TalonStack(Stack,
nredeals = _('Unlimited redeals.') nredeals = _('Unlimited redeals.')
else: else:
n = self.max_rounds-1 n = self.max_rounds-1
nredeals = ungettext('%d readeal', '%d redeals', n) % n nredeals = ungettext('%d redeal', '%d redeals', n) % n
# round = _('Round #%d.') % self.round # round = _('Round #%d.') % self.round
return _('Talon.')+' '+nredeals # +' '+round return _('Talon.')+' '+nredeals # +' '+round

View file

@ -199,7 +199,7 @@ class FileStatsFormatter(PysolStatsFormatter):
def writeStats(self, player, sort_by='name'): def writeStats(self, player, sort_by='name'):
if player is None: if player is None:
player = _('Demo') player = _('Demo')
header = _("Statistics for ") + player header = _("Statistics for %(player)s") % {'player': player}
self.writeHeader(header, 62) self.writeHeader(header, 62)
header = self.getStatHeader() header = self.getStatHeader()
self.pstats(*header) self.pstats(*header)
@ -209,7 +209,8 @@ class FileStatsFormatter(PysolStatsFormatter):
self.pstats(gameid=gameid, *result) self.pstats(gameid=gameid, *result)
self.nl() self.nl()
total, played, won, lost, time, moves, perc = self.getStatSummary() total, played, won, lost, time, moves, perc = self.getStatSummary()
self.pstats(_("Total (%d out of %d games)") % (played, total), self.pstats(_("Total (%(played)d out of %(total)d games)") %
{'played': played, 'total': total},
won+lost, won, lost, time, moves, perc) won+lost, won, lost, time, moves, perc)
self.nl(2) self.nl(2)
return played return played
@ -231,14 +232,14 @@ class FileStatsFormatter(PysolStatsFormatter):
def writeFullLog(self, player): def writeFullLog(self, player):
if player is None: if player is None:
player = _('Demo') player = _('Demo')
header = _("Full log for ") + player header = _("Full log for %(player)s") % {'player': player}
prev_games = self.app.stats.prev_games.get(player) prev_games = self.app.stats.prev_games.get(player)
return self.writeLog(player, header, prev_games) return self.writeLog(player, header, prev_games)
def writeSessionLog(self, player): def writeSessionLog(self, player):
if player is None: if player is None:
player = _('Demo') player = _('Demo')
header = _("Session log for ") + player header = _("Session log for %(player)s") % {'player': player}
prev_games = self.app.stats.session_games.get(player) prev_games = self.app.stats.session_games.get(player)
return self.writeLog(player, header, prev_games) return self.writeLog(player, header, prev_games)

View file

@ -105,8 +105,8 @@ class PysolMenubarTk(PysolMenubarTkCommon):
self._calc_MfxMessageDialog()( self._calc_MfxMessageDialog()(
self.top, title=_("Change theme"), self.top, title=_("Change theme"),
text=_("""\ text=_("""\
This settings will take effect These settings will take effect
the next time you restart """)+TITLE, the next time you restart %(app)s""") % {'app': TITLE},
bitmap="warning", bitmap="warning",
default=0, strings=(_("&OK"),)) default=0, strings=(_("&OK"),))

View file

@ -144,7 +144,7 @@ class SelectGameData(SelectDialogTreeData):
if name is None or not list(filter( if name is None or not list(filter(
select_func, self.all_games_gi)): select_func, self.all_games_gi)):
continue continue
name = _("New games in v. ") + name name = _("New games in v. %(version)s") % {'version': 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_pysol_version = SelectGameNode(None, _("by PySol version"), s_by_pysol_version = SelectGameNode(None, _("by PySol version"),
@ -513,7 +513,7 @@ class SelectGameDialogWithPreview(SelectGameDialog):
# self.top.wm_title("Select Game - " + # self.top.wm_title("Select Game - " +
# self.app.getGameTitleName(gameid)) # self.app.getGameTitleName(gameid))
title = self.app.getGameTitleName(gameid) title = self.app.getGameTitleName(gameid)
self.top.wm_title(_("Playable Preview - ") + title) self.top.wm_title(_("Playable Preview - %(game)s") % {'game': title})
# #
self.preview_game = gi.gameclass(gi) self.preview_game = gi.gameclass(gi)
self.preview_game.createPreview(self.preview_app) self.preview_game.createPreview(self.preview_app)

View file

@ -368,7 +368,8 @@ class TreeFormatter(PysolStatsFormatter):
self.parent_window.games[id] = t8 self.parent_window.games[id] = t8
total, played, won, lost, time_, moves, perc = self.getStatSummary() total, played, won, lost, time_, moves, perc = self.getStatSummary()
text = _("Total (%d out of %d games)") % (played, total) text = _("Total (%(played)d out of %(total)d games)") % {
'played': played, 'total': total}
id = self.tree.insert("", "end", text=text, id = self.tree.insert("", "end", text=text,
values=(won+lost, won, lost, time_, moves, perc)) values=(won+lost, won, lost, time_, moves, perc))
self.parent_window.tree_items.append(id) self.parent_window.tree_items.append(id)

View file

@ -188,7 +188,7 @@ class PysolToolbarTk:
(n_("Statistics"), self.mPlayerStats, _("View statistics")), (n_("Statistics"), self.mPlayerStats, _("View statistics")),
(n_("Rules"), self.mHelpRules, _("Rules for this game")), (n_("Rules"), self.mHelpRules, _("Rules for this game")),
(None, None, None), (None, None, None),
(n_("Quit"), self.mQuit, _("Quit ")+TITLE), (n_("Quit"), self.mQuit, _("Quit %s") % TITLE),
): ):
if label is None: if label is None:
sep = self._createSeparator() sep = self._createSeparator()

View file

@ -144,7 +144,7 @@ class SelectGameData(SelectDialogTreeData):
if name is None or not list(filter( if name is None or not list(filter(
select_func, self.all_games_gi)): select_func, self.all_games_gi)):
continue continue
name = _("New games in v. ") + name name = _("New games in v. %(version)s") % {'version': 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_pysol_version = SelectGameNode(None, _("by PySol version"), s_by_pysol_version = SelectGameNode(None, _("by PySol version"),
@ -514,7 +514,7 @@ class SelectGameDialogWithPreview(SelectGameDialog):
# self.top.wm_title("Select Game - " + # self.top.wm_title("Select Game - " +
# self.app.getGameTitleName(gameid)) # self.app.getGameTitleName(gameid))
title = self.app.getGameTitleName(gameid) title = self.app.getGameTitleName(gameid)
self.top.wm_title(_("Playable Preview - ") + title) self.top.wm_title(_("Playable Preview - %(game)s") % {'game': title})
# #
self.preview_game = gi.gameclass(gi) self.preview_game = gi.gameclass(gi)
self.preview_game.createPreview(self.preview_app) self.preview_game.createPreview(self.preview_app)

View file

@ -410,7 +410,8 @@ class CanvasFormatter(PysolStatsFormatter):
# #
y += self.h y += self.h
total, played, won, lost, time_, moves, perc = self.getStatSummary() total, played, won, lost, time_, moves, perc = self.getStatSummary()
s = _("Total (%d out of %d games)") % (played, total) s = _("Total (%(played)d out of %(total)d games)") % {
'played': played, 'total': total}
self.pstats(y, (s, won+lost, won, lost, time_, moves, perc)) self.pstats(y, (s, won+lost, won, lost, time_, moves, perc))
def writeLog(self, player, prev_games): def writeLog(self, player, prev_games):

View file

@ -188,7 +188,7 @@ class PysolToolbarTk:
(n_("Statistics"), self.mPlayerStats, _("View statistics")), (n_("Statistics"), self.mPlayerStats, _("View statistics")),
(n_("Rules"), self.mHelpRules, _("Rules for this game")), (n_("Rules"), self.mHelpRules, _("Rules for this game")),
(None, None, None), (None, None, None),
(n_("Quit"), self.mQuit, _("Quit ")+TITLE), (n_("Quit"), self.mQuit, _("Quit %s") % TITLE),
): ):
if label is None: if label is None:
sep = self._createSeparator() sep = self._createSeparator()

View file

@ -293,7 +293,7 @@ class PysolMenubarTkCommon:
if WIN_SYSTEM == "aqua": if WIN_SYSTEM == "aqua":
applemenu = MfxMenu(self.menubar, "apple") applemenu = MfxMenu(self.menubar, "apple")
applemenu.add_command( applemenu.add_command(
label=_("&About ")+TITLE, command=self.mHelpAbout) label=_("&About %s") % TITLE, command=self.mHelpAbout)
menu = MfxMenu(self.menubar, n_("&File")) menu = MfxMenu(self.menubar, n_("&File"))
menu.add_command( menu.add_command(
@ -663,7 +663,7 @@ class PysolMenubarTkCommon:
if WIN_SYSTEM != "aqua": if WIN_SYSTEM != "aqua":
menu.add_separator() menu.add_separator()
menu.add_command( menu.add_command(
label=n_("&About ")+TITLE+"...", label=_("&About %s...") % TITLE,
command=self.mHelpAbout) command=self.mHelpAbout)
MfxMenubar.addPath = None MfxMenubar.addPath = None
@ -968,7 +968,8 @@ class PysolMenubarTkCommon:
def updateGamesMenu(self, menu, games): def updateGamesMenu(self, menu, games):
menu.delete(0, 'last') menu.delete(0, 'last')
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(key=lambda x: x.name) games.sort(key=lambda x: x.name)
self._addSelectAllGameSubMenu(games, menu, self._addSelectAllGameSubMenu(games, menu,
@ -1132,7 +1133,8 @@ class PysolMenubarTkCommon:
# #
DEFAULTEXTENSION = ".pso" DEFAULTEXTENSION = ".pso"
FILETYPES = ((TITLE+" files", "*"+DEFAULTEXTENSION), ("All files", "*")) FILETYPES = ((_("%s files") % TITLE, "*" + DEFAULTEXTENSION),
(_("All files"), "*"))
def mAddFavor(self, *event): def mAddFavor(self, *event):
gameid = self.app.game.id gameid = self.app.game.id

View file

@ -25,7 +25,7 @@ class BaseSolverDialog:
def __init__(self, parent, app, **kw): def __init__(self, parent, app, **kw):
self.parent = parent self.parent = parent
self.app = app self.app = app
title = TITLE+' - FreeCell Solver' title = _('%(app)s - FreeCell Solver') % {'app': TITLE}
kw = self.initKw(kw) kw = self.initKw(kw)
self._calc_MfxDialog().__init__( self._calc_MfxDialog().__init__(
self, parent, title, kw.resizable, kw.default) self, parent, title, kw.resizable, kw.default)

View file

@ -311,13 +311,13 @@ class Base_HTMLViewer:
for p in REMOTE_PROTOCOLS: for p in REMOTE_PROTOCOLS:
if url.startswith(p): if url.startswith(p):
if not openURL(url): if not openURL(url):
self.errorDialog(TITLE + _('''HTML limitation: self.errorDialog(_('''%(app)s HTML limitation:
The %s protocol is not supported yet. The %(protocol)s protocol is not supported yet.
Please use your standard web browser Please use your standard web browser
to open the following URL: to open the following URL:
%s %(url)s
''') % (p, url)) ''') % {'app': TITLE, 'protocol': p, 'url': url})
return return
# locate the file relative to the current url # locate the file relative to the current url
@ -429,7 +429,7 @@ to open the following URL:
def errorDialog(self, msg): def errorDialog(self, msg):
self._calc_MfxMessageDialog()( self._calc_MfxMessageDialog()(
self.parent, title=TITLE+" HTML Problem", self.parent, title="%(app)s HTML Problem" % {'app': TITLE},
text=msg, text=msg,
# bitmap="warning", # FIXME: this interp don't have images # bitmap="warning", # FIXME: this interp don't have images
strings=(_("&OK"),), default=0) strings=(_("&OK"),), default=0)