This commit is contained in:
恍兮惚兮 2024-08-07 00:18:10 +08:00
parent 0a0e53f5f2
commit 57c912f919
41 changed files with 425 additions and 251 deletions

View File

@ -42,6 +42,7 @@ from gui.codeacceptdialog import codeacceptdialog
from gui.inputdialog import (
noundictconfigdialog1,
yuyinzhidingsetting,
postconfigdialog2x,
autoinitdialog,
autoinitdialog_items,
postconfigdialog,
@ -591,7 +592,19 @@ def maybehavebutton(self, gameuid, post):
icon="fa.gear", callback=lambda: codeacceptdialog(self)
)
elif "args" in postprocessconfig[post]:
if isinstance(list(postprocessconfig[post]["args"].values())[0], dict):
if post == "stringreplace":
callback = functools.partial(
postconfigdialog2x,
self,
savehook_new_data[gameuid]["save_text_process_info"][
"postprocessconfig"
][post]["args"]["internal"],
savehook_new_data[gameuid]["save_text_process_info"][
"postprocessconfig"
][post]["name"],
["正则", "转义", "原文内容", "替换为"],
)
elif isinstance(list(postprocessconfig[post]["args"].values())[0], dict):
callback = functools.partial(
postconfigdialog,
self,
@ -1081,7 +1094,7 @@ class dialog_setting_game_internal(QWidget):
self,
savehook_new_data[gameuid]["tts_repair_regex"],
"语音修正",
["正则", "原文", "替换"],
["正则", "转义", "原文", "替换"],
),
icon="fa.gear",
),

View File

@ -36,40 +36,22 @@ class noundictconfigdialog1(LDialog):
self.model.insertRow(
row,
[
QStandardItem(),
QStandardItem(),
QStandardItem(item["key"]),
QStandardItem(item["value"]),
],
)
if "regex" not in item:
item["regex"] = False
if "escape" not in item:
item["escape"] = item["regex"]
self.table.setIndexWidget(
self.model.index(row, 0), getsimpleswitch(item, "regex")
)
def showmenu(self, table: TableViewW, _):
r = table.currentIndex().row()
if r < 0:
return
menu = QMenu(table)
up = LAction("上移")
down = LAction("下移")
copy = LAction("复制")
paste = LAction("粘贴")
menu.addAction(up)
menu.addAction(down)
menu.addAction(copy)
menu.addAction(paste)
action = menu.exec(table.cursor().pos())
if action == up:
table.moverank(-1)
elif action == down:
table.moverank(1)
elif action == copy:
table.copytable()
elif action == paste:
table.pastetable()
self.table.setIndexWidget(
self.model.index(row, 1), getsimpleswitch(item, "escape")
)
def __init__(self, parent, reflist, title, label) -> None:
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
@ -82,15 +64,15 @@ class noundictconfigdialog1(LDialog):
self.model.setHorizontalHeaderLabels(label)
table = TableViewW(self)
table.setModel(self.model)
table.horizontalHeader().setSectionResizeMode(3, QHeaderView.ResizeMode.Stretch)
table.horizontalHeader().setSectionResizeMode(2, QHeaderView.ResizeMode.Stretch)
table.horizontalHeader().setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
table.horizontalHeader().setSectionResizeMode(
1, QHeaderView.ResizeMode.ResizeToContents
)
table.horizontalHeader().setSectionResizeMode(
0, QHeaderView.ResizeMode.ResizeToContents
)
table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
table.customContextMenuRequested.connect(
functools.partial(self.showmenu, table)
)
table.setsimplemenu()
self.table = table
for row, item in enumerate(reflist):
@ -141,18 +123,39 @@ class noundictconfigdialog1(LDialog):
def __setindexwidget(self, index: QModelIndex, data):
if index.column() == 0:
self.table.setIndexWidget(index, getsimpleswitch(data, "regex"))
if index.column() == 1:
self.table.setIndexWidget(index, getsimpleswitch(data, "escape"))
def __getindexwidgetdata(self, index: QModelIndex):
return {"regex": self.table.indexWidgetX(index).isChecked()}
if index.column() == 0:
return {"regex": self.table.indexWidgetX(index).isChecked()}
if index.column() == 1:
return {"escape": self.table.indexWidgetX(index).isChecked()}
def apply(self):
self.table.dedumpmodel(1)
def __check(row):
k = self.model.item(row, 2).text()
if k == "":
return ""
switch = self.table.indexWidgetX(row, 0).isChecked()
es = self.table.indexWidgetX(row, 1).isChecked()
return (switch, es, k)
self.table.dedumpmodel(__check)
self.reflist.clear()
for row in range(self.model.rowCount()):
k = self.model.item(row, 1).text()
v = self.model.item(row, 2).text()
k = self.model.item(row, 2).text()
v = self.model.item(row, 3).text()
switch = self.table.indexWidgetX(row, 0)
self.reflist.append({"key": k, "value": v, "regex": switch.isChecked()})
es = self.table.indexWidgetX(row, 1)
self.reflist.append(
{
"key": k,
"value": v,
"escape": es.isChecked(),
"regex": switch.isChecked(),
}
)
def closeEvent(self, a0: QCloseEvent) -> None:
self.button.setFocus()
@ -261,24 +264,6 @@ class yuyinzhidingsetting(LDialog):
self.table.setIndexWidget(self.model.index(row, 1), com)
self.table.setIndexWidget(self.model.index(row, 3), self.createacombox(item))
def showmenu(self, table: TableViewW, _):
r = table.currentIndex().row()
if r < 0:
return
menu = QMenu(table)
up = LAction("上移")
down = LAction("下移")
menu.addAction(up)
menu.addAction(down)
action = menu.exec(table.cursor().pos())
if action == up:
table.moverank(-1)
elif action == down:
table.moverank(1)
def createacombox(self, config):
com = LFocusCombo()
com.addItems(["跳过", "默认", "选择声音"])
@ -348,10 +333,7 @@ class yuyinzhidingsetting(LDialog):
table.horizontalHeader().setSectionResizeMode(
0, QHeaderView.ResizeMode.ResizeToContents
)
table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
table.customContextMenuRequested.connect(
functools.partial(self.showmenu, table)
)
table.setsimplemenu({"copypaste": False})
self.table = table
for row, item in enumerate(reflist):
@ -695,38 +677,8 @@ class multicolorset(LDialog):
@Singleton_close
class postconfigdialog_(LDialog):
def closeEvent(self, a0: QCloseEvent) -> None:
if self.closeevent:
self.button.setFocus()
self.apply()
if self.closecallback:
self.closecallback()
def showmenu(self, table: TableViewW, pos):
r = table.currentIndex().row()
if r < 0:
return
menu = QMenu(table)
up = LAction("上移")
down = LAction("下移")
copy = LAction("复制")
paste = LAction("粘贴")
menu.addAction(up)
menu.addAction(down)
menu.addAction(copy)
menu.addAction(paste)
action = menu.exec(table.cursor().pos())
if action == up:
table.moverank(-1)
elif action == down:
table.moverank(1)
elif action == copy:
table.copytable()
elif action == paste:
table.pastetable()
self.button.setFocus()
self.apply()
def apply(self):
self.table.dedumpmodel(0)
@ -747,14 +699,9 @@ class postconfigdialog_(LDialog):
else:
raise
def __init__(
self, parent, configdict, title, headers, closecallback=None, dictkeys=None
) -> None:
def __init__(self, parent, configdict, title, headers, dictkeys=None) -> None:
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
self.closecallback = closecallback
self.setWindowTitle(title)
# self.setWindowModality(Qt.ApplicationModal)
self.closeevent = False
formLayout = QVBoxLayout(self) # 配置layout
self.dictkeys = dictkeys
model = LStandardItemModel(len(configdict), 1, self)
@ -781,10 +728,7 @@ class postconfigdialog_(LDialog):
table.setModel(model)
table.setWordWrap(False)
table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
table.customContextMenuRequested.connect(
functools.partial(self.showmenu, table)
)
table.setsimplemenu()
button = threebuttons(texts=["添加行", "删除行", "上移", "下移", "立即应用"])
self.table = table
button.btn1clicked.connect(table.insertplainrow)
@ -796,7 +740,6 @@ class postconfigdialog_(LDialog):
self.button = button
self.model = model
self.configdict = configdict
self.closeevent = True
search = QHBoxLayout()
searchcontent = QLineEdit()
search.addWidget(searchcontent)
@ -827,3 +770,7 @@ class postconfigdialog_(LDialog):
def postconfigdialog(parent, configdict, title, header):
postconfigdialog_(parent, configdict, title, header)
def postconfigdialog2x(parent, reflist, title, header):
noundictconfigdialog1(parent, reflist, title, header)

View File

@ -16,7 +16,12 @@ from gui.usefulwidget import (
getvboxwidget,
makesubtab_lazy,
)
from gui.inputdialog import postconfigdialog, autoinitdialog, autoinitdialog_items
from gui.inputdialog import (
postconfigdialog,
autoinitdialog,
autoinitdialog_items,
postconfigdialog2x,
)
def delaysetcomparetext(self, s):
@ -101,7 +106,16 @@ def setTab7_lazy(self, basel):
callback=lambda: codeacceptdialog(self),
)
elif "args" in postprocessconfig[post]:
if isinstance(list(postprocessconfig[post]["args"].values())[0], dict):
if post=='stringreplace':
callback = functools.partial(
postconfigdialog2x,
self,
postprocessconfig[post]["args"]['internal'],
postprocessconfig[post]["name"],
["正则", "转义", "原文内容", "替换为"],
)
elif isinstance(list(postprocessconfig[post]["args"].values())[0], dict):
callback = functools.partial(
postconfigdialog,
self,

View File

@ -234,7 +234,7 @@ def setTab5lz(self):
self,
globalconfig["ttscommon"]["tts_repair_regex"],
"语音修正",
["正则", "原文", "替换"],
["正则",'转义', "原文", "替换"],
),
icon="fa.gear",
),

View File

@ -95,6 +95,36 @@ class TableViewW(QTableView):
super().__init__(*argc)
self.setSelectionMode(QAbstractItemView.SelectionMode.ContiguousSelection)
def showmenu(self, info, pos):
r = self.currentIndex().row()
if r < 0:
return
menu = QMenu(self)
up = LAction("上移")
down = LAction("下移")
copy = LAction("复制")
paste = LAction("粘贴")
menu.addAction(up)
menu.addAction(down)
if info.get("copypaste", True):
menu.addAction(copy)
menu.addAction(paste)
action = menu.exec(self.cursor().pos())
if action == up:
self.moverank(-1)
elif action == down:
self.moverank(1)
elif action == copy:
self.copytable()
elif action == paste:
self.pastetable()
def setsimplemenu(self, info=None):
self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
if info is None:
info = {}
self.customContextMenuRequested.connect(functools.partial(self.showmenu, info))
def insertplainrow(self, row=0):
self.model().insertRow(
row, [QStandardItem() for _ in range(self.model().columnCount())]
@ -106,11 +136,15 @@ class TableViewW(QTableView):
dedump = set()
needremoves = []
for row in range(rows):
k = self.safetext(row, col)
if isinstance(col, int):
k = self.safetext(row, col)
elif callable(col):
k = col(row)
if k == "" or k in dedump:
needremoves.append(row)
continue
dedump.add(k)
for row in reversed(needremoves):
self.model().removeRow(row)

View File

@ -2,7 +2,7 @@ import os, hashlib, queue, gobject
from myutils.proxy import getproxy
from threading import Thread
from myutils.commonbase import proxysession
from myutils.config import globalconfig, savehook_new_data
from myutils.config import globalconfig, savehook_new_data, namemapcast
from traceback import print_exc
from requests import RequestException
@ -176,11 +176,21 @@ class common:
if _url not in _urls:
savehook_new_data[gameuid]["relationlinks"].append((_vis, _url))
if namemap:
if (len(savehook_new_data[gameuid]["namemap"]) == 0) or (
not savehook_new_data[gameuid]["vndbnamemap_modified"]
):
savehook_new_data[gameuid]["namemap"] = namemap
savehook_new_data[gameuid]["vndbnamemap_modified"] = False
dedump = set()
for _ in savehook_new_data[gameuid]["namemap2"]:
dedump.add(_.get("key", ""))
namemap = namemapcast(namemap)
for name in namemap:
if name in dedump:
continue
savehook_new_data[gameuid]["namemap2"].append(
{
"key": name,
"value": namemap[name],
"regex": False,
"escape": False,
}
)
for _ in webtags:
if _ in savehook_new_data[gameuid]["webtags"]:

View File

@ -210,7 +210,6 @@ class searcher(common):
elif isinstance(__, dict):
developers.append(__["v"])
return {
# "namemap": namemap,
"title": response["name"],
"imagepath_all": [imagepath],
"webtags": vndbtags,

View File

@ -113,7 +113,6 @@ class searcher(common):
print(imags1)
return {
# "namemap": namemap,
"title": title,
"imagepath_all": [self.dispatchdownloadtask(_) for _ in imags1 + imags2],
"webtags": tags,

View File

@ -171,7 +171,6 @@ class searcher(common):
inner = simplehtmlparser(response.text, "div", '<div ref="product_slider_data"')
return {
# "namemap": namemap,
"title": title,
"imagepath_all": [
self.dispatchdownloadtask(_.replace("js-", "jp-")) for _ in imags2

View File

@ -185,7 +185,6 @@ class searcher(common):
+ [data.get("background_raw", None)]
)
return {
# "namemap": namemap,
"title": data["name"],
"imagepath_all": [
self.dispatchdownloadtask(re.sub("\\?t=(\\d+)", "", _)) for _ in images

View File

@ -4,6 +4,19 @@ from traceback import print_exc
from qtsymbols import *
def namemapcast(namemap):
bettermap = namemap.copy()
for k, v in namemap.items():
for sp in ["", " "]:
spja = k.split(sp)
spen = v.split(" ")
if len(spja) == len(spen) and len(spen) > 1:
for i in range(len(spja)):
if len(spja[i]) >= 2:
bettermap[spja[i]] = spen[i]
return bettermap
def tryreadconfig(path, default=None):
path = os.path.join("userconfig", path)
try:
@ -165,9 +178,9 @@ def getdefaultsavehook(title=None):
"gptpromptdict_use": False,
"gptpromptdict_merge": False,
"gptpromptdict": [],
"vndbnamemap_modified": False,
# 元数据
"namemap": {}, # 人名翻译映射vndb独占用于优化翻译
"namemap2": [],
# "namemap": {}, # 人名翻译映射vndb独占用于优化翻译
#
# "vid": 0,
# "bgmsid": 0,
@ -187,6 +200,11 @@ def getdefaultsavehook(title=None):
return default
needcast = False
if "xxxcast" not in globalconfig:
globalconfig["xxxcast"] = True
needcast = True
# fmt: off
oldlanguage = ["zh","ja","en","ru","es","ko","fr","cht","vi","tr","pl","uk","it","ar","th","bo","de","sv","nl"]
# fmt: on
@ -212,6 +230,14 @@ for gameconfig in savehook_new_data.values():
if ("private_srclang" in gameconfig) and ("private_srclang_2" not in gameconfig):
gameconfig["private_srclang_2"] = oldlanguage[gameconfig["private_srclang"]]
gameconfig["private_tgtlang_2"] = oldlanguage[gameconfig["private_tgtlang"]]
if "namemap" in gameconfig:
gameconfig["namemap2"] = []
for k, v in namemapcast(gameconfig.pop("namemap")).items():
gameconfig["namemap2"].append(
{"key": k, "value": v, "regex": False, "escape": False}
)
for __k, __v in _dfsavehook.items():
if __k not in gameconfig:
if isinstance(__v, (list, dict)):
@ -221,6 +247,84 @@ for gameconfig in savehook_new_data.values():
if not gameconfig.get("leuse", True):
gameconfig.pop("leuse")
gameconfig["launch_method"] = "direct"
if needcast:
if "save_text_process_info" not in gameconfig:
continue
if "rank" not in gameconfig["save_text_process_info"]:
continue
if "postprocessconfig" not in gameconfig["save_text_process_info"]:
continue
items = []
try:
ifuse = False
for post in gameconfig["save_text_process_info"]["rank"]:
# 简单
if post == "_7":
ifuse = (
ifuse
or gameconfig["save_text_process_info"]["postprocessconfig"][
"_7"
]["use"]
)
gameconfig["save_text_process_info"]["postprocessconfig"]["_7"][
"use"
] = False
for k, v in gameconfig["save_text_process_info"][
"postprocessconfig"
]["_7"]["args"]["替换内容"].items():
items.append(
{"regex": False, "escape": False, "key": k, "value": v}
)
if post == "_7_zhuanyi":
ifuse = (
ifuse
or gameconfig["save_text_process_info"]["postprocessconfig"][
"_7_zhuanyi"
]["use"]
)
gameconfig["save_text_process_info"]["postprocessconfig"][
"_7_zhuanyi"
]["use"] = False
for k, v in gameconfig["save_text_process_info"][
"postprocessconfig"
]["_7_zhuanyi"]["args"]["替换内容"].items():
items.append(
{"regex": False, "escape": True, "key": k, "value": v}
)
# 正则
if post == "_8":
ifuse = (
ifuse
or gameconfig["save_text_process_info"]["postprocessconfig"][
"_8"
]["use"]
)
gameconfig["save_text_process_info"]["postprocessconfig"]["_8"][
"use"
] = False
for k, v in gameconfig["save_text_process_info"][
"postprocessconfig"
]["_8"]["args"]["替换内容"].items():
items.append(
{"regex": True, "escape": True, "key": k, "value": v}
)
if len(items):
gameconfig["save_text_process_info"]["rank"].append("stringreplace")
gameconfig["save_text_process_info"]["postprocessconfig"][
"stringreplace"
] = {
"args": {"internal": items},
"use": ifuse,
"name": "字符串替换",
}
except:
print_exc()
if "global_namemap" in globalconfig:
globalconfig["global_namemap2"] = []
for k, v in namemapcast(globalconfig.pop("global_namemap")).items():
globalconfig["global_namemap2"].append(
{"key": k, "value": v, "regex": False, "escape": False}
)
class __uid2gamepath:
@ -325,6 +429,35 @@ if ocrerrorfix == {}:
ocrerrorfix = ocrerrorfixdefault
syncconfig(postprocessconfig, defaultpost, True, 3)
if needcast:
ifuse = False
for post in globalconfig["postprocess_rank"]:
# 简单
if post == "_7":
ifuse = ifuse or postprocessconfig["_7"]["use"]
postprocessconfig["_7"]["use"] = False
for k, v in postprocessconfig["_7"]["args"]["替换内容"].items():
postprocessconfig["stringreplace"]["args"]["internal"].append(
{"regex": False, "escape": False, "key": k, "value": v}
)
if post == "_7_zhuanyi":
ifuse = ifuse or postprocessconfig["_7_zhuanyi"]["use"]
postprocessconfig["_7_zhuanyi"]["use"] = False
for k, v in postprocessconfig["_7_zhuanyi"]["args"]["替换内容"].items():
postprocessconfig["stringreplace"]["args"]["internal"].append(
{"regex": False, "escape": True, "key": k, "value": v}
)
# 正则
if post == "_8":
ifuse = ifuse or postprocessconfig["_8"]["use"]
postprocessconfig["_8"]["use"] = False
for k, v in postprocessconfig["_8"]["args"]["替换内容"].items():
postprocessconfig["stringreplace"]["args"]["internal"].append(
{"regex": True, "escape": True, "key": k, "value": v}
)
postprocessconfig["stringreplace"]["use"] = ifuse
for key in defaultglobalconfig["toolbutton"]["buttons"]:
if key not in globalconfig["toolbutton"]["rank2"]:
globalconfig["toolbutton"]["rank2"].append(key)

View File

@ -2,7 +2,7 @@ import re, codecs, inspect
from traceback import print_exc
from collections import Counter
import gobject
from myutils.utils import checkchaos, checkmd5reloadmodule, LRUCache, getlangsrc
from myutils.utils import checkchaos, checkmd5reloadmodule, LRUCache, getlangsrc, parsemayberegexreplace
from myutils.config import (
postprocessconfig,
globalconfig,
@ -219,6 +219,11 @@ def _92_f(line):
return line
def stringreplace(line, args):
filters = args["internal"]
return parsemayberegexreplace(filters, line)
def _7_zhuanyi_f(line, args):
filters = args["替换内容"]
for fil in filters:
@ -370,6 +375,7 @@ def POSTSOLVE(line):
"length_threshold": length_threshold,
"lines_threshold": lines_threshold,
"_11": _mypostloader,
"stringreplace": stringreplace,
}
useranklist = globalconfig["postprocess_rank"]
usedpostprocessconfig = postprocessconfig

View File

@ -493,17 +493,34 @@ class autosql(sqlite3.Connection):
@tryprint
def parsemayberegexreplace(dic: dict, res: str):
for item in dic:
if item["regex"]:
res = re.sub(
codecs.escape_decode(bytes(item["key"], "utf-8"))[0].decode("utf-8"),
codecs.escape_decode(bytes(item["value"], "utf-8"))[0].decode("utf-8"),
res,
)
def parsemayberegexreplace(lst: list, line: str):
for fil in lst:
regex = fil.get("regex", False)
escape = fil.get("escape", regex)
key = fil.get("key", "")
value = fil.get("value", "")
if key == "":
continue
if regex:
if escape:
line = re.sub(
codecs.escape_decode(bytes(key, "utf-8"))[0].decode("utf-8"),
codecs.escape_decode(bytes(value, "utf-8"))[0].decode("utf-8"),
)
else:
line = re.sub(key, value)
else:
res = res.replace(item["key"], item["value"])
return res
if escape:
line = line.replace(
codecs.escape_decode(bytes(key, "utf-8"))[0].decode("utf-8"),
codecs.escape_decode(bytes(value, "utf-8"))[0].decode("utf-8"),
)
else:
line = line.replace(key, value)
return line
def checkpostlangmatch(name):

View File

@ -16,33 +16,6 @@ class noundictconfigdialog(LDialog):
self.button.setFocus()
self.apply()
def showmenu(self, table: TableViewW, pos):
r = table.currentIndex().row()
if r < 0:
return
menu = QMenu(table)
up = LAction("上移")
down = LAction("下移")
copy = LAction("复制")
paste = LAction("粘贴")
menu.addAction(up)
menu.addAction(down)
menu.addAction(copy)
menu.addAction(paste)
action = menu.exec(table.cursor().pos())
if action == up:
table.moverank(-1)
elif action == down:
table.moverank(1)
elif action == copy:
table.copytable()
elif action == paste:
table.pastetable()
def apply(self):
rows = self.model.rowCount()
self.configdict.clear()
@ -84,10 +57,7 @@ class noundictconfigdialog(LDialog):
table = TableViewW(self)
table.setModel(model)
table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
table.customContextMenuRequested.connect(
functools.partial(self.showmenu, table)
)
table.setsimplemenu()
button = threebuttons(texts=["添加行", "删除行", "上移", "下移", "立即应用"])
self.table = table
@ -154,34 +124,6 @@ class noundictconfigdialog_private(LDialog):
self.button.setFocus()
self.apply()
def showmenu(self, table: TableViewW, pos):
r = table.currentIndex().row()
if r < 0:
return
menu = QMenu(table)
up = LAction("上移")
down = LAction("下移")
copy = LAction("复制")
paste = LAction("粘贴")
menu.addAction(up)
menu.addAction(down)
menu.addAction(copy)
menu.addAction(paste)
action = menu.exec(table.cursor().pos())
if action == up:
table.moverank(-1)
elif action == down:
table.moverank(1)
elif action == copy:
table.copytable()
elif action == paste:
table.pastetable()
def apply(self):
self.table.dedumpmodel(0)
rows = self.model.rowCount()
@ -214,10 +156,7 @@ class noundictconfigdialog_private(LDialog):
table = TableViewW(self)
table.setModel(model)
table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.Stretch)
table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
table.customContextMenuRequested.connect(
functools.partial(self.showmenu, table)
)
table.setsimplemenu()
button = threebuttons(texts=["添加行", "删除行", "上移", "下移", "立即应用"])
self.table = table
button.btn1clicked.connect(table.insertplainrow)

View File

@ -13,7 +13,7 @@ class Process:
parent_window,
transerrorfixdictconfig["dict_v2"],
"翻译结果修正_设置",
["正则", "翻译", "替换"],
["正则",'转义', "翻译", "替换"],
)
@staticmethod
@ -23,7 +23,7 @@ class Process:
parent_window,
savehook_new_data[gameuid]["transerrorfix"],
"翻译结果修正_设置",
["正则", "翻译", "替换"],
["正则",'转义', "翻译", "替换"],
).setWindowIcon(getExeIcon(uid2gamepath[gameuid], cache=True))
def process_after(self, res, mp1):

View File

@ -1,6 +1,6 @@
from myutils.config import globalconfig, savehook_new_data, uid2gamepath
from myutils.utils import postusewhich
from gui.inputdialog import postconfigdialog_
from myutils.utils import postusewhich, parsemayberegexreplace
from gui.inputdialog import noundictconfigdialog1
import gobject, json, functools
from myutils.hwnd import getExeIcon
@ -10,29 +10,22 @@ class Process:
@staticmethod
def get_setting_window(parent_window):
return (
postconfigdialog_(
noundictconfigdialog1(
parent_window,
globalconfig["global_namemap"],
globalconfig["global_namemap2"],
"专有名词翻译_直接替换_设置",
["原文", "翻译"],
["正则",'转义', "原文", "翻译"],
),
)
@staticmethod
def get_setting_window_gameprivate(parent_window, gameuid):
def checkchange(gameuid, __):
__2 = json.dumps(savehook_new_data[gameuid]["namemap"])
if __ != __2:
savehook_new_data[gameuid]["vndbnamemap_modified"] = True
__ = json.dumps(savehook_new_data[gameuid]["namemap"])
postconfigdialog_(
noundictconfigdialog1(
parent_window,
savehook_new_data[gameuid]["namemap"],
savehook_new_data[gameuid]["namemap2"],
"专有名词翻译_直接替换_设置",
["原文", "翻译"],
closecallback=functools.partial(checkchange, gameuid, __),
["正则",'转义', "原文", "翻译"],
).setWindowIcon(getExeIcon(uid2gamepath[gameuid], cache=True))
@property
@ -42,20 +35,17 @@ class Process:
def usewhich(self) -> dict:
which = postusewhich("vndbnamemap")
if which == 1:
return globalconfig["global_namemap"]
return globalconfig["global_namemap2"]
elif which == 2:
gameuid = gobject.baseobject.textsource.gameuid
return savehook_new_data[gameuid]["namemap"]
return savehook_new_data[gameuid]["namemap2"]
elif which == 3:
_ = {}
_.update(globalconfig["global_namemap"])
gameuid = gobject.baseobject.textsource.gameuid
_.update(savehook_new_data[gameuid]["namemap"])
return _
return savehook_new_data[gameuid]["namemap2"] + globalconfig["global_namemap2"]
def process_before(self, s):
namemap = self.usewhich()
s=parsemayberegexreplace(namemap,s)
bettermap = {}
for k, v in namemap.items():
for sp in ["", " "]:

View File

@ -499,7 +499,7 @@
1200,
600
],
"global_namemap": {},
"global_namemap2": [],
"settingfontsize": 12,
"filter_chaos_code": false,
"accept_encoding": [

View File

@ -1,4 +1,11 @@
{
"stringreplace": {
"use": false,
"name": "字符串替换",
"args": {
"internal":[]
}
},
"_remove_non_shiftjis_char": {
"use": false,
"name": "过滤文本中的非日语字符集字符"
@ -157,21 +164,21 @@
},
"_7": {
"use": true,
"name": "简单字符串替换",
"name": "!_不推荐使用_简单字符串替换_!",
"args": {
"替换内容": {}
}
},
"_7_zhuanyi": {
"use": true,
"name": "转义字符串替换",
"name": "!_不推荐使用_转义字符串替换_!",
"args": {
"替换内容": {}
}
},
"_8": {
"use": false,
"name": "正则表达式替换",
"name": "!_不推荐使用_正则表达式替换_!",
"args": {
"替换内容": {}
}

View File

@ -849,5 +849,8 @@
"语音指定": "صوت محدد",
"指定为": "تعيين",
"跳过": "تخطي",
"作用于翻译": "العمل على الترجمة"
"作用于翻译": "العمل على الترجمة",
"字符串替换": "سلسلة استبدال",
"转义": "هروب",
"不推荐使用": "لا ينصح باستخدام"
}

View File

@ -849,5 +849,8 @@
"语音指定": "語音指定",
"指定为": "指定為",
"跳过": "跳過",
"作用于翻译": "作用於翻譯"
"作用于翻译": "作用於翻譯",
"字符串替换": "字串替換",
"转义": "轉義",
"不推荐使用": "不推薦使用"
}

View File

@ -849,5 +849,8 @@
"语音指定": "Označení hlasu",
"指定为": "Určeno jako",
"跳过": "přeskočit",
"作用于翻译": "Použití na překlad"
"作用于翻译": "Použití na překlad",
"字符串替换": "Náhrada řetězce",
"转义": "Útěk",
"不推荐使用": "Nedoporučuje se k použití"
}

View File

@ -849,5 +849,8 @@
"语音指定": "Sprachbezeichnung",
"指定为": "Bestimmt als",
"跳过": "überspringen",
"作用于翻译": "Auf Übersetzungen angewendet"
"作用于翻译": "Auf Übersetzungen angewendet",
"字符串替换": "Zeichenfolgenersatz",
"转义": "Flucht",
"不推荐使用": "Nicht empfohlen für die Anwendung"
}

View File

@ -849,5 +849,8 @@
"语音指定": "Voice designation",
"指定为": "Designated as",
"跳过": "skip",
"作用于翻译": "Applied to translation"
"作用于翻译": "Applied to translation",
"字符串替换": "String replacement",
"转义": "Escaping",
"不推荐使用": "Not recommended for use"
}

View File

@ -849,5 +849,8 @@
"语音指定": "Designación de voz",
"指定为": "Designado como",
"跳过": "Saltar",
"作用于翻译": "Actuar sobre la traducción"
"作用于翻译": "Actuar sobre la traducción",
"字符串替换": "Reemplazo de cadenas",
"转义": "Transliteración",
"不推荐使用": "No se recomienda usar"
}

View File

@ -849,5 +849,8 @@
"语音指定": "Désignation vocale",
"指定为": "Désigné comme",
"跳过": "Sauter",
"作用于翻译": "Agir sur la traduction"
"作用于翻译": "Agir sur la traduction",
"字符串替换": "Remplacement de chaîne",
"转义": "échappement",
"不推荐使用": "Utilisation non recommandée"
}

View File

@ -849,5 +849,8 @@
"语音指定": "Denominazione vocale",
"指定为": "Designato come",
"跳过": "salta",
"作用于翻译": "Applicato alla traduzione"
"作用于翻译": "Applicato alla traduzione",
"字符串替换": "Sostituzione stringa",
"转义": "Scappare",
"不推荐使用": "Non raccomandato per l'uso"
}

View File

@ -849,5 +849,8 @@
"语音指定": "音声指定",
"指定为": "指定#シテイ#",
"跳过": "スキップ",
"作用于翻译": "翻訳に役立つ"
"作用于翻译": "翻訳に役立つ",
"字符串替换": "文字列置換",
"转义": "エスケープ",
"不推荐使用": "使用を推奨しない"
}

View File

@ -849,5 +849,8 @@
"语音指定": "음성 지정",
"指定为": "다음으로 지정",
"跳过": "건너뛰기",
"作用于翻译": "번역에 적용"
"作用于翻译": "번역에 적용",
"字符串替换": "문자열 대체",
"转义": "전의",
"不推荐使用": "권장하지 않음"
}

View File

@ -849,5 +849,8 @@
"语音指定": "Stembepaling",
"指定为": "Aangeduid als",
"跳过": "overslaan",
"作用于翻译": "Toegepast op vertaling"
"作用于翻译": "Toegepast op vertaling",
"字符串替换": "Vervanging van tekenreeks",
"转义": "Ontsnappen",
"不推荐使用": "Niet aanbevolen voor gebruik"
}

View File

@ -849,5 +849,8 @@
"语音指定": "Oznaczenie głosu",
"指定为": "Wyznaczony jako",
"跳过": "pominięcie",
"作用于翻译": "Zastosowanie do tłumaczenia"
"作用于翻译": "Zastosowanie do tłumaczenia",
"字符串替换": "Zastąpienie ciągu",
"转义": "Ucieczka",
"不推荐使用": "Nie zaleca się stosowania"
}

View File

@ -849,5 +849,8 @@
"语音指定": "Designação da voz",
"指定为": "Designado como",
"跳过": "pular",
"作用于翻译": "Aplicado à tradução"
"作用于翻译": "Aplicado à tradução",
"字符串替换": "Substituição de strings",
"转义": "Escapar",
"不推荐使用": "Não recomendado para utilização"
}

View File

@ -849,5 +849,8 @@
"语音指定": "Голосовое назначение",
"指定为": "Назначено",
"跳过": "Пропустить",
"作用于翻译": "Роль перевода"
"作用于翻译": "Роль перевода",
"字符串替换": "Замена строки",
"转义": "Транслитерация",
"不推荐使用": "Не рекомендуется использовать"
}

View File

@ -849,5 +849,8 @@
"语音指定": "Röstbeteckning",
"指定为": "Utnämnd som",
"跳过": "hoppa över",
"作用于翻译": "Tillämpad på översättning"
"作用于翻译": "Tillämpad på översättning",
"字符串替换": "Strängersättning",
"转义": "Flykt",
"不推荐使用": "Rekommenderas inte för användning"
}

View File

@ -849,5 +849,8 @@
"语音指定": "การกำหนดเสียง",
"指定为": "กำหนดให้เป็น",
"跳过": "ข้าม",
"作用于翻译": "บทบาทในการแปล"
"作用于翻译": "บทบาทในการแปล",
"字符串替换": "การแทนที่สตริง",
"转义": "แปลความหมาย",
"不推荐使用": "ไม่แนะนำให้ใช้"
}

View File

@ -849,5 +849,8 @@
"语音指定": "Ses tasarımı",
"指定为": "Şöyle tasarlanmıştır",
"跳过": "atla",
"作用于翻译": "Çevirmeye uygulandı"
"作用于翻译": "Çevirmeye uygulandı",
"字符串替换": "String Replacement",
"转义": "Kaçmak",
"不推荐使用": "Kullanmak için önerilmez"
}

View File

@ -849,5 +849,8 @@
"语音指定": "Визначення голосу",
"指定为": "Визначено як",
"跳过": "пропустити",
"作用于翻译": "Застосовано до перекладу"
"作用于翻译": "Застосовано до перекладу",
"字符串替换": "Заміна рядків",
"转义": "Бег",
"不推荐使用": "Не рекомендується використовувати"
}

View File

@ -849,5 +849,8 @@
"语音指定": "Chỉ định giọng nói",
"指定为": "Xác định là",
"跳过": "Bỏ qua",
"作用于翻译": "Hành động để dịch"
"作用于翻译": "Hành động để dịch",
"字符串替换": "Thay thế chuỗi",
"转义": "Thoát",
"不推荐使用": "Không khuyến khích sử dụng"
}

View File

@ -849,5 +849,8 @@
"语音指定": "",
"指定为": "",
"跳过": "",
"作用于翻译": ""
"作用于翻译": "",
"字符串替换": "",
"转义": "",
"不推荐使用": ""
}

View File

@ -85,19 +85,19 @@
**18. 简单字符串替换**
~~**18. 简单字符串替换**~~ 过时的,不再推荐使用,请改用**字符串替换**
不止是替换,主要也可以用来过滤。可以将固定的若干乱码字符、反复刷新的倒三角字符等通过替换成空白来进行过滤。
~~不止是替换,主要也可以用来过滤。可以将固定的若干乱码字符、反复刷新的倒三角字符等通过替换成空白来进行过滤。~~
**19. 转义字符串替换**
~~**19. 转义字符串替换**~~ 过时的,不再推荐使用,请改用**字符串替换**
主要是可以支持`\n`来表示换行符,从而实现可以过滤仅在换行符前后出现的字符。
~~主要是可以支持`\n`来表示换行符,从而实现可以过滤仅在换行符前后出现的字符。~~
**20. 正则表达式替换**
~~**20. 正则表达式替换**~~ 过时的,不再推荐使用,请改用**字符串替换**
注:**这个输入的内容都是转义字符串**也就是说比如你在外面写python代码`re.sub(r"\n","")`来测试再填入,想把`\n`这两个字符替换掉,实际上这里会替换掉**换行符**,你想在外面测试的话请用`re.sub("\\n","")`这样来测试
~~注:**这个输入的内容都是转义字符串**也就是说比如你在外面写python代码`re.sub(r"\n","")`来测试再填入,想把`\n`这两个字符替换掉,实际上这里会替换掉**换行符**,你想在外面测试的话请用`re.sub("\\n","")`这样来测试~~
**21. 去除重复行_ABCDBCDCDD->ABCD**
@ -123,3 +123,11 @@ def POSTSOLVE(line):
# 请在这里编写自定义处理
return line
```
**25. 字符串替换**
原`简单字符串替换` `转义字符串替换` `正则表达式替换`的整合,同时可设置`正则`和`转义`两个选项。
原正则表达式替换存在一定缺陷,输入的表达式是默认转义的,因此输入起来非常麻烦。
该处理添加时将默认使用简单替换,激活正则后将使用字符串字面量进行正则处理。仅激活转义后才使用转义字符串进行处理。
旧的处理词典在更新后首次运行将自动迁移到新的处理词典中。在之后的很长一段时间中,旧的处理不会被删除,但不会再进行维护。

View File

@ -2,7 +2,7 @@
#### **1. 专有名词翻译 直接替换**
这种方法会在翻译之前,直接用译文将原文进行替换。
这种方法会在翻译之前,直接用译文将原文进行替换。支持使用`正则` `转义`进行更复杂的替换。
当游戏从VNDB加载元数据时会查询游戏中的人名信息作为预设的词典。不过译文由于VNDB的原因是英文可以自行进行修改译文成中文。

View File

@ -28,8 +28,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/version)
include(generate_product_version)
set(VERSION_MAJOR 5)
set(VERSION_MINOR 22)
set(VERSION_PATCH 2)
set(VERSION_MINOR 23)
set(VERSION_PATCH 0)
add_library(pch pch.cpp)
target_precompile_headers(pch PUBLIC pch.h)