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"), GdkPixbuf.Pixbuf.new_from_file(addDataPrefix("glade/white.png"))) combo.addItem(_("Black"), GdkPixbuf.Pixbuf.new_from_file(addDataPrefix("glade/black.png"))) combo.addItem(_("Random"), GdkPixbuf.Pixbuf.new_from_file(addDataPrefix("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) glock_connect_after(discoverer, "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 setActive (self, active): assert isinstance(active, bool) self._active = active if self._active is True: self.image.set_from_file(addDataPrefix("glade/stock-vchain-24.png")) else: self.image.set_from_file(addDataPrefix("glade/stock-vchain-broken-24.png"))
def onClicked (self, button): if self._active is False: self.image.set_from_file(addDataPrefix("glade/stock-vchain-24.png")) self._active = True else: self.image.set_from_file(addDataPrefix("glade/stock-vchain-broken-24.png")) self._active = False
def createPlayerUIGlobals(discoverer): global playerItems global analyzerItems global allEngineItems playerItems = [] analyzerItems = [] allEngineItems = [] for variantClass in variants.values(): playerItems += [[(ipeople, _("Human Being"))]] for engine in discoverer.getEngines(): name = engine["name"] c = discoverer.getCountry(engine) path = addDataPrefix("flags/%s.png" % c) if c and os.path.isfile(path): flag_icon = get_pixbuf(path) else: path = addDataPrefix("flags/unknown.png") flag_icon = get_pixbuf(path) allEngineItems.append((flag_icon, name)) for variant in discoverer.getEngineVariants(engine): playerItems[variant] += [(flag_icon, name)] if discoverer.is_analyzer(engine): analyzerItems.append((flag_icon, name))
def _init (cls): def callback (widget, allocation): cls.widgets["enterGameNotationFrame"].set_size_request( 223, allocation.height-4) cls.widgets["enterGameNotationSidePanel"].connect_after("size-allocate", callback) flags = [] if isInstalled(): path = gettext.find("pychess") else: path = gettext.find("pychess", localedir=addDataPrefix("lang")) if path: loc = locale.getdefaultlocale()[0][-2:].lower() flags.append(addDataPrefix("flags/%s.png" % loc)) flags.append(addDataPrefix("flags/us.png")) cls.ib = ImageButton(flags) cls.widgets["imageButtonDock"].add(cls.ib) cls.ib.show() cls.sourcebuffer = GtkSource.Buffer() sourceview = GtkSource.View.new_with_buffer(cls.sourcebuffer) sourceview.set_tooltip_text( _("Type or paste PGN game or FEN positions here")) cls.widgets["scrolledwindow6"].add(sourceview) sourceview.show() # Pgn format does not allow tabulator sourceview.set_insert_spaces_instead_of_tabs(True) sourceview.set_wrap_mode(Gtk.WrapMode.WORD) man = GtkSource.LanguageManager() # Init new version if hasattr(man.props, 'search_path'): try: path = os.path.join(getDataPrefix(),"gtksourceview-1.0/language-specs") man.props.search_path = man.props.search_path + [path] if 'pgn' in man.get_language_ids(): lang = man.get_language('pgn') cls.sourcebuffer.set_language(lang) else: log.warning("Unable to load pgn syntax-highlighting.") cls.sourcebuffer.set_highlight_syntax(True) except NotImplementedError: # Python 2.7.3 in Ubuntu 12.04 log.warning("Unable to load pgn syntax-highlighting.") # Init old version else: os.environ["XDG_DATA_DIRS"] = getDataPrefix()+":/usr/share/" man = LanguageManager() for lang in man.get_available_languages(): if lang.get_name() == "PGN": cls.sourcebuffer.set_language(lang) break else: log.warning("Unable to load pgn syntax-highlighting.") cls.sourcebuffer.set_highlight(True)
def run(widgets): global firstRun, engine_dialog if firstRun: # Display of the countries items = [] for iso in ISO3166_LIST: path = addDataPrefix("flags/%s.png" % iso.iso2) if not(iso.iso2 and os.path.isfile(path)): path = addDataPrefix("flags/unknown.png") items.append((get_pixbuf(path), iso.country)) uistuff.createCombo(widgets["engine_country_combo"], name="engine_country_combo", ellipsize_mode=Pango.EllipsizeMode.END) data = [(item[0], item[1]) for item in items] uistuff.updateCombo(widgets["engine_country_combo"], data) engine_dialog = EnginesDialog(widgets) def cancel_event(widget, with_confirmation, *args): # Confirm if the changes need to be saved modified = discoverer.hasChanged() if modified and with_confirmation: dialog = Gtk.MessageDialog(mainwindow(), type=Gtk.MessageType.QUESTION, buttons=Gtk.ButtonsType.YES_NO) dialog.set_markup(_("You have unsaved changes. Do you want to save before leaving?")) response = dialog.run() dialog.destroy() # if response == Gtk.ResponseType.CANCEL: # return False if response == Gtk.ResponseType.NO: discoverer.restore() if response == Gtk.ResponseType.YES: discoverer.save() # Close the window widgets["manage_engines_dialog"].hide() return True def save_event(widget, *args): discoverer.save() widgets["manage_engines_dialog"].hide() return True widgets["manage_engines_dialog"].connect("delete-event", cancel_event, True) widgets["engine_cancel_button"].connect("clicked", cancel_event, False) widgets["engine_save_button"].connect("clicked", save_event) widgets["manage_engines_dialog"].connect( "key-press-event", lambda w, e: cancel_event(w, True) if e.keyval == Gdk.KEY_Escape else None) discoverer.backup() engine_dialog.widgets["enginebook"].set_current_page(0) widgets["manage_engines_dialog"].show() if not firstRun: engine_dialog.update_store() firstRun = False
def get_svg_pieces(svgdir): """Load figurines from .svg files""" if all_in_one: rsvg_handles = Rsvg.Handle.new_from_file(addDataPrefix("pieces/%s/%s.svg" % (svgdir, svgdir))) else: rsvg_handles = [[None]*7, [None]*7] for c, color in ((WHITE, 'white'), (BLACK, 'black')): for p in pieces: rsvg_handles[c][p] = Rsvg.Handle.new_from_file(addDataPrefix("pieces/%s/%s%s.svg" % (svgdir, color[0], reprSign[p].lower()))) return rsvg_handles
def discover_themes(self): themes = ['Pychess'] pieces = addDataPrefix("pieces") themes += [d.capitalize() for d in listdir(pieces) if isdir(os.path.join(pieces,d)) and d != 'ttf'] ttf = addDataPrefix("pieces/ttf") themes += ["ttf-" + splitext(d)[0].capitalize() for d in listdir(ttf) if splitext(d)[1] == '.ttf'] themes.sort() return themes
def onColorRadioChanged(self, radio): if self.widgets["nocolorRadio"].get_active(): self.widgets["colorImage"].set_from_file(addDataPrefix( "glade/piece-unknown.png")) self.widgets["colorImage"].set_sensitive(False) elif self.widgets["whitecolorRadio"].get_active(): self.widgets["colorImage"].set_from_file(addDataPrefix( "glade/piece-white.png")) self.widgets["colorImage"].set_sensitive(True) elif self.widgets["blackcolorRadio"].get_active(): self.widgets["colorImage"].set_from_file(addDataPrefix( "glade/piece-black.png")) self.widgets["colorImage"].set_sensitive(True)
def __init__ (self, id): TopDock.__init__(self, id) self.set_no_show_all(True) self.highlightArea = HighlightArea(self) self.buttons = (ArrowButton(self, addDataPrefix("glade/dock_top.svg"), NORTH), ArrowButton(self, addDataPrefix("glade/dock_right.svg"), EAST), ArrowButton(self, addDataPrefix("glade/dock_bottom.svg"), SOUTH), ArrowButton(self, addDataPrefix("glade/dock_left.svg"), WEST)) for button in self.buttons: button.connect("dropped", self.__onDrop) button.connect("hovered", self.__onHover) button.connect("left", self.__onLeave)
def get_pixbuf(path, size=None): file = Gio.File.new_for_path(addDataPrefix(path)) if size is None: return GdkPixbuf.Pixbuf.new_from_stream(file.read(None), None) else: return GdkPixbuf.Pixbuf.new_from_stream_at_scale( file.read(None), size, size, True, None)
def load (self, gmwidg): self.gamemodel = gmwidg.board.view.model self.gmhandlers = [ glock_connect(self.gamemodel, "game_changed", self.game_changed), glock_connect(self.gamemodel, "game_started", self.game_started), glock_connect(self.gamemodel, "moves_undoing", self.moves_undoing) ] widgets = Gtk.Builder() widgets.add_from_file(addDataPrefix("sidepanel/book.glade")) self.tv = widgets.get_object("treeview") scrollwin = widgets.get_object("scrolledwindow") scrollwin.unparent() self.store = Gtk.ListStore(str) self.tv.set_model(self.store) self.tv.get_selection().set_mode(Gtk.SelectionMode.BROWSE) uistuff.appendAutowrapColumn(self.tv, "Comment", text=0) self.tv.get_selection().connect_after('changed', self.select_cursor_row) self.boardview = gmwidg.board.view self.boardview.connect("shown_changed", self.shown_changed) self.frozen = Switch() return scrollwin
def on_opening_file_entry_changed(none): default_path = os.path.join(addDataPrefix("pychess_book.bin")) path = conf.get("opening_file_entry", default_path) if os.path.isfile(path): for advisor in self.advisors: if advisor.mode == OPENING: advisor.shown_changed(self.boardview, self.boardview.shown)
def load (self, gmwidg): widgets = gtk.glade.XML(addDataPrefix("sidepanel/book.glade")) self.tv = widgets.get_widget("treeview") self.sw = widgets.get_widget("scrolledwindow") self.sw.unparent() self.store = gtk.ListStore(str, str, gobject.TYPE_PYOBJECT) self.tv.set_model(self.store) self.tv.append_column(gtk.TreeViewColumn( "Move", gtk.CellRendererText(), text=0)) r = gtk.CellRendererText() r.set_property("xalign", 1) self.tv.append_column(gtk.TreeViewColumn("Games", r, text=1)) self.tv.append_column(gtk.TreeViewColumn( "Win/Draw/Loss", BookCellRenderer(), data=2)) self.boardcontrol = gmwidg.board self.board = self.boardcontrol.view self.board.connect("shown_changed", self.shown_changed) self.tv.connect("cursor_changed", self.selection_changed) self.tv.connect("select_cursor_row", self.selection_changed) self.tv.connect("row-activated", self.row_activated) self.tv.connect("query-tooltip", self.query_tooltip) self.tv.props.has_tooltip = True self.shown_changed(self.board, 0) return self.sw
def __init__(self, filename): # TODO: remove this when upstream fixes translations with Python3+Windows if sys.platform == "win32" and not no_gettext: tree = ET.parse(addDataPrefix("glade/%s" % filename)) for node in tree.iter(): if 'translatable' in node.attrib: node.text = _(node.text) del node.attrib['translatable'] if node.get('name') in ('pixbuf', 'logo'): node.text = addDataPrefix("glade/%s" % node.text) xml_text = ET.tostring(tree.getroot(), encoding='unicode', method='xml') self.builder = Gtk.Builder.new_from_string(xml_text, -1) else: self.builder = Gtk.Builder() if not no_gettext: self.builder.set_translation_domain("pychess") self.builder.add_from_file(addDataPrefix("glade/%s" % filename))
def discoverThemes(self): """ :Description: Finds all the different chess sets that are present in the pieces directory :return: (a List) of themes """ themes = ['Pychess'] pieces = addDataPrefix("pieces") themes += [d.capitalize() for d in listdir(pieces) if isdir(os.path.join(pieces, d)) and d != 'ttf'] ttf = addDataPrefix("pieces/ttf") themes += ["ttf-" + splitext(d)[0].capitalize() for d in listdir(ttf) if splitext(d)[1] == '.ttf'] themes.sort() return themes
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")
def __init__ (self, widgets): self.themes = self.discover_themes() store = Gtk.ListStore(GdkPixbuf.Pixbuf, str) for theme in self.themes: pngfile = "%s/%s.png" % (addDataPrefix("pieces"), theme) if isfile(pngfile): pixbuf = GdkPixbuf.Pixbuf.new_from_file(pngfile) store.append((pixbuf, theme)) else: print("WARNING: No piece theme preview icons found. Please run create_theme_preview.sh !") break iconView = widgets["pieceTheme"] iconView.set_model(store) iconView.set_pixbuf_column(0) iconView.set_text_column(1) ############################################# # Hack to fix spacing problem in iconview # http://stackoverflow.com/questions/14090094/what-causes-the-different-display-behaviour-for-a-gtkiconview-between-different def keep_size(crt, *args): crt.handler_block(crt_notify) crt.set_property('width', 40) crt.handler_unblock(crt_notify) crt, crp = iconView.get_cells() crt_notify = crt.connect('notify', keep_size) ############################################# def _get_active(iconview): model = iconview.get_model() selected = iconview.get_selected_items() if len(selected) == 0: return conf.get("pieceTheme", "Pychess") indices = selected[0].get_indices() if indices: i = indices[0] theme = model[i][1] Pieces.set_piece_theme(theme) return theme def _set_active(iconview, value): try: index = self.themes.index(value) except ValueError: index = 0 iconview.select_path(Gtk.TreePath(index,)) uistuff.keep(widgets["pieceTheme"], "pieceTheme", _get_active, _set_active, "Pychess")
def __init__(self, id): TabReceiver.__init__(self) self.id = id self.set_no_show_all(True) self.highlightArea = HighlightArea(self) self.button_cids = defaultdict(list) self.buttons = ( ArrowButton(self, addDataPrefix("glade/dock_top.svg"), NORTH), ArrowButton(self, addDataPrefix("glade/dock_right.svg"), EAST), ArrowButton(self, addDataPrefix("glade/dock_bottom.svg"), SOUTH), ArrowButton(self, addDataPrefix("glade/dock_left.svg"), WEST)) for button in self.buttons: self.button_cids[button] += [ button.connect("dropped", self.__onDrop), button.connect("hovered", self.__onHover), button.connect("left", self.__onLeave), ]
def __init__(self, filename): # TODO: remove this when upstream fixes translations with Python3+Windows if sys.platform == "win32" and not no_gettext: tree = ET.parse(addDataPrefix("glade/%s" % filename)) for node in tree.iter(): if 'translatable' in node.attrib: node.text = _(node.text) if node.get('name') in ('pixbuf', 'logo'): node.text = addDataPrefix("glade/%s" % node.text) # temp_file = BytesIO() temp_file = addDataPrefix("glade/%s.temp" % filename) tree.write(temp_file, encoding='utf-8', xml_declaration=True) # xml_text = temp_file.getvalue().decode() # self.builder = Gtk.Builder.new_from_string(xml_text, len(xml_text)) self.builder = Gtk.Builder() self.builder.add_from_file(temp_file) else: self.builder = Gtk.Builder() if not no_gettext: self.builder.set_translation_domain("pychess") self.builder.add_from_file(addDataPrefix("glade/%s" % filename))
def start_puzzle_from(filename, index=None): if filename.lower().endswith(".pgn"): chessfile = PGNFile(protoopen(addDataPrefix("learn/puzzles/%s" % filename))) chessfile.limit = 1000 chessfile.init_tag_database() elif filename.lower().endswith(".olv"): chessfile = OLVFile(protoopen(addDataPrefix("learn/puzzles/%s" % filename), encoding="utf-8")) records, plys = chessfile.get_records() progress = puzzles_solving_progress.get(filename, [0] * chessfile.count) if index is None: index = progress.index(0) rec = records[index] timemodel = TimeModel(0, 0) gamemodel = LearnModel(timemodel) chessfile.loadToModel(rec, 0, gamemodel) start_puzzle_game(gamemodel, filename, records, index, rec)
def run(widgets): global firstRun if firstRun: # Bubble sort for the translated countries for i in range(len(ISO3166_LIST) - 1, 1, - 1): for j in range(1, i - 1): if ISO3166_LIST[i].country < ISO3166_LIST[j].country: tmp = ISO3166_LIST[i] ISO3166_LIST[i] = ISO3166_LIST[j] ISO3166_LIST[j] = tmp # Display of the countries items = [] for iso in ISO3166_LIST: path = addDataPrefix("flags/%s.png" % iso.iso2) if not(iso.iso2 and os.path.isfile(path)): path = addDataPrefix("flags/unknown.png") items.append((get_pixbuf(path), iso.country)) uistuff.createCombo(widgets["engine_country_combo"], name="engine_country_combo", ellipsize_mode=Pango.EllipsizeMode.END) data = [(item[0], item[1]) for item in items] uistuff.updateCombo(widgets["engine_country_combo"], data) EnginesDialog(widgets) def delete_event(widget, *args): widgets["manage_engines_dialog"].hide() return True widgets["manage_engines_dialog"].connect("delete-event", delete_event) widgets["engines_close_button"].connect("clicked", delete_event) widgets["manage_engines_dialog"].connect( "key-press-event", lambda w, e: delete_event(w) if e.keyval == Gdk.KEY_Escape else None) firstRun = False widgets["manage_engines_dialog"].show()
def get_chess_font_face(name): """Set chess font and char mapping for a chess .ttf""" name = name[4:] if name in ('alpha', 'berlin', 'cheq'): char_map = ('phbrqk', 'ojntwl') else: char_map = ('pnbrqk', 'omvtwl') piece_chars = [[None]*7, [None]*7] for color in (WHITE, BLACK): for piece, char in zip(pieces, char_map[color]): piece_chars[color][piece] = char face = create_cairo_font_face_for_file(addDataPrefix("pieces/ttf/%s.ttf" % name)) return face, piece_chars
def __init__ (self, filename): self.glade = None try: if filename in cachedGlades: self.glade = cachedGlades[filename].get(block=False) except Queue.Empty: pass if not self.glade: glock.acquire() # print "uistuff.py:gladefile = %s" % filename self.glade = gtk.glade.XML(addDataPrefix("glade/%s" % filename)) glock.release() self.extras = {}
def createPlayerUIGlobals (discoverer): global playerItems global smallPlayerItems for variantClass in variants.values(): playerItems += [ [(ipeople, _("Human Being"))] ] smallPlayerItems += [ [(speople, _("Human Being"))] ] for engine in discoverer.getEngines().values(): name = discoverer.getName(engine) c = discoverer.getCountry(engine) path = addDataPrefix("flags/%s.png" % c) if c and os.path.isfile(path): flag_icon = gtk.gdk.pixbuf_new_from_file(path) else: flag_icon = inotebook for variant in discoverer.getEngineVariants(engine): playerItems[variant] += [(flag_icon, name)] smallPlayerItems[variant] += [(snotebook, name)]
def __init__(self): GObject.GObject.__init__(self) chainline = ChainLine(CHAIN_TOP) self.pack_start(chainline, True, True, 0) self.button = Gtk.Button() self.pack_start(self.button, False, True, 0) chainline = ChainLine(CHAIN_BOTTOM) self.pack_start(chainline, True, True, 0) self.image = Gtk.Image() self.image.set_from_file(addDataPrefix("glade/stock-vchain-24.png")) self.button.set_image(self.image) self.button.set_relief(Gtk.ReliefStyle.NONE) self.button.set_property("yalign", 0) self._active = True self.button.connect("clicked", self.onClicked)
def __init__ (self): gtk.VBox.__init__(self) chainline = ChainLine(CHAIN_TOP) self.pack_start(chainline) self.button = gtk.Button() self.pack_start(self.button, expand=False) chainline = ChainLine(CHAIN_BOTTOM) self.pack_start(chainline) self.image = gtk.Image() self.image.set_from_file(addDataPrefix("glade/stock-vchain-24.png")) self.button.set_image(self.image) self.button.set_relief(gtk.RELIEF_NONE) self.button.set_property("yalign", 0) self._active = True self.button.connect("clicked", self.onClicked)
def __init__ (self, filename): self.builder = None try: if filename in cachedGlades: self.builder = cachedGlades[filename].get(block=False) except Empty: pass if not self.builder: glock.acquire() # print "uistuff.py:gladefile = %s" % filename self.builder = Gtk.Builder() self.builder.set_translation_domain("pychess") self.builder.add_from_file(addDataPrefix("glade/%s" % filename)) glock.release() self.extras = {}
def getOpenings (board): """ Return a tuple (move, weight, games, score) for each opening move in the given position. The weight is proportional to the probability that a move should be played. By convention, games is the number of times a move has been tried, and score the number of points it has scored (with 2 per victory and 1 per draw). However, opening books aren't required to keep this information. """ default_path = os.path.join(addDataPrefix("pychess_book.bin")) path = conf.get("opening_file_entry", default_path) openings = [] if not os.path.isfile(path): return openings with open(path, "rb") as bookFile: key = board.hash # Find the first entry whose key is >= the position's hash bookFile.seek(0, os.SEEK_END) lo, hi = 0, bookFile.tell() // 16 - 1 if hi < 0: return openings while lo < hi: mid = (lo + hi) // 2 bookFile.seek(mid * 16) entry = bookFile.read(entrysize) if len(entry) != entrysize: return openings entry = BookEntry._make(entrystruct.unpack(entry)) if entry.key < key: lo = mid + 1 else: hi = mid bookFile.seek(lo * 16) while True: entry = bookFile.read(entrysize) if len(entry) != entrysize: return openings entry = BookEntry._make(entrystruct.unpack(entry)) if entry.key != key: break mv = parsePolyglot(board, entry.move) openings.append( ( mv, entry.weight, entry.games, entry.score ) ) return openings
def __init__ (self, widgets): conf.set("pieceTheme", conf.get("pieceTheme", "pychess")) self.themes = self.discover_themes() store = gtk.ListStore(gtk.gdk.Pixbuf, str) for theme in self.themes: pngfile = "%s/%s.png" % (addDataPrefix("pieces"), theme) if isfile(pngfile): pixbuf = gtk.gdk.pixbuf_new_from_file(pngfile) store.append((pixbuf, theme)) else: print "WARNING: No piece theme preview icons find. Run create_theme_preview.sh !" break iconView = widgets["pieceTheme"] iconView.set_model(store) iconView.set_pixbuf_column(0) iconView.set_text_column(1) def _get_active(iconview): model = iconview.get_model() selected = iconview.get_selected_items() if len(selected) == 0: return conf.get("pieceTheme", "pychess") i = selected[0][0] theme = model[i][1] Pieces.set_piece_theme(theme) return theme def _set_active(iconview, value): try: index = self.themes.index(value) except ValueError: index = 0 iconview.select_path((index,)) uistuff.keep (widgets["pieceTheme"], "pieceTheme", _get_active, _set_active)
def __init__(self, widget, title, id, perspective): TabReceiver.__init__(self, perspective) self.perspective = perspective self.set_no_show_all(True) def customGetTabLabelText(child): try: name = self.book.get_tab_label(child).get_text() except: name = child.get_name() return name self.book = Gtk.Notebook() self.book.set_name(id) self.book_cids = [ self.book.connect("drag-begin", self.__onDragBegin), self.book.connect("drag-end", self.__onDragEnd), self.book.connect_after("switch-page", self.__onPageSwitched), ] self.add(self.book) self.book.show() self.highlightArea = HighlightArea(self) self.button_cids = [] self.starButton = StarArrowButton( self, addDataPrefix("glade/dock_top.svg"), addDataPrefix("glade/dock_right.svg"), addDataPrefix("glade/dock_bottom.svg"), addDataPrefix("glade/dock_left.svg"), addDataPrefix("glade/dock_center.svg"), addDataPrefix("glade/dock_star.svg")) self.button_cids += [ self.starButton.connect("dropped", self.__onDrop), self.starButton.connect("hovered", self.__onHover), self.starButton.connect("left", self.__onLeave), ] self.dockable = True self.panels = [] self.zoomPointer = Gtk.Label() self.realtop = None self.zoomed = False # assert isinstance(widget, Gtk.Notebook) self.__add(widget, title, id)
def __init__ (self, filename): self.builder = Gtk.Builder() self.builder.set_translation_domain("pychess") self.builder.add_from_file(addDataPrefix("glade/%s" % filename)) # TODO: remove this when upstream fixes translations with Python3+Windows if PY3 and sys.platform == "win32": for obj in self.builder.get_objects(): if (not isinstance(obj, Gtk.SeparatorMenuItem)) and hasattr(obj, "get_label"): label = obj.get_label() if label is not None: obj.set_label(_(label)) elif hasattr(obj, "get_title"): title = obj.get_title() if title is not None: obj.set_title(_(title)) if hasattr(obj, "get_tooltip_text"): text = obj.get_tooltip_text() if text is not None: obj.set_tooltip_text(_(text))
def start_puzzle_from(filename): chessfile = PGNFile(protoopen(addDataPrefix("lectures/%s" % filename))) chessfile.limit = 1000 importer = PgnImport(chessfile) chessfile.init_tag_database(importer) records, plys = chessfile.get_records() rec = records[random.randrange(0, len(records))] timemodel = TimeModel(0, 0) gamemodel = GameModel(timemodel) gamemodel.set_practice_game() gamemodel.practice = ("puzzle", filename) chessfile.loadToModel(rec, 0, gamemodel) # TODO: change colors according to FEN! name = rec["White"] p0 = (LOCAL, Human, (WHITE, name), name) engine = discoverer.getEngineByName(stockfish_name) name = rec["Black"] ponder_off = True p1 = (ARTIFICIAL, discoverer.initPlayerEngine, (engine, BLACK, 20, variants[NORMALCHESS], 60, 0, 0, ponder_off), name) def fix_name(gamemodel, name): asyncio. async (gamemodel.start_analyzer(HINT, force_engine=stockfish_name)) gamemodel.players[1].name = name gamemodel.emit("players_changed") gamemodel.connect("game_started", fix_name, name) gamemodel.variant.need_initial_board = True gamemodel.status = WAITING_TO_START perspective = perspective_manager.get_perspective("games") asyncio. async (perspective.generalStart(gamemodel, p0, p1))
def __init__(self, widget, title, id): DockLeaf.__init__(self) self.set_no_show_all(True) self.book = Gtk.Notebook() self.book.connect("drag-begin", self.__onDragBegin) self.book.connect("drag-end", self.__onDragEnd) self.book.connect_after("switch-page", self.__onPageSwitched) self.add(self.book) self.book.show() #self.book.props.tab_vborder = 0 #self.book.props.tab_hborder = 1 self.highlightArea = HighlightArea(self) #self.put(self.highlightArea, 0, 0) self.starButton = StarArrowButton( self, addDataPrefix("glade/dock_top.svg"), addDataPrefix("glade/dock_right.svg"), addDataPrefix("glade/dock_bottom.svg"), addDataPrefix("glade/dock_left.svg"), addDataPrefix("glade/dock_center.svg"), addDataPrefix("glade/dock_star.svg")) #self.put(self.starButton, 0, 0) self.starButton.connect("dropped", self.__onDrop) self.starButton.connect("hovered", self.__onHover) self.starButton.connect("left", self.__onLeave) self.dockable = True self.panels = [] self.zoomPointer = Gtk.Label() self.realtop = None self.zoomed = False #assert isinstance(widget, Gtk.Notebook) self.__add(widget, title, id)
from gi.repository import Gtk from pychess.System import uistuff from pychess.System.prefix import addDataPrefix TYPE_PERSONAL, TYPE_CHANNEL, TYPE_GUEST, TYPE_ADMIN, TYPE_COMP, TYPE_BLINDFOLD = range( 6) def get_playername(playername): re_m = re.match("(\w+)\W*", playername) return re_m.groups()[0] __title__ = _("Talking") __icon__ = addDataPrefix("glade/panel_chat.svg") __desc__ = _("List of server channels") class Sidepanel: def load(self, widgets, connection, lounge): self.connection = connection # deferred imports to not slow down PyChess starting up from pychess.widgets.ViewsPanel import ViewsPanel from pychess.widgets.InfoPanel import InfoPanel from pychess.widgets.ChannelsPanel import ChannelsPanel self.viewspanel = ViewsPanel(self.connection) self.channelspanel = ChannelsPanel(self.connection)
def __init__(self, widgets): # Put engines in trees and combos engines = discoverer.getEngines() allstore = gtk.ListStore(gtk.gdk.Pixbuf, str) for engine in engines.values(): c = discoverer.getCountry(engine) if c: flag = addDataPrefix("flags/%s.png" % c) if not c or not os.path.isfile(flag): flag = addDataPrefix("flags/unknown.png") flag_icon = gtk.gdk.pixbuf_new_from_file(flag) allstore.append((flag_icon, discoverer.getName(engine))) tv = widgets["engines_treeview"] tv.set_model(allstore) tv.append_column( gtk.TreeViewColumn(_("Flag"), gtk.CellRendererPixbuf(), pixbuf=0)) tv.append_column( gtk.TreeViewColumn(_("Name"), gtk.CellRendererText(), text=1)) analyzers = list(discoverer.getAnalyzers()) ana_data = [] invana_data = [] for engine in analyzers: name = discoverer.getName(engine) c = discoverer.getCountry(engine) if c: flag = addDataPrefix("flags/%s.png" % c) if not c or not os.path.isfile(flag): flag = addDataPrefix("flags/unknown.png") flag_icon = gtk.gdk.pixbuf_new_from_file(flag) ana_data.append((flag_icon, name)) invana_data.append((flag_icon, name)) uistuff.createCombo(widgets["ana_combobox"], ana_data) uistuff.createCombo(widgets["inv_ana_combobox"], invana_data) # Save, load and make analyze combos active conf.set("ana_combobox", conf.get("ana_combobox", 0)) conf.set("inv_ana_combobox", conf.get("inv_ana_combobox", 0)) def on_analyzer_check_toggled(check): widgets["analyzers_vbox"].set_sensitive(check.get_active()) widgets["hint_mode"].set_active(check.get_active()) from pychess.Main import gameDic if gameDic: widgets["hint_mode"].set_sensitive(check.get_active()) widgets["analyzer_check"].connect("toggled", on_analyzer_check_toggled) uistuff.keep(widgets["analyzer_check"], "analyzer_check") def on_invanalyzer_check_toggled(check): widgets["inv_analyzers_vbox"].set_sensitive(check.get_active()) widgets["spy_mode"].set_active(check.get_active()) from pychess.Main import gameDic if gameDic: widgets["spy_mode"].set_sensitive(check.get_active()) widgets["inv_analyzer_check"].connect("toggled", on_invanalyzer_check_toggled) uistuff.keep(widgets["inv_analyzer_check"], "inv_analyzer_check") # Put options in trees in add/edit dialog #======================================================================= # tv = widgets["optionview"] # tv.append_column(gtk.TreeViewColumn( # "Option", gtk.CellRendererText(), text=0)) # tv.append_column(gtk.TreeViewColumn( # "Value", gtk.CellRendererText(), text=1)) # # def edit (button): # # iter = widgets["engines_treeview"].get_selection().get_selected()[1] # if iter: row = allstore.get_path(iter)[0] # else: return # # engine = discoverer.getEngineN(row) # optionstags = engine.getElementsByTagName("options") # if not optionstags: # widgets["engine_options_expander"].hide() # else: # widgets["engine_options_expander"].show() # widgets["engine_options_expander"].set_expanded(False) # # optionsstore = gtk.ListStore(str, str) # tv = widgets["optionview"] # tv.set_model(optionsstore) # # for option in optionstags[0].childNodes: # if option.nodeType != option.ELEMENT_NODE: continue # optionsstore.append( [option.getAttribute("name"), # option.getAttribute("default")] ) # # widgets["engine_path_chooser"].set_title(_("Locate Engine")) # widgets["engine_path_chooser"].set_uri("file:///usr/bin/gnuchess") # # dialog = widgets["addconfig_engine"] # answer = dialog.run() # dialog.hide() # widgets["edit_engine_button"].connect("clicked", edit) #======================================================================= #widgets["remove_engine_button"].connect("clicked", remove) #widgets["add_engine_button"].connect("clicked", add) # Give widgets to kepper for combo in ("ana_combobox", "inv_ana_combobox"): def get_value(combobox): engine = list(discoverer.getAnalyzers())[combobox.get_active()] if engine.find('md5') != None: return engine.find('md5').text.strip() def set_value(combobox, value): engine = discoverer.getEngineByMd5(value) if not engine: combobox.set_active(0) else: try: index = list(discoverer.getAnalyzers()).index(engine) except ValueError: index = 0 combobox.set_active(index) uistuff.keep(widgets[combo], combo, get_value, set_value) # Init info box uistuff.makeYellow(widgets["analyzer_pref_infobox"]) widgets["analyzer_pref_infobox"].hide() def updatePrefInfobox(widget, *args): widgets["analyzer_pref_infobox"].show() widgets["ana_combobox"].connect("changed", updatePrefInfobox) widgets["analyzer_check"].connect("toggled", updatePrefInfobox) widgets["inv_ana_combobox"].connect("changed", updatePrefInfobox) widgets["inv_analyzer_check"].connect("toggled", updatePrefInfobox) widgets["preferences"].connect( "hide", lambda *a: widgets["analyzer_pref_infobox"].hide())
def isgit(): return os.path.isdir(prefix.addDataPrefix(".git"))
def load(self, gmwidg): widgets = Gtk.Builder() widgets.add_from_file(addDataPrefix("sidepanel/history.glade")) __widget__ = widgets.get_object("panel") __widget__.unparent() self.boardview = gmwidg.board.view glock_connect(self.boardview.model, "game_changed", self.game_changed) glock_connect(self.boardview.model, "game_started", self.game_changed) glock_connect(self.boardview.model, "moves_undoing", self.moves_undoing) self.boardview.connect("shown_changed", self.shown_changed) # Initialize treeviews self.numbers = widgets.get_object("treeview1") self.left = widgets.get_object("treeview2") self.right = widgets.get_object("treeview3") def fixList(list, xalign=0): list.set_model(Gtk.ListStore(str)) renderer = Gtk.CellRendererText() renderer.set_property("xalign", xalign) list.append_column(Gtk.TreeViewColumn(None, renderer, text=0)) list.get_selection().set_mode(Gtk.SelectionMode.SINGLE) fixList(self.numbers, 1) fixList(self.left, 0) fixList(self.right, 0) self.left.get_selection().connect('changed', self.on_selection_changed, self.left, 0) self.right.get_selection().connect('changed', self.on_selection_changed, self.right, 1) # Lock scrolling scrollwin = widgets.get_object("panel") def changed(vadjust): if not hasattr(vadjust, "need_scroll") or vadjust.need_scroll: vadjust.set_value(vadjust.get_upper() - vadjust.get_page_size()) vadjust.need_scroll = True scrollwin.get_vadjustment().connect("changed", changed) def value_changed(vadjust): vadjust.need_scroll = abs(vadjust.get_value() + vadjust.get_page_size() - \ vadjust.get_upper()) < vadjust.get_step_increment() scrollwin.get_vadjustment().connect("value-changed", value_changed) # Connect to preferences def figuresInNotationCallback(none): game = self.boardview.model for board, move in zip(game.variations[0], game.moves): if conf.get("figuresInNotation", False): notat = toFAN(board, move) else: notat = toSAN(board, move, True) row, col, other = self._ply_to_row_col_other(board.ply + 1) iter = col.get_model().get_iter((row, )) col.get_model().set(iter, 0, notat) conf.notify_add("figuresInNotation", figuresInNotationCallback) # Return return __widget__
def __init__(self, widgets): self.widgets = widgets # Background image path = conf.get("welcome_image", addDataPrefix("glade/clear.png")) conf.set("welcome_image", path) image_chooser_dialog = Gtk.FileChooserDialog( _("Select background image file"), mainwindow(), Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) image_chooser_button = Gtk.FileChooserButton.new_with_dialog( image_chooser_dialog) filter = Gtk.FileFilter() filter.set_name(_("Images")) filter.add_pattern("*.bmp") filter.add_pattern("*.jpg") filter.add_pattern("*.png") filter.add_pattern("*.svg") image_chooser_dialog.add_filter(filter) image_chooser_button.set_filename(path) self.widgets["imageChooserDock"].add(image_chooser_button) image_chooser_button.show() def select_new_image(button): new_image = image_chooser_dialog.get_filename() if new_image: conf.set("welcome_image", new_image) from pychess.widgets.TaskerManager import tasker newTheme(tasker, background=new_image) tasker.queue_draw() else: # restore the original image_chooser_dialog.set_filename(path) image_chooser_button.connect("file-set", select_new_image) # Board Colours style_ctxt = widgets["main_window"].get_style_context() LIGHT = hexcol(style_ctxt.lookup_color("p_light_color")[1]) DARK = hexcol(style_ctxt.lookup_color("p_dark_color")[1]) def onColourSetLight(_): """ :Description: Sets the light squares of the chess board to the value selected in the colour picker """ conf.set('lightcolour', widgets['light_cbtn'].get_color().to_string()) widgets["light_cbtn"].connect_after("color-set", onColourSetLight) def onColourSetDark(_): """ :Description: Sets the dark squares of the chess board to the value selected in the colour picker """ conf.set('darkcolour', widgets['dark_cbtn'].get_color().to_string()) widgets["dark_cbtn"].connect_after("color-set", onColourSetDark) def onResetColourClicked(_): """ :Description: Resets the chess board squares to factory default """ conf.set("lightcolour", LIGHT) conf.set("darkcolour", DARK) widgets["reset_btn"].connect("clicked", onResetColourClicked) # Get the current board colours if set, if not set, set them to default conf.set("lightcolour", conf.get("lightcolour", LIGHT)) conf.set("darkcolour", conf.get("darkcolour", DARK)) # Next 2 lines take a #hex str converts them to a color then to a RGBA representation self.lightcolour = Gdk.RGBA() self.lightcolour.parse(conf.get("lightcolour", LIGHT)) self.darkcolour = Gdk.RGBA() self.darkcolour.parse(conf.get("darkcolour", DARK)) # Set the color swatches in preference to stored values widgets['light_cbtn'].set_rgba(self.lightcolour) widgets['dark_cbtn'].set_rgba(self.darkcolour) # Chess Sets self.themes = self.discoverThemes() store = Gtk.ListStore(GdkPixbuf.Pixbuf, str) for theme in self.themes: pngfile = "%s/%s.png" % (addDataPrefix("pieces"), theme) if isfile(pngfile): pixbuf = get_pixbuf(pngfile) store.append((pixbuf, theme)) else: print( "WARNING: No piece theme preview icons found. Please run \ create_theme_preview.sh !") break self.icon_view = widgets["pieceTheme"] self.icon_view.set_model(store) self.icon_view.set_pixbuf_column(0) self.icon_view.set_text_column(1) def keepSize(crt, _): """ :Description: Hack to fix spacing problem in iconview http://stackoverflow.com/questions/14090094/what-causes-the-different-\ display-behaviour-for-a-gtkiconview-between-different """ crt.handler_block(crt_notify) crt.set_property('width', 40) crt.handler_unblock(crt_notify) crt = self.icon_view.get_cells()[0] crt_notify = crt.connect('notify', keepSize) def _getActive(iconview): model = iconview.get_model() selected = iconview.get_selected_items() if len(selected) == 0: return conf.get("pieceTheme", "Chessicons") indices = selected[0].get_indices() if indices: idx = indices[0] theme = model[idx][1] Pieces.set_piece_theme(theme) return theme def _setActive(iconview, value): try: index = self.themes.index(value) except ValueError: index = 0 iconview.select_path(Gtk.TreePath(index, )) uistuff.keep(widgets["pieceTheme"], "pieceTheme", _getActive, _setActive, "Chessicons")
def __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)
from pychess.compat import basestring, unicode from pychess.Utils import prettyPrintScore from pychess.Utils.const import * from pychess.System import conf from pychess.System.glock import glock_connect from pychess.System.Log import log from pychess.System.prefix import addDataPrefix from pychess.Utils.lutils.lmove import toSAN, toFAN from pychess.Savers.pgn import move_count from pychess.Savers.pgnbase import nag2symbol from pychess.widgets.ChessClock import formatTime __title__ = _("Annotation") __active__ = True __icon__ = addDataPrefix("glade/panel_annotation.svg") __desc__ = _("Annotated game") """ We are maintaining a list of nodes to help manipulate the textbuffer. Node can represent a move, comment or variation (start/end) marker. Nodes are dicts with keys like: board = in move node it's the lboard of move in comment node it's the lboard where the comment belongs to in end variation marker node it's the first lboard of the variation in start variation marker is's None start = the beginning offest of the node in the textbuffer end = the ending offest of the node in the textbuffer parent = the parent lboard if the node is a move in a variation, otherwise None vari = in end variation node it's the start variation marker node
from gi.repository import Gtk from pychess.System import conf from pychess.System.idle_add import idle_add from pychess.System.prefix import addDataPrefix from pychess.Utils.Move import toSAN, toFAN __title__ = _("Move History") __active__ = True __icon__ = addDataPrefix("glade/panel_moves.svg") __desc__ = _( "The moves sheet keeps track of the players' moves and lets you navigate through the game history" ) class Switch: def __init__(self): self.on = False def __enter__(self): self.on = True def __exit__(self, *a): self.on = False class Sidepanel: def __init__(self): self.frozen = Switch() def load(self, gmwidg):
""" Sets the application background image """ from os import path from gi.repository import Gtk, Gdk import cairo from pychess.System.prefix import addDataPrefix, addUserCachePrefix CLEARPATH = addDataPrefix("glade/clear.png") surface = None provider = None loldcolor = None doldcolor = None def giveBackground(widget): widget.connect("draw", expose) widget.connect("style-updated", newTheme) def expose(widget, context): cairo_create = widget.get_window().cairo_create() x_loc = widget.get_allocation().x y_loc = widget.get_allocation().y width = widget.get_allocation().width height = widget.get_allocation().height cairo_create.rectangle(x_loc, y_loc, width, height) if not surface: newTheme(widget)
from math import e from pychess.ic.FICSObjects import ( FICSChallenge, get_seek_tooltip_text, get_challenge_tooltip_text, ) from pychess.perspectives.fics.ParrentListSection import ParrentListSection from pychess.System.Log import log from pychess.System.prefix import addDataPrefix from pychess.widgets.SpotGraph import SpotGraph __title__ = _("Seek Graph") __icon__ = addDataPrefix("glade/manseek.svg") __desc__ = _("Handle seeks on graphical way") YMARKS = (800, 1600, 2400) # YLOCATION = lambda y: min(y / 3000., 3000) XMARKS = (5, 15) # XLOCATION = lambda x: e**(-6.579 / (x + 1)) def YLOCATION(y): return min(y / 3000.0, 3000) def XLOCATION(x): return e**(-6.579 / (x + 1))
import sys from math import e, floor from random import randint from gi.repository import Gtk, GObject from gi.repository import Gdk from pychess.System import uistuff, conf from pychess.System.prefix import addDataPrefix from pychess.Utils.const import WHITE, DRAW, WHITEWON, BLACKWON from pychess.Utils.lutils import leval __title__ = _("Score") __icon__ = addDataPrefix("glade/panel_score.svg") __desc__ = _( "The score panel tries to evaluate the positions and shows you a graph of the game progress" ) class Sidepanel: def load(self, gmwidg): self.boardview = gmwidg.board.view self.plot = ScorePlot(self.boardview) self.sw = __widget__ = Gtk.ScrolledWindow() __widget__.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) port = Gtk.Viewport() port.add(self.plot) port.set_shadow_type(Gtk.ShadowType.NONE) __widget__.add(port) __widget__.show_all()
image = Gtk.Image() image.set_from_pixbuf(pixbuf) return image light_on = load_icon(16, "stock_3d-light-on", "weather-clear") light_off = load_icon(16, "stock_3d-light-off", "weather-clear-night") gtk_close = load_icon(16, "gtk-close", "window-close") media_previous = load_icon(24, "gtk-media-previous-ltr", "media-skip-backward") media_rewind = load_icon(24, "gtk-media-rewind-ltr", "media-seek-backward") media_forward = load_icon(24, "gtk-media-forward-ltr", "media-seek-forward") media_next = load_icon(24, "gtk-media-next-ltr", "media-skip-forward") media_eject = load_icon(24, "player-eject", "media-eject") path = prefix.addDataPrefix("sidepanel") postfix = "Panel.py" files = [f[:-3] for f in os.listdir(path) if f.endswith(postfix)] sidePanels = [imp.load_module(f, *imp.find_module(f, [path])) for f in files] dockLocation = addUserConfigPrefix("pydock.xml") # ############################################################################### # Initialize module variables # # ############################################################################### widgets = None def setWidgets(w): global widgets
uistuff.keep(self.widgets["max_analysis_spin"], "max_analysis_spin", first_value=3) # Sound initing # Setup default sounds EXT = "wav" if sys.platform == "win32" else "ogg" for i in range(11): if not conf.hasKey("soundcombo%d" % i): conf.set("soundcombo%d" % i, SOUND_URI) if not conf.hasKey("sounduri0"): conf.set("sounduri0", "file:" + pathname2url(addDataPrefix("sounds/move1.%s" % EXT))) if not conf.hasKey("sounduri1"): conf.set("sounduri1", "file:" + pathname2url(addDataPrefix("sounds/check1.%s" % EXT))) if not conf.hasKey("sounduri2"): conf.set("sounduri2", "file:" + pathname2url(addDataPrefix("sounds/capture1.%s" % EXT))) if not conf.hasKey("sounduri3"): conf.set("sounduri3", "file:" + pathname2url(addDataPrefix("sounds/start1.%s" % EXT))) if not conf.hasKey("sounduri4"): conf.set("sounduri4", "file:" + pathname2url(addDataPrefix("sounds/win1.%s" % EXT))) if not conf.hasKey("sounduri5"): conf.set("sounduri5", "file:" + pathname2url(addDataPrefix("sounds/lose1.%s" % EXT)))
def initGlade(self, log_viewer): # Init glade and the 'GladeHandlers' self.widgets = widgets = uistuff.GladeWidgets("PyChess.glade") self.glade_handlers = GladeHandlers(self) widgets.getGlade().connect_signals(self.glade_handlers) self.window = widgets["main_window"] # new_game_tasker, internet_game_tasker = NewGameTasker( # ), InternetGameTasker() # tasker.packTaskers(new_game_tasker, internet_game_tasker) # widgets["Background"].add(tasker) # Redirect widgets gamewidget.setWidgets(widgets) # The only menuitems that need special initing for widget in ("hint_mode", "spy_mode"): widgets[widget].set_sensitive(False) uistuff.keep(widgets["hint_mode"], "hint_mode") uistuff.keep(widgets["spy_mode"], "spy_mode") uistuff.keep(widgets["show_sidepanels"], "show_sidepanels") uistuff.keep(widgets["auto_call_flag"], "autoCallFlag") # Show main window and init d'n'd widgets["main_window"].set_title('%s - PyChess' % _('Welcome')) widgets["main_window"].connect("delete-event", self.glade_handlers.on_quit1_activate) widgets["main_window"].connect("key-press-event", self.glade_handlers.on_window_key_press) uistuff.keepWindowSize("main", widgets["main_window"], None, uistuff.POSITION_GOLDEN) # To get drag in the whole window, we add it to the menu and the # background. If it can be gotten to work, the drag_dest_set_proxy # method is very interesting. widgets["menubar1"].drag_dest_set(Gtk.DestDefaults.ALL, DND_LIST, DRAG_ACTION) widgets["box2"].drag_dest_set(Gtk.DestDefaults.ALL, DND_LIST, DRAG_ACTION) widgets["perspectives_notebook"].drag_dest_set(Gtk.DestDefaults.ALL, DND_LIST, DRAG_ACTION) # Init 'minor' dialogs # Log dialog if log_viewer: from pychess.widgets import LogDialog LogDialog.add_destroy_notify( lambda: widgets["log_viewer1"].set_active(0)) else: widgets["log_viewer1"].set_property('sensitive', False) # About dialog self.aboutdialog = widgets["aboutdialog1"] self.aboutdialog.set_program_name(NAME) self.aboutdialog.set_copyright("Copyright © 2006-2020") self.aboutdialog.set_version(VERSION_NAME + " " + VERSION) if isgit(): try: self.git_rev = subprocess.check_output( ["git", "describe", "--tags"]).decode().strip() self.aboutdialog.set_version('%s Git %s' % (VERSION_NAME, self.git_rev)) except subprocess.CalledProcessError: pass self.aboutdialog.set_comments(self.aboutdialog.get_comments()) with open(prefix.addDataPrefix("ARTISTS"), encoding="utf-8") as f: self.aboutdialog.set_artists(f.read().splitlines()) with open(prefix.addDataPrefix("AUTHORS"), encoding="utf-8") as f: self.aboutdialog.set_authors(f.read().splitlines()) with open(prefix.addDataPrefix("DOCUMENTERS"), encoding="utf-8") as f: self.aboutdialog.set_documenters(f.read().splitlines()) with open(prefix.addDataPrefix("TRANSLATORS"), encoding="utf-8") as f: self.aboutdialog.set_translator_credits(f.read()) with open(prefix.addDataPrefix("LICENSE"), encoding="utf-8") as f: self.aboutdialog.set_license(f.read()) widgets["load_recent_game1"].set_submenu(recent_menu) if conf.get("autoLogin"): internet_game_tasker.connectClicked(None)
class SoundTab: SOUND_DIRS = (addDataPrefix("sounds"), "/usr/share/sounds", "/usr/local/share/sounds", os.path.expanduser("~")) COUNT_OF_SOUNDS = 11 actionToKeyNo = { "aPlayerMoves": 0, "aPlayerChecks": 1, "aPlayerCaptures": 2, "gameIsSetup": 3, "gameIsWon": 4, "gameIsLost": 5, "gameIsDrawn": 6, "observedMoves": 7, "oberservedEnds": 8, "shortOnTime": 9, "invalidMove": 10, } _player = None @classmethod def getPlayer(cls): if not cls._player: cls._player = gstreamer.sound_player return cls._player @classmethod def playAction(cls, action): if not conf.get("useSounds", True): return if isinstance(action, str): key_no = cls.actionToKeyNo[action] else: key_no = action typ = conf.get("soundcombo%d" % key_no, SOUND_MUTE) if typ == SOUND_BEEP: sys.stdout.write("\a") sys.stdout.flush() elif typ == SOUND_URI: uri = conf.get("sounduri%d" % key_no, "") if not os.path.isfile(url2pathname(uri[5:])): conf.set("soundcombo%d" % key_no, SOUND_MUTE) return cls.getPlayer().play(uri) def __init__(self, widgets): # Init open dialog opendialog = Gtk.FileChooserDialog( _("Open Sound File"), mainwindow(), Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.ACCEPT)) for dir in self.SOUND_DIRS: if os.path.isdir(dir): opendialog.set_current_folder(dir) break soundfilter = Gtk.FileFilter() soundfilter.set_name(_("Sound files")) soundfilter.add_mime_type("audio/%s" % EXT) soundfilter.add_pattern("*.%s" % EXT) opendialog.add_filter(soundfilter) # Get combo icons icons = ((_("No sound"), "audio-volume-muted", "audio-volume-muted"), (_("Beep"), "stock_bell", "audio-x-generic"), (_("Select sound file..."), "gtk-open", "document-open")) items = [] for level, stock, altstock in icons: image = load_icon(16, stock, altstock) items += [(image, level)] audioIco = load_icon(16, "audio-x-generic") # Set-up combos def callback(combobox, index): if combobox.get_active() == SOUND_SELECT: if opendialog.run() == Gtk.ResponseType.ACCEPT: uri = opendialog.get_uri() model = combobox.get_model() conf.set("sounduri%d" % index, uri) label = unquote(os.path.split(uri)[1]) if len(model) == 3: model.append([audioIco, label]) else: model.set(model.get_iter((3, )), 1, label) combobox.set_active(3) else: combobox.set_active( conf.get("soundcombo%d" % index, SOUND_MUTE)) opendialog.hide() for i in range(self.COUNT_OF_SOUNDS): combo = widgets["sound%dcombo" % i] uistuff.createCombo(combo, items, name="soundcombo%d" % i) # combo.set_active(0) combo.connect("changed", callback, i) label = widgets["soundlabel%d" % i] label.props.mnemonic_widget = combo uri = conf.get("sounduri%d" % i, "") if os.path.isfile(url2pathname(uri[5:])): model = combo.get_model() model.append([audioIco, unquote(os.path.split(uri)[1])]) # combo.set_active(3) for i in range(self.COUNT_OF_SOUNDS): if conf.get("soundcombo%d" % i, SOUND_MUTE) == SOUND_URI and \ not os.path.isfile(url2pathname(conf.get("sounduri%d" % i, "")[5:])): conf.set("soundcombo%d" % i, SOUND_MUTE) uistuff.keep(widgets["sound%dcombo" % i], "soundcombo%d" % i) # Init play button def playCallback(button, index): SoundTab.playAction(index) for i in range(self.COUNT_OF_SOUNDS): button = widgets["sound%dbutton" % i] button.connect("clicked", playCallback, i) # Init 'use sound" checkbutton def checkCallBack(*args): checkbox = widgets["useSounds"] widgets["sounds_frame"].set_property("sensitive", checkbox.get_active()) conf.notify_add("useSounds", checkCallBack) widgets["useSounds"].set_active(True) uistuff.keep(widgets["useSounds"], "useSounds") checkCallBack() if not self.getPlayer().ready: widgets["useSounds"].set_sensitive(False) widgets["useSounds"].set_active(False) uistuff.keep(widgets["alarm_spin"], "alarm_spin", first_value=15)
from pychess.Utils.LearnModel import LearnModel, PUZZLE from pychess.Utils.TimeModel import TimeModel from pychess.Variants import variants from pychess.Players.Human import Human from pychess.Players.engineNest import discoverer from pychess.perspectives import perspective_manager from pychess.perspectives.learn import lessons_solving_progress from pychess.perspectives.learn import puzzles_solving_progress from pychess.Savers.olv import OLVFile from pychess.Savers.pgn import PGNFile from pychess.System import conf from pychess.System.protoopen import protoopen __title__ = _("Puzzles") __icon__ = addDataPrefix("glade/panel_book.svg") __desc__ = _("Lichess practice studies Puzzles from GM games and Chess compositions") # https://lichess.org/practice, http://wtharvey.com, http://www.yacpdb.org puzzles0 = [] puzzles1 = [] puzzles2 = [] puzzles3 = [] for elem in sorted(os.listdir(path=addDataPrefix("learn/puzzles/"))): if elem.startswith("lichess_study") and elem.endswith(".pgn"): if elem[14:31] == "lichess-practice-": puzzles0.append((elem, elem[31:elem.find("_by_")].replace("-", " ").capitalize(), "lichess.org")) else:
userdata = getpwuid(getuid()) realname = userdata.pw_gecos.split(",")[0] if realname: username = realname else: username = userdata.pw_name if getattr(sys, 'frozen', False) and not MSYS2: # pyinstaller specific! if hasattr(sys, "_MEIPASS"): base_path = sys._MEIPASS else: base_path = os.path.dirname(sys.executable) default_book_path = os.path.join(base_path, "pychess_book.bin") else: default_book_path = os.path.join(addDataPrefix("pychess_book.bin")) no_gettext = False idkeyfuncs = {} conid = 0 def notify_add(key, func, *args, section=section): """The signature for func must be self, client, *args, **kwargs""" assert isinstance(key, str) global conid idkeyfuncs[conid] = (key, func, args, section) conid += 1 return conid - 1
# Authors: Jonas Thiem import re from gi.repository import Gtk, GObject, Pango from pychess.System import uistuff from pychess.System.glock import glock_connect from pychess.System.Log import log from pychess.System.prefix import addDataPrefix from pychess.Utils.const import ARTIFICIAL __title__ = _("Engines") __icon__ = addDataPrefix("glade/panel_engineoutput.svg") white = addDataPrefix("glade/panel_engineoutput.svg") __desc__ = _( "The engine output panel shows the thinking output of chess engines (computer players) during a game" ) class Sidepanel: def load(self, gmwidg): # Specify whether the panel should have a horizontal layout: horizontal = True if horizontal: self.box = Gtk.HBox() else: self.box = Gtk.VBox()
# -*- coding: UTF-8 -*- from gi.repository import Gtk from pychess.System import uistuff from pychess.System.prefix import addDataPrefix from pychess.System.idle_add import idle_add from pychess.Utils.const import reprCord from pychess.Utils.repr import reprColor, reprPiece from pychess.Utils.lutils.lmove import TCORD from pychess.Utils.lutils.leval import evalMaterial from pychess.Utils.lutils import strateval __title__ = _("Comments") __icon__ = addDataPrefix("glade/panel_comments.svg") __desc__ = _( "The comments panel will try to analyze and explain the moves played") class Switch: def __init__(self): self.on = False def __enter__(self): self.on = True def __exit__(self, *a): self.on = False
def start_lecture_from(filename, index=None): if index is None: index = 0 # connection.client.run_command("examine") timemodel = TimeModel(0, 0) gamemodel = LearnModel(timemodel) gamemodel.set_learn_data(LECTURE, filename, index) white_name = black_name = "PyChess" p0 = (LOCAL, Human, (WHITE, white_name), white_name) p1 = (LOCAL, Human, (BLACK, black_name), black_name) def on_game_started(gamemodel): perspective.activate_panel("chatPanel") gamemodel.connect("game_started", on_game_started) perspective = perspective_manager.get_perspective("games") asyncio. async (perspective.generalStart(gamemodel, p0, p1)) def lecture_steps(lecture_file): with open(lecture_file, "r") as f: for line in f: yield line return lecture_file = addDataPrefix("learn/lectures/%s" % filename) steps = lecture_steps(lecture_file) @asyncio.coroutine def coro(gamemodel, steps): exit_lecture = False inside_bsetup = False paused = False moves_played = 0 KIBITZ, BACKWARD, BSETUP, BSETUP_DONE, FEN, TOMOVE, WCASTLE, BCASTLE, \ WNAME, BNAME, REVERT, WAIT, MOVE = range(13) while True: try: step = next(steps) print(step) parts = step.strip().split() command = None param = "" if parts[0] == "k" or parts[0] == "kibitz": command = KIBITZ param = " ".join(parts[1:]) elif parts[0] == "back": command = BACKWARD param = int(parts[1]) if len(parts) > 1 else 1 elif parts[0] == "bsetup": if len(parts) == 1: command = BSETUP else: if parts[1] == "done": command = BSETUP_DONE elif parts[1] == "fen": command = FEN param = parts[2] elif parts[1] == "tomove": command = TOMOVE param = "w" if parts[2].lower()[0] == "w" else "b" elif parts[1] == "wcastle": command = WCASTLE param = parts[2] elif parts[1] == "bcastle": command = BCASTLE param = parts[2] elif parts[0] == "tomove": command = TOMOVE param = "w" if parts[1].lower()[0] == "w" else "b" elif parts[0] == "wname": command = WNAME param = parts[1] elif parts[0] == "bname": command = BNAME param = parts[1] elif parts[0] == "revert": command = REVERT elif len(parts) == 1 and parts[0].isdigit(): command = WAIT param = int(parts[0]) else: command = MOVE param = parts[0] if not inside_bsetup and command == BSETUP: inside_bsetup = True pieces = "" color = "" castl = "" ep = "" elif inside_bsetup and command == BSETUP_DONE: inside_bsetup = False wait_sec = int(param) if command == WAIT else 2 if inside_bsetup: wait_sec = -1 while wait_sec >= 0: if gamemodel.lecture_exit_event.is_set(): gamemodel.lecture_exit_event.clear() exit_lecture = True break if gamemodel.lecture_skip_event.is_set(): gamemodel.lecture_skip_event.clear() paused = False break if gamemodel.lecture_pause_event.is_set(): gamemodel.lecture_pause_event.clear() paused = True yield from asyncio.sleep(0.1) if not paused: wait_sec = wait_sec - 0.1 if exit_lecture: gamemodel.players[0].putMessage("Lecture exited.") break if command != WAIT: if command == KIBITZ: gamemodel.players[0].putMessage(param) if command == BACKWARD: gamemodel.undoMoves(param) moves_played -= param if command == MOVE: board = gamemodel.getBoardAtPly(gamemodel.ply) move = parseAny(board, param) gamemodel.curplayer.move_queue.put_nowait(move) moves_played += 1 elif command == REVERT: gamemodel.undoMoves(moves_played) moves_played = 0 elif command == BNAME: gamemodel.players[BLACK].name = param gamemodel.emit("players_changed") elif command == WNAME: gamemodel.players[WHITE].name = param gamemodel.emit("players_changed") elif command == FEN: pieces = param elif command == TOMOVE: color = param elif command == WCASTLE: if param == "both": castl += "KQ" elif param == "kside": castl += "K" elif param == "qside": castl += "Q" elif command == BCASTLE: if param == "both": castl += "kq" elif param == "kside": castl += "k" elif param == "qside": castl += "q" elif command == BSETUP_DONE: if not castl: castl = "-" if not ep: ep = "-" fen = "%s %s %s %s 0 1" % (pieces, color, castl, ep) curplayer = gamemodel.curplayer gamemodel.status = RUNNING gamemodel.loadAndStart(StringIO(fen), fen_loader, 0, -1, first_time=False) curplayer.move_queue.put_nowait("int") gamemodel.emit("game_started") moves_played = 0 except StopIteration: # connection.client.run_command("kibitz That concludes this lecture.") break asyncio. async (coro(gamemodel, steps))
def _init(cls): def callback(widget, allocation): cls.widgets["enterGameNotationFrame"].set_size_request( 223, allocation.height - 4) cls.widgets["enterGameNotationSidePanel"].connect_after( "size-allocate", callback) flags = [] if isInstalled(): path = gettext.find("pychess") else: path = gettext.find("pychess", localedir=addDataPrefix("lang")) if path: default_locale = locale.getdefaultlocale() if default_locale[0] is not None: loc = locale.getdefaultlocale()[0][-2:].lower() flags.append(addDataPrefix("flags/%s.png" % loc)) flags.append(addDataPrefix("flags/us.png")) cls.ib = ImageButton(flags) cls.widgets["imageButtonDock"].add(cls.ib) cls.ib.show() cls.sourcebuffer = GtkSource.Buffer() sourceview = GtkSource.View.new_with_buffer(cls.sourcebuffer) sourceview.set_tooltip_text( _("Type or paste PGN game or FEN positions here")) cls.widgets["scrolledwindow6"].add(sourceview) sourceview.show() # Pgn format does not allow tabulator sourceview.set_insert_spaces_instead_of_tabs(True) sourceview.set_wrap_mode(Gtk.WrapMode.WORD) man = GtkSource.LanguageManager() # Init new version if hasattr(man.props, 'search_path'): try: path = os.path.join(getDataPrefix(), "gtksourceview-3.0/language-specs") man.props.search_path = man.props.search_path + [path] if 'pgn' in man.get_language_ids(): lang = man.get_language('pgn') cls.sourcebuffer.set_language(lang) else: log.warning("Unable to load pgn syntax-highlighting.") cls.sourcebuffer.set_highlight_syntax(True) except NotImplementedError: # Python 2.7.3 in Ubuntu 12.04 log.warning("Unable to load pgn syntax-highlighting.") # Init old version else: os.environ["XDG_DATA_DIRS"] = getDataPrefix() + ":/usr/share/" man = GtkSource.LanguageManager() for lang in man.get_available_languages(): if lang.get_name() == "PGN": cls.sourcebuffer.set_language(lang) break else: log.warning("Unable to load pgn syntax-highlighting.") cls.sourcebuffer.set_highlight(True)
# -*- coding: UTF-8 -*- from gi.repository import Gtk, GObject from pychess.Utils.lutils.LBoard import LBoard from pychess.Utils.lutils.lmove import toSAN, parseAN from pychess.Utils.const import FEN_START from pychess.System.prefix import addDataPrefix __title__ = _("Openings") __icon__ = addDataPrefix("glade/panel_book.svg") __desc__ = _("Openings panel can filter game list by opening moves") class OpeningTreePanel(Gtk.TreeView): def __init__(self, persp): GObject.GObject.__init__(self) self.persp = persp self.filtered = False self.persp.connect("chessfile_imported", self.on_chessfile_imported) self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) self.liststore = Gtk.ListStore(int, str, int, int) self.modelsort = Gtk.TreeModelSort(self.liststore) self.modelsort.set_sort_column_id(2, Gtk.SortType.DESCENDING) self.set_model(self.modelsort)
from collections import namedtuple from pychess.System import conf from pychess.System.prefix import addDataPrefix from pychess.Utils.lutils.lmove import parsePolyglot from pychess.System.Log import log if getattr(sys, 'frozen', False): # pyinstaller specific! if hasattr(sys, "_MEIPASS"): base_path = sys._MEIPASS else: base_path = os.path.dirname(sys.executable) default_path = os.path.join(base_path, "pychess_book.bin") else: default_path = os.path.join(addDataPrefix("pychess_book.bin")) path = conf.get("opening_file_entry", default_path) if os.path.isfile(path): bookfile = True else: bookfile = False log.warning("Could not find %s" % path) # The book probing code is based on that of PolyGlot by Fabien Letouzey. # PolyGlot is available under the GNU GPL from http://wbec-ridderkerk.nl BookEntry = namedtuple('BookEntry', 'key move weight games score') # 'key' c_uint64 the position's hash # 'move' c_uint16 the candidate move
# English eco.pgn was converted from # http://www.chessville.com/downloads_files/instructional_materials/ECO_Codes_With_Names_and_Moves.zip # others from wikipedia import os import sqlite3 from pychess.Savers.pgn import load from pychess.System.protoopen import protoopen from pychess.System.prefix import addDataPrefix from pychess.Utils.eco import hash_struct path = os.path.join(addDataPrefix("eco.db")) conn = sqlite3.connect(path) if __name__ == '__main__': c = conn.cursor() c.execute("drop table if exists openings") # Unfortunately sqlite doesn't support uint64, so we have to use blob type to store polyglot-hash values c.execute( "create table openings(hash blob, base integer, eco text, lang text, opening text, variation text)" ) def feed(pgnfile, lang): cf = load(protoopen(pgnfile)) rows = [] old_eco = "" for i, game in enumerate(cf.games): model = cf.loadToModel(i)
def __init__(self, white=True): GObject.GObject.__init__(self) self.attached_engine = None # engine attached to which we listen self.white = white self.clear_on_output = False # next thinking line belongs to new move # Title bar: self.title_label = Gtk.Label() self.title_color = Gtk.Image() self.title_hbox = Gtk.HBox() #self.title_hbox.pack_start(self.title_color, False) self.title_hbox.pack_start(self.title_color, False, False, 0) #self.title_hbox.pack_start(self.title_label, True, True) self.title_hbox.pack_start(self.title_label, True, True, 0) # Set black or white player icon in front: if white == True: self.title_color.set_from_file(addDataPrefix("glade/white.png")) else: self.title_color.set_from_file(addDataPrefix("glade/black.png")) # output scrolled window container: self.output_container = Gtk.ScrolledWindow() self.output_container.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) # Allow the user to make the output pretty tiny vertically # (to save space, only the last output line is really important) self.output_container.set_size_request(-1, 40) # scroll down on new output: -- not reliable with multilines added #uistuff.keepDown(self.output_container) # scroll down on new output: -- brute force variant def changed(vadjust): vadjust.set_value(vadjust.get_upper() - vadjust.get_page_size()) self.output_container.get_vadjustment().connect("changed", changed) # Text field for output: self.output = Gtk.TextView() self.output_container.add(self.output) self.output.set_editable(False) self.output.set_wrap_mode(Gtk.WrapMode.WORD_CHAR) self.tag_bold = self.output.get_buffer().create_tag( "bold", weight=Pango.Weight.BOLD) self.tag_color = self.output.get_buffer().create_tag( "color", foreground="#0033ff") # Add all sub widgets to ourselves: #self.pack_start(self.title_hbox, False) #self.pack_start(self.output_container, True) self.pack_start(self.title_hbox, False, False, 0) self.pack_start(self.output_container, True, False, 0) # Precompile regexes we want to use: self.re_thinking_line_cecp = re.compile(r'^[0-9]+\.? +\-?[0-9]+ +') self.re_thinking_line_uci = re.compile( r'^info (.*) pv [a-hA-H][0-9][a-hA-H][0-9](.*)$') self.re_move_line_cecp_alg = re.compile( r'^(move +)?[a-hA-H][0-9][a-hA-H][0-9]$') self.re_move_line_cecp_san = re.compile( r'^(move +)?([QKNB]?[a-hA-H]?[xX@]?[a-hA-H][0-9]\+?#?|[oO]-[oO]-[oO]|[oO]-[oO])$' ) self.re_move_line_uci = re.compile( r'^bestmove +[a-hA-H][0-9][a-hA-H][0-9]( .*)?$') self.re_extract_cecp_all = re.compile( r'^([0-9]+)\.? +(\-?[0-9]+) +[0-9]+.?[0-9]* ([^ ].*)$') self.re_extract_uci_depth = re.compile(r'depth +([0-9]+) +') self.re_extract_uci_score = re.compile(r'score cp +(-?[0-9]+) +') self.re_extract_uci_score_mate_other = re.compile( r'score +mate +([0-9]+) +') self.re_extract_uci_score_mate_us = re.compile( r'score +mate +\-([0-9]+) +') self.re_extract_uci_score_lowerbound = re.compile( r'score +lowerbound +') self.re_extract_uci_score_upperbound = re.compile( r'score +upperbound +') self.re_extract_uci_pv = re.compile(r'pv +([a-hA-HoO].*[^ ]) *$')
def init_layout(self): perspective_widget = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) perspective_manager.set_perspective_widget("database", perspective_widget) self.gamelist = GameList(database.load(None)) self.switcher_panel = SwitcherPanel(self.gamelist) self.opening_tree_panel = OpeningTreePanel(self.gamelist) self.filter_panel = FilterPanel(self.gamelist) self.preview_panel = PreviewPanel(self.gamelist) self.progressbar0 = Gtk.ProgressBar(show_text=True) self.progressbar = Gtk.ProgressBar(show_text=True) self.progress_dialog = Gtk.Dialog("Import", None, 0, ( Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)) self.progress_dialog.get_content_area().pack_start(self.progressbar0, True, True, 0) self.progress_dialog.get_content_area().pack_start(self.progressbar, True, True, 0) self.progress_dialog.get_content_area().show_all() perspective = perspective_manager.get_perspective("database") self.dock = PyDockTop("database", perspective) align = Gtk.Alignment() align.show() align.add(self.dock) self.dock.show() perspective_widget.pack_start(align, True, True, 0) dockLocation = addUserConfigPrefix("pydock-database.xml") docks = { "gamelist": (Gtk.Label(label="gamelist"), self.gamelist.box), "switcher": (dock_panel_tab(_("Database switcher"), "", addDataPrefix("glade/panel_docker.svg")), self.switcher_panel.alignment), "openingtree": (dock_panel_tab(_("Opening tree"), "", addDataPrefix("glade/panel_docker.svg")), self.opening_tree_panel.box), "filter": (dock_panel_tab(_("Filter"), "", addDataPrefix("glade/panel_docker.svg")), self.filter_panel.box), "preview": (dock_panel_tab(_("Preview"), "", addDataPrefix("glade/panel_docker.svg")), self.preview_panel.box), } if os.path.isfile(dockLocation): try: self.dock.loadFromXML(dockLocation, docks) except Exception as e: stringio = StringIO() traceback.print_exc(file=stringio) error = stringio.getvalue() log.error("Dock loading error: %s\n%s" % (e, error)) msg_dia = Gtk.MessageDialog(None, type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.CLOSE) msg_dia.set_markup(_( "<b><big>PyChess was unable to load your panel settings</big></b>")) msg_dia.format_secondary_text(_( "Your panel settings have been reset. If this problem repeats, \ you should report it to the developers")) msg_dia.run() msg_dia.hide() os.remove(dockLocation) for title, panel in docks.values(): title.unparent() panel.unparent() if not os.path.isfile(dockLocation): leaf = self.dock.dock(docks["gamelist"][1], CENTER, docks["gamelist"][0], "gamelist") leaf.setDockable(False) leaf.dock(docks["switcher"][1], NORTH, docks["switcher"][0], "switcher") leaf = leaf.dock(docks["filter"][1], EAST, docks["filter"][0], "filter") leaf = leaf.dock(docks["openingtree"][1], SOUTH, docks["openingtree"][0], "openingtree") leaf.dock(docks["preview"][1], SOUTH, docks["preview"][0], "preview") def unrealize(dock): dock.saveToXML(dockLocation) dock._del() self.dock.connect("unrealize", unrealize) self.dock.show_all() perspective_widget.show_all() perspective_manager.set_perspective_toolbuttons("database", [self.import_button, self.close_button]) self.switcher_panel.connect("chessfile_switched", self.on_chessfile_switched)