def handleArgs(self, chess_file): if chess_file: def do(discoverer): GLib.idle_add(newGameDialog.LoadFileExtension.run, chess_file) discoverer.connect_after("all_engines_discovered", do)
def handleArgs(self, chess_file): if chess_file: def do(discoverer): GLib.idle_add(newGameDialog.LoadFileExtension.run, chess_file) discoverer.connect_after("all_engines_discovered", do)
def __init__(self): #GObject.GObject.__init__(self,0,0,0,0) GObject.GObject.__init__(self) self.widgets = widgets = uistuff.GladeWidgets("taskers.glade") tasker = widgets["newGameTasker"] tasker.unparent() self.add(tasker) combo = ToggleComboBox() combo.addItem(_("White"), get_pixbuf("glade/white.png")) combo.addItem(_("Black"), get_pixbuf("glade/black.png")) combo.addItem(_("Random"), get_pixbuf("glade/random.png")) combo.setMarkup("<b>", "</b>") widgets["colorDock"].add(combo) uistuff.keep(combo, "newgametasker_colorcombo") widgets['yourColorLabel'].set_mnemonic_widget(combo) # We need to wait until after engines have been discovered, to init the # playerCombos. We use connect_after to make sure, that newGameDialog # has also had time to init the constants we share with them. self.playerCombo = ToggleComboBox() widgets["opponentDock"].add(self.playerCombo) discoverer.connect_after("all_engines_discovered", self.__initPlayerCombo, widgets) widgets['opponentLabel'].set_mnemonic_widget(self.playerCombo) def on_skill_changed(scale): pix = newGameDialog.skillToIconLarge[int(scale.get_value())] widgets["skillImage"].set_from_pixbuf(pix) widgets["skillSlider"].connect("value-changed", on_skill_changed) on_skill_changed(widgets["skillSlider"]) widgets["startButton"].connect("clicked", self.startClicked) self.widgets["opendialog1"].connect("clicked", self.openDialogClicked)
def __init__(self): #GObject.GObject.__init__(self,0,0,0,0) GObject.GObject.__init__(self) self.widgets = widgets = uistuff.GladeWidgets("taskers.glade") tasker = widgets["newGameTasker"] tasker.unparent() self.add(tasker) combo = ToggleComboBox() combo.addItem(_("White"), get_pixbuf("glade/white.png")) combo.addItem(_("Black"), get_pixbuf("glade/black.png")) combo.addItem(_("Random"), get_pixbuf("glade/random.png")) combo.setMarkup("<b>", "</b>") widgets["colorDock"].add(combo) uistuff.keep(combo, "newgametasker_colorcombo") widgets['yourColorLabel'].set_mnemonic_widget(combo) # We need to wait until after engines have been discovered, to init the # playerCombos. We use connect_after to make sure, that newGameDialog # has also had time to init the constants we share with them. self.playerCombo = ToggleComboBox() widgets["opponentDock"].add(self.playerCombo) discoverer.connect_after("all_engines_discovered", self.__initPlayerCombo, widgets) widgets['opponentLabel'].set_mnemonic_widget(self.playerCombo) def on_skill_changed(scale): pix = newGameDialog.skillToIconLarge[int(scale.get_value())] widgets["skillImage"].set_from_pixbuf(pix) widgets["skillSlider"].connect("value-changed", on_skill_changed) on_skill_changed(widgets["skillSlider"]) widgets["startButton"].connect("clicked", self.startClicked) self.widgets["opendialog1"].connect("clicked", self.openDialogClicked)
def handleArgs(self, chess_file): if chess_file: def do(discoverer): perspective = perspective_manager.get_perspective("database") GLib.idle_add(perspective.open_chessfile, chess_file) discoverer.connect_after("all_engines_discovered", do)
def handleArgs(self, chess_file): if chess_file: def do(discoverer): perspective = perspective_manager.get_perspective("database") perspective.open_chessfile(chess_file) self.dd_task.cancel() discoverer.connect_after("all_engines_discovered", do)
def handleArgs(self, chess_file): if chess_file: def do(discoverer): perspective = perspective_manager.get_perspective("database") perspective.open_chessfile(chess_file) self.dd_task.cancel() discoverer.connect_after("all_engines_discovered", do)
def __init__(self): GObject.GObject.__init__(self) self.widgets = widgets = tasker_widgets tasker = widgets["newGameTasker"] tasker.unparent() self.add(tasker) startButton = self.widgets["startButton"] startButton.set_name("startButton") combo = Gtk.ComboBox() uistuff.createCombo( combo, [ (get_pixbuf("glade/white.png"), _("White")), (get_pixbuf("glade/black.png"), _("Black")), (get_pixbuf("glade/random.png"), _("Random")), ], ) widgets["colorDock"].add(combo) if combo.get_active() < 0: combo.set_active(0) widgets["yourColorLabel"].set_mnemonic_widget(combo) # We need to wait until after engines have been discovered, to init the # playerCombos. We use connect_after to make sure, that newGameDialog # has also had time to init the constants we share with them. self.playerCombo = Gtk.ComboBox() widgets["opponentDock"].add(self.playerCombo) discoverer.connect_after("all_engines_discovered", self.__initPlayerCombo, widgets) widgets["opponentLabel"].set_mnemonic_widget(self.playerCombo) def on_skill_changed(scale): # Just to make sphinx happy... try: pix = newGameDialog.skillToIconLarge[int(scale.get_value())] widgets["skillImage"].set_from_pixbuf(pix) except TypeError: pass widgets["skillSlider"].connect("value-changed", on_skill_changed) on_skill_changed(widgets["skillSlider"]) widgets["startButton"].connect("clicked", self.startClicked) self.widgets["opendialog1"].connect("clicked", self.openDialogClicked)
def __init__(self): GObject.GObject.__init__(self) self.widgets = widgets = uistuff.GladeWidgets("taskers.glade") tasker = widgets["newGameTasker"] tasker.unparent() self.add(tasker) startButton = self.widgets["startButton"] startButton.set_name("startButton") combo = Gtk.ComboBox() uistuff.createCombo(combo, [ (get_pixbuf("glade/white.png"), _("White")), (get_pixbuf("glade/black.png"), _("Black")), (get_pixbuf("glade/random.png"), _("Random"))]) widgets["colorDock"].add(combo) if combo.get_active() < 0: combo.set_active(0) uistuff.keep(combo, "newgametasker_colorcombo") widgets['yourColorLabel'].set_mnemonic_widget(combo) # We need to wait until after engines have been discovered, to init the # playerCombos. We use connect_after to make sure, that newGameDialog # has also had time to init the constants we share with them. self.playerCombo = Gtk.ComboBox() widgets["opponentDock"].add(self.playerCombo) discoverer.connect_after("all_engines_discovered", self.__initPlayerCombo, widgets) widgets['opponentLabel'].set_mnemonic_widget(self.playerCombo) def on_skill_changed(scale): # Just to make sphinx happy... try: pix = newGameDialog.skillToIconLarge[int(scale.get_value())] widgets["skillImage"].set_from_pixbuf(pix) except TypeError: pass widgets["skillSlider"].connect("value-changed", on_skill_changed) on_skill_changed(widgets["skillSlider"]) widgets["startButton"].connect("clicked", self.startClicked) self.widgets["opendialog1"].connect("clicked", self.openDialogClicked)
def do_activate(self): # create_task(self.print_tasks()) self.add_window(self.window) self.window.show_all() gamewidget.getWidgets()["player_rating1"].hide() gamewidget.getWidgets()["leave_fullscreen1"].hide() # Externals download dialog if not conf.get("dont_show_externals_at_startup"): externals_dialog = ExternalsDialog() externals_dialog.show() # Tip of the day dialog if conf.get("show_tip_at_startup"): tip_of_the_day = TipOfTheDay() tip_of_the_day.show() preferencesDialog.run(gamewidget.getWidgets()) def on_all_engine_discovered(discoverer): engine = discoverer.getEngineByName(discoverer.getEngineLearn()) if engine is None: engine = discoverer.getEngineN(-1) default_engine = engine.get("md5") conf.set("ana_combobox", default_engine) conf.set("inv_ana_combobox", default_engine) # Try to set conf analyzer engine on very first start of pychess if conf.get("ana_combobox") == 0: discoverer.connect_after("all_engines_discovered", on_all_engine_discovered) dd = DiscovererDialog(discoverer) self.dd_task = create_task(dd.start()) style_ctxt = gamewidget.getWidgets()["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]) conf.DEFAULTS["General"]["lightcolour"] = LIGHT conf.DEFAULTS["General"]["darkcolour"] = DARK self.splash.destroy()
def protocol_changed(widget): if self.cur_engine is not None and not self.add and not self.selection: active = self.widgets["engine_protocol_combo"].get_active() new_protocol = "uci" if active==0 else "xboard" engine = discoverer.getEngineByName(self.cur_engine) old_protocol = engine["protocol"] if new_protocol != old_protocol: engine_command = engine_chooser_dialog.get_filename() # is the new protocol supported by the engine? if new_protocol == "uci": ok = is_uci(engine_command) else: ok = is_cecp(engine_command) if ok: # discover engine options for new protocol engine["protocol"] = new_protocol engine["recheck"] = True discoverer.connect_after("engine_discovered", update_options) discoverer.discover() else: # restore the original protocol widgets["engine_protocol_combo"].set_active(0 if old_protocol=="uci" else 1)
def do_activate(self): # create_task(self.print_tasks()) self.add_window(self.window) self.window.show_all() gamewidget.getWidgets()["player_rating1"].hide() gamewidget.getWidgets()["leave_fullscreen1"].hide() # Externals download dialog if not conf.get("dont_show_externals_at_startup"): externals_dialog = ExternalsDialog() externals_dialog.show() # Tip of the day dialog if conf.get("show_tip_at_startup"): tip_of_the_day = TipOfTheDay() tip_of_the_day.show() preferencesDialog.run(gamewidget.getWidgets()) def on_all_engine_discovered(discoverer): engine = discoverer.getEngineByName(discoverer.getEngineLearn()) if engine is None: engine = discoverer.getEngineN(-1) default_engine = engine.get("md5") conf.set("ana_combobox", default_engine) conf.set("inv_ana_combobox", default_engine) # Try to set conf analyzer engine on very first start of pychess if conf.get("ana_combobox") == 0: discoverer.connect_after("all_engines_discovered", on_all_engine_discovered) dd = DiscovererDialog(discoverer) self.dd_task = create_task(dd.start()) style_ctxt = gamewidget.getWidgets()["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]) conf.set("lightcolour", LIGHT) conf.set("darkcolour", DARK)
def add(button): self.add = True response = engine_chooser_dialog.run() if response == Gtk.ResponseType.OK: new_engine = engine_chooser_dialog.get_filename() if new_engine.lower().endswith(".exe") and sys.platform != "win32": vm_name = "wine" vmpath = searchPath(vm_name, access=os.R_OK|os.X_OK) if vmpath is None: d = Gtk.MessageDialog( type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) d.set_markup(_("<big><b>Unable to add %s</b></big>" % new_engine)) d.format_secondary_text(_("wine not installed")) d.run() d.hide() new_engine = "" else: vmpath += " " else: vm_name = None vmpath = "" if new_engine: try: uci = is_uci(vmpath + new_engine) if not uci: if not is_cecp(vmpath + new_engine): # restore the original engine = discoverer.getEngineByName(self.cur_engine) engine_chooser_dialog.set_filename(engine["command"]) d = Gtk.MessageDialog( type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) d.set_markup(_("<big><b>Unable to add %s</b></big>" % new_engine)) d.format_secondary_text(_("There is something wrong with this executable")) d.run() d.hide() engine_chooser_dialog.hide() return path, binname = os.path.split(new_engine) for e in discoverer.getEngines(): if e["name"] == binname: binname = e["name"] + "(1)" break self.widgets["engine_command_entry"].set_text(new_engine) self.widgets["engine_protocol_combo"].set_active(0 if uci else 1) self.widgets["engine_args_entry"].set_text("") active = self.widgets["engine_protocol_combo"].get_active() protocol = "uci" if active==0 else "xboard" discoverer.addEngine(binname, new_engine, protocol, vm_name) self.cur_engine = binname discoverer.connect_after("engine_discovered", update_store) self.add = False discoverer.discover() except: d = Gtk.MessageDialog( type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) d.set_markup(_("<big><b>Unable to add %s</b></big>" % new_engine)) d.format_secondary_text(_("There is something wrong with this executable")) d.run() d.hide() else: # restore the original engine = discoverer.getEngineByName(self.cur_engine) engine_chooser_dialog.set_filename(engine["command"]) engine_chooser_dialog.hide()
def initialize(gameDic): uistuff.keep(widgets["fromCurrent"], "fromCurrent", first_value=True) uistuff.keep(widgets["threatPV"], "threatPV") uistuff.keep(widgets["showEval"], "showEval") uistuff.keep(widgets["showBlunder"], "showBlunder", first_value=True) uistuff.keep(widgets["max_analysis_spin"], "max_analysis_spin", first_value=3) uistuff.keep(widgets["variation_thresold_spin"], "variation_thresold_spin", first_value=50) # Analyzing engines uistuff.createCombo(widgets["ana_combobox"]) from pychess.widgets import newGameDialog @idle_add def update_analyzers_store(discoverer): data = [(item[0], item[1]) for item in newGameDialog.analyzerItems] uistuff.updateCombo(widgets["ana_combobox"], data) discoverer.connect_after("all_engines_discovered", update_analyzers_store) update_analyzers_store(discoverer) uistuff.keep(widgets["ana_combobox"], "ana_combobox", anal_combo_get_value, lambda combobox, value: anal_combo_set_value(combobox, value, "hint_mode", "analyzer_check", HINT)) def hide_window(button, *args): widgets["analyze_game"].hide() return True def abort (): stop_event.set() widgets["analyze_game"].hide() 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 widgets["analyze_game"].connect("delete-event", hide_window) widgets["analyze_cancel_button"].connect("clicked", hide_window) widgets["analyze_ok_button"].connect("clicked", run_analyze)
def _init(cls): cls.white = get_pixbuf("glade/white.png") cls.black = get_pixbuf("glade/black.png") cls.widgets = uistuff.GladeWidgets("newInOut.glade") cls.widgets["newgamedialog"].set_transient_for(mainwindow()) def on_exchange_players(widget, button_event): white = cls.widgets["whitePlayerCombobox"].get_active() black = cls.widgets["blackPlayerCombobox"].get_active() whiteLevel = cls.widgets["skillSlider1"].get_value() blackLevel = cls.widgets["skillSlider2"].get_value() cls.widgets["whitePlayerCombobox"].set_active(black) cls.widgets["blackPlayerCombobox"].set_active(white) cls.widgets["skillSlider1"].set_value(blackLevel) cls.widgets["skillSlider2"].set_value(whiteLevel) cls.widgets["whitePlayerButton"].set_image( Gtk.Image.new_from_pixbuf(cls.white)) cls.widgets["whitePlayerButton"].connect("button-press-event", on_exchange_players) cls.widgets["blackPlayerButton"].set_image( Gtk.Image.new_from_pixbuf(cls.black)) cls.widgets["blackPlayerButton"].connect("button-press-event", on_exchange_players) uistuff.createCombo(cls.widgets["whitePlayerCombobox"], name="whitePlayerCombobox") uistuff.createCombo(cls.widgets["blackPlayerCombobox"], name="blackPlayerCombobox") cls.widgets["playersIcon"].set_from_pixbuf(big_people) cls.widgets["timeIcon"].set_from_pixbuf(big_time) def on_playerCombobox_changed(widget, skill_hbox): skill_hbox.props.visible = widget.get_active() > 0 cls.widgets["whitePlayerCombobox"].connect("changed", on_playerCombobox_changed, cls.widgets["skillHbox1"]) cls.widgets["blackPlayerCombobox"].connect("changed", on_playerCombobox_changed, cls.widgets["skillHbox2"]) cls.widgets["whitePlayerCombobox"].set_active(0) cls.widgets["blackPlayerCombobox"].set_active(1) def on_skill_changed(scale, image): image.set_from_pixbuf(skillToIcon[int(scale.get_value())]) cls.widgets["skillSlider1"].connect("value-changed", on_skill_changed, cls.widgets["skillIcon1"]) cls.widgets["skillSlider2"].connect("value-changed", on_skill_changed, cls.widgets["skillIcon2"]) cls.widgets["skillSlider1"].set_value(3) cls.widgets["skillSlider2"].set_value(3) cls.__initTimeRadio(_("Blitz"), "ngblitz", cls.widgets["blitzRadio"], cls.widgets["configImageBlitz"], 5, 0, 0) cls.__initTimeRadio(_("Rapid"), "ngrapid", cls.widgets["rapidRadio"], cls.widgets["configImageRapid"], 15, 5, 0) cls.__initTimeRadio(_("Normal"), "ngnormal", cls.widgets["normalRadio"], cls.widgets["configImageNormal"], 40, 15, 0) cls.__initTimeRadio(_("Classical"), "ngclassical", cls.widgets["classicalRadio"], cls.widgets["configImageClassical"], 3, 0, 40) cls.__initVariantRadio("ngvariant1", cls.widgets["playVariant1Radio"], cls.widgets["configImageVariant1"], FISCHERRANDOMCHESS) cls.__initVariantRadio("ngvariant2", cls.widgets["playVariant2Radio"], cls.widgets["configImageVariant2"], LOSERSCHESS) 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__) data = [(item[0], item[1]) for item in playerItems[variant]] uistuff.updateCombo(cls.widgets["blackPlayerCombobox"], data) uistuff.updateCombo(cls.widgets["whitePlayerCombobox"], data) discoverer.connect_after("all_engines_discovered", updateCombos) updateCombos(discoverer) conf.notify_add("ngvariant1", updateCombos) conf.notify_add("ngvariant2", updateCombos) cls.widgets["playNormalRadio"].connect("toggled", updateCombos) cls.widgets["playNormalRadio"].set_tooltip_text( variants[NORMALCHESS].__desc__) cls.widgets["playVariant1Radio"].connect("toggled", updateCombos) variant1 = conf.get("ngvariant1", FISCHERRANDOMCHESS) cls.widgets["playVariant1Radio"].set_tooltip_text( variants[variant1].__desc__) cls.widgets["playVariant2Radio"].connect("toggled", updateCombos) variant2 = conf.get("ngvariant2", LOSERSCHESS) cls.widgets["playVariant2Radio"].set_tooltip_text( variants[variant2].__desc__) # The "variant" has to come before players, because the engine positions # in the user comboboxes can be different in different variants for key in ("whitePlayerCombobox", "blackPlayerCombobox", "skillSlider1", "skillSlider2", "notimeRadio", "blitzRadio", "rapidRadio", "normalRadio", "classicalRadio", "playNormalRadio", "playVariant1Radio", "playVariant2Radio"): uistuff.keep(cls.widgets[key], key) # We don't want the dialog to deallocate when closed. Rather we hide # it on respond cls.widgets["newgamedialog"].connect("delete_event", lambda *a: True)
def _init (cls): cls.widgets = uistuff.GladeWidgets ("newInOut.glade") uistuff.createCombo(cls.widgets["whitePlayerCombobox"], name="whitePlayerCombobox") uistuff.createCombo(cls.widgets["blackPlayerCombobox"], name="blackPlayerCombobox") cls.widgets["playersIcon"].set_from_pixbuf(big_people) cls.widgets["timeIcon"].set_from_pixbuf(big_time) def on_playerCombobox_changed (widget, skillHbox): skillHbox.props.visible = widget.get_active() > 0 cls.widgets["whitePlayerCombobox"].connect( "changed", on_playerCombobox_changed, cls.widgets["skillHbox1"]) cls.widgets["blackPlayerCombobox"].connect( "changed", on_playerCombobox_changed, cls.widgets["skillHbox2"]) cls.widgets["whitePlayerCombobox"].set_active(0) cls.widgets["blackPlayerCombobox"].set_active(1) def on_skill_changed (scale, image): image.set_from_pixbuf(skillToIcon[int(scale.get_value())]) cls.widgets["skillSlider1"].connect("value-changed", on_skill_changed, cls.widgets["skillIcon1"]) cls.widgets["skillSlider2"].connect("value-changed", on_skill_changed, cls.widgets["skillIcon2"]) cls.widgets["skillSlider1"].set_value(3) cls.widgets["skillSlider2"].set_value(3) cls.__initTimeRadio(_("Blitz"), "ngblitz", cls.widgets["blitzRadio"], cls.widgets["configImageBlitz"], 5, 0) cls.__initTimeRadio(_("Rapid"), "ngrapid", cls.widgets["rapidRadio"], cls.widgets["configImageRapid"], 15, 5) cls.__initTimeRadio(_("Normal"), "ngnormal", cls.widgets["normalRadio"], cls.widgets["configImageNormal"], 40, 15) cls.__initVariantRadio("ngvariant1", cls.widgets["playVariant1Radio"], cls.widgets["configImageVariant1"], FISCHERRANDOMCHESS) cls.__initVariantRadio("ngvariant2", cls.widgets["playVariant2Radio"], cls.widgets["configImageVariant2"], LOSERSCHESS) #@idle_add 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__) data = [(item[0], item[1]) for item in playerItems[variant]] uistuff.updateCombo(cls.widgets["blackPlayerCombobox"], data) uistuff.updateCombo(cls.widgets["whitePlayerCombobox"], data) discoverer.connect_after("all_engines_discovered", updateCombos) updateCombos(discoverer) conf.notify_add("ngvariant1", updateCombos) conf.notify_add("ngvariant2", updateCombos) cls.widgets["playNormalRadio"].connect("toggled", updateCombos) cls.widgets["playNormalRadio"].set_tooltip_text(variants[NORMALCHESS].__desc__) cls.widgets["playVariant1Radio"].connect("toggled", updateCombos) variant1 = conf.get("ngvariant1", FISCHERRANDOMCHESS) cls.widgets["playVariant1Radio"].set_tooltip_text(variants[variant1].__desc__) cls.widgets["playVariant2Radio"].connect("toggled", updateCombos) variant2 = conf.get("ngvariant2", LOSERSCHESS) cls.widgets["playVariant2Radio"].set_tooltip_text(variants[variant2].__desc__) # The "variant" has to come before players, because the engine positions # in the user comboboxes can be different in different variants for key in ("whitePlayerCombobox", "blackPlayerCombobox", "skillSlider1", "skillSlider2", "notimeRadio", "blitzRadio", "rapidRadio", "normalRadio", "playNormalRadio", "playVariant1Radio", "playVariant2Radio"): uistuff.keep(cls.widgets[key], key) # We don't want the dialog to deallocate when closed. Rather we hide # it on respond cls.widgets["newgamedialog"].connect("delete_event", lambda *a: True)
def __init__(self, widgets): self.widgets = widgets # Options on by default for key in ("opening_check", "endgame_check", "online_egtb_check", "analyzer_check", "inv_analyzer_check"): uistuff.keep(widgets[key], key, 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 # Let Stockfish to be default analyzer in Windows installer default = discoverer.getEngineN(-1).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)
def __init__(self, widgets): self.widgets = widgets self.dialog = self.widgets["manage_engines_dialog"] self.cur_engine = None self.default_workdir = getEngineDataPrefix() uistuff.keepWindowSize("engineswindow", self.dialog) # Put engines into tree store self.allstore = Gtk.ListStore(Pixbuf, str) self.tv = self.widgets["engines_treeview"] self.tv.set_model(self.allstore) self.tv.append_column( Gtk.TreeViewColumn("Flag", Gtk.CellRendererPixbuf(), pixbuf=0)) name_renderer = Gtk.CellRendererText() name_renderer.set_property("editable", False) self.tv.append_column(Gtk.TreeViewColumn("Name", name_renderer, text=1)) # Add cell renderer to protocol combo column protocol_combo = self.widgets["engine_protocol_combo"] protocol_combo.set_name("engine_protocol_combo") cell = Gtk.CellRendererText() protocol_combo.pack_start(cell, True) protocol_combo.add_attribute(cell, "text", 0) # Add columns and cell renderers to options treeview self.options_store = Gtk.ListStore(str, str, GObject.TYPE_PYOBJECT) optv = self.widgets["options_treeview"] optv.set_model(self.options_store) optv.append_column( Gtk.TreeViewColumn(" ", Gtk.CellRendererText(), text=0)) optv.append_column( Gtk.TreeViewColumn(_("Option"), Gtk.CellRendererText(), text=1)) optv.append_column( Gtk.TreeViewColumn(_("Value"), KeyValueCellRenderer(self.options_store), data=2)) self.update_store() def do_update_store(self, *args): GLib.idle_add(engine_dialog.update_store) discoverer.connect_after("engine_discovered", do_update_store) ################################################################ # remove button ################################################################ def remove(button): if self.cur_engine is not None: self.widgets['remove_engine_button'].set_sensitive(False) discoverer.removeEngine(self.cur_engine) selection = self.tv.get_selection() result = selection.get_selected() if result is not None: model, ts_iter = result model.remove(ts_iter) if model.iter_n_children() == 0: clearView() # Notify playerCombos in NewGameTasker discoverer.emit("all_engines_discovered") self.widgets["remove_engine_button"].connect("clicked", remove) ################################################################ # add button ################################################################ engine_chooser_dialog = Gtk.FileChooserDialog( _("Select engine"), mainwindow(), Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) filter = Gtk.FileFilter() filter.set_name(_("Executable files")) filter.add_mime_type("application/x-executable") filter.add_mime_type("application/x-sharedlib") filter.add_mime_type("application/x-ms-dos-executable") filter.add_mime_type("application/x-msdownload") filter.add_pattern("*.exe") for vm in VM_LIST: filter.add_pattern("*%s" % vm.ext) engine_chooser_dialog.add_filter(filter) self.add = False def add(button): self.add = True response = engine_chooser_dialog.run() if response == Gtk.ResponseType.OK: new_engine = engine_chooser_dialog.get_filename() binname = os.path.split(new_engine)[1] ext = os.path.splitext(new_engine)[1] # Verify if the engine already exists under the same name if new_engine != "": for eng in discoverer.getEngines(): if eng["command"] == new_engine: msg_dia = Gtk.MessageDialog( mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup( _("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text( _("The engine is already installed under the same name" )) msg_dia.run() msg_dia.hide() new_engine = "" break # Detect the host application if new_engine != "": vm_name = None vm_args = None vmpath = "" # Scripting for vm in VM_LIST: if ext == vm.ext: vm_name = vm.name vm_args = vm.args break # Wine for Windows application under Linux if vm_name is None and new_engine.lower().endswith( ".exe") and sys.platform != "win32": vm_name = "wine" # Check that the interpreter is available if vm_name is not None: vmpath = shutil.which(vm_name, mode=os.R_OK | os.X_OK) if vmpath is None: msg_dia = Gtk.MessageDialog( mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup( _("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text( vm_name + _(" is not installed")) msg_dia.run() msg_dia.hide() new_engine = "" # Next checks if new_engine: vm_ext_list = [vm.ext for vm in VM_LIST] if ext not in vm_ext_list and not os.access( new_engine, os.X_OK): msg_dia = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup( _("<big><b>%s is not marked executable in the filesystem</b></big>" % new_engine)) msg_dia.format_secondary_text( _("Try chmod a+x %s" % new_engine)) msg_dia.run() msg_dia.hide() self.add = False engine_chooser_dialog.hide() return try: engine_command = [] if vmpath: engine_command.append(vmpath) if vm_args is not None: engine_command += vm_args engine_command.append(new_engine) # Search the engines based on the most expectable protocol refeng = discoverer.getReferencedEngine(binname) if refeng is not None and refeng[ "protocol"] == "xboard": checkers = [is_cecp, is_uci] else: checkers = [is_uci, is_cecp] uci = False for checker in checkers: check_ok = checker(engine_command) if check_ok: uci = checker is is_uci break if not check_ok: # restore the original engine = discoverer.getEngineByName( self.cur_engine) engine_chooser_dialog.set_filename( engine["command"]) msg_dia = Gtk.MessageDialog( mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup( _("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text( _("There is something wrong with this executable" )) msg_dia.run() msg_dia.hide() engine_chooser_dialog.hide() self.add = False engine_chooser_dialog.hide() return self.widgets["engine_command_entry"].set_text( new_engine) self.widgets["engine_protocol_combo"].set_active( 0 if uci else 1) self.widgets["engine_args_entry"].set_text("") # active = self.widgets["engine_protocol_combo"].get_active() protocol = "uci" if uci else "xboard" # print(binname, new_engine, protocol, vm_name, vm_args) discoverer.addEngine(binname, new_engine, protocol, vm_name, vm_args) self.cur_engine = binname self.add = False discoverer.discover() except Exception: msg_dia = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup( _("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text( _("There is something wrong with this executable")) msg_dia.run() msg_dia.hide() self.add = False engine_chooser_dialog.hide() return else: # restore the original engine = discoverer.getEngineByName(self.cur_engine) engine_chooser_dialog.set_filename(engine["command"]) engine_chooser_dialog.hide() self.widgets["add_engine_button"].connect("clicked", add) ################################################################ # add in mass button ################################################################ def addInMass(button): # Ask the user to select a folder folder_dlg = Gtk.FileChooserDialog( _("Choose a folder"), None, Gtk.FileChooserAction.SELECT_FOLDER, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) answer = folder_dlg.run() path = folder_dlg.get_filename() folder_dlg.destroy() # Search for the engines if answer != Gtk.ResponseType.OK: return False possibleFiles = listEnginesFromPath(path) # Remove the existing engines from the list def isNewEngine(path): sfn = os.path.basename(path) for engine in discoverer.getEngines(): if sfn in engine.get( "command"): # The short name must be unique return False return True possibleFiles = [fn for fn in possibleFiles if isNewEngine(fn)] if len(possibleFiles) == 0: return False # Prepare the result in a dialog mass_dialog = self.widgets["engine_list_dialog"] self.widgets["mass_path_label"].set_text(path) mass_list = self.widgets["mass_list_treeview"] if len(mass_list.get_columns()) == 0: # Not initialized yet mass_store = Gtk.ListStore(bool, str) mass_list.set_model(mass_store) def checkbox_renderer_cb(cell, path, model): model[path][0] = not model[path][0] return checkbox_renderer = Gtk.CellRendererToggle() checkbox_renderer.set_property("activatable", True) checkbox_renderer.connect("toggled", checkbox_renderer_cb, mass_store) mass_list.append_column( Gtk.TreeViewColumn(_("Import"), checkbox_renderer, active=0)) mass_list.append_column( Gtk.TreeViewColumn(_("File name"), Gtk.CellRendererText(), text=1)) else: mass_store = mass_list.get_model() mass_store.clear() for fn in possibleFiles: mass_store.append([False, fn[len(path):]]) # Show the dialog answer = mass_dialog.run() mass_dialog.hide() if answer != Gtk.ResponseType.OK.real: return False # Add the new engines self.add = True found = False for entry in mass_store: if entry[0]: newengine = discoverer.getReferencedEngine(path + entry[1]) if newengine is not None: discoverer.addEngineFromReference(newengine) found = True self.add = False if found: discoverer.discover() return True self.widgets["mass_engine_button"].connect("clicked", addInMass) ################################################################ def clearView(): self.selection = True self.cur_engine = None self.widgets["vm_command_entry"].set_text("") self.widgets["vm_args_entry"].set_text("") self.widgets["engine_command_entry"].set_text("") self.widgets["engine_args_entry"].set_text("") self.widgets["engine_protocol_combo"].set_active(0) self.widgets["engine_country_combo"].set_active(0) self.widgets["engine_comment_entry"].set_text("") self.widgets["engine_level_scale"].set_value(ENGINE_DEFAULT_LEVEL) self.options_store.clear() self.selection = False ################################################################ # vm args ################################################################ def vm_args_changed(widget): if self.cur_engine is not None and not self.selection: new_args = self.widgets["vm_args_entry"].get_text().strip() engine = discoverer.getEngineByName(self.cur_engine) old_args = engine.get("vm_args") if new_args != old_args: engine["vm_args"] = new_args.split() self.widgets["vm_args_entry"].connect("changed", vm_args_changed) ################################################################ # engine args ################################################################ def args_changed(widget): if self.cur_engine is not None and not self.selection: new_args = self.widgets["engine_args_entry"].get_text().strip() engine = discoverer.getEngineByName(self.cur_engine) old_args = engine.get("args") if new_args != old_args: engine["args"] = new_args.split() self.widgets["engine_args_entry"].connect("changed", args_changed) ################################################################ # engine working directory ################################################################ dir_chooser_dialog = Gtk.FileChooserDialog( _("Select working directory"), mainwindow(), Gtk.FileChooserAction.SELECT_FOLDER, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) dir_chooser_button = Gtk.FileChooserButton.new_with_dialog( dir_chooser_dialog) self.widgets["dirChooserDock"].add(dir_chooser_button) dir_chooser_button.show() def select_dir(button): new_directory = dir_chooser_dialog.get_filename() engine = discoverer.getEngineByName(self.cur_engine) old_directory = engine.get("workingDirectory") if new_directory != old_directory and new_directory != self.default_workdir: engine["workingDirectory"] = new_directory dir_chooser_button.connect("current-folder-changed", select_dir) ################################################################ # engine protocol ################################################################ def protocol_changed(widget): if self.cur_engine is not None and not self.add and not self.selection: active = self.widgets["engine_protocol_combo"].get_active() new_protocol = "uci" if active == 0 else "xboard" engine = discoverer.getEngineByName(self.cur_engine) old_protocol = engine["protocol"] if new_protocol != old_protocol: command = engine.get("command") engine_command = [] vm_command = engine.get("vm_command") if vm_command is not None: engine_command.append(vm_command) vm_args = engine.get("vm_args") if vm_args is not None: engine_command.append(", ".join(vm_args)) engine_command.append(command) # is the new protocol supported by the engine? if new_protocol == "uci": check_ok = is_uci(engine_command) else: check_ok = is_cecp(engine_command) if check_ok: # discover engine options for new protocol engine["protocol"] = new_protocol engine["recheck"] = True discoverer.discover() else: # restore the original protocol widgets["engine_protocol_combo"].set_active( 0 if old_protocol == "uci" else 1) self.widgets["engine_protocol_combo"].connect("changed", protocol_changed) ################################################################ # engine country ################################################################ def country_changed(widget): if self.cur_engine is not None and not self.selection: engine = discoverer.getEngineByName(self.cur_engine) old_country = discoverer.getCountry(engine) new_country = ISO3166_LIST[widget.get_active()].iso2 if old_country != new_country: engine["country"] = new_country # Refresh the flag in the tree view path = addDataPrefix("flags/%s.png" % new_country) if not os.path.isfile(path): path = addDataPrefix("flags/unknown.png") item = self.tv.get_selection().get_selected() if item is not None: model, ts_iter = item model[ts_iter][0] = get_pixbuf(path) # Notify playerCombos in NewGameTasker discoverer.emit("all_engines_discovered") self.widgets["engine_country_combo"].connect("changed", country_changed) def country_keypressed(widget, event): idx = 0 for iso in ISO3166_LIST: if (idx != 0) and ( (ord(iso.country[0].lower()) == event.keyval) or (ord(iso.country[0].upper()) == event.keyval)): widget.set_active(idx) break idx += 1 self.widgets["engine_country_combo"].connect("key-press-event", country_keypressed) ################################################################ # comment changed ################################################################ def comment_changed(widget): if self.cur_engine is not None and not self.selection: new_comment = self.widgets["engine_comment_entry"].get_text( ).strip() engine = discoverer.getEngineByName(self.cur_engine) old_comment = engine.get("comment") if new_comment != old_comment: engine["comment"] = new_comment self.widgets["engine_comment_entry"].connect("changed", comment_changed) ################################################################ # level changed ################################################################ def level_changed(widget): if self.cur_engine is not None and not self.selection: new_level = widget.get_value() engine = discoverer.getEngineByName(self.cur_engine) old_level = engine.get("level") if new_level != old_level: engine["level"] = int(new_level) self.widgets["engine_level_scale"].connect("value-changed", level_changed) ################################################################ # engine tree ################################################################ self.selection = False def selection_changed(treeselection): store, tv_iter = self.tv.get_selection().get_selected() if tv_iter: self.selection = True path = store.get_path(tv_iter) indices = path.get_indices() row = indices[0] name = store[row][1] self.cur_engine = name engine = discoverer.getEngineByName(name) if "PyChess.py" in engine["command"]: self.widgets['remove_engine_button'].set_sensitive(False) else: self.widgets['remove_engine_button'].set_sensitive(True) self.widgets["engine_command_entry"].set_text( engine["command"]) engine_chooser_dialog.set_filename(engine["command"]) args = [] if engine.get("args") is None else engine.get("args") self.widgets["engine_args_entry"].set_text(' '.join(args)) vm = engine.get("vm_command") self.widgets["vm_command_entry"].set_text( vm if vm is not None else "") args = [] if engine.get("vm_args") is None else engine.get( "vm_args") self.widgets["vm_args_entry"].set_text(' '.join(args)) directory = engine.get("workingDirectory") dir_choice = directory if directory is not None else self.default_workdir dir_chooser_dialog.set_current_folder(dir_choice) self.widgets["engine_protocol_combo"].set_active( 0 if engine["protocol"] == "uci" else 1) self.widgets["engine_country_combo"].set_active(0) country = discoverer.getCountry(engine) idx = 0 for iso in ISO3166_LIST: if iso.iso2 == country: self.widgets["engine_country_combo"].set_active(idx) break idx += 1 comment = engine.get("comment") self.widgets["engine_comment_entry"].set_text( comment if comment is not None else "") level = engine.get("level") try: level = int(level) except Exception: level = ENGINE_DEFAULT_LEVEL self.widgets["engine_level_scale"].set_value(level) self.update_options() self.selection = False tree_selection = self.tv.get_selection() tree_selection.connect('changed', selection_changed) tree_selection.select_path((0, )) selection_changed(tree_selection) ################################################################ # restore the default options of the engine ################################################################ def engine_default_options(button): if self.cur_engine is not None and not self.selection: engine = discoverer.getEngineByName(self.cur_engine) options = engine.get("options") if options: dialog = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.QUESTION, buttons=Gtk.ButtonsType.YES_NO) dialog.set_markup( _("Do you really want to restore the default options of the engine ?" )) response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.YES: for option in options: if "default" in option: option["value"] = option["default"] self.update_options() self.widgets["engine_default_options_button"].connect( "clicked", engine_default_options)
def __init__(self, widgets): self.widgets = widgets # Options on by default for key in ("opening_check", "endgame_check", "online_egtb_check", "analyzer_check", "inv_analyzer_check"): uistuff.keep(widgets[key], key, 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"), None, 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"), None, 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 # Let Stockfish to be default analyzer in Windows installer default = discoverer.getEngineN(-1).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)
def __init__(self, widgets): self.widgets = widgets self.dialog = self.widgets["manage_engines_dialog"] self.cur_engine = None self.default_workdir = getEngineDataPrefix() uistuff.keepWindowSize("engineswindow", self.dialog, defaultSize=(1, 500)) # Put engines into tree store allstore = Gtk.ListStore(Pixbuf, str) self.tv = self.widgets["engines_treeview"] self.tv.set_model(allstore) self.tv.append_column(Gtk.TreeViewColumn( "Flag", Gtk.CellRendererPixbuf(), pixbuf=0)) name_renderer = Gtk.CellRendererText() name_renderer.set_property("editable", True) self.tv.append_column(Gtk.TreeViewColumn("Name", name_renderer, text=1)) def name_edited(renderer, path, new_name): if self.cur_engine is not None: old_name = self.cur_engine if new_name and new_name != old_name: names = [engine["name"] for engine in discoverer.getEngines()] if new_name not in names: engine = discoverer.getEngineByName(self.cur_engine) engine["name"] = new_name discoverer.save() self.cur_engine = new_name update_store() # Notify playerCombos in NewGameTasker discoverer.emit("all_engines_discovered") name_renderer.connect("edited", name_edited) # Add cell renderer to protocol combo column protocol_combo = self.widgets["engine_protocol_combo"] cell = Gtk.CellRendererText() protocol_combo.pack_start(cell, True) protocol_combo.add_attribute(cell, "text", 0) # Add columns and cell renderers to options treeview self.options_store = Gtk.ListStore(str, GObject.TYPE_PYOBJECT) optv = self.widgets["options_treeview"] optv.set_model(self.options_store) optv.append_column(Gtk.TreeViewColumn( "Option", Gtk.CellRendererText(), text=0)) optv.append_column(Gtk.TreeViewColumn( "Data", KeyValueCellRenderer(self.options_store), data=1)) def update_options(*args): if self.cur_engine is not None: engines = discoverer.getEngines() names = [engine["name"] for engine in engines] # After deleting an engine we will select first if self.cur_engine not in names: self.cur_engine = engines[0]["name"] engine = discoverer.getEngineByName(self.cur_engine) options = engine.get("options") if options: self.options_store.clear() for option in options: key = option["name"] val = option if option["type"] != "button": val["default"] = option.get("default") val["value"] = option.get("value", val["default"]) self.options_store.append([key, val]) def update_store(*args): newGameDialog.createPlayerUIGlobals(discoverer) engine_names = [row[1] for row in allstore] new_items = [] # don't add the very first (Human) player to engine store for item in newGameDialog.playerItems[0][1:]: if item[1] not in engine_names: new_items.append(item) iter = None for item in new_items: iter = allstore.append(item) if iter is not None: ts = self.tv.get_selection() ts.select_iter(iter) update_options() update_store() def do_update_store(*args): GLib.idle_add(update_store) discoverer.connect_after("engine_discovered", do_update_store) ################################################################ # remove button ################################################################ def remove(button): if self.cur_engine is not None: self.widgets['remove_engine_button'].set_sensitive(False) engine = discoverer.getEngineByName(self.cur_engine) discoverer.removeEngine(self.cur_engine) discoverer.save() selection = self.tv.get_selection() result = selection.get_selected() if result is not None: model, iter = result model.remove(iter) # Notify playerCombos in NewGameTasker discoverer.emit("all_engines_discovered") self.widgets["remove_engine_button"].connect("clicked", remove) ################################################################ # add button ################################################################ engine_chooser_dialog = Gtk.FileChooserDialog(_("Select engine"), None, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) filter = Gtk.FileFilter() filter.set_name(_("Executable files")) filter.add_mime_type("application/x-executable") filter.add_mime_type("application/x-ms-dos-executable") filter.add_mime_type("application/x-msdownload") filter.add_pattern("*.exe") engine_chooser_dialog.add_filter(filter) self.add = False def add(button): self.add = True response = engine_chooser_dialog.run() if response == Gtk.ResponseType.OK: new_engine = engine_chooser_dialog.get_filename() if new_engine.lower().endswith(".exe") and sys.platform != "win32": vm_name = "wine" vmpath = searchPath(vm_name, access=os.R_OK|os.X_OK) if vmpath is None: d = Gtk.MessageDialog( type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) d.set_markup(_("<big><b>Unable to add %s</b></big>" % new_engine)) d.format_secondary_text(_("wine not installed")) d.run() d.hide() new_engine = "" else: vmpath += " " else: vm_name = None vmpath = "" if new_engine: try: # Some engines support CECP and UCI, but variant engines are CECP, # so we better to start with CECP this case variant_engines = ("fmax", "sjaakii", "sjeng") if any((True for e in variant_engines if e in new_engine.lower())): checkers = [is_cecp, is_uci] else: checkers = [is_uci, is_cecp] uci = False for checker in checkers: ok = checker(vmpath + new_engine) if ok: uci = checker is is_uci break else: continue if not ok: # restore the original engine = discoverer.getEngineByName(self.cur_engine) engine_chooser_dialog.set_filename(engine["command"]) d = Gtk.MessageDialog( type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) d.set_markup(_("<big><b>Unable to add %s</b></big>" % new_engine)) d.format_secondary_text(_("There is something wrong with this executable")) d.run() d.hide() engine_chooser_dialog.hide() return path, binname = os.path.split(new_engine) for e in discoverer.getEngines(): if e["name"] == binname: binname = e["name"] + "(1)" break self.widgets["engine_command_entry"].set_text(new_engine) self.widgets["engine_protocol_combo"].set_active(0 if uci else 1) self.widgets["engine_args_entry"].set_text("") active = self.widgets["engine_protocol_combo"].get_active() protocol = "uci" if uci else "xboard" discoverer.addEngine(binname, new_engine, protocol, vm_name) self.cur_engine = binname self.add = False discoverer.discover() except: d = Gtk.MessageDialog( type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) d.set_markup(_("<big><b>Unable to add %s</b></big>" % new_engine)) d.format_secondary_text(_("There is something wrong with this executable")) d.run() d.hide() else: # restore the original engine = discoverer.getEngineByName(self.cur_engine) engine_chooser_dialog.set_filename(engine["command"]) engine_chooser_dialog.hide() self.widgets["add_engine_button"].connect("clicked", add) ################################################################ # engine args ################################################################ def args_changed(widget): if self.cur_engine is not None: new_args = self.widgets["engine_args_entry"].get_text().strip() engine = discoverer.getEngineByName(self.cur_engine) old_args = engine.get("args") if new_args != old_args: engine["args"] = new_args.split() discoverer.save() self.widgets["engine_args_entry"].connect("changed", args_changed) ################################################################ # engine working directory ################################################################ dir_chooser_dialog = Gtk.FileChooserDialog(_("Select working directory"), None, Gtk.FileChooserAction.SELECT_FOLDER, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) dir_chooser_button = Gtk.FileChooserButton.new_with_dialog(dir_chooser_dialog) self.widgets["dirChooserDock"].add(dir_chooser_button) dir_chooser_button.show() def select_dir(button): new_directory = dir_chooser_dialog.get_filename() engine = discoverer.getEngineByName(self.cur_engine) old_directory = engine.get("workingDirectory") if new_directory != old_directory and new_directory != self.default_workdir: engine["workingDirectory"] = new_directory discoverer.save() dir_chooser_button.connect("current-folder-changed", select_dir) ################################################################ # engine protocol ################################################################ def protocol_changed(widget): if self.cur_engine is not None and not self.add and not self.selection: active = self.widgets["engine_protocol_combo"].get_active() new_protocol = "uci" if active==0 else "xboard" engine = discoverer.getEngineByName(self.cur_engine) old_protocol = engine["protocol"] if new_protocol != old_protocol: engine_command = engine_chooser_dialog.get_filename() # is the new protocol supported by the engine? if new_protocol == "uci": ok = is_uci(engine_command) else: ok = is_cecp(engine_command) if ok: # discover engine options for new protocol engine["protocol"] = new_protocol engine["recheck"] = True discoverer.discover() else: # restore the original protocol widgets["engine_protocol_combo"].set_active(0 if old_protocol=="uci" else 1) self.widgets["engine_protocol_combo"].connect("changed", protocol_changed) ################################################################ # engine tree ################################################################ self.selection = False def selection_changed(treeselection): store, iter = self.tv.get_selection().get_selected() if iter: self.selection = True path = store.get_path(iter) indices = path.get_indices() row = indices[0] name = store[row][1] self.cur_engine = name engine = discoverer.getEngineByName(name) self.widgets['copy_engine_button'].set_sensitive(True) if "PyChess.py" in engine["command"]: self.widgets['remove_engine_button'].set_sensitive(False) else: self.widgets['remove_engine_button'].set_sensitive(True) self.widgets["engine_command_entry"].set_text(engine["command"]) engine_chooser_dialog.set_filename(engine["command"]) args = [] if engine.get("args") is None else engine.get("args") self.widgets["engine_args_entry"].set_text(' '.join(args)) directory = engine.get("workingDirectory") d = directory if directory is not None else self.default_workdir dir_chooser_dialog.set_current_folder(d) self.widgets["engine_protocol_combo"].set_active(0 if engine["protocol"]=="uci" else 1) update_options() self.selection = False tree_selection = self.tv.get_selection() tree_selection.connect('changed', selection_changed) tree_selection.select_path((0,))
def __init__(self, widgets): self.widgets = widgets self.dialog = self.widgets["manage_engines_dialog"] self.cur_engine = None self.default_workdir = getEngineDataPrefix() uistuff.keepWindowSize("engineswindow", self.dialog) # Put engines into tree store self.allstore = Gtk.ListStore(Pixbuf, str) self.tv = self.widgets["engines_treeview"] self.tv.set_model(self.allstore) self.tv.append_column(Gtk.TreeViewColumn("Flag", Gtk.CellRendererPixbuf(), pixbuf=0)) name_renderer = Gtk.CellRendererText() name_renderer.set_property("editable", False) self.tv.append_column(Gtk.TreeViewColumn("Name", name_renderer, text=1)) # Add cell renderer to protocol combo column protocol_combo = self.widgets["engine_protocol_combo"] protocol_combo.set_name("engine_protocol_combo") cell = Gtk.CellRendererText() protocol_combo.pack_start(cell, True) protocol_combo.add_attribute(cell, "text", 0) # Add columns and cell renderers to options treeview self.options_store = Gtk.ListStore(str, str, GObject.TYPE_PYOBJECT) optv = self.widgets["options_treeview"] optv.set_model(self.options_store) optv.append_column(Gtk.TreeViewColumn(" ", Gtk.CellRendererText(), text=0)) optv.append_column(Gtk.TreeViewColumn(_("Option"), Gtk.CellRendererText(), text=1)) optv.append_column(Gtk.TreeViewColumn(_("Value"), KeyValueCellRenderer(self.options_store), data=2)) self.update_store() def do_update_store(self, *args): GLib.idle_add(engine_dialog.update_store) discoverer.connect_after("engine_discovered", do_update_store) ################################################################ # remove button ################################################################ def remove(button): if self.cur_engine is not None: self.widgets['remove_engine_button'].set_sensitive(False) discoverer.removeEngine(self.cur_engine) selection = self.tv.get_selection() result = selection.get_selected() if result is not None: model, ts_iter = result model.remove(ts_iter) if model.iter_n_children() == 0: clearView() # Notify playerCombos in NewGameTasker discoverer.emit("all_engines_discovered") self.widgets["remove_engine_button"].connect("clicked", remove) ################################################################ # add button ################################################################ engine_chooser_dialog = Gtk.FileChooserDialog( _("Select engine"), mainwindow(), Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) filter = Gtk.FileFilter() filter.set_name(_("Executable files")) filter.add_mime_type("application/x-executable") filter.add_mime_type("application/x-sharedlib") filter.add_mime_type("application/x-ms-dos-executable") filter.add_mime_type("application/x-msdownload") filter.add_pattern("*.exe") for vm in VM_LIST: filter.add_pattern("*%s" % vm.ext) engine_chooser_dialog.add_filter(filter) self.add = False def add(button): self.add = True response = engine_chooser_dialog.run() if response == Gtk.ResponseType.OK: new_engine = engine_chooser_dialog.get_filename() binname = os.path.split(new_engine)[1] ext = os.path.splitext(new_engine)[1] # Verify if the engine already exists under the same name if new_engine != "": for eng in discoverer.getEngines(): if eng["command"] == new_engine: msg_dia = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup(_("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text(_("The engine is already installed under the same name")) msg_dia.run() msg_dia.hide() new_engine = "" break # Detect the host application if new_engine != "": vm_name = None vm_args = None vmpath = "" # Scripting for vm in VM_LIST: if ext == vm.ext: vm_name = vm.name vm_args = vm.args break # Wine for Windows application under Linux if vm_name is None and new_engine.lower().endswith(".exe") and sys.platform != "win32": vm_name = "wine" # Check that the interpreter is available if vm_name is not None: vmpath = shutil.which(vm_name, mode=os.R_OK | os.X_OK) if vmpath is None: msg_dia = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup(_("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text(vm_name + _(" is not installed")) msg_dia.run() msg_dia.hide() new_engine = "" # Next checks if new_engine: vm_ext_list = [vm.ext for vm in VM_LIST] if ext not in vm_ext_list and not os.access(new_engine, os.X_OK): msg_dia = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup(_("<big><b>%s is not marked executable in the filesystem</b></big>" % new_engine)) msg_dia.format_secondary_text(_("Try chmod a+x %s" % new_engine)) msg_dia.run() msg_dia.hide() self.add = False engine_chooser_dialog.hide() return try: engine_command = [] if vmpath: engine_command.append(vmpath) if vm_args is not None: engine_command.append(vm_args) engine_command.append(new_engine) # Search the engines based on the most expectable protocol refeng = discoverer.getReferencedEngine(binname) if refeng is not None and refeng["protocol"] == "xboard": checkers = [is_cecp, is_uci] else: checkers = [is_uci, is_cecp] uci = False for checker in checkers: check_ok = checker(engine_command) if check_ok: uci = checker is is_uci break else: continue if not check_ok: # restore the original engine = discoverer.getEngineByName(self.cur_engine) engine_chooser_dialog.set_filename(engine["command"]) msg_dia = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup( _("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text(_("There is something wrong with this executable")) msg_dia.run() msg_dia.hide() engine_chooser_dialog.hide() self.add = False engine_chooser_dialog.hide() return self.widgets["engine_command_entry"].set_text(new_engine) self.widgets["engine_protocol_combo"].set_active(0 if uci else 1) self.widgets["engine_args_entry"].set_text("") # active = self.widgets["engine_protocol_combo"].get_active() protocol = "uci" if uci else "xboard" if vm_args is not None: vm_args = vm_args.split(",") # print(binname, new_engine, protocol, vm_name, vm_args) discoverer.addEngine(binname, new_engine, protocol, vm_name, vm_args) self.cur_engine = binname self.add = False discoverer.discover() except Exception: msg_dia = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup(_("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text(_("There is something wrong with this executable")) msg_dia.run() msg_dia.hide() self.add = False engine_chooser_dialog.hide() return else: # restore the original engine = discoverer.getEngineByName(self.cur_engine) engine_chooser_dialog.set_filename(engine["command"]) engine_chooser_dialog.hide() self.widgets["add_engine_button"].connect("clicked", add) ################################################################ def clearView(): self.selection = True self.cur_engine = None self.widgets["vm_command_entry"].set_text("") self.widgets["vm_args_entry"].set_text("") self.widgets["engine_command_entry"].set_text("") self.widgets["engine_args_entry"].set_text("") self.widgets["engine_protocol_combo"].set_active(0) self.widgets["engine_country_combo"].set_active(0) self.widgets["engine_comment_entry"].set_text("") self.widgets["engine_level_scale"].set_value(defaultEngineLevel) self.options_store.clear() self.selection = False ################################################################ # vm args ################################################################ def vm_args_changed(widget): if self.cur_engine is not None and not self.selection: new_args = self.widgets["vm_args_entry"].get_text().strip() engine = discoverer.getEngineByName(self.cur_engine) old_args = engine.get("vm_args") if new_args != old_args: engine["vm_args"] = new_args.split() self.widgets["vm_args_entry"].connect("changed", vm_args_changed) ################################################################ # engine args ################################################################ def args_changed(widget): if self.cur_engine is not None and not self.selection: new_args = self.widgets["engine_args_entry"].get_text().strip() engine = discoverer.getEngineByName(self.cur_engine) old_args = engine.get("args") if new_args != old_args: engine["args"] = new_args.split() self.widgets["engine_args_entry"].connect("changed", args_changed) ################################################################ # engine working directory ################################################################ dir_chooser_dialog = Gtk.FileChooserDialog( _("Select working directory"), mainwindow(), Gtk.FileChooserAction.SELECT_FOLDER, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) dir_chooser_button = Gtk.FileChooserButton.new_with_dialog( dir_chooser_dialog) self.widgets["dirChooserDock"].add(dir_chooser_button) dir_chooser_button.show() def select_dir(button): new_directory = dir_chooser_dialog.get_filename() engine = discoverer.getEngineByName(self.cur_engine) old_directory = engine.get("workingDirectory") if new_directory != old_directory and new_directory != self.default_workdir: engine["workingDirectory"] = new_directory dir_chooser_button.connect("current-folder-changed", select_dir) ################################################################ # engine protocol ################################################################ def protocol_changed(widget): if self.cur_engine is not None and not self.add and not self.selection: active = self.widgets["engine_protocol_combo"].get_active() new_protocol = "uci" if active == 0 else "xboard" engine = discoverer.getEngineByName(self.cur_engine) old_protocol = engine["protocol"] if new_protocol != old_protocol: command = engine.get("command") engine_command = [] vm_command = engine.get("vm_command") if vm_command is not None: engine_command.append(vm_command) vm_args = engine.get("vm_args") if vm_args is not None: engine_command.append(", ".join(vm_args)) engine_command.append(command) # is the new protocol supported by the engine? if new_protocol == "uci": check_ok = is_uci(engine_command) else: check_ok = is_cecp(engine_command) if check_ok: # discover engine options for new protocol engine["protocol"] = new_protocol engine["recheck"] = True discoverer.discover() else: # restore the original protocol widgets["engine_protocol_combo"].set_active( 0 if old_protocol == "uci" else 1) self.widgets["engine_protocol_combo"].connect("changed", protocol_changed) ################################################################ # engine country ################################################################ def country_changed(widget): if self.cur_engine is not None and not self.selection: engine = discoverer.getEngineByName(self.cur_engine) old_country = discoverer.getCountry(engine) new_country = ISO3166_LIST[widget.get_active()].iso2 if old_country != new_country: engine["country"] = new_country # Refresh the flag in the tree view path = addDataPrefix("flags/%s.png" % new_country) if not os.path.isfile(path): path = addDataPrefix("flags/unknown.png") item = self.tv.get_selection().get_selected() if item is not None: model, ts_iter = item model[ts_iter][0] = get_pixbuf(path) # Notify playerCombos in NewGameTasker discoverer.emit("all_engines_discovered") self.widgets["engine_country_combo"].connect("changed", country_changed) def country_keypressed(widget, event): idx = 0 for iso in ISO3166_LIST: if (idx != 0) and ((ord(iso.country[0].lower()) == event.keyval) or (ord(iso.country[0].upper()) == event.keyval)): widget.set_active(idx) break idx += 1 self.widgets["engine_country_combo"].connect("key-press-event", country_keypressed) ################################################################ # comment changed ################################################################ def comment_changed(widget): if self.cur_engine is not None and not self.selection: new_comment = self.widgets["engine_comment_entry"].get_text().strip() engine = discoverer.getEngineByName(self.cur_engine) old_comment = engine.get("comment") if new_comment != old_comment: engine["comment"] = new_comment self.widgets["engine_comment_entry"].connect("changed", comment_changed) ################################################################ # level changed ################################################################ def level_changed(widget): if self.cur_engine is not None and not self.selection: new_level = widget.get_value() engine = discoverer.getEngineByName(self.cur_engine) old_level = engine.get("level") if new_level != old_level: engine["level"] = int(new_level) self.widgets["engine_level_scale"].connect("value-changed", level_changed) ################################################################ # engine tree ################################################################ self.selection = False def selection_changed(treeselection): store, tv_iter = self.tv.get_selection().get_selected() if tv_iter: self.selection = True path = store.get_path(tv_iter) indices = path.get_indices() row = indices[0] name = store[row][1] self.cur_engine = name engine = discoverer.getEngineByName(name) if "PyChess.py" in engine["command"]: self.widgets['remove_engine_button'].set_sensitive(False) else: self.widgets['remove_engine_button'].set_sensitive(True) self.widgets["engine_command_entry"].set_text(engine["command"]) engine_chooser_dialog.set_filename(engine["command"]) args = [] if engine.get("args") is None else engine.get("args") self.widgets["engine_args_entry"].set_text(' '.join(args)) vm = engine.get("vm_command") self.widgets["vm_command_entry"].set_text(vm if vm is not None else "") args = [] if engine.get("vm_args") is None else engine.get("vm_args") self.widgets["vm_args_entry"].set_text(' '.join(args)) directory = engine.get("workingDirectory") dir_choice = directory if directory is not None else self.default_workdir dir_chooser_dialog.set_current_folder(dir_choice) self.widgets["engine_protocol_combo"].set_active(0 if engine["protocol"] == "uci" else 1) self.widgets["engine_country_combo"].set_active(0) country = discoverer.getCountry(engine) idx = 0 for iso in ISO3166_LIST: if iso.iso2 == country: self.widgets["engine_country_combo"].set_active(idx) break idx += 1 comment = engine.get("comment") self.widgets["engine_comment_entry"].set_text(comment if comment is not None else "") level = engine.get("level") try: level = int(level) if level else defaultEngineLevel except Exception: level = defaultEngineLevel self.widgets["engine_level_scale"].set_value(level) self.update_options() self.selection = False tree_selection = self.tv.get_selection() tree_selection.connect('changed', selection_changed) tree_selection.select_path((0, )) selection_changed(tree_selection) ################################################################ # restore the default options of the engine ################################################################ def engine_default_options(button): if self.cur_engine is not None and not self.selection: engine = discoverer.getEngineByName(self.cur_engine) options = engine.get("options") if options: dialog = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.QUESTION, buttons=Gtk.ButtonsType.YES_NO) dialog.set_markup(_("Do you really want to restore the default options of the engine ?")) response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.YES: for option in options: if "default" in option: option["value"] = option["default"] self.update_options() self.widgets["engine_default_options_button"].connect("clicked", engine_default_options)
def initialize(gameDic): uistuff.keep(widgets["fromCurrent"], "fromCurrent", first_value=True) uistuff.keep(widgets["threatPV"], "threatPV") uistuff.keep(widgets["showEval"], "showEval") uistuff.keep(widgets["showBlunder"], "showBlunder", first_value=True) uistuff.keep(widgets["max_analysis_spin"], "max_analysis_spin", first_value=3) uistuff.keep(widgets["variation_thresold_spin"], "variation_thresold_spin", first_value=50) # Analyzing engines uistuff.createCombo(widgets["ana_combobox"]) from pychess.widgets import newGameDialog @idle_add def update_analyzers_store(discoverer): data = [(item[0], item[1]) for item in newGameDialog.analyzerItems] uistuff.updateCombo(widgets["ana_combobox"], data) discoverer.connect_after("all_engines_discovered", update_analyzers_store) update_analyzers_store(discoverer) uistuff.keep( widgets["ana_combobox"], "ana_combobox", anal_combo_get_value, lambda combobox, value: anal_combo_set_value( combobox, value, "hint_mode", "analyzer_check", HINT)) def hide_window(button, *args): widgets["analyze_game"].hide() return True def abort(): stop_event.set() widgets["analyze_game"].hide() 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.replaceMessages(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) if threat_PV: 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 widgets["analyze_game"].connect("delete-event", hide_window) widgets["analyze_cancel_button"].connect("clicked", hide_window) widgets["analyze_ok_button"].connect("clicked", run_analyze)
def __init__(self, widgets): self.widgets = widgets self.dialog = self.widgets["manage_engines_dialog"] self.cur_engine = None self.default_workdir = getEngineDataPrefix() uistuff.keepWindowSize("engineswindow", self.dialog) # Put engines into tree store allstore = Gtk.ListStore(Pixbuf, str) self.tv = self.widgets["engines_treeview"] self.tv.set_model(allstore) self.tv.append_column(Gtk.TreeViewColumn("Flag", Gtk.CellRendererPixbuf(), pixbuf=0)) name_renderer = Gtk.CellRendererText() name_renderer.set_property("editable", False) self.tv.append_column(Gtk.TreeViewColumn("Name", name_renderer, text=1)) def name_edited(renderer, path, new_name): if self.cur_engine is not None: old_name = self.cur_engine if new_name and new_name != old_name: names = [engine["name"] for engine in discoverer.getEngines()] if new_name not in names: engine = discoverer.getEngineByName(self.cur_engine) engine["name"] = new_name discoverer.save() self.cur_engine = new_name update_store() # Notify playerCombos in NewGameTasker discoverer.emit("all_engines_discovered") name_renderer.connect("edited", name_edited) # Add cell renderer to protocol combo column protocol_combo = self.widgets["engine_protocol_combo"] protocol_combo.set_name("engine_protocol_combo") cell = Gtk.CellRendererText() protocol_combo.pack_start(cell, True) protocol_combo.add_attribute(cell, "text", 0) # Add columns and cell renderers to options treeview self.options_store = Gtk.ListStore(str, GObject.TYPE_PYOBJECT) optv = self.widgets["options_treeview"] optv.set_model(self.options_store) optv.append_column(Gtk.TreeViewColumn("Option", Gtk.CellRendererText(), text=0)) optv.append_column(Gtk.TreeViewColumn("Data", KeyValueCellRenderer( self.options_store), data=1)) def update_options(*args): if self.cur_engine is not None: engines = discoverer.getEngines() names = [engine["name"] for engine in engines] # After deleting an engine we will select first if self.cur_engine not in names: self.cur_engine = engines[0]["name"] engine = discoverer.getEngineByName(self.cur_engine) options = engine.get("options") self.options_store.clear() if options: options.sort(key=lambda obj: obj['name'].lower() if 'name' in obj else '') for option in options: key = option["name"] val = option if option["type"] != "button": val["default"] = option.get("default") val["value"] = option.get("value", val["default"]) self.options_store.append([key, val]) def update_store(*args): newGameDialog.createPlayerUIGlobals(discoverer) engine_names = [row[1] for row in allstore] new_items = [] # don't add the very first (Human) player to engine store for item in newGameDialog.allEngineItems: if item[1] not in engine_names: new_items.append(item) ts_iter = None for item in new_items: ts_iter = allstore.append(item) if ts_iter is not None: text_select = self.tv.get_selection() text_select.select_iter(ts_iter) update_options() update_store() def do_update_store(*args): GLib.idle_add(update_store) discoverer.connect_after("engine_discovered", do_update_store) ################################################################ # remove button ################################################################ def remove(button): if self.cur_engine is not None: self.widgets['remove_engine_button'].set_sensitive(False) # engine = discoverer.getEngineByName(self.cur_engine) discoverer.removeEngine(self.cur_engine) discoverer.save() selection = self.tv.get_selection() result = selection.get_selected() if result is not None: model, ts_iter = result model.remove(ts_iter) # Notify playerCombos in NewGameTasker discoverer.emit("all_engines_discovered") self.widgets["remove_engine_button"].connect("clicked", remove) ################################################################ # add button ################################################################ engine_chooser_dialog = Gtk.FileChooserDialog( _("Select engine"), mainwindow(), Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) filter = Gtk.FileFilter() filter.set_name(_("Executable files")) filter.add_mime_type("application/x-executable") filter.add_mime_type("application/x-sharedlib") filter.add_mime_type("application/x-ms-dos-executable") filter.add_mime_type("application/x-msdownload") filter.add_pattern("*.exe") for vm in VM_LIST: filter.add_pattern("*%s" % vm.ext) engine_chooser_dialog.add_filter(filter) self.add = False def add(button): self.add = True response = engine_chooser_dialog.run() if response == Gtk.ResponseType.OK: new_engine = engine_chooser_dialog.get_filename() vm_name = None vm_args = None vmpath = "" if new_engine.lower().endswith(".exe") and sys.platform != "win32": vm_name = "wine" vmpath = shutil.which(vm_name, mode=os.R_OK | os.X_OK) if vmpath is None: msg_dia = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup(_("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text(_("wine not installed")) msg_dia.run() msg_dia.hide() new_engine = "" for vm in VM_LIST: ext = os.path.splitext(new_engine)[1] if ext == vm.ext: vm_name = vm.name vm_args = vm.args vmpath = shutil.which(vm_name, mode=os.R_OK | os.X_OK) if vmpath is None: msg_dia = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup(_("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text(vm_name + _(" is not installed")) msg_dia.run() msg_dia.hide() new_engine = "" break if new_engine: vm_ext_list = [vm.ext for vm in VM_LIST] if ext not in vm_ext_list and not os.access(new_engine, os.X_OK): msg_dia = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup(_("<big><b>%s is not marked executable in the filesystem</b></big>" % new_engine)) msg_dia.format_secondary_text(_("Try chmod a+x %s" % new_engine)) msg_dia.run() msg_dia.hide() self.add = False engine_chooser_dialog.hide() return try: engine_command = [] if vmpath: engine_command.append(vmpath) if vm_args is not None: engine_command.append(vm_args) engine_command.append(new_engine) # Some engines support CECP and UCI, but main variant engines are CECP, # so we better to start with CECP this case variant_engines = ("fmax", "sjaakii", "sjeng") if any((True for eng in variant_engines if eng in new_engine.lower())): checkers = [is_cecp, is_uci] else: checkers = [is_uci, is_cecp] uci = False for checker in checkers: check_ok = checker(engine_command) if check_ok: uci = checker is is_uci break else: continue if not check_ok: # restore the original engine = discoverer.getEngineByName( self.cur_engine) engine_chooser_dialog.set_filename(engine[ "command"]) msg_dia = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup( _("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text(_( "There is something wrong with this executable")) msg_dia.run() msg_dia.hide() engine_chooser_dialog.hide() self.add = False engine_chooser_dialog.hide() return binname = os.path.split(new_engine)[1] for eng in discoverer.getEngines(): if eng["name"] == binname: binname = eng["name"] + "(1)" break self.widgets["engine_command_entry"].set_text(new_engine) self.widgets["engine_protocol_combo"].set_active(0 if uci else 1) self.widgets["engine_args_entry"].set_text("") # active = self.widgets["engine_protocol_combo"].get_active() protocol = "uci" if uci else "xboard" if vm_args is not None: vm_args = vm_args.split(",") # print(binname, new_engine, protocol, vm_name, vm_args) discoverer.addEngine(binname, new_engine, protocol, vm_name, vm_args, "unknown") self.cur_engine = binname self.add = False discoverer.discover() except Exception: msg_dia = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup(_("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text(_( "There is something wrong with this executable")) msg_dia.run() msg_dia.hide() self.add = False engine_chooser_dialog.hide() return else: # restore the original engine = discoverer.getEngineByName(self.cur_engine) engine_chooser_dialog.set_filename(engine["command"]) engine_chooser_dialog.hide() self.widgets["add_engine_button"].connect("clicked", add) ################################################################ # vm args ################################################################ def vm_args_changed(widget): if self.cur_engine is not None: new_args = self.widgets["vm_args_entry"].get_text().strip() engine = discoverer.getEngineByName(self.cur_engine) old_args = engine.get("vm_args") if new_args != old_args: engine["vm_args"] = new_args.split() discoverer.save() self.widgets["vm_args_entry"].connect("changed", vm_args_changed) ################################################################ # engine args ################################################################ def args_changed(widget): if self.cur_engine is not None: new_args = self.widgets["engine_args_entry"].get_text().strip() engine = discoverer.getEngineByName(self.cur_engine) old_args = engine.get("args") if new_args != old_args: engine["args"] = new_args.split() discoverer.save() self.widgets["engine_args_entry"].connect("changed", args_changed) ################################################################ # engine working directory ################################################################ dir_chooser_dialog = Gtk.FileChooserDialog( _("Select working directory"), mainwindow(), Gtk.FileChooserAction.SELECT_FOLDER, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) dir_chooser_button = Gtk.FileChooserButton.new_with_dialog( dir_chooser_dialog) self.widgets["dirChooserDock"].add(dir_chooser_button) dir_chooser_button.show() def select_dir(button): new_directory = dir_chooser_dialog.get_filename() engine = discoverer.getEngineByName(self.cur_engine) old_directory = engine.get("workingDirectory") if new_directory != old_directory and new_directory != self.default_workdir: engine["workingDirectory"] = new_directory discoverer.save() dir_chooser_button.connect("current-folder-changed", select_dir) ################################################################ # engine protocol ################################################################ def protocol_changed(widget): if self.cur_engine is not None and not self.add and not self.selection: active = self.widgets["engine_protocol_combo"].get_active() new_protocol = "uci" if active == 0 else "xboard" engine = discoverer.getEngineByName(self.cur_engine) old_protocol = engine["protocol"] if new_protocol != old_protocol: command = engine.get("command") engine_command = [] vm_command = engine.get("vm_command") if vm_command is not None: engine_command.append(vm_command) vm_args = engine.get("vm_args") if vm_args is not None: engine_command.append(", ".join(vm_args)) engine_command.append(command) # is the new protocol supported by the engine? if new_protocol == "uci": check_ok = is_uci(engine_command) else: check_ok = is_cecp(engine_command) if check_ok: # discover engine options for new protocol engine["protocol"] = new_protocol engine["recheck"] = True discoverer.discover() else: # restore the original protocol widgets["engine_protocol_combo"].set_active( 0 if old_protocol == "uci" else 1) self.widgets["engine_protocol_combo"].connect("changed", protocol_changed) ################################################################ # engine country ################################################################ def country_changed(widget): if self.cur_engine is not None and not self.selection: engine = discoverer.getEngineByName(self.cur_engine) old_country = discoverer.getCountry(engine) new_country = ISO3166_LIST[widget.get_active()].iso2 if old_country != new_country: engine["country"] = new_country discoverer.save() # Refresh the flag in the tree view path = addDataPrefix("flags/%s.png" % new_country) if not os.path.isfile(path): path = addDataPrefix("flags/unknown.png") item = self.tv.get_selection().get_selected() if item is not None: model, ts_iter = item model[ts_iter][0] = get_pixbuf(path) # Notify playerCombos in NewGameTasker discoverer.emit("all_engines_discovered") self.widgets["engine_country_combo"].connect("changed", country_changed) def country_keypressed(widget, event): idx = 0 for iso in ISO3166_LIST: if (idx != 0) and ((ord(iso.country[0].lower()) == event.keyval) or (ord(iso.country[0].upper()) == event.keyval)): widget.set_active(idx) break idx += 1 self.widgets["engine_country_combo"].connect("key-press-event", country_keypressed) ################################################################ # engine tree ################################################################ self.selection = False def selection_changed(treeselection): store, tv_iter = self.tv.get_selection().get_selected() if tv_iter: self.selection = True path = store.get_path(tv_iter) indices = path.get_indices() row = indices[0] name = store[row][1] self.cur_engine = name engine = discoverer.getEngineByName(name) self.widgets['copy_engine_button'].set_sensitive(True) if "PyChess.py" in engine["command"]: self.widgets['remove_engine_button'].set_sensitive(False) else: self.widgets['remove_engine_button'].set_sensitive(True) self.widgets["engine_command_entry"].set_text(engine["command"]) engine_chooser_dialog.set_filename(engine["command"]) args = [] if engine.get("args") is None else engine.get("args") self.widgets["engine_args_entry"].set_text(' '.join(args)) vm = engine.get("vm_command") self.widgets["vm_command_entry"].set_text(vm if vm is not None else "") args = [] if engine.get("vm_args") is None else engine.get("vm_args") self.widgets["vm_args_entry"].set_text(' '.join(args)) directory = engine.get("workingDirectory") dir_choice = directory if directory is not None else self.default_workdir dir_chooser_dialog.set_current_folder(dir_choice) self.widgets["engine_protocol_combo"].set_active(0 if engine["protocol"] == "uci" else 1) self.widgets["engine_country_combo"].set_active(0) country = discoverer.getCountry(engine) idx = 0 for iso in ISO3166_LIST: if iso.iso2 == country: self.widgets["engine_country_combo"].set_active(idx) break idx += 1 update_options() self.selection = False tree_selection = self.tv.get_selection() tree_selection.connect('changed', selection_changed) tree_selection.select_path((0, )) selection_changed(tree_selection) ################################################################ # restore the default options of the engine ################################################################ def engine_default_options(button): if self.cur_engine is not None and not self.selection: engine = discoverer.getEngineByName(self.cur_engine) options = engine.get("options") if options: dialog = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.QUESTION, buttons=Gtk.ButtonsType.YES_NO) dialog.set_markup(_("Do you really want to restore the default options of the engine ?")) response = dialog.run() dialog.destroy() if response == Gtk.ResponseType.YES: for option in options: if "default" in option: option["value"] = option["default"] discoverer.save() update_options() self.widgets["engine_default_options_button"].connect("clicked", engine_default_options)
def _init(cls): cls.white = get_pixbuf("glade/white.png") cls.black = get_pixbuf("glade/black.png") cls.widgets = uistuff.GladeWidgets("newInOut.glade") cls.widgets["newgamedialog"].set_transient_for(mainwindow()) def on_exchange_players(widget, button_event): white = cls.widgets["whitePlayerCombobox"].get_active() black = cls.widgets["blackPlayerCombobox"].get_active() whiteLevel = cls.widgets["skillSlider1"].get_value() blackLevel = cls.widgets["skillSlider2"].get_value() cls.widgets["whitePlayerCombobox"].set_active(black) cls.widgets["blackPlayerCombobox"].set_active(white) cls.widgets["skillSlider1"].set_value(blackLevel) cls.widgets["skillSlider2"].set_value(whiteLevel) cls.widgets["whitePlayerButton"].set_image(Gtk.Image.new_from_pixbuf(cls.white)) cls.widgets["whitePlayerButton"].connect("button-press-event", on_exchange_players) cls.widgets["blackPlayerButton"].set_image(Gtk.Image.new_from_pixbuf(cls.black)) cls.widgets["blackPlayerButton"].connect("button-press-event", on_exchange_players) uistuff.createCombo(cls.widgets["whitePlayerCombobox"], name="whitePlayerCombobox") uistuff.createCombo(cls.widgets["blackPlayerCombobox"], name="blackPlayerCombobox") cls.widgets["playersIcon"].set_from_pixbuf(big_people) cls.widgets["timeIcon"].set_from_pixbuf(big_time) def on_playerCombobox_changed(widget, skill_hbox, skill_level): position = widget.get_active() skill_hbox.props.visible = position > 0 if position > 0: tree_iter = widget.get_active_iter() if tree_iter is not None: engine_name = widget.get_model()[tree_iter][1] engine = discoverer.getEngineByName(engine_name) if engine: pref_level = engine.get("level") if pref_level: skill_level.set_value(pref_level) cls.widgets["whitePlayerCombobox"].connect("changed", on_playerCombobox_changed, cls.widgets["skillHbox1"], cls.widgets["skillSlider1"]) cls.widgets["blackPlayerCombobox"].connect("changed", on_playerCombobox_changed, cls.widgets["skillHbox2"], cls.widgets["skillSlider2"]) cls.widgets["whitePlayerCombobox"].set_active(0) cls.widgets["blackPlayerCombobox"].set_active(1) def on_skill_changed(scale, image): image.set_from_pixbuf(skillToIcon[int(scale.get_value())]) cls.widgets["skillSlider1"].connect("value-changed", on_skill_changed, cls.widgets["skillIcon1"]) cls.widgets["skillSlider2"].connect("value-changed", on_skill_changed, cls.widgets["skillIcon2"]) cls.widgets["skillSlider1"].set_value(3) cls.widgets["skillSlider2"].set_value(3) cls.__initTimeRadio("ngblitz", cls.widgets["blitzRadio"], cls.widgets["configImageBlitz"], 5, 0, 0) cls.__initTimeRadio("ngrapid", cls.widgets["rapidRadio"], cls.widgets["configImageRapid"], 15, 5, 0) cls.__initTimeRadio("ngnormal", cls.widgets["normalRadio"], cls.widgets["configImageNormal"], 45, 15, 0) cls.__initTimeRadio("ngclassical", cls.widgets["classicalRadio"], cls.widgets["configImageClassical"], 3, 0, 40) cls.__initVariantRadio("ngvariant1", cls.widgets["playVariant1Radio"], cls.widgets["configImageVariant1"]) cls.__initVariantRadio("ngvariant2", cls.widgets["playVariant2Radio"], cls.widgets["configImageVariant2"]) 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) discoverer.connect_after("all_engines_discovered", updateCombos) updateCombos(discoverer) conf.notify_add("ngvariant1", updateCombos) conf.notify_add("ngvariant2", updateCombos) cls.widgets["playNormalRadio"].connect("toggled", updateCombos) cls.widgets["playNormalRadio"].set_tooltip_text(variants[NORMALCHESS].__desc__) cls.widgets["playVariant1Radio"].connect("toggled", updateCombos) variant1 = conf.get("ngvariant1") cls.widgets["playVariant1Radio"].set_tooltip_text(variants[variant1].__desc__) cls.widgets["playVariant2Radio"].connect("toggled", updateCombos) variant2 = conf.get("ngvariant2") cls.widgets["playVariant2Radio"].set_tooltip_text(variants[variant2].__desc__) # The "variant" has to come before players, because the engine positions # in the user comboboxes can be different in different variants for key in ("whitePlayerCombobox", "blackPlayerCombobox", "skillSlider1", "skillSlider2", "notimeRadio", "blitzRadio", "rapidRadio", "normalRadio", "classicalRadio", "playNormalRadio", "playVariant1Radio", "playVariant2Radio"): uistuff.keep(cls.widgets[key], key) # We don't want the dialog to deallocate when closed. Rather we hide # it on respond cls.widgets["newgamedialog"].connect("delete_event", lambda *a: True)
def __init__(self, widgets): self.widgets = widgets self.dialog = self.widgets["manage_engines_dialog"] self.cur_engine = None self.default_workdir = getEngineDataPrefix() uistuff.keepWindowSize("engineswindow", self.dialog, defaultSize=(1, 500)) # Put engines into tree store allstore = Gtk.ListStore(Pixbuf, str) self.tv = self.widgets["engines_treeview"] self.tv.set_model(allstore) self.tv.append_column( Gtk.TreeViewColumn("Flag", Gtk.CellRendererPixbuf(), pixbuf=0)) name_renderer = Gtk.CellRendererText() name_renderer.set_property("editable", True) self.tv.append_column(Gtk.TreeViewColumn("Name", name_renderer, text=1)) def name_edited(renderer, path, new_name): if self.cur_engine is not None: old_name = self.cur_engine if new_name and new_name != old_name: names = [ engine["name"] for engine in discoverer.getEngines() ] if new_name not in names: engine = discoverer.getEngineByName(self.cur_engine) engine["name"] = new_name discoverer.save() self.cur_engine = new_name update_store() # Notify playerCombos in NewGameTasker discoverer.emit("all_engines_discovered") name_renderer.connect("edited", name_edited) # Add cell renderer to protocol combo column protocol_combo = self.widgets["engine_protocol_combo"] protocol_combo.set_name("engine_protocol_combo") cell = Gtk.CellRendererText() protocol_combo.pack_start(cell, True) protocol_combo.add_attribute(cell, "text", 0) # Add columns and cell renderers to options treeview self.options_store = Gtk.ListStore(str, GObject.TYPE_PYOBJECT) optv = self.widgets["options_treeview"] optv.set_model(self.options_store) optv.append_column( Gtk.TreeViewColumn("Option", Gtk.CellRendererText(), text=0)) optv.append_column( Gtk.TreeViewColumn("Data", KeyValueCellRenderer(self.options_store), data=1)) def update_options(*args): if self.cur_engine is not None: engines = discoverer.getEngines() names = [engine["name"] for engine in engines] # After deleting an engine we will select first if self.cur_engine not in names: self.cur_engine = engines[0]["name"] engine = discoverer.getEngineByName(self.cur_engine) options = engine.get("options") if options: self.options_store.clear() for option in options: key = option["name"] val = option if option["type"] != "button": val["default"] = option.get("default") val["value"] = option.get("value", val["default"]) self.options_store.append([key, val]) def update_store(*args): newGameDialog.createPlayerUIGlobals(discoverer) engine_names = [row[1] for row in allstore] new_items = [] # don't add the very first (Human) player to engine store for item in newGameDialog.playerItems[0][1:]: if item[1] not in engine_names: new_items.append(item) ts_iter = None for item in new_items: ts_iter = allstore.append(item) if ts_iter is not None: text_select = self.tv.get_selection() text_select.select_iter(ts_iter) update_options() update_store() def do_update_store(*args): GLib.idle_add(update_store) discoverer.connect_after("engine_discovered", do_update_store) ################################################################ # remove button ################################################################ def remove(button): if self.cur_engine is not None: self.widgets['remove_engine_button'].set_sensitive(False) # engine = discoverer.getEngineByName(self.cur_engine) discoverer.removeEngine(self.cur_engine) discoverer.save() selection = self.tv.get_selection() result = selection.get_selected() if result is not None: model, ts_iter = result model.remove(ts_iter) # Notify playerCombos in NewGameTasker discoverer.emit("all_engines_discovered") self.widgets["remove_engine_button"].connect("clicked", remove) ################################################################ # add button ################################################################ engine_chooser_dialog = Gtk.FileChooserDialog( _("Select engine"), None, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) filter = Gtk.FileFilter() filter.set_name(_("Executable files")) filter.add_mime_type("application/x-executable") filter.add_mime_type("application/x-ms-dos-executable") filter.add_mime_type("application/x-msdownload") filter.add_pattern("*.exe") for vm in VM_LIST: filter.add_pattern("*%s" % vm.ext) engine_chooser_dialog.add_filter(filter) self.add = False def add(button): self.add = True response = engine_chooser_dialog.run() if response == Gtk.ResponseType.OK: new_engine = engine_chooser_dialog.get_filename() vm_name = None vm_args = None vmpath = "" if new_engine.lower().endswith( ".exe") and sys.platform != "win32": vm_name = "wine" vmpath = shutil.which(vm_name, mode=os.R_OK | os.X_OK) if vmpath is None: msg_dia = Gtk.MessageDialog(type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup( _("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text(_("wine not installed")) msg_dia.run() msg_dia.hide() new_engine = "" for vm in VM_LIST: ext = os.path.splitext(new_engine)[1] if ext == vm.ext: vm_name = vm.name vm_args = vm.args vmpath = shutil.which(vm_name, mode=os.R_OK | os.X_OK) if vmpath is None: msg_dia = Gtk.MessageDialog( type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup( _("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text( vm_name + _(" is not installed")) msg_dia.run() msg_dia.hide() new_engine = "" break if new_engine: vm_ext_list = [vm.ext for vm in VM_LIST] if ext not in vm_ext_list and not os.access( new_engine, os.X_OK): msg_dia = Gtk.MessageDialog(type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup( _("<big><b>%s is not marked executable in the filesystem</b></big>" % new_engine)) msg_dia.format_secondary_text( _("Try chmod a+x %s" % new_engine)) msg_dia.run() msg_dia.hide() self.add = False engine_chooser_dialog.hide() return try: engine_command = [] if vmpath: engine_command.append(vmpath) if vm_args is not None: engine_command.append(vm_args) engine_command.append(new_engine) # Some engines support CECP and UCI, but main variant engines are CECP, # so we better to start with CECP this case variant_engines = ("fmax", "sjaakii", "sjeng") if any((True for eng in variant_engines if eng in new_engine.lower())): checkers = [is_cecp, is_uci] else: checkers = [is_uci, is_cecp] uci = False for checker in checkers: check_ok = checker(engine_command) if check_ok: uci = checker is is_uci break else: continue if not check_ok: # restore the original engine = discoverer.getEngineByName( self.cur_engine) engine_chooser_dialog.set_filename( engine["command"]) msg_dia = Gtk.MessageDialog( type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup( _("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text( _("There is something wrong with this executable" )) msg_dia.run() msg_dia.hide() engine_chooser_dialog.hide() self.add = False engine_chooser_dialog.hide() return binname = os.path.split(new_engine)[1] for eng in discoverer.getEngines(): if eng["name"] == binname: binname = eng["name"] + "(1)" break self.widgets["engine_command_entry"].set_text( new_engine) self.widgets["engine_protocol_combo"].set_active( 0 if uci else 1) self.widgets["engine_args_entry"].set_text("") # active = self.widgets["engine_protocol_combo"].get_active() protocol = "uci" if uci else "xboard" if vm_args is not None: vm_args = vm_args.split(",") # print(binname, new_engine, protocol, vm_name, vm_args) discoverer.addEngine(binname, new_engine, protocol, vm_name, vm_args) self.cur_engine = binname self.add = False discoverer.discover() except: msg_dia = Gtk.MessageDialog(type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK) msg_dia.set_markup( _("<big><b>Unable to add %s</b></big>" % new_engine)) msg_dia.format_secondary_text( _("There is something wrong with this executable")) msg_dia.run() msg_dia.hide() self.add = False engine_chooser_dialog.hide() return else: # restore the original engine = discoverer.getEngineByName(self.cur_engine) engine_chooser_dialog.set_filename(engine["command"]) engine_chooser_dialog.hide() self.widgets["add_engine_button"].connect("clicked", add) ################################################################ # vm args ################################################################ def vm_args_changed(widget): if self.cur_engine is not None: new_args = self.widgets["vm_args_entry"].get_text().strip() engine = discoverer.getEngineByName(self.cur_engine) old_args = engine.get("vm_args") if new_args != old_args: engine["vm_args"] = new_args.split() discoverer.save() self.widgets["vm_args_entry"].connect("changed", vm_args_changed) ################################################################ # engine args ################################################################ def args_changed(widget): if self.cur_engine is not None: new_args = self.widgets["engine_args_entry"].get_text().strip() engine = discoverer.getEngineByName(self.cur_engine) old_args = engine.get("args") if new_args != old_args: engine["args"] = new_args.split() discoverer.save() self.widgets["engine_args_entry"].connect("changed", args_changed) ################################################################ # engine working directory ################################################################ dir_chooser_dialog = Gtk.FileChooserDialog( _("Select working directory"), None, Gtk.FileChooserAction.SELECT_FOLDER, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) dir_chooser_button = Gtk.FileChooserButton.new_with_dialog( dir_chooser_dialog) self.widgets["dirChooserDock"].add(dir_chooser_button) dir_chooser_button.show() def select_dir(button): new_directory = dir_chooser_dialog.get_filename() engine = discoverer.getEngineByName(self.cur_engine) old_directory = engine.get("workingDirectory") if new_directory != old_directory and new_directory != self.default_workdir: engine["workingDirectory"] = new_directory discoverer.save() dir_chooser_button.connect("current-folder-changed", select_dir) ################################################################ # engine protocol ################################################################ def protocol_changed(widget): if self.cur_engine is not None and not self.add and not self.selection: active = self.widgets["engine_protocol_combo"].get_active() new_protocol = "uci" if active == 0 else "xboard" engine = discoverer.getEngineByName(self.cur_engine) old_protocol = engine["protocol"] if new_protocol != old_protocol: command = engine.get("command") engine_command = [] vm_command = engine.get("vm_command") if vm_command is not None: engine_command.append(vm_command) vm_args = engine.get("vm_args") if vm_args is not None: engine_command.append(", ".join(vm_args)) engine_command.append(command) # is the new protocol supported by the engine? if new_protocol == "uci": check_ok = is_uci(engine_command) else: check_ok = is_cecp(engine_command) if check_ok: # discover engine options for new protocol engine["protocol"] = new_protocol engine["recheck"] = True discoverer.discover() else: # restore the original protocol widgets["engine_protocol_combo"].set_active( 0 if old_protocol == "uci" else 1) self.widgets["engine_protocol_combo"].connect("changed", protocol_changed) ################################################################ # engine tree ################################################################ self.selection = False def selection_changed(treeselection): store, tv_iter = self.tv.get_selection().get_selected() if tv_iter: self.selection = True path = store.get_path(tv_iter) indices = path.get_indices() row = indices[0] name = store[row][1] self.cur_engine = name engine = discoverer.getEngineByName(name) self.widgets['copy_engine_button'].set_sensitive(True) if "PyChess.py" in engine["command"]: self.widgets['remove_engine_button'].set_sensitive(False) else: self.widgets['remove_engine_button'].set_sensitive(True) self.widgets["engine_command_entry"].set_text( engine["command"]) engine_chooser_dialog.set_filename(engine["command"]) args = [] if engine.get("args") is None else engine.get("args") self.widgets["engine_args_entry"].set_text(' '.join(args)) vm = engine.get("vm_command") self.widgets["vm_command_entry"].set_text( vm if vm is not None else "") args = [] if engine.get("vm_args") is None else engine.get( "vm_args") self.widgets["vm_args_entry"].set_text(' '.join(args)) directory = engine.get("workingDirectory") dir_choice = directory if directory is not None else self.default_workdir dir_chooser_dialog.set_current_folder(dir_choice) self.widgets["engine_protocol_combo"].set_active( 0 if engine["protocol"] == "uci" else 1) update_options() self.selection = False tree_selection = self.tv.get_selection() tree_selection.connect('changed', selection_changed) tree_selection.select_path((0, ))
def __init__(self): self.widgets = uistuff.GladeWidgets("analyze_game.glade") self.widgets["analyze_game"].set_transient_for(mainwindow()) self.stop_event = asyncio.Event() uistuff.keep(self.widgets["fromCurrent"], "fromCurrent") uistuff.keep(self.widgets["shouldBlack"], "shouldBlack") uistuff.keep(self.widgets["shouldWhite"], "shouldWhite") uistuff.keep(self.widgets["threatPV"], "threatPV") uistuff.keep(self.widgets["showEval"], "showEval") uistuff.keep(self.widgets["showBlunder"], "showBlunder") uistuff.keep(self.widgets["max_analysis_spin"], "max_analysis_spin") uistuff.keep(self.widgets["variation_threshold_spin"], "variation_threshold_spin") # Analyzing engines uistuff.createCombo(self.widgets["ana_combobox"], name="ana_combobox") from pychess.widgets import newGameDialog def update_analyzers_store(discoverer): data = [(item[0], item[1]) for item in newGameDialog.analyzerItems] uistuff.updateCombo(self.widgets["ana_combobox"], data) discoverer.connect_after("all_engines_discovered", update_analyzers_store) update_analyzers_store(discoverer) uistuff.keep( self.widgets["ana_combobox"], "ana_combobox", anal_combo_get_value, lambda combobox, value: anal_combo_set_value( combobox, value, "hint_mode", HINT)) def hide_window(button, *args): self.widgets["analyze_game"].destroy() def abort(): self.analyzer.pause() if self.threat_PV: self.inv_analyzer.pause() self.stop_event.set() self.widgets["analyze_game"].destroy() def run_analyze(button, *args): @asyncio.coroutine def coro(): persp = perspective_manager.get_perspective("games") gmwidg = persp.cur_gmwidg() gamemodel = gmwidg.gamemodel old_check_value = conf.get("analyzer_check") conf.set("analyzer_check", True) if HINT not in gamemodel.spectators: try: yield from asyncio.wait_for( gamemodel.start_analyzer(HINT), 5.0) except asyncio.TimeoutError: log.error( "Got timeout error while starting hint analyzer") return except Exception: log.error("Unknown error while starting hint analyzer") return self.analyzer = gamemodel.spectators[HINT] gmwidg.menuitems["hint_mode"].active = True self.threat_PV = conf.get("ThreatPV") if self.threat_PV: old_inv_check_value = conf.get("inv_analyzer_check") conf.set("inv_analyzer_check", True) if SPY not in gamemodel.spectators: try: yield from asyncio.wait_for( gamemodel.start_analyzer(SPY), 5.0) except asyncio.TimeoutError: log.error( "Got timeout error while starting spy analyzer" ) return except Exception: log.error( "Unknown error while starting spy analyzer") return 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): conf.set("analyzer_check", old_check_value) if self.threat_PV: conf.set("inv_analyzer_check", old_inv_check_value) message.dismiss() abort() message = InfoBarMessage(Gtk.MessageType.QUESTION, content, response_cb) message.add_button( InfoBarMessageButton(_("Abort"), Gtk.ResponseType.CANCEL)) gmwidg.replaceMessages(message) @asyncio.coroutine def analyse_moves(): should_black = conf.get("shouldBlack") should_white = conf.get("shouldWhite") from_current = conf.get("fromCurrent") start_ply = gmwidg.board.view.shown if from_current else 0 move_time = int(conf.get("max_analysis_spin")) threshold = int(conf.get("variation_threshold_spin")) for board in gamemodel.boards[start_ply:]: if self.stop_event.is_set(): break gmwidg.board.view.setShownBoard(board) self.analyzer.setBoard(board) if self.threat_PV: inv_analyzer.setBoard(board) yield from asyncio.sleep(move_time + 0.1) ply = board.ply - gamemodel.lowply 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) ) and (gamemodel.moves[ply - 1] != parseAny( gamemodel.boards[ply - 1], oldmoves[0])): if self.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="Threatening", score=score_str0, emit=False) 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, emit=False) 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)) self.widgets["analyze_game"].hide() self.widgets["analyze_ok_button"].set_sensitive(True) conf.set("analyzer_check", old_check_value) if self.threat_PV: conf.set("inv_analyzer_check", old_inv_check_value) message.dismiss() gamemodel.emit("analysis_finished") create_task(analyse_moves()) hide_window(None) return True create_task(coro()) self.widgets["analyze_game"].connect("delete-event", hide_window) self.widgets["analyze_cancel_button"].connect("clicked", hide_window) self.widgets["analyze_ok_button"].connect("clicked", run_analyze)
def __init__(self): self.widgets = uistuff.GladeWidgets("analyze_game.glade") self.widgets["analyze_game"].set_transient_for(mainwindow()) self.stop_event = asyncio.Event() uistuff.keep(self.widgets["fromCurrent"], "fromCurrent") uistuff.keep(self.widgets["shouldBlack"], "shouldBlack") uistuff.keep(self.widgets["shouldWhite"], "shouldWhite") uistuff.keep(self.widgets["threatPV"], "threatPV") uistuff.keep(self.widgets["showEval"], "showEval") uistuff.keep(self.widgets["showBlunder"], "showBlunder") uistuff.keep(self.widgets["max_analysis_spin"], "max_analysis_spin") uistuff.keep(self.widgets["variation_threshold_spin"], "variation_threshold_spin") # Analyzing engines uistuff.createCombo(self.widgets["ana_combobox"], name="ana_combobox") from pychess.widgets import newGameDialog def update_analyzers_store(discoverer): data = [(item[0], item[1]) for item in newGameDialog.analyzerItems] uistuff.updateCombo(self.widgets["ana_combobox"], data) discoverer.connect_after("all_engines_discovered", update_analyzers_store) update_analyzers_store(discoverer) uistuff.keep(self.widgets["ana_combobox"], "ana_combobox", anal_combo_get_value, lambda combobox, value: anal_combo_set_value(combobox, value, "hint_mode", HINT)) def hide_window(button, *args): self.widgets["analyze_game"].destroy() def abort(): self.stop_event.set() self.widgets["analyze_game"].destroy() def run_analyze(button, *args): @asyncio.coroutine def coro(): persp = perspective_manager.get_perspective("games") gmwidg = persp.cur_gmwidg() gamemodel = gmwidg.gamemodel old_check_value = conf.get("analyzer_check") conf.set("analyzer_check", True) if HINT not in gamemodel.spectators: try: yield from asyncio.wait_for(gamemodel.start_analyzer(HINT), 5.0) except asyncio.TimeoutError: log.error("Got timeout error while starting hint analyzer") return except Exception: log.error("Unknown error while starting hint analyzer") return analyzer = gamemodel.spectators[HINT] gmwidg.menuitems["hint_mode"].active = True threat_PV = conf.get("ThreatPV") if threat_PV: old_inv_check_value = conf.get("inv_analyzer_check") conf.set("inv_analyzer_check", True) if SPY not in gamemodel.spectators: try: yield from asyncio.wait_for(gamemodel.start_analyzer(SPY), 5.0) except asyncio.TimeoutError: log.error("Got timeout error while starting spy analyzer") return except Exception: log.error("Unknown error while starting spy analyzer") return 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): conf.set("analyzer_check", old_check_value) if threat_PV: conf.set("inv_analyzer_check", old_inv_check_value) message.dismiss() abort() message = InfoBarMessage(Gtk.MessageType.QUESTION, content, response_cb) message.add_button(InfoBarMessageButton(_("Abort"), Gtk.ResponseType.CANCEL)) gmwidg.replaceMessages(message) @asyncio.coroutine def analyse_moves(): should_black = conf.get("shouldBlack") should_white = conf.get("shouldWhite") from_current = conf.get("fromCurrent") start_ply = gmwidg.board.view.shown if from_current else 0 move_time = int(conf.get("max_analysis_spin")) threshold = int(conf.get("variation_threshold_spin")) for board in gamemodel.boards[start_ply:]: if self.stop_event.is_set(): break gmwidg.board.view.setShownBoard(board) analyzer.setBoard(board) if threat_PV: inv_analyzer.setBoard(board) yield from asyncio.sleep(move_time + 0.1) ply = board.ply - gamemodel.lowply 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)) and ( gamemodel.moves[ply - 1] != parseAny(gamemodel.boards[ply - 1], oldmoves[0])): 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="Threatening", score=score_str0, emit=False) 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, emit=False) 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)) self.widgets["analyze_game"].hide() self.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() gamemodel.emit("analysis_finished") create_task(analyse_moves()) hide_window(None) return True create_task(coro()) self.widgets["analyze_game"].connect("delete-event", hide_window) self.widgets["analyze_cancel_button"].connect("clicked", hide_window) self.widgets["analyze_ok_button"].connect("clicked", run_analyze)