From 46a21910118d1c84de8ddb683c408af4724041da Mon Sep 17 00:00:00 2001 From: skomoroh Date: Sat, 18 Aug 2007 21:19:52 +0000 Subject: [PATCH] + 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 --- pysollib/app.py | 8 ++++- pysollib/game.py | 23 +++++++------- pysollib/gamedb.py | 29 ++++++++++++----- pysollib/games/beleagueredcastle.py | 15 ++++----- pysollib/games/bristol.py | 16 +++++----- pysollib/games/klondike.py | 49 +++++++++++++++-------------- pysollib/games/matriarchy.py | 5 +++ pysollib/games/royalcotillion.py | 13 +++++--- pysollib/games/yukon.py | 16 +++++++--- pysollib/hint.py | 6 ++-- pysollib/mfxutil.py | 6 +++- pysollib/options.py | 13 ++++++-- pysollib/settings.py | 3 ++ pysollib/tile/findcarddialog.py | 3 +- pysollib/tile/menubar.py | 3 +- pysollib/tile/selecttile.py | 3 +- pysollib/tile/tkwidget.py | 11 +++++-- pysollib/tk/findcarddialog.py | 3 +- pysollib/tk/menubar.py | 3 +- pysollib/tk/selecttile.py | 2 +- pysollib/tk/tkwidget.py | 11 +++++-- 21 files changed, 153 insertions(+), 88 deletions(-) diff --git a/pysollib/app.py b/pysollib/app.py index 7b6ef030..8b6f7dcd 100644 --- a/pysollib/app.py +++ b/pysollib/app.py @@ -550,7 +550,7 @@ class Application: if self.opt.save_games_geometry and not self.opt.wm_maximized: w = self.canvas.winfo_width() 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.freeGame() # @@ -1056,7 +1056,10 @@ Please select a %s type %s. def loadStatistics(self): if not os.path.exists(self.fn.stats): return + import time + t = time.time() stats = unpickle(self.fn.stats) + print 'loadStatistics', time.time()-t if stats: ##print "loaded:", 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) def saveStatistics(self): + import time + t = time.time() self.__saveObject(self.stats, self.fn.stats) + print 'saveStatistics', time.time()-t def saveComments(self): self.__saveObject(self.comments, self.fn.comments) diff --git a/pysollib/game.py b/pysollib/game.py index 903886c4..cf79c86b 100644 --- a/pysollib/game.py +++ b/pysollib/game.py @@ -46,7 +46,7 @@ from mfxutil import Pickler, Unpickler, UnpicklingError from mfxutil import Image, ImageTk from mfxutil import destruct, Struct, SubclassResponsibility 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 VERSION, VERSION_TUPLE from settings import DEBUG @@ -220,8 +220,9 @@ class Game: for stack in self.s.foundations: ncards += stack.cap.max_cards if ncards != self.gameinfo.ncards: - print 'WARNING: invalid sum of foundations.max_cards:', \ - class_name, ncards, self.gameinfo.ncards + print_err('invalid sum of foundations.max_cards: ' + '%s: %s %s' % (class_name, ncards, self.gameinfo.ncards), + 2) if self.s.rows: from stack import AC_RowStack, UD_AC_RowStack, \ SS_RowStack, UD_SS_RowStack, \ @@ -243,20 +244,20 @@ class Game: self._shallHighlightMatch_RKW)),): if isinstance(r, c): if self.shallHighlightMatch not in f: - print 'WARNING: shallHighlightMatch is not valid:', \ - class_name, r.__class__ + print_err('shallHighlightMatch is not valid: ' + ' %s, %s' % (class_name, r.__class__), 2) if r.cap.mod == 13 and self.shallHighlightMatch != f[1]: - print 'WARNING: shallHighlightMatch is not valid (wrap):', \ - class_name, r.__class__ + print_err('shallHighlightMatch is not valid (wrap): ' + ' %s, %s' % (class_name, r.__class__), 2) break if self.s.talon.max_rounds > 1 and \ self.s.talon.texts.rounds is None: - print 'WARNING: max_rounds > 1, but talon.texts.rounds is None:', \ - class_name + print_err('max_rounds > 1, but talon.texts.rounds is None: ' + '%s' % class_name, 2) elif self.s.talon.max_rounds <= 1 and \ self.s.talon.texts.rounds is not None: - print 'WARNING: max_rounds <= 1, but talon.texts.rounds is not None:', \ - class_name + print_err('max_rounds <= 1, but talon.texts.rounds is not None: ' + '%s' % class_name, 2) def initBindings(self): diff --git a/pysollib/gamedb.py b/pysollib/gamedb.py index 11ea404c..0d32a8a6 100644 --- a/pysollib/gamedb.py +++ b/pysollib/gamedb.py @@ -38,9 +38,9 @@ import imp # PySol imports -from mfxutil import Struct +from mfxutil import Struct, print_err from resource import CSI -from settings import CHECK_GAMES +import settings # /*********************************************************************** @@ -411,20 +411,33 @@ class GameInfo(Struct): 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)) game_flags = game_type & ~1023 game_type = game_type & 1023 + name = to_unicode(name) en_name = name # for app.getGameRulesFilename - if not isinstance(name, unicode): - en_name = unicode(name, 'utf-8') - name = _(name) + if settings.TRANSLATE_GAME_NAMES: + name = _(name) if not short_name: short_name = name else: - short_name = _(short_name) + short_name = to_unicode(short_name) + if settings.TRANSLATE_GAME_NAMES: + short_name = _(short_name) if isinstance(altnames, basestring): 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 game_type == GI.GT_HANAFUDA: @@ -537,7 +550,7 @@ class GameManager: ##print gi.id, gi.short_name.encode('utf-8') if not isinstance(gi, GameInfo): raise GameInfoException("wrong GameInfo class") - if self.check_game and CHECK_GAMES: + if self.check_game and settings.CHECK_GAMES: self._check_game(gi) ##if 0 and gi.si.game_flags & GI.GT_XORIGINAL: ## return diff --git a/pysollib/games/beleagueredcastle.py b/pysollib/games/beleagueredcastle.py index 74a5980d..99a8d01b 100644 --- a/pysollib/games/beleagueredcastle.py +++ b/pysollib/games/beleagueredcastle.py @@ -96,7 +96,7 @@ class StreetsAndAlleys(Game): x = x1 for i in range(4): s.foundations.append(self.Foundation_Class(x, y, self, suit=i, max_move=0)) - y = y + l.YS + y += l.YS if texts: tx, ty, ta, tf = l.getTextAttr(None, "ss") tx, ty = x+tx, y-l.YS+ty @@ -109,7 +109,7 @@ class StreetsAndAlleys(Game): stack = self.RowStack_Class(x, y, self) stack.CARD_XOFFSET, stack.CARD_YOFFSET = l.XOFFSET, 0 s.rows.append(stack) - y = y + l.YS + y += l.YS x, y = self.width - l.XS, self.height - l.YS s.talon = InitialDealTalonStack(x, y, self) if reserves: @@ -384,20 +384,17 @@ class CastlesEnd(Bastion): class Chessboard_Foundation(SS_FoundationStack): 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) def acceptsCards(self, from_stack, cards): + if not SS_FoundationStack.acceptsCards(self, from_stack, cards): + return False 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: if s.cards: return cards[0].rank == s.cards[0].rank - return True - return SS_FoundationStack.acceptsCards(self, from_stack, cards) + return True class Chessboard_RowStack(UD_SS_RowStack): diff --git a/pysollib/games/bristol.py b/pysollib/games/bristol.py index e7da8a0d..375f8de7 100644 --- a/pysollib/games/bristol.py +++ b/pysollib/games/bristol.py @@ -76,14 +76,13 @@ class Bristol_Talon(TalonStack): class Bristol(Game): - Layout_Method = Layout.klondikeLayout Hint_Class = Bristol_Hint # # game layout # - def createGame(self, **layout): + def createGame(self): # create layout l, s = Layout(self), self.s @@ -94,7 +93,7 @@ class Bristol(Game): x, y, = l.XM + 3*l.XS, l.YM for i in range(4): s.foundations.append(RK_FoundationStack(x, y, self, max_move=0)) - x = x + l.XS + x += l.XS for i in range(2): y = l.YM + (i*2+3)*l.YS/2 for j in range(4): @@ -105,9 +104,12 @@ class Bristol(Game): x, y, = l.XM + 3*l.XS, l.YM + 4*l.YS s.talon = Bristol_Talon(x, y, self) l.createText(s.talon, "sw") + x += l.XS for i in range(3): - x = x + l.XS - s.reserves.append(ReserveStack(x, y, self, max_accept=0, max_cards=UNLIMITED_CARDS)) + stack = WasteStack(x, y, self) + l.createText(stack, 'n') + s.reserves.append(stack) + x += l.XS # define stack-groups 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 if c.rank == KING: kings.append(i) - i = i + 1 + i += 1 for i in kings: j = i % n # j = card index of rowstack bottom while j < i: if cards[j].rank != KING: cards[j], cards[i] = cards[i], cards[j] break - j = j + n + j += n cards.reverse() return cards diff --git a/pysollib/games/klondike.py b/pysollib/games/klondike.py index 5268624d..3e08df5e 100644 --- a/pysollib/games/klondike.py +++ b/pysollib/games/klondike.py @@ -884,34 +884,35 @@ class Q_C_(Klondike): self.s.talon.dealRow(frames=0) self.startDealSample() self.s.talon.dealRow() - self.s.talon.dealCards() # deal first card to WasteStack - self.fillAll() + while self.s.talon.cards: + self.s.talon.dealCards() # deal first card to WasteStack + if not self.fillWaste(): + break - def fillOne(self, stack): - if stack.cards: - c = stack.cards[-1] + def fillWaste(self): + waste = self.s.waste + if waste.cards: + c = waste.cards[-1] for f in self.s.foundations: - if f.acceptsCards(stack, [c]): - stack.moveMove(1, f) - return 1 - return 0 + if f.acceptsCards(self.s.waste, [c]): + waste.moveMove(1, f) + return True + return False - def fillAll(self): - # fill - if not self.s.waste.cards and self.s.talon.cards: - self.s.talon.dealCards() - for stack in self.s.rows: - if not stack.cards and self.s.waste.cards: - self.s.waste.moveMove(1, stack) - # move to foundations - if self.fillOne(self.s.waste): - self.fillAll() - for stack in self.s.rows: - if self.fillOne(stack): - self.fillAll() + def fillStack(self, stack=None): + waste = self.s.waste + while True: + if not self.fillWaste(): + break + if stack in self.s.rows and not stack.cards: + if not waste.cards: + while self.s.talon.cards: + self.s.talon.dealCards() + if not self.fillWaste(): + break + if waste.cards: + waste.moveMove(1, stack) - def fillStack(self, stack): - self.fillAll() shallHighlightMatch = Game._shallHighlightMatch_SS diff --git a/pysollib/games/matriarchy.py b/pysollib/games/matriarchy.py index 867ec424..aa595dce 100644 --- a/pysollib/games/matriarchy.py +++ b/pysollib/games/matriarchy.py @@ -94,6 +94,9 @@ class Matriarchy_Talon(WasteTalonStack): n = 0 update_flags = 1 # deal + if self.cards: + if sound and not self.game.demo: + self.game.playSample("dealwaste") while n < ncards: # from self to waste while n < ncards: @@ -108,6 +111,8 @@ class Matriarchy_Talon(WasteTalonStack): if n < ncards and len(waste.cards) > 0: assert len(self.cards) == 0 assert self.round < self.max_rounds or update_flags == 0 + if sound: + self.game.playSample("turnwaste", priority=20) self.game.turnStackMove(waste, self) if update_flags: self.game.nextRoundMove(self) diff --git a/pysollib/games/royalcotillion.py b/pysollib/games/royalcotillion.py index fa557073..78995c30 100644 --- a/pysollib/games/royalcotillion.py +++ b/pysollib/games/royalcotillion.py @@ -564,9 +564,11 @@ class NewBritishConstitution(BritishConstitution): class Twenty_RowStack(BasicRowStack): def acceptsCards(self, from_stack, cards): - #if not BasicRowStack.acceptsCards(self, from_stack, cards): - # return False + if not BasicRowStack.acceptsCards(self, from_stack, cards): + return False return len(self.cards) == 0 + def getHelp(self): + return _('Tableau. Empty piles can be filled with any card.') class Twenty(Game): def createGame(self): @@ -574,7 +576,7 @@ class Twenty(Game): l, s = Layout(self), self.s # 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 x, y = l.XM, l.YM @@ -589,10 +591,11 @@ class Twenty(Game): base_rank=KING, dir=-1)) 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 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 # define stack-groups diff --git a/pysollib/games/yukon.py b/pysollib/games/yukon.py index 84bf5e53..0753b511 100644 --- a/pysollib/games/yukon.py +++ b/pysollib/games/yukon.py @@ -141,8 +141,8 @@ class Odessa(RussianSolitaire): # ************************************************************************/ class Grandfather_Talon(RedealTalonStack): - def redealCards(self, sound=False): - RedealTalonStack.redealCards(self, sound=sound, shuffle=True) + def dealCards(self, sound=False): + self.redealCards(sound=sound, shuffle=True) class Grandfather(RussianSolitaire): Talon_Class = StackWrapper(Grandfather_Talon, max_rounds=3) @@ -152,9 +152,17 @@ class Grandfather(RussianSolitaire): l.createRoundText(self.s.talon, 'nn') def startGame(self): + frames = 0 + sound = False 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) - self.startDealSample() + if len(self.s.talon.cards) <= j-i: + 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() for i in range(4): self.s.talon.dealRowAvail(rows=self.s.rows[1:]) diff --git a/pysollib/hint.py b/pysollib/hint.py index 8ef4ae36..198e0486 100644 --- a/pysollib/hint.py +++ b/pysollib/hint.py @@ -463,11 +463,11 @@ class DefaultHint(AbstractHint): 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 - if not self.hints: + if not self.hints or self.level == 0: self.step040(game.s.rows, game.sg.reservestacks) # 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) # Don't be too clever and give up ;-) @@ -488,7 +488,7 @@ class DefaultHint(AbstractHint): score, color = 0, None score, color = self._getDropCardScore(score, color, r, t, ncards) self.addHint(score, ncards, r, t, color) - if score >= 90000: + if score >= 90000 and self.level >= 1: break # 1b) try if we can move cards to one of the RowStacks for pile in self.step010b_getPiles(r): diff --git a/pysollib/mfxutil.py b/pysollib/mfxutil.py index cf411d89..85058e92 100644 --- a/pysollib/mfxutil.py +++ b/pysollib/mfxutil.py @@ -106,6 +106,8 @@ def print_err(s, level=1): ss = PACKAGE+': ERROR:' elif level == 1: ss = PACKAGE+': WARNING:' + elif level == 2: + ss = PACKAGE+': DEBUG WARNING:' print >> sys.stderr, ss, s.encode(locale.getpreferredencoding()) sys.stderr.flush() @@ -165,7 +167,9 @@ def win32_gethomedir(): return hd hd = os.path.expanduser('~') 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 # /*********************************************************************** diff --git a/pysollib/options.py b/pysollib/options.py index 23c8bbb6..c5dc7f6c 100644 --- a/pysollib/options.py +++ b/pysollib/options.py @@ -25,9 +25,9 @@ import traceback # PySol imports from mfxutil import print_err -from settings import VERSION_TUPLE, WIN_SYSTEM from resource import CSI from configobj import configobj, validate +import settings # Toolkit imports from pysoltk import TOOLBAR_BUTTONS @@ -97,6 +97,7 @@ tabletile_name = string recent_gameid = int_list favorite_gameid = int_list visible_buttons = string_list +translate_game_names = boolean [sound_samples] move = boolean @@ -219,6 +220,7 @@ class Options: ('sound_sample_volume', 'int'), ('sound_music_volume', 'int'), ('tabletile_name', 'str'), + ('translate_game_names', 'bool'), #('toolbar_vars', 'list'), #('recent_gameid', 'list'), #('favorite_gameid', 'list'), @@ -229,7 +231,7 @@ class Options: self._config = None # configobj.ConfigObj instance self._config_encoding = 'utf-8' - self.version_tuple = VERSION_TUPLE # XXX + self.version_tuple = settings.VERSION_TUPLE # XXX self.saved = 0 # XXX # options menu: self.player = _("Unknown") @@ -277,6 +279,7 @@ class Options: self.mouse_type = 'drag-n-drop' # or 'sticky-mouse' or 'point-n-click' self.mouse_undo = False # use mouse for undo/redo self.negative_bottom = True + self.translate_game_names = True # sound self.sound = True self.sound_mode = 1 @@ -354,6 +357,7 @@ class Options: self.dragcursor = True def setDefaults(self, top=None): + WIN_SYSTEM = settings.WIN_SYSTEM # toolbar #if WIN_SYSTEM == 'win32': # self.toolbar_style = 'crystal' @@ -494,6 +498,7 @@ class Options: def load(self, filename): + # create ConfigObj instance try: config = configobj.ConfigObj(filename, configspec=configspec, @@ -504,6 +509,7 @@ class Options: encoding=self._config_encoding) self._config = config + # create sections for section in ( 'general', 'sound_samples', @@ -516,6 +522,7 @@ class Options: if section not in config: config[section] = {} + # add initial comment if not os.path.exists(filename): config.initial_comment = ['-*- coding: %s -*-' % self._config_encoding] @@ -544,6 +551,8 @@ class Options: elif val is not None: setattr(self, key, val) + settings.TRANSLATE_GAME_NAMES = self.translate_game_names + recent_gameid = self._getOption('general', 'recent_gameid', 'list') if recent_gameid is not None: try: diff --git a/pysollib/settings.py b/pysollib/settings.py index 4c29ebce..7322765f 100644 --- a/pysollib/settings.py +++ b/pysollib/settings.py @@ -72,6 +72,9 @@ TOP_TITLE = n_('Top 10') # use menu for select game SELECT_GAME_MENU = True +# i18n, see also options.py +TRANSLATE_GAME_NAMES = True + # debug DEBUG = 0 # must be integer CHECK_GAMES = False # check duplicated names and classes diff --git a/pysollib/tile/findcarddialog.py b/pysollib/tile/findcarddialog.py index 5a12bdff..26f9e4c0 100644 --- a/pysollib/tile/findcarddialog.py +++ b/pysollib/tile/findcarddialog.py @@ -48,7 +48,8 @@ class FindCardDialog(Tkinter.Toplevel): def __init__(self, parent, game, dir, size='large'): Tkinter.Toplevel.__init__(self) - self.title(_('Find card')) + title = TITLE + ' - ' + _('Find card') + self.title(title) self.wm_resizable(False, False) # ##self.images_dir = dir diff --git a/pysollib/tile/menubar.py b/pysollib/tile/menubar.py index 74feac32..2c53e499 100644 --- a/pysollib/tile/menubar.py +++ b/pysollib/tile/menubar.py @@ -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 &as..."), command=self.mSaveAs) 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": 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, "o", self.mOpen) self._bindKey(ctrl, "s", self.mSave) + self._bindKey(ctrl, "x", self.mHoldAndQuit) self._bindKey(ctrl, "q", self.mQuit) self._bindKey("", "z", self.mUndo) self._bindKey("", "BackSpace", self.mUndo) # undocumented diff --git a/pysollib/tile/selecttile.py b/pysollib/tile/selecttile.py index 0e21b7bc..19e0e82e 100644 --- a/pysollib/tile/selecttile.py +++ b/pysollib/tile/selecttile.py @@ -192,12 +192,11 @@ class SelectTileDialogWithPreview(MfxDialog): MfxDialog.mDone(self, button) def updatePreview(self, key): - ##print key if key == self.preview_key: return canvas = self.preview.canvas canvas.deleteAllItems() - if isinstance(key, str): + if isinstance(key, basestring): # solid color canvas.config(bg=key) canvas.setTile(None) diff --git a/pysollib/tile/tkwidget.py b/pysollib/tile/tkwidget.py index fcbc6eac..e2753ea3 100644 --- a/pysollib/tile/tkwidget.py +++ b/pysollib/tile/tkwidget.py @@ -560,10 +560,15 @@ class MfxScrolledCanvas: width = kw.get("width") height = kw.get("height") self.frame = Tile.Frame(self.parent, width=width, height=height) - def createCanvas(self, kw): - self.canvas = MfxCanvas(self.frame, **kw) - self.canvas.grid(row=0, column=0, sticky="news") + bd = kw['bd'] + 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): self.hbar = Tile.Scrollbar(self.frame, takefocus=0, orient="horizontal") diff --git a/pysollib/tk/findcarddialog.py b/pysollib/tk/findcarddialog.py index 2643ae8e..88e3e649 100644 --- a/pysollib/tk/findcarddialog.py +++ b/pysollib/tk/findcarddialog.py @@ -51,7 +51,8 @@ class FindCardDialog(Tkinter.Toplevel): def __init__(self, parent, game, dir, size='large'): Tkinter.Toplevel.__init__(self) - self.title(_('Find card')) + title = TITLE + ' - ' + _('Find card') + self.title(title) self.wm_resizable(False, False) # ##self.images_dir = dir diff --git a/pysollib/tk/menubar.py b/pysollib/tk/menubar.py index 178ec1ae..7a9307de 100644 --- a/pysollib/tk/menubar.py +++ b/pysollib/tk/menubar.py @@ -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 &as..."), command=self.mSaveAs) 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": 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, "o", self.mOpen) self._bindKey(ctrl, "s", self.mSave) + self._bindKey(ctrl, "x", self.mHoldAndQuit) self._bindKey(ctrl, "q", self.mQuit) self._bindKey("", "z", self.mUndo) self._bindKey("", "BackSpace", self.mUndo) # undocumented diff --git a/pysollib/tk/selecttile.py b/pysollib/tk/selecttile.py index 6fb53375..5908aa9d 100644 --- a/pysollib/tk/selecttile.py +++ b/pysollib/tk/selecttile.py @@ -196,7 +196,7 @@ class SelectTileDialogWithPreview(MfxDialog): return canvas = self.preview.canvas canvas.deleteAllItems() - if isinstance(key, str): + if isinstance(key, basestring): # solid color canvas.config(bg=key) canvas.setTile(None) diff --git a/pysollib/tk/tkwidget.py b/pysollib/tk/tkwidget.py index 1f52abcc..fbef7c4d 100644 --- a/pysollib/tk/tkwidget.py +++ b/pysollib/tk/tkwidget.py @@ -550,10 +550,15 @@ class MfxScrolledCanvas: width = kw.get("width") height = kw.get("height") self.frame = Tkinter.Frame(self.parent, width=width, height=height) - def createCanvas(self, kw): - self.canvas = MfxCanvas(self.frame, **kw) - self.canvas.grid(row=0, column=0, sticky="news") + bd = kw['bd'] + 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): self.hbar = Tkinter.Scrollbar(self.frame, takefocus=0, orient="horizontal")