## vim:ts=4:et:nowrap ## ##---------------------------------------------------------------------------## ## ## PySol -- a Python Solitaire game ## ## Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer ## Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer ## Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer ## Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer ## Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer ## Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer ## All Rights Reserved. ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; see the file COPYING. ## If not, write to the Free Software Foundation, Inc., ## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ## ## Markus F.X.J. Oberhumer ## ## http://www.oberhumer.com/pysol ## ##---------------------------------------------------------------------------## # imports import os, re, sys, string, time, types # PySol imports from mfxtools import * from mfxutil import EnvError, SubclassResponsibility from mfxutil import Struct, destruct, openURL from util import PACKAGE, PACKAGE_URL, VERSION, bundle from random import constructRandom # stats imports from stats import Status_StatsDialog, PysolStatsFormatter from pysoltk import SingleGame_StatsDialog, AllGames_StatsDialog from pysoltk import FullLog_StatsDialog, SessionLog_StatsDialog # toolkit imports from pysoltk import EVENT_HANDLED, EVENT_PROPAGATE from pysoltk import MfxDialog, MfxSimpleSlider, MfxSimpleEntry from pysoltk import MfxExceptionDialog from pysoltk import MfxCheckMenuItem, MfxRadioMenuItem from pysoltk import getFont from pysoltk import PlayerOptionsDialog from pysoltk import SoundOptionsDialog from pysoltk import DemoOptionsDialog, HintOptionsDialog from pysoltk import EditTextDialog from help import helpAbout, helpAboutSimple, helpHTML # /*********************************************************************** # // menubar # ************************************************************************/ class PysolMenubarActions: def __init__(self, app, top): self.app = app self.top = top self.game = None # enabled/disabled - this is set by updateMenuState() self.menustate = Struct( save = 0, save_as = 0, hold_and_quit = 0, undo = 0, redo = 0, restart = 0, deal = 0, hint = 0, autofaceup = 0, autodrop = 0, autodeal = 0, quickplay = 0, demo = 0, highlight_piles = 0, rules = 0, ) # structure to convert menu-options to Toolkit variables self.tkopt = Struct( gameid = MfxRadioMenuItem(self), gameid_popular = MfxRadioMenuItem(self), comment = MfxCheckMenuItem(self), autofaceup = MfxCheckMenuItem(self), autodrop = MfxCheckMenuItem(self), autodeal = MfxCheckMenuItem(self), quickplay = MfxCheckMenuItem(self), undo = MfxCheckMenuItem(self), bookmarks = MfxCheckMenuItem(self), hint = MfxCheckMenuItem(self), highlight_piles = MfxCheckMenuItem(self), highlight_cards = MfxCheckMenuItem(self), highlight_samerank = MfxCheckMenuItem(self), sound = MfxCheckMenuItem(self), cardback = MfxRadioMenuItem(self), tabletile = MfxRadioMenuItem(self), animations = MfxRadioMenuItem(self), shadow = MfxCheckMenuItem(self), shade = MfxCheckMenuItem(self), toolbar = MfxRadioMenuItem(self), toolbar_size = MfxRadioMenuItem(self), toolbar_relief = MfxRadioMenuItem(self), statusbar = MfxCheckMenuItem(self), ) def connectGame(self, game): self.game = game if game is None: return assert self.app is game.app tkopt, opt = self.tkopt, self.app.opt # set state of the menu items tkopt.gameid.set(game.id) tkopt.gameid_popular.set(game.id) tkopt.comment.set(bool(game.gsaveinfo.comment)) tkopt.autofaceup.set(opt.autofaceup) tkopt.autodrop.set(opt.autodrop) tkopt.autodeal.set(opt.autodeal) tkopt.quickplay.set(opt.quickplay) tkopt.undo.set(opt.undo) tkopt.hint.set(opt.hint) tkopt.bookmarks.set(opt.bookmarks) tkopt.highlight_piles.set(opt.highlight_piles) tkopt.highlight_cards.set(opt.highlight_cards) tkopt.highlight_samerank.set(opt.highlight_samerank) tkopt.sound.set(opt.sound) tkopt.cardback.set(self.app.cardset.backindex) tkopt.tabletile.set(self.app.tabletile_index), tkopt.animations.set(opt.animations) tkopt.shadow.set(opt.shadow) tkopt.shade.set(opt.shade) tkopt.toolbar.set(opt.toolbar) tkopt.toolbar_size.set(opt.toolbar_size) tkopt.toolbar_relief.set(opt.toolbar_relief) tkopt.statusbar.set(opt.statusbar) # will get called after connectGame() def updateRecentGamesMenu(self, gameids): pass def updateBookmarkMenuState(self): pass # will get called after a new cardset has been loaded def updateBackgroundImagesMenu(self): pass # # delegation to Game # def _finishDrag(self): return self.game is None or self.game._finishDrag() def _cancelDrag(self): return self.game is None or self.game._cancelDrag() def changed(self, *args, **kw): assert self.game is not None return apply(self.game.changed, args, kw) # # menu updates # def setMenuState(self, state, path): raise SubclassResponsibility def setToolbarState(self, state, path): raise SubclassResponsibility def _clearMenuState(self): ms = self.menustate for k, v in ms.__dict__.items(): if type(v) is types.ListType: ms.__dict__[k] = [0] * len(v) else: ms.__dict__[k] = 0 # update self.menustate for menu items and toolbar def _updateMenuState(self): self._clearMenuState() game = self.game assert game is not None opt = self.app.opt ms = self.menustate # 0 = DISABLED, 1 = ENABLED ms.save_as = game.canSaveGame() ms.hold_and_quit = ms.save_as if game.filename and ms.save_as: ms.save = 1 if opt.undo: if game.canUndo() and game.moves.index > 0: ms.undo = 1 if game.canRedo() and game.moves.index < len(game.moves.history): ms.redo = 1 if game.moves.index > 0: ms.restart = 1 if game.canDealCards(): ms.deal = 1 if game.getHintClass() is not None: if opt.hint: ms.hint = 1 ###if not game.demo: # if not already running ms.demo = 1 autostacks = game.getAutoStacks() if autostacks[0]: ms.autofaceup = 1 if autostacks[1] and game.s.foundations: ms.autodrop = 1 if game.s.waste: ms.autodeal = 1 if autostacks[2]: ms.quickplay = 1 ms.highlight_piles = 0 if opt.highlight_piles and game.getHighlightPilesStacks(): ms.highlight_piles = 1 if game.app.getGameRulesFilename(game.id): # note: this may return "" ms.rules = 1 # update menu items and toolbar def _updateMenus(self): if self.game is None: return ms = self.menustate # File menu self.setMenuState(ms.save, "file.save") self.setMenuState(ms.save_as, "file.saveas") self.setMenuState(ms.hold_and_quit, "file.holdandquit") # Edit menu self.setMenuState(ms.undo, "edit.undo") self.setMenuState(ms.redo, "edit.redo") self.setMenuState(ms.redo, "edit.redoall") self.updateBookmarkMenuState() self.setMenuState(ms.restart, "edit.restartgame") # Game menu self.setMenuState(ms.deal, "game.dealcards") self.setMenuState(ms.autodrop, "game.autodrop") # Assist menu self.setMenuState(ms.hint, "assist.hint") self.setMenuState(ms.highlight_piles, "assist.highlightpiles") self.setMenuState(ms.demo, "assist.demo") self.setMenuState(ms.demo, "assist.demoallgames") # Options menu self.setMenuState(ms.autofaceup, "options.automaticplay.autofaceup") self.setMenuState(ms.autodrop, "options.automaticplay.autodrop") self.setMenuState(ms.autodeal, "options.automaticplay.autodeal") self.setMenuState(ms.quickplay, "options.automaticplay.quickplay") # Help menu self.setMenuState(ms.rules, "help.rulesforthisgame") # Toolbar self.setToolbarState(ms.restart, "restart") self.setToolbarState(ms.save_as, "save") self.setToolbarState(ms.undo, "undo") self.setToolbarState(ms.redo, "redo") self.setToolbarState(ms.autodrop, "autodrop") self.setToolbarState(ms.rules, "rules") # self.tkopt.comment.set(bool(self.game.gsaveinfo.comment)) # update menu items and toolbar def updateMenus(self): if self.game is None: return self._updateMenuState() self._updateMenus() # disable menu items and toolbar def disableMenus(self): if self.game is None: return self._clearMenuState() self._updateMenus() # # File menu # def mNewGame(self, *args): if self._cancelDrag(): return if self.changed(): if not self.game.areYouSure("New game"): return if self.game.nextGameFlags(self.game.id) == 0: self.game.endGame() self.game.newGame() else: self.game.endGame() self.game.quitGame(self.game.id) def _mSelectGame(self, id, random=None): if self._cancelDrag(): return if self.game.id == id: return if self.changed(): if not self.game.areYouSure("Select game"): # restore radiobutton settings self.tkopt.gameid.set(self.game.id) self.tkopt.gameid_popular.set(self.game.id) return self.game.endGame() self.game.quitGame(id, random=random) def mSelectGame(self, *args): self._mSelectGame(self.tkopt.gameid.get()) def mSelectGamePopular(self, *args): self._mSelectGame(self.tkopt.gameid_popular.get()) def _mNewGameBySeed(self, seed, origin): try: id, random = constructRandom(seed) if id is None: id = self.game.id if random is None: return if not self.app.getGameInfo(id): raise ValueError except (ValueError, TypeError), ex: d = MfxDialog(self.top, title="Invalid game number", text="Invalid game number\n" + str(seed), bitmap="error") return f = self.game.nextGameFlags(id, random) if f & 17 == 0: return random.origin = origin if f & 15 == 0: self.game.endGame() self.game.newGame(random=random) else: self.game.endGame() self.game.quitGame(id, random=random) def mNewGameWithNextId(self, *args): if self._cancelDrag(): return if self.changed(): if not self.game.areYouSure("Select next game number"): return r = self.game.random seed = r.increaseSeed(r.initial_seed) seed = r.str(seed) self._mNewGameBySeed(seed, self.game.random.ORIGIN_NEXT_GAME) def mSelectGameById(self, *args): if self._cancelDrag(): return id, f = None, self.game.getGameNumber(format=0) d = MfxSimpleEntry(self.top, "Select new game number", "\n\nEnter new game number", f, strings=("OK", "Next number", "Cancel"), default=0, e_width=25) if d.status != 0: return if d.button == 2: return if d.button == 1: self.mNewGameWithNextId() return if self.changed(): if not self.game.areYouSure("Select new game number"): return self._mNewGameBySeed(d.value, self.game.random.ORIGIN_SELECTED) def mSelectRandomGame(self, *args): if self._cancelDrag(): return if self.changed(): if not self.game.areYouSure("Select random game"): return for i in range(1000): # just in case, don't loop forever gi = self.app.getGameInfo(self.app.getRandomGameId()) if gi is None: continue if 1 and gi.id == self.game.id: # force change of game continue if 1 and gi.category != self.game.gameinfo.category: # don't change game category continue break if gi and gi.id != self.game.id: self.game.endGame() self.game.quitGame(gi.id) def _mSelectNextGameFromList(self, gl, step): if self._cancelDrag(): return id = self.game.id gl = list(gl) if len(gl) < 2 or not id in gl: return if self.changed(): if not self.game.areYouSure("Select next game"): return index = (gl.index(id) + step) % len(gl) self.game.endGame() self.game.quitGame(gl[index]) def mSelectNextGameById(self, *args): self._mSelectNextGameFromList(self.app.gdb.getGamesIdSortedById(), 1) def mSelectPrevGameById(self, *args): self._mSelectNextGameFromList(self.app.gdb.getGamesIdSortedById(), -1) def mSelectNextGameByName(self, *args): self._mSelectNextGameFromList(self.app.gdb.getGamesIdSortedByName(), 1) def mSelectPrevGameByName(self, *args): self._mSelectNextGameFromList(self.app.gdb.getGamesIdSortedByName(), -1) def mSave(self, *args): if self._cancelDrag(): return if self.menustate.save_as: if self.game.filename: self.game.saveGame(self.game.filename) else: self.mSaveAs() def mHoldAndQuit(self, *args): if self._cancelDrag(): return self.game.endGame(holdgame=1) self.game.quitGame(holdgame=1) def mQuit(self, *args): if self._cancelDrag(): return if self.changed(): if not self.game.areYouSure("Quit PySol"): return self.game.endGame() self.game.quitGame() # # Edit menu # def mUndo(self, *args): if self._cancelDrag(): return if self.menustate.undo: self.game.playSample("undo") self.game.undo() def mRedo(self, *args): if self._cancelDrag(): return if self.menustate.redo: self.game.playSample("redo") self.game.redo() self.game.checkForWin() def mRedoAll(self, *args): if self._cancelDrag(): return if self.menustate.redo: self.game.playSample("redo", loop=1) while self.game.moves.index < len(self.game.moves.history): self.game.redo() if self.game.checkForWin(): break self.game.stopSamples() def mSetBookmark(self, n, confirm=1): if self._cancelDrag(): return if not self.app.opt.bookmarks: return if not (0 <= n <= 8): return self.game.setBookmark(n, confirm=confirm) self.game.updateMenus() def mGotoBookmark(self, n, confirm=-1): if self._cancelDrag(): return if not self.app.opt.bookmarks: return if not (0 <= n <= 8): return self.game.gotoBookmark(n, confirm=confirm) self.game.updateMenus() def mClearBookmarks(self, *args): if self._cancelDrag(): return if not self.app.opt.bookmarks: return if not self.game.gsaveinfo.bookmarks: return if not self.game.areYouSure("Clear bookmarks","Clear all bookmarks ?"): return self.game.gsaveinfo.bookmarks = {} self.game.updateMenus() def mRestart(self, *args): if self._cancelDrag(): return if self.game.moves.index == 0: return if self.changed(restart=1): if not self.game.areYouSure("Restart game","Restart this game ?"): return self.game.restartGame() # # Game menu # def mDeal(self, *args): if self._cancelDrag(): return self.game.dealCards() def mDrop(self, *args): if self._cancelDrag(): return self.game.autoPlay(autofaceup=-1, autodrop=1) def mDrop1(self, *args): if self._cancelDrag(): return self.game.autoPlay(autofaceup=1, autodrop=1) def mStatus(self, *args): if self._cancelDrag(): return self.mPlayerStats(mode=100) def mEditGameComment(self, *args): if self._cancelDrag(): return game, gi = self.game, self.game.gameinfo t = " " + game.getGameNumber(format=1) cc = "Comments for " + gi.name + t + ":\n\n" c = game.gsaveinfo.comment or cc d = EditTextDialog(game.top, "Comments for"+t, text=c) if d.status == 0 and d.button == 0: if string.strip(d.text) == string.strip(cc): game.gsaveinfo.comment = "" else: game.gsaveinfo.comment = string.rstrip(d.text) self.tkopt.comment.set(bool(game.gsaveinfo.comment)) # # Game menu - statistics # def _mStatsSave(self, player, header, filename, write_method): file = None if player is None: text = "Demo statistics" filename = filename + "_demo" else: text = "Your statistics" filename = os.path.join(self.app.dn.config, filename + ".txt") filename = os.path.normpath(filename) try: file = open(filename, "a") a = PysolStatsFormatter(self.app) writer = a.FileWriter(file) apply(write_method, (a, writer, player, header)) destruct(a) except EnvError, ex: if file: file.close() d = MfxExceptionDialog(self.top, ex, text="Error while writing to file") else: if file: file.close() d = MfxDialog(self.top, title=PACKAGE+" Info", bitmap="info", text=text + " were appended to\n\n" + filename) def mPlayerStats(self, *args, **kw): mode = kw.get("mode", 101) demo = 0 while mode > 0: if mode > 1000: demo = not demo mode = mode % 1000 # d = Struct(status=-1, button=-1) if demo: player = None p0, p1, p2 = PACKAGE+" Demo", PACKAGE+" Demo ", "" else: player = self.app.opt.player p0, p1, p2 = player, "", " for " + player n = self.game.gameinfo.short_name # if mode == 100: d = Status_StatsDialog(self.top, game=self.game) elif mode == 101: header = p1 + "Statistics for " + n d = SingleGame_StatsDialog(self.top, header, self.app, player, gameid=self.game.id) elif mode == 102: header = p1 + "Statistics" + p2 d = AllGames_StatsDialog(self.top, header, self.app, player) elif mode == 103: header = p1 + "Full log" + p2 d = FullLog_StatsDialog(self.top, header, self.app, player) elif mode == 104: header = p1 + "Session log" + p2 d = SessionLog_StatsDialog(self.top, header, self.app, player) elif mode == 202: # print stats to file header = "Statistics for " + p0 write_method = PysolStatsFormatter.writeStats self._mStatsSave(player, header, "stats", write_method) elif mode == 203: # print full log to file header = "Full log for " + p0 write_method = PysolStatsFormatter.writeFullLog self._mStatsSave(player, header, "log", write_method) elif mode == 204: # print session log to file header = "Session log for " + p0 write_method = PysolStatsFormatter.writeSessionLog self._mStatsSave(player, header, "log", write_method) elif mode == 301: # reset all player stats if self.game.areYouSure("Reset all statistics", "Reset ALL statistics and logs for player\n" + p0 + " ?", confirm=1, default=1): self.app.stats.resetStats(player, 0) self.game.updateStatus(stats=self.app.stats.getStats(self.app.opt.player, self.game.id)) elif mode == 302: # reset player stats for current game if self.game.areYouSure("Reset game statistics", "Reset statistics and logs for player\n" + p0 + "\nand game\n" + n +" ?", confirm=1, default=1): self.app.stats.resetStats(player, self.game.id) self.game.updateStatus(stats=self.app.stats.getStats(self.app.opt.player, self.game.id)) elif mode == 401: # start a new game with a gameid ## TODO pass elif mode == 402: # start a new game with a gameid / gamenumber ## TODO pass else: print "stats problem:", mode, demo, player pass if d.status != 0: break mode = d.button # # Assist menu # def mHint(self, *args): if self._cancelDrag(): return if self.app.opt.hint: if self.game.showHint(0, self.app.opt.hint_sleep): self.game.stats.hints = self.game.stats.hints + 1 def mHint1(self, *args): if self._cancelDrag(): return if self.app.opt.hint: if self.game.showHint(1, self.app.opt.hint_sleep): self.game.stats.hints = self.game.stats.hints + 1 def mHighlightPiles(self, *args): if self._cancelDrag(): return if self.app.opt.highlight_piles: if self.game.highlightPiles(self.app.opt.highlight_piles_sleep): self.game.stats.highlight_piles = self.game.stats.highlight_piles + 1 def mDemo(self, *args): if self._cancelDrag(): return if self.game.getHintClass() is not None: self._mDemo(mixed=0) def mMixedDemo(self, *args): if self._cancelDrag(): return self._mDemo(mixed=1) def _mDemo(self, mixed): if self._cancelDrag(): return if self.changed(): # only ask if there have been no demo moves or hints yet if self.game.stats.demo_moves == 0 and self.game.stats.hints == 0: if not self.game.areYouSure("Play demo"): return ##self.app.demo_counter = 0 self.game.startDemo(mixed=mixed) # # Options menu # def mOptPlayerOptions(self, *args): if self._cancelDrag(): return d = PlayerOptionsDialog(self.top, "Set player options", self.app) if d.status == 0 and d.button == 0: self.app.opt.confirm = bool(d.confirm) self.app.opt.update_player_stats = bool(d.update_stats) self.app.opt.win_animation = bool(d.win_animation) ##n = string.strip(d.player) n = string.strip(d.player[:30]) if 0 < len(n) <= 30: self.app.opt.player = n self.game.updateStatus(player=self.app.opt.player) self.game.updateStatus(stats=self.app.stats.getStats(self.app.opt.player, self.game.id)) def mOptAutoFaceUp(self, *args): if self._cancelDrag(): return self.app.opt.autofaceup = self.tkopt.autofaceup.get() if self.app.opt.autofaceup: self.game.autoPlay() def mOptAutoDrop(self, *args): if self._cancelDrag(): return self.app.opt.autodrop = self.tkopt.autodrop.get() if self.app.opt.autodrop: self.game.autoPlay() def mOptAutoDeal(self, *args): if self._cancelDrag(): return self.app.opt.autodeal = self.tkopt.autodeal.get() if self.app.opt.autodeal: self.game.autoPlay() def mOptQuickPlay(self, *args): if self._cancelDrag(): return self.app.opt.quickplay = self.tkopt.quickplay.get() def mOptEnableUndo(self, *args): if self._cancelDrag(): return self.app.opt.undo = self.tkopt.undo.get() self.game.updateMenus() def mOptEnableBookmarks(self, *args): if self._cancelDrag(): return self.app.opt.bookmarks = self.tkopt.bookmarks.get() self.game.updateMenus() def mOptEnableHint(self, *args): if self._cancelDrag(): return self.app.opt.hint = self.tkopt.hint.get() self.game.updateMenus() def mOptEnableHighlightPiles(self, *args): if self._cancelDrag(): return self.app.opt.highlight_piles = self.tkopt.highlight_piles.get() self.game.updateMenus() def mOptEnableHighlightCards(self, *args): if self._cancelDrag(): return self.app.opt.highlight_cards = self.tkopt.highlight_cards.get() self.game.updateMenus() def mOptEnableHighlightSameRank(self, *args): if self._cancelDrag(): return self.app.opt.highlight_samerank = self.tkopt.highlight_samerank.get() self.game.updateMenus() def mOptSound(self, *args): if self._cancelDrag(): return self.app.opt.sound = self.tkopt.sound.get() if not self.app.opt.sound: self.app.audio.stopAll() def mOptSoundDialog(self, *args): if self._cancelDrag(): return d = SoundOptionsDialog(self.top, "Sound settings", self.app) self.tkopt.sound.set(self.app.opt.sound) def mOptAnimations(self, *args): if self._cancelDrag(): return self.app.opt.animations = self.tkopt.animations.get() def mOptShadow(self, *args): if self._cancelDrag(): return self.app.opt.shadow = self.tkopt.shadow.get() def mOptShade(self, *args): if self._cancelDrag(): return self.app.opt.shade = self.tkopt.shade.get() def mOptIrregularPiles(self, *args): if self._cancelDrag(): return self.app.opt.irregular_piles = self.tkopt.irregular_piles.get() def mOptDemoOptions(self, *args): if self._cancelDrag(): return d = DemoOptionsDialog(self.top, "Set demo options", self.app) if d.status == 0 and d.button == 0: self.app.opt.demo_logo = d.demo_logo self.app.opt.demo_score = d.demo_score self.app.opt.demo_sleep = d.demo_sleep def mOptHintOptions(self, *args): if self._cancelDrag(): return d = HintOptionsDialog(self.top, "Set hint options", self.app) if d.status == 0 and d.button == 0: self.app.opt.hint_sleep = d.hint_sleep def mOptSave(self, *args): if self._cancelDrag(): return try: self.app.saveOptions() except Exception, ex: d = MfxExceptionDialog(self.top, ex, text="Error while saving options") else: # tell the player where their config files reside d = MfxDialog(self.top, title=PACKAGE+" Info", text="Options were saved to\n\n" + self.app.fn.opt, bitmap="info") # # Help menu # def mHelp(self, *args): if self._cancelDrag(): return helpHTML(self.app, "index.html", "html") def mHelpHowToPlay(self, *args): if self._cancelDrag(): return helpHTML(self.app, "howtoplay.html", "html") def mHelpRules(self, *args): if self._cancelDrag(): return if not self.menustate.rules: return dir = os.path.join("html", "rules") ## FIXME: plugins helpHTML(self.app, self.app.getGameRulesFilename(self.game.id), dir) def mHelpLicense(self, *args): if self._cancelDrag(): return helpHTML(self.app, "license.html", "html") def mHelpNews(self, *args): if self._cancelDrag(): return helpHTML(self.app, "news.html", "html") def mHelpWebSite(self, *args): openURL(PACKAGE_URL) def mHelpAbout(self, *args): if self._cancelDrag(): return if self.app and bundle & 4: helpAboutSimple(self.app) else: helpAbout(self.app) # # misc # def mScreenshot(self, *args): if self._cancelDrag(): return f = os.path.join(self.app.dn.config, "screenshots") if not os.path.isdir(f): return f = os.path.join(f, self.app.getGameSaveName(self.game.id)) i = 1 while 1: fn = f + ("-%d.ppm" % i) if not os.path.isfile(fn): break i = i + 1 if i >= 10000: # give up return self.top.screenshot(fn) def mPlayNextMusic(self, *args): if self._cancelDrag(): return if self.app.audio and self.app.opt.sound_music_volume > 0: self.app.audio.playNextMusic() if 1 and self.app.debug: index = self.app.audio.getMusicInfo() music = self.app.music_manager.get(index) if music: print "playing music:", music.filename # /*********************************************************************** # // toolbar # ************************************************************************/ class PysolToolbarActions: def __init__(self): self.game = None self.menubar = None # # public methods # def connectGame(self, game, menubar): self.game = game self.menubar = menubar # # button event handlers - delegate to menubar # def _busy(self): raise SubclassResponsibility def mNewGame(self, *args): if not self._busy(): self.menubar.mNewGame() return 1 def mOpen(self, *args): if not self._busy(): self.menubar.mOpen() return 1 def mRestart(self, *args): if not self._busy(): self.menubar.mRestart() return 1 def mSave(self, *args): if not self._busy(): self.menubar.mSaveAs() return 1 def mUndo(self, *args): if not self._busy(): self.menubar.mUndo() return 1 def mRedo(self, *args): if not self._busy(): self.menubar.mRedo() return 1 def mDrop(self, *args): if not self._busy(): self.menubar.mDrop() return 1 def mStatus(self, *args): if not self._busy(): self.menubar.mStatus() return 1 def mPlayerStats(self, *args): if not self._busy(): self.menubar.mPlayerStats() return 1 def mHelpRules(self, *args): if not self._busy(): self.menubar.mHelpRules() return 1 def mQuit(self, *args): if not self._busy(): self.menubar.mQuit() return 1 def mOptPlayerOptions(self, *args): if not self._busy(): self.menubar.mOptPlayerOptions() return 1