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

+ added config-file option `translate_game_names'

+ added accelerator ctrl-x: `Hold and quit'
* fixed games `Matriarchy', `Grandfather', `Bristol', `Chessboard', Twenty, `Q.C.'
* improved MfxScrolledCanvas
* improved hint
* fixed SelectTileDialogWithPreview


git-svn-id: file:///home/shlomif/Backup/svn-dumps/PySolFC/svnsync-repos/pysolfc/PySolFC/trunk@194 efabe8c0-fbe8-4139-b769-b5e6d273206e
This commit is contained in:
skomoroh 2007-08-18 21:19:52 +00:00
parent ebb552c135
commit 46a2191011
21 changed files with 153 additions and 88 deletions

View file

@ -550,7 +550,7 @@ class Application:
if self.opt.save_games_geometry and not self.opt.wm_maximized: if self.opt.save_games_geometry and not self.opt.wm_maximized:
w = self.canvas.winfo_width() w = self.canvas.winfo_width()
h = self.canvas.winfo_height() h = self.canvas.winfo_height()
geom = (w-2, h-2) # XXX: subtract canvas borderwidth geom = (w, h)
self.opt.games_geometry[self.game.id] = geom self.opt.games_geometry[self.game.id] = geom
self.freeGame() self.freeGame()
# #
@ -1056,7 +1056,10 @@ Please select a %s type %s.
def loadStatistics(self): def loadStatistics(self):
if not os.path.exists(self.fn.stats): if not os.path.exists(self.fn.stats):
return return
import time
t = time.time()
stats = unpickle(self.fn.stats) stats = unpickle(self.fn.stats)
print 'loadStatistics', time.time()-t
if stats: if stats:
##print "loaded:", stats.__dict__ ##print "loaded:", stats.__dict__
self.stats.__dict__.update(stats.__dict__) self.stats.__dict__.update(stats.__dict__)
@ -1082,7 +1085,10 @@ Please select a %s type %s.
self.opt.save(self.fn.opt_cfg) self.opt.save(self.fn.opt_cfg)
def saveStatistics(self): def saveStatistics(self):
import time
t = time.time()
self.__saveObject(self.stats, self.fn.stats) self.__saveObject(self.stats, self.fn.stats)
print 'saveStatistics', time.time()-t
def saveComments(self): def saveComments(self):
self.__saveObject(self.comments, self.fn.comments) self.__saveObject(self.comments, self.fn.comments)

View file

@ -46,7 +46,7 @@ from mfxutil import Pickler, Unpickler, UnpicklingError
from mfxutil import Image, ImageTk from mfxutil import Image, ImageTk
from mfxutil import destruct, Struct, SubclassResponsibility from mfxutil import destruct, Struct, SubclassResponsibility
from mfxutil import uclock, usleep from mfxutil import uclock, usleep
from mfxutil import format_time from mfxutil import format_time, print_err
from settings import PACKAGE, TITLE, TOOLKIT, TOP_TITLE from settings import PACKAGE, TITLE, TOOLKIT, TOP_TITLE
from settings import VERSION, VERSION_TUPLE from settings import VERSION, VERSION_TUPLE
from settings import DEBUG from settings import DEBUG
@ -220,8 +220,9 @@ class Game:
for stack in self.s.foundations: for stack in self.s.foundations:
ncards += stack.cap.max_cards ncards += stack.cap.max_cards
if ncards != self.gameinfo.ncards: if ncards != self.gameinfo.ncards:
print 'WARNING: invalid sum of foundations.max_cards:', \ print_err('invalid sum of foundations.max_cards: '
class_name, ncards, self.gameinfo.ncards '%s: %s %s' % (class_name, ncards, self.gameinfo.ncards),
2)
if self.s.rows: if self.s.rows:
from stack import AC_RowStack, UD_AC_RowStack, \ from stack import AC_RowStack, UD_AC_RowStack, \
SS_RowStack, UD_SS_RowStack, \ SS_RowStack, UD_SS_RowStack, \
@ -243,20 +244,20 @@ class Game:
self._shallHighlightMatch_RKW)),): self._shallHighlightMatch_RKW)),):
if isinstance(r, c): if isinstance(r, c):
if self.shallHighlightMatch not in f: if self.shallHighlightMatch not in f:
print 'WARNING: shallHighlightMatch is not valid:', \ print_err('shallHighlightMatch is not valid: '
class_name, r.__class__ ' %s, %s' % (class_name, r.__class__), 2)
if r.cap.mod == 13 and self.shallHighlightMatch != f[1]: if r.cap.mod == 13 and self.shallHighlightMatch != f[1]:
print 'WARNING: shallHighlightMatch is not valid (wrap):', \ print_err('shallHighlightMatch is not valid (wrap): '
class_name, r.__class__ ' %s, %s' % (class_name, r.__class__), 2)
break break
if self.s.talon.max_rounds > 1 and \ if self.s.talon.max_rounds > 1 and \
self.s.talon.texts.rounds is None: self.s.talon.texts.rounds is None:
print 'WARNING: max_rounds > 1, but talon.texts.rounds is None:', \ print_err('max_rounds > 1, but talon.texts.rounds is None: '
class_name '%s' % class_name, 2)
elif self.s.talon.max_rounds <= 1 and \ elif self.s.talon.max_rounds <= 1 and \
self.s.talon.texts.rounds is not None: self.s.talon.texts.rounds is not None:
print 'WARNING: max_rounds <= 1, but talon.texts.rounds is not None:', \ print_err('max_rounds <= 1, but talon.texts.rounds is not None: '
class_name '%s' % class_name, 2)
def initBindings(self): def initBindings(self):

View file

@ -38,9 +38,9 @@
import imp import imp
# PySol imports # PySol imports
from mfxutil import Struct from mfxutil import Struct, print_err
from resource import CSI from resource import CSI
from settings import CHECK_GAMES import settings
# /*********************************************************************** # /***********************************************************************
@ -411,20 +411,33 @@ class GameInfo(Struct):
rules_filename=None, rules_filename=None,
): ):
# #
def to_unicode(s):
if isinstance(s, unicode):
return s
try:
s = unicode(s, 'utf-8')
except UnicodeDecodeError, err:
print_err(err)
s = unicode(s, 'utf-8', 'ignore')
return s
ncards = decks * (len(suits) * len(ranks) + len(trumps)) ncards = decks * (len(suits) * len(ranks) + len(trumps))
game_flags = game_type & ~1023 game_flags = game_type & ~1023
game_type = game_type & 1023 game_type = game_type & 1023
name = to_unicode(name)
en_name = name # for app.getGameRulesFilename en_name = name # for app.getGameRulesFilename
if not isinstance(name, unicode): if settings.TRANSLATE_GAME_NAMES:
en_name = unicode(name, 'utf-8') name = _(name)
name = _(name)
if not short_name: if not short_name:
short_name = name short_name = name
else: else:
short_name = _(short_name) short_name = to_unicode(short_name)
if settings.TRANSLATE_GAME_NAMES:
short_name = _(short_name)
if isinstance(altnames, basestring): if isinstance(altnames, basestring):
altnames = (altnames,) altnames = (altnames,)
altnames = [_(n) for n in altnames] altnames = [to_unicode(n) for n in altnames]
if settings.TRANSLATE_GAME_NAMES:
altnames = [_(n) for n in altnames]
# #
if not (1 <= category <= 9): if not (1 <= category <= 9):
if game_type == GI.GT_HANAFUDA: if game_type == GI.GT_HANAFUDA:
@ -537,7 +550,7 @@ class GameManager:
##print gi.id, gi.short_name.encode('utf-8') ##print gi.id, gi.short_name.encode('utf-8')
if not isinstance(gi, GameInfo): if not isinstance(gi, GameInfo):
raise GameInfoException("wrong GameInfo class") raise GameInfoException("wrong GameInfo class")
if self.check_game and CHECK_GAMES: if self.check_game and settings.CHECK_GAMES:
self._check_game(gi) self._check_game(gi)
##if 0 and gi.si.game_flags & GI.GT_XORIGINAL: ##if 0 and gi.si.game_flags & GI.GT_XORIGINAL:
## return ## return

View file

@ -96,7 +96,7 @@ class StreetsAndAlleys(Game):
x = x1 x = x1
for i in range(4): for i in range(4):
s.foundations.append(self.Foundation_Class(x, y, self, suit=i, max_move=0)) s.foundations.append(self.Foundation_Class(x, y, self, suit=i, max_move=0))
y = y + l.YS y += l.YS
if texts: if texts:
tx, ty, ta, tf = l.getTextAttr(None, "ss") tx, ty, ta, tf = l.getTextAttr(None, "ss")
tx, ty = x+tx, y-l.YS+ty tx, ty = x+tx, y-l.YS+ty
@ -109,7 +109,7 @@ class StreetsAndAlleys(Game):
stack = self.RowStack_Class(x, y, self) stack = self.RowStack_Class(x, y, self)
stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0 stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0
s.rows.append(stack) s.rows.append(stack)
y = y + l.YS y += l.YS
x, y = self.width - l.XS, self.height - l.YS x, y = self.width - l.XS, self.height - l.YS
s.talon = InitialDealTalonStack(x, y, self) s.talon = InitialDealTalonStack(x, y, self)
if reserves: if reserves:
@ -384,20 +384,17 @@ class CastlesEnd(Bastion):
class Chessboard_Foundation(SS_FoundationStack): class Chessboard_Foundation(SS_FoundationStack):
def __init__(self, x, y, game, suit, **cap): def __init__(self, x, y, game, suit, **cap):
kwdefault(cap, mod=13, min_cards=1, max_move=0) kwdefault(cap, mod=13, min_cards=1, max_move=0, base_rank=ANY_RANK)
SS_FoundationStack.__init__(self, x, y, game, suit, **cap) SS_FoundationStack.__init__(self, x, y, game, suit, **cap)
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
if not SS_FoundationStack.acceptsCards(self, from_stack, cards):
return False
if not self.cards: if not self.cards:
if len(cards) != 1 or not cards[0].face_up:
return False
if cards[0].suit != self.cap.base_suit:
return False
for s in self.game.s.foundations: for s in self.game.s.foundations:
if s.cards: if s.cards:
return cards[0].rank == s.cards[0].rank return cards[0].rank == s.cards[0].rank
return True return True
return SS_FoundationStack.acceptsCards(self, from_stack, cards)
class Chessboard_RowStack(UD_SS_RowStack): class Chessboard_RowStack(UD_SS_RowStack):

View file

@ -76,14 +76,13 @@ class Bristol_Talon(TalonStack):
class Bristol(Game): class Bristol(Game):
Layout_Method = Layout.klondikeLayout
Hint_Class = Bristol_Hint Hint_Class = Bristol_Hint
# #
# game layout # game layout
# #
def createGame(self, **layout): def createGame(self):
# create layout # create layout
l, s = Layout(self), self.s l, s = Layout(self), self.s
@ -94,7 +93,7 @@ class Bristol(Game):
x, y, = l.XM + 3*l.XS, l.YM x, y, = l.XM + 3*l.XS, l.YM
for i in range(4): for i in range(4):
s.foundations.append(RK_FoundationStack(x, y, self, max_move=0)) s.foundations.append(RK_FoundationStack(x, y, self, max_move=0))
x = x + l.XS x += l.XS
for i in range(2): for i in range(2):
y = l.YM + (i*2+3)*l.YS/2 y = l.YM + (i*2+3)*l.YS/2
for j in range(4): for j in range(4):
@ -105,9 +104,12 @@ class Bristol(Game):
x, y, = l.XM + 3*l.XS, l.YM + 4*l.YS x, y, = l.XM + 3*l.XS, l.YM + 4*l.YS
s.talon = Bristol_Talon(x, y, self) s.talon = Bristol_Talon(x, y, self)
l.createText(s.talon, "sw") l.createText(s.talon, "sw")
x += l.XS
for i in range(3): for i in range(3):
x = x + l.XS stack = WasteStack(x, y, self)
s.reserves.append(ReserveStack(x, y, self, max_accept=0, max_cards=UNLIMITED_CARDS)) l.createText(stack, 'n')
s.reserves.append(stack)
x += l.XS
# define stack-groups # define stack-groups
self.sg.openstacks = s.foundations + s.rows self.sg.openstacks = s.foundations + s.rows
@ -125,14 +127,14 @@ class Bristol(Game):
for c in cards[:24]: # search the first 24 cards only for c in cards[:24]: # search the first 24 cards only
if c.rank == KING: if c.rank == KING:
kings.append(i) kings.append(i)
i = i + 1 i += 1
for i in kings: for i in kings:
j = i % n # j = card index of rowstack bottom j = i % n # j = card index of rowstack bottom
while j < i: while j < i:
if cards[j].rank != KING: if cards[j].rank != KING:
cards[j], cards[i] = cards[i], cards[j] cards[j], cards[i] = cards[i], cards[j]
break break
j = j + n j += n
cards.reverse() cards.reverse()
return cards return cards

View file

@ -884,34 +884,35 @@ class Q_C_(Klondike):
self.s.talon.dealRow(frames=0) self.s.talon.dealRow(frames=0)
self.startDealSample() self.startDealSample()
self.s.talon.dealRow() self.s.talon.dealRow()
self.s.talon.dealCards() # deal first card to WasteStack while self.s.talon.cards:
self.fillAll() self.s.talon.dealCards() # deal first card to WasteStack
if not self.fillWaste():
break
def fillOne(self, stack): def fillWaste(self):
if stack.cards: waste = self.s.waste
c = stack.cards[-1] if waste.cards:
c = waste.cards[-1]
for f in self.s.foundations: for f in self.s.foundations:
if f.acceptsCards(stack, [c]): if f.acceptsCards(self.s.waste, [c]):
stack.moveMove(1, f) waste.moveMove(1, f)
return 1 return True
return 0 return False
def fillAll(self): def fillStack(self, stack=None):
# fill waste = self.s.waste
if not self.s.waste.cards and self.s.talon.cards: while True:
self.s.talon.dealCards() if not self.fillWaste():
for stack in self.s.rows: break
if not stack.cards and self.s.waste.cards: if stack in self.s.rows and not stack.cards:
self.s.waste.moveMove(1, stack) if not waste.cards:
# move to foundations while self.s.talon.cards:
if self.fillOne(self.s.waste): self.s.talon.dealCards()
self.fillAll() if not self.fillWaste():
for stack in self.s.rows: break
if self.fillOne(stack): if waste.cards:
self.fillAll() waste.moveMove(1, stack)
def fillStack(self, stack):
self.fillAll()
shallHighlightMatch = Game._shallHighlightMatch_SS shallHighlightMatch = Game._shallHighlightMatch_SS

View file

@ -94,6 +94,9 @@ class Matriarchy_Talon(WasteTalonStack):
n = 0 n = 0
update_flags = 1 update_flags = 1
# deal # deal
if self.cards:
if sound and not self.game.demo:
self.game.playSample("dealwaste")
while n < ncards: while n < ncards:
# from self to waste # from self to waste
while n < ncards: while n < ncards:
@ -108,6 +111,8 @@ class Matriarchy_Talon(WasteTalonStack):
if n < ncards and len(waste.cards) > 0: if n < ncards and len(waste.cards) > 0:
assert len(self.cards) == 0 assert len(self.cards) == 0
assert self.round < self.max_rounds or update_flags == 0 assert self.round < self.max_rounds or update_flags == 0
if sound:
self.game.playSample("turnwaste", priority=20)
self.game.turnStackMove(waste, self) self.game.turnStackMove(waste, self)
if update_flags: if update_flags:
self.game.nextRoundMove(self) self.game.nextRoundMove(self)

View file

@ -564,9 +564,11 @@ class NewBritishConstitution(BritishConstitution):
class Twenty_RowStack(BasicRowStack): class Twenty_RowStack(BasicRowStack):
def acceptsCards(self, from_stack, cards): def acceptsCards(self, from_stack, cards):
#if not BasicRowStack.acceptsCards(self, from_stack, cards): if not BasicRowStack.acceptsCards(self, from_stack, cards):
# return False return False
return len(self.cards) == 0 return len(self.cards) == 0
def getHelp(self):
return _('Tableau. Empty piles can be filled with any card.')
class Twenty(Game): class Twenty(Game):
def createGame(self): def createGame(self):
@ -574,7 +576,7 @@ class Twenty(Game):
l, s = Layout(self), self.s l, s = Layout(self), self.s
# set window # set window
self.setSize(l.XM+10*l.XS, l.YM+3*l.XS+10*l.YOFFSET) self.setSize(l.XM+10*l.XS, l.YM+3*l.YS+10*l.YOFFSET)
# create stacks # create stacks
x, y = l.XM, l.YM x, y = l.XM, l.YM
@ -589,10 +591,11 @@ class Twenty(Game):
base_rank=KING, dir=-1)) base_rank=KING, dir=-1))
x += l.XS x += l.XS
for y in (l.YM+l.YS, l.YM+2*l.XS+5*l.YOFFSET): for y in (l.YM+l.YS, l.YM+2*l.YS+5*l.YOFFSET):
x = l.XM x = l.XM
for i in range(10): for i in range(10):
s.rows.append(Twenty_RowStack(x, y, self)) s.rows.append(Twenty_RowStack(x, y, self,
base_rank=ANY_RANK, max_accept=1))
x += l.XS x += l.XS
# define stack-groups # define stack-groups

View file

@ -141,8 +141,8 @@ class Odessa(RussianSolitaire):
# ************************************************************************/ # ************************************************************************/
class Grandfather_Talon(RedealTalonStack): class Grandfather_Talon(RedealTalonStack):
def redealCards(self, sound=False): def dealCards(self, sound=False):
RedealTalonStack.redealCards(self, sound=sound, shuffle=True) self.redealCards(sound=sound, shuffle=True)
class Grandfather(RussianSolitaire): class Grandfather(RussianSolitaire):
Talon_Class = StackWrapper(Grandfather_Talon, max_rounds=3) Talon_Class = StackWrapper(Grandfather_Talon, max_rounds=3)
@ -152,9 +152,17 @@ class Grandfather(RussianSolitaire):
l.createRoundText(self.s.talon, 'nn') l.createRoundText(self.s.talon, 'nn')
def startGame(self): def startGame(self):
frames = 0
sound = False
for i, j in ((1,7),(1,6),(2,6),(2,5),(3,5),(3,4)): for i, j in ((1,7),(1,6),(2,6),(2,5),(3,5),(3,4)):
self.s.talon.dealRowAvail(rows=self.s.rows[i:j], flip=0, frames=0) if len(self.s.talon.cards) <= j-i:
self.startDealSample() frames = -1
sound = True
self.startDealSample()
self.s.talon.dealRowAvail(rows=self.s.rows[i:j],
flip=0, frames=frames)
if not sound:
self.startDealSample()
self.s.talon.dealRowAvail() self.s.talon.dealRowAvail()
for i in range(4): for i in range(4):
self.s.talon.dealRowAvail(rows=self.s.rows[1:]) self.s.talon.dealRowAvail(rows=self.s.rows[1:])

View file

@ -463,11 +463,11 @@ class DefaultHint(AbstractHint):
self.step030(game.s.foundations, game.s.rows, game.sg.dropstacks) self.step030(game.s.foundations, game.s.rows, game.sg.dropstacks)
# 4) try if we can move a card from a RowStack to a ReserveStack # 4) try if we can move a card from a RowStack to a ReserveStack
if not self.hints: if not self.hints or self.level == 0:
self.step040(game.s.rows, game.sg.reservestacks) self.step040(game.s.rows, game.sg.reservestacks)
# 5) try if we should move a card from a ReserveStack to a RowStack # 5) try if we should move a card from a ReserveStack to a RowStack
if not self.hints: if not self.hints or self.level == 0:
self.step050(game.sg.reservestacks, game.s.rows) self.step050(game.sg.reservestacks, game.s.rows)
# Don't be too clever and give up ;-) # Don't be too clever and give up ;-)
@ -488,7 +488,7 @@ class DefaultHint(AbstractHint):
score, color = 0, None score, color = 0, None
score, color = self._getDropCardScore(score, color, r, t, ncards) score, color = self._getDropCardScore(score, color, r, t, ncards)
self.addHint(score, ncards, r, t, color) self.addHint(score, ncards, r, t, color)
if score >= 90000: if score >= 90000 and self.level >= 1:
break break
# 1b) try if we can move cards to one of the RowStacks # 1b) try if we can move cards to one of the RowStacks
for pile in self.step010b_getPiles(r): for pile in self.step010b_getPiles(r):

View file

@ -106,6 +106,8 @@ def print_err(s, level=1):
ss = PACKAGE+': ERROR:' ss = PACKAGE+': ERROR:'
elif level == 1: elif level == 1:
ss = PACKAGE+': WARNING:' ss = PACKAGE+': WARNING:'
elif level == 2:
ss = PACKAGE+': DEBUG WARNING:'
print >> sys.stderr, ss, s.encode(locale.getpreferredencoding()) print >> sys.stderr, ss, s.encode(locale.getpreferredencoding())
sys.stderr.flush() sys.stderr.flush()
@ -165,7 +167,9 @@ def win32_gethomedir():
return hd return hd
hd = os.path.expanduser('~') hd = os.path.expanduser('~')
if hd == '~': # win9x if hd == '~': # win9x
return os.path.abspath('/') hd = os.path.abspath('/windows/Application Data')
if not os.path.exists(hd):
hd = os.path.abspath('/')
return hd return hd
# /*********************************************************************** # /***********************************************************************

View file

@ -25,9 +25,9 @@ import traceback
# PySol imports # PySol imports
from mfxutil import print_err from mfxutil import print_err
from settings import VERSION_TUPLE, WIN_SYSTEM
from resource import CSI from resource import CSI
from configobj import configobj, validate from configobj import configobj, validate
import settings
# Toolkit imports # Toolkit imports
from pysoltk import TOOLBAR_BUTTONS from pysoltk import TOOLBAR_BUTTONS
@ -97,6 +97,7 @@ tabletile_name = string
recent_gameid = int_list recent_gameid = int_list
favorite_gameid = int_list favorite_gameid = int_list
visible_buttons = string_list visible_buttons = string_list
translate_game_names = boolean
[sound_samples] [sound_samples]
move = boolean move = boolean
@ -219,6 +220,7 @@ class Options:
('sound_sample_volume', 'int'), ('sound_sample_volume', 'int'),
('sound_music_volume', 'int'), ('sound_music_volume', 'int'),
('tabletile_name', 'str'), ('tabletile_name', 'str'),
('translate_game_names', 'bool'),
#('toolbar_vars', 'list'), #('toolbar_vars', 'list'),
#('recent_gameid', 'list'), #('recent_gameid', 'list'),
#('favorite_gameid', 'list'), #('favorite_gameid', 'list'),
@ -229,7 +231,7 @@ class Options:
self._config = None # configobj.ConfigObj instance self._config = None # configobj.ConfigObj instance
self._config_encoding = 'utf-8' self._config_encoding = 'utf-8'
self.version_tuple = VERSION_TUPLE # XXX self.version_tuple = settings.VERSION_TUPLE # XXX
self.saved = 0 # XXX self.saved = 0 # XXX
# options menu: # options menu:
self.player = _("Unknown") self.player = _("Unknown")
@ -277,6 +279,7 @@ class Options:
self.mouse_type = 'drag-n-drop' # or 'sticky-mouse' or 'point-n-click' self.mouse_type = 'drag-n-drop' # or 'sticky-mouse' or 'point-n-click'
self.mouse_undo = False # use mouse for undo/redo self.mouse_undo = False # use mouse for undo/redo
self.negative_bottom = True self.negative_bottom = True
self.translate_game_names = True
# sound # sound
self.sound = True self.sound = True
self.sound_mode = 1 self.sound_mode = 1
@ -354,6 +357,7 @@ class Options:
self.dragcursor = True self.dragcursor = True
def setDefaults(self, top=None): def setDefaults(self, top=None):
WIN_SYSTEM = settings.WIN_SYSTEM
# toolbar # toolbar
#if WIN_SYSTEM == 'win32': #if WIN_SYSTEM == 'win32':
# self.toolbar_style = 'crystal' # self.toolbar_style = 'crystal'
@ -494,6 +498,7 @@ class Options:
def load(self, filename): def load(self, filename):
# create ConfigObj instance
try: try:
config = configobj.ConfigObj(filename, config = configobj.ConfigObj(filename,
configspec=configspec, configspec=configspec,
@ -504,6 +509,7 @@ class Options:
encoding=self._config_encoding) encoding=self._config_encoding)
self._config = config self._config = config
# create sections
for section in ( for section in (
'general', 'general',
'sound_samples', 'sound_samples',
@ -516,6 +522,7 @@ class Options:
if section not in config: if section not in config:
config[section] = {} config[section] = {}
# add initial comment
if not os.path.exists(filename): if not os.path.exists(filename):
config.initial_comment = ['-*- coding: %s -*-' % config.initial_comment = ['-*- coding: %s -*-' %
self._config_encoding] self._config_encoding]
@ -544,6 +551,8 @@ class Options:
elif val is not None: elif val is not None:
setattr(self, key, val) setattr(self, key, val)
settings.TRANSLATE_GAME_NAMES = self.translate_game_names
recent_gameid = self._getOption('general', 'recent_gameid', 'list') recent_gameid = self._getOption('general', 'recent_gameid', 'list')
if recent_gameid is not None: if recent_gameid is not None:
try: try:

View file

@ -72,6 +72,9 @@ TOP_TITLE = n_('Top 10')
# use menu for select game # use menu for select game
SELECT_GAME_MENU = True SELECT_GAME_MENU = True
# i18n, see also options.py
TRANSLATE_GAME_NAMES = True
# debug # debug
DEBUG = 0 # must be integer DEBUG = 0 # must be integer
CHECK_GAMES = False # check duplicated names and classes CHECK_GAMES = False # check duplicated names and classes

View file

@ -48,7 +48,8 @@ class FindCardDialog(Tkinter.Toplevel):
def __init__(self, parent, game, dir, size='large'): def __init__(self, parent, game, dir, size='large'):
Tkinter.Toplevel.__init__(self) Tkinter.Toplevel.__init__(self)
self.title(_('Find card')) title = TITLE + ' - ' + _('Find card')
self.title(title)
self.wm_resizable(False, False) self.wm_resizable(False, False)
# #
##self.images_dir = dir ##self.images_dir = dir

View file

@ -368,7 +368,7 @@ class PysolMenubar(PysolMenubarActions):
menu.add_command(label=n_("&Save"), command=self.mSave, accelerator=m+"S") menu.add_command(label=n_("&Save"), command=self.mSave, accelerator=m+"S")
menu.add_command(label=n_("Save &as..."), command=self.mSaveAs) menu.add_command(label=n_("Save &as..."), command=self.mSaveAs)
menu.add_separator() menu.add_separator()
menu.add_command(label=n_("&Hold and quit"), command=self.mHoldAndQuit) menu.add_command(label=n_("&Hold and quit"), command=self.mHoldAndQuit, accelerator=m+"X")
if WIN_SYSTEM != "aqua": if WIN_SYSTEM != "aqua":
menu.add_command(label=n_("&Quit"), command=self.mQuit, accelerator=m+"Q") menu.add_command(label=n_("&Quit"), command=self.mQuit, accelerator=m+"Q")
@ -532,6 +532,7 @@ class PysolMenubar(PysolMenubarActions):
self._bindKey(ctrl, "n", self.mNewGameWithNextId) self._bindKey(ctrl, "n", self.mNewGameWithNextId)
self._bindKey(ctrl, "o", self.mOpen) self._bindKey(ctrl, "o", self.mOpen)
self._bindKey(ctrl, "s", self.mSave) self._bindKey(ctrl, "s", self.mSave)
self._bindKey(ctrl, "x", self.mHoldAndQuit)
self._bindKey(ctrl, "q", self.mQuit) self._bindKey(ctrl, "q", self.mQuit)
self._bindKey("", "z", self.mUndo) self._bindKey("", "z", self.mUndo)
self._bindKey("", "BackSpace", self.mUndo) # undocumented self._bindKey("", "BackSpace", self.mUndo) # undocumented

View file

@ -192,12 +192,11 @@ class SelectTileDialogWithPreview(MfxDialog):
MfxDialog.mDone(self, button) MfxDialog.mDone(self, button)
def updatePreview(self, key): def updatePreview(self, key):
##print key
if key == self.preview_key: if key == self.preview_key:
return return
canvas = self.preview.canvas canvas = self.preview.canvas
canvas.deleteAllItems() canvas.deleteAllItems()
if isinstance(key, str): if isinstance(key, basestring):
# solid color # solid color
canvas.config(bg=key) canvas.config(bg=key)
canvas.setTile(None) canvas.setTile(None)

View file

@ -560,10 +560,15 @@ class MfxScrolledCanvas:
width = kw.get("width") width = kw.get("width")
height = kw.get("height") height = kw.get("height")
self.frame = Tile.Frame(self.parent, width=width, height=height) self.frame = Tile.Frame(self.parent, width=width, height=height)
def createCanvas(self, kw): def createCanvas(self, kw):
self.canvas = MfxCanvas(self.frame, **kw) bd = kw['bd']
self.canvas.grid(row=0, column=0, sticky="news") kw['bd'] = 0
relief = kw['relief']
del kw['relief']
frame = Tkinter.Frame(self.frame, bd=bd, relief=relief)
frame.grid(row=0, column=0, sticky="news")
self.canvas = MfxCanvas(frame, **kw)
self.canvas.pack(expand=True, fill='both')
def createHbar(self): def createHbar(self):
self.hbar = Tile.Scrollbar(self.frame, takefocus=0, self.hbar = Tile.Scrollbar(self.frame, takefocus=0,
orient="horizontal") orient="horizontal")

View file

@ -51,7 +51,8 @@ class FindCardDialog(Tkinter.Toplevel):
def __init__(self, parent, game, dir, size='large'): def __init__(self, parent, game, dir, size='large'):
Tkinter.Toplevel.__init__(self) Tkinter.Toplevel.__init__(self)
self.title(_('Find card')) title = TITLE + ' - ' + _('Find card')
self.title(title)
self.wm_resizable(False, False) self.wm_resizable(False, False)
# #
##self.images_dir = dir ##self.images_dir = dir

View file

@ -365,7 +365,7 @@ class PysolMenubar(PysolMenubarActions):
menu.add_command(label=n_("&Save"), command=self.mSave, accelerator=m+"S") menu.add_command(label=n_("&Save"), command=self.mSave, accelerator=m+"S")
menu.add_command(label=n_("Save &as..."), command=self.mSaveAs) menu.add_command(label=n_("Save &as..."), command=self.mSaveAs)
menu.add_separator() menu.add_separator()
menu.add_command(label=n_("&Hold and quit"), command=self.mHoldAndQuit) menu.add_command(label=n_("&Hold and quit"), command=self.mHoldAndQuit, accelerator=m+"X")
if WIN_SYSTEM != "aqua": if WIN_SYSTEM != "aqua":
menu.add_command(label=n_("&Quit"), command=self.mQuit, accelerator=m+"Q") menu.add_command(label=n_("&Quit"), command=self.mQuit, accelerator=m+"Q")
@ -536,6 +536,7 @@ class PysolMenubar(PysolMenubarActions):
self._bindKey(ctrl, "n", self.mNewGameWithNextId) self._bindKey(ctrl, "n", self.mNewGameWithNextId)
self._bindKey(ctrl, "o", self.mOpen) self._bindKey(ctrl, "o", self.mOpen)
self._bindKey(ctrl, "s", self.mSave) self._bindKey(ctrl, "s", self.mSave)
self._bindKey(ctrl, "x", self.mHoldAndQuit)
self._bindKey(ctrl, "q", self.mQuit) self._bindKey(ctrl, "q", self.mQuit)
self._bindKey("", "z", self.mUndo) self._bindKey("", "z", self.mUndo)
self._bindKey("", "BackSpace", self.mUndo) # undocumented self._bindKey("", "BackSpace", self.mUndo) # undocumented

View file

@ -196,7 +196,7 @@ class SelectTileDialogWithPreview(MfxDialog):
return return
canvas = self.preview.canvas canvas = self.preview.canvas
canvas.deleteAllItems() canvas.deleteAllItems()
if isinstance(key, str): if isinstance(key, basestring):
# solid color # solid color
canvas.config(bg=key) canvas.config(bg=key)
canvas.setTile(None) canvas.setTile(None)

View file

@ -550,10 +550,15 @@ class MfxScrolledCanvas:
width = kw.get("width") width = kw.get("width")
height = kw.get("height") height = kw.get("height")
self.frame = Tkinter.Frame(self.parent, width=width, height=height) self.frame = Tkinter.Frame(self.parent, width=width, height=height)
def createCanvas(self, kw): def createCanvas(self, kw):
self.canvas = MfxCanvas(self.frame, **kw) bd = kw['bd']
self.canvas.grid(row=0, column=0, sticky="news") kw['bd'] = 0
relief = kw['relief']
del kw['relief']
frame = Tkinter.Frame(self.frame, bd=bd, relief=relief)
frame.grid(row=0, column=0, sticky="news")
self.canvas = MfxCanvas(frame, **kw)
self.canvas.pack(expand=True, fill='both')
def createHbar(self): def createHbar(self):
self.hbar = Tkinter.Scrollbar(self.frame, takefocus=0, self.hbar = Tkinter.Scrollbar(self.frame, takefocus=0,
orient="horizontal") orient="horizontal")