def analyse_moves(): move_time = int(conf.get("max_analysis_spin", 3)) thresold = int(conf.get("variation_thresold_spin", 50)) for board in gamemodel.boards: if stop_event.is_set(): break glock.acquire() try: gmwidg.board.view.setShownBoard(board) finally: glock.release() analyzer.setBoard(board) time.sleep(move_time + 0.1) ply = board.ply if ply - 1 in gamemodel.scores: color = (ply - 1) % 2 oldmoves, oldscore, olddepth = gamemodel.scores[ply - 1] oldscore = oldscore * -1 if color == BLACK else oldscore moves, score, depth = gamemodel.scores[ply] score = score * -1 if color == WHITE else score diff = score - oldscore if (diff > thresold and color == BLACK) or (diff < -1 * thresold and color == WHITE): gamemodel.add_variation(gamemodel.boards[ply - 1], oldmoves) widgets["analyze_game"].hide() widgets["analyze_ok_button"].set_sensitive(True) conf.set("analyzer_check", old_check_value)
def on_game_started (gamemodel, gmwidg): on_gmwidg_infront(gmwidg) # setup menu items sensitivity # Rotate to human player boardview = gmwidg.board.view if gamemodel.players[1].__type__ == LOCAL: if gamemodel.players[0].__type__ != LOCAL: boardview.rotation = math.pi elif conf.get("autoRotate", True) and \ gamemodel.curplayer == gamemodel.players[1]: boardview.rotation = math.pi # Play set-up sound preferencesDialog.SoundTab.playAction("gameIsSetup") # Connect player offers to statusbar for player in gamemodel.players: if player.__type__ == LOCAL: player.connect("offer", offer_callback, gamemodel, gmwidg) # Start analyzers if any gamemodel.connect("analyzer_added", analyzer_added, gmwidg) if not (isinstance(gamemodel, ICGameModel) and \ gamemodel.isObservationGame() is False) and \ not gamemodel.isEngine2EngineGame(): gamemodel.start_analyzer(HINT) gamemodel.start_analyzer(SPY) if not conf.get("hint_mode", False): gamemodel.pause_analyzer(HINT) if not conf.get("spy_mode", False): gamemodel.pause_analyzer(SPY) return False
def run (no_debug, no_idle_add_debug, no_thread_debug, log_viewer, chess_file, ics_host, ics_port): # Start logging if log_viewer: log.logger.addHandler(GLogHandler(logemitter)) log.logger.setLevel(logging.WARNING if no_debug is True else logging.DEBUG) oldlogs = [l for l in os.listdir(getUserDataPrefix()) if l.endswith(".log")] conf.set("max_log_files", conf.get("max_log_files", 10)) if len(oldlogs) >= conf.get("max_log_files", 10): oldlogs.sort() try: os.remove(addUserDataPrefix(oldlogs[0])) except OSError as e: pass signal.signal(signal.SIGINT, Gtk.main_quit) def cleanup (): SubProcess.finishAllSubprocesses() atexit.register(cleanup) pychess = PyChess(log_viewer, chess_file) idle_add.debug = not no_idle_add_debug sys.stdout = LogPipe(sys.stdout, "stdout") sys.stderr = LogPipe(sys.stderr, "stdout") log.info("PyChess %s %s rev. %s %s started" % (VERSION_NAME, VERSION, pychess.hg_rev, pychess.hg_date)) log.info("Command line args: '%s'" % chess_file) if not no_thread_debug: start_thread_dump() if ics_host: ICLogon.host = ics_host if ics_port: ICLogon.port = ics_port Gtk.main()
def on_game_started(self, gamemodel, gmwidg): # Rotate to human player boardview = gmwidg.board.view if gamemodel.players[1].__type__ == LOCAL: if gamemodel.players[0].__type__ != LOCAL: boardview.rotation = math.pi elif conf.get("autoRotate", True) and \ gamemodel.curplayer == gamemodel.players[1]: boardview.rotation = math.pi # Play set-up sound preferencesDialog.SoundTab.playAction("gameIsSetup") # Connect player offers to infobar for player in gamemodel.players: if player.__type__ == LOCAL: self.offer_cids[gamemodel][player] = player.connect( "offer", self.offer_callback, gamemodel, gmwidg) # Start analyzers if any if not gamemodel.isEngine2EngineGame(): asyncio.async(gamemodel.start_analyzer(HINT)) asyncio.async(gamemodel.start_analyzer(SPY)) if not conf.get("hint_mode", False): gamemodel.pause_analyzer(HINT) if not conf.get("spy_mode", False): gamemodel.pause_analyzer(SPY) return False
def onFinger(self, fm, finger): if not finger.getName() == self.connection.getUsername(): return self.finger = finger numfingers = conf.get("numberOfFingers") + 1 conf.set("numberOfFingers", numfingers) if conf.get("numberOfTimesLoggedInAsRegisteredUser") is 1 and numfingers is 1: standard = self.__getRating(TYPE_STANDARD) blitz = self.__getRating(TYPE_BLITZ) lightning = self.__getRating(TYPE_LIGHTNING) if standard is not None: self.seekEditorWidgetDefaults["ratingCenterSlider"][ 0] = standard // RATING_SLIDER_STEP elif blitz is not None: self.seekEditorWidgetDefaults["ratingCenterSlider"][ 0] = blitz // RATING_SLIDER_STEP if blitz is not None: self.seekEditorWidgetDefaults["ratingCenterSlider"][ 1] = blitz // RATING_SLIDER_STEP if lightning is not None: self.seekEditorWidgetDefaults["ratingCenterSlider"][ 2] = lightning // RATING_SLIDER_STEP elif blitz is not None: self.seekEditorWidgetDefaults["ratingCenterSlider"][ 2] = blitz // RATING_SLIDER_STEP for i in range(1, 4): self.__loadSeekEditor(i) self.__updateSeekEditor(i) self.__saveSeekEditor(i) self.__writeSavedSeeks(i) self.__updateYourRatingHBox()
def startClicked(self, button): color = self.widgets["colorDock"].get_child().active if color == 2: color = random.choice([WHITE, BLACK]) opponent = self.widgets["opponentDock"].get_child().active difficulty = int(self.widgets["skillSlider"].get_value()) gamemodel = GameModel(TimeModel(5 * 60, 0)) name = conf.get("firstName", _("You")) player0tup = (LOCAL, Human, (color, name), name) if opponent == 0: name = conf.get("secondName", _("Guest")) player1tup = (LOCAL, Human, (1 - color, name), name) else: engine = discoverer.getEngineN(opponent - 1) name = discoverer.getName(engine) player1tup = (ARTIFICIAL, discoverer.initPlayerEngine, (engine, 1 - color, difficulty, variants[NORMALCHESS], 5 * 60, 0), name) if color == WHITE: ionest.generalStart(gamemodel, player0tup, player1tup) else: ionest.generalStart(gamemodel, player1tup, player0tup)
def analyse_moves(): should_black = conf.get("shouldBlack", True) should_white = conf.get("shouldWhite", True) from_current = conf.get("fromCurrent", True) start_ply = gmwidg.board.view.shown if from_current else 0 move_time = int(conf.get("max_analysis_spin", 3)) threshold = int(conf.get("variation_threshold_spin", 50)) for board in gamemodel.boards[start_ply:]: if stop_event.is_set(): break @idle_add def do(): gmwidg.board.view.setShownBoard(board) do() analyzer.setBoard(board) if threat_PV: inv_analyzer.setBoard(board) time.sleep(move_time + 0.1) ply = board.ply color = (ply - 1) % 2 if ply - 1 in gamemodel.scores and ply in gamemodel.scores and ( (color == BLACK and should_black) or (color == WHITE and should_white)): oldmoves, oldscore, olddepth = gamemodel.scores[ply - 1] oldscore = oldscore * -1 if color == BLACK else oldscore score_str = prettyPrintScore(oldscore, olddepth) moves, score, depth = gamemodel.scores[ply] score = score * -1 if color == WHITE else score diff = score - oldscore if (diff > threshold and color == BLACK) or (diff < -1 * threshold and color == WHITE): if threat_PV: try: if ply - 1 in gamemodel.spy_scores: oldmoves0, oldscore0, olddepth0 = gamemodel.spy_scores[ply - 1] score_str0 = prettyPrintScore(oldscore0, olddepth0) pv0 = listToMoves(gamemodel.boards[ply - 1], ["--"] + oldmoves0, validate=True) if len(pv0) > 2: gamemodel.add_variation(gamemodel.boards[ply - 1], pv0, comment="Treatening", score=score_str0) except ParsingError as e: # ParsingErrors may happen when parsing "old" lines from # analyzing engines, which haven't yet noticed their new tasks log.debug("__parseLine: Ignored (%s) from analyzer: ParsingError%s" % (' '.join(oldmoves), e)) try: pv = listToMoves(gamemodel.boards[ply - 1], oldmoves, validate=True) gamemodel.add_variation(gamemodel.boards[ply - 1], pv, comment="Better is", score=score_str) except ParsingError as e: # ParsingErrors may happen when parsing "old" lines from # analyzing engines, which haven't yet noticed their new tasks log.debug("__parseLine: Ignored (%s) from analyzer: ParsingError%s" % (' '.join(oldmoves), e)) widgets["analyze_game"].hide() widgets["analyze_ok_button"].set_sensitive(True) conf.set("analyzer_check", old_check_value) if threat_PV: conf.set("inv_analyzer_check", old_inv_check_value) message.dismiss()
def coro(): altpath = getEngineDataPrefix() if pgn.scoutfish_path is None and conf.get("download_scoutfish", False): binary = "https://github.com/pychess/scoutfish/releases/download/20170627/%s" % pgn.scoutfish filename = yield from download_file_async(binary) if filename is not None: dest = shutil.move(filename, os.path.join(altpath, pgn.scoutfish)) os.chmod(dest, stat.S_IEXEC | stat.S_IREAD | stat.S_IWRITE) pgn.scoutfish_path = dest if pgn.chess_db_path is None and conf.get("download_chess_db", False): binary = "https://github.com/pychess/chess_db/releases/download/20170627/%s" % pgn.parser filename = yield from download_file_async(binary) if filename is not None: dest = shutil.move(filename, os.path.join(altpath, pgn.parser)) os.chmod(dest, stat.S_IEXEC | stat.S_IREAD | stat.S_IWRITE) pgn.chess_db_path = dest if TimeSeal.timestamp_path is None and conf.get("download_timestamp", False): binary = "https://www.chessclub.com/user/resources/icc/timestamp/%s" % TimeSeal.timestamp filename = yield from download_file_async(binary) if filename is not None: dest = shutil.move(filename, os.path.join(altpath, TimeSeal.timestamp)) os.chmod(dest, stat.S_IEXEC | stat.S_IREAD | stat.S_IWRITE) TimeSeal.timestamp_path = dest
def saveGamePGN(self, game): if game.practice_game: return True if conf.get("saveOwnGames", False) and not game.hasLocalPlayer(): return True filename = conf.get("autoSaveFormat", "pychess") filename = filename.replace("#n1", game.tags["White"]) filename = filename.replace("#n2", game.tags["Black"]) year, month, day = parseDateTag(game.tags["Date"]) year = '' if year is None else str(year) month = '' if month is None else str(month) day = '' if day is None else str(day) filename = filename.replace("#y", "%s" % year) filename = filename.replace("#m", "%s" % month) filename = filename.replace("#d", "%s" % day) pgn_path = conf.get("autoSavePath", os.path.expanduser("~")) + "/" + filename + ".pgn" append = True try: if not os.path.isfile(pgn_path): # create new file with open(pgn_path, "w"): pass base_offset = os.path.getsize(pgn_path) # save to .sqlite database_path = os.path.splitext(pgn_path)[0] + '.sqlite' database.save(database_path, game, base_offset) # save to .scout from pychess.Savers.pgn import scoutfish_path if scoutfish_path is not None: pgn_text = pgn.save(StringIO(), game) tmp = tempfile.NamedTemporaryFile(mode="w", delete=False) pgnfile = tmp.name with tmp.file as f: f.write(pgn_text) # create new .scout from pgnfile we are importing args = [scoutfish_path, "make", pgnfile, "%s" % base_offset] output = subprocess.check_output(args, stderr=subprocess.STDOUT) # append it to our existing one if output.decode().find(u"Processing...done") > 0: old_scout = os.path.splitext(pgn_path)[0] + '.scout' new_scout = os.path.splitext(pgnfile)[0] + '.scout' with open(old_scout, "ab") as file1, open(new_scout, "rb") as file2: file1.write(file2.read()) # TODO: do we realy want to update .bin ? It can be huge/slow! # save to .pgn game.save(pgn_path, pgn, append) return True except IOError: return False
def on_gmwidg_infront (gmwidg): # Set right sensitivity states in menubar, when tab is switched auto = gmwidg.gamemodel.players[0].__type__ != LOCAL and \ gmwidg.gamemodel.players[1].__type__ != LOCAL for item in ACTION_MENU_ITEMS: getWidgets()[item].props.sensitive = not auto for widget in MENU_ITEMS: sensitive = False if widget == 'abort': if isinstance(gmwidg.gamemodel, pychess.ic.ICGameModel.ICGameModel): sensitive = True elif widget == 'adjourn': if isinstance(gmwidg.gamemodel, pychess.ic.ICGameModel.ICGameModel): sensitive = True elif widget == 'hint_mode': if gmwidg.gamemodel.hintEngineSupportsVariant and conf.get("analyzer_check", True): sensitive = True elif widget == 'spy_mode': if gmwidg.gamemodel.spyEngineSupportsVariant and conf.get("inv_analyzer_check", True): sensitive = True elif widget == 'show_sidepanels': if not isDesignGWShown(): sensitive = True else: sensitive = True getWidgets()[widget].set_property('sensitive', sensitive) # Change window title getWidgets()['window1'].set_title('%s - PyChess' % gmwidg.getTabText())
def startClicked(self, button): color = self.widgets["colorDock"].get_child().get_active() if color == 2: color = random.choice([WHITE, BLACK]) opp = self.widgets["opponentDock"].get_child() tree_iter = opp.get_active_iter() if tree_iter is not None: model = opp.get_model() engine = model[tree_iter][1] opponent = self.widgets["opponentDock"].get_child().get_active() difficulty = int(self.widgets["skillSlider"].get_value()) gamemodel = GameModel(TimeModel(5 * 60, 0)) name = conf.get("firstName") player0tup = (LOCAL, Human, (color, name), name) if opponent == 0: name = conf.get("secondName") player1tup = (LOCAL, Human, (1 - color, name), name) else: engine = discoverer.getEngineByName(engine) name = discoverer.getName(engine) player1tup = (ARTIFICIAL, discoverer.initPlayerEngine, (engine, 1 - color, difficulty, variants[NORMALCHESS], 5 * 60, 0), name) perspective = perspective_manager.get_perspective("games") if color == WHITE: create_task(perspective.generalStart(gamemodel, player0tup, player1tup)) else: create_task(perspective.generalStart(gamemodel, player1tup, player0tup))
def init_engine(analyzer_type, gamemodel, force=False): """ Initializes and starts the engine analyzer of analyzer_type the user has configured in the Engines tab of the preferencesDialog, for gamemodel. If no such engine is set in the preferences, or if the configured engine doesn't support the chess variant being played in gamemodel, then no analyzer is started and None is returned. """ if analyzer_type == HINT: combo_name = "ana_combobox" check_name = "analyzer_check" mode = ANALYZING else: combo_name = "inv_ana_combobox" check_name = "inv_analyzer_check" mode = INVERSE_ANALYZING analyzer = None if conf.get(check_name, True): anaengines = list(discoverer.getAnalyzers()) engine = discoverer.getEngineByMd5(conf.get(combo_name, 0)) if engine is None: engine = anaengines[0] if gamemodel.variant.variant in discoverer.getEngineVariants(engine): analyzer = discoverer.initAnalyzerEngine(engine, mode, gamemodel.variant) log.debug("%s analyzer: %s" % (analyzer_type, repr(analyzer))) return analyzer
def __init__ (self, widgets): # Init 'auto save" checkbutton def checkCallBack (*args): checkbox = widgets["autoSave"] widgets["autosave_grid"].set_property("sensitive", checkbox.get_active()) conf.notify_add("autoSave", checkCallBack) widgets["autoSave"].set_active(False) uistuff.keep(widgets["autoSave"], "autoSave") checkCallBack() default_path = os.path.expanduser("~") autoSavePath = conf.get("autoSavePath", default_path) conf.set("autoSavePath", autoSavePath) auto_save_chooser_dialog = Gtk.FileChooserDialog(_("Select auto save path"), None, Gtk.FileChooserAction.SELECT_FOLDER, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) auto_save_chooser_button = Gtk.FileChooserButton.new_with_dialog(auto_save_chooser_dialog) auto_save_chooser_button.set_current_folder(autoSavePath) widgets["savePathChooserDock"].add(auto_save_chooser_button) auto_save_chooser_button.show() def select_auto_save(button): new_directory = auto_save_chooser_dialog.get_filename() if new_directory != autoSavePath: conf.set("autoSavePath", new_directory) auto_save_chooser_button.connect("current-folder-changed", select_auto_save) conf.set("autoSaveFormat", conf.get("autoSaveFormat", "pychess")) uistuff.keep(widgets["autoSaveFormat"], "autoSaveFormat") uistuff.keep(widgets["saveEmt"], "saveEmt") uistuff.keep(widgets["saveEval"], "saveEval") uistuff.keep(widgets["saveOwnGames"], "saveOwnGames")
def __init__(self, widgets): conf.set("firstName", conf.get("firstName", conf.username)) conf.set("secondName", conf.get("secondName", _("Guest"))) # Give to uistuff.keeper for key in ( "firstName", "secondName", "showEmt", "showEval", "hideTabs", "faceToFace", "showCords", "showCaptured", "figuresInNotation", "fullAnimation", "moveAnimation", "noAnimation", ): uistuff.keep(widgets[key], key) # Options on by default for key in ("autoRotate", "fullAnimation", "showBlunder"): uistuff.keep(widgets[key], key, first_value=True)
def __init__(self): self.window = Gtk.Window(Gtk.WindowType.TOPLEVEL, title=_("Ask for permissions")) self.window.set_transient_for(mainwindow()) vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) gtk_version = (Gtk.get_major_version(), Gtk.get_minor_version()) if gtk_version >= (3, 12): vbox.props.margin_start = 9 vbox.props.margin_end = 9 else: vbox.props.margin_left = 9 vbox.props.margin_right = 9 vbox.props.margin_bottom = 9 self.window.add(vbox) uistuff.keepWindowSize("externalsdialog", self.window, (320, 240), uistuff.POSITION_CENTER) label = Gtk.Label(_("Some of PyChess features needs your permission to download external programs")) vbox.pack_start(label, True, True, 0) box = Gtk.Box() check_button = Gtk.CheckButton(_("database querying needs scoutfish")) check_button.set_active(conf.get("download_scoutfish", False)) check_button.connect("toggled", lambda w: conf.set("download_scoutfish", w.get_active())) box.add(check_button) link = "https://github.com/pychess/scoutfish" link_button = Gtk.LinkButton(link, link) box.add(link_button) vbox.pack_start(box, False, False, 0) box = Gtk.Box() check_button = Gtk.CheckButton(_("database opening tree needs chess_db")) check_button.set_active(conf.get("download_chess_db", False)) check_button.connect("toggled", lambda w: conf.set("download_chess_db", w.get_active())) box.add(check_button) link = "https://github.com/pychess/chess_db" link_button = Gtk.LinkButton(link, link) box.add(link_button) vbox.pack_start(box, False, False, 0) box = Gtk.Box() check_button = Gtk.CheckButton(_("ICC lag compensation needs timestamp")) check_button.set_active(conf.get("download_timestamp", False)) check_button.connect("toggled", lambda w: conf.set("download_timestamp", w.get_active())) box.add(check_button) link = "https://www.chessclub.com/user/resources/icc/timestamp" link_button = Gtk.LinkButton(link, link) box.add(link_button) vbox.pack_start(box, False, False, 0) check_button = Gtk.CheckButton(_("Don't show this dialog on startup.")) check_button.set_active(conf.get("dont_show_externals_at_startup", False)) check_button.connect("toggled", lambda w: conf.set("dont_show_externals_at_startup", w.get_active())) vbox.pack_start(check_button, True, True, 0) buttonbox = Gtk.ButtonBox() close_button = Gtk.Button.new_from_stock(Gtk.STOCK_OK) close_button.connect("clicked", self.on_close_clicked) self.window.connect("delete_event", lambda w, a: self.window.destroy()) buttonbox.add(close_button) vbox.pack_start(buttonbox, False, False, 0)
def load(self, gmwidg): __widget__ = Gtk.ScrolledWindow() __widget__.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) __widget__.add(self.textview) self.gamewidget = gmwidg self.boardview = gmwidg.board.view self.boardview.connect("shownChanged", self.shownChanged) self.gamemodel = gmwidg.board.view.model self.gamemodel.connect_after("game_loaded", self.game_loaded) self.gamemodel.connect_after("game_changed", self.game_changed) self.gamemodel.connect_after("game_started", self.update) self.gamemodel.connect_after("game_ended", self.update) self.gamemodel.connect_after("moves_undone", self.moves_undone) self.gamemodel.connect_after("opening_changed", self.update) self.gamemodel.connect_after("players_changed", self.players_changed) self.gamemodel.connect("variation_added", self.variation_added) self.gamemodel.connect("variation_extended", self.variation_extended) self.gamemodel.connect("analysis_changed", self.analysis_changed) # Connect to preferences self.fan = conf.get("figuresInNotation", False) def figuresInNotationCallback(none): self.fan = conf.get("figuresInNotation", False) self.update() conf.notify_add("figuresInNotation", figuresInNotationCallback) # Elapsed move time self.showEmt = conf.get("showEmt", False) def showEmtCallback(none): self.showEmt = conf.get("showEmt", False) self.update() conf.notify_add("showEmt", showEmtCallback) # Blunders self.showBlunder = conf.get("showBlunder", False) def showBlunderCallback(none): self.showBlunder = conf.get("showBlunder", False) self.update() conf.notify_add("showBlunder", showBlunderCallback) # Eval values self.showEval = conf.get("showEval", False) def showEvalCallback(none): self.showEval = conf.get("showEval", False) self.update() conf.notify_add("showEval", showEvalCallback) return __widget__
def setFromConf(): try: v = conf.get(key) except TypeError: log.warning("uistuff.keep.setFromConf: Key '%s' from conf had the wrong type '%s', ignored" % (key, type(conf.get(key)))) # print("uistuff.keep TypeError %s %s" % (key, conf.get(key))) else: set_value(v)
def onResponse(dialog, res): cls.widgets["newgamedialog"].hide() cls.widgets["newgamedialog"].disconnect(handlerId) if res != gtk.RESPONSE_OK: return # Find variant if cls.widgets["playNormalRadio"].get_active(): variant_index = NORMALCHESS elif cls.widgets["playVariant1Radio"].get_active(): variant_index = conf.get("ngvariant1", FISCHERRANDOMCHESS) else: variant_index = conf.get("ngvariant2", LOSERSCHESS) variant = variants[variant_index] # Find time if cls.widgets["notimeRadio"].get_active(): secs = 0 incr = 0 elif cls.widgets["blitzRadio"].get_active(): secs = cls.widgets["ngblitz min"].get_value_as_int()*60 incr = cls.widgets["ngblitz gain"].get_value_as_int() elif cls.widgets["rapidRadio"].get_active(): secs = cls.widgets["ngrapid min"].get_value_as_int()*60 incr = cls.widgets["ngrapid gain"].get_value_as_int() elif cls.widgets["normalRadio"].get_active(): secs = cls.widgets["ngnormal min"].get_value_as_int()*60 incr = cls.widgets["ngnormal gain"].get_value_as_int() # Find players player0 = cls.widgets["whitePlayerCombobox"].get_active() player0 = playerItems[0].index(playerItems[variant_index][player0]) diffi0 = int(cls.widgets["skillSlider1"].get_value()) player1 = cls.widgets["blackPlayerCombobox"].get_active() player1 = playerItems[0].index(playerItems[variant_index][player1]) diffi1 = int(cls.widgets["skillSlider2"].get_value()) # Prepare players for ionest playertups = [] for i, playerno, diffi, color in ((0, player0, diffi0, WHITE), (1, player1, diffi1, BLACK)): if playerno > 0: engine = discoverer.getEngineN (playerno-1) name = discoverer.getName(engine) playertups.append((ARTIFICIAL, discoverer.initPlayerEngine, (engine, color, diffi, variant, secs, incr), name)) else: playertups.append((LOCAL, Human, (color, ""), _("Human"))) if secs > 0: timemodel = TimeModel (secs, incr) else: timemodel = None gamemodel = GameModel (timemodel, variant) callback(gamemodel, playertups[0], playertups[1])
def save(file, model, position=None): status = "%s" % reprResult[model.status] print('[Event "%s"]' % model.tags["Event"], file=file) print('[Site "%s"]' % model.tags["Site"], file=file) print('[Date "%04d.%02d.%02d"]' % (int(model.tags["Year"]), int(model.tags["Month"]), int(model.tags["Day"])), file=file) print('[Round "%s"]' % model.tags["Round"], file=file) print('[White "%s"]' % repr(model.players[WHITE]), file=file) print('[Black "%s"]' % repr(model.players[BLACK]), file=file) print('[Result "%s"]' % status, file=file) if "ECO" in model.tags: print('[ECO "%s"]' % model.tags["ECO"], file=file) if "WhiteElo" in model.tags: print('[WhiteElo "%s"]' % model.tags["WhiteElo"], file=file) if "BlackElo" in model.tags: print('[BlackElo "%s"]' % model.tags["BlackElo"], file=file) if "TimeControl" in model.tags: print('[TimeControl "%s"]' % model.tags["TimeControl"], file=file) if "Time" in model.tags: print('[Time "%s"]' % str(model.tags["Time"]), file=file) if model.timed: print('[WhiteClock "%s"]' % msToClockTimeTag(int(model.timemodel.getPlayerTime(WHITE) * 1000)), file=file) print('[BlackClock "%s"]' % msToClockTimeTag(int(model.timemodel.getPlayerTime(BLACK) * 1000)), file=file) if model.variant.variant != NORMALCHESS: print('[Variant "%s"]' % model.variant.cecp_name.capitalize(), file=file) if model.boards[0].asFen() != FEN_START: print('[SetUp "1"]', file=file) print('[FEN "%s"]' % model.boards[0].asFen(), file=file) print('[PlyCount "%s"]' % (model.ply - model.lowply), file=file) if "EventDate" in model.tags: print('[EventDate "%s"]' % model.tags["EventDate"], file=file) if "Annotator" in model.tags: print('[Annotator "%s"]' % model.tags["Annotator"], file=file) print("", file=file) save_emt = conf.get("saveEmt", False) save_eval = conf.get("saveEval", False) result = [] walk(model.boards[0].board, result, model, save_emt, save_eval) result = " ".join(result) result = wrap(result, 80) print(result, status, file=file) print("", file=file) output = file.getvalue() if isinstance(file, StringIO) else "" file.close() return output
def loadPosition(window): # log.debug("keepWindowSize.loadPosition: %s" % window.title) # Just to make sphinx happy... try: width, height = window.get_size_request() except TypeError: pass if conf.hasKey(key + "_width") and conf.hasKey(key + "_height"): width = conf.get(key + "_width") height = conf.get(key + "_height") log.debug("Resizing window to width=%s height=%s" % (width, height)) window.resize(width, height) elif defaultSize: width, height = defaultSize log.debug("Resizing window to width=%s height=%s" % (width, height)) window.resize(width, height) elif key == "mainwindow": monitor_x, monitor_y, monitor_width, monitor_height = getMonitorBounds() width = int(monitor_width / 2) height = int(monitor_height / 4) * 3 log.debug("Resizing window to width=%s height=%s" % (width, height)) window.resize(width, height) elif key == "preferencesdialogwindow": monitor_x, monitor_y, monitor_width, monitor_height = getMonitorBounds() width = int(monitor_width / 2) height = int(monitor_height / 4) * 3 window.resize(1, 1) else: monitor_x, monitor_y, monitor_width, monitor_height = getMonitorBounds() width = int(monitor_width / 2) height = int(monitor_height / 4) * 3 if conf.hasKey(key + "_x") and conf.hasKey(key + "_y"): x = max(0, conf.get(key + "_x")) y = max(0, conf.get(key + "_y")) log.debug("Moving window to x=%s y=%s" % (x, y)) window.move(x, y) elif defaultPosition in (POSITION_CENTER, POSITION_GOLDEN): monitor_x, monitor_y, monitor_width, monitor_height = getMonitorBounds() x_loc = int(monitor_width / 2 - width / 2) + monitor_x if defaultPosition == POSITION_CENTER: y_loc = int(monitor_height / 2 - height / 2) + monitor_y else: # Place the window on the upper golden ratio line y_loc = int(monitor_height / 2.618 - height / 2) + monitor_y log.debug("Moving window to x=%s y=%s" % (x_loc, y_loc)) window.move(x_loc, y_loc)
def on_ics_combo_changed(self, combo): tree_iter = combo.get_active_iter() if tree_iter is not None: model = combo.get_model() self.ics = model[tree_iter][0] # print("Selected: %s" % self.ics) self.widgets["logOnAsGuest"].set_active(conf.get("asGuestCheck", False, section=self.ics)) self.user_name_set_value(self.widgets["nameEntry"], conf.get("usernameEntry", "", section=self.ics)) self.password_set_value(self.widgets["passEntry"], conf.get("passwordEntry", "", section=self.ics)) default_host = "freechess.org" if self.ics == "FICS" else "chessclub.com" self.host_set_value(self.widgets["hostEntry"], conf.get("hostEntry", default_host, section=self.ics))
def __init__ (self, widgets): conf.set("firstName", conf.get("firstName", conf.username)) conf.set("secondName", conf.get("secondName", _("Guest"))) # Give to uistuff.keeper for key in ("firstName", "secondName", "hideTabs", "autoRotate", "faceToFace", "showCords", "figuresInNotation", "autoCallFlag", "fullAnimation", "moveAnimation", "noAnimation"): uistuff.keep(widgets[key], key)
def setFromConf(): try: v = conf.get(key) except TypeError: log.warning("uistuff.keep.setFromConf: Key '%s' from conf had the wrong type '%s', ignored" % (key, type(conf.get(key)))) if first_value is not None: conf.set(key, first_value) else: conf.set(key, get_value()) else: set_value(v)
def run(no_debug, idle_add_debug, thread_debug, log_viewer, purge_recent, chess_file, ics_host, ics_port): # Start logging if log_viewer: log.logger.addHandler(GLogHandler(logemitter)) log.logger.setLevel(logging.WARNING if no_debug is True else logging.DEBUG) oldlogs = [l for l in os.listdir(getUserDataPrefix()) if l.endswith(".log")] conf.set("max_log_files", conf.get("max_log_files", 10)) oldlogs.sort() l = len(oldlogs) while l > conf.get("max_log_files", 10): try: os.remove(addUserDataPrefix(oldlogs[0])) del oldlogs[0] except OSError: pass l -= 1 if purge_recent: items = recentManager.get_items() for item in items: uri = item.get_uri() if item.get_application_info("pychess"): recentManager.remove_item(uri) signal.signal(signal.SIGINT, Gtk.main_quit) signal.signal(signal.SIGTERM, Gtk.main_quit) def cleanup(): ICLogon.stop() SubProcess.finishAllSubprocesses() atexit.register(cleanup) pychess = PyChess(log_viewer, chess_file) idle_add.debug = idle_add_debug sys.stdout = LogPipe(sys.stdout, "stdout") sys.stderr = LogPipe(sys.stderr, "stdout") log.info("PyChess %s %s git %s" % (VERSION_NAME, VERSION, pychess.git_rev)) log.info("Command line args: '%s'" % chess_file) log.info("Platform: %s" % platform.platform()) log.info("Python version: %s.%s.%s" % sys.version_info[0:3]) log.info("Pyglib version: %s.%s.%s" % GLib.pyglib_version) if thread_debug: start_thread_dump() if ics_host: ICLogon.host = ics_host if ics_port: ICLogon.port = ics_port Gtk.main()
def on_ics_combo_changed(self, combo): tree_iter = combo.get_active_iter() if tree_iter is not None: model = combo.get_model() self.ics = model[tree_iter][0] # print("Selected: %s" % self.ics) self.widgets["logOnAsGuest"].set_active(conf.get("asGuestCheck", section=self.ics)) self.on_logOnAsGuest_toggled(self.widgets["logOnAsGuest"]) self.user_name_set_value(self.widgets["nameEntry"], conf.get("usernameEntry", section=self.ics)) self.password_set_value(self.widgets["passEntry"], conf.get("passwordEntry", section=self.ics)) self.host_set_value(self.widgets["hostEntry"], conf.get("hostEntry", section=self.ics)) self.widgets["timesealCheck"].set_active(conf.get("timesealCheck", section=self.ics)) self.on_timeseal_toggled(self.widgets["timesealCheck"])
def on_quit1_activate(self, widget, *args): if isinstance(widget, Gdk.Event): if len(gameDic) == 1 and conf.get("hideTabs", False): gmwidg = gamewidget.cur_gmwidg() response = ionest.closeGame(gmwidg, gameDic[gmwidg]) return True elif len(gameDic) >= 1 and conf.get("closeAll", False): response = ionest.closeAllGames(gameDic.items()) return True if ionest.closeAllGames(gameDic.items()) in (Gtk.ResponseType.OK, Gtk.ResponseType.YES): Gtk.main_quit() else: return True
def updateCombos(*args): if cls.widgets["playNormalRadio"].get_active(): variant = NORMALCHESS elif cls.widgets["playVariant1Radio"].get_active(): variant = conf.get("ngvariant1", FISCHERRANDOMCHESS) else: variant = conf.get("ngvariant2", LOSERSCHESS) variant1 = conf.get("ngvariant1", FISCHERRANDOMCHESS) cls.widgets["playVariant1Radio"].set_tooltip_text(variants[variant1].__desc__) variant2 = conf.get("ngvariant2", LOSERSCHESS) cls.widgets["playVariant2Radio"].set_tooltip_text(variants[variant2].__desc__) uistuff.updateCombo(cls.widgets["blackPlayerCombobox"], playerItems[variant]) uistuff.updateCombo(cls.widgets["whitePlayerCombobox"], playerItems[variant])
def workfunc (worker, gamemodel, player0tup, player1tup, loaddata=None): log.debug("ionest.workfunc: %s\n %s\n %s\n" % (gamemodel, player0tup, player1tup)) gmwidg = gamewidget.GameWidget(gamemodel) worker.publish((gmwidg,gamemodel)) # Initing players players = [] for i, playertup in enumerate((player0tup, player1tup)): type, func, args, prename = playertup if type != LOCAL: players.append(func(*args)) #if type == ARTIFICIAL: # def readyformoves (player, color): # gmwidg.setTabText(gmwidg.display_text)) # players[i].connect("readyForMoves", readyformoves, i) else: # Until PyChess has a proper profiles system, as discussed on the # issue tracker, we need to give human players special treatment player = func(gmwidg, *args) players.append(player) # Connect to conf if i == 0 or (i == 1 and player0tup[0] != LOCAL): key = "firstName" alt = _("You") else: key = "secondName" alt = _("Guest") if prename == conf.get(key, alt): conf.notify_add(key, lambda *a:player.setName(conf.get(key,alt))) if player0tup[0] == ARTIFICIAL and player1tup[0] == ARTIFICIAL: def emit_action (action, param): if gmwidg.isInFront(): gamemodel.curplayer.emit("offer", Offer(action, param=param)) gmwidg.board.connect("action", lambda b,action,param: emit_action(action, param)) gamemodel.setPlayers(players) # Starting if loaddata: try: uri, loader, gameno, position = loaddata gamemodel.loadAndStart (uri, loader, gameno, position) except LoadingError, e: d = gtk.MessageDialog (type=gtk.MESSAGE_WARNING, buttons=gtk.BUTTONS_OK) d.set_markup ("<big><b>%s</b></big>" % e.args[0]) d.format_secondary_text (e.args[1] + "\n\n" + _("Correct the move, or start playing with what could be read")) d.connect("response", lambda d,a: d.hide()) worker.publish(d.show)
def updateCombos(*args): if cls.widgets["playNormalRadio"].get_active(): variant = NORMALCHESS elif cls.widgets["playVariant1Radio"].get_active(): variant = conf.get("ngvariant1") else: variant = conf.get("ngvariant2") variant1 = conf.get("ngvariant1") cls.widgets["playVariant1Radio"].set_tooltip_text(variants[variant1].__desc__) variant2 = conf.get("ngvariant2") cls.widgets["playVariant2Radio"].set_tooltip_text(variants[variant2].__desc__) data = [(item[0], item[1]) for item in playerItems[variant]] uistuff.updateCombo(cls.widgets["blackPlayerCombobox"], data) uistuff.updateCombo(cls.widgets["whitePlayerCombobox"], data)
def __init__(self, widgets): # Init 'auto save" checkbutton def checkCallBack(_): """ :Description: Sets the various option based on user interaction with the checkboxes in the gui """ checkbox = widgets["autoSave"] widgets["autosave_grid"].set_property("sensitive", checkbox.get_active()) conf.notify_add("autoSave", checkCallBack) widgets["autoSave"].set_active(False) uistuff.keep(widgets["autoSave"], "autoSave") checkCallBack(_) default_path = os.path.expanduser("~") self.auto_save_path = conf.get("autoSavePath", default_path) conf.set("autoSavePath", self.auto_save_path) auto_save_chooser_dialog = Gtk.FileChooserDialog( _("Select auto save path"), None, Gtk.FileChooserAction.SELECT_FOLDER, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) auto_save_chooser_button = Gtk.FileChooserButton.new_with_dialog( auto_save_chooser_dialog) auto_save_chooser_button.set_current_folder(self.auto_save_path) widgets["savePathChooserDock"].add(auto_save_chooser_button) auto_save_chooser_button.show() def selectAutoSave(_): """ :Description: Sets the auto save path for stored games if it has changed since last time :signal: Activated on receiving the 'current-folder-changed' signal """ new_directory = auto_save_chooser_dialog.get_filename() if new_directory != self.auto_save_path: conf.set("autoSavePath", new_directory) auto_save_chooser_button.connect("current-folder-changed", selectAutoSave) conf.set("autoSaveFormat", conf.get("autoSaveFormat", "pychess")) uistuff.keep(widgets["autoSaveFormat"], "autoSaveFormat") uistuff.keep(widgets["saveEmt"], "saveEmt") uistuff.keep(widgets["saveEval"], "saveEval") uistuff.keep(widgets["saveOwnGames"], "saveOwnGames")
def init_layout(self): perspective_widget = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) perspective_manager.set_perspective_widget("games", perspective_widget) self.notebooks = { "board": new_notebook("board"), "buttons": new_notebook("buttons"), "messageArea": new_notebook("messageArea") } self.main_notebook = self.notebooks["board"] for panel in self.sidePanels: self.notebooks[panel.__name__] = new_notebook(panel.__name__) # Initing headbook align = gamewidget.createAlignment(4, 4, 0, 4) align.set_property("yscale", 0) headbook = Gtk.Notebook() headbook.set_name("headbook") headbook.set_scrollable(True) align.add(headbook) perspective_widget.pack_start(align, False, True, 0) self.show_tabs(not conf.get("hideTabs", False)) # Initing center centerVBox = Gtk.VBox() # The dock self.dock = PyDockTop("main", self) self.dockAlign = gamewidget.createAlignment(4, 4, 0, 4) self.dockAlign.add(self.dock) centerVBox.pack_start(self.dockAlign, True, True, 0) self.dockAlign.show() self.dock.show() self.docks["board"] = (Gtk.Label(label="Board"), self.notebooks["board"], None) for panel in self.sidePanels: self.docks[panel.__name__][1] = self.notebooks[panel.__name__] self.load_from_xml() # Default layout of side panels if not os.path.isfile(self.dockLocation): leaf = self.dock.dock(self.docks["board"][1], CENTER, Gtk.Label(label=self.docks["board"][0]), "board") self.docks["board"][1].show_all() leaf.setDockable(False) # S epanel = leaf.dock(self.docks["bookPanel"][1], SOUTH, self.docks["bookPanel"][0], "bookPanel") epanel.default_item_height = 45 epanel = epanel.dock(self.docks["engineOutputPanel"][1], CENTER, self.docks["engineOutputPanel"][0], "engineOutputPanel") # NE leaf = leaf.dock(self.docks["annotationPanel"][1], EAST, self.docks["annotationPanel"][0], "annotationPanel") leaf = leaf.dock(self.docks["historyPanel"][1], CENTER, self.docks["historyPanel"][0], "historyPanel") leaf = leaf.dock(self.docks["scorePanel"][1], CENTER, self.docks["scorePanel"][0], "scorePanel") # SE leaf = leaf.dock(self.docks["chatPanel"][1], SOUTH, self.docks["chatPanel"][0], "chatPanel") leaf = leaf.dock(self.docks["commentPanel"][1], CENTER, self.docks["commentPanel"][0], "commentPanel") def unrealize(dock, notebooks): # unhide the panel before saving so its configuration is saved correctly self.notebooks["board"].get_parent().get_parent().zoomDown() dock.saveToXML(self.dockLocation) dock._del() self.dock.connect("unrealize", unrealize, self.notebooks) hbox = Gtk.HBox() # Buttons self.notebooks["buttons"].set_border_width(4) hbox.pack_start(self.notebooks["buttons"], False, True, 0) # The message area # TODO: If you try to fix this first read issue #958 and 1018 align = gamewidget.createAlignment(0, 0, 0, 0) # sw = Gtk.ScrolledWindow() # port = Gtk.Viewport() # port.add(self.notebooks["messageArea"]) # sw.add(port) # align.add(sw) align.add(self.notebooks["messageArea"]) hbox.pack_start(align, True, True, 0) def ma_switch_page(notebook, gpointer, page_num): notebook.props.visible = notebook.get_nth_page(page_num).\ get_child().props.visible self.notebooks["messageArea"].connect("switch-page", ma_switch_page) centerVBox.pack_start(hbox, False, True, 0) perspective_widget.pack_start(centerVBox, True, True, 0) centerVBox.show_all() perspective_widget.show_all() perspective_manager.set_perspective_menuitems("games", self.menuitems) conf.notify_add("hideTabs", self.tabsCallback) # Connecting headbook to other notebooks def hb_switch_page(notebook, gpointer, page_num): for notebook in self.notebooks.values(): notebook.set_current_page(page_num) gmwidg = self.key2gmwidg[self.getheadbook().get_nth_page(page_num)] if isinstance(gmwidg.gamemodel, ICGameModel): primary = "primary " + str(gmwidg.gamemodel.ficsgame.gameno) gmwidg.gamemodel.connection.client.run_command(primary) headbook.connect("switch-page", hb_switch_page) if hasattr(headbook, "set_tab_reorderable"): def page_reordered(widget, child, new_num, headbook): old_num = self.notebooks["board"].page_num( self.key2gmwidg[child].boardvbox) if old_num == -1: log.error('Games and labels are out of sync!') else: for notebook in self.notebooks.values(): notebook.reorder_child(notebook.get_nth_page(old_num), new_num) headbook.connect("page-reordered", page_reordered, headbook)
def tabsCallback(self, widget): head = self.getheadbook() if not head: return if head.get_n_pages() == 1: self.show_tabs(not conf.get("hideTabs", False))
def __init__(self, widgets): self.widgets = widgets # Options on by default for key in ("opening_check", "endgame_check", "online_egtb_check", "inv_analyzer_check"): uistuff.keep(widgets[key], key, first_value=False) uistuff.keep(widgets["analyzer_check"], "analyzer_check", first_value=True) # Opening book default_path = os.path.join(addDataPrefix("pychess_book.bin")) path = conf.get("opening_file_entry", default_path) conf.set("opening_file_entry", path) book_chooser_dialog = Gtk.FileChooserDialog( _("Select book file"), mainwindow(), Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) book_chooser_button = Gtk.FileChooserButton.new_with_dialog( book_chooser_dialog) filter = Gtk.FileFilter() filter.set_name(_("Opening books")) filter.add_pattern("*.bin") book_chooser_dialog.add_filter(filter) book_chooser_button.set_filename(path) self.widgets["bookChooserDock"].add(book_chooser_button) book_chooser_button.show() def select_new_book(button): new_book = book_chooser_dialog.get_filename() if new_book: conf.set("opening_file_entry", new_book) else: # restore the original book_chooser_dialog.set_filename(path) book_chooser_button.connect("file-set", select_new_book) def on_opening_check_toggled(check): self.widgets["opening_hbox"].set_sensitive(check.get_active()) self.widgets["opening_check"].connect_after("toggled", on_opening_check_toggled) # Endgame default_path = os.path.join(getDataPrefix()) egtb_path = conf.get("egtb_path", default_path) conf.set("egtb_path", egtb_path) egtb_chooser_dialog = Gtk.FileChooserDialog( _("Select Gaviota TB path"), mainwindow(), Gtk.FileChooserAction.SELECT_FOLDER, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) egtb_chooser_button = Gtk.FileChooserButton.new_with_dialog( egtb_chooser_dialog) egtb_chooser_button.set_current_folder(egtb_path) self.widgets["egtbChooserDock"].add(egtb_chooser_button) egtb_chooser_button.show() def select_egtb(button): new_directory = egtb_chooser_dialog.get_filename() if new_directory != egtb_path: conf.set("egtb_path", new_directory) egtb_chooser_button.connect("current-folder-changed", select_egtb) def on_endgame_check_toggled(check): self.widgets["endgame_hbox"].set_sensitive(check.get_active()) self.widgets["endgame_check"].connect_after("toggled", on_endgame_check_toggled) # Analyzing engines from pychess.widgets import newGameDialog data = [(item[0], item[1]) for item in newGameDialog.analyzerItems] uistuff.createCombo(widgets["ana_combobox"], data, name="ana_combobox") uistuff.createCombo(widgets["inv_ana_combobox"], data, name="inv_ana_combobox") def update_analyzers_store(discoverer): data = [(item[0], item[1]) for item in newGameDialog.analyzerItems] uistuff.updateCombo(widgets["ana_combobox"], data) uistuff.updateCombo(widgets["inv_ana_combobox"], data) discoverer.connect_after("all_engines_discovered", update_analyzers_store) update_analyzers_store(discoverer) # Save, load and make analyze combos active engine = discoverer.getEngineByName(discoverer.getEngineLearn()) if engine is None: engine = discoverer.getEngineN(-1) default = engine.get("md5") conf.set("ana_combobox", conf.get("ana_combobox", default)) conf.set("inv_ana_combobox", conf.get("inv_ana_combobox", default)) def on_analyzer_check_toggled(check): self.widgets["analyzers_vbox"].set_sensitive(check.get_active()) from pychess.widgets.gamewidget import widgets perspective = perspective_manager.get_perspective("games") if len(perspective.gamewidgets) != 0: if check.get_active(): for gmwidg in perspective.gamewidgets: asyncio. async ( gmwidg.gamemodel.restart_analyzer(HINT)) if not widgets["hint_mode"].get_active(): gmwidg.gamemodel.pause_analyzer(HINT) else: for gmwidg in perspective.gamewidgets: gmwidg.gamemodel.remove_analyzer(HINT) self.widgets["analyzers_vbox"].set_sensitive( widgets["analyzer_check"].get_active()) self.widgets["analyzer_check"].connect_after( "toggled", on_analyzer_check_toggled) def on_invanalyzer_check_toggled(check): self.widgets["inv_analyzers_vbox"].set_sensitive( check.get_active()) perspective = perspective_manager.get_perspective("games") if len(perspective.gamewidgets) != 0: if check.get_active(): for gmwidg in perspective.gamewidgets: asyncio. async (gmwidg.gamemodel.restart_analyzer(SPY)) if not widgets["spy_mode"].get_active(): gmwidg.gamemodel.pause_analyzer(SPY) else: for gmwidg in perspective.gamewidgets: gmwidg.gamemodel.remove_analyzer(SPY) self.widgets["inv_analyzers_vbox"].set_sensitive( widgets["inv_analyzer_check"].get_active()) self.widgets["inv_analyzer_check"].connect_after( "toggled", on_invanalyzer_check_toggled) # Give widgets to keeper uistuff.keep( self.widgets["ana_combobox"], "ana_combobox", anal_combo_get_value, lambda combobox, value: anal_combo_set_value( combobox, value, "hint_mode", "analyzer_check", HINT)) uistuff.keep( self.widgets["inv_ana_combobox"], "inv_ana_combobox", anal_combo_get_value, lambda combobox, value: anal_combo_set_value( combobox, value, "spy_mode", "inv_analyzer_check", SPY)) uistuff.keep(self.widgets["max_analysis_spin"], "max_analysis_spin", first_value=3) uistuff.keep(self.widgets["infinite_analysis"], "infinite_analysis", first_value=False)
def closeAllGames(self, gamewidgets): log.debug("Games.closeAllGames") response = None changedPairs = [(gmwidg, gmwidg.gamemodel) for gmwidg in gamewidgets if gmwidg.gamemodel.isChanged()] if len(changedPairs) == 0: response = Gtk.ResponseType.OK elif len(changedPairs) == 1: response = self.closeGame(changedPairs[0][0]) else: markup = "<big><b>" + ngettext("There is %d game with unsaved moves.", "There are %d games with unsaved moves.", len(changedPairs)) % len(changedPairs) + " " + \ _("Save moves before closing?") + "</b></big>" for gmwidg, game in changedPairs: if not gmwidg.gamemodel.isChanged(): response = Gtk.ResponseType.OK else: if conf.get("autoSave", False): x = self.saveGamePGN(game) if x: response = Gtk.ResponseType.OK else: response = None markup = "<b><big>" + _( "Unable to save to configured file. \ Save the games before closing?" ) + "</big></b>" break if response is None: widgets = GladeWidgets("saveGamesDialog.glade") dialog = widgets["saveGamesDialog"] heading = widgets["saveGamesDialogHeading"] saveLabel = widgets["saveGamesDialogSaveLabel"] treeview = widgets["saveGamesDialogTreeview"] heading.set_markup(markup) liststore = Gtk.ListStore(bool, str) treeview.set_model(liststore) renderer = Gtk.CellRendererToggle() renderer.props.activatable = True treeview.append_column( Gtk.TreeViewColumn("", renderer, active=0)) treeview.append_column( Gtk.TreeViewColumn("", Gtk.CellRendererText(), text=1)) for gmwidg, game in changedPairs: liststore.append( (True, "%s %s %s" % (game.players[0], _("vs."), game.players[1]))) def callback(cell, path): if path: liststore[path][0] = not liststore[path][0] saves = len(tuple(row for row in liststore if row[0])) saveLabel.set_text( ngettext("_Save %d document", "_Save %d documents", saves) % saves) saveLabel.set_use_underline(True) renderer.connect("toggled", callback) callback(None, None) while True: response = dialog.run() if response == Gtk.ResponseType.YES: for i in range(len(liststore) - 1, -1, -1): checked, name = liststore[i] if checked: cgmwidg, cgame = changedPairs[i] if self.saveGame( cgame) == Gtk.ResponseType.ACCEPT: liststore.remove(liststore.get_iter((i, ))) del changedPairs[i] if cgame.status in UNFINISHED_STATES: cgame.end(ABORTED, ABORTED_AGREEMENT) cgame.terminate() self.delGameWidget(cgmwidg) else: break else: break else: break dialog.destroy() if response not in (Gtk.ResponseType.DELETE_EVENT, Gtk.ResponseType.CANCEL): pairs = [(gmwidg, gmwidg.gamemodel) for gmwidg in gamewidgets] for gmwidg, game in pairs: if game.status in UNFINISHED_STATES: game.end(ABORTED, ABORTED_AGREEMENT) game.terminate() if gmwidg.notebookKey in self.key2gmwidg: self.delGameWidget(gmwidg) return response
def saveGamePGN(self, game): if conf.get("saveOwnGames") and not game.hasLocalPlayer(): return True filename = conf.get("autoSaveFormat") filename = filename.replace("#n1", game.tags["White"]) filename = filename.replace("#n2", game.tags["Black"]) year, month, day = parseDateTag(game.tags["Date"]) year = '' if year is None else str(year) month = '' if month is None else str(month) day = '' if day is None else str(day) filename = filename.replace("#y", "%s" % year) filename = filename.replace("#m", "%s" % month) filename = filename.replace("#d", "%s" % day) pgn_path = conf.get("autoSavePath") + "/" + filename + ".pgn" append = True try: if not os.path.isfile(pgn_path): # create new file with open(pgn_path, "w"): pass base_offset = os.path.getsize(pgn_path) # save to .sqlite database_path = os.path.splitext(pgn_path)[0] + '.sqlite' database.save(database_path, game, base_offset) # save to .scout from pychess.Savers.pgn import scoutfish_path if scoutfish_path is not None: pgn_text = pgn.save(StringIO(), game) tmp = tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", delete=False) pgnfile = tmp.name with tmp.file as f: f.write(pgn_text) # create new .scout from pgnfile we are importing args = [scoutfish_path, "make", pgnfile, "%s" % base_offset] output = subprocess.check_output(args, stderr=subprocess.STDOUT) # append it to our existing one if output.decode().find(u"Processing...done") > 0: old_scout = os.path.splitext(pgn_path)[0] + '.scout' new_scout = os.path.splitext(pgnfile)[0] + '.scout' with open(old_scout, "ab") as file1, open(new_scout, "rb") as file2: file1.write(file2.read()) # TODO: do we realy want to update .bin ? It can be huge/slow! # save to .pgn game.save(pgn_path, pgn, append) return True except IOError: return False
def showBlunderCallback(none): self.showBlunder = conf.get("showBlunder", False) self.update()
def load(self, gmwidg): self.gmwidg = gmwidg self.boardcontrol = gmwidg.board self.boardview = gmwidg.board.view self.figuresInNotation = conf.get("figuresInNotation") self.sw = Gtk.ScrolledWindow() self.tv = Gtk.TreeView() self.tv.set_property("headers_visible", False) self.sw.add(self.tv) self.sw.show_all() self.store = Gtk.TreeStore(GObject.TYPE_PYOBJECT, GObject.TYPE_PYOBJECT, int, bool, str, bool, bool) self.tv.set_model(self.store) # ## move suggested moveRenderer = Gtk.CellRendererText() moveRenderer.set_property("xalign", 1.0) moveRenderer.set_property("yalign", 0) c0 = Gtk.TreeViewColumn("Move", moveRenderer) def getMoveText(column, cell, store, iter, data): board, move, pv = store[iter][0] if not move: cell.set_property("text", "") else: if self.figuresInNotation: cell.set_property("text", toFAN(board, move)) else: cell.set_property("text", toSAN(board, move, True)) c0.set_cell_data_func(moveRenderer, getMoveText) # ## strength of the move c1 = Gtk.TreeViewColumn("Strength", StrengthCellRenderer(), data=1) # ## multipv (number of analysis lines) self.multipvRenderer = Gtk.CellRendererSpin() adjustment = Gtk.Adjustment(value=1, lower=1, upper=9, step_increment=1) self.multipvRenderer.set_property("adjustment", adjustment) self.multipvRenderer.set_property("editable", True) self.multipvRenderer.set_property("width_chars", 1) c2 = Gtk.TreeViewColumn("PV", self.multipvRenderer, editable=3) c2.set_property("min_width", 80) def spin_visible(column, cell, store, iter, data): if store[iter][2] == 0: cell.set_property('visible', False) else: cell.set_property("text", str(store[iter][2])) cell.set_property('visible', True) c2.set_cell_data_func(self.multipvRenderer, spin_visible) def multipv_edited(renderer, path, text): iter = self.store.get_iter(path) self.store.set_value( iter, 2, self.advisors[int( path[0])].multipv_edited(1 if text == "" else int(text))) self.multipv_cid = self.multipvRenderer.connect( 'edited', multipv_edited) # ## start/stop button for analysis engines self.toggleRenderer = CellRendererPixbufXt() self.toggleRenderer.set_property("stock-id", "gtk-add") c4 = Gtk.TreeViewColumn("StartStop", self.toggleRenderer) self.play_image = get_pixbuf("glade/play.png") self.pause_image = get_pixbuf("glade/pause.png") def cb_visible(column, cell, store, iter, data): if not store[iter][6]: cell.set_property('visible', False) else: cell.set_property('visible', True) if store[iter][5]: cell.set_property("pixbuf", self.play_image) else: cell.set_property("pixbuf", self.pause_image) c4.set_cell_data_func(self.toggleRenderer, cb_visible) def toggled_cb(cell, path): self.store[path][5] = not self.store[path][5] self.advisors[int(path[0])].start_stop(self.store[path][5]) self.toggle_cid = self.toggleRenderer.connect('clicked', toggled_cb) self.tv.append_column(c4) self.tv.append_column(c0) self.tv.append_column(c1) self.tv.append_column(c2) # ## header text, or analysis line uistuff.appendAutowrapColumn(self.tv, "Details", text=4) self.cid = self.boardview.connect("shownChanged", self.shownChanged) self.tv_cids = [ self.tv.connect("cursor_changed", self.selection_changed), self.tv.connect("select_cursor_row", self.selection_changed), self.tv.connect("row-activated", self.row_activated), self.tv.connect("query-tooltip", self.query_tooltip), ] self.tv.props.has_tooltip = True self.tv.set_property("show-expanders", False) self.advisors = [] self.conf_conids = [] if conf.get("opening_check"): advisor = OpeningAdvisor(self.store, self.tv, self.boardcontrol) self.advisors.append(advisor) if conf.get("endgame_check"): advisor = EndgameAdvisor(self.store, self.tv, self.boardcontrol) self.advisors.append(advisor) self.model_cids = [ gmwidg.gamemodel.connect("analyzer_added", self.on_analyzer_added), gmwidg.gamemodel.connect("analyzer_removed", self.on_analyzer_removed), gmwidg.gamemodel.connect_after("game_terminated", self.on_game_terminated), ] def on_opening_check(none): if conf.get("opening_check") and self.boardview is not None: advisor = OpeningAdvisor(self.store, self.tv, self.boardcontrol) self.advisors.append(advisor) advisor.shownChanged(self.boardview, self.boardview.shown) else: for advisor in self.advisors: if advisor.mode == OPENING: parent = advisor.empty_parent() self.store.remove(parent) self.advisors.remove(advisor) self.conf_conids.append( conf.notify_add("opening_check", on_opening_check)) def on_opening_file_entry_changed(none): path = conf.get("opening_file_entry") if os.path.isfile(path): for advisor in self.advisors: if advisor.mode == OPENING and self.boardview is not None: advisor.shownChanged(self.boardview, self.boardview.shown) self.conf_conids.append( conf.notify_add("opening_file_entry", on_opening_file_entry_changed)) def on_endgame_check(none): if conf.get("endgame_check"): advisor = EndgameAdvisor(self.store, self.tv, self.boardcontrol) self.advisors.append(advisor) advisor.shownChanged(self.boardview, self.boardview.shown) else: for advisor in self.advisors: if advisor.mode == ENDGAME: advisor._del() parent = advisor.empty_parent() self.store.remove(parent) self.advisors.remove(advisor) self.conf_conids.append( conf.notify_add("endgame_check", on_endgame_check)) def on_figures_in_notation(none): self.figuresInNotation = conf.get("figuresInNotation") self.conf_conids.append( conf.notify_add("figuresInNotation", on_figures_in_notation)) return self.sw
def showEvalCallback(none): self.showEval = conf.get( "showEval", False) and not self.gamemodel.isPlayingICSGame() self.update()
def showBlunderCallback(none): self.showBlunder = conf.get( "showBlunder", False) and not self.gamemodel.isPlayingICSGame() self.update()
def showEmtCallback(none): self.showEmt = conf.get("showEmt", False) self.update()
def figuresInNotationCallback(none): self.fan = conf.get("figuresInNotation", False) self.update()
def game_ended(self, gamemodel, reason, gmwidg): log.debug("gamenanny.game_ended: reason=%s gmwidg=%s\ngamemodel=%s" % (reason, gmwidg, gamemodel)) nameDic = { "white": gamemodel.players[WHITE], "black": gamemodel.players[BLACK], "mover": gamemodel.curplayer } if gamemodel.status == WHITEWON: nameDic["winner"] = gamemodel.players[WHITE] nameDic["loser"] = gamemodel.players[BLACK] elif gamemodel.status == BLACKWON: nameDic["winner"] = gamemodel.players[BLACK] nameDic["loser"] = gamemodel.players[WHITE] msg_one = reprResult_long[gamemodel.status] % nameDic msg_two = reprReason_long[reason] % nameDic if gamemodel.reason == WON_ADJUDICATION: color = BLACK if gamemodel.status == WHITEWON else WHITE invalid_move = gamemodel.players[color].invalid_move if invalid_move: msg_two += _(" invalid engine move: %s" % invalid_move) content = InfoBar.get_message_content(msg_one, msg_two, Gtk.STOCK_DIALOG_INFO) message = InfoBarMessage(Gtk.MessageType.INFO, content, None) callback = None if isinstance(gamemodel, ICGameModel): if gamemodel.hasLocalPlayer() and not gamemodel.examined: def status_changed(player, prop, message): make_sensitive_if_available(message.buttons[0], player) make_sensitive_if_playing(message.buttons[1], player) def callback(infobar, response, message, gamemodel=gamemodel): if response == 0: gamemodel.remote_player.offerRematch() elif response == 1: gamemodel.remote_player.observe() return False gmwidg.cids[gamemodel.remote_ficsplayer] = \ gamemodel.remote_ficsplayer.connect("notify::status", status_changed, message) message.add_button(InfoBarMessageButton(_("Offer Rematch"), 0)) message.add_button( InfoBarMessageButton( _("Observe %s" % gamemodel.remote_ficsplayer.name), 1)) status_changed(gamemodel.remote_ficsplayer, None, message) else: def status_changed(player, prop, button): make_sensitive_if_playing(button, player) def callback(infobar, response, message, gamemodel=gamemodel): if response in (0, 1): gamemodel.players[response].observe() return False for i, player in enumerate(gamemodel.ficsplayers): button = InfoBarMessageButton( _("Observe %s" % player.name), i) message.add_button(button) gmwidg.cids[player] = player.connect( "notify::status", status_changed, button) status_changed(player, None, button) elif gamemodel.hasLocalPlayer(): def callback(infobar, response, message, gamemodel=gamemodel): if response == 1: # newGameDialog uses ionest uses gamenanny uses newGameDialog... from pychess.widgets.newGameDialog import createRematch createRematch(gamemodel) elif response == 2: if gamemodel.ply > 1: offer = Offer(TAKEBACK_OFFER, gamemodel.ply - 2) else: offer = Offer(TAKEBACK_OFFER, gamemodel.ply - 1) if gamemodel.players[0].__type__ == LOCAL: gamemodel.players[0].emit("offer", offer) else: gamemodel.players[1].emit("offer", offer) return False if not gamemodel.isLoadedGame(): message.add_button(InfoBarMessageButton(_("Play Rematch"), 1)) if gamemodel.status in UNDOABLE_STATES and gamemodel.reason in UNDOABLE_REASONS: if gamemodel.ply == 1: message.add_button( InfoBarMessageButton(_("Undo one move"), 2)) elif gamemodel.ply > 1: message.add_button( InfoBarMessageButton(_("Undo two moves"), 2)) message.callback = callback gmwidg.game_ended_message = message if len(key2gmwidg) > 0: gmwidg.replaceMessages(message) if reason == WHITE_ENGINE_DIED: self.engineDead(gamemodel.players[0], gmwidg) elif reason == BLACK_ENGINE_DIED: self.engineDead(gamemodel.players[1], gmwidg) if (isinstance(gamemodel, ICGameModel) and not gamemodel.isObservationGame()) or \ gamemodel.isEngine2EngineGame(): gamemodel.restart_analyzer(HINT) gamemodel.restart_analyzer(SPY) if not conf.get("hint_mode", False): gamemodel.pause_analyzer(HINT) if not conf.get("spy_mode", False): gamemodel.pause_analyzer(SPY) return False
def autoFlagNotify(self, *args): self.connection.client.run_command( "set autoflag %s" % int(conf.get('autoCallFlag', False)))
def load(self, widgets, connection, lounge): self.widgets = widgets self.connection = connection self.lounge = lounge __widget__ = lounge.players_list self.players = {} self.columns = {TYPE_BLITZ: 3, TYPE_STANDARD: 4, TYPE_LIGHTNING: 5} self.tv = widgets["playertreeview"] self.store = Gtk.ListStore(FICSPlayer, GdkPixbuf.Pixbuf, str, int, int, int, str, str) self.player_filter = self.store.filter_new() self.player_filter.set_visible_func(self.player_filter_func) self.filter_toggles = {} self.filter_buttons = ("registered_toggle", "guest_toggle", "computer_toggle", "titled_toggle") for widget in self.filter_buttons: uistuff.keep(self.widgets[widget], widget) self.widgets[widget].connect("toggled", self.on_filter_button_toggled) initial = conf.get(widget, True) self.filter_toggles[widget] = initial self.widgets[widget].set_active(initial) self.model = self.player_filter.sort_new_with_model() self.tv.set_model(self.model) self.addColumns(self.tv, "FICSPlayer", "", _("Name"), _("Blitz"), _("Standard"), _("Lightning"), _("Status"), "tooltip", hide=[0, 7], pix=[1]) self.tv.set_tooltip_column(7, ) self.tv.get_model().set_sort_func(0, self.pixCompareFunction, 1) try: self.tv.set_search_position_func(self.lowLeftSearchPosFunc, None) except AttributeError: # Unknow signal name is raised by gtk < 2.10 pass connection.players.connect("FICSPlayerEntered", self.onPlayerAdded) connection.players.connect("FICSPlayerExited", self.onPlayerRemoved) widgets["private_chat_button"].connect("clicked", self.on_chat) widgets["private_chat_button"].set_sensitive(False) widgets["observe_button"].connect("clicked", self.on_observe) widgets["observe_button"].set_sensitive(False) self.tv.get_selection().connect_after("changed", self.onSelectionChanged) self.onSelectionChanged(None) self.tv.connect('button-press-event', self.button_press_event) self.createLocalMenu( (CHALLENGE, CHAT, OBSERVE, FOLLOW, SEPARATOR, FINGER, ARCHIVED)) return __widget__
def on_figures_in_notation(none): self.figuresInNotation = conf.get("figuresInNotation")
def set_name(none, player, key, alt): player.setName(conf.get(key, alt))
def showEvalCallback(none): self.showEval = conf.get("showEval", False) self.update()
def initGlade(self, log_viewer): # Init glade and the 'GladeHandlers' self.widgets = widgets = uistuff.GladeWidgets("PyChess.glade") self.glade_handlers = GladeHandlers(self) widgets.getGlade().connect_signals(self.glade_handlers) self.window = widgets["main_window"] # new_game_tasker, internet_game_tasker = NewGameTasker( # ), InternetGameTasker() # tasker.packTaskers(new_game_tasker, internet_game_tasker) # widgets["Background"].add(tasker) # Redirect widgets gamewidget.setWidgets(widgets) # The only menuitems that need special initing for widget in ("hint_mode", "spy_mode"): widgets[widget].set_sensitive(False) uistuff.keep(widgets["hint_mode"], "hint_mode") uistuff.keep(widgets["spy_mode"], "spy_mode") uistuff.keep(widgets["show_sidepanels"], "show_sidepanels") uistuff.keep(widgets["auto_call_flag"], "autoCallFlag") # Show main window and init d'n'd widgets["main_window"].set_title('%s - PyChess' % _('Welcome')) widgets["main_window"].connect("delete-event", self.glade_handlers.on_quit1_activate) widgets["main_window"].connect("key-press-event", self.glade_handlers.on_window_key_press) uistuff.keepWindowSize("main", widgets["main_window"], None, uistuff.POSITION_GOLDEN) # To get drag in the whole window, we add it to the menu and the # background. If it can be gotten to work, the drag_dest_set_proxy # method is very interesting. widgets["menubar1"].drag_dest_set(Gtk.DestDefaults.ALL, DND_LIST, DRAG_ACTION) widgets["box2"].drag_dest_set(Gtk.DestDefaults.ALL, DND_LIST, DRAG_ACTION) widgets["perspectives_notebook"].drag_dest_set(Gtk.DestDefaults.ALL, DND_LIST, DRAG_ACTION) # Init 'minor' dialogs # Log dialog if log_viewer: from pychess.widgets import LogDialog LogDialog.add_destroy_notify( lambda: widgets["log_viewer1"].set_active(0)) else: widgets["log_viewer1"].set_property('sensitive', False) # About dialog self.aboutdialog = widgets["aboutdialog1"] self.aboutdialog.set_program_name(NAME) self.aboutdialog.set_copyright("Copyright © 2006-2019") self.aboutdialog.set_version(VERSION_NAME + " " + VERSION) if os.path.isdir(prefix.addDataPrefix(".git")): try: self.git_rev = subprocess.check_output(["git", "describe", "--tags"]).decode().strip() self.aboutdialog.set_version('%s Git %s' % (VERSION_NAME, self.git_rev)) except subprocess.CalledProcessError: pass self.aboutdialog.set_comments(self.aboutdialog.get_comments()) with open(prefix.addDataPrefix("ARTISTS"), encoding="utf-8") as f: self.aboutdialog.set_artists(f.read().splitlines()) with open(prefix.addDataPrefix("AUTHORS"), encoding="utf-8") as f: self.aboutdialog.set_authors(f.read().splitlines()) with open(prefix.addDataPrefix("DOCUMENTERS"), encoding="utf-8") as f: self.aboutdialog.set_documenters(f.read().splitlines()) with open(prefix.addDataPrefix("TRANSLATORS"), encoding="utf-8") as f: self.aboutdialog.set_translator_credits(f.read()) with open(prefix.addDataPrefix("LICENSE"), encoding="utf-8") as f: self.aboutdialog.set_license(f.read()) widgets["load_recent_game1"].set_submenu(recent_menu) if conf.get("autoLogin"): internet_game_tasker.connectClicked(None)
def fetch_chess_conf(self): self.plot.linear_scale = conf.get("scoreLinearScale")
def scoreAllMoves(self, board, probeSoft=False): global URL, expression, PROMOTION_FLAGS fen = board.asFen().split()[0] + " w - - 0 1" if (fen, board.color) in self.table: return self.table[(fen, board.color)] if probeSoft or not conf.get("online_egtb_check"): return [] def get_data(URL, fen): # Request the page url = (URL + fen).replace(" ", "%20") try: f = urlopen(url) except IOError as e: log.warning( "Unable to read endgame tablebase from the Internet: %s" % repr(e)) data = b"" data = f.read() return data loop = asyncio.get_event_loop() future = loop.run_in_executor(None, get_data, URL, fen) data = yield from future # Parse for color, move_data in enumerate(data.split(b"\nNEXTCOLOR\n")): try: moves = [] for fcord, tcord, promotion, result in expression.findall( move_data.decode()): fcord = int(fcord) tcord = int(tcord) if promotion: flag = PROMOTION_FLAGS[int(promotion)] elif (RANK(fcord) != RANK(tcord) and FILE(fcord) != FILE(tcord) and board.arBoard[fcord] == PAWN and board.arBoard[tcord] == EMPTY): flag = ENPASSANT else: flag = NORMAL_MOVE move = newMove(fcord, tcord, flag) if result == "Draw": state = DRAW steps = 0 else: s, steps = result.split(" in ") steps = int(steps) if result.startswith("Win"): if color == WHITE: state = WHITEWON else: state = BLACKWON elif result.startswith("Lose"): if color == WHITE: state = BLACKWON else: state = WHITEWON moves.append((move, state, steps)) if moves: self.table[(fen, color)] = moves elif color == board.color and board.opIsChecked(): log.warning("Asked endgametable for a won position: %s" % fen) elif color == board.color: log.warning( "Couldn't get %s data for position %s.\nData was: %s" % (reprColor[color], fen, repr(data))) except (KeyError, ValueError): log.warning( "Couldn't parse %s data for position %s.\nData was: %s" % (reprColor[color], fen, repr(data))) self.table[(fen, color)] = [] # Don't try again. if (fen, board.color) in self.table: return self.table[(fen, board.color)] return []
def run_analyze(button, *args): gmwidg = gamewidget.cur_gmwidg() gamemodel = gameDic[gmwidg] old_check_value = conf.get("analyzer_check", True) conf.set("analyzer_check", True) analyzer = gamemodel.spectators[HINT] gmwidg.menuitems["hint_mode"].active = True threat_PV = conf.get("ThreatPV", False) if threat_PV: old_inv_check_value = conf.get("inv_analyzer_check", True) conf.set("inv_analyzer_check", True) inv_analyzer = gamemodel.spectators[SPY] gmwidg.menuitems["spy_mode"].active = True title = _("Game analyzing in progress...") text = _("Do you want to abort it?") content = InfoBar.get_message_content(title, text, Gtk.STOCK_DIALOG_QUESTION) def response_cb(infobar, response, message): message.dismiss() abort() message = InfoBarMessage(Gtk.MessageType.QUESTION, content, response_cb) message.add_button( InfoBarMessageButton(_("Abort"), Gtk.ResponseType.CANCEL)) gmwidg.showMessage(message) def analyse_moves(): from_current = conf.get("fromCurrent", True) start_ply = gmwidg.board.view.shown if from_current else 0 move_time = int(conf.get("max_analysis_spin", 3)) thresold = int(conf.get("variation_thresold_spin", 50)) for board in gamemodel.boards[start_ply:]: if stop_event.is_set(): break @idle_add def do(): gmwidg.board.view.setShownBoard(board) do() analyzer.setBoard(board) inv_analyzer.setBoard(board) time.sleep(move_time + 0.1) ply = board.ply if ply - 1 in gamemodel.scores and ply in gamemodel.scores: color = (ply - 1) % 2 oldmoves, oldscore, olddepth = gamemodel.scores[ply - 1] score_str = prettyPrintScore(oldscore, olddepth) oldscore = oldscore * -1 if color == BLACK else oldscore moves, score, depth = gamemodel.scores[ply] score = score * -1 if color == WHITE else score diff = score - oldscore if (diff > thresold and color == BLACK) or (diff < -1 * thresold and color == WHITE): if threat_PV: try: if ply - 1 in gamemodel.spy_scores: oldmoves0, oldscore0, olddepth0 = gamemodel.spy_scores[ ply - 1] score_str0 = prettyPrintScore( oldscore0, olddepth0) pv0 = listToMoves(gamemodel.boards[ply - 1], ["--"] + oldmoves0, validate=True) if len(pv0) > 2: gamemodel.add_variation( gamemodel.boards[ply - 1], pv0, comment="Treatening", score=score_str0) except ParsingError as e: # ParsingErrors may happen when parsing "old" lines from # analyzing engines, which haven't yet noticed their new tasks log.debug("__parseLine: Ignored (%s) from analyzer: ParsingError%s" % \ (' '.join(oldmoves),e)) try: pv = listToMoves(gamemodel.boards[ply - 1], oldmoves, validate=True) gamemodel.add_variation(gamemodel.boards[ply - 1], pv, comment="Better is", score=score_str) except ParsingError as e: # ParsingErrors may happen when parsing "old" lines from # analyzing engines, which haven't yet noticed their new tasks log.debug("__parseLine: Ignored (%s) from analyzer: ParsingError%s" % \ (' '.join(oldmoves),e)) widgets["analyze_game"].hide() widgets["analyze_ok_button"].set_sensitive(True) conf.set("analyzer_check", old_check_value) if threat_PV: conf.set("inv_analyzer_check", old_inv_check_value) message.dismiss() t = threading.Thread(target=analyse_moves, name=fident(analyse_moves)) t.daemon = True t.start() hide_window(None) return True
import os from struct import Struct from collections import namedtuple from pychess.System import conf from pychess.Utils.lutils.lmove import parsePolyglot from pychess.System.Log import log path = conf.get("opening_file_entry") if os.path.isfile(path): bookfile = True else: bookfile = False log.warning("Could not find %s" % path) # The book probing code is based on that of PolyGlot by Fabien Letouzey. # PolyGlot is available under the GNU GPL from http://wbec-ridderkerk.nl BookEntry = namedtuple("BookEntry", "key move weight learn") # 'key' c_uint64 the position's hash # 'move' c_uint16 the candidate move # 'weight' c_uint16 proportional to prob. we should play it # The following terms are not always available: # 'learn' c_uint32 we use this NOT the polyglot way but as in # https://github.com/mcostalba/chess_db entrystruct = Struct(">QHHI") entrysize = entrystruct.size
def __init__(self, widgets): self.widgets = widgets # Font chooser font = conf.get("movetextFont", "FreeSerif Regular 12") font_button = Gtk.FontButton.new_with_font(font) demo_text = "♔a1 ♕f8 ♖h8 ♗g7 ♘g2 Ka1 Qf8 Rh8 Bg7 Ng2" font_button.set_preview_text(demo_text) self.widgets["fontChooserDock"].add(font_button) font_button.show() def select_font(button): conf.set("movetextFont", button.get_font_name()) font_button.connect("font-set", select_font) # Background image path = conf.get("welcome_image", addDataPrefix("glade/clear.png")) conf.set("welcome_image", path) image_chooser_dialog = Gtk.FileChooserDialog( _("Select background image file"), mainwindow(), Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) image_chooser_button = Gtk.FileChooserButton.new_with_dialog( image_chooser_dialog) filter = Gtk.FileFilter() filter.set_name(_("Images")) filter.add_pattern("*.bmp") filter.add_pattern("*.jpg") filter.add_pattern("*.png") filter.add_pattern("*.svg") image_chooser_dialog.add_filter(filter) image_chooser_button.set_filename(path) self.widgets["imageChooserDock"].add(image_chooser_button) image_chooser_button.show() def select_new_image(button): new_image = image_chooser_dialog.get_filename() if new_image: conf.set("welcome_image", new_image) from pychess.widgets.TaskerManager import tasker newTheme(tasker, background=new_image) tasker.queue_draw() else: # restore the original image_chooser_dialog.set_filename(path) image_chooser_button.connect("file-set", select_new_image) # Board style uistuff.createCombo(widgets["board_style"], name="board_style") data = [(item[0], item[1]) for item in board_items] uistuff.createCombo(widgets["board_style"], data) uistuff.keep(widgets["board_style"], "board_style", first_value=1) # conf.set("board_style", conf.get("board_style", 1)) # Board frame uistuff.createCombo(widgets["board_frame"], name="board_frame") data = [(item[0], item[1]) for item in [(None, "no frame")] + board_items[1:]] uistuff.createCombo(widgets["board_frame"], data) uistuff.keep(widgets["board_frame"], "board_frame", first_value=1) # conf.set("board_frame", conf.get("board_frame", 1)) # Board Colours style_ctxt = widgets["main_window"].get_style_context() LIGHT = hexcol(style_ctxt.lookup_color("p_light_color")[1]) DARK = hexcol(style_ctxt.lookup_color("p_dark_color")[1]) def onColourSetLight(_): """ :Description: Sets the light squares of the chess board to the value selected in the colour picker """ conf.set('lightcolour', widgets['light_cbtn'].get_color().to_string()) widgets["light_cbtn"].connect_after("color-set", onColourSetLight) def onColourSetDark(_): """ :Description: Sets the dark squares of the chess board to the value selected in the colour picker """ conf.set('darkcolour', widgets['dark_cbtn'].get_color().to_string()) widgets["dark_cbtn"].connect_after("color-set", onColourSetDark) def onResetColourClicked(_): """ :Description: Resets the chess board squares to factory default """ conf.set("lightcolour", LIGHT) conf.set("darkcolour", DARK) widgets["reset_btn"].connect("clicked", onResetColourClicked) # Get the current board colours if set, if not set, set them to default conf.set("lightcolour", conf.get("lightcolour", LIGHT)) conf.set("darkcolour", conf.get("darkcolour", DARK)) # Next 2 lines take a #hex str converts them to a color then to a RGBA representation self.lightcolour = Gdk.RGBA() self.lightcolour.parse(conf.get("lightcolour", LIGHT)) self.darkcolour = Gdk.RGBA() self.darkcolour.parse(conf.get("darkcolour", DARK)) # Set the color swatches in preference to stored values widgets['light_cbtn'].set_rgba(self.lightcolour) widgets['dark_cbtn'].set_rgba(self.darkcolour) # Chess Sets self.themes = self.discoverThemes() store = Gtk.ListStore(GdkPixbuf.Pixbuf, str) for theme in self.themes: pngfile = "%s/%s.png" % (addDataPrefix("pieces"), theme) if isfile(pngfile): pixbuf = get_pixbuf(pngfile) store.append((pixbuf, theme)) else: print( "WARNING: No piece theme preview icons found. Please run \ create_theme_preview.sh !") break self.icon_view = widgets["pieceTheme"] self.icon_view.set_model(store) self.icon_view.set_pixbuf_column(0) self.icon_view.set_text_column(1) def keepSize(crt, _): """ :Description: Hack to fix spacing problem in iconview http://stackoverflow.com/questions/14090094/what-causes-the-different-\ display-behaviour-for-a-gtkiconview-between-different """ crt.handler_block(crt_notify) crt.set_property('width', 40) crt.handler_unblock(crt_notify) crt = self.icon_view.get_cells()[0] crt_notify = crt.connect('notify', keepSize) def _getActive(iconview): model = iconview.get_model() selected = iconview.get_selected_items() if len(selected) == 0: return conf.get("pieceTheme", "Chessicons") indices = selected[0].get_indices() if indices: idx = indices[0] theme = model[idx][1] Pieces.set_piece_theme(theme) return theme def _setActive(iconview, value): try: index = self.themes.index(value) except ValueError: index = 0 iconview.select_path(Gtk.TreePath(index, )) uistuff.keep(widgets["pieceTheme"], "pieceTheme", _getActive, _setActive, "Chessicons")
def analyse_moves(): from_current = conf.get("fromCurrent", True) start_ply = gmwidg.board.view.shown if from_current else 0 move_time = int(conf.get("max_analysis_spin", 3)) thresold = int(conf.get("variation_thresold_spin", 50)) for board in gamemodel.boards[start_ply:]: if stop_event.is_set(): break @idle_add def do(): gmwidg.board.view.setShownBoard(board) do() analyzer.setBoard(board) inv_analyzer.setBoard(board) time.sleep(move_time + 0.1) ply = board.ply if ply - 1 in gamemodel.scores and ply in gamemodel.scores: color = (ply - 1) % 2 oldmoves, oldscore, olddepth = gamemodel.scores[ply - 1] score_str = prettyPrintScore(oldscore, olddepth) oldscore = oldscore * -1 if color == BLACK else oldscore moves, score, depth = gamemodel.scores[ply] score = score * -1 if color == WHITE else score diff = score - oldscore if (diff > thresold and color == BLACK) or (diff < -1 * thresold and color == WHITE): if threat_PV: try: if ply - 1 in gamemodel.spy_scores: oldmoves0, oldscore0, olddepth0 = gamemodel.spy_scores[ ply - 1] score_str0 = prettyPrintScore( oldscore0, olddepth0) pv0 = listToMoves(gamemodel.boards[ply - 1], ["--"] + oldmoves0, validate=True) if len(pv0) > 2: gamemodel.add_variation( gamemodel.boards[ply - 1], pv0, comment="Treatening", score=score_str0) except ParsingError as e: # ParsingErrors may happen when parsing "old" lines from # analyzing engines, which haven't yet noticed their new tasks log.debug("__parseLine: Ignored (%s) from analyzer: ParsingError%s" % \ (' '.join(oldmoves),e)) try: pv = listToMoves(gamemodel.boards[ply - 1], oldmoves, validate=True) gamemodel.add_variation(gamemodel.boards[ply - 1], pv, comment="Better is", score=score_str) except ParsingError as e: # ParsingErrors may happen when parsing "old" lines from # analyzing engines, which haven't yet noticed their new tasks log.debug("__parseLine: Ignored (%s) from analyzer: ParsingError%s" % \ (' '.join(oldmoves),e)) widgets["analyze_game"].hide() widgets["analyze_ok_button"].set_sensitive(True) conf.set("analyzer_check", old_check_value) if threat_PV: conf.set("inv_analyzer_check", old_inv_check_value) message.dismiss()
def __init__(self, widgets): # Init open dialog opendialog = Gtk.FileChooserDialog( _("Open Sound File"), mainwindow(), Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.ACCEPT)) for dir in self.SOUND_DIRS: if os.path.isdir(dir): opendialog.set_current_folder(dir) break soundfilter = Gtk.FileFilter() soundfilter.set_name(_("Sound files")) soundfilter.add_mime_type("audio/%s" % EXT) soundfilter.add_pattern("*.%s" % EXT) opendialog.add_filter(soundfilter) # Get combo icons icons = ((_("No sound"), "audio-volume-muted", "audio-volume-muted"), (_("Beep"), "stock_bell", "audio-x-generic"), (_("Select sound file..."), "gtk-open", "document-open")) items = [] for level, stock, altstock in icons: image = load_icon(16, stock, altstock) items += [(image, level)] audioIco = load_icon(16, "audio-x-generic") # Set-up combos def callback(combobox, index): if combobox.get_active() == SOUND_SELECT: if opendialog.run() == Gtk.ResponseType.ACCEPT: uri = opendialog.get_uri() model = combobox.get_model() conf.set("sounduri%d" % index, uri) label = unquote(os.path.split(uri)[1]) if len(model) == 3: model.append([audioIco, label]) else: model.set(model.get_iter((3, )), 1, label) combobox.set_active(3) else: combobox.set_active( conf.get("soundcombo%d" % index, SOUND_MUTE)) opendialog.hide() for i in range(COUNT_OF_SOUNDS): combo = widgets["sound%dcombo" % i] uistuff.createCombo(combo, items, name="soundcombo%d" % i) combo.connect("changed", callback, i) label = widgets["soundlabel%d" % i] label.props.mnemonic_widget = combo uri = conf.get("sounduri%d" % i, "") if os.path.isfile(url2pathname(uri[5:])): model = combo.get_model() model.append([audioIco, unquote(os.path.split(uri)[1])]) for i in range(COUNT_OF_SOUNDS): if conf.get("soundcombo%d" % i, SOUND_MUTE) == SOUND_URI and \ not os.path.isfile(url2pathname(conf.get("sounduri%d" % i, "")[5:])): conf.set("soundcombo%d" % i, SOUND_MUTE) uistuff.keep(widgets["sound%dcombo" % i], "soundcombo%d" % i) # Init play button def playCallback(button, index): SoundTab.playAction(index) for i in range(COUNT_OF_SOUNDS): button = widgets["sound%dbutton" % i] button.connect("clicked", playCallback, i) # Init 'use sound" checkbutton def checkCallBack(*args): checkbox = widgets["useSounds"] widgets["sounds_frame"].set_property("sensitive", checkbox.get_active()) conf.notify_add("useSounds", checkCallBack) widgets["useSounds"].set_active(True) uistuff.keep(widgets["useSounds"], "useSounds") checkCallBack() if not self.getPlayer().ready: widgets["useSounds"].set_sensitive(False) widgets["useSounds"].set_active(False) uistuff.keep(widgets["alarm_spin"], "alarm_spin", first_value=15)
def release(self, x_loc, y_loc): cord = self.point2Cord(x_loc, y_loc) if cord == self.view.active == self.view.selected == self.parent.selected_last: # User clicked (press+release) same piece twice, so unselect it self.view.active = None self.view.selected = None self.view.dragged_piece = None self.view.startAnimation() self.parent.setStateNormal() elif self.parent.allowPremove and self.view.selected and self.isAPotentiallyLegalNextMove( self.view.selected, cord): # In mixed locked selected/active state and user selects a valid premove cord board = self.getBoard() if board[self.view.selected].sign == PAWN and \ cord.cord in board.PROMOTION_ZONE[1 - board.color]: if conf.get("autoPromote", False): promotion = lmove.PROMOTE_PIECE(QUEEN_PROMOTION) else: promotion = self.parent.getPromotion() else: promotion = None self.view.setPremove(board[self.view.selected], self.view.selected, cord, self.view.shown + 2, promotion) self.view.selected = None self.view.active = None self.view.dragged_piece = None self.view.startAnimation() self.parent.setStateNormal() elif self.parent.allowPremove and self.isAPotentiallyLegalNextMove( self.view.active, cord): # User drags a piece to a valid premove square board = self.getBoard() if board[self.view.active].sign == PAWN and \ cord.cord in board.PROMOTION_ZONE[1 - board.color]: if conf.get("autoPromote", False): promotion = lmove.PROMOTE_PIECE(QUEEN_PROMOTION) else: promotion = self.parent.getPromotion() else: promotion = None self.view.setPremove(self.getBoard()[self.view.active], self.view.active, cord, self.view.shown + 2, promotion) self.view.selected = None self.view.active = None self.view.dragged_piece = None self.view.startAnimation() self.parent.setStateNormal() elif self.view.active or self.view.selected: # Select last piece user tried to move or that was selected self.view.selected = self.view.active if self.view.active else self.view.selected self.view.active = None self.view.dragged_piece = None self.view.startAnimation() self.parent.setStateSelected() else: self.view.active = None self.view.selected = None self.view.dragged_piece = None self.view.startAnimation() self.parent.setStateNormal() self.parent.selected_last = self.view.selected
def save(handle, model, position=None, flip=False): """ Saves the game from GameModel to .pgn """ processed_tags = [] def write_tag(tag, value, roster=False): nonlocal processed_tags if tag in processed_tags or (not roster and not value): return try: pval = str(value) pval = pval.replace("\\", "\\\\") pval = pval.replace("\"", "\\\"") print('[%s "%s"]' % (tag, pval), file=handle) except UnicodeEncodeError: pval = bytes(pval, "utf-8").decode(PGN_ENCODING, errors="ignore") print('[%s "%s"]' % (tag, pval), file=handle) processed_tags = processed_tags + [tag] # Mandatory ordered seven-tag roster status = reprResult[model.status] for tag in mandatory_tags: value = model.tags[tag] if tag == "Date": y, m, d = parseDateTag(value) y = "%04d" % y if y is not None else "????" m = "%02d" % m if m is not None else "??" d = "%02d" % d if d is not None else "??" value = "%s.%s.%s" % (y, m, d) elif value == "": value = "?" write_tag(tag, value, roster=True) write_tag("Result", reprResult[model.status], roster=True) # Variant if model.variant.variant != NORMALCHESS: write_tag("Variant", model.variant.cecp_name.capitalize()) # Initial position if model.boards[0].asFen() != FEN_START: write_tag("SetUp", "1") write_tag("FEN", model.boards[0].asFen()) # Number of moves write_tag("PlyCount", model.ply - model.lowply) # Final position if model.reason == WON_CALLFLAG: value = "time forfeit" elif model.reason == WON_ADJUDICATION and model.isEngine2EngineGame(): value = "rules infraction" elif model.reason in (DRAW_ADJUDICATION, WON_ADJUDICATION): value = "adjudication" elif model.reason == WHITE_ENGINE_DIED: value = "white engine died" elif model.reason == BLACK_ENGINE_DIED: value = "black engine died" elif model.reason in ABORTED_REASONS: value = "abandoned" elif model.reason in ADJOURNED_REASONS: value = "unterminated" else: value = "unterminated" if status == "*" else None if value is not None: write_tag("Termination", value) # ELO and its variation if conf.get("saveRatingChange"): welo = model.tags["WhiteElo"] belo = model.tags["BlackElo"] if welo != "" and belo != "": write_tag("WhiteRatingDiff", get_elo_rating_change_pgn(model, WHITE)) # Unofficial write_tag("BlackRatingDiff", get_elo_rating_change_pgn(model, BLACK)) # Unofficial # Time if model.timed: write_tag( 'WhiteClock', msToClockTimeTag(int(model.timemodel.getPlayerTime(WHITE) * 1000))) write_tag( 'BlackClock', msToClockTimeTag(int(model.timemodel.getPlayerTime(BLACK) * 1000))) # Write all the unprocessed tags for tag in model.tags: # Debug: print(">> %s = %s" % (tag, str(model.tags[tag]))) write_tag(tag, model.tags[tag]) # Discovery of the moves and comments save_emt = conf.get("saveEmt") save_eval = conf.get("saveEval") result = [] walk(model.boards[0].board, result, model, save_emt, save_eval) # Alignment of the fetched elements indented = conf.get("indentPgn") if indented: buffer = "" depth = 0 crlf = False for text in result: # De/Indentation crlf = (buffer[-1:] if len(buffer) > 0 else "") in ["\r", "\n"] if text == "(": depth += 1 if indented and not crlf: buffer += os.linesep crlf = True # Space between each term last = buffer[-1:] if len(buffer) > 0 else "" crlf = last in ["\r", "\n"] if not crlf and last != " " and last != "\t" and last != "(" and not text.startswith( "\r") and not text.startswith( "\n") and text != ")" and len(buffer) > 0: buffer += " " # New line for a new main move if len(buffer) == 0 or (indented and depth == 0 and last != "\r" and last != "\n" and re.match( "^[0-9]+\.", text) is not None): buffer += os.linesep crlf = True # Alignment if crlf and depth > 0: for j in range(0, depth): buffer += " " # Term buffer += text if indented and text == ")": buffer += os.linesep crlf = True depth -= 1 else: # Add new line to separate tag section and movetext print('', file=handle) buffer = textwrap.fill(" ".join(result), width=80) # Final status = reprResult[model.status] print(buffer, status, file=handle) # Add new line to separate next game print('', file=handle) output = handle.getvalue() if isinstance(handle, StringIO) else "" handle.close() return output
def load(self, gmwidg): self.textview = Gtk.TextView() self.textview.set_wrap_mode(Gtk.WrapMode.WORD) self.cursor_standard = Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR) self.cursor_hand = Gdk.Cursor.new(Gdk.CursorType.HAND2) self.nodelist = [] self.oldWidth = 0 self.autoUpdateSelected = True self.textview_cids = [ self.textview.connect("motion-notify-event", self.motion_notify_event), self.textview.connect("button-press-event", self.button_press_event), ] bg_color, fg_color = set_textview_color(self.textview) self.textbuffer = self.textview.get_buffer() color0 = fg_color color1 = Gdk.RGBA(red=0.2, green=0.0, blue=0.0) color2 = Gdk.RGBA(red=0.4, green=0.0, blue=0.0) color3 = Gdk.RGBA(red=0.6, green=0.0, blue=0.0) color4 = Gdk.RGBA(red=0.8, green=0.0, blue=0.0) color5 = Gdk.RGBA(red=1.0, green=0.0, blue=0.0) self.remove_vari_tag = self.textbuffer.create_tag("remove-variation") self.rmv_cid = self.remove_vari_tag.connect("event", self.tag_event_handler) self.new_line_tag = self.textbuffer.create_tag("new_line") self.textbuffer.create_tag("head1") self.textbuffer.create_tag("head2", weight=Pango.Weight.BOLD) self.textbuffer.create_tag("move", weight=Pango.Weight.BOLD) self.textbuffer.create_tag("scored0", foreground_rgba=color0) self.textbuffer.create_tag("scored1", foreground_rgba=color1) self.textbuffer.create_tag("scored2", foreground_rgba=color2) self.textbuffer.create_tag("scored3", foreground_rgba=color3) self.textbuffer.create_tag("scored4", foreground_rgba=color4) self.textbuffer.create_tag("scored5", foreground_rgba=color5) self.textbuffer.create_tag("emt", foreground="darkgrey", weight=Pango.Weight.NORMAL) self.textbuffer.create_tag("comment", foreground="darkblue") self.textbuffer.create_tag("variation-toplevel", weight=Pango.Weight.NORMAL) self.textbuffer.create_tag("variation-even", foreground="darkgreen", style="italic") self.textbuffer.create_tag("variation-uneven", foreground="darkred", style="italic") self.textbuffer.create_tag("selected", background_full_height=True, background="grey") self.textbuffer.create_tag("margin", left_margin=4) self.textbuffer.create_tag("variation-margin0", left_margin=20) self.textbuffer.create_tag("variation-margin1", left_margin=36) self.textbuffer.create_tag("variation-margin2", left_margin=52) __widget__ = Gtk.ScrolledWindow() __widget__.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.ALWAYS) __widget__.add(self.textview) self.boardview = gmwidg.board.view self.cid = self.boardview.connect("shownChanged", self.shownChanged) self.gamemodel = gmwidg.gamemodel self.model_cids = [ self.gamemodel.connect_after("game_loaded", self.game_loaded), self.gamemodel.connect_after("game_changed", self.game_changed), self.gamemodel.connect_after("game_started", self.update), self.gamemodel.connect_after("game_ended", self.update), self.gamemodel.connect_after("moves_undone", self.moves_undone), self.gamemodel.connect_after("opening_changed", self.update), self.gamemodel.connect_after("players_changed", self.players_changed), self.gamemodel.connect_after("game_terminated", self.on_game_terminated), self.gamemodel.connect("variation_added", self.variation_added), self.gamemodel.connect("variation_extended", self.variation_extended), self.gamemodel.connect("analysis_changed", self.analysis_changed), self.gamemodel.connect("analysis_finished", self.update), ] # Connect to preferences self.conf_conids = [] self.fan = conf.get("figuresInNotation", False) def figuresInNotationCallback(none): self.fan = conf.get("figuresInNotation", False) self.update() self.conf_conids.append( conf.notify_add("figuresInNotation", figuresInNotationCallback)) # Elapsed move time self.showEmt = conf.get("showEmt", False) def showEmtCallback(none): self.showEmt = conf.get("showEmt", False) self.update() self.conf_conids.append(conf.notify_add("showEmt", showEmtCallback)) # Blunders self.showBlunder = conf.get( "showBlunder", False) and not self.gamemodel.isPlayingICSGame() def showBlunderCallback(none): self.showBlunder = conf.get( "showBlunder", False) and not self.gamemodel.isPlayingICSGame() self.update() self.conf_conids.append( conf.notify_add("showBlunder", showBlunderCallback)) # Eval values self.showEval = conf.get( "showEval", False) and not self.gamemodel.isPlayingICSGame() def showEvalCallback(none): self.showEval = conf.get( "showEval", False) and not self.gamemodel.isPlayingICSGame() self.update() self.conf_conids.append(conf.notify_add("showEval", showEvalCallback)) return __widget__
global chess_font_face global piece2char piece_set = piece_set.lower() if piece_set == 'pychess': from pychess.gfx.pychess_pieces import drawPiece2 drawPiece = drawPiece2 elif piece_set.startswith("ttf-"): drawPiece = drawPiece4 try: chess_font_face, piece2char = get_chess_font_face(piece_set) except Exception: from pychess.gfx.pychess_pieces import drawPiece2 drawPiece = drawPiece2 elif piece_set in ('celtic', 'eyes', 'fantasy', 'fantasy_alt', 'freak', 'prmi', 'skulls', 'spatial'): all_in_one = True drawPiece = drawPiece3 svg_pieces = get_svg_pieces(piece_set) else: all_in_one = False drawPiece = drawPiece3 try: svg_pieces = get_svg_pieces(piece_set) except Exception: from pychess.gfx.pychess_pieces import drawPiece2 drawPiece = drawPiece2 set_piece_theme(conf.get("pieceTheme"))
def closeGame(self, gmwidg): log.debug("Games.closeGame") response = None if not gmwidg.gamemodel.isChanged(): response = Gtk.ResponseType.OK else: markup = "<b><big>" + _( "Save the current game before you close it?") + "</big></b>" if conf.get("autoSave", False): x = self.saveGamePGN(gmwidg.gamemodel) if x: response = Gtk.ResponseType.OK else: markup = "<b><big>" + _( "Unable to save to configured file. \ Save the current game before you close it?" ) + "</big></b>" if response is None: d = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.WARNING) d.add_button(_("Close _without Saving"), Gtk.ResponseType.OK) d.add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL) if gmwidg.gamemodel.uri: d.add_button(Gtk.STOCK_SAVE, Gtk.ResponseType.YES) else: d.add_button(Gtk.STOCK_SAVE_AS, Gtk.ResponseType.YES) gmwidg.bringToFront() d.set_markup(markup) d.format_secondary_text( _("It is not possible later to continue the game,\nif you don't save it." )) response = d.run() d.destroy() if response == Gtk.ResponseType.YES: # Test if cancel was pressed in the save-file-dialog if self.saveGame(gmwidg.gamemodel) != Gtk.ResponseType.ACCEPT: response = Gtk.ResponseType.CANCEL if response not in (Gtk.ResponseType.DELETE_EVENT, Gtk.ResponseType.CANCEL): if gmwidg.gamemodel.status in UNFINISHED_STATES: gmwidg.gamemodel.end(ABORTED, ABORTED_AGREEMENT) gmwidg.disconnect(self.gmwidg_cids[gmwidg]) del self.gmwidg_cids[gmwidg] for cid in self.notify_cids[gmwidg]: conf.notify_remove(cid) del self.notify_cids[gmwidg] if gmwidg.board in self.board_cids: gmwidg.board.disconnect(self.board_cids[gmwidg.board]) del self.board_cids[gmwidg.board] self.delGameWidget(gmwidg) self.gamewidgets.remove(gmwidg) gmwidg.gamemodel.terminate() if len(self.gamewidgets) == 0: for widget in MENU_ITEMS: gamewidget.getWidgets()[widget].set_property( 'sensitive', False) return response