diff --git a/LunaTranslator/LunaTranslator/LunaTranslator.py b/LunaTranslator/LunaTranslator/LunaTranslator.py index 63676d28..c2e1db62 100644 --- a/LunaTranslator/LunaTranslator/LunaTranslator.py +++ b/LunaTranslator/LunaTranslator/LunaTranslator.py @@ -425,9 +425,7 @@ class MAINUI: try: time.sleep(globalconfig["textthreaddelay"] / 1000) name = self.textsource.currentname - names = savehook_new_data[self.textsource.pname][ - "allow_tts_auto_names" - ].split("|") + names = savehook_new_data[self.textsource.pname]["allow_tts_auto_names_v4"] needpass = False if name in names: needpass = True @@ -759,10 +757,24 @@ class MAINUI: self.mainuiloadafter() def checkgameplayingthread(self): + self.tracestarted = False while True: statistictime = time.time() time.sleep(1) + def isok(name_): + now = time.time() + if self.tracestarted == False: + self.tracestarted = True + savehook_new_data[name_]["traceplaytime_v2"].append( + [statistictime, statistictime] + ) + savehook_new_data[name_]["statistic_playtime"] += now - statistictime + savehook_new_data[name_]["traceplaytime_v2"][-1][1] = now + + def isbad(): + self.tracestarted = False + try: _hwnd = windows.GetForegroundWindow() _pid = windows.GetWindowThreadProcessId(_hwnd) @@ -773,17 +785,17 @@ class MAINUI: ): try: if _pid in self.textsource.pids: - savehook_new_data[self.textsource.pname][ - "statistic_playtime" - ] += (time.time() - statistictime) + isok(self.textsource.pname) + else: + isbad() except: pass else: name_ = getpidexe(_pid) if name_ and name_ in savehook_new_list: - savehook_new_data[name_]["statistic_playtime"] += ( - time.time() - statistictime - ) + isok(name_) + else: + isbad() except: print_exc() diff --git a/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py b/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py index 04f882c4..a7c5001a 100644 --- a/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py +++ b/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py @@ -1,4 +1,6 @@ import functools, time, qtawesome +from datetime import datetime, timedelta +from gui.specialwidget import ScrollFlow, chartwidget from PyQt5.QtWidgets import ( QPushButton, QDialog, @@ -15,17 +17,13 @@ from PyQt5.QtWidgets import ( QTableView, QAbstractItemView, QLabel, - QVBoxLayout, - QSpacerItem, QTabWidget, ) import windows -from PyQt5.QtCore import QPoint, QRect, QSize, Qt, pyqtSignal +from PyQt5.QtCore import QRect, QSize, Qt, pyqtSignal import os, hashlib -from PyQt5 import QtWidgets from PyQt5.QtWidgets import ( QApplication, - QLayout, QSizePolicy, QWidget, QMenu, @@ -35,12 +33,10 @@ from PyQt5.QtWidgets import ( from PyQt5.QtGui import ( QCloseEvent, QIntValidator, - QPaintEvent, QResizeEvent, QPixmap, QPainter, QPen, - QColor, ) from PyQt5.QtCore import Qt from gui.usefulwidget import ( @@ -51,7 +47,7 @@ from gui.usefulwidget import ( getspinbox, selectcolor, ) -from PyQt5.QtCore import QPoint, QRect, QSize, Qt, pyqtSignal +from PyQt5.QtCore import QRect, QSize, Qt, pyqtSignal import os from myutils.hwnd import showintab from PyQt5.QtGui import QStandardItem, QStandardItemModel @@ -218,134 +214,6 @@ class IMGWidget(QLabel): self.setimg(pixmap) -class ScrollFlow(QWidget): - def resizeEvent(self, a0) -> None: - self.qscrollarea.resize(self.size()) - return super().resizeEvent(a0) - - def __init__(self): - super(ScrollFlow, self).__init__() - - self.listWidget = QtWidgets.QListWidget(self) - # self.listWidget.setFixedWidth(600) - - self.l = FlowLayout() - - self.listWidget.setLayout(self.l) - - self.qscrollarea = QtWidgets.QScrollArea(self) - self.qscrollarea.setWidgetResizable(True) - self.qscrollarea.setWidget(self.listWidget) - - def addwidget(self, wid): - self.l.addWidget(wid) - - def removeidx(self, index): - _ = self.l.takeAt(index) - _.widget().hide() - - -class FlowLayout(QLayout): - heightChanged = pyqtSignal(int) - - def __init__(self, parent=None, margin=0, spacing=-1): - super().__init__(parent) - if parent is not None: - self.setContentsMargins(margin, margin, margin, margin) - self.setSpacing(spacing) - - self._item_list = [] - - def __del__(self): - while self.count(): - self.takeAt(0) - - def addItem(self, item): # pylint: disable=invalid-name - self._item_list.append(item) - - def addSpacing(self, size): # pylint: disable=invalid-name - self.addItem(QSpacerItem(size, 0, QSizePolicy.Fixed, QSizePolicy.Minimum)) - - def count(self): - return len(self._item_list) - - def itemAt(self, index): # pylint: disable=invalid-name - if 0 <= index < len(self._item_list): - return self._item_list[index] - return None - - def takeAt(self, index): # pylint: disable=invalid-name - if 0 <= index < len(self._item_list): - return self._item_list.pop(index) - return None - - def expandingDirections(self): # pylint: disable=invalid-name,no-self-use - return Qt.Orientations(Qt.Orientation(0)) - - def hasHeightForWidth(self): # pylint: disable=invalid-name,no-self-use - return True - - def heightForWidth(self, width): # pylint: disable=invalid-name - height = self._do_layout(QRect(0, 0, width, 0), True) - return height - - def setGeometry(self, rect): # pylint: disable=invalid-name - super().setGeometry(rect) - self._do_layout(rect, False) - - def sizeHint(self): # pylint: disable=invalid-name - return self.minimumSize() - - def minimumSize(self): # pylint: disable=invalid-name - size = QSize() - - for item in self._item_list: - minsize = item.minimumSize() - extent = item.geometry().bottomRight() - size = size.expandedTo(QSize(minsize.width(), extent.y())) - - margin = self.contentsMargins().left() - size += QSize(2 * margin, 2 * margin) - return size - - def _do_layout(self, rect, test_only=False): - m = self.contentsMargins() - effective_rect = rect.adjusted(+m.left(), +m.top(), -m.right(), -m.bottom()) - x = effective_rect.x() - y = effective_rect.y() - line_height = 0 - - for item in self._item_list: - wid = item.widget() - - space_x = self.spacing() - space_y = self.spacing() - if wid is not None: - space_x += wid.style().layoutSpacing( - QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Horizontal - ) - space_y += wid.style().layoutSpacing( - QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Vertical - ) - - next_x = x + item.sizeHint().width() + space_x - if next_x - space_x > effective_rect.right() and line_height > 0: - x = effective_rect.x() - y = y + line_height + space_y - next_x = x + item.sizeHint().width() + space_x - line_height = 0 - - if not test_only: - item.setGeometry(QRect(QPoint(x, y), item.sizeHint())) - - x = next_x - line_height = max(line_height, item.sizeHint().height()) - - new_height = y + line_height - rect.y() - self.heightChanged.emit(new_height) - return new_height - - def opendir(k): try: os.startfile(os.path.dirname(k)) @@ -574,15 +442,47 @@ class dialog_setting_game(QDialog): self.editpath.setText(res) self.exepath = res + def closeEvent(self, a0: QCloseEvent) -> None: + self.isopened = False + return super().closeEvent(a0) + def __init__(self, parent, exepath, item=None, gametitleitme=None) -> None: super().__init__(parent, Qt.WindowCloseButtonHint) + self.isopened = True checkifnewgame(exepath) - formLayout = QVBoxLayout(self) # 配置layout - + vbox = QVBoxLayout(self) # 配置layout + self.setLayout(vbox) + formwidget = QWidget() + formLayout = QFormLayout() + formwidget.setLayout(formLayout) self.item = item self.exepath = exepath self.gametitleitme = gametitleitme - + editpath = QLineEdit(exepath) + editpath.setReadOnly(True) + if item: + self.table = parent.table + self.model = parent.model + editpath.textEdited.connect(lambda _: item.__setitem__("savetext", _)) + self.editpath = editpath + self.setWindowTitle(savehook_new_data[exepath]["title"]) + self.resize(QSize(600, 200)) + self.setWindowIcon(getExeIcon(exepath, cache=True)) + formLayout.addRow( + _TR("路径"), + getboxlayout( + [ + editpath, + getcolorbutton( + "", + "", + functools.partial(self.selectexe), + icon="fa.gear", + constcolor="#FF69B4", + ), + ] + ), + ) titleedit = QLineEdit(savehook_new_data[exepath]["title"]) def _titlechange(x): @@ -593,7 +493,7 @@ class dialog_setting_game(QDialog): gametitleitme.settitle(x) titleedit.textChanged.connect(_titlechange) - formLayout.addLayout(getboxlayout([QLabel(_TR("标题")), titleedit])) + formLayout.addRow(_TR("标题"), titleedit) imgpath = QLineEdit(savehook_new_data[exepath]["imagepath"]) imgpath.setReadOnly(True) @@ -612,77 +512,66 @@ class dialog_setting_game(QDialog): imgpath.setText(res) gametitleitme.setimg(_pixmap) - formLayout.addLayout( - getboxlayout( - [ - QLabel(_TR("封面")), - imgpath, - getcolorbutton( - "", "", selectimg, icon="fa.gear", constcolor="#FF69B4" - ), - ] - ) - ) - vndbid = QLineEdit(str(savehook_new_data[exepath]["vid"])) vndbid.setValidator(QIntValidator()) vndbid.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) vndbid.textEdited.connect(functools.partial(vidchangedtask, exepath)) - statiswids = [ - QLabel(_TR("统计信息")), - getcolorbutton( - "", - "", - lambda: dialog_statistic(self, exepath), - icon="fa.bar-chart", - constcolor="#FF69B4", - ), - QLabel(_TR("vndbid")), - vndbid, - getcolorbutton( - "", - "", - lambda: browserdialog(self, exepath), - icon="fa.book", - constcolor="#FF69B4", - ), - getcolorbutton( - "", - "", - lambda: vidchangedtask(exepath, savehook_new_data[exepath]["vid"]), - icon="fa.refresh", - constcolor="#FF69B4", - ), - ] - formLayout.addLayout(getboxlayout(statiswids)) - editpath = QLineEdit(exepath) - editpath.setReadOnly(True) - if item: - self.table = parent.table - self.model = parent.model - editpath.textEdited.connect(lambda _: item.__setitem__("savetext", _)) - self.editpath = editpath - self.setWindowTitle(savehook_new_data[exepath]["title"]) - self.resize(QSize(600, 200)) - self.setWindowIcon(getExeIcon(exepath, cache=True)) - formLayout.addLayout( + formLayout.addRow( + _TR("封面"), getboxlayout( [ - QLabel(_TR("修改路径")), - editpath, + imgpath, + getcolorbutton( + "", "", selectimg, icon="fa.gear", constcolor="#FF69B4" + ), + ] + ), + ) + formLayout.addRow( + "vndbid", + getboxlayout( + [ + vndbid, getcolorbutton( "", "", - functools.partial(self.selectexe), - icon="fa.gear", + lambda: browserdialog(self, exepath), + icon="fa.book", + constcolor="#FF69B4", + ), + getcolorbutton( + "", + "", + lambda: vidchangedtask( + exepath, savehook_new_data[exepath]["vid"] + ), + icon="fa.refresh", constcolor="#FF69B4", ), ] - ) + ), ) + methodtab = QTabWidget() + methodtab.addTab(self.starttab(exepath), "启动") + methodtab.addTab(self.gethooktab(exepath), "HOOK") + methodtab.addTab(self.getpretranstab(exepath), _TR("预翻译")) + methodtab.addTab(self.getttssetting(exepath), _TR("语音")) + methodtab.addTab(self.getlabelsetting(exepath), _TR("标签")) + methodtab.addTab(self.getstatistic(exepath), _TR("统计信息")) + + vbox.addWidget(formwidget) + vbox.addWidget(methodtab) + + self.show() + + def starttab(self, exepath): + _w = QWidget() + formLayout = QFormLayout() + _w.setLayout(formLayout) + b = windows.GetBinaryType(exepath) if b == 6: @@ -691,17 +580,16 @@ class dialog_setting_game(QDialog): _methods = ["Locale-Emulator", "Locale_Remulator", "Ntleas"] if b == 6 and savehook_new_data[exepath]["localeswitcher"] == 0: savehook_new_data[exepath]["localeswitcher"] = 2 - formLayout.addLayout( + formLayout.addRow( + _TR("转区启动"), getboxlayout( [ - QLabel(_TR("转区启动")), getsimpleswitch(savehook_new_data[exepath], "leuse"), - QLabel(_TR("转区方法")), getsimplecombobox( _TRL(_methods), savehook_new_data[exepath], "localeswitcher" ), - ][(type != 2) * 2 :] - ) + ] + ), ) editcmd = QLineEdit(savehook_new_data[exepath]["startcmd"]) @@ -709,61 +597,140 @@ class dialog_setting_game(QDialog): lambda _: savehook_new_data[exepath].__setitem__("startcmd", _) ) - formLayout.addLayout( + formLayout.addRow( + _TR("命令行启动"), getboxlayout( [ - QLabel(_TR("命令行启动")), getsimpleswitch(savehook_new_data[exepath], "startcmduse"), editcmd, ] - ) + ), ) - formLayout.addLayout( - getboxlayout( - [ - QLabel(_TR("自动切换到模式")), - getsimplecombobox( - _TRL(["不切换", "HOOK", "剪贴板", "OCR"]), - savehook_new_data[exepath], - "onloadautochangemode2", - ), - ] - ) + formLayout.addRow( + _TR("自动切换到模式"), + getsimplecombobox( + _TRL(["不切换", "HOOK", "剪贴板", "OCR"]), + savehook_new_data[exepath], + "onloadautochangemode2", + ), ) - formLayout.addLayout( - getboxlayout( - [ - QLabel(_TR("自动切换源语言")), - getsimplecombobox( - _TRL(["不切换"]) - + _TRL(static_data["language_list_translator"]), - savehook_new_data[exepath], - "onloadautoswitchsrclang", - ), - ] - ) + formLayout.addRow( + _TR("自动切换源语言"), + getsimplecombobox( + _TRL(["不切换"]) + _TRL(static_data["language_list_translator"]), + savehook_new_data[exepath], + "onloadautoswitchsrclang", + ), ) - methodtab = QTabWidget() - methodtab.addTab(self.gethooktab(exepath), "HOOK") - methodtab.addTab(self.getpretranstab(exepath), _TR("预翻译")) - methodtab.addTab(self.getttssetting(exepath), _TR("语音")) - methodtab.addTab(self.getlabelsetting(exepath), _TR("标签")) - formLayout.addWidget(methodtab) + return _w - self.show() + def getstatistic(self, exepath): + _w = QWidget() + formLayout = QVBoxLayout() + + _w.setLayout(formLayout) + formLayout.setContentsMargins(0, 0, 0, 0) + chart = chartwidget() + chart.xtext = lambda x: ( + "0" if x == 0 else str(datetime.fromtimestamp(x)).split(" ")[0] + ) + chart.ytext = lambda y: self.formattime(y, False) + + self.chart = chart + self._timelabel = QLabel() + self._wordlabel = QLabel() + self._wordlabel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) + self._timelabel.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed) + formLayout.addLayout(getboxlayout([QLabel(_TR("文字计数")), self._wordlabel])) + formLayout.addLayout(getboxlayout([QLabel(_TR("游戏时间")), self._timelabel])) + + formLayout.addWidget(chart) + + threading.Thread(target=self.refresh).start() + return _w + + def split_range_into_days(self, times): + everyday = {} + for start, end in times: + if start == 0: + everyday[0] = end + continue + + start_date = datetime.fromtimestamp(start) + end_date = datetime.fromtimestamp(end) + + current_date = start_date + while current_date <= end_date: + end_of_day = current_date.replace( + hour=23, minute=59, second=59, microsecond=0 + ) + end_of_day = end_of_day.timestamp() + 1 + + if end_of_day >= end_date.timestamp(): + useend = end_date.timestamp() + else: + useend = end_of_day + duration = useend - current_date.timestamp() + today = end_of_day - 1 + if today not in everyday: + everyday[today] = 0 + everyday[today] += duration + current_date += timedelta(days=1) + current_date = current_date.replace( + hour=0, minute=0, second=0, microsecond=0 + ) + lists = [] + for k in sorted(everyday.keys()): + lists.append((k, everyday[k])) + return lists + + def refresh(self): + while self.isopened: + self._timelabel.setText( + self.formattime(savehook_new_data[self.exepath]["statistic_playtime"]) + ) + self._wordlabel.setText( + str(savehook_new_data[self.exepath]["statistic_wordcount"]) + ) + self.chart.setdata( + self.split_range_into_days( + savehook_new_data[self.exepath]["traceplaytime_v2"] + ) + ) + time.sleep(1) + + def formattime(self, t, usingnotstart=True): + t = int(t) + s = t % 60 + t = t // 60 + m = t % 60 + t = t // 60 + h = t + string = "" + if h: + string += str(h) + _TR("时") + if m: + string += str(m) + _TR("分") + if s: + string += str(s) + _TR("秒") + if string == "": + if usingnotstart: + string = _TR("未开始") + else: + string = "0" + return string def getlabelsetting(self, exepath): _w = QWidget() formLayout = QVBoxLayout() - # formLayout.setAlignment(Qt.AlignTop) _w.setLayout(formLayout) formLayout.setContentsMargins(0, 0, 0, 0) self.labelflow = ScrollFlow() - def newitem(text, removeable): + def newitem(text, removeable, first=False): qw = tagitem(text, removeable) def __(_qw, t): @@ -779,7 +746,10 @@ class dialog_setting_game(QDialog): self.parent().tagswidget.addTag(t) qw.labelclicked.connect(_lbclick) - self.labelflow.addwidget(qw) + if first: + self.labelflow.insertwidget(0, qw) + else: + self.labelflow.addwidget(qw) for tag in savehook_new_data[exepath]["usertags"]: newitem(tag, True) @@ -794,8 +764,8 @@ class dialog_setting_game(QDialog): def _add(_): tag = globalconfig["labelset"][_dict["new"]] if tag not in savehook_new_data[exepath]["usertags"]: - savehook_new_data[exepath]["usertags"].append(tag) - newitem(tag, True) + savehook_new_data[exepath]["usertags"].insert(0, tag) + newitem(tag, True, True) button.clicked.connect(_add) @@ -815,12 +785,29 @@ class dialog_setting_game(QDialog): formLayout.setAlignment(Qt.AlignTop) _w.setLayout(formLayout) - edit = QLineEdit(savehook_new_data[exepath]["allow_tts_auto_names"]) - edit.textChanged.connect( - lambda x: savehook_new_data[exepath].__setitem__("allow_tts_auto_names", x) - ) formLayout.addLayout( - getboxlayout([QLabel(_TR("禁止自动朗读的人名(以|分隔多个)")), edit]) + getboxlayout( + [ + QLabel(_TR("禁止自动朗读的人名")), + getcolorbutton( + "", + "", + lambda _: listediter( + self, + _TR("禁止自动朗读的人名"), + _TRL( + [ + "删除", + "人名", + ] + ), + savehook_new_data[exepath]["allow_tts_auto_names_v4"], + ), + icon="fa.gear", + constcolor="#FF69B4", + ), + ] + ) ) formLayout.addLayout( getboxlayout( @@ -847,8 +834,7 @@ class dialog_setting_game(QDialog): def getpretranstab(self, exepath): _w = QWidget() - formLayout = QVBoxLayout() - formLayout.setAlignment(Qt.AlignTop) + formLayout = QFormLayout() _w.setLayout(formLayout) def selectimg(key, filter1, le): @@ -868,10 +854,10 @@ class dialog_setting_game(QDialog): editjson = QLineEdit(exepath) editjson.setReadOnly(True) editjson.setText(savehook_new_data[exepath][key]) - formLayout.addLayout( + formLayout.addRow( + _TR(showname), getboxlayout( [ - QLabel(_TR(showname)), editjson, getcolorbutton( "", @@ -881,35 +867,27 @@ class dialog_setting_game(QDialog): constcolor="#FF69B4", ), ] - ) + ), ) return _w def gethooktab(self, exepath): _w = QWidget() - formLayout = QVBoxLayout() + formLayout = QFormLayout() _w.setLayout(formLayout) - formLayout.addLayout( - getboxlayout( - [ - QLabel(_TR("代码页")), - getsimplecombobox( - _TRL(static_data["codepage_display"]), - savehook_new_data[exepath], - "codepage_index", - lambda x: gobject.baseobject.textsource.setsettings(), - ), - ] - ) + formLayout.addRow( + _TR("代码页"), + getsimplecombobox( + _TRL(static_data["codepage_display"]), + savehook_new_data[exepath], + "codepage_index", + lambda x: gobject.baseobject.textsource.setsettings(), + ), ) - formLayout.addLayout( - getboxlayout( - [ - QLabel(_TR("移除非选定hook")), - getsimpleswitch(savehook_new_data[exepath], "removeuseless"), - ] - ) + formLayout.addRow( + _TR("移除非选定hook"), + getsimpleswitch(savehook_new_data[exepath], "removeuseless"), ) model = QStandardItemModel() @@ -937,31 +915,19 @@ class dialog_setting_game(QDialog): for row, k in enumerate(savehook_new_data[exepath]["needinserthookcode"]): # 2 self.newline(row, k) - formLayout.addWidget(self.hctable) + formLayout.addRow(self.hctable) - formLayout.addLayout( - getboxlayout( - [ - QLabel(_TR("插入特殊码延迟(ms)")), - getspinbox( - 0, 1000000, savehook_new_data[exepath], "inserthooktimeout" - ), - ] - ) + formLayout.addRow( + _TR("插入特殊码延迟(ms)"), + getspinbox(0, 1000000, savehook_new_data[exepath], "inserthooktimeout"), ) if ( savehook_new_data[exepath]["use_saved_text_process"] or "save_text_process_info" in savehook_new_data[exepath] ): - formLayout.addLayout( - getboxlayout( - [ - QLabel(_TR("使用保存的文本处理流程")), - getsimpleswitch( - savehook_new_data[exepath], "use_saved_text_process" - ), - ] - ) + formLayout.addRow( + _TR("使用保存的文本处理流程"), + getsimpleswitch(savehook_new_data[exepath], "use_saved_text_process"), ) return _w @@ -1042,57 +1008,6 @@ class dialog_syssetting(QDialog): self.show() -@Singleton -class dialog_statistic(QDialog): - def formattime(self, t): - t = int(t) - s = t % 60 - t = t // 60 - m = t % 60 - t = t // 60 - h = t - string = "" - if h: - string += str(h) + _TR("时") - if m: - string += str(m) + _TR("分") - if s: - string += str(s) + _TR("秒") - if string == "": - string = _TR("未开始") - return string - - refreshsignal = pyqtSignal() - - def refresh(self): - while self.isVisible(): - time.sleep(1) - self._timelabel.setText( - self.formattime(savehook_new_data[self.exepath]["statistic_playtime"]) - ) - self._wordlabel.setText( - str(savehook_new_data[self.exepath]["statistic_wordcount"]) - ) - - def __init__(self, parent, exepath) -> None: - super().__init__(parent, Qt.WindowCloseButtonHint) - checkifnewgame(exepath) - self.exepath = exepath - self.setWindowTitle(_TR("统计信息")) - # self.resize(QSize(800,400)) - formlayout = QFormLayout() - self._timelabel = QLabel( - self.formattime(savehook_new_data[exepath]["statistic_playtime"]) - ) - formlayout.addRow(_TR("游戏时间"), self._timelabel) - self._wordlabel = QLabel(str(savehook_new_data[exepath]["statistic_wordcount"])) - formlayout.addRow(_TR("文字计数"), self._wordlabel) - self.setLayout(formlayout) - self.refreshsignal.connect(self.refresh) - self.show() - threading.Thread(target=self.refresh).start() - - @threader def startgame(game): try: @@ -1178,20 +1093,14 @@ def startgame(game): @Singleton_close -class labelsetedit(QDialog): - def __init__(self, p) -> None: +class listediter(QDialog): + def __init__(self, p, title, headers, lst) -> None: super().__init__(p) + self.lst = lst try: - self.setWindowTitle(_TR("标签集")) + self.setWindowTitle(title) model = QStandardItemModel() - model.setHorizontalHeaderLabels( - _TRL( - [ - "删除", - "标签", - ] - ) - ) + model.setHorizontalHeaderLabels(headers) self.hcmodel = model table = QTableView() @@ -1204,7 +1113,7 @@ class labelsetedit(QDialog): table.setModel(model) self.hctable = table - for row, k in enumerate(globalconfig["labelset"]): # 2 + for row, k in enumerate(lst): # 2 self.newline(row, k) formLayout = QVBoxLayout() formLayout.addWidget(self.hctable) @@ -1218,7 +1127,7 @@ class labelsetedit(QDialog): def clicked2(self): try: - globalconfig["labelset"].pop(self.hctable.currentIndex().row()) + self.lst.pop(self.hctable.currentIndex().row()) self.hcmodel.removeRow(self.hctable.currentIndex().row()) except: pass @@ -1227,13 +1136,13 @@ class labelsetedit(QDialog): rows = self.hcmodel.rowCount() rowoffset = 0 dedump = set() - globalconfig["labelset"].clear() + self.lst.clear() for row in range(rows): k = self.hcmodel.item(row, 1).text() if k == "" or k in dedump: rowoffset += 1 continue - globalconfig["labelset"].append(k) + self.lst.append(k) dedump.add(k) def newline(self, row, k): @@ -1333,7 +1242,17 @@ class TagWidget(QWidget): getcolorbutton( "", "", - lambda _: labelsetedit(parent), + lambda _: listediter( + parent, + _TR("标签集"), + _TRL( + [ + "删除", + "标签", + ] + ), + globalconfig["labelset"], + ), icon="fa.gear", constcolor="#FF69B4", ), @@ -1386,9 +1305,11 @@ class dialog_savedgame_new(saveposwindow): savehook_new_list.pop(idx) if game in savehook_new_data: savehook_new_data.pop(game) - self.flow.removeidx(self.idxsave.index(game)) - self.idxsave.pop(self.idxsave.index(game)) - self.keepocus(idx) + + idx2 = self.idxsave.index(game) + self.flow.removeidx(idx2) + self.idxsave.pop(idx2) + self.flow.setfocus(idx2) except: pass @@ -1405,17 +1326,8 @@ class dialog_savedgame_new(saveposwindow): if res != "": res = res.replace("/", "\\") if res not in savehook_new_list: - self.newline(res) - self.idxsave.append(res) - - def keepocus(self, idx): - idx = min(len(savehook_new_list) - 1, idx) - if len(savehook_new_list): - self.flow.l._item_list[idx].widget().setFocus() - - def top1focus(self): - if len(savehook_new_list): - self.flow.l._item_list[0].widget().setFocus() + self.newline(res, True) + self.idxsave.insert(0, res) def tagschanged(self, tags): checkexists = _TR("存在") in tags @@ -1493,13 +1405,15 @@ class dialog_savedgame_new(saveposwindow): def showsettingdialog(self): idx = self.idxsave.index(self.currentfocuspath) - - dialog_setting_game( - self, - self.currentfocuspath, - None, - gametitleitme=self.flow.l._item_list[idx].widget(), - ) + try: + dialog_setting_game( + self, + self.currentfocuspath, + None, + gametitleitme=self.flow.widget(idx), + ) + except: + print_exc() def simplebutton(self, text, save, callback, exists): button5 = QPushButton() @@ -1532,7 +1446,7 @@ class dialog_savedgame_new(saveposwindow): ) _btn.setEnabled(_able1) - def newline(self, k): + def newline(self, k, first=False): checkifnewgame(k) def _getpixfunction(kk): @@ -1547,4 +1461,7 @@ class dialog_savedgame_new(saveposwindow): gameitem.connectexepath(k) gameitem.doubleclicked.connect(self.startgame) gameitem.focuschanged.connect(self.itemfocuschanged) - self.flow.addwidget(gameitem) + if first: + self.flow.insertwidget(0, gameitem) + else: + self.flow.addwidget(gameitem) diff --git a/LunaTranslator/LunaTranslator/gui/rangeselect.py b/LunaTranslator/LunaTranslator/gui/rangeselect.py index 6e7d576d..901f58d8 100644 --- a/LunaTranslator/LunaTranslator/gui/rangeselect.py +++ b/LunaTranslator/LunaTranslator/gui/rangeselect.py @@ -1,4 +1,4 @@ -from PyQt5.QtWidgets import QMenu, QDesktopWidget, QMainWindow, QLabel, QAction, QDialog +from PyQt5.QtWidgets import QMenu, QApplication, QMainWindow, QLabel, QAction, QDialog from PyQt5.QtGui import QPainter, QPen, QColor from PyQt5.QtCore import Qt, QPoint, QRect, QEvent from myutils.config import _TR @@ -57,19 +57,21 @@ class rangeadjust(Mainw): self._startPos = None self._endPos = None + def rectoffset(self, rect): + return [ + ( + rect.left() + globalconfig["ocrrangewidth"], + rect.top() + globalconfig["ocrrangewidth"], + ), + ( + rect.right() - globalconfig["ocrrangewidth"], + rect.bottom() - globalconfig["ocrrangewidth"], + ), + ] + def moveEvent(self, e): - rect = self.geometry() if self._rect: - self._rect = [ - ( - rect.left() + globalconfig["ocrrangewidth"], - rect.top() + globalconfig["ocrrangewidth"], - ), - ( - rect.right() - globalconfig["ocrrangewidth"], - rect.bottom() - globalconfig["ocrrangewidth"], - ), - ] + self._rect = self.rectoffset(self.geometry()) def enterEvent(self, QEvent): self.drag_label.setStyleSheet("background-color:rgba(0,0,0, 0.1)") @@ -80,18 +82,8 @@ class rangeadjust(Mainw): def resizeEvent(self, a0): self.label.setGeometry(0, 0, self.width(), self.height()) - rect = self.geometry() if self._rect: - self._rect = [ - ( - rect.left() + globalconfig["ocrrangewidth"], - rect.top() + globalconfig["ocrrangewidth"], - ), - ( - rect.right() - globalconfig["ocrrangewidth"], - rect.bottom() - globalconfig["ocrrangewidth"], - ), - ] + self._rect = self.rectoffset(self.geometry()) super(rangeadjust, self).resizeEvent(a0) def getrect(self): @@ -121,16 +113,13 @@ class rangeselct(QMainWindow): self.setAttribute(Qt.WA_TranslucentBackground) def reset(self): - num_screens = QDesktopWidget().screenCount() - x, y, x2, y2 = 9999, 9999, 0, 0 - for i in range(num_screens): - _rect = QDesktopWidget().screenGeometry(i) - x = min(x, _rect.x()) - y = min(y, _rect.y()) - x2 = max(x2, _rect.x() + _rect.width()) - y2 = max(y2, _rect.y() + _rect.height()) - self.setGeometry(x, y, x2 - x, y2 - y) - self.rectlabel.setGeometry(x, y, x2 - x, y2 - y) + # screens = QDesktopWidget().screenCount() + # desktop = QDesktopWidget().screenGeometry(0) + # for i in range(1, screens): + # desktop = desktop.united(QDesktopWidget().screenGeometry(i)) + desktop = QApplication.primaryScreen().virtualGeometry() + self.setGeometry(desktop) + self.rectlabel.resize(desktop.size()) self.setCursor(Qt.CrossCursor) self.is_drawing = False self.setMouseTracking(True) diff --git a/LunaTranslator/LunaTranslator/gui/specialwidget.py b/LunaTranslator/LunaTranslator/gui/specialwidget.py new file mode 100644 index 00000000..a650961c --- /dev/null +++ b/LunaTranslator/LunaTranslator/gui/specialwidget.py @@ -0,0 +1,258 @@ +from PyQt5.QtWidgets import QWidget, QSizePolicy, QListWidget, QScrollArea +from PyQt5.QtGui import QPainter, QPen, QFont, QFontMetrics +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import ( + QSpacerItem, + QWidgetItem, +) +from PyQt5.QtCore import QPoint, QRect, QSize, Qt, pyqtSignal +from PyQt5.QtWidgets import QLayout +from traceback import print_exc + + +class chartwidget(QWidget): + def __init__(self) -> None: + super().__init__() + + font = QFont("Arial", 10) + fmetrics = QFontMetrics(font) + + fhall = fmetrics.height() + self.font = font + + self.ymargin = int(fhall) + 10 # 20 + self.valuewidth = 10 + self.xtext = lambda x: str(x) + self.ytext = lambda y: str(y) + self.fmetrics = fmetrics + self.scalelinelen = 5 + + def setdata(self, data): + data = sorted(data, key=lambda _: _[0]) + self.data = data + + def paintEvent(self, event): + if self.data is None or len(self.data) == 0: + return + try: + if len(self.data) == 1: + self.data.insert(0, (0, 0)) + painter = QPainter(self) + painter.setRenderHint(QPainter.Antialiasing) + + pen = QPen(Qt.blue) + pen.setWidth(2) + painter.setPen(pen) + + painter.setFont(self.font) + + ymargin = self.ymargin + + xmargin = 0 + + max_y = int(max(y for _, y in self.data)) + y_labels = [self.ytext(i * max_y / 5) for i in range(6)] + + x_labels = [self.xtext(x) for x, _ in self.data] + for l in y_labels: + xmargin = max(xmargin, self.fmetrics.width(l)) + + xmargin = xmargin + self.scalelinelen + + width = self.width() - xmargin - self.fmetrics.width(x_labels[-1]) // 2 + height = self.height() - 2 * ymargin + + # 纵坐标 + for i, label in enumerate(y_labels): + y = int(ymargin + height - i * (height / 5)) + painter.drawLine(xmargin - self.scalelinelen, y, xmargin, y) + painter.drawText( + xmargin - self.scalelinelen - self.fmetrics.width(label), + y + 5, + label, + ) + + painter.drawLine(xmargin, ymargin, xmargin, ymargin + height) # Y轴 + painter.drawLine( + xmargin, ymargin + height, xmargin + width, ymargin + height + ) # X轴 + + # 计算数据点在绘图区域中的坐标 + x_scale = width / (len(self.data) - 1) + y_scale = height / max(max(y for _, y in self.data), 1) + + points = [] + for i, (x, y) in enumerate(self.data): + x_coord = xmargin + i * x_scale + y_coord = ymargin + height - y * y_scale + points.append((int(x_coord), int(y_coord))) + + # 绘制折线 + for i in range(len(points) - 1): + x1, y1 = points[i] + x2, y2 = points[i + 1] + painter.drawLine(x1, y1, x2, y2) + + if self.data[i + 1][1]: #!=0 + text = self.ytext(self.data[i + 1][1]) + painter.drawText( + x2 - self.fmetrics.width(text) // 2, y2 - 10, text + ) # value + + for i, (x, y) in enumerate(points): + painter.drawLine(x, ymargin + height, x, ymargin + height + 5) # 刻度线 + painter.drawText( + x - self.fmetrics.width(x_labels[i]) // 2, + ymargin + height + 20, + x_labels[i], + ) # 标签 + except: + print_exc() + + +class ScrollFlow(QWidget): + def resizeEvent(self, a0) -> None: + self.qscrollarea.resize(self.size()) + return super().resizeEvent(a0) + + def __init__(self): + super(ScrollFlow, self).__init__() + + self.listWidget = QListWidget(self) + # self.listWidget.setFixedWidth(600) + + self.l = FlowLayout() + + self.listWidget.setLayout(self.l) + + self.qscrollarea = QScrollArea(self) + self.qscrollarea.setWidgetResizable(True) + self.qscrollarea.setWidget(self.listWidget) + + def addwidget(self, wid): + self.l.addWidget(wid) + + def insertwidget(self, idx, wid): + self.l.insertWidget(idx, wid) + + def removeidx(self, index): + _ = self.l.takeAt(index) + _.widget().hide() + + def setfocus(self, idx): + self.widget(idx).setFocus() + + def widget(self, idx): + idx = min(idx, len(self.l._item_list) - 1) + idx = max(idx, 0) + return self.l._item_list[idx].widget() + + +class FlowLayout(QLayout): + heightChanged = pyqtSignal(int) + + def __init__(self, parent=None, margin=0, spacing=-1): + super().__init__(parent) + if parent is not None: + self.setContentsMargins(margin, margin, margin, margin) + self.setSpacing(spacing) + + self._item_list = [] + + def __del__(self): + while self.count(): + self.takeAt(0) + + def insertWidget(self, idx, widget): + item = QWidgetItem(widget) + widget.setParent(self.parentWidget()) + widget.adjustSize() + widget.setVisible(True) + self._item_list.insert(idx, item) + + self._do_layout(self.geometry(), False) + + def addItem(self, item): # pylint: disable=invalid-name + self._item_list.append(item) + + def addSpacing(self, size): # pylint: disable=invalid-name + self.addItem(QSpacerItem(size, 0, QSizePolicy.Fixed, QSizePolicy.Minimum)) + + def count(self): + return len(self._item_list) + + def itemAt(self, index): # pylint: disable=invalid-name + if 0 <= index < len(self._item_list): + return self._item_list[index] + return None + + def takeAt(self, index): # pylint: disable=invalid-name + if 0 <= index < len(self._item_list): + return self._item_list.pop(index) + return None + + def expandingDirections(self): # pylint: disable=invalid-name,no-self-use + return Qt.Orientations(Qt.Orientation(0)) + + def hasHeightForWidth(self): # pylint: disable=invalid-name,no-self-use + return True + + def heightForWidth(self, width): # pylint: disable=invalid-name + height = self._do_layout(QRect(0, 0, width, 0), True) + return height + + def setGeometry(self, rect): # pylint: disable=invalid-name + super().setGeometry(rect) + self._do_layout(rect, False) + + def sizeHint(self): # pylint: disable=invalid-name + return self.minimumSize() + + def minimumSize(self): # pylint: disable=invalid-name + size = QSize() + + for item in self._item_list: + minsize = item.minimumSize() + extent = item.geometry().bottomRight() + size = size.expandedTo(QSize(minsize.width(), extent.y())) + + margin = self.contentsMargins().left() + size += QSize(2 * margin, 2 * margin) + return size + + def _do_layout(self, rect, test_only=False): + m = self.contentsMargins() + effective_rect = rect.adjusted(+m.left(), +m.top(), -m.right(), -m.bottom()) + x = effective_rect.x() + y = effective_rect.y() + line_height = 0 + + for item in self._item_list: + wid = item.widget() + + space_x = self.spacing() + space_y = self.spacing() + if wid is not None: + space_x += wid.style().layoutSpacing( + QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Horizontal + ) + space_y += wid.style().layoutSpacing( + QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Vertical + ) + + next_x = x + item.sizeHint().width() + space_x + if next_x - space_x > effective_rect.right() and line_height > 0: + x = effective_rect.x() + y = y + line_height + space_y + next_x = x + item.sizeHint().width() + space_x + line_height = 0 + + if not test_only: + sz = item.sizeHint() + item.setGeometry(QRect(QPoint(x, y), sz)) + x = next_x + line_height = max(line_height, item.sizeHint().height()) + + new_height = y + line_height - rect.y() + self.heightChanged.emit(new_height) + return new_height diff --git a/LunaTranslator/LunaTranslator/myutils/config.py b/LunaTranslator/LunaTranslator/myutils/config.py index a7d49e43..886311e5 100644 --- a/LunaTranslator/LunaTranslator/myutils/config.py +++ b/LunaTranslator/LunaTranslator/myutils/config.py @@ -1,5 +1,5 @@ import json -import os +import os, time def tryreadconfig(path, default=None): @@ -76,7 +76,8 @@ def getdefaultsavehook(gamepath, title=None): "needinserthookcode": [], "removeuseless": False, "codepage_index": 0, - "allow_tts_auto_names": "", + # "allow_tts_auto_names": "", + "allow_tts_auto_names_v4": [], "tts_repair": False, "tts_repair_regex": [], "hooktypeasname": {}, @@ -88,6 +89,7 @@ def getdefaultsavehook(gamepath, title=None): "gamexmlfile": "", "vndbtags": [], "usertags": [], + "traceplaytime_v2": [], # [[start,end]] } if gamepath == "0": default["title"] = "No Game" @@ -99,11 +101,30 @@ def getdefaultsavehook(gamepath, title=None): + "/" + os.path.basename(gamepath) ) + return default _dfsavehook = getdefaultsavehook("") for game in savehook_new_data: + if ("traceplaytime_v2" not in savehook_new_data[game]) and ( + "statistic_playtime" in savehook_new_data[game] + ): + savehook_new_data[game]["traceplaytime_v2"] = [ + [ + 0, + savehook_new_data[game]["statistic_playtime"], + ] + ] + if ( + ("allow_tts_auto_names_v4" not in savehook_new_data[game]) + and ("allow_tts_auto_names" in savehook_new_data[game]) + and len(savehook_new_data[game]["allow_tts_auto_names"]) + ): + savehook_new_data[game]["allow_tts_auto_names_v4"] = savehook_new_data[game][ + "allow_tts_auto_names" + ].split("|") + for k in _dfsavehook: if k not in savehook_new_data[game]: savehook_new_data[game][k] = _dfsavehook[k] diff --git a/LunaTranslator/LunaTranslator/myutils/ocrutil.py b/LunaTranslator/LunaTranslator/myutils/ocrutil.py index eef124de..577e8002 100644 --- a/LunaTranslator/LunaTranslator/myutils/ocrutil.py +++ b/LunaTranslator/LunaTranslator/myutils/ocrutil.py @@ -45,7 +45,6 @@ def imagesolve(image): def imageCut(hwnd, x1, y1, x2, y2, viscompare=True): screen = QApplication.primaryScreen() - for _ in range(2): if _ % 2 == 0: diff --git a/LunaTranslator/files/defaultconfig/static_data.json b/LunaTranslator/files/defaultconfig/static_data.json index 0e75dee6..af2a25eb 100644 --- a/LunaTranslator/files/defaultconfig/static_data.json +++ b/LunaTranslator/files/defaultconfig/static_data.json @@ -1,5 +1,5 @@ { - "version":"v2.45.0", + "version":"v2.45.1", "themes":{ "dark":[ {"file":"dark1.qss","name":"PyQtDarkTheme"}, diff --git a/LunaTranslator/files/lang/ar.json b/LunaTranslator/files/lang/ar.json index d3e687cc..30bffa8c 100644 --- a/LunaTranslator/files/lang/ar.json +++ b/LunaTranslator/files/lang/ar.json @@ -88,7 +88,6 @@ "英语(CP437)": "الإنجليزية ( CP437 )", "代理设置": "إعدادات الوكيل", "土耳其语(CP1254)": "التركية ( CP1254 )", - "修改路径": "تعديل المسار", "韩语": "كوري", "排除复制自翻译器的文本": "استبعاد نسخ النص من المترجم", "请重新下载并关闭杀毒软件后重试": "الرجاء إعادة تحميل وإغلاق برامج مكافحة الفيروسات وحاول مرة أخرى", @@ -378,7 +377,6 @@ "仅": "فقط", "显示原文": "عرض النص الأصلي", "不支持的键位": "مفتاح غير معتمد", - "转区方法": "طريقة تحويل المنطقة", "自动更新": "التحديثات التلقائية", "越南语": "الفيتنامية", "希伯来语": "العبرية", @@ -606,7 +604,6 @@ "译文字体": "ترجمة الخط", "额外的行间距": "تباعد صف إضافي", "区分人名和文本": "التمييز بين الأسماء و النصوص", - "禁止自动朗读的人名(以|分隔多个)": "اسم الشخص الذي يمنع القراءة التلقائية ( مفصولة | )", "选取OCR范围后显示范围框": "حدد نطاق التعرف الضوئي على الحروف بعد عرض مربع النطاق", "下载": "للتحميل", "附加参数": "معلمة إضافية", @@ -757,5 +754,7 @@ "存在": "موجود", "标签集": "تسمية مجموعة", "添加": "إضافة .", - "使用原型查询": "باستخدام نموذج الاستعلام" + "使用原型查询": "باستخدام نموذج الاستعلام", + "时": "وقت", + "禁止自动朗读的人名": "أسماء الأشخاص المحظورين من القراءة التلقائية" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/cht.json b/LunaTranslator/files/lang/cht.json index bed6185c..d8b66a37 100644 --- a/LunaTranslator/files/lang/cht.json +++ b/LunaTranslator/files/lang/cht.json @@ -406,7 +406,6 @@ "删除": "删除", "自动切换到模式": "自動切換到模式", "不切换": "不切換", - "修改路径": "修改路徑", "类型": "類型", "人名": "人名", "显示": "顯示", @@ -492,7 +491,6 @@ "有道TTS": "有道TTS", "不支持的键位": "不支持的鍵位", "快捷键冲突": "快速鍵衝突", - "转区方法": "轉區方法", "乌克兰语": "烏克蘭語", "打开目录": "打開目錄", "标题": "標題", @@ -606,7 +604,6 @@ "译文字体": "譯文字體", "额外的行间距": "額外的行間距", "区分人名和文本": "區分人名和文字", - "禁止自动朗读的人名(以|分隔多个)": "禁止自動朗讀的人名(以|分隔多個)", "选取OCR范围后显示范围框": "選取OCR範圍後顯示範圍框", "下载": "下載", "附加参数": "附加參數", @@ -757,5 +754,7 @@ "存在": "存在", "标签集": "標籤集", "添加": "添加", - "使用原型查询": "使用原型査詢" + "使用原型查询": "使用原型査詢", + "时": "時", + "禁止自动朗读的人名": "禁止自動朗讀的人名" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/en.json b/LunaTranslator/files/lang/en.json index 5bb58c48..956019d0 100644 --- a/LunaTranslator/files/lang/en.json +++ b/LunaTranslator/files/lang/en.json @@ -406,7 +406,6 @@ "删除": "delete", "自动切换到模式": "Automatically switch to mode", "不切换": "Do not switch", - "修改路径": "Modify path", "类型": "type", "人名": "name", "显示": "display", @@ -492,7 +491,6 @@ "有道TTS": "Youdao TTS", "不支持的键位": "Unsupported key position", "快捷键冲突": "Shortcut key conflict", - "转区方法": "Transfer method", "乌克兰语": "Ukrainian", "打开目录": "Open directory", "标题": "title", @@ -606,7 +604,6 @@ "译文字体": "Translation font", "额外的行间距": "Additional line spacing", "区分人名和文本": "Distinguish between person names and text", - "禁止自动朗读的人名(以|分隔多个)": "Names of people that are not allowed to be automatically read (separated by |)", "选取OCR范围后显示范围框": "Show range box after selecting OCR range", "下载": "download", "附加参数": "Additional parameters", @@ -757,5 +754,7 @@ "存在": "existence", "标签集": "Label set", "添加": "Add", - "使用原型查询": "Using prototype queries" + "使用原型查询": "Using prototype queries", + "时": "Time", + "禁止自动朗读的人名": "Names that are prohibited from automatic reading" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/es.json b/LunaTranslator/files/lang/es.json index 9166e76b..c370db35 100644 --- a/LunaTranslator/files/lang/es.json +++ b/LunaTranslator/files/lang/es.json @@ -406,7 +406,6 @@ "删除": "Eliminar", "自动切换到模式": "Cambiar automáticamente al modo", "不切换": "Sin cambiar", - "修改路径": "Modificar ruta", "类型": "Tipo", "人名": "Nombre", "显示": "Mostrar", @@ -492,7 +491,6 @@ "有道TTS": "Youdao TTS", "不支持的键位": "Teclas no soportadas", "快捷键冲突": "Conflicto de teclas de acceso rápido", - "转区方法": "Método de transferencia", "乌克兰语": "Ucraniano", "打开目录": "Abrir catálogo", "标题": "Título", @@ -606,7 +604,6 @@ "译文字体": "Fuente de traducción", "额外的行间距": "Espaciamiento adicional de filas", "区分人名和文本": "Distinguir entre nombre y texto", - "禁止自动朗读的人名(以|分隔多个)": "Nombres de personas cuya lectura automática está prohibida (separados por | varios)", "选取OCR范围后显示范围框": "Después de seleccionar el rango ocr, se muestra el cuadro de rango.", "下载": "Descargar", "附加参数": "Parámetros adicionales", @@ -757,5 +754,7 @@ "存在": "Existencia", "标签集": "Conjunto de etiquetas", "添加": "Añadir", - "使用原型查询": "Consulta con prototipo" + "使用原型查询": "Consulta con prototipo", + "时": "Hora", + "禁止自动朗读的人名": "Nombres de personas cuya lectura automática está prohibida" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/fr.json b/LunaTranslator/files/lang/fr.json index b69ab30e..e001ed06 100644 --- a/LunaTranslator/files/lang/fr.json +++ b/LunaTranslator/files/lang/fr.json @@ -406,7 +406,6 @@ "删除": "Supprimer", "自动切换到模式": "Basculement automatique en mode", "不切换": "Pas de commutation", - "修改路径": "Modifier le chemin", "类型": "Type", "人名": "Nom de la personne", "显示": "Afficher", @@ -492,7 +491,6 @@ "有道TTS": "Avec tts", "不支持的键位": "Clés non supportées", "快捷键冲突": "Conflit de touches de raccourci", - "转区方法": "Méthode de transfert de zone", "乌克兰语": "Ukrainien", "打开目录": "Ouvrir le catalogue", "标题": "Titre", @@ -606,7 +604,6 @@ "译文字体": "Police de traduction", "额外的行间距": "Espacement des lignes supplémentaire", "区分人名和文本": "Différencier les noms de personnes et les textes", - "禁止自动朗读的人名(以|分隔多个)": "Noms de personnes interdits en lecture automatique (séparés par |)", "选取OCR范围后显示范围框": "Afficher la zone de portée après avoir sélectionné la plage ocr", "下载": "Télécharger", "附加参数": "Paramètres supplémentaires", @@ -757,5 +754,7 @@ "存在": "Présence", "标签集": "Ensemble d'étiquettes", "添加": "Ajouter", - "使用原型查询": "Utiliser une requête prototype" + "使用原型查询": "Utiliser une requête prototype", + "时": "Lorsque", + "禁止自动朗读的人名": "Noms de personnes interdits de Lecture automatique" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/it.json b/LunaTranslator/files/lang/it.json index cdf14de4..76883ead 100644 --- a/LunaTranslator/files/lang/it.json +++ b/LunaTranslator/files/lang/it.json @@ -396,7 +396,6 @@ "删除": "elimina", "自动切换到模式": "Passa automaticamente alla modalità", "不切换": "Non cambiare", - "修改路径": "Modifica tracciato", "类型": "tipo", "人名": "nome", "用户词典选择JcUserdic文件夹": "Selezione dizionario utente Cartella JcUserdic", @@ -492,7 +491,6 @@ "有道TTS": "Youdao TTS", "不支持的键位": "Posizione chiave non supportata", "快捷键冲突": "Conflitto di tasti scorciatoie", - "转区方法": "Metodo di trasferimento", "乌克兰语": "Ucraino", "打开目录": "Apri directory", "标题": "titolo", @@ -606,7 +604,6 @@ "译文字体": "Carattere di traduzione", "额外的行间距": "Spaziatura riga aggiuntiva", "区分人名和文本": "Distinguere i nomi delle persone e il testo", - "禁止自动朗读的人名(以|分隔多个)": "Nomi di persone che non possono essere letti automaticamente (separati da |)", "选取OCR范围后显示范围框": "Mostra la casella di intervallo dopo aver selezionato l'intervallo OCR", "下载": "download", "附加参数": "Parametri aggiuntivi", @@ -757,5 +754,7 @@ "存在": "esistenza", "标签集": "Set di etichette", "添加": "Aggiungi", - "使用原型查询": "Utilizzo di query prototipali" + "使用原型查询": "Utilizzo di query prototipali", + "时": "Tempo", + "禁止自动朗读的人名": "Nomi vietati dalla lettura automatica" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/ja.json b/LunaTranslator/files/lang/ja.json index f47aae84..f6e0c711 100644 --- a/LunaTranslator/files/lang/ja.json +++ b/LunaTranslator/files/lang/ja.json @@ -406,7 +406,6 @@ "删除": "削除#サクジョ#", "自动切换到模式": "モードに自動切り替え", "不切换": "切り替えない", - "修改路径": "パスの変更", "类型": "を選択してオプションを設定します。", "人名": "人名", "显示": "表示", @@ -492,7 +491,6 @@ "有道TTS": "有道TTS", "不支持的键位": "サポートされていないキー", "快捷键冲突": "ショートカットキーの競合", - "转区方法": "ゾーン移動方法", "乌克兰语": "ウクライナ語", "打开目录": "ディレクトリを開く", "标题": "タイトル", @@ -606,7 +604,6 @@ "译文字体": "訳文フォント", "额外的行间距": "余分な行間隔", "区分人名和文本": "人名とテキストの区別", - "禁止自动朗读的人名(以|分隔多个)": "自動朗読を禁止している人の名前(|で区切って複数)", "选取OCR范围后显示范围框": "OCR範囲を選択して範囲ボックスを表示", "下载": "ダウンロード", "附加参数": "追加パラメータ", @@ -757,5 +754,7 @@ "存在": "存在する", "标签集": "ラベルセット", "添加": "追加", - "使用原型查询": "プロトタイプクエリーの使用" + "使用原型查询": "プロトタイプクエリーの使用", + "时": "時", + "禁止自动朗读的人名": "自動朗読禁止の人名" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/ko.json b/LunaTranslator/files/lang/ko.json index a08f8cd1..32817e49 100644 --- a/LunaTranslator/files/lang/ko.json +++ b/LunaTranslator/files/lang/ko.json @@ -406,7 +406,6 @@ "删除": "삭제", "自动切换到模式": "모드로 자동 전환", "不切换": "비전환", - "修改路径": "경로 수정", "类型": "유형", "人名": "인명", "显示": "표시", @@ -492,7 +491,6 @@ "有道TTS": "TTS가 있어요.", "不支持的键位": "지원되지 않는 키", "快捷键冲突": "단축키 충돌", - "转区方法": "영역 변환 방법", "乌克兰语": "우크라이나어", "打开目录": "디렉토리 열기", "标题": "제목", @@ -606,7 +604,6 @@ "译文字体": "번역문 글꼴", "额外的行间距": "추가 행 간격", "区分人名和文本": "사람 이름과 텍스트 구분", - "禁止自动朗读的人名(以|分隔多个)": "자동 발음이 금지된 사람 이름 (여러 개 / 로 구분)", "选取OCR范围后显示范围框": "OCR 범위를 선택한 후 범위 상자 표시", "下载": "다운로드", "附加参数": "추가 매개변수", @@ -757,5 +754,7 @@ "存在": "존재", "标签集": "태그 세트", "添加": "추가", - "使用原型查询": "원형 조회 사용" + "使用原型查询": "원형 조회 사용", + "时": "시", + "禁止自动朗读的人名": "자동 발음이 금지된 사람 이름" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/pl.json b/LunaTranslator/files/lang/pl.json index 798b0a10..e862088f 100644 --- a/LunaTranslator/files/lang/pl.json +++ b/LunaTranslator/files/lang/pl.json @@ -406,7 +406,6 @@ "删除": "usunąć", "自动切换到模式": "Automatyczne przełączenie do trybu", "不切换": "Nie przełączaj", - "修改路径": "Zmień ścieżkę", "类型": "typ", "人名": "nazwa", "用户词典选择JcUserdic文件夹": "Wybór słownika użytkownika JcUserdic folder", @@ -492,7 +491,6 @@ "有道TTS": "Youdao TTS", "不支持的键位": "Nieobsługiwana pozycja klucza", "快捷键冲突": "Konflikt kluczy skrótów", - "转区方法": "Metoda transferu", "乌克兰语": "Ukraiński", "打开目录": "Otwórz katalog", "标题": "tytuł", @@ -606,7 +604,6 @@ "译文字体": "Czcionka tłumaczenia", "额外的行间距": "Dodatkowe odstępy linii", "区分人名和文本": "Rozróżnianie nazwisk i tekstu osób", - "禁止自动朗读的人名(以|分隔多个)": "Nazwy osób, które nie mogą być automatycznie odczytywane (oddzielone przez |)", "选取OCR范围后显示范围框": "Pokaż pole zakresu po wybraniu zakresu OCR", "下载": "pobierz", "附加参数": "Dodatkowe parametry", @@ -757,5 +754,7 @@ "存在": "istnienie", "标签集": "Zestaw etykiet", "添加": "Dodaj", - "使用原型查询": "Korzystanie z prototypowych zapytań" + "使用原型查询": "Korzystanie z prototypowych zapytań", + "时": "Czas", + "禁止自动朗读的人名": "Nazwy, które są zabronione automatycznego odczytu" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/ru.json b/LunaTranslator/files/lang/ru.json index b80a5d2f..485b2c4f 100644 --- a/LunaTranslator/files/lang/ru.json +++ b/LunaTranslator/files/lang/ru.json @@ -406,7 +406,6 @@ "删除": "Удалить", "自动切换到模式": "Автоматическое переключение в режим", "不切换": "Не переключаться", - "修改路径": "Изменить путь", "类型": "Тип", "人名": "Имя человека", "显示": "Показать", @@ -492,7 +491,6 @@ "有道TTS": "Есть TTS", "不支持的键位": "Не поддерживаемые клавиши", "快捷键冲突": "Конфликт комбинаций клавиш", - "转区方法": "Метод перехода", "乌克兰语": "Украинский язык", "打开目录": "Открыть каталог", "标题": "Заголовок", @@ -606,7 +604,6 @@ "译文字体": "Шрифт перевода", "额外的行间距": "Дополнительное расстояние между строками", "区分人名和文本": "Различие между именем и текстом", - "禁止自动朗读的人名(以|分隔多个)": "Имя человека, которое запрещено читать автоматически (разделить несколько)", "选取OCR范围后显示范围框": "Показывать диапазон после выбора диапазона OCR", "下载": "Скачать", "附加参数": "Дополнительные параметры", @@ -757,5 +754,7 @@ "存在": "Наличие", "标签集": "Набор меток", "添加": "Добавить", - "使用原型查询": "Использовать запрос прототипа" + "使用原型查询": "Использовать запрос прототипа", + "时": "Время", + "禁止自动朗读的人名": "Имя человека, которое запрещено читать автоматически" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/th.json b/LunaTranslator/files/lang/th.json index e67f42fd..7e681b8f 100644 --- a/LunaTranslator/files/lang/th.json +++ b/LunaTranslator/files/lang/th.json @@ -13,7 +13,6 @@ "特殊字体样式填充颜色": "รูปแบบตัวอักษรพิเศษสีเติม", "过滤数字": "กรองตัวเลข", "插入特殊码": "แทรกรหัสพิเศษ", - "转区方法": "วิธีการโอนโซน", "移除非选定hook": "ลบ hook ที่ไม่ได้เลือก", "周期执行": "การดำเนินการตามวัฏจักร", "错误": "ข้อผิดพลาด", @@ -456,7 +455,6 @@ "分析图像更新+周期执行": "การวิเคราะห์การอัปเดตภาพ + การดำเนินการเป็นระยะเวลา", "是否显示翻译器名称": "แสดงชื่อของนักแปลหรือไม่", "语音设置": "การตั้งค่าเสียง", - "修改路径": "แก้ไขพาธ", "&显示": "แสดงภาพ", "中东欧(CP1250)": "ยุโรปกลางและยุโรปตะวันออก (CP1250)", "排除复制自翻译器的文本": "ยกเว้นการคัดลอกข้อความที่แปลด้วยตนเอง", @@ -606,7 +604,6 @@ "译文字体": "Translation ตัวอักษร", "额外的行间距": "ระยะห่างระหว่างแถวเพิ่มเติม", "区分人名和文本": "แยกแยะชื่อบุคคลและข้อความ", - "禁止自动朗读的人名(以|分隔多个)": "ห้ามอ่านออกเสียงชื่อของบุคคลโดยอัตโนมัติ (แยกหลาย ๆ คนด้วย #)", "选取OCR范围后显示范围框": "แสดงกล่องช่วงหลังจากเลือกช่วง OCR", "下载": "ดาวน์โหลด", "附加参数": "พารามิเตอร์เพิ่มเติม", @@ -757,5 +754,7 @@ "存在": "การปรากฏตัว", "标签集": "ชุดแท็ก", "添加": "เพิ่ม", - "使用原型查询": "การใช้แบบสอบถามต้นแบบ" + "使用原型查询": "การใช้แบบสอบถามต้นแบบ", + "时": "เวลา", + "禁止自动朗读的人名": "ชื่อของบุคคลที่ห้ามอ่านออกเสียงโดยอัตโนมัติ" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/tr.json b/LunaTranslator/files/lang/tr.json index ea16ae50..c74fbdf3 100644 --- a/LunaTranslator/files/lang/tr.json +++ b/LunaTranslator/files/lang/tr.json @@ -406,7 +406,6 @@ "删除": "Sil", "自动切换到模式": "Otomatik moda değiştir", "不切换": "Değiştirme", - "修改路径": "Yolu değiştir", "类型": "tür", "人名": "isim", "显示": "Ekran", @@ -492,7 +491,6 @@ "有道TTS": "Youdao TTS", "不支持的键位": "Desteklenmeyen anahtar pozisyonu", "快捷键冲突": "Kısayol tuş çatışması", - "转区方法": "Transfer yöntemi", "乌克兰语": "Ukraince", "打开目录": "Dizini Aç", "标题": "isim", @@ -606,7 +604,6 @@ "译文字体": "Çeviri yazıtipi", "额外的行间距": "Ekstra çizgi boşluğu", "区分人名和文本": "Kişisel isimler ve metin arasında ayrı", - "禁止自动朗读的人名(以|分隔多个)": "Otomatik okunmaya izin verilmeyen insanların isimleri (ayrılmış .).", "选取OCR范围后显示范围框": "OCR menzili seçmeden sonra menzil kutusunu göster", "下载": "indir", "附加参数": "Ekstra parametre", @@ -757,5 +754,7 @@ "存在": "varlığı", "标签集": "Etiket seti", "添加": "Ekle", - "使用原型查询": "Prototip sorguları kullanılıyor" + "使用原型查询": "Prototip sorguları kullanılıyor", + "时": "Zaman", + "禁止自动朗读的人名": "Otomatik okuma yasaklanmış isimler" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/uk.json b/LunaTranslator/files/lang/uk.json index f48cb577..b930099f 100644 --- a/LunaTranslator/files/lang/uk.json +++ b/LunaTranslator/files/lang/uk.json @@ -396,7 +396,6 @@ "删除": "вилучити", "自动切换到模式": "Автоматично перемикати у режим", "不切换": "Не перемикати", - "修改路径": "Змінити шлях", "类型": "тип", "人名": "name", "用户词典选择JcUserdic文件夹": "Вибір словника користувача JcUserdic folder", @@ -492,7 +491,6 @@ "有道TTS": "Youdao TTS", "不支持的键位": "Непідтримувана позиція ключа", "快捷键冲突": "Конфлікт клавіш скорочення", - "转区方法": "Метод перенесення", "乌克兰语": "УкраїнськаName", "打开目录": "Відкрити каталог", "标题": "заголовок", @@ -606,7 +604,6 @@ "译文字体": "Шрифт перекладу", "额外的行间距": "Додаткове розділення ліній", "区分人名和文本": "Розділ між іменами людей і текстом", - "禁止自动朗读的人名(以|分隔多个)": "Назви людей, які не дозволяють автоматично читати (відокремлені [UNK])", "选取OCR范围后显示范围框": "Показувати діапазон після вибору діапазону OCR", "下载": "звантажити", "附加参数": "Додаткові параметри", @@ -757,5 +754,7 @@ "存在": "існування", "标签集": "Встановлення мітки", "添加": "Додати", - "使用原型查询": "Використання запитів прототипу" + "使用原型查询": "Використання запитів прототипу", + "时": "Час", + "禁止自动朗读的人名": "Назви, які заборонені автоматичне читання" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/vi.json b/LunaTranslator/files/lang/vi.json index 80829fa2..49974556 100644 --- a/LunaTranslator/files/lang/vi.json +++ b/LunaTranslator/files/lang/vi.json @@ -406,7 +406,6 @@ "删除": "Xoá", "自动切换到模式": "Tự động chuyển sang chế độ", "不切换": "Không chuyển đổi", - "修改路径": "Sửa đổi đường dẫn", "类型": "Loại", "人名": "Tên người", "显示": "Hiển thị", @@ -492,7 +491,6 @@ "有道TTS": "Có TTS", "不支持的键位": "Các phím không được hỗ trợ", "快捷键冲突": "Xung đột phím tắt", - "转区方法": "Phương pháp chuyển vùng", "乌克兰语": "Tiếng Việt", "打开目录": "Mở thư mục", "标题": "Tiêu đề", @@ -606,7 +604,6 @@ "译文字体": "Phông chữ dịch", "额外的行间距": "Thêm khoảng cách hàng", "区分人名和文本": "Phân biệt tên người và văn bản", - "禁止自动朗读的人名(以|分隔多个)": "Tên của những người bị cấm tự động đọc to (để phân tách nhiều hơn một)", "选取OCR范围后显示范围框": "Hiển thị hộp phạm vi sau khi chọn phạm vi OCR", "下载": "Tải về", "附加参数": "Tham số bổ sung", @@ -757,5 +754,7 @@ "存在": "Hiện diện", "标签集": "Bộ thẻ", "添加": "Thêm", - "使用原型查询": "Truy vấn với Prototype" + "使用原型查询": "Truy vấn với Prototype", + "时": "Khi", + "禁止自动朗读的人名": "Tên người bị cấm đọc tự động" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/zh.json b/LunaTranslator/files/lang/zh.json index e07f3024..c255ad28 100644 --- a/LunaTranslator/files/lang/zh.json +++ b/LunaTranslator/files/lang/zh.json @@ -13,7 +13,6 @@ "特殊字体样式填充颜色": "", "过滤数字": "", "插入特殊码": "", - "转区方法": "", "移除非选定hook": "", "周期执行": "", "错误": "", @@ -451,7 +450,6 @@ "分析图像更新+周期执行": "", "是否显示翻译器名称": "", "语音设置": "", - "修改路径": "", "&显示": "", "中东欧(CP1250)": "", "排除复制自翻译器的文本": "", @@ -601,7 +599,6 @@ "译文字体": "", "额外的行间距": "", "区分人名和文本": "", - "禁止自动朗读的人名(以|分隔多个)": "", "下载": "", "附加参数": "", "语言": "", @@ -757,5 +754,7 @@ "存在": "", "标签集": "", "添加": "", - "使用原型查询": "" + "使用原型查询": "", + "时": "", + "禁止自动朗读的人名": "" } \ No newline at end of file