diff --git a/Resources/IntFiles/Iconos.bin b/Resources/IntFiles/Iconos.bin index 0ca85100..180f208a 100644 Binary files a/Resources/IntFiles/Iconos.bin and b/Resources/IntFiles/Iconos.bin differ diff --git a/Resources/IntFiles/Iconos.dic b/Resources/IntFiles/Iconos.dic index 0f6f5fb7..ca7029a8 100644 --- a/Resources/IntFiles/Iconos.dic +++ b/Resources/IntFiles/Iconos.dic @@ -532,3 +532,4 @@ AI=1055409,1056083 Advice=1056083,1057168 PauseBlue=1057168,1058181 Forest=1058181,1059441 +Analisis=1059441,1059832 diff --git a/Resources/IntFiles/Iconos_dark.bin b/Resources/IntFiles/Iconos_dark.bin index 46a93653..efc6a613 100644 Binary files a/Resources/IntFiles/Iconos_dark.bin and b/Resources/IntFiles/Iconos_dark.bin differ diff --git a/Resources/IntFiles/Iconos_dark.dic b/Resources/IntFiles/Iconos_dark.dic index ce78c91c..0d223c25 100644 --- a/Resources/IntFiles/Iconos_dark.dic +++ b/Resources/IntFiles/Iconos_dark.dic @@ -532,3 +532,4 @@ AI=1045106,1045894 Advice=1045894,1047372 PauseBlue=1047372,1048310 Forest=1048310,1049985 +Analisis=1049985,1050636 diff --git a/Resources/IntFiles/Iconos_sepia.bin b/Resources/IntFiles/Iconos_sepia.bin index 95307bea..18c9e0fd 100644 Binary files a/Resources/IntFiles/Iconos_sepia.bin and b/Resources/IntFiles/Iconos_sepia.bin differ diff --git a/Resources/IntFiles/Iconos_sepia.dic b/Resources/IntFiles/Iconos_sepia.dic index a69d66de..724d9f4e 100644 --- a/Resources/IntFiles/Iconos_sepia.dic +++ b/Resources/IntFiles/Iconos_sepia.dic @@ -532,3 +532,4 @@ AI=966338,967181 Advice=967181,968588 PauseBlue=968588,969533 Forest=969533,970955 +Analisis=970955,971598 diff --git a/Resources/Locale/fr/LC_MESSAGES/lucaschess.mo b/Resources/Locale/fr/LC_MESSAGES/lucaschess.mo index 86a49066..bb2673eb 100644 Binary files a/Resources/Locale/fr/LC_MESSAGES/lucaschess.mo and b/Resources/Locale/fr/LC_MESSAGES/lucaschess.mo differ diff --git a/Resources/Locale/hu/LC_MESSAGES/lucaschess.mo b/Resources/Locale/hu/LC_MESSAGES/lucaschess.mo index 19b4cb64..87371a13 100644 Binary files a/Resources/Locale/hu/LC_MESSAGES/lucaschess.mo and b/Resources/Locale/hu/LC_MESSAGES/lucaschess.mo differ diff --git a/Resources/Locale/hu/lang.ini b/Resources/Locale/hu/lang.ini index 6d633000..c505d848 100644 --- a/Resources/Locale/hu/lang.ini +++ b/Resources/Locale/hu/lang.ini @@ -1,3 +1,3 @@ NAME=Magyar AUTHOR=József Oláh -%=99 +%=100 diff --git a/bin/Code/Analysis/Analysis.py b/bin/Code/Analysis/Analysis.py index b26425a6..97a48368 100644 --- a/bin/Code/Analysis/Analysis.py +++ b/bin/Code/Analysis/Analysis.py @@ -156,9 +156,11 @@ def active_position(self): return move_active.position, move_active.from_sq, move_active.to_sq def get_game(self): - game_original = self.move.game + game_original: Game.Game = self.move.game if self.move.movimiento(): game_send = game_original.copy_until_move(self.move) + if len(game_send) == 0: + game_send = game_original.copia() else: game_send = game_original.copia() if self.pos_mov_active > -1: diff --git a/bin/Code/Analysis/WindowAnalysis.py b/bin/Code/Analysis/WindowAnalysis.py index d461f24d..1473ec4f 100644 --- a/bin/Code/Analysis/WindowAnalysis.py +++ b/bin/Code/Analysis/WindowAnalysis.py @@ -318,31 +318,31 @@ def __init__(self, tb_analysis, ventana, is_white, must_save, tab_analysis_init, ly_motor = Colocacion.H().control(self.lbPuntuacion).relleno().control(self.lb_engine).control(self.lb_time) - lyV = Colocacion.V() - lyV.control(tb_work) - lyV.otro(ly_tabl) - lyV.otro(lytb).espacio(20) - lyV.otro(ly_motor) - lyV.control(scroll) - lyV.relleno() + ly_v = Colocacion.V() + ly_v.control(tb_work) + ly_v.otro(ly_tabl) + ly_v.otro(lytb).espacio(20) + ly_v.otro(ly_motor) + ly_v.control(scroll) + # ly_v.relleno() wm = OneAnalysis(self, tab_analysis_init) tab_analysis_init.wmu = wm # Layout self.ly = Colocacion.H().margen(10) - self.ly.otro(lyV) + self.ly.otro(ly_v) self.ly.control(wm) - lyM = Colocacion.H().margen(0).otro(self.ly).relleno() + ly_m = Colocacion.H().margen(0).otro(self.ly).relleno() layout = Colocacion.V() - layout.otro(lyM) + layout.otro(ly_m) layout.margen(3) layout.setSpacing(1) self.setLayout(layout) - self.restore_video(siTam=False) + self.restore_video(siAncho=False) wm.cambiadoRM(tab_analysis_init.pos_selected) self.activate_analysis(tab_analysis_init) diff --git a/bin/Code/Analysis/WindowAnalysisVariations.py b/bin/Code/Analysis/WindowAnalysisVariations.py index c52503ef..2602e710 100644 --- a/bin/Code/Analysis/WindowAnalysisVariations.py +++ b/bin/Code/Analysis/WindowAnalysisVariations.py @@ -79,7 +79,7 @@ def start_clock(self, funcion): self.timer.start(1000) def stop_clock(self): - if hasattr(self, "timer"): + if hasattr(self, "timer") and self.timer: self.timer.stop() delattr(self, "timer") diff --git a/bin/Code/Board/Board.py b/bin/Code/Board/Board.py index f99abe07..9ef3d4f3 100644 --- a/bin/Code/Board/Board.py +++ b/bin/Code/Board/Board.py @@ -1382,7 +1382,10 @@ def dbvisual_close(self): self.dbVisual.close() def dbvisual_contains(self, fenm2): - return fenm2 in self.dbVisual.dbFEN and len(self.dbVisual.dbFEN[fenm2]) > 0 + try: + return fenm2 in self.dbVisual.dbFEN and len(self.dbVisual.dbFEN[fenm2]) > 0 + except AttributeError: + return False def dbvisual_list(self, fenm2): return self.dbVisual.dbFEN[fenm2] diff --git a/bin/Code/Databases/DBgames.py b/bin/Code/Databases/DBgames.py index a13377fb..5af1c812 100644 --- a/bin/Code/Databases/DBgames.py +++ b/bin/Code/Databases/DBgames.py @@ -381,8 +381,8 @@ def remove_data(self, li_recnos): else: for recno in li_recnos: rowid = self.li_row_ids[recno] - sql += " WHERE ROWID=?" - self.conexion.execute(sql, [rowid, ]) + sqln = f"{sql} WHERE ROWID=?" + self.conexion.execute(sqln, [rowid, ]) self.conexion.commit() def get_summary(self, pvBase, dicAnalisis, with_figurines, allmoves=True): diff --git a/bin/Code/Databases/WDB_Games.py b/bin/Code/Databases/WDB_Games.py index 3a1ed7d9..41a1d12e 100644 --- a/bin/Code/Databases/WDB_Games.py +++ b/bin/Code/Databases/WDB_Games.py @@ -221,9 +221,8 @@ def setInfoMove(self, infoMove): def updateStatus(self): if self.terminado: return - if not self.summaryActivo: - txt = "" - else: + recs = self.db_games.reccount() + if self.summaryActivo: game = self.summaryActivo.get("game", Game.Game()) nj = len(game) if nj > 1: @@ -233,9 +232,10 @@ def updateStatus(self): txt = "" si_pte = self.db_games.if_there_are_records_to_read() if not si_pte: - recs = self.db_games.reccount() if recs: txt += "%s: %d" % (_("Games"), recs) + else: + txt += f'{_("Working...")}' if self.where: where = self.where wxpv = 'XPV LIKE "' @@ -249,8 +249,19 @@ def updateStatus(self): pgn = g.pgn_base_raw(translated=True) where = where[:pos] + pgn + where[pos + len(wxpv) + pos_apos + 1:] txt += " | %s: %s" % (_("Filter"), where) - if si_pte: - QtCore.QTimer.singleShot(1000, self.updateStatus) + else: + si_pte = self.db_games.if_there_are_records_to_read() + txt = "" + if not si_pte: + if recs: + txt += "%s: %d" % (_("Games"), recs) + else: + txt += f'{_("Working...")}' + + if si_pte: + QtCore.QTimer.singleShot(500, self.updateStatus) + + self.grid.refresh() self.status.showMessage(txt, 0) @@ -1409,7 +1420,8 @@ def tw_exportar_db(self, lista): if not dbpath: return if dbpath == ":n": - dbpath = new_database(self, self.configuration) + name = os.path.basename(self.db_games.path_file) if self.is_temporary else "" + dbpath = new_database(self, self.configuration, name=name) if dbpath is None: return @@ -1432,7 +1444,7 @@ def tw_exportar_pgn(self, only_selected=False): remove_comments = dic_result["REMCOMMENTSVAR"] ws = WindowSavePGN.FileSavePGN(self, dic_result) if ws.open(): - pb = QTUtil2.BarraProgreso1(self, _("Saving..."), formato1="%p%") + pb = QTUtil2.BarraProgreso1(self, _("Saving..."), formato1="%v/%m (%p%)") pb.mostrar() if only_selected: li_sel = self.grid.recnosSeleccionados() @@ -1441,7 +1453,10 @@ def tw_exportar_pgn(self, only_selected=False): pb.set_total(len(li_sel)) for n, recno in enumerate(li_sel): pb.pon(n) - game = self.db_games.read_game_recno(recno) + try: + game = self.db_games.read_game_recno(recno) + except AttributeError: + return if pb.is_canceled(): break if game is None: @@ -1469,6 +1484,8 @@ def tw_exportar_csv(self, only_selected): dic_csv.get("FOLDER", self.configuration.carpeta), "csv") if not path_csv: return + if not path_csv.lower().endswith(".csv"): + path_csv = path_csv.strip() + ".csv" dic_csv["FOLDER"] = os.path.dirname(path_csv) self.configuration.write_variables("CSV", dic_csv) pb = QTUtil2.BarraProgreso1(self, _("Saving...")) @@ -1508,16 +1525,20 @@ def tw_exportar_csv(self, only_selected): writer.writerow(li_data) if not pb.is_canceled(): + QTUtil2.temporary_message(self, _("Saved"), 0.8) if not self.is_temporary: self.changes = False pb.close() if not pb.is_canceled(): Code.startfile(path_csv) - def tw_importar_pgn(self): - files = SelectFiles.select_pgns(self) - if not files: - return None + def tw_importar_pgn(self, path_pgn=None): + if path_pgn is None: + files = SelectFiles.select_pgns(self) + if not files: + return None + else: + files = [path_pgn,] dl_tmp = QTVarios.ImportarFicheroPGN(self) if self.db_games.allows_duplicates: @@ -1656,7 +1677,6 @@ def url_id(url): continue fen = row[pos_fen] pv = row[pos_moves] - del row[pos_moves] if dic_gid_pv: gid = url_id(row[pos_gameurl]) opening = dic_gid_pv.get(gid) @@ -1668,6 +1688,7 @@ def url_id(url): eco = "" row.append(name) row.append(eco) + del row[pos_moves] with_commit = pos % 100000 == 0 self.db_games.add_reg_lichess(sql, fen, pv, row, with_commit) @@ -1685,16 +1706,17 @@ def url_id(url): class WOptionsDatabase(QtWidgets.QDialog): - def __init__(self, owner, configuration, dic_data): + def __init__(self, owner, configuration, dic_data, with_import_pgn=False, name=""): super(WOptionsDatabase, self).__init__(owner) self.new = len(dic_data) == 0 self.dic_data = dic_data self.dic_data_resp = None + self.with_import_pgn = with_import_pgn - def d_str(key): - return dic_data.get(key, "") + def d_str(key, default=""): + return dic_data.get(key, default) def d_true(key): return dic_data.get(key, True) @@ -1713,7 +1735,7 @@ def d_false(key): valid_rx = r'^[^<>:;,?"*|/\\]+' lb_name = Controles.LB2P(self, _("Name")) - self.ed_name = Controles.ED(self, d_str("NAME")).controlrx(valid_rx) + self.ed_name = Controles.ED(self, d_str("NAME", name)).controlrx(valid_rx) ly_name = Colocacion.H().control(lb_name).control(self.ed_name) @@ -1774,6 +1796,16 @@ def d_false(key): x1 = -2 ly_group = Colocacion.V().otro(ly_group).espacio(x1).otro(ly_subgroup_l1).espacio(x1).otro(ly_subgroup_l2) + self.path_import_pgn = None + ly_import_pgn = None + if self.with_import_pgn: + self.lb_import_pgn = Controles.LB2P(self, f'{_("Import")}/{_("PGN")}') + self.pb_select_import_pgn = Controles.PB(self, "", self.select_pgn, False) + self.pb_select_import_pgn.setSizePolicy( + QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) + ) + ly_import_pgn = Colocacion.H().control(self.lb_import_pgn).control(self.pb_select_import_pgn) + gb_group = Controles.GB(self, "%s (%s)" % (_("Group"), _("optional")), ly_group) lb_summary = Controles.LB2P(self, _("Opening explorer depth (0=disable)")) @@ -1819,6 +1851,8 @@ def d_false(key): layout.otro(ly_name).espacio(x0).control(gb_group).espacio(x0) layout.otro(ly_summary).espacio(x0) layout.otro(ly_external).espacio(x0) + if ly_import_pgn: + layout.otro(ly_import_pgn).espacio(x0) layout.control(gb_restrictions) layout.margen(9) @@ -1840,6 +1874,23 @@ def select_external(self): self.bt_external.set_text(self.external_folder) + def select_pgn(self): + key_var = "OPENINGLINES" + dic_var = self.configuration.read_variables(key_var) + carpeta = dic_var.get("CARPETAPGN", self.configuration.carpeta) + + fichero_pgn = SelectFiles.leeFichero(self, carpeta, "pgn", titulo=_("File to import")) + if not fichero_pgn: + return + dic_var["CARPETAPGN"] = os.path.dirname(fichero_pgn) + self.configuration.write_variables(key_var, dic_var) + self.path_import_pgn = fichero_pgn + name_pgn = os.path.basename(fichero_pgn) + self.pb_select_import_pgn.set_text(name_pgn) + name = self.ed_name.texto().strip() + if not name: + self.ed_name.set_text(name_pgn[:-4]) + def remove_external(self): self.external_folder = "" self.bt_external.set_text("") @@ -1929,15 +1980,17 @@ def save(self): "ALLOWS_COMPLETE_GAMES": self.chb_complete.valor(), "ALLOWS_ZERO_MOVES": self.chb_zeromoves.valor(), "SUMMARY_DEPTH": self.sb_summary.valor(), "FILEPATH": filepath_in_databases, "EXTERNAL_FOLDER": self.external_folder, - "FILEPATH_WITH_DATA": filepath_with_data + "FILEPATH_WITH_DATA": filepath_with_data, } + if self.with_import_pgn: + self.dic_data_resp["IMPORT_PGN"] = self.path_import_pgn self.accept() -def new_database(owner, configuration): +def new_database(owner, configuration, with_import_pgn=False, name = ""): dic_data = {} - w = WOptionsDatabase(owner, configuration, dic_data) + w = WOptionsDatabase(owner, configuration, dic_data, with_import_pgn, name) if w.exec_(): filepath = w.dic_data_resp["FILEPATH"] if w.external_folder: @@ -1947,9 +2000,15 @@ def new_database(owner, configuration): for key, value in w.dic_data_resp.items(): db.save_config(key, value) db.close() - return filepath + if with_import_pgn: + return filepath, w.dic_data_resp["IMPORT_PGN"] + else: + return filepath else: - return None + if with_import_pgn: + return None, None + else: + return None class WTags(LCDialog.LCDialog): diff --git a/bin/Code/Databases/WDB_Players.py b/bin/Code/Databases/WDB_Players.py index 80996939..ded86074 100644 --- a/bin/Code/Databases/WDB_Players.py +++ b/bin/Code/Databases/WDB_Players.py @@ -178,6 +178,8 @@ def __init__(self, procesador, wb_database, db_games): tabs.new_tab(self.gridOpeningBlack, _("Black openings")) tabs.new_tab(wWhite, _("White moves")) tabs.new_tab(wblack, _("Black moves")) + tabs.dispatchChange(self.tabChanged) + self.tabs = tabs # ToolBar liAccionesWork = [ @@ -200,23 +202,42 @@ def __init__(self, procesador, wb_database, db_games): self.setdbGames(db_games) self.setPlayer(self.leeVariable("PLAYER", "")) + def tabChanged(self, ntab): + QtWidgets.QApplication.processEvents() + + if ntab == 0: #in (0, 2): + grid = self.gridOpeningWhite + elif ntab == 1: + grid = self.gridOpeningBlack + elif ntab == 2: + grid = self.gridMovesWhite + else: + grid = self.gridMovesBlack + recno = grid.recno() + reccount = grid.reccount() + if reccount: + self.grid_cambiado_registro(grid, recno, None) + + def actualiza(self): + self.tabChanged(self.tabs.current_position()) + def dispatchMoves(self, side, opcion): - dataSide = self.data[MOVES_WHITE if side == "white" else MOVES_BLACK] + data_side = self.data[MOVES_WHITE if side == "white" else MOVES_BLACK] if opcion == "all": - showData = range(len(dataSide)) + show_data = range(len(data_side)) elif opcion in ("e2e4", "d2d4", "c2c4", "g1f3"): - showData = [n for n in range(len(dataSide)) if dataSide[n]["pv"].startswith(opcion)] + show_data = [n for n in range(len(data_side)) if data_side[n]["pv"].startswith(opcion)] elif opcion == "other": - showData = [ + show_data = [ n - for n in range(len(dataSide)) - if not dataSide[n]["pv"].startswith("e2e4") - and not dataSide[n]["pv"].startswith("d2d4") - and not dataSide[n]["pv"].startswith("c2c4") - and not dataSide[n]["pv"].startswith("g1f3") + for n in range(len(data_side)) + if not data_side[n]["pv"].startswith("e2e4") + and not data_side[n]["pv"].startswith("d2d4") + and not data_side[n]["pv"].startswith("c2c4") + and not data_side[n]["pv"].startswith("g1f3") ] else: # if opcion.startswith("p"): @@ -224,17 +245,17 @@ def dispatchMoves(self, side, opcion): if num == 0: return self.dispatchMoves(side, "all") if self.lastFilterMoves[side].startswith("p"): - showDataPrevio = range(len(dataSide)) + show_data_previo = range(len(data_side)) else: - showDataPrevio = self.movesWhite if side == "white" else self.movesBlack - showData = [n for n in showDataPrevio if dataSide[n]["pv"].count(" ") < num] + show_data_previo = self.movesWhite if side == "white" else self.movesBlack + show_data = [n for n in show_data_previo if data_side[n]["pv"].count(" ") < num] if side == "white": - self.movesWhite = showData + self.movesWhite = show_data self.gridMovesWhite.refresh() else: - self.movesBlack = showData + self.movesBlack = show_data self.gridMovesBlack.refresh() self.lastFilterMoves[side] = opcion @@ -666,3 +687,5 @@ def ordena(empieza, nivel): self.gridMovesWhite.gotop() self.gridMovesBlack.gotop() self.gridOpeningWhite.setFocus() + + self.actualiza() diff --git a/bin/Code/Databases/WindowDatabase.py b/bin/Code/Databases/WindowDatabase.py index b54ee21a..3cb8cd7c 100644 --- a/bin/Code/Databases/WindowDatabase.py +++ b/bin/Code/Databases/WindowDatabase.py @@ -25,9 +25,9 @@ def __init__(self, w_parent, procesador, file_database, is_temporary, si_select) self.db_games = DBgames.DBgames(file_database) self.dicvideo = self.restore_dicvideo() - dicVideo = self.dicvideo + dic_video = self.dicvideo - siSummary = not si_select + si_summary = not si_select self.wplayer = WDB_Players.WPlayer(procesador, self, self.db_games) self.wplayer_active = False @@ -36,7 +36,7 @@ def __init__(self, w_parent, procesador, file_database, is_temporary, si_select) self.register_grid(self.wplayer.gridOpeningWhite) self.register_grid(self.wplayer.gridOpeningBlack) - if siSummary: + if si_summary: self.wsummary = WDB_Summary.WSummary(procesador, self, self.db_games, siMoves=False) self.register_grid(self.wsummary.grid) @@ -49,7 +49,7 @@ def __init__(self, w_parent, procesador, file_database, is_temporary, si_select) self.tab = Controles.Tab() self.tab.new_tab(self.wgames, _("Games")) - if siSummary: + if si_summary: self.tab.new_tab(self.wsummary, _("Opening explorer")) self.tab.dispatchChange(self.tabChanged) if not si_select: @@ -76,15 +76,15 @@ def __init__(self, w_parent, procesador, file_database, is_temporary, si_select) self.setLayout(layout) self.restore_video(anchoDefecto=1200, altoDefecto=600) - if not dicVideo: - dicVideo = {"SPLITTER": [800, 380], "TREE_1": 25, "TREE_2": 25, "TREE_3": 50, "TREE_4": 661} + if not dic_video: + dic_video = {"SPLITTER": [800, 380], "TREE_1": 25, "TREE_2": 25, "TREE_3": 50, "TREE_4": 661} - if not ("SPLITTER" in dicVideo): + if not ("SPLITTER" in dic_video): ancho = self.width() ancho_board = self.infoMove.board.width() sz = [ancho - ancho_board, ancho_board] else: - sz = dicVideo["SPLITTER"] + sz = dic_video["SPLITTER"] self.splitter.setSizes(sz) dic_grid = self.db_games.read_config("dic_grid") @@ -141,11 +141,14 @@ def tabChanged(self, ntab): board = self.infoMove.board board.disable_all() - if ntab in (0, 2): + if ntab == 0: #in (0, 2): self.wgames.actualiza() + elif ntab == 2: + self.wplayer.actualiza() else: self.wsummary.gridActualiza() + def inicializa(self): self.setWindowTitle(self.db_games.label()) self.wgames.setdbGames(self.db_games) diff --git a/bin/Code/Director/TabVisual.py b/bin/Code/Director/TabVisual.py index db564701..6d854159 100644 --- a/bin/Code/Director/TabVisual.py +++ b/bin/Code/Director/TabVisual.py @@ -904,6 +904,7 @@ def file(self): def dbFEN(self): if self._dbFEN is None: self._dbFEN = UtilSQL.DictSQL(self._fichero, tabla="FEN") + self._dbFEN.wrong_pickle(b"Physicalphysical_pos", b"PhysicalPos") return self._dbFEN @property diff --git a/bin/Code/Kibitzers/Kibitzers.py b/bin/Code/Kibitzers/Kibitzers.py index f91875d8..771eaada 100644 --- a/bin/Code/Kibitzers/Kibitzers.py +++ b/bin/Code/Kibitzers/Kibitzers.py @@ -114,22 +114,25 @@ def read_uci_options(self): Engines.Engine.read_uci_options(self) def restore(self, txt): + Util.restore_obj_pickle(self, txt) + ok = True if self.tipo in (KIB_CANDIDATES, KIB_BESTMOVE, KIB_BESTMOVE_ONELINE, KIB_THREATS, KIB_STOCKFISH): - Engines.Engine.restore(self, txt) if not os.path.isfile(self.path_exe): eng = Code.configuration.buscaRival(self.alias) if eng: self.path_exe = eng.path_exe - else: - Util.restore_obj_pickle(self, txt) + else: + ok = False - if self.tipo == KIB_POLYGLOT: + elif self.tipo == KIB_POLYGLOT: if not os.path.isfile(self.path_exe): lbooks = Books.ListBooks() book = lbooks.seek_book(self.key) if book: self.path_exe = book.path - + else: + ok = False + return ok class Kibitzers: def __init__(self): @@ -147,8 +150,8 @@ def read(self): if lista_pk: for txt in lista_pk: kib = Kibitzer() - kib.restore(txt) - lista.append(kib) + if kib.restore(txt): + lista.append(kib) return lista, lastfolder def number(self, huella): diff --git a/bin/Code/MainWindow/MainWindow.py b/bin/Code/MainWindow/MainWindow.py index 2e58684d..8b1aedc1 100644 --- a/bin/Code/MainWindow/MainWindow.py +++ b/bin/Code/MainWindow/MainWindow.py @@ -69,9 +69,9 @@ def __init__(self, manager, owner=None, extparam=None): alt_a.setKey(QtGui.QKeySequence("Alt+a")) alt_a.activated.connect(self.pressed_shortcut_alt_a) - ctrlF10 = QtWidgets.QShortcut(self) - ctrlF10.setKey(QtGui.QKeySequence("Ctrl+0")) - ctrlF10.activated.connect(self.pressed_shortcut_Ctrl0) + ctrl_f10 = QtWidgets.QShortcut(self) + ctrl_f10.setKey(QtGui.QKeySequence("Ctrl+0")) + ctrl_f10.activated.connect(self.pressed_shortcut_Ctrl0) F11 = QtWidgets.QShortcut(self) F11.setKey(QtGui.QKeySequence("F11")) @@ -126,15 +126,15 @@ def quitTrayIcon(self): def pressed_shortcut_F12(self): if not self.trayIcon: - restoreAction = QtWidgets.QAction(Iconos.PGN(), _("Show"), self, triggered=self.restauraTrayIcon) - quitAction = QtWidgets.QAction(Iconos.Terminar(), _("Quit"), self, triggered=self.quitTrayIcon) - trayIconMenu = QtWidgets.QMenu(self) - trayIconMenu.addAction(restoreAction) - trayIconMenu.addSeparator() - trayIconMenu.addAction(quitAction) + restore_action = QtWidgets.QAction(Iconos.PGN(), _("Show"), self, triggered=self.restauraTrayIcon) + quit_action = QtWidgets.QAction(Iconos.Terminar(), _("Quit"), self, triggered=self.quitTrayIcon) + tray_icon_menu = QtWidgets.QMenu(self) + tray_icon_menu.addAction(restore_action) + tray_icon_menu.addSeparator() + tray_icon_menu.addAction(quit_action) self.trayIcon = QtWidgets.QSystemTrayIcon(self) - self.trayIcon.setContextMenu(trayIconMenu) + self.trayIcon.setContextMenu(tray_icon_menu) self.trayIcon.setIcon(Iconos.Aplicacion64()) self.trayIcon.activated.connect(self.activateTrayIcon) self.trayIcon.hide() @@ -188,7 +188,8 @@ def save_width_piece(self): dic["WIDTH_PIEZE_MAIN"] = ct.width_piece() Code.configuration.write_variables("WIDTH_PIEZES", dic) - def restore_width_pieze(self): + @staticmethod + def restore_width_pieze(): dic = Code.configuration.read_variables("WIDTH_PIEZES") return dic.get("WIDTH_PIEZE_MAIN") @@ -489,7 +490,7 @@ def save_video(self, dic_extended=None): if sps is None or sps[1] == 0: dr = self.restore_dicvideo() if key in dr: - dic[key] = dr + dic[key] = dr[key] continue sps = [1, 1] dic["SP_%s" % name] = sps @@ -507,7 +508,10 @@ def xrestore_video(self): self.informacionPGN.parent_width_saved = dic.get("WINFOPARENT_WIDTH") self.informacionPGN.sp_sizes = dic.get("SP_InformacionPGN") if self.informacionPGN.sp_sizes: - self.informacionPGN.splitter.setSizes(self.informacionPGN.sp_sizes) + try: + self.informacionPGN.splitter.setSizes(self.informacionPGN.sp_sizes) + except TypeError: + pass def check_translated_help_mode(self): if not Code.configuration.x_translation_mode: diff --git a/bin/Code/Openings/WindowOpeningLine.py b/bin/Code/Openings/WindowOpeningLine.py index 7d379e32..3661ac6e 100644 --- a/bin/Code/Openings/WindowOpeningLine.py +++ b/bin/Code/Openings/WindowOpeningLine.py @@ -794,7 +794,7 @@ def import_polyglot(self, game): def import_pgn(self, game): dic_vars = self.read_config_vars() - carpeta = dic_vars.get("CARPETAPGN", "") + carpeta = dic_vars.get("CARPETAPGN", self.configuration.carpeta) li_path_pgn = SelectFiles.leeFicheros(self, carpeta, "pgn", titulo=_("File to import")) if not li_path_pgn: @@ -812,7 +812,7 @@ def import_pgn(self, game): def ta_import_pgn_comments(self): dic_var = self.read_config_vars() - carpeta = dic_var.get("CARPETAPGN", "") + carpeta = dic_var.get("CARPETAPGN", self.configuration.carpeta) fichero_pgn = SelectFiles.leeFichero(self, carpeta, "pgn", titulo=_("File to import")) if not fichero_pgn: diff --git a/bin/Code/PlayAgainstEngine/ManagerPlayAgainstEngine.py b/bin/Code/PlayAgainstEngine/ManagerPlayAgainstEngine.py index c8184b13..a3955432 100644 --- a/bin/Code/PlayAgainstEngine/ManagerPlayAgainstEngine.py +++ b/bin/Code/PlayAgainstEngine/ManagerPlayAgainstEngine.py @@ -863,7 +863,10 @@ def set_summary(self, key, value): def is_mandatory_move(self): if self.opening_mandatory: - return True + if len(self.opening_mandatory.dicFEN) <= len(self.game): + self.opening_mandatory = None + else: + return True # OPENING LINE-------------------------------------------------------------------------------------------------- if self.opening_line: diff --git a/bin/Code/Procesador.py b/bin/Code/Procesador.py index 007604fd..e709c888 100644 --- a/bin/Code/Procesador.py +++ b/bin/Code/Procesador.py @@ -931,8 +931,9 @@ def database(self, accion, dbpath, is_temporary=False): Code.startfile(self.configuration.folder_databases()) return + path_pgn = None if accion == "N": - dbpath = WDB_Games.new_database(self.main_window, self.configuration) + dbpath, path_pgn = WDB_Games.new_database(self.main_window, self.configuration, with_import_pgn=True) if dbpath is None: return accion = "R" @@ -951,6 +952,9 @@ def database(self, accion, dbpath, is_temporary=False): w = WindowDatabase.WBDatabase(self.main_window, self, dbpath, is_temporary, False) if self.main_window: with QTUtil.EscondeWindow(self.main_window): + if path_pgn: + w.show() + w.wgames.tw_importar_pgn(path_pgn) if w.exec_(): if w.reiniciar: self.database("R", self.configuration.get_last_database()) diff --git a/bin/Code/QT/Iconos.py b/bin/Code/QT/Iconos.py index 81d9081a..7e9ad7b9 100644 --- a/bin/Code/QT/Iconos.py +++ b/bin/Code/QT/Iconos.py @@ -3212,3 +3212,9 @@ def pmForest(): def Forest(): return iget("Forest") + +def pmAnalisis(): + return iget("pmAnalisis") + +def Analisis(): + return iget("Analisis") diff --git a/bin/Code/QT/LCDialog.py b/bin/Code/QT/LCDialog.py index 9888c706..20cda778 100644 --- a/bin/Code/QT/LCDialog.py +++ b/bin/Code/QT/LCDialog.py @@ -47,7 +47,7 @@ def save_video(self, dic_extended=None): def restore_dicvideo(self): return Code.configuration.restore_video(self.key_video) - def restore_video(self, siTam=True, anchoDefecto=None, altoDefecto=None, dicDef=None, shrink=False): + def restore_video(self, siTam=True, siAncho=True, anchoDefecto=None, altoDefecto=None, dicDef=None, shrink=False): dic = self.restore_dicvideo() if not dic: dic = dicDef @@ -75,14 +75,20 @@ def restore_video(self, siTam=True, anchoDefecto=None, altoDefecto=None, dicDef= h = hE - 40 elif h < 20: h = 20 - self.resize(w, h) + if siAncho: + self.resize(w, h) + else: + self.resize(self.width(), h) for grid in self.liGrids: grid.restore_video(dic) grid.releerColumnas() - for sp, name in self.liSplitters: - k = "SP_%s" % name - if k in dic: - sp.setSizes(dic[k]) + try: + for sp, name in self.liSplitters: + k = "SP_%s" % name + if k in dic: + sp.setSizes(dic[k]) + except TypeError: + pass if shrink: QTUtil.shrink(self) if "_POSICION_" in dic: diff --git a/bin/Code/QT/WindowSavePGN.py b/bin/Code/QT/WindowSavePGN.py index 1cfa6a32..023460f2 100644 --- a/bin/Code/QT/WindowSavePGN.py +++ b/bin/Code/QT/WindowSavePGN.py @@ -69,7 +69,8 @@ def file_select(self): last_dir = os.path.dirname(self.history_list[0]) if not os.path.isdir(last_dir): last_dir = "" - + if not last_dir: + last_dir = self.configuration.carpeta fich = SelectFiles.leeCreaFichero(self, last_dir, "pgn") if fich: if not fich.lower().endswith(".pgn"): diff --git a/bin/Code/SQL/UtilSQL.py b/bin/Code/SQL/UtilSQL.py index 8776abf5..ec243ddb 100644 --- a/bin/Code/SQL/UtilSQL.py +++ b/bin/Code/SQL/UtilSQL.py @@ -26,6 +26,8 @@ def __init__(self, path_db, tabla="Data", max_cache=2048): self.normal_save_mode = True self.pending_commit = False + self.li_breplaces_pickle = [] + def reset(self): cursor = self.conexion.execute("SELECT KEY FROM %s" % self.tabla) self.li_keys = [reg[0] for reg in cursor.fetchall()] @@ -67,6 +69,9 @@ def __setitem__(self, key, obj): elif not self.pending_commit: self.pending_commit = True + def wrong_pickle(self, bwrong, bcorrect): + self.li_breplaces_pickle.append((bwrong, bcorrect)) + def __getitem__(self, key): if key in self.li_keys: if key in self.cache: @@ -74,7 +79,17 @@ def __getitem__(self, key): sql = "SELECT VALUE FROM %s WHERE KEY= ?" % self.tabla row = self.conexion.execute(sql, (key,)).fetchone() - obj = pickle.loads(row[0]) + try: + obj = pickle.loads(row[0]) + except AttributeError: + if self.li_breplaces_pickle: + btxt = row[0] + for btxt_wrong, btxt_correct in self.li_breplaces_pickle: + btxt = btxt.replace(btxt_wrong, btxt_correct) + obj = pickle.loads(btxt) + self.__setitem__(key, obj) + else: + obj = None self.add_cache(key, obj) return obj diff --git a/bin/Code/Tournaments/WTournamentRun.py b/bin/Code/Tournaments/WTournamentRun.py index d82b8c5f..cf251587 100644 --- a/bin/Code/Tournaments/WTournamentRun.py +++ b/bin/Code/Tournaments/WTournamentRun.py @@ -789,7 +789,7 @@ def test_is_finished(self): return False - def move_the_pieces(self, liMovs): + def move_the_pieces(self, li_movs): if self.slow_pieces: rapidez = self.configuration.pieces_speed_porc() @@ -798,7 +798,7 @@ def move_the_pieces(self, liMovs): seconds = None # primero los movimientos - for movim in liMovs: + for movim in li_movs: if movim[0] == "m": if seconds is None: from_sq, to_sq = movim[1], movim[2] @@ -813,20 +813,20 @@ def move_the_pieces(self, liMovs): seconds = 1.0 # segundo los borrados - for movim in liMovs: + for movim in li_movs: if movim[0] == "b": n = cpu.duerme(seconds * 0.80 / rapidez) cpu.borraPieza(movim[1], padre=n) # tercero los cambios - for movim in liMovs: + for movim in li_movs: if movim[0] == "c": cpu.cambiaPieza(movim[1], movim[2], siExclusiva=True) cpu.runLineal() else: - for movim in liMovs: + for movim in li_movs: if movim[0] == "b": self.board.borraPieza(movim[1]) elif movim[0] == "m": diff --git a/bin/Code/Tutor/Tutor.py b/bin/Code/Tutor/Tutor.py index 1be70911..e3807936 100644 --- a/bin/Code/Tutor/Tutor.py +++ b/bin/Code/Tutor/Tutor.py @@ -81,7 +81,7 @@ def elegir(self, has_hints, li_ap_posibles=None): self.gameUsuario.li_moves[0].pgn_html_base(Code.configuration.x_pgn_withfigurines) + \ " " + self.rmUsuario.texto() - w.ponPuntuacionUsuario(message) + w.set_score_user(message) if si_rival: self.rm_rival.change_side() @@ -103,7 +103,7 @@ def elegir(self, has_hints, li_ap_posibles=None): message = _("Opponent's prediction") + "

" + \ self.gameRival.li_moves[0].pgn_html_base(Code.configuration.x_pgn_withfigurines) + \ " " + self.rm_rival.texto_rival() - w.ponPuntuacionRival(message) + w.set_score_rival(message) self.moving_tutor(True) self.moving_user(True) @@ -140,10 +140,17 @@ def ponVariations(self, move, movenum): game_usuario = Game.Game(self.move.position_before) game_usuario.read_pv(self.rmUsuario.get_pv()) - txt = game_usuario.pgn_translated() - puntos = self.rmUsuario.texto() - vusu = "%s : %s" % (puntos, txt) - move.set_comment(vusu.replace("\n", "")) + + jgvar = game_usuario.move(0) + jgvar.set_comment(self.rmUsuario.texto()) + + move.add_variation(game_usuario) + # + # + # txt = game_usuario.pgn_translated() + # puntos = self.rmUsuario.texto() + # vusu = "%s : %s" % (puntos, txt) + # move.set_comment(vusu.replace("\n", "")) def do_lirm(self, posUsuario): li = [] @@ -171,7 +178,7 @@ def cambiadoRM(self, pos): self.game_tutor.li_moves[0].pgn_html_base(Code.configuration.x_pgn_withfigurines) + \ " " + rm.texto() - self.w.ponPuntuacionTutor(message) + self.w.set_score_tutor(message) self.pos_tutor = 0 self.max_tutor = len(self.game_tutor) diff --git a/bin/Code/Tutor/WindowTutor.py b/bin/Code/Tutor/WindowTutor.py index 4b09d46f..8a1c65c8 100644 --- a/bin/Code/Tutor/WindowTutor.py +++ b/bin/Code/Tutor/WindowTutor.py @@ -19,7 +19,7 @@ class WindowTutor(LCDialog.LCDialog): - def __init__(self, manager, tutor, siRival, siOpenings, is_white, has_hints): + def __init__(self, manager, tutor, with_rival, with_openings, is_white, has_hints): titulo = _("Tutor") icono = Iconos.Tutor() extparam = "tutor" @@ -29,6 +29,7 @@ def __init__(self, manager, tutor, siRival, siOpenings, is_white, has_hints): self.manager = manager self.respLibro = None self.siElegidaOpening = False + self.timer = None self.x_tutor_view = manager.configuration.x_tutor_view @@ -41,40 +42,45 @@ def __init__(self, manager, tutor, siRival, siOpenings, is_white, has_hints): # Boards - def create_board(name, si=True, siLibre=True, siMas=False): + def create_board(name, si=True, si_libre=True, si_mas=False): if not si: return None, None, None board = Board.Board(self, config_board) board.crea() board.set_side_bottom(is_white) - lytb, tb = QTVarios.ly_mini_buttons(self, name, siLibre, siMas=siMas) + lytb, tb = QTVarios.ly_mini_buttons(self, name, si_libre, siMas=si_mas) return board, lytb, tb self.boardTutor, lytbtutor, self.tbtutor = create_board("tutor") self.boardUsuario, lytbuser, self.tbuser = create_board("user") - self.boardRival, lytbRival, self.tbRival = create_board("rival", siRival) - self.boardOpening, lytbOpening, self.tbOpening = create_board("opening", siOpenings, siLibre=False) + self.boardRival, lytbRival, self.tbRival = create_board("rival", with_rival) + self.boardOpening, lytbOpening, self.tbOpening = create_board("opening", with_openings, si_libre=False) tutor.ponBoardsGUI(self.boardTutor, self.boardUsuario, self.boardRival, self.boardOpening) + tb_analisis = Controles.TBrutina(self, icon_size=16, with_text=False) + tb_analisis.new("", Iconos.Analisis(), self.launch_analysis, tool_tip=_("Analysis")) + lytbtutor = Colocacion.H().relleno().otro(lytbtutor).relleno().control(tb_analisis) + # Puntuaciones self.lb_tutor = Controles.LB(self).set_font(f).align_center() self.lb_tutor.setFixedWidth(self.boardTutor.ancho) manager.configuration.set_property(self.lb_tutor, "tutor-tutor" if has_hints else "tutor-tutor-disabled") if has_hints: - self.lb_tutor.mousePressEvent = self.elegirTutor + self.lb_tutor.mousePressEvent = self.select_tutor self.lb_player = Controles.LB(self).set_font(f).align_center() self.lb_player.setFixedWidth(self.boardUsuario.ancho) - self.lb_player.mousePressEvent = self.elegirUsuario + self.lb_player.mousePressEvent = self.select_user manager.configuration.set_property(self.lb_player, "tutor-player" if has_hints else "tutor-tutor") - if siRival: + if with_rival: self.lb_rival = Controles.LB(self).set_font(f).align_center() self.lb_rival.setFixedWidth(self.boardRival.ancho) manager.configuration.set_property(self.lb_rival, "tutor-tutor-disabled") # Openings - if siOpenings: + ly_openings = None + if with_openings: li_options = self.tutor.opcionesOpenings() self.cbOpenings = Controles.CB(self, li_options, 0) self.cbOpenings.setFont(flba) @@ -85,7 +91,7 @@ def create_board(name, si=True, siLibre=True, siMas=False): lb_openings.setFixedWidth(self.boardOpening.ancho) manager.configuration.set_property(lb_openings, "tutor-tutor" if has_hints else "tutor-tutor-disabled") if has_hints: - lb_openings.mousePressEvent = self.elegirOpening + lb_openings.mousePressEvent = self.select_opening ly_openings = Colocacion.V().control(lb_openings).control(self.cbOpenings) self.tutor.cambiarOpening(0) @@ -96,11 +102,10 @@ def create_board(name, si=True, siLibre=True, siMas=False): self.cbRM, self.lbRM = QTUtil2.combobox_lb(self, li_rm, li_rm[0][1], _("Moves analyzed")) self.cbRM.capture_changes(tutor.cambiadoRM) - bt_eye = Controles.PB(self, "", self.launch_analysis).ponIcono(Iconos.Eye()) - ly_rm = Colocacion.H().control(self.lbRM).control(self.cbRM).control(bt_eye).relleno(1) + ly_rm = Colocacion.H().control(self.lbRM).control(self.cbRM).relleno(1) - btLibros = Controles.PB(self, " %s " % _("Consult a book"), self.consultaLibro).ponPlano(False) + bt_libros = Controles.PB(self, " %s " % _("Consult a book"), self.consult_book).ponPlano(False) dic_vista = { POS_TUTOR_HORIZONTAL: ((0, 1), (0, 2)), @@ -118,11 +123,11 @@ def create_board(name, si=True, siLibre=True, siMas=False): layout.controlc(self.lb_tutor, 0, 0).controlc(self.boardTutor, 1, 0).otro(lytbtutor, 2, 0).otroc(ly_rm, 3, 0) layout.controlc(self.lb_player, fu, cu).controlc(self.boardUsuario, fu + 1, cu).otro(lytbuser, fu + 2, cu).controlc( - btLibros, fu + 3, cu + bt_libros, fu + 3, cu ) - if siRival: + if with_rival: layout.controlc(self.lb_rival, fr, cr).controlc(self.boardRival, fr + 1, cr).otro(lytbRival, fr + 2, cr) - elif siOpenings: + elif with_openings: layout.otroc(ly_openings, fr, cr).controlc(self.boardOpening, fr + 1, cr).otro(lytbOpening, fr + 2, cr) layout.margen(8) @@ -143,61 +148,54 @@ def toolbar_rightmouse(self): QTVarios.change_interval(self, Code.configuration) def process_toolbar(self): - self.exeTB(self.sender().key) + self.run_toolbar(self.sender().key) - def exeTB(self, accion): + def run_toolbar(self, accion): x = accion.index("Mover") quien = accion[:x] que = accion[x + 5:] self.tutor.mueve(quien, que) - # def cambioBoard(self): - # self.boardUsuario.crea() - # if self.boardRival: - # self.boardRival.crea() - # if self.boardOpening: - # self.boardOpening.crea() - def board_wheel_event(self, board, forward): forward = Code.configuration.wheel_board(forward) for t in ["Tutor", "Usuario", "Rival", "Opening"]: if eval("self.board%s == board" % t): - self.exeTB(t.lower() + "Mover" + ("Adelante" if forward else "Atras")) + self.run_toolbar(t.lower() + "Mover" + ("Adelante" if forward else "Atras")) return - def consultaLibro(self): - liMovs = self.manager.librosConsulta(True) - if liMovs: - self.respLibro = liMovs[-1] + def consult_book(self): + li_movs = self.manager.librosConsulta(True) + if li_movs: + self.respLibro = li_movs[-1] self.save_video() self.accept() - def elegirTutor(self, ev): + def select_tutor(self, ev): self.save_video() self.accept() - def elegirOpening(self, ev): + def select_opening(self, ev): self.siElegidaOpening = True self.save_video() self.accept() - def elegirUsuario(self, ev): + def select_user(self, ev): self.save_video() self.reject() - def ponPuntuacionUsuario(self, txt): + def set_score_user(self, txt): self.lb_player.setText(txt) - def ponPuntuacionTutor(self, txt): + def set_score_tutor(self, txt): self.lb_tutor.setText(txt) - def ponPuntuacionRival(self, txt): + def set_score_rival(self, txt): self.lb_rival.setText(txt) def start_clock(self, funcion): if not hasattr(self, "timer"): self.timer = QtCore.QTimer(self) - self.connect(self.timer, QtCore.SIGNAL("timeout()"), funcion) + self.timer.timeout.connect(funcion) self.timer.start(Code.configuration.x_interval_replay) def stop_clock(self): diff --git a/bin/Code/__init__.py b/bin/Code/__init__.py index aa67e888..3afd6b57 100644 --- a/bin/Code/__init__.py +++ b/bin/Code/__init__.py @@ -99,7 +99,7 @@ def relative_root(path): BASE_VERSION = "B" # Para el control de updates que necesitan reinstalar entero -VERSION = "R 2.16" +VERSION = "R 2.16a" DEBUG = False DEBUG_ENGINES = False diff --git a/bin/_genicons/Formatos.tema b/bin/_genicons/Formatos.tema index 4cbdd33b..c3a7595f 100644 --- a/bin/_genicons/Formatos.tema +++ b/bin/_genicons/Formatos.tema @@ -764,3 +764,5 @@ Advice windows8 icons8-idea-32.png PauseBlue windows8 Sleep_Mode.png Forest windows8 icons8-bosque-32.png + +Analisis windows8 icons8-analysis-16.png diff --git a/bin/_genicons/dark.png b/bin/_genicons/dark.png index e7c6d786..4578f384 100644 Binary files a/bin/_genicons/dark.png and b/bin/_genicons/dark.png differ diff --git a/bin/_genicons/sepia.png b/bin/_genicons/sepia.png index 6ee1e6b9..12cfa002 100644 Binary files a/bin/_genicons/sepia.png and b/bin/_genicons/sepia.png differ diff --git a/bin/_genicons/windows8/icons8-analysis-16.png b/bin/_genicons/windows8/icons8-analysis-16.png new file mode 100644 index 00000000..ff3c7b88 Binary files /dev/null and b/bin/_genicons/windows8/icons8-analysis-16.png differ diff --git a/bin/bug.log b/bin/bug.log index b721e802..d72dc3c4 100644 --- a/bin/bug.log +++ b/bin/bug.log @@ -1 +1 @@ -Version R 2.16 +Version R 2.16a