diff --git a/LunaTranslator/LunaTranslator/LunaTranslator.py b/LunaTranslator/LunaTranslator/LunaTranslator.py index 721daf1d..3de85644 100644 --- a/LunaTranslator/LunaTranslator/LunaTranslator.py +++ b/LunaTranslator/LunaTranslator/LunaTranslator.py @@ -369,8 +369,7 @@ class MAINUI: if ( globalconfig["embedded"]["as_fast_as_posible"] - or classname - == list(globalconfig["fanyi"])[globalconfig["embedded"]["translator"]] + or classname == globalconfig["embedded"]["translator_2"] ): return returnandembedcallback( kanjitrans(zhconv.convert(res, "zh-tw")) diff --git a/LunaTranslator/LunaTranslator/cishu/cishubase.py b/LunaTranslator/LunaTranslator/cishu/cishubase.py index 83ba3821..020cef95 100644 --- a/LunaTranslator/LunaTranslator/cishu/cishubase.py +++ b/LunaTranslator/LunaTranslator/cishu/cishubase.py @@ -17,7 +17,7 @@ class cishubase: self.init() self.needinit = False except: - pass + print_exc() @threader def safesearch(self, sentence, callback): diff --git a/LunaTranslator/LunaTranslator/cishu/mdict.py b/LunaTranslator/LunaTranslator/cishu/mdict.py index 6e85e9b5..f93704ab 100644 --- a/LunaTranslator/LunaTranslator/cishu/mdict.py +++ b/LunaTranslator/LunaTranslator/cishu/mdict.py @@ -1,4 +1,5 @@ -import math +import math, base64, uuid +import threading, time class FlexBuffer: @@ -1934,6 +1935,8 @@ if sys.hexversion >= 0x03000000: version = "1.1" +import hashlib + class IndexBuilder(object): # todo: enable history @@ -1959,13 +1962,20 @@ class IndexBuilder(object): _filename, _file_extension = os.path.splitext(fname) assert _file_extension == ".mdx" assert os.path.isfile(fname) - self._mdx_db = _filename + ".mdx.db" + os.makedirs("cache/mdict/index", exist_ok=True) + _mdxmd5 = ( + os.path.basename(_filename) + + "_" + + hashlib.md5(_filename.encode("utf8")).hexdigest() + ) + _targetfilenamebase = os.path.join("cache/mdict/index", _mdxmd5) + self._mdx_db = _targetfilenamebase + ".mdx.db" # make index anyway if force_rebuild: self._make_mdx_index(self._mdx_db) if os.path.isfile(_filename + ".mdd"): self._mdd_file = _filename + ".mdd" - self._mdd_db = _filename + ".mdd.db" + self._mdd_db = _targetfilenamebase + ".mdd.db" self._make_mdd_index(self._mdd_db) if os.path.isfile(self._mdx_db): @@ -1984,7 +1994,7 @@ class IndexBuilder(object): print("mdx.db rebuilt!") if os.path.isfile(_filename + ".mdd"): self._mdd_file = _filename + ".mdd" - self._mdd_db = _filename + ".mdd.db" + self._mdd_db = _targetfilenamebase + ".mdd.db" self._make_mdd_index(self._mdd_db) print("mdd.db rebuilt!") return None @@ -2020,7 +2030,7 @@ class IndexBuilder(object): if os.path.isfile(_filename + ".mdd"): self._mdd_file = _filename + ".mdd" - self._mdd_db = _filename + ".mdd.db" + self._mdd_db = _targetfilenamebase + ".mdd.db" if not os.path.isfile(self._mdd_db): self._make_mdd_index(self._mdd_db) pass @@ -2038,54 +2048,6 @@ class IndexBuilder(object): txt_styled = txt_styled + style[0] + p + style[1] return txt_styled - def make_sqlite(self): - sqlite_file = self._mdx_file + ".sqlite.db" - if os.path.exists(sqlite_file): - os.remove(sqlite_file) - mdx = MDX(self._mdx_file) - conn = sqlite3.connect(sqlite_file) - cursor = conn.cursor() - cursor.execute( - """ CREATE TABLE MDX_DICT - (key text not null, - value text - )""" - ) - - # remove '(pīnyīn)', remove `1`: - aeiou = "āáǎàĀÁǍÀēéěèêềếĒÉĚÈÊỀẾīíǐìÍǏÌōóǒòŌÓǑÒūúǔùŪÚǓÙǖǘǚǜǕǗǙǛḾǹňŃŇ" - pattern = r"`\d+`|[(\(]?['a-z%s]*[%s]['a-z%s]*[\))]?" % (aeiou, aeiou, aeiou) - tuple_list = [ - (key.decode(), re.sub(pattern, "", value.decode())) - for key, value in mdx.items() - ] - - cursor.executemany("INSERT INTO MDX_DICT VALUES (?,?)", tuple_list) - - returned_index = mdx.get_index(check_block=self._check) - meta = returned_index["meta"] - cursor.execute("""CREATE TABLE META (key text, value text)""") - - cursor.executemany( - "INSERT INTO META VALUES (?,?)", - [ - ("encoding", meta["encoding"]), - ("stylesheet", meta["stylesheet"]), - ("title", meta["title"]), - ("description", meta["description"]), - ("version", version), - ], - ) - - if self._sql_index: - cursor.execute( - """ - CREATE INDEX key_index ON MDX_DICT (key) - """ - ) - conn.commit() - conn.close() - def _make_mdx_index(self, db_name): if os.path.exists(db_name): os.remove(db_name) @@ -2321,32 +2283,82 @@ import re class mdict(cishubase): + def init_once_mdx(self, f): + if not os.path.isfile(f): + return + f = os.path.normpath(f) + if f in self.dedump: + return + self.dedump.add(f) + _ = self.extraconf[f] = self.extraconf.get(f, {}) + _["priority"] = _.get("priority", 100) # 越大展示的越靠前 + _["distance"] = _.get( + "distance", -1 + ) # -1是跟随mdict全局distance,否则使用私有distance + _["title"] = _.get("title", None) # None是使用默认显示名,否则使用自定义显示名 + if os.path.exists(f): + try: + index = IndexBuilder(f) + + title = _["title"] + if title is None: + t = os.path.basename(f)[:-4] + if index._title.strip() != "": + t1 = index._title.strip() + if (t1.isascii()) and (t.isascii()): + t = t1 + elif not t1.isascii(): + t = t1 + title = t + distance = _["distance"] + if distance == -1: + distance = self.config["distance"] + self.builders.append((f, index, title, distance, _["priority"])) + + except: + print(f) + from traceback import print_exc + + print_exc() + def init(self): + try: + with open("cache/mdict/config.json", "r", encoding="utf8") as ff: + self.extraconf = json.loads(ff.read()) + except: + self.extraconf = {} self.sql = None - paths = self.config["path"] + self.builders = [] + self.dedump = set() + for f in paths.split("|"): - if os.path.exists(f): - try: - self.builders.append((IndexBuilder(f), f)) - # with open('1.txt','a',encoding='utf8') as ff: - # print(f,file=ff) - # print(self.builders[-1][0].get_mdx_keys(),file=ff) - # print(self.builders[-1][0].get_mdd_keys(),file=ff) - except: - from traceback import print_exc + if f.strip() == "": + continue + self.init_once_mdx(f) - print_exc() + for _dir, _, _fs in os.walk(self.config["path_dir"]): + for f in _fs: + if not f.lower().endswith(".mdx"): + continue + f = os.path.join(_dir, f) + self.init_once_mdx(f) - def querycomplex(self, word, index): + try: + with open("cache/mdict/config.json", "w", encoding="utf8") as ff: + ff.write(json.dumps(self.extraconf, ensure_ascii=False, indent=4)) + except: + pass + + def querycomplex(self, word, distance, index): results = [] diss = {} import winsharedutils for k in index("*" + word + "*"): dis = winsharedutils.distance(k, word) - if dis <= self.config["distance"]: + if dis <= distance: results.append(k) diss[k] = dis @@ -2482,8 +2494,94 @@ class mdict(cishubase): else: return "application/octet-stream" + def parseaudio(self, html_content, url, file_content): + base64_content = base64.b64encode(file_content).decode("utf-8") + + uid = str(uuid.uuid4()) + # with open(uid+'.mp3','wb') as ff: + # ff.write(file_content) + audio = f'' + html_content = audio + html_content.replace( + url, + f"javascript:document.getElementById('{uid}').play()", + ) + return html_content + + def tryloadurl(self, index: IndexBuilder, base, url: str): + _local = os.path.join(base, url) + iscss = url.lower().endswith(".css") + _type = 0 + file_content = None + if iscss: + _type = 1 + if os.path.exists(_local) and os.path.isfile(_local): + with open(os.path.join(base, url), "rb") as f: + file_content = f.read() + return _type, file_content + + if url.startswith("#"): # a href # 页内跳转 + return -1, None + + url1 = url.replace("/", "\\") + if not url1.startswith("\\"): + url1 = "\\" + url1 + try: + file_content = index.mdd_lookup(url1)[0] + except: + pass + if file_content: + return _type, file_content + + func = url.split(r"://")[0] + if func == "entry": + return -1, None + url1 = url.split(r"://")[1] + url1 = url1.replace("/", "\\") + + if not url1.startswith("\\"): + url1 = "\\" + url1 + try: + file_content = index.mdd_lookup(url1)[0] + except: + return None + if func == "sound": + _type = 2 + return _type, file_content + + def tryparsecss(self, html_content, url, file_content, divid): + try: + import sass + + css = file_content.decode("utf8") + css = sass.compile(string=(f"#{divid} {{ {css} }}")) + csss = css.split("\n") + i = 0 + while i < len(csss): + css = csss[i] + if css.endswith(" body {"): + csss[i] = css[: -len(" body {")] + "{" + elif css == "@font-face {": + csss[i + 1] = "" + for j in range(i + 2, len(csss)): + if csss[j].endswith("} }"): + i = j + csss[j] = csss[j][:-1] + break + i += 1 + css = "\n".join(csss) + file_content = css.encode("utf8") + # print(css) + except: + from traceback import print_exc + + print_exc() + base64_content = base64.b64encode(file_content).decode("utf-8") + html_content = html_content.replace( + url, f"data:text/css;base64,{base64_content}" + ) + return html_content + def repairtarget(self, index, base, html_content): - import base64, uuid src_pattern = r'src="([^"]+)"' href_pattern = r'href="([^"]+)"' @@ -2492,122 +2590,62 @@ class mdict(cishubase): href_matches = re.findall(href_pattern, html_content) divid = "luna_internal_" + str(uuid.uuid4()) for url in src_matches + href_matches: - oked = False - iscss = url.lower().endswith(".css") try: - try: - with open(os.path.join(base, url), "rb") as f: - file_content = f.read() - - except: - url1 = url.replace("/", "\\") - if not url1.startswith("\\"): - url1 = "\\" + url1 - try: - file_content = index.mdd_lookup(url1)[0] - except: - func = url.split(r"://")[0] - if func == "entry": - continue - url1 = url.split(r"://")[1] - url1 = url1.replace("/", "\\") - - if not url1.startswith("\\"): - url1 = "\\" + url1 - file_content = index.mdd_lookup(url1)[0] - if func == "sound": - - base64_content = base64.b64encode(file_content).decode( - "utf-8" - ) - import uuid - - uid = str(uuid.uuid4()) - # with open(uid+'.mp3','wb') as ff: - # ff.write(file_content) - audio = f'' - html_content = audio + html_content.replace( - url, - f"javascript:document.getElementById('{uid}').play()", - ) - file_content = None - oked = True - else: - print(url) + file_content = self.tryloadurl(index, base, url) except: - file_content = None - if file_content: - if iscss: - try: - import sass - - css = file_content.decode("utf8") - css = sass.compile(string=(f"#{divid} {{ {css} }}")) - csss = css.split("\n") - i = 0 - while i < len(csss): - css = csss[i] - if css.endswith(" body {"): - csss[i] = css[: -len(" body {")] + "{" - elif css == "@font-face {": - csss[i + 1] = "" - for j in range(i + 2, len(csss)): - if csss[j].endswith("} }"): - i = j - csss[j] = csss[j][:-1] - break - i += 1 - css = "\n".join(csss) - file_content = css.encode("utf8") - # print(css) - except: - from traceback import print_exc - - print_exc() - - base64_content = base64.b64encode(file_content).decode("utf-8") - if iscss: - html_content = html_content.replace( - url, f"data:text/css;base64,{base64_content}" - ) - else: - html_content = html_content.replace( - url, f"data:application/octet-stream;base64,{base64_content}" - ) - elif not oked: + print("unknown", url) + continue + if not file_content: print(url) + continue + _type, file_content = file_content + if _type == -1: + continue + elif _type == 1: + html_content = self.tryparsecss(html_content, url, file_content, divid) + elif _type == 2: + html_content = self.parseaudio(html_content, url, file_content) + elif _type == 0: + base64_content = base64.b64encode(file_content).decode("utf-8") + html_content = html_content.replace( + url, f"data:application/octet-stream;base64,{base64_content}" + ) return f'
{html_content}
' - def search(self, word): - allres = [] - for index, f in self.builders: - results = [] - # print(f) - try: - keys = self.querycomplex(word, index.get_mdx_keys) - # print(keys) - for k in keys: - content = index.mdx_lookup(k)[0] - match = re.match("@@@LINK=(.*)", content.strip()) - if match: - match = match.groups()[0] - content = index.mdx_lookup(match)[0] - results.append(self.parseashtml(content)) - except: - from traceback import print_exc + def searchthread(self, allres, i, word): + f, index, title, distance, priority = self.builders[i] + results = [] + try: + keys = self.querycomplex(word, distance, index.get_mdx_keys) + # print(keys) + for k in keys: + content = index.mdx_lookup(k)[0] + match = re.match("@@@LINK=(.*)", content.strip()) + if match: + match = match.groups()[0] + content = index.mdx_lookup(match)[0] + results.append(self.parseashtml(content)) + except: + from traceback import print_exc - print_exc() - if len(results) == 0: - continue + print_exc() + for i in range(len(results)): + results[i] = self.repairtarget(index, os.path.dirname(f), results[i]) + if len(results): + allres.append((priority, title, "".join(results))) - for i in range(len(results)): - results[i] = self.repairtarget(index, os.path.dirname(f), results[i]) - #
- # /rjx0849.png->mddkey \\rjx0849.png entry://rjx0848->跳转到mdxkey rjx0849 - # 太麻烦,不搞了。 - allres.append((f, "".join(results))) - if len(allres) == 0: - return + def generatehtml_tabswitch(self, allres): + btns = [] + contents = [] + idx = 0 + for _, title, res in allres: + idx += 1 + btns.append( + f"""""" + ) + contents.append( + f"""
{res}
""" + ) commonstyle = """ """ return res + + def generatehtml_flow(self, allres): + content = """""" + content += """ +""" + lis = [] + for _, title, res in allres: + uid = str(uuid.uuid4()) + lis.append( + rf"""
  • {title}
    + {res} +
  • """ + ) + content += rf""" +""" + + return content + + def search(self, word): + allres = [] + # threads = [] + # for i in range(len(self.builders)): + # threads.append( + # threading.Thread(target=self.searchthread, args=(allres, i, word)) + # ) + + # for _ in threads: + # _.start() + # for _ in threads: + # _.join() + for i in range(len(self.builders)): + self.searchthread(allres, i, word) + if len(allres) == 0: + return + allres.sort(key=lambda _: -_[0]) + if self.config["stylehv"] == 0: + return self.generatehtml_tabswitch(allres) + elif self.config["stylehv"] == 1: + return self.generatehtml_flow(allres) diff --git a/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py b/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py index 21fa037d..3348336b 100644 --- a/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py +++ b/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py @@ -571,7 +571,7 @@ class dialog_setting_game(QDialog): res = f[0] if res != "": - res = res.replace("/", "\\") + res = os.path.normpath(res) if res in savehook_new_list: return savehook_new_list[savehook_new_list.index(self.exepath)] = res @@ -1448,7 +1448,7 @@ class dialog_savedgame_new(saveposwindow): res = f[0] if res != "": - res = res.replace("/", "\\") + res = os.path.normpath(res) if res not in savehook_new_list: checkifnewgame(res) self.newline(res, True) diff --git a/LunaTranslator/LunaTranslator/gui/edittext.py b/LunaTranslator/LunaTranslator/gui/edittext.py index ca716220..816e3046 100644 --- a/LunaTranslator/LunaTranslator/gui/edittext.py +++ b/LunaTranslator/LunaTranslator/gui/edittext.py @@ -2,8 +2,8 @@ from qtsymbols import * import qtawesome import threading, windows import gobject, time -from myutils.config import globalconfig, _TR -from gui.usefulwidget import closeashidewindow, saveposwindow +from myutils.config import globalconfig, _TR, _TRL +from gui.usefulwidget import closeashidewindow, getsimplecombobox from myutils.utils import str2rgba from myutils.wrapper import Singleton_close, threader @@ -138,6 +138,14 @@ class edittrans(QMainWindow): submit = QPushButton(_TR("确定")) qv.addWidget(self.textOutput) + qv.addWidget( + getsimplecombobox( + _TRL([globalconfig["fanyi"][x]["name"] for x in globalconfig["fanyi"]]), + globalconfig, + "realtime_edit_target", + internallist=list(globalconfig["fanyi"]), + ) + ) qv.addWidget(submit) submit.clicked.connect(self.submitfunction) @@ -148,7 +156,11 @@ class edittrans(QMainWindow): return try: gobject.baseobject.textsource.sqlqueueput( - (gobject.baseobject.currenttext, "realtime_edit", text) + ( + gobject.baseobject.currenttext, + globalconfig["realtime_edit_target"], + text, + ) ) displayreskwargs = dict( name=globalconfig["fanyi"]["realtime_edit"]["name"], diff --git a/LunaTranslator/LunaTranslator/gui/settingpage1.py b/LunaTranslator/LunaTranslator/gui/settingpage1.py index 2e26d4d5..e6feb6b9 100644 --- a/LunaTranslator/LunaTranslator/gui/settingpage1.py +++ b/LunaTranslator/LunaTranslator/gui/settingpage1.py @@ -197,7 +197,7 @@ def exportchspatch(self): exe = f[0] if exe == "": return - exe = exe.replace("/", "\\") + exe = os.path.normpath(exe) doexportchspatch(exe, realgame) md5 = getfilemd5(exe) name = os.path.basename(exe).replace("." + os.path.basename(exe).split(".")[-1], "") @@ -292,7 +292,8 @@ def gethookembedgrid(self): ] ), globalconfig["embedded"], - "translator", + "translator_2", + internallist=list(globalconfig["fanyi"]), ), 5, ), diff --git a/LunaTranslator/LunaTranslator/gui/usefulwidget.py b/LunaTranslator/LunaTranslator/gui/usefulwidget.py index 83720396..57cb8408 100644 --- a/LunaTranslator/LunaTranslator/gui/usefulwidget.py +++ b/LunaTranslator/LunaTranslator/gui/usefulwidget.py @@ -368,13 +368,32 @@ def callbackwrap(d, k, call, _): print_exc() -def getsimplecombobox(lst, d, k, callback=None, fixedsize=False): +def comboboxcallbackwrap(internallist, d, k, call, _): + d[k] = internallist[_] + if call: + try: + call(_) + except: + print_exc() + + +def getsimplecombobox(lst, d, k, callback=None, fixedsize=False, internallist=None): s = QComboBox() s.addItems(lst) - if (k not in d) or (d[k] >= len(lst)): - d[k] = 0 - s.setCurrentIndex(d[k]) - s.currentIndexChanged.connect(functools.partial(callbackwrap, d, k, callback)) + + if internallist: + if (k not in d) or (d[k] not in internallist): + d[k] = internallist[0] + s.setCurrentIndex(internallist.index(d[k])) + s.currentIndexChanged.connect( + functools.partial(comboboxcallbackwrap, internallist, d, k, callback) + ) + else: + if (k not in d) or (d[k] >= len(lst)): + d[k] = 0 + s.setCurrentIndex(d[k]) + s.currentIndexChanged.connect(functools.partial(callbackwrap, d, k, callback)) + if fixedsize: s.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) return s diff --git a/LunaTranslator/LunaTranslator/myutils/config.py b/LunaTranslator/LunaTranslator/myutils/config.py index 55fe1fa4..ebe5c8d9 100644 --- a/LunaTranslator/LunaTranslator/myutils/config.py +++ b/LunaTranslator/LunaTranslator/myutils/config.py @@ -1,5 +1,6 @@ import json import os, time +from traceback import print_exc def tryreadconfig(path, default=None): @@ -137,7 +138,7 @@ def syncconfig(config1, default, drop=False, deep=0, skipdict=False): if key not in config1: config1[key] = default[key] - elif key == "name": + elif key in ("name", "tip"): config1[key] = default[key] elif key == "argstype": config1[key] = default[key] @@ -241,6 +242,70 @@ def _TR(k): return languageshow[k] +lastapppath = os.path.normpath(globalconfig["lastapppath"]) +thisapppath = os.path.normpath(os.getcwd()) + +if lastapppath is None: + lastapppath = thisapppath + + +def dynamicrelativepath(abspath): + if os.path.exists(abspath): + return abspath + _ = os.path.normpath(abspath) + if _.startswith(lastapppath): + np = thisapppath + _[len(lastapppath) :] + if os.path.exists(np): + return np + return abspath + + +def parsetarget(dict, key): + t = dict[key] + if type(t) != str: + raise Exception("not a path") + if "|" in t: + t = "|".join([dynamicrelativepath(_) for _ in t.split("|")]) + else: + t = dynamicrelativepath(t) + dict[key] = t + + +def autoparsedynamicpath(): + for dic, routine, target in ( + (globalconfig, ("cishu", "mdict", "args"), "path"), + (globalconfig, ("cishu", "mdict", "args"), "path_dir"), + (globalconfig, ("cishu", "edict", "args"), "path"), + (globalconfig, ("cishu", "linggesi", "args"), "path"), + (globalconfig, ("cishu", "xiaoxueguan", "args"), "path"), + (globalconfig, ("hirasetting", "mecab", "args"), "path"), + (globalconfig, ("hirasetting", "mecab", "args"), "path"), + (globalconfig, ("reader", "voiceroid2", "args"), "path"), + (translatorsetting, ("dreye", "args"), "路径"), + (translatorsetting, ("jb7", "args"), "路径"), + (translatorsetting, ("jb7", "args"), "用户词典3(可选)"), + (translatorsetting, ("jb7", "args"), "用户词典1(可选)"), + (translatorsetting, ("jb7", "args"), "用户词典2(可选)"), + (translatorsetting, ("kingsoft", "args"), "路径"), + (translatorsetting, ("ort_sp", "args"), "路径"), + (translatorsetting, ("premt", "args"), "sqlite文件"), + (translatorsetting, ("rengong", "args"), "json文件"), + ): + try: + for _k in routine: + dic = dic.get(_k, None) + if dic is None: + break + if dic is None: + continue + parsetarget(dic, target) + except: + print_exc() + + +autoparsedynamicpath() + + def _TRL(kk): x = [] for k in kk: @@ -249,6 +314,8 @@ def _TRL(kk): def saveallconfig(): + globalconfig["lastapppath"] = thisapppath + def safesave(fname, js): # 有时保存时意外退出,会导致config文件被清空 with open(fname + ".tmp", "w", encoding="utf-8") as ff: diff --git a/LunaTranslator/LunaTranslator/ocrengines/tesseract5.py b/LunaTranslator/LunaTranslator/ocrengines/tesseract5.py index ac19f6bf..9821ffaf 100644 --- a/LunaTranslator/LunaTranslator/ocrengines/tesseract5.py +++ b/LunaTranslator/LunaTranslator/ocrengines/tesseract5.py @@ -1,6 +1,5 @@ import os, uuid from myutils.config import _TR, ocrsetting -from myutils.ocrutil import binary2qimage from ocrengines.baseocrclass import baseocr from myutils.subproc import subproc_w diff --git a/LunaTranslator/files/defaultconfig/config.json b/LunaTranslator/files/defaultconfig/config.json index bd8ad513..1d2a6522 100644 --- a/LunaTranslator/files/defaultconfig/config.json +++ b/LunaTranslator/files/defaultconfig/config.json @@ -1,4 +1,5 @@ { + "lastapppath": null, "loadbalance": false, "loadbalance_oncenum": 1, "ocrafterrangeselect": true, @@ -469,7 +470,7 @@ }, "edittrans": { "use": false, - "tip": "编辑_预翻译", + "tip": "编辑_翻译记录", "icon": "fa.edit", "align": 0 }, @@ -1044,7 +1045,9 @@ "args": { "path": "", "distance": 0, - "priority": 100 + "priority": 100, + "stylehv": 0, + "path_dir": "" }, "argstype": { "path": { @@ -1054,6 +1057,11 @@ "multi": true, "filter": "*.mdx" }, + "path_dir": { + "type": "file", + "name": "遍历目录中的全部词典文件", + "dir": true + }, "distance": { "type": "intspin", "name": "模糊匹配_编辑距离", @@ -1067,6 +1075,14 @@ "min": 0, "max": 10000, "step": 1 + }, + "stylehv": { + "type": "combo", + "name": "样式", + "list": [ + "Tab", + "Flow" + ] } } } @@ -1573,9 +1589,10 @@ "use": false, "type": "pre", "color": "blue", - "name": "即时编辑" + "name": "实时编辑" } }, + "realtime_edit_target": "realtime_edit", "magpiepath": "", "minifollow": false, "movefollow": false, diff --git a/LunaTranslator/files/lang/ar.json b/LunaTranslator/files/lang/ar.json index 4c63e11b..a6fd819b 100644 --- a/LunaTranslator/files/lang/ar.json +++ b/LunaTranslator/files/lang/ar.json @@ -801,5 +801,8 @@ "工具按钮": "أداة زر", "界面主题": "واجهة الموضوع", "窗口行为": "نافذة السلوك", - "窗口特效": "نافذة المؤثرات الخاصة" + "窗口特效": "نافذة المؤثرات الخاصة", + "实时编辑": "في الوقت الحقيقي تحرير", + "翻译记录": "سجل الترجمة", + "遍历目录中的全部词典文件": "اجتياز جميع ملفات القاموس في الدليل" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/cht.json b/LunaTranslator/files/lang/cht.json index 59217351..59982bdc 100644 --- a/LunaTranslator/files/lang/cht.json +++ b/LunaTranslator/files/lang/cht.json @@ -801,5 +801,8 @@ "工具按钮": "工具按鈕", "界面主题": "介面主題", "窗口行为": "視窗行為", - "窗口特效": "視窗特效" + "窗口特效": "視窗特效", + "实时编辑": "實时編輯", + "翻译记录": "翻譯記錄", + "遍历目录中的全部词典文件": "遍歷目錄中的全部詞典檔案" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/en.json b/LunaTranslator/files/lang/en.json index 3d8a4094..beb4a9ae 100644 --- a/LunaTranslator/files/lang/en.json +++ b/LunaTranslator/files/lang/en.json @@ -801,5 +801,8 @@ "工具按钮": "Tool buttons", "界面主题": "Interface Theme", "窗口行为": "Window behavior", - "窗口特效": "Window effects" + "窗口特效": "Window effects", + "实时编辑": "Real time editing", + "翻译记录": "Translation records", + "遍历目录中的全部词典文件": "Traverse all dictionary files in the directory" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/es.json b/LunaTranslator/files/lang/es.json index 5773ad99..a5ca797a 100644 --- a/LunaTranslator/files/lang/es.json +++ b/LunaTranslator/files/lang/es.json @@ -801,5 +801,8 @@ "工具按钮": "Botones de herramientas", "界面主题": "Tema de la interfaz", "窗口行为": "Comportamiento de la ventana", - "窗口特效": "Efectos especiales de la ventana" + "窗口特效": "Efectos especiales de la ventana", + "实时编辑": "Edición en tiempo real", + "翻译记录": "Registros de traducción", + "遍历目录中的全部词典文件": "Recorrer todos los archivos del diccionario en el catálogo" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/fr.json b/LunaTranslator/files/lang/fr.json index c527814c..f2c98563 100644 --- a/LunaTranslator/files/lang/fr.json +++ b/LunaTranslator/files/lang/fr.json @@ -801,5 +801,8 @@ "工具按钮": "Le bouton outils", "界面主题": "Thème de l'interface", "窗口行为": "Comportement de la fenêtre", - "窗口特效": "Effets spéciaux de fenêtre" + "窗口特效": "Effets spéciaux de fenêtre", + "实时编辑": "Edit en temps réel", + "翻译记录": "Record de traduction", + "遍历目录中的全部词典文件": "Parcourir tous les fichiers de dictionnaire dans le Répertoire" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/it.json b/LunaTranslator/files/lang/it.json index 9545004b..2f6b4e97 100644 --- a/LunaTranslator/files/lang/it.json +++ b/LunaTranslator/files/lang/it.json @@ -801,5 +801,8 @@ "工具按钮": "Pulsanti strumenti", "界面主题": "Tema interfaccia", "窗口行为": "Comportamento delle finestre", - "窗口特效": "Effetti finestra" + "窗口特效": "Effetti finestra", + "实时编辑": "Modifica in tempo reale", + "翻译记录": "Record di traduzione", + "遍历目录中的全部词典文件": "Attraversa tutti i file del dizionario nella directory" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/ja.json b/LunaTranslator/files/lang/ja.json index 398a7ca3..ea63ba7c 100644 --- a/LunaTranslator/files/lang/ja.json +++ b/LunaTranslator/files/lang/ja.json @@ -801,5 +801,8 @@ "工具按钮": "ツールボタン", "界面主题": "インタフェーストピック", "窗口行为": "ウィンドウの動作", - "窗口特效": "ウィンドウ効果" + "窗口特效": "ウィンドウ効果", + "实时编辑": "リアルタイム編集", + "翻译记录": "翻訳レコード", + "遍历目录中的全部词典文件": "ディレクトリ内のすべての辞書ファイルを巡回" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/ko.json b/LunaTranslator/files/lang/ko.json index bf8d4566..4fffa2c8 100644 --- a/LunaTranslator/files/lang/ko.json +++ b/LunaTranslator/files/lang/ko.json @@ -801,5 +801,8 @@ "工具按钮": "도구 단추", "界面主题": "인터페이스 주제", "窗口行为": "창 동작", - "窗口特效": "창 효과" + "窗口特效": "창 효과", + "实时编辑": "실시간 편집", + "翻译记录": "번역 기록", + "遍历目录中的全部词典文件": "디렉토리의 모든 사전 파일 반복" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/pl.json b/LunaTranslator/files/lang/pl.json index a11de4b2..366484ef 100644 --- a/LunaTranslator/files/lang/pl.json +++ b/LunaTranslator/files/lang/pl.json @@ -801,5 +801,8 @@ "工具按钮": "Przyciski narzędziowe", "界面主题": "Motyw interfejsu", "窗口行为": "Zachowanie okna", - "窗口特效": "Efekty okien" + "窗口特效": "Efekty okien", + "实时编辑": "Edycja w czasie rzeczywistym", + "翻译记录": "Zapisy tłumaczeń", + "遍历目录中的全部词典文件": "Przejrzyj wszystkie pliki słownika w katalogu" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/ru.json b/LunaTranslator/files/lang/ru.json index 67ea1c93..e1943cba 100644 --- a/LunaTranslator/files/lang/ru.json +++ b/LunaTranslator/files/lang/ru.json @@ -801,5 +801,8 @@ "工具按钮": "Кнопки инструментов", "界面主题": "Интерфейсная тема", "窗口行为": "Поведение окна", - "窗口特效": "Специальные эффекты окон" + "窗口特效": "Специальные эффекты окон", + "实时编辑": "Редактирование в реальном времени", + "翻译记录": "Перевод записей", + "遍历目录中的全部词典文件": "Все словарные файлы в каталоге" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/th.json b/LunaTranslator/files/lang/th.json index 91ccad99..475e8737 100644 --- a/LunaTranslator/files/lang/th.json +++ b/LunaTranslator/files/lang/th.json @@ -801,5 +801,8 @@ "工具按钮": "ปุ่มเครื่องมือ", "界面主题": "ธีมอินเตอร์เฟซ", "窗口行为": "พฤติกรรมของหน้าต่าง", - "窗口特效": "เทคนิคพิเศษของหน้าต่าง" + "窗口特效": "เทคนิคพิเศษของหน้าต่าง", + "实时编辑": "แก้ไขแบบเรียลไทม์", + "翻译记录": "บันทึกการแปล", + "遍历目录中的全部词典文件": "ผ่านไฟล์พจนานุกรมทั้งหมดในไดเรกทอรี" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/tr.json b/LunaTranslator/files/lang/tr.json index c14ba2c5..edc09691 100644 --- a/LunaTranslator/files/lang/tr.json +++ b/LunaTranslator/files/lang/tr.json @@ -801,5 +801,8 @@ "工具按钮": "Araç düğmeleri", "界面主题": "Interface Theme", "窗口行为": "Pencere davranışları", - "窗口特效": "Pencere etkileri" + "窗口特效": "Pencere etkileri", + "实时编辑": "Gerçek zamanlı düzenleme", + "翻译记录": "Çeviri kayıtları", + "遍历目录中的全部词典文件": "Dizindeki bütün sözlük dosyalarını yolla" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/uk.json b/LunaTranslator/files/lang/uk.json index 5d4d84c8..ed638c93 100644 --- a/LunaTranslator/files/lang/uk.json +++ b/LunaTranslator/files/lang/uk.json @@ -801,5 +801,8 @@ "工具按钮": "Кнопки інструментів", "界面主题": "Тема інтерфейсу", "窗口行为": "Поведінка вікон", - "窗口特效": "Ефекти вікна" + "窗口特效": "Ефекти вікна", + "实时编辑": "Редагування реального часу", + "翻译记录": "Записи перекладів", + "遍历目录中的全部词典文件": "Пересунути всі файли словника у каталозі" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/vi.json b/LunaTranslator/files/lang/vi.json index da670de7..bef03faf 100644 --- a/LunaTranslator/files/lang/vi.json +++ b/LunaTranslator/files/lang/vi.json @@ -801,5 +801,8 @@ "工具按钮": "Nút công cụ", "界面主题": "Giao diện sắc thái", "窗口行为": "Ứng xử cửa sổ", - "窗口特效": "Hiệu ứng cửa sổ" + "窗口特效": "Hiệu ứng cửa sổ", + "实时编辑": "Chỉnh sửa thời gian thực", + "翻译记录": "Bản dịch", + "遍历目录中的全部词典文件": "Đi qua tất cả các tập tin từ điển trong thư mục" } \ No newline at end of file diff --git a/LunaTranslator/files/lang/zh.json b/LunaTranslator/files/lang/zh.json index 9cf55391..7ea64c9a 100644 --- a/LunaTranslator/files/lang/zh.json +++ b/LunaTranslator/files/lang/zh.json @@ -801,5 +801,8 @@ "工具按钮": "", "界面主题": "", "窗口行为": "", - "窗口特效": "" + "窗口特效": "", + "实时编辑": "", + "翻译记录": "", + "遍历目录中的全部词典文件": "" } \ No newline at end of file diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 7653a531..e46a8453 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -29,7 +29,7 @@ include(generate_product_version) set(VERSION_MAJOR 3) set(VERSION_MINOR 0) -set(VERSION_PATCH 4) +set(VERSION_PATCH 5) add_library(pch pch.cpp) target_precompile_headers(pch PUBLIC pch.h)