This commit is contained in:
恍兮惚兮 2024-06-18 17:44:02 +08:00
parent 48f9afae8e
commit 8c6c4f2441
38 changed files with 1699 additions and 1104 deletions

View File

@ -908,8 +908,29 @@ class MAINUI:
self.__currentexe = None
except:
print_exc()
@threader
def clickwordcallback(self,word, append):
if globalconfig["usewordorigin"] == False:
word = word["orig"]
else:
word = word.get("origorig", word["orig"])
if globalconfig["usecopyword"]:
if append:
winsharedutils.clipboard_set(
winsharedutils.clipboard_get() + word
)
else:
winsharedutils.clipboard_set(word)
if globalconfig["usesearchword"]:
self.searchwordW.getnewsentencesignal.emit(
word, append
)
def setshowintab_checked(self, widget):
try:
self.translation_ui
except:
return
if widget == self.translation_ui:
winsharedutils.showintab(int(widget.winId()), globalconfig["showintab"])
return

View File

@ -249,9 +249,7 @@ class autoinitdialog(QDialog):
)
lineW.rejected.connect(self.close)
lineW.accepted.connect(
functools.partial(
save, None if "callback" not in line else line["callback"]
)
functools.partial(save, line.get("callback", None))
)
lineW.button(QDialogButtonBox.StandardButton.Ok).setText(_TR("确定"))
@ -281,17 +279,17 @@ class autoinitdialog(QDialog):
regist.append([dd, key, lineW.isChecked])
elif line["type"] == "spin":
lineW = FocusDoubleSpin()
lineW.setMinimum(0 if "min" not in line else line["min"])
lineW.setMaximum(100 if "max" not in line else line["max"])
lineW.setSingleStep(0.1 if "step" not in line else line["step"])
lineW.setMinimum(line.get("min", 0))
lineW.setMaximum(line.get("max", 100))
lineW.setSingleStep(line.get("step", 0.1))
lineW.setValue(dd[key])
lineW.valueChanged.connect(functools.partial(dd.__setitem__, key))
elif line["type"] == "intspin":
lineW = FocusSpin()
lineW.setMinimum(0 if "min" not in line else line["min"])
lineW.setMaximum(100 if "max" not in line else line["max"])
lineW.setSingleStep(1 if "step" not in line else line["step"])
lineW.setMinimum(line.get("min", 0))
lineW.setMaximum(line.get("max", 100))
lineW.setSingleStep(line.get("step", 1))
lineW.setValue(dd[key])
lineW.valueChanged.connect(functools.partial(dd.__setitem__, key))
if "name" in line:

View File

@ -1,17 +1,22 @@
from qtsymbols import *
import functools
import gobject
from myutils.config import globalconfig, _TRL
import gobject, os
from myutils.config import globalconfig, _TRL, _TR
from gui.inputdialog import multicolorset
from gui.usefulwidget import (
D_getsimplecombobox,
getsimplecombobox,
getsimpleswitch,
D_getspinbox,
getspinbox,
D_getcolorbutton,
getcolorbutton,
D_getsimpleswitch,
selectcolor,
FocusFontCombo
FocusFontCombo,
FocusCombo,
FocusDoubleSpin,
FocusSpin,
)
@ -67,6 +72,115 @@ def createfenciwitch(self):
return self.show_fenciswitch
def createinternalfontsettings(self, group, _type):
globalconfig["rendertext_using_internal"][group] = _type
__internal = globalconfig["rendertext"][group][_type]
dd = __internal.get("args", {})
lay: QFormLayout = self.goodfontsettingsWidget.layout()
while lay.count() > 2:
item = lay.takeAt(2)
if not item:
break
w = item.widget()
lay.removeWidget(w)
w.deleteLater()
for key in dd:
line = __internal["argstype"][key]
name = line["name"]
_type = line["type"]
if _type == "colorselect":
lineW = getcolorbutton(
dd,
key,
transparent=False,
callback=functools.partial(
lambda dd, key, _: selectcolor(
self, dd, key, self.miaobian_color_button
),
dd,
key,
),
name="miaobian_color_button",
parent=self,
)
elif _type == "spin":
lineW = FocusDoubleSpin()
lineW.setMinimum(line.get("min", 0))
lineW.setMaximum(line.get("max", 100))
lineW.setSingleStep(line.get("step", 0.1))
lineW.setValue(dd[key])
lineW.valueChanged.connect(functools.partial(dd.__setitem__, key))
elif _type == "intspin":
lineW = FocusSpin()
lineW.setMinimum(line.get("min", 0))
lineW.setMaximum(line.get("max", 100))
lineW.setSingleStep(line.get("step", 1))
lineW.setValue(dd[key])
lineW.valueChanged.connect(functools.partial(dd.__setitem__, key))
lay.addRow(
name,
lineW,
)
def resetgroudswitchcallback(self, group):
try:
self.goodfontgroupswitch.currentIndexChanged.disconnect()
except:
pass
_ = []
for k in globalconfig["rendertext"][group]:
if not os.path.exists(f"LunaTranslator/rendertext/internal/{group}/{k}.py"):
_.append(k)
for k in _:
globalconfig["rendertext"][group].pop(k)
if (
globalconfig["rendertext_using_internal"][group]
not in globalconfig["rendertext"][group]
):
globalconfig["rendertext_using_internal"][group] = list(
globalconfig["rendertext"][group].keys()
)[0]
self.goodfontgroupswitch.clear()
self.goodfontgroupswitch.addItems(
_TRL(
[
globalconfig["rendertext"][group][x]["name"]
for x in globalconfig["rendertext"][group]
]
)
)
self.goodfontgroupswitch.setCurrentIndex(-1)
self.goodfontgroupswitch.currentIndexChanged.connect(
lambda idx: createinternalfontsettings(
self, group, list(globalconfig["rendertext"][group].keys())[idx]
)
)
self.goodfontgroupswitch.setCurrentIndex(
list(globalconfig["rendertext"][group].keys()).index(
globalconfig["rendertext_using_internal"][group]
)
)
def firsttime(self):
self.goodfontgroupswitch = FocusCombo()
self.goodfontsettingsformlayout.addRow(_TR("字体样式"), self.goodfontgroupswitch)
resetgroudswitchcallback(self, globalconfig["rendertext_using"])
def creategoodfontwid(self):
self.goodfontsettingsWidget = QGroupBox()
self.goodfontsettingsformlayout = QFormLayout()
self.goodfontsettingsWidget.setLayout(self.goodfontsettingsformlayout)
return self.goodfontsettingsWidget, functools.partial(firsttime, self)
def xianshigrid(self):
textgrid = [
@ -93,71 +207,21 @@ def xianshigrid(self):
("加粗字体", 5),
D_getsimpleswitch(globalconfig, "showbold"),
],
[],
[
"",
],
[
("字体样式", 3),
("显示引擎", 3),
(
D_getsimplecombobox(
_TRL(
[
"普通字体",
"空心字体",
"描边字体",
"描边字体_2",
"描边字体_2_投影",
"发光字体",
]
),
_TRL(list(globalconfig["rendertext"].keys())),
globalconfig,
"zitiyangshi2",
"rendertext_using",
internallist=list(globalconfig["rendertext"].keys()),
callback=functools.partial(resetgroudswitchcallback, self),
),
6,
),
],
[
("特殊字体样式填充颜色", 5),
D_getcolorbutton(
globalconfig,
"miaobiancolor",
transparent=False,
callback=lambda: selectcolor(
self, globalconfig, "miaobiancolor", self.miaobian_color_button
),
name="miaobian_color_button",
parent=self,
),
],
[
("空心线宽", 3),
(
D_getspinbox(
0.1, 100, globalconfig, "miaobianwidth", double=True, step=0.1
),
3,
),
"",
("描边宽度", 3),
(
D_getspinbox(
0.1, 100, globalconfig, "miaobianwidth2", double=True, step=0.1
),
3,
),
],
[
("发光亮度", 3),
(D_getspinbox(1, 100, globalconfig, "shadowforce"), 3),
"",
("投影距离", 3),
(
D_getspinbox(
0.1, 100, globalconfig, "traceoffset", double=True, step=0.1
),
3,
),
],
[(functools.partial(creategoodfontwid, self), 0)],
[],
[
("显示原文", 5),

View File

@ -1,780 +1,74 @@
from qtsymbols import *
import functools
from traceback import print_exc
from myutils.config import globalconfig
class Qlabel_c(QLabel):
def mousePressEvent(self, ev):
self.pr = True
return super().mousePressEvent(ev)
def mouseMoveEvent(self, ev):
pass
# return super().mouseMoveEvent(ev)
def mouseReleaseEvent(self, event: QMouseEvent):
try:
if self.geometry().contains(self.parent().mapFromGlobal(QCursor.pos())):
try:
if self.pr:
if event.button() == Qt.MouseButton.RightButton:
self.callback(True)
else:
self.callback(False)
except:
print_exc()
self.pr = False
except:
print_exc()
return super().mouseReleaseEvent(event)
def enterEvent(self, a0) -> None:
if self.company:
self.company.setStyleSheet("background-color: rgba(0,0,0,0.5);")
self.setStyleSheet("background-color: rgba(0,0,0,0.5);")
return super().enterEvent(a0)
def leaveEvent(self, a0) -> None:
if self.company:
self.company.setStyleSheet("background-color: rgba(0,0,0,0.01);")
self.setStyleSheet("background-color: rgba(0,0,0,0.01);")
return super().leaveEvent(a0)
class QGraphicsDropShadowEffect_multi(QGraphicsDropShadowEffect):
def __init__(self, x) -> None:
self.x = x
super().__init__()
def draw(self, painter) -> None:
for i in range(self.x):
super().draw(painter)
class BorderedLabel(QLabel):
def move(self, point: QPoint):
self.movedx = 0
self.movedy = 0
text = self.text()
isarabic = any((ord(char) >= 0x0600 and ord(char) <= 0x06E0) for char in text)
if isarabic:
self.movedx -= self.width()
self.movedx -= self.m_fontOutLineWidth
self.movedy -= self.m_fontOutLineWidth
point.setX(int(point.x() + self.movedx))
point.setY(int(point.y() + self.movedy))
super().move(point)
def pos(self) -> QPoint:
p = super().pos()
p.setX(int(p.x() - self.movedx))
p.setY(int(p.y() - self.movedy))
return p
def clearShadow(self):
self.setGraphicsEffect(None)
def setShadow(self, colorshadow, width=1, deepth=1, trace=False):
shadow2 = QGraphicsDropShadowEffect_multi(deepth)
if trace:
shadow2.setBlurRadius(width)
shadow2.setOffset(QPointF(width, width))
else:
shadow2.setBlurRadius(width)
shadow2.setOffset(0)
shadow2.setColor(QColor(colorshadow))
self.setGraphicsEffect(shadow2)
def __init__(self, parent=None):
super().__init__(parent)
self.movedy = 0
self.movedx = 0
self.m_outLineColor = QColor()
self.m_fontOutLineWidth = 1
self.m_contentColor = QColor()
self._type = 0
self._pix = None
self._m_text = ""
def text(self):
return self._m_text
def setText(self, text):
self._m_text = text
def setColorWidth(self, outLineColor, contentColor, width, _type=0):
self.m_outLineColor = QColor(outLineColor)
self.m_contentColor = QColor(contentColor)
self.m_fontOutLineWidth = width
self._type = _type
def adjustSize(self):
self._pix = None
font = self.font()
text = self.text()
font_m = QFontMetrics(font)
self.resize(
int(font_m.size(0, text).width() + 2 * self.m_fontOutLineWidth),
int(font_m.height() + 2 * self.m_fontOutLineWidth),
)
def labelresetcolor(self, color, rate=1):
c1 = color
c2 = globalconfig["miaobiancolor"]
if c1 is None:
c1 = ""
if c2 is None:
c2 = ""
if globalconfig["zitiyangshi2"] == 2:
self.setColorWidth(c1, c2, rate * globalconfig["miaobianwidth2"])
self.clearShadow()
elif globalconfig["zitiyangshi2"] == 3:
self.setColorWidth(c2, c1, rate * globalconfig["miaobianwidth2"])
self.clearShadow()
elif globalconfig["zitiyangshi2"] == 1:
self.setColorWidth(c1, c2, rate * globalconfig["miaobianwidth"], 1)
self.clearShadow()
elif globalconfig["zitiyangshi2"] == 4:
self.setColorWidth(c2, c1, rate * globalconfig["miaobianwidth2"])
self.setShadow(c2, rate * globalconfig["traceoffset"], 1, True)
elif globalconfig["zitiyangshi2"] == 0:
self.setColorWidth("", c1, 0, 2)
self.clearShadow()
elif globalconfig["zitiyangshi2"] == 5:
self.setColorWidth("", c2, 0, 2)
self.setShadow(
c1, rate * globalconfig["fontsize"], globalconfig["shadowforce"]
)
def paintEvent(self, event):
if not self._pix:
rate = self.devicePixelRatioF()
self._pix = QPixmap(self.size() * rate)
self._pix.setDevicePixelRatio(rate)
self._pix.fill(Qt.GlobalColor.transparent)
text = self.text()
font = self.font()
font_m = QFontMetrics(font)
painter = QPainter(self._pix)
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
path = QPainterPath()
if self._type == 2:
path.addText(
0,
font_m.ascent(),
font,
text,
)
painter.fillPath(path, QBrush(self.m_contentColor))
else:
path.addText(
self.m_fontOutLineWidth,
self.m_fontOutLineWidth + font_m.ascent(),
font,
text,
)
pen = QPen(
self.m_outLineColor,
self.m_fontOutLineWidth,
Qt.PenStyle.SolidLine,
Qt.PenCapStyle.RoundCap,
Qt.PenJoinStyle.RoundJoin,
)
if self._type == 0:
painter.strokePath(path, pen)
painter.fillPath(path, QBrush(self.m_contentColor))
elif self._type == 1:
painter.fillPath(path, QBrush(self.m_contentColor))
painter.strokePath(path, pen)
painter = QPainter(self)
painter.drawPixmap(0, 0, self._pix)
import importlib
class Textbrowser(QLabel):
contentsChanged = pyqtSignal(int, int)
contentsChanged = pyqtSignal(QSize)
_padding = 10
def __makeborder(self, size: QSize):
_padding_resize = 5
_padding_move = 5
_padding = _padding_resize + _padding_move
_padding = self._padding
self.masklabel_right.move(self.width() - _padding, 0)
self.masklabel_bottom.move(0, 0 + size.height() - _padding)
self.masklabel_left.resize(_padding, size.height())
self.masklabel_right.resize(_padding, size.height())
self.masklabel_bottom.resize(size.width(), _padding)
def move(self, x, y):
super().move(x, y)
self.textbrowser.move(x, y)
self.atback2.move(x, y)
self.toplabel2.move(x, y)
self.__makeborder(self.size())
def resizeEvent(self, event: QResizeEvent):
self.atback2.resize(event.size())
self.toplabel2.resize(event.size())
self.masklabel.resize(event.size())
_padding = self._padding
self.textbrowser.setGeometry(
_padding,
0,
event.size().width() - 2 * _padding,
event.size().height() - _padding,
)
self.__makeborder(event.size())
def contentchangedfunction(self):
sz = self.textbrowser.document().size().toSize()
self.textbrowser.resize(self.width(), sz.height())
self.contentsChanged.emit(sz.width(), sz.height())
def _contentsChanged(self, size: QSize):
self.contentsChanged.emit(QSize(size.width(), size.height()))
def loadinternal(self):
tb = importlib.import_module(
f'rendertext.{globalconfig["rendertext_using"]}'
).TextBrowser
self.textbrowser = tb(self)
self.textbrowser.setMouseTracking(True)
self.textbrowser.contentsChanged.connect(self._contentsChanged)
def __init__(self, parent):
super().__init__(parent)
self.setMouseTracking(True)
self.atback2 = QLabel(parent)
self.toplabel2 = QLabel(parent)
self.atback2.setMouseTracking(True)
self.textbrowser = QTextBrowser(parent)
self.textbrowser.document().contentsChanged.connect(self.contentchangedfunction)
self.tranparentcolor = QColor()
self.tranparentcolor.setAlpha(0)
self.textbrowser.setTextColor(self.tranparentcolor)
self.cleared = False
self.font = QFont()
self.toplabel2.setMouseTracking(True)
self.textbrowser.setStyleSheet(
"border-width: 0;\
border-style: outset;\
background-color: rgba(0, 0, 0, 0)"
)
self.textcursor = self.textbrowser.textCursor()
self.textbrowser.setVerticalScrollBarPolicy(
Qt.ScrollBarPolicy.ScrollBarAlwaysOff
)
self.textbrowser.setHorizontalScrollBarPolicy(
Qt.ScrollBarPolicy.ScrollBarAlwaysOff
)
self.masklabel = QLabel(self.textbrowser)
self.masklabel.setMouseTracking(True)
self.masklabel_left = QLabel(self.textbrowser)
self.cleared = True
self.loadinternal()
self.masklabel_left = QLabel(self)
self.masklabel_left.setMouseTracking(True)
self.masklabel_right = QLabel(self.textbrowser)
# self.masklabel_left.setStyleSheet('background-color:red')
self.masklabel_right = QLabel(self)
# self.masklabel_right.setStyleSheet('background-color:red')
self.masklabel_right.setMouseTracking(True)
self.masklabel_bottom = QLabel(self.textbrowser)
self.masklabel_bottom = QLabel(self)
self.masklabel_bottom.setMouseTracking(True)
self.savetaglabels = []
self.searchmasklabels_clicked = []
self.searchmasklabels = []
self.backcolorlabels = []
self.yinyinglabels = []
self.yinyinglabels_idx = 0
self.yinyingpos = 0
self.yinyingposline = 0
self.lastcolor = None
# self.masklabel_bottom.setStyleSheet('background-color:red')
self.setselectable()
self.blockcount = 0
self.iteryinyinglabelsave = {}
def setselectable(self):
self.masklabel.setHidden(globalconfig["selectable"])
self.textbrowser.setselectable(globalconfig["selectable"])
def setnextfont(self, origin):
if origin:
self.font.setFamily(globalconfig["fonttype"])
else:
self.font.setFamily(globalconfig["fonttype2"])
self.font.setPointSizeF(globalconfig["fontsize"])
self.font.setBold(globalconfig["showbold"])
self.textbrowser.moveCursor(QTextCursor.MoveOperation.End)
f = QTextCharFormat()
f.setFont(self.font)
f.setForeground(self.tranparentcolor)
c = self.textbrowser.textCursor()
c.setCharFormat(f)
self.textbrowser.setTextCursor(c)
def setAlignment(self, x):
self.textbrowser.setAlignment(x)
def append(self, x, tag, color):
if self.cleared:
_space = ""
self.blockcount = 0
b1 = 0
else:
_space = "\n"
b1 = self.textbrowser.document().blockCount()
def iter_append(self, iter_context_class, origin, atcenter, text, color):
cleared = self.cleared
self.cleared = False
self.textbrowser.insertPlainText(_space + x)
b2 = self.textbrowser.document().blockCount()
fh = globalconfig["extra_space"]
for i in range(self.blockcount, self.textbrowser.document().blockCount()):
b = self.textbrowser.document().findBlockByNumber(i)
tf = b.blockFormat()
if isqt5:
lht = QTextBlockFormat.LineHeightTypes.LineDistanceHeight
else:
lht = 4
tf.setLineHeight(fh, lht)
self.textcursor.setPosition(b.position())
self.textcursor.setBlockFormat(tf)
self.textbrowser.setTextCursor(self.textcursor)
self.blockcount = self.textbrowser.document().blockCount()
if len(tag) > 0:
self.addtag(tag)
self.showyinyingtext(b1, b2, color)
def getcurrpointer(self):
return self.textcursor.position()
def insertatpointer(self, pointer, text):
self.textcursor.setPosition(pointer)
self.textbrowser.setTextCursor(self.textcursor)
self.textbrowser.insertPlainText(text)
def deletebetween(self, p1, p2):
self.textcursor.setPosition(p1, QTextCursor.MoveMode.MoveAnchor)
self.textcursor.setPosition(p2, QTextCursor.MoveMode.KeepAnchor)
self.textcursor.removeSelectedText()
def showyinyingtext2(self, color, iter_context_class, pos, text):
if iter_context_class not in self.iteryinyinglabelsave:
self.iteryinyinglabelsave[iter_context_class] = [[], 0]
maxh = 0
maxh2 = 9999999
for label in self.iteryinyinglabelsave[iter_context_class][0]:
maxh2 = min(label.pos().y(), maxh2)
if label.isVisible() == False:
continue
label.hide()
maxh = max(label.pos().y(), maxh)
subtext = []
subpos = []
lastpos = None
posx = pos
for i in range(len(text)):
self.textcursor.setPosition(posx)
posx += 1
tl1 = self.textbrowser.cursorRect(self.textcursor).topLeft()
if lastpos is None or tl1.y() != lastpos.y() or text[i] == "\n":
lastpos = tl1
subpos.append(lastpos)
subtext.append("")
subtext[-1] += text[i]
maxnewh = 0
for i in range(len(subtext)):
if self.iteryinyinglabelsave[iter_context_class][1] >= len(
self.iteryinyinglabelsave[iter_context_class][0]
):
self.iteryinyinglabelsave[iter_context_class][0].append(
BorderedLabel(self.toplabel2)
)
maxnewh = max(maxnewh, subpos[i].y())
_ = self.iteryinyinglabelsave[iter_context_class][0][
self.iteryinyinglabelsave[iter_context_class][1]
]
_.labelresetcolor(color)
_.setText(subtext[i])
_.setFont(self.font)
_.adjustSize()
_.move(subpos[i])
_.show()
self.iteryinyinglabelsave[iter_context_class][1] += 1
if maxh:
if maxnewh == 0:
maxnewh = maxh2
for label in self.yinyinglabels:
if label.isVisible() == False:
continue
if label.pos().y() > maxh:
label.move(
QPoint(label.pos().x(), label.pos().y() + maxnewh - maxh)
)
for klass in self.iteryinyinglabelsave:
if klass == iter_context_class:
continue
for label in self.iteryinyinglabelsave[klass][0]:
if label.isVisible() == False:
continue
if label.pos().y() > maxh:
label.move(
QPoint(label.pos().x(), label.pos().y() + maxnewh - maxh)
self.textbrowser.iter_append(
iter_context_class, origin, atcenter, text, color, cleared
)
def showyinyingtext(self, b1, b2, color):
linei = self.yinyingposline
doc = self.textbrowser.document()
block = doc.findBlockByNumber(0)
for blocki in range(b1, b2):
block = doc.findBlockByNumber(blocki)
layout = block.layout()
blockstart = block.position()
lc = layout.lineCount()
for lineii in range(lc):
line = layout.lineAt(lineii)
s = line.textStart()
l = line.textLength()
self.textcursor.setPosition(blockstart + s)
self.textbrowser.setTextCursor(self.textcursor)
tl1 = self.textbrowser.cursorRect(self.textcursor).topLeft()
if self.yinyinglabels_idx >= len(self.yinyinglabels):
self.yinyinglabels.append(BorderedLabel(self.toplabel2))
_ = self.yinyinglabels[self.yinyinglabels_idx]
self.yinyinglabels_idx += 1
_.labelresetcolor(color)
_.setText(block.text()[s : s + l])
_.setFont(self.font)
_.adjustSize()
_.move(tl1)
_.show()
linei += 1
self.yinyingposline = linei
def addsearchwordmask(self, x, raw, callback=None):
if len(x) == 0:
return
# print(x)
pos = 0
labeli = 0
self.textcursor.setPosition(0)
self.textbrowser.setTextCursor(self.textcursor)
idx = 0
heigth, __, _ = self.getfh(False)
for word in x:
idx += 1
l = len(word["orig"])
tl1 = self.textbrowser.cursorRect(self.textcursor).topLeft()
tl4 = self.textbrowser.cursorRect(self.textcursor).bottomRight()
if True:
self.textcursor.setPosition(pos + l)
self.textbrowser.setTextCursor(self.textcursor)
tl2 = self.textbrowser.cursorRect(self.textcursor).bottomRight()
tl3 = self.textbrowser.cursorRect(self.textcursor).topLeft()
color = self.randomcolor(word)
if color:
if word["orig"] not in ["\n", " ", ""]:
if labeli >= len(self.searchmasklabels) - 1:
ql = QLabel(self.atback2)
ql.setMouseTracking(True)
self.searchmasklabels.append(ql)
ql = Qlabel_c(self.textbrowser)
ql.setMouseTracking(True)
ql.setStyleSheet("background-color: rgba(0,0,0,0.01);")
self.searchmasklabels_clicked.append(ql)
ql = QLabel(self.atback2)
ql.setMouseTracking(True)
self.searchmasklabels.append(ql)
ql = Qlabel_c(self.textbrowser)
ql.setMouseTracking(True)
ql.setStyleSheet("background-color: rgba(0,0,0,0.01);")
self.searchmasklabels_clicked.append(ql)
if tl1.y() != tl3.y():
for __i in range(len(word["orig"])):
self.textcursor.setPosition(pos + __i)
self.textbrowser.setTextCursor(self.textcursor)
_tl = self.textbrowser.cursorRect(
self.textcursor
).topLeft()
if _tl.y() != tl1.y():
break
self.textcursor.setPosition(pos + l)
self.textbrowser.setTextCursor(self.textcursor)
__fm = self.getfh(False, getfm=True)
w1 = int(__fm.size(0, word["orig"][:__i]).width())
w2 = int(__fm.size(0, word["orig"][__i:]).width())
pos1 = (
tl1.x() + 1,
tl1.y(),
w1 - 2,
int(heigth),
)
pos2 = tl3.x() + 1 - w2, tl3.y(), w2 - 2, int(heigth)
if (
globalconfig["usesearchword"]
or globalconfig["usecopyword"]
):
self.searchmasklabels_clicked[labeli].setGeometry(*pos1)
self.searchmasklabels_clicked[labeli].show()
self.searchmasklabels_clicked[labeli].company = (
self.searchmasklabels_clicked[labeli + 1]
)
if callback:
self.searchmasklabels_clicked[labeli].callback = (
functools.partial(callback, (word))
)
self.searchmasklabels_clicked[labeli + 1].setGeometry(
*pos2
)
self.searchmasklabels_clicked[labeli + 1].show()
self.searchmasklabels_clicked[labeli + 1].company = (
self.searchmasklabels_clicked[labeli]
)
if callback:
self.searchmasklabels_clicked[
labeli + 1
].callback = functools.partial(callback, (word))
if globalconfig["show_fenci"]:
self.searchmasklabels[labeli].setGeometry(*pos1)
self.searchmasklabels[labeli].setStyleSheet(
"background-color: rgba{};".format(color)
)
self.searchmasklabels[labeli].show()
self.searchmasklabels[labeli + 1].setGeometry(*pos2)
self.searchmasklabels[labeli + 1].setStyleSheet(
"background-color: rgba{};".format(color)
)
self.searchmasklabels[labeli + 1].show()
labeli += 2
else:
pos1 = (
tl1.x() + 1,
tl1.y(),
tl2.x() - tl1.x() - 2,
int(heigth),
)
if (
globalconfig["usesearchword"]
or globalconfig["usecopyword"]
):
self.searchmasklabels_clicked[labeli].setGeometry(*pos1)
self.searchmasklabels_clicked[labeli].company = None
self.searchmasklabels_clicked[labeli].show()
if callback:
self.searchmasklabels_clicked[labeli].callback = (
functools.partial(callback, word)
)
if globalconfig["show_fenci"]:
self.searchmasklabels[labeli].setGeometry(*pos1)
self.searchmasklabels[labeli].setStyleSheet(
"background-color: rgba{};".format(color)
)
self.searchmasklabels[labeli].show()
labeli += 1
tl1 = tl3
tl4 = tl2
pos += l
def randomcolor(self, word):
if word.get("isdeli", False):
return None
c = QColor("white")
if "cixing" in word:
try:
if globalconfig["cixingcolorshow"][word["cixing"]] == False:
return None
c = QColor(globalconfig["cixingcolor"][word["cixing"]])
except:
pass
return (c.red(), c.green(), c.blue(), globalconfig["showcixing_touming"] / 100)
def getfh(self, half, origin=True, getfm=False):
font = QFont()
font.setBold(globalconfig["showbold"])
if origin:
font.setFamily(globalconfig["fonttype"])
else:
font.setFamily(globalconfig["fonttype2"])
# font.setPixelSize(int(globalconfig['fontsize']) )
if half:
font.setPointSizeF((globalconfig["fontsize"]) * globalconfig["kanarate"])
else:
font.setPointSizeF((globalconfig["fontsize"]))
fm = QFontMetricsF(font)
if getfm:
return fm
return fm.height(), fm.ascent(), font
def addtag(self, x):
pos = 0
fasall, _, fontorig = self.getfh(False)
fha, fascent, fonthira = self.getfh(True)
for i in range(0, self.textbrowser.document().blockCount()):
b = self.textbrowser.document().findBlockByNumber(i)
tf = b.blockFormat()
if isqt5:
lht = QTextBlockFormat.LineHeightTypes.FixedHeight
else:
lht = 2
tf.setLineHeight(fasall + fha, lht)
self.textcursor.setPosition(b.position())
self.textcursor.setBlockFormat(tf)
self.textbrowser.setTextCursor(self.textcursor)
x = self.nearmerge(x, pos, fonthira, fontorig)
self.settextposcursor(pos)
savetaglabels_idx = 0
for word in x:
l = len(word["orig"])
tl1 = self.textbrowser.cursorRect(self.textcursor).topLeft()
self.settextposcursor(pos + l)
pos += l
tl2 = self.textbrowser.cursorRect(self.textcursor).topLeft()
if word["hira"] == word["orig"]:
continue
# print(tl1,tl2,word['hira'],self.textbrowser.textCursor().position())
if word["orig"] == " ":
continue
if savetaglabels_idx >= len(self.savetaglabels):
self.savetaglabels.append(BorderedLabel(self.atback2))
self.solvejiaminglabel(
self.savetaglabels[savetaglabels_idx], word, fonthira, tl1, tl2, fascent
)
savetaglabels_idx += 1
def settextposcursor(self, pos):
self.textcursor.setPosition(pos)
self.textbrowser.setTextCursor(self.textcursor)
def nearmerge(self, x, startpos, fonthira, fontorig):
pos = startpos
linex = []
newline = []
self.settextposcursor(pos)
_metrichira = QFontMetricsF(fonthira)
_metricorig = QFontMetricsF(fontorig)
for i, word in enumerate(x):
word["orig_w"] = _metricorig.size(0, word["orig"]).width()
word["hira_w"] = _metrichira.size(0, word["hira"]).width()
# print(word['hira'],word['hira_w'])
newline.append(word)
l = len(word["orig"])
tl1 = self.textbrowser.cursorRect(self.textcursor).topLeft()
self.settextposcursor(pos + l)
pos += l
tl2 = self.textbrowser.cursorRect(self.textcursor).topLeft()
# print(tl1,tl2,word['hira'],self.textbrowser.textCursor().position())
if tl1.y() != tl2.y() or i == len(x) - 1:
linex.append(newline)
newline = []
res = []
for line in linex:
while True:
allnotbig = True
newline = []
canmerge = False
for word in line:
if (
word["hira"] == word["orig"]
or word["hira"] == ""
or word["orig"] == ""
):
newline.append(word.copy())
canmerge = False
else:
if (
len(newline) > 0
and canmerge
and (
word["hira_w"] + newline[-1]["hira_w"]
> word["orig_w"] + newline[-1]["orig_w"]
)
):
# print(word['hira'],word['hira_w'],newline[-1]['hira_w'],word['orig_w'],newline[-1]['orig_w'])
newline[-1]["hira"] += word["hira"]
newline[-1]["orig"] += word["orig"]
newline[-1]["hira_w"] += word["hira_w"]
newline[-1]["orig_w"] += word["orig_w"]
allnotbig = False
else:
newline.append(word.copy())
canmerge = True
line = newline
if allnotbig:
break
res += newline
newline = []
self.settextposcursor(startpos)
return res
def solvejiaminglabel(self, _: BorderedLabel, word, font, tl1, tl2, fh):
_.labelresetcolor(globalconfig["jiamingcolor"], rate=globalconfig["kanarate"])
_.setText(word["hira"])
_.setFont(font)
_.adjustSize()
w = _.width()
if tl1.y() != tl2.y():
# print(label,word)
x = tl1.x()
if x + w / 2 < self.textbrowser.width():
x = tl1.x()
y = tl1.y() - fh
else:
x = tl2.x() - w
y = tl2.y() - fh
else:
x = tl1.x() / 2 + tl2.x() / 2 - w / 2
y = tl2.y() - fh
_.move(QPoint(int(x), int(y)))
_.show()
return _
def append(self, origin, atcenter, text, tag, flags, color):
cleared = self.cleared
self.cleared = False
self.textbrowser.append(origin, atcenter, text, tag, flags, color, cleared)
def clear(self):
for label in self.searchmasklabels:
label.hide()
for label in self.searchmasklabels_clicked:
label.hide()
for label in self.savetaglabels:
label.hide()
self.yinyinglabels_idx = 0
for label in self.yinyinglabels:
label.hide()
for klass, labels in self.iteryinyinglabelsave.items():
for label in labels[0]:
label.hide()
labels[1] = 0
self.yinyingpos = 0
self.yinyingposline = 0
self.cleared = True
self.textbrowser.clear()

View File

@ -99,7 +99,7 @@ class QUnFrameWindow(resizableframeless):
except:
print_exc()
def showraw(self, kwargs): # hira,res,color,onlytrans):
def showraw(self, kwargs): # res,color,onlytrans):
text = kwargs.get("text")
color = kwargs.get("color")
onlytrans = kwargs.get("onlytrans")
@ -113,13 +113,7 @@ class QUnFrameWindow(resizableframeless):
else:
_res = text
if globalconfig["isshowrawtext"]:
hira = (
globalconfig["isshowhira"]
or globalconfig["usesearchword"]
or globalconfig["usecopyword"]
or globalconfig["show_fenci"]
)
self.showline(clear=clear, text=_res, hira=hira, color=color)
self.showline(clear=clear, text=_res, isshowrawtext=True, color=color)
else:
self.showline(clear=clear)
@ -157,98 +151,45 @@ class QUnFrameWindow(resizableframeless):
clear = kwargs.get("clear", True)
origin = kwargs.get("origin", True)
text = kwargs.get("text", None)
color = kwargs.get("color", None)
hira = kwargs.get("hira", False)
color = kwargs.get("color", 'black')
isshowrawtext = kwargs.get("isshowrawtext", False)
iter_context = kwargs.get("iter_context", None)
if clear:
self.translate_text.clear()
self.saveiterclasspointer.clear()
if text is None:
return
text = self.cleartext(text)
if hira:
hira = self.parsehira(text)
else:
hira = []
self.translate_text.setnextfont(origin)
if globalconfig["showatcenter"]:
self.translate_text.setAlignment(Qt.AlignmentFlag.AlignCenter)
else:
self.translate_text.setAlignment(Qt.AlignmentFlag.AlignLeft)
atcenter = globalconfig["showatcenter"]
if iter_context:
_, iter_context_class = iter_context
if iter_context_class not in self.saveiterclasspointer:
self.translate_text.append(" ", hira, origin)
self.saveiterclasspointer[iter_context_class] = {
"currtext": "",
"curr": self.translate_text.getcurrpointer(),
"start": self.translate_text.getcurrpointer(),
}
currbefore = self.saveiterclasspointer[iter_context_class]["curr"]
currlen = len(self.saveiterclasspointer[iter_context_class]["currtext"])
if len(text) < currlen:
self.translate_text.deletebetween(
self.saveiterclasspointer[iter_context_class]["start"] + len(text),
self.saveiterclasspointer[iter_context_class]["curr"],
self.translate_text.iter_append(
iter_context_class, origin, atcenter, text, color
)
else:
newtext = text[currlen:]
self.translate_text.insertatpointer(
self.saveiterclasspointer[iter_context_class]["start"] + currlen,
newtext,
hira = []
isshowhira = isshow_fenci = isfenciclick = False
if isshowrawtext:
isshowhira = globalconfig["isshowhira"]
isshow_fenci = globalconfig["show_fenci"]
isfenciclick = (
globalconfig["usesearchword"] or globalconfig["usecopyword"]
)
needhira = isshow_fenci or isshowhira or isfenciclick
if needhira:
hira = self.parsehira(text)
self.saveiterclasspointer[iter_context_class]["currtext"] = text
currcurrent = self.translate_text.getcurrpointer()
self.saveiterclasspointer[iter_context_class]["curr"] = currcurrent
currchange = currcurrent - currbefore
for klass in self.saveiterclasspointer:
if klass == iter_context_class:
continue
if self.saveiterclasspointer[klass]["curr"] > currbefore:
self.saveiterclasspointer[klass]["curr"] += currchange
self.saveiterclasspointer[klass]["start"] += currchange
self.translate_text.showyinyingtext2(
color,
iter_context_class,
self.saveiterclasspointer[iter_context_class]["start"],
text,
)
else:
self.translate_text.append(
text, hira if globalconfig["isshowhira"] else [], color
origin,
atcenter,
text,
hira,
(isshowhira, isshow_fenci, isfenciclick),
color,
)
if hira:
@threader
def callback(word, append):
if globalconfig["usewordorigin"] == False:
word = word["orig"]
else:
word = word.get("origorig", word["orig"])
if globalconfig["usecopyword"]:
if append:
winsharedutils.clipboard_set(
winsharedutils.clipboard_get() + word
)
else:
winsharedutils.clipboard_set(word)
if globalconfig["usesearchword"]:
gobject.baseobject.searchwordW.getnewsentencesignal.emit(
word, append
)
self.translate_text.addsearchwordmask(hira, text, callback)
if globalconfig["autodisappear"]:
flag = (globalconfig["showintab"] and self.isMinimized()) or (
not globalconfig["showintab"] and self.isHidden()
@ -591,13 +532,14 @@ class QUnFrameWindow(resizableframeless):
self.buttons = {}
self.showbuttons = []
self.stylebuttons = {}
self.saveiterclasspointer = {}
def displayglobaltooltip_f(self, string):
QToolTip.showText(
QCursor.pos(),
string,
gobject.baseobject.translation_ui,
)
def initsignals(self):
self.hidesignal.connect(self.hide_)
self.displayglobaltooltip.connect(self.displayglobaltooltip_f)
@ -644,7 +586,6 @@ class QUnFrameWindow(resizableframeless):
self._TitleLabel = QLabel(self)
self.addbuttons()
self.translate_text = Textbrowser(self)
self.translate_text.contentsChanged.connect(self.textAreaChanged)
def createborderradiusstring(self, r, merge, top=False):
@ -695,7 +636,7 @@ class QUnFrameWindow(resizableframeless):
)
self.translate_text.setStyleSheet(
"border-width: 0;%s;background-color: %s"
"Textbrowser{border-width: 0;%s;background-color: %s}"
% (
topr,
str2rgba(
@ -879,21 +820,17 @@ class QUnFrameWindow(resizableframeless):
globalconfig["locktools"] = not globalconfig["locktools"]
self.refreshtoolicon()
def textAreaChanged(self, w, h):
def textAreaChanged(self, size: QSize):
if globalconfig["fixedheight"]:
return
if self.translate_text.cleared:
return
newHeight = h
newHeight = size.height() + self.translate_text._padding
width = self.width()
self.resize(
width,
int(
max(0, -globalconfig["extra_space"])
+ newHeight
+ globalconfig["buttonsize"] * 1.5
),
int(newHeight + globalconfig["buttonsize"] * 1.5),
)
def clickRange(self, auto):

View File

@ -30,6 +30,7 @@ class FocusCombo(QComboBox):
class FocusFontCombo(QFontComboBox, FocusCombo):
pass
class FocusSpin(QSpinBox):
def __init__(self, parent: QWidget = None) -> None:
super().__init__(parent)
@ -423,7 +424,8 @@ def callbackwrap(d, k, call, _):
def comboboxcallbackwrap(internallist, d, k, call, _):
d[k] = internallist[_]
_ = internallist[_]
d[k] = _
if call:
try:
call(_)
@ -670,7 +672,53 @@ class abstractwebview(QWidget):
on_ZoomFactorChanged = pyqtSignal(float)
html_limit = 2 * 1024 * 1024
def parsehtml(self, html):
# 必须的接口
def _setHtml(self, html):
pass
def navigate(self, url):
pass
#
def _parsehtml(self, html):
return self._parsehtml_dark_auto(html)
def set_zoom(self, zoom):
pass
def set_transparent_background(self):
pass
def clear(self):
self.navigate("about:blank")
def setHtml(self, html):
html = self._parsehtml(html)
if len(html) < self.html_limit:
self._setHtml(html)
else:
os.makedirs("cache/temp", exist_ok=True)
lastcachehtml = os.path.abspath("cache/temp/" + str(time.time()) + ".html")
with open(lastcachehtml, "w", encoding="utf8") as ff:
ff.write(html)
self.navigate(lastcachehtml)
def _parsehtml_dark(self, html):
if nowisdark():
html = (
html
+ """
<style>
body
{
background-color: rgb(44,44,44);
color: white;
}
</style>"""
)
return html
def _parsehtml_dark_auto(self, html):
return (
html
+ """
@ -690,9 +738,6 @@ class abstractwebview(QWidget):
"""
)
def set_zoom(self, zoom):
pass
class WebivewWidget(abstractwebview):
@ -766,9 +811,56 @@ class WebivewWidget(abstractwebview):
size = getscaledrect(a0.size())
windows.MoveWindow(hwnd, 0, 0, size[0], size[1], True)
def setHtml(self, html):
def _setHtml(self, html):
self.webview.set_html(html)
def set_transparent_background(self):
winsharedutils.set_transparent_background(self.get_controller())
class QWebWrap(abstractwebview):
def __init__(self) -> None:
super().__init__()
from PyQt5.QtWebEngineWidgets import QWebEngineView
self.internal = QWebEngineView(self)
self.internal.page().urlChanged.connect(
lambda qurl: self.on_load.emit(qurl.url())
)
self.internal_zoom = 1
t = QTimer(self)
t.setInterval(100)
t.timeout.connect(self.__getzoomfactor)
t.timeout.emit()
t.start()
def set_zoom(self, zoom):
self.internal_zoom = zoom
self.internal.setZoomFactor(zoom)
def __getzoomfactor(self):
z = self.internal.zoomFactor()
if z != self.internal_zoom:
self.internal_zoom = z
self.on_ZoomFactorChanged.emit(z)
def navigate(self, url: str):
from PyQt5.QtCore import QUrl
if not url.lower().startswith("http"):
url = url.replace("\\", "/")
self.internal.load(QUrl(url))
def _setHtml(self, html):
self.internal.setHtml(html)
def resizeEvent(self, a0: QResizeEvent) -> None:
self.internal.resize(a0.size())
def _parsehtml(self, html):
return self._parsehtml_dark(html)
class mshtmlWidget(abstractwebview):
@ -797,22 +889,11 @@ class mshtmlWidget(abstractwebview):
size = getscaledrect(a0.size())
self.browser.resize(0, 0, size[0], size[1])
def setHtml(self, html):
def _setHtml(self, html):
self.browser.set_html(html)
def parsehtml(self, html):
if nowisdark():
html = (
html
+ """
<style>
body
{
background-color: rgb(44,44,44);
color: white;
}
</style>"""
)
def _parsehtml(self, html):
html = self._parsehtml_dark(html)
html = """<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8" /></head><body style=" font-family:'{}'">{}</body></html>""".format(
QFontDatabase.systemFont(QFontDatabase.GeneralFont).family(), html
)
@ -850,68 +931,12 @@ def D_getsimplekeyseq(dic, key, callback=None):
return lambda: getsimplekeyseq(dic, key, callback)
class QWebWrap(abstractwebview):
def __init__(self) -> None:
super().__init__()
from PyQt5.QtWebEngineWidgets import QWebEngineView
self.internal = QWebEngineView(self)
self.internal.page().urlChanged.connect(
lambda qurl: self.on_load.emit(qurl.url())
)
self.internal_zoom = 1
t = QTimer(self)
t.setInterval(100)
t.timeout.connect(self.__getzoomfactor)
t.timeout.emit()
t.start()
def parsehtml(self, html):
if nowisdark():
html = (
html
+ """
<style>
body
{
background-color: rgb(44,44,44);
color: white;
}
</style>"""
)
return html
def set_zoom(self, zoom):
self.internal_zoom = zoom
self.internal.setZoomFactor(zoom)
def __getzoomfactor(self):
z = self.internal.zoomFactor()
if z != self.internal_zoom:
self.internal_zoom = z
self.on_ZoomFactorChanged.emit(z)
def navigate(self, url: str):
from PyQt5.QtCore import QUrl
if not url.lower().startswith("http"):
url = url.replace("\\", "/")
self.internal.load(QUrl(url))
def setHtml(self, html):
self.internal.setHtml(html)
def resizeEvent(self, a0: QResizeEvent) -> None:
self.internal.resize(a0.size())
class auto_select_webview(QWidget):
on_load = pyqtSignal(str)
on_ZoomFactorChanged = pyqtSignal(float)
def clear(self):
self.navigate("about:blank")
self.internal.clear()
def navigate(self, url):
self._maybecreate()
@ -921,15 +946,7 @@ class auto_select_webview(QWidget):
def setHtml(self, html):
self._maybecreate()
self.internal.set_zoom(self.internalsavedzoom)
html = self.internal.parsehtml(html)
if len(html) < self.internal.html_limit:
self.internal.setHtml(html)
else:
os.makedirs("cache/temp", exist_ok=True)
lastcachehtml = os.path.abspath("cache/temp/" + str(time.time()) + ".html")
with open(lastcachehtml, "w", encoding="utf8") as ff:
ff.write(html)
self.internal.navigate(lastcachehtml)
def set_zoom(self, zoom):
self.internalsavedzoom = zoom
@ -1078,9 +1095,14 @@ def automakegrid(grid: QGridLayout, lis, save=False, savelist=None):
col = maxl - nowc
else:
col = -maxl // cols
do = None
if callable(wid):
wid = wid()
if isinstance(wid, tuple):
wid, do = wid
grid.addWidget(wid, nowr, nowc, 1, col)
if do:
do()
if save:
ll.append(wid)
nowc += cols
@ -1281,7 +1303,7 @@ class listediter(QDialog):
multi=False,
edit=None,
isdir=self.ispathsedit.get("isdir", False),
filter1=self.ispathsedit.get("filter1",'*.*'),
filter1=self.ispathsedit.get("filter1", "*.*"),
callback=self.__cb,
)
else:

View File

@ -1,6 +1,6 @@
try:
from PyQt5 import QtSvg
from PyQt5.QtWidgets import QFrame,QListView,QCheckBox,QAbstractItemView,QTextEdit,QTableView,QHeaderView,QColorDialog,QSpinBox,QDoubleSpinBox,QComboBox,QDialogButtonBox,QMainWindow,QMessageBox,QDialog,QGridLayout,QTextBrowser,QGraphicsDropShadowEffect,QWidget,QSizePolicy,QScrollArea,QApplication,QPushButton,QSystemTrayIcon,QPlainTextEdit,QAction,QMenu,QFileDialog,QKeySequenceEdit,QLabel,QSpacerItem,QWidgetItem,QLayout,QTextBrowser,QLineEdit,QFormLayout,QSizePolicy,QTabWidget,QTabBar,QSplitter,QListWidget,QListWidgetItem,QHBoxLayout,QVBoxLayout,QSizeGrip,QFontComboBox,QProgressBar,QRadioButton,QButtonGroup,QSlider,QToolTip
from PyQt5.QtWidgets import QFrame,QListView,QCheckBox,QAbstractItemView,QTextEdit,QTableView,QHeaderView,QColorDialog,QSpinBox,QDoubleSpinBox,QComboBox,QDialogButtonBox,QMainWindow,QMessageBox,QDialog,QGridLayout,QTextBrowser,QGraphicsDropShadowEffect,QWidget,QSizePolicy,QScrollArea,QApplication,QPushButton,QSystemTrayIcon,QPlainTextEdit,QAction,QMenu,QFileDialog,QKeySequenceEdit,QLabel,QSpacerItem,QWidgetItem,QLayout,QTextBrowser,QLineEdit,QFormLayout,QSizePolicy,QTabWidget,QTabBar,QSplitter,QListWidget,QListWidgetItem,QHBoxLayout,QVBoxLayout,QSizeGrip,QFontComboBox,QProgressBar,QRadioButton,QButtonGroup,QSlider,QToolTip,QGroupBox
from PyQt5.QtGui import QIconEngine,QIntValidator,QStandardItem,QStandardItemModel,QImageWriter,QIcon,QTextCharFormat,QTextBlockFormat,QResizeEvent,QTextCursor,QFontMetricsF,QMouseEvent,QImage,QPainter,QRegion,QCloseEvent,QFontDatabase,QKeySequence,QPixmap,QCursor,QColor,QFont,QPen,QPainterPath,QBrush,QFontMetrics,QShowEvent,QWheelEvent
from PyQt5.QtCore import QObject,pyqtSignal,Qt,QSize,QByteArray,QBuffer,QPointF,QPoint,QRect,QEvent,QModelIndex,QTimer
isqt5 = True
@ -8,7 +8,7 @@ except:
#from traceback import print_exc
#print_exc()
from PyQt6 import QtSvg
from PyQt6.QtWidgets import QFrame,QListView,QCheckBox,QAbstractItemView,QTextEdit,QTableView,QHeaderView,QColorDialog,QSpinBox,QDoubleSpinBox,QComboBox,QDialogButtonBox,QMainWindow,QMessageBox,QDialog,QGridLayout,QTextBrowser,QGraphicsDropShadowEffect,QWidget,QSizePolicy,QScrollArea,QApplication,QPushButton,QSystemTrayIcon,QPlainTextEdit,QMenu,QFileDialog,QKeySequenceEdit,QLabel,QSpacerItem,QWidgetItem,QLayout,QTextBrowser,QLineEdit,QFormLayout,QSizePolicy,QTabWidget,QTabBar,QSplitter,QListWidget,QListWidgetItem,QHBoxLayout,QVBoxLayout,QSizeGrip,QFontComboBox,QProgressBar,QRadioButton,QButtonGroup,QSlider,QToolTip
from PyQt6.QtWidgets import QFrame,QListView,QCheckBox,QAbstractItemView,QTextEdit,QTableView,QHeaderView,QColorDialog,QSpinBox,QDoubleSpinBox,QComboBox,QDialogButtonBox,QMainWindow,QMessageBox,QDialog,QGridLayout,QTextBrowser,QGraphicsDropShadowEffect,QWidget,QSizePolicy,QScrollArea,QApplication,QPushButton,QSystemTrayIcon,QPlainTextEdit,QMenu,QFileDialog,QKeySequenceEdit,QLabel,QSpacerItem,QWidgetItem,QLayout,QTextBrowser,QLineEdit,QFormLayout,QSizePolicy,QTabWidget,QTabBar,QSplitter,QListWidget,QListWidgetItem,QHBoxLayout,QVBoxLayout,QSizeGrip,QFontComboBox,QProgressBar,QRadioButton,QButtonGroup,QSlider,QToolTip,QGroupBox
from PyQt6.QtGui import QIconEngine,QIntValidator,QAction,QStandardItem,QStandardItemModel,QImageWriter,QIcon,QTextCharFormat,QTextBlockFormat,QResizeEvent,QTextCursor,QFontMetricsF,QMouseEvent,QImage,QPainter,QRegion,QCloseEvent,QFontDatabase,QKeySequence,QPixmap,QCursor,QColor,QFont,QPen,QPainterPath,QBrush,QFontMetrics,QShowEvent,QWheelEvent
from PyQt6.QtCore import QObject,pyqtSignal,Qt,QSize,QByteArray,QBuffer,QPointF,QPoint,QRect,QEvent,QModelIndex,QTimer
isqt5 = False

View File

@ -0,0 +1,121 @@
from qtsymbols import *
from myutils.config import globalconfig
class QGraphicsDropShadowEffect_multi(QGraphicsDropShadowEffect):
def __init__(self, x) -> None:
self.x = x
super().__init__()
def draw(self, painter) -> None:
for i in range(self.x):
super().draw(painter)
class base(QLabel):
def paintText(self, painter: QPainter):
raise Exception
def setShadow(self):
pass
def moveoffset(self):
return self.config.get("width", 0), self.config.get("width", 0)
def extraWH(self):
return 2 * self.config.get("width", 0), 2 * self.config.get("width", 0)
def init(self):
pass
@property
def config(self):
return globalconfig["rendertext"]["textbrowser"][self.typename].get("args", {})
@property
def basecolor(self):
return self._basecolor
def setColor(self, color: str):
if color is None:
self._basecolor = QColor()
else:
self._basecolor = QColor(color)
def __init__(self, typename, parent):
super().__init__(parent)
self._basecolor = QColor()
self.typename = typename
self.movedy = 0
self.movedx = 0
self._pix = None
self._m_text = ""
self.init()
def adjustSize(self):
self._pix = None
font = self.font()
text = self.text()
font_m = QFontMetrics(font)
w, h = self.extraWH()
self.resize(
int(font_m.size(0, text).width() + w),
int(font_m.height() + h),
)
self.setShadow()
def move(self, point: QPoint):
self.movedx = 0
self.movedy = 0
text = self.text()
isarabic = any((ord(char) >= 0x0600 and ord(char) <= 0x06E0) for char in text)
if isarabic:
self.movedx -= self.width()
x, y = self.moveoffset()
self.movedx -= x
self.movedy -= y
point.setX(int(point.x() + self.movedx))
point.setY(int(point.y() + self.movedy))
super().move(point)
def pos(self) -> QPoint:
p = super().pos()
p.setX(int(p.x() - self.movedx))
p.setY(int(p.y() - self.movedy))
return p
def clearShadow(self):
self.setGraphicsEffect(None)
def setShadow_internal(self, colorshadow, width=1, deepth=1, trace=False):
shadow2 = QGraphicsDropShadowEffect_multi(deepth)
if trace:
shadow2.setBlurRadius(width)
shadow2.setOffset(QPointF(width, width))
else:
shadow2.setBlurRadius(width)
shadow2.setOffset(0)
shadow2.setColor(QColor(colorshadow))
self.setGraphicsEffect(shadow2)
def text(self):
return self._m_text
def setText(self, text):
self._m_text = text
def paintEvent(self, event):
if not self._pix:
rate = self.devicePixelRatioF()
self._pix = QPixmap(self.size() * rate)
self._pix.setDevicePixelRatio(rate)
self._pix.fill(Qt.GlobalColor.transparent)
painter = QPainter(self._pix)
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
self.paintText(painter)
painter = QPainter(self)
painter.drawPixmap(0, 0, self._pix)

View File

@ -0,0 +1,13 @@
from qtsymbols import *
from rendertext.internal.textbrowser.normal import TextLine as TextLabel_0
class TextLine(TextLabel_0):
def usingcolor(self):
return QColor(self.config["fillcolor"])
def setShadow(self):
font = self.font()
self.setShadow_internal(
self.basecolor, font.pointSizeF(), self.config["shadowforce"]
)

View File

@ -0,0 +1,34 @@
from qtsymbols import *
from rendertext.internal.textbrowser.base import base
class TextLine(base):
def colorpair(self):
return QColor(self.config["fillcolor"]), QColor(self.basecolor)
def paintText(self, painter: QPainter):
self.m_outLineColor, self.m_contentColor = self.colorpair()
self.m_fontOutLineWidth = self.config["width"]
text = self.text()
font = self.font()
font_m = QFontMetrics(font)
path = QPainterPath()
path.addText(
self.m_fontOutLineWidth,
self.m_fontOutLineWidth + font_m.ascent(),
font,
text,
)
pen = QPen(
self.m_outLineColor,
self.m_fontOutLineWidth,
Qt.PenStyle.SolidLine,
Qt.PenCapStyle.RoundCap,
Qt.PenJoinStyle.RoundJoin,
)
painter.fillPath(path, QBrush(self.m_contentColor))
painter.strokePath(path, pen)

View File

@ -0,0 +1,34 @@
from qtsymbols import *
from rendertext.internal.textbrowser.base import base
class TextLine(base):
def colorpair(self):
return QColor(self.config["fillcolor"]), QColor(self.basecolor)
def paintText(self, painter: QPainter):
self.m_outLineColor, self.m_contentColor = self.colorpair()
self.m_fontOutLineWidth = self.config["width"]
text = self.text()
font = self.font()
font_m = QFontMetrics(font)
path = QPainterPath()
path.addText(
self.m_fontOutLineWidth,
self.m_fontOutLineWidth + font_m.ascent(),
font,
text,
)
pen = QPen(
self.m_outLineColor,
self.m_fontOutLineWidth,
Qt.PenStyle.SolidLine,
Qt.PenCapStyle.RoundCap,
Qt.PenJoinStyle.RoundJoin,
)
painter.strokePath(path, pen)
painter.fillPath(path, QBrush(self.m_contentColor))

View File

@ -0,0 +1,7 @@
from qtsymbols import *
from rendertext.internal.textbrowser.miaobian import TextLine as TB1
class TextLine(TB1):
def colorpair(self):
return QColor(self.basecolor), QColor(self.config["fillcolor"])

View File

@ -0,0 +1,21 @@
from qtsymbols import *
from rendertext.internal.textbrowser.base import base
class TextLine(base):
def usingcolor(self):
return self.basecolor
def paintText(self, painter: QPainter):
path = QPainterPath()
text = self.text()
font = self.font()
font_m = QFontMetrics(font)
path.addText(
0,
font_m.ascent(),
font,
text,
)
painter.fillPath(path, QBrush(self.usingcolor()))

View File

@ -0,0 +1,25 @@
from qtsymbols import *
import uuid
def gen_html(configs, text, fm, fs, bold, atcenter, color):
align = "text-align: center;" if atcenter else ""
bold = "font-weight: bold;" if bold else ""
_id = f"luna_{uuid.uuid4()}"
ntimes = ""
for i in range(configs["shadowforce"]):
ntimes += f"0px 0px {fs*0.4}px {color}"
if i == configs["shadowforce"] - 1:
ntimes += ";"
else:
ntimes += ","
style = f"""<style>#{_id}{{
font-family: {fm};
font-size: {fs}pt;
color:{configs['fillcolor']};
{bold}
text-shadow:{ntimes};
{align}
}}</style>"""
return style + f'<div id="{_id}">{text}</div>'

View File

@ -0,0 +1,17 @@
from qtsymbols import *
import uuid
def gen_html(configs, text, fm, fs, bold, atcenter, color):
align = "text-align: center;" if atcenter else ""
bold = "font-weight: bold;" if bold else ""
_id = f"luna_{uuid.uuid4()}"
style = f"""<style>#{_id}{{
font-family: {fm};
font-size: {fs}pt;
color:white;
color:{color};
{bold}
{align}
}}</style>"""
return style + f'<div id="{_id}">{text}</div>'

View File

@ -0,0 +1,41 @@
from qtsymbols import *
from myutils.config import globalconfig
class dataget:
def _randomcolor_1(self, word):
if word.get("isdeli", False):
return None
c = QColor("white")
if "cixing" in word:
try:
if globalconfig["cixingcolorshow"][word["cixing"]] == False:
return None
c = QColor(globalconfig["cixingcolor"][word["cixing"]])
except:
pass
return (c.red(), c.green(), c.blue(), globalconfig["showcixing_touming"] / 100)
def _randomcolor(self, word, ignorealpha=False):
color = self._randomcolor_1(word)
if not color:
return None
r, g, b, a = color
if ignorealpha:
a = 1
return f"rgba({r}, {g}, {b}, {a})"
def _getfontinfo(self, origin):
if origin:
fm = globalconfig["fonttype"]
else:
fm = globalconfig["fonttype2"]
return fm, globalconfig["fontsize"], globalconfig["showbold"]
def _getfontinfo_kana(self):
fm, fs, bold = self._getfontinfo(True)
return fm, fs * globalconfig["kanarate"], bold
def _getkanacolor(self):
return globalconfig["jiamingcolor"]

View File

@ -0,0 +1,697 @@
from PyQt5.QtWidgets import QWidget
from qtsymbols import *
from myutils.config import globalconfig
from rendertext.somefunctions import dataget
import gobject, functools, importlib
from traceback import print_exc
from rendertext.internal.textbrowser.base import base
class Qlabel_c(QLabel):
def mousePressEvent(self, ev):
self.pr = True
return super().mousePressEvent(ev)
def mouseMoveEvent(self, ev):
pass
# return super().mouseMoveEvent(ev)
def mouseReleaseEvent(self, event: QMouseEvent):
try:
if self.geometry().contains(self.parent().mapFromGlobal(QCursor.pos())):
try:
if self.pr:
if event.button() == Qt.MouseButton.RightButton:
self.callback(True)
else:
self.callback(False)
except:
print_exc()
self.pr = False
except:
print_exc()
return super().mouseReleaseEvent(event)
def enterEvent(self, a0) -> None:
if self.company:
self.company.setStyleSheet("background-color: rgba(0,0,0,0.5);")
self.setStyleSheet("background-color: rgba(0,0,0,0.5);")
return super().enterEvent(a0)
def leaveEvent(self, a0) -> None:
if self.company:
self.company.setStyleSheet("background-color: rgba(0,0,0,0.01);")
self.setStyleSheet("background-color: rgba(0,0,0,0.01);")
return super().leaveEvent(a0)
class TextBrowser(QWidget, dataget):
contentsChanged = pyqtSignal(QSize)
def contentchangedfunction(self):
sz = self.textbrowser.document().size().toSize()
self.textbrowser.resize(self.width(), sz.height())
self.resize(self.width(), sz.height())
self.contentsChanged.emit(QSize(sz.width(), sz.height()))
def resizeEvent(self, event: QResizeEvent):
self.atback2.resize(event.size())
self.toplabel2.resize(event.size())
self.masklabel.resize(event.size())
def setselectable(self, b):
self.masklabel.setHidden(b)
def __init__(self, parent) -> None:
super().__init__(parent)
self.atback2 = QLabel(self)
self.atback2.setMouseTracking(True)
self.toplabel2 = QLabel(self)
self.toplabel2.setMouseTracking(True)
self.textbrowser = QTextBrowser(self)
self.textbrowser.document().contentsChanged.connect(self.contentchangedfunction)
self.tranparentcolor = QColor()
self.tranparentcolor.setAlpha(0)
self.textbrowser.setTextColor(self.tranparentcolor)
self.textbrowser.setStyleSheet(
"border-width: 0;\
border-style: outset;\
background-color: rgba(0, 0, 0, 0)"
)
self.textcursor = self.textbrowser.textCursor()
self.textbrowser.setVerticalScrollBarPolicy(
Qt.ScrollBarPolicy.ScrollBarAlwaysOff
)
self.textbrowser.setHorizontalScrollBarPolicy(
Qt.ScrollBarPolicy.ScrollBarAlwaysOff
)
self.masklabel = QLabel(self.textbrowser)
self.masklabel.setMouseTracking(True)
self.savetaglabels = []
self.searchmasklabels_clicked = []
self.searchmasklabels = []
self.backcolorlabels = []
self.yinyinglabels = []
self.yinyinglabels_idx = 0
self.yinyingpos = 0
self.yinyingposline = 0
self.lastcolor = None
self.blockcount = 0
self.iteryinyinglabelsave = {}
self.saveiterclasspointer = {}
self.resets1()
def resets1(self):
self.currenttype = globalconfig["rendertext_using_internal"]["textbrowser"]
try:
__ = importlib.import_module(
f"rendertext.internal.textbrowser.{self.currenttype}"
)
except:
self.currenttype = globalconfig["rendertext_using_internal"][
"textbrowser"
] = list(globalconfig["rendertext"]["textbrowser"].keys())[0]
__ = importlib.import_module(
f"rendertext.internal.textbrowser.{self.currenttype}"
)
self.currentclass = functools.partial(__.TextLine, self.currenttype)
def resets(self):
for label in self.searchmasklabels:
label.hide()
for label in self.searchmasklabels_clicked:
label.hide()
for label in self.savetaglabels:
label.hide()
self.yinyinglabels_idx = 0
for label in self.yinyinglabels:
label.hide()
for klass, labels in self.iteryinyinglabelsave.items():
for label in labels[0]:
label.hide()
labels[1] = 0
if self.currenttype == globalconfig["rendertext_using_internal"]["textbrowser"]:
return
self.resets1()
for label in self.searchmasklabels:
label.deleteLater()
self.searchmasklabels.clear()
for label in self.searchmasklabels_clicked:
label.deleteLater()
self.searchmasklabels_clicked.clear()
for label in self.savetaglabels:
label.deleteLater()
self.savetaglabels.clear()
self.yinyinglabels_idx = 0
for label in self.yinyinglabels:
label.deleteLater()
self.yinyinglabels.clear()
for klass, labels in self.iteryinyinglabelsave.items():
for label in labels[0]:
label.deleteLater()
labels[0].clear()
labels[1] = 0
self.iteryinyinglabelsave.clear()
def setselectable(self, b):
self.masklabel.setHidden(b)
def _createqfont(self, origin):
fm, fs, bold = self._getfontinfo(origin)
font = QFont()
font.setFamily(fm)
font.setPointSizeF(fs)
font.setBold(bold)
return font
def _setnextfont(self, font):
self.textbrowser.moveCursor(QTextCursor.MoveOperation.End)
f = QTextCharFormat()
f.setFont(font)
f.setForeground(self.tranparentcolor)
c = self.textbrowser.textCursor()
c.setCharFormat(f)
self.textbrowser.setTextCursor(c)
def iter_append(self, iter_context_class, origin, atcenter, text, color, cleared):
self._textbrowser_iter_append(
iter_context_class, origin, atcenter, text, color, cleared
)
def _textbrowser_iter_append(
self, iter_context_class, origin, atcenter, text, color, cleared
):
if iter_context_class not in self.saveiterclasspointer:
self._textbrowser_append(origin, atcenter, " ", [], color, cleared)
self.saveiterclasspointer[iter_context_class] = {
"currtext": "",
"curr": self._getcurrpointer(),
"start": self._getcurrpointer(),
}
currbefore = self.saveiterclasspointer[iter_context_class]["curr"]
currlen = len(self.saveiterclasspointer[iter_context_class]["currtext"])
if len(text) < currlen:
self._deletebetween(
self.saveiterclasspointer[iter_context_class]["start"] + len(text),
self.saveiterclasspointer[iter_context_class]["curr"],
)
else:
newtext = text[currlen:]
self._insertatpointer(
self.saveiterclasspointer[iter_context_class]["start"] + currlen,
newtext,
)
self.saveiterclasspointer[iter_context_class]["currtext"] = text
currcurrent = self._getcurrpointer()
self.saveiterclasspointer[iter_context_class]["curr"] = currcurrent
currchange = currcurrent - currbefore
for klass in self.saveiterclasspointer:
if klass == iter_context_class:
continue
if self.saveiterclasspointer[klass]["curr"] > currbefore:
self.saveiterclasspointer[klass]["curr"] += currchange
self.saveiterclasspointer[klass]["start"] += currchange
self._showyinyingtext2(
color,
iter_context_class,
self.saveiterclasspointer[iter_context_class]["start"],
text,
self._createqfont(origin),
)
def append(self, origin, atcenter, text, tag, flags, color, cleared):
isshowhira, isshow_fenci, isfenciclick = flags
self._textbrowser_append(
origin, atcenter, text, tag if isshowhira else [], color, cleared
)
if isshow_fenci or isfenciclick:
self.addsearchwordmask(
isshow_fenci,
isfenciclick,
tag,
text,
gobject.baseobject.clickwordcallback,
)
def _getqalignment(self, atcenter):
return Qt.AlignmentFlag.AlignCenter if atcenter else Qt.AlignmentFlag.AlignLeft
def _textbrowser_append(self, origin, atcenter, text, tag, color, cleared):
font = self._createqfont(origin)
self._setnextfont(font)
self.textbrowser.setAlignment(self._getqalignment(atcenter))
if cleared:
_space = ""
self.blockcount = 0
b1 = 0
else:
_space = "\n"
b1 = self.textbrowser.document().blockCount()
self.textbrowser.insertPlainText(_space + text)
b2 = self.textbrowser.document().blockCount()
fh = globalconfig["extra_space"]
for i in range(self.blockcount, self.textbrowser.document().blockCount()):
b = self.textbrowser.document().findBlockByNumber(i)
tf = b.blockFormat()
if isqt5:
lht = QTextBlockFormat.LineHeightTypes.LineDistanceHeight
else:
lht = 4
tf.setLineHeight(fh, lht)
self.textcursor.setPosition(b.position())
self.textcursor.setBlockFormat(tf)
self.textbrowser.setTextCursor(self.textcursor)
self.blockcount = self.textbrowser.document().blockCount()
if len(tag) > 0:
self._addtag(tag)
self._showyinyingtext(b1, b2, color, font)
def _getcurrpointer(self):
return self.textcursor.position()
def _insertatpointer(self, pointer, text):
self.textcursor.setPosition(pointer)
self.textbrowser.setTextCursor(self.textcursor)
self.textbrowser.insertPlainText(text)
def _deletebetween(self, p1, p2):
self.textcursor.setPosition(p1, QTextCursor.MoveMode.MoveAnchor)
self.textcursor.setPosition(p2, QTextCursor.MoveMode.KeepAnchor)
self.textcursor.removeSelectedText()
def _showyinyingtext2(self, color, iter_context_class, pos, text, font):
if iter_context_class not in self.iteryinyinglabelsave:
self.iteryinyinglabelsave[iter_context_class] = [[], 0]
maxh = 0
maxh2 = 9999999
for label in self.iteryinyinglabelsave[iter_context_class][0]:
maxh2 = min(label.pos().y(), maxh2)
if label.isVisible() == False:
continue
label.hide()
maxh = max(label.pos().y(), maxh)
subtext = []
subpos = []
lastpos = None
posx = pos
for i in range(len(text)):
self.textcursor.setPosition(posx)
posx += 1
tl1 = self.textbrowser.cursorRect(self.textcursor).topLeft()
if lastpos is None or tl1.y() != lastpos.y() or text[i] == "\n":
lastpos = tl1
subpos.append(lastpos)
subtext.append("")
subtext[-1] += text[i]
maxnewh = 0
for i in range(len(subtext)):
if self.iteryinyinglabelsave[iter_context_class][1] >= len(
self.iteryinyinglabelsave[iter_context_class][0]
):
self.iteryinyinglabelsave[iter_context_class][0].append(
self.currentclass(self.toplabel2)
)
maxnewh = max(maxnewh, subpos[i].y())
_ = self.iteryinyinglabelsave[iter_context_class][0][
self.iteryinyinglabelsave[iter_context_class][1]
]
_.setColor(color)
_.setText(subtext[i])
_.setFont(font)
_.adjustSize()
_.move(subpos[i])
_.show()
self.iteryinyinglabelsave[iter_context_class][1] += 1
if maxh:
if maxnewh == 0:
maxnewh = maxh2
for label in self.yinyinglabels:
if label.isVisible() == False:
continue
if label.pos().y() > maxh:
label.move(
QPoint(label.pos().x(), label.pos().y() + maxnewh - maxh)
)
for klass in self.iteryinyinglabelsave:
if klass == iter_context_class:
continue
for label in self.iteryinyinglabelsave[klass][0]:
if label.isVisible() == False:
continue
if label.pos().y() > maxh:
label.move(
QPoint(label.pos().x(), label.pos().y() + maxnewh - maxh)
)
def _showyinyingtext(self, b1, b2, color, font):
linei = self.yinyingposline
doc = self.textbrowser.document()
block = doc.findBlockByNumber(0)
for blocki in range(b1, b2):
block = doc.findBlockByNumber(blocki)
layout = block.layout()
blockstart = block.position()
lc = layout.lineCount()
for lineii in range(lc):
line = layout.lineAt(lineii)
s = line.textStart()
l = line.textLength()
self.textcursor.setPosition(blockstart + s)
self.textbrowser.setTextCursor(self.textcursor)
tl1 = self.textbrowser.cursorRect(self.textcursor).topLeft()
if self.yinyinglabels_idx >= len(self.yinyinglabels):
self.yinyinglabels.append(self.currentclass(self.toplabel2))
_ = self.yinyinglabels[self.yinyinglabels_idx]
self.yinyinglabels_idx += 1
_.setColor(color)
_.setText(block.text()[s : s + l])
_.setFont(font)
_.adjustSize()
_.move(tl1)
_.show()
linei += 1
self.yinyingposline = linei
def addsearchwordmask(self, isshow_fenci, isfenciclick, x, raw, callback=None):
if len(x) == 0:
return
# print(x)
pos = 0
labeli = 0
self.textcursor.setPosition(0)
self.textbrowser.setTextCursor(self.textcursor)
idx = 0
heigth, __, _ = self._getfh(False)
for word in x:
idx += 1
l = len(word["orig"])
tl1 = self.textbrowser.cursorRect(self.textcursor).topLeft()
tl4 = self.textbrowser.cursorRect(self.textcursor).bottomRight()
if True:
self.textcursor.setPosition(pos + l)
self.textbrowser.setTextCursor(self.textcursor)
tl2 = self.textbrowser.cursorRect(self.textcursor).bottomRight()
tl3 = self.textbrowser.cursorRect(self.textcursor).topLeft()
color = self._randomcolor(word)
if color:
if word["orig"] not in ["\n", " ", ""]:
if labeli >= len(self.searchmasklabels) - 1:
ql = QLabel(self.atback2)
ql.setMouseTracking(True)
self.searchmasklabels.append(ql)
ql = Qlabel_c(self.textbrowser)
ql.setMouseTracking(True)
ql.setStyleSheet("background-color: rgba(0,0,0,0.01);")
self.searchmasklabels_clicked.append(ql)
ql = QLabel(self.atback2)
ql.setMouseTracking(True)
self.searchmasklabels.append(ql)
ql = Qlabel_c(self.textbrowser)
ql.setMouseTracking(True)
ql.setStyleSheet("background-color: rgba(0,0,0,0.01);")
self.searchmasklabels_clicked.append(ql)
if tl1.y() != tl3.y():
for __i in range(len(word["orig"])):
self.textcursor.setPosition(pos + __i)
self.textbrowser.setTextCursor(self.textcursor)
_tl = self.textbrowser.cursorRect(
self.textcursor
).topLeft()
if _tl.y() != tl1.y():
break
self.textcursor.setPosition(pos + l)
self.textbrowser.setTextCursor(self.textcursor)
__fm = self._getfh(False, getfm=True)
w1 = int(__fm.size(0, word["orig"][:__i]).width())
w2 = int(__fm.size(0, word["orig"][__i:]).width())
pos1 = (
tl1.x() + 1,
tl1.y(),
w1 - 2,
int(heigth),
)
pos2 = tl3.x() + 1 - w2, tl3.y(), w2 - 2, int(heigth)
if isfenciclick:
self.searchmasklabels_clicked[labeli].setGeometry(*pos1)
self.searchmasklabels_clicked[labeli].show()
self.searchmasklabels_clicked[labeli].company = (
self.searchmasklabels_clicked[labeli + 1]
)
if callback:
self.searchmasklabels_clicked[labeli].callback = (
functools.partial(callback, (word))
)
self.searchmasklabels_clicked[labeli + 1].setGeometry(
*pos2
)
self.searchmasklabels_clicked[labeli + 1].show()
self.searchmasklabels_clicked[labeli + 1].company = (
self.searchmasklabels_clicked[labeli]
)
if callback:
self.searchmasklabels_clicked[
labeli + 1
].callback = functools.partial(callback, (word))
if isshow_fenci:
self.searchmasklabels[labeli].setGeometry(*pos1)
self.searchmasklabels[labeli].setStyleSheet(
"background-color: {};".format(color)
)
self.searchmasklabels[labeli].show()
self.searchmasklabels[labeli + 1].setGeometry(*pos2)
self.searchmasklabels[labeli + 1].setStyleSheet(
"background-color: {};".format(color)
)
self.searchmasklabels[labeli + 1].show()
labeli += 2
else:
pos1 = (
tl1.x() + 1,
tl1.y(),
tl2.x() - tl1.x() - 2,
int(heigth),
)
if isfenciclick:
self.searchmasklabels_clicked[labeli].setGeometry(*pos1)
self.searchmasklabels_clicked[labeli].company = None
self.searchmasklabels_clicked[labeli].show()
if callback:
self.searchmasklabels_clicked[labeli].callback = (
functools.partial(callback, word)
)
if isshow_fenci:
self.searchmasklabels[labeli].setGeometry(*pos1)
self.searchmasklabels[labeli].setStyleSheet(
"background-color: {};".format(color)
)
self.searchmasklabels[labeli].show()
labeli += 1
tl1 = tl3
tl4 = tl2
pos += l
def _getfh(self, half, origin=True, getfm=False):
font = QFont()
font.setBold(globalconfig["showbold"])
if origin:
font.setFamily(globalconfig["fonttype"])
else:
font.setFamily(globalconfig["fonttype2"])
# font.setPixelSize(int(globalconfig['fontsize']) )
if half:
font.setPointSizeF((globalconfig["fontsize"]) * globalconfig["kanarate"])
else:
font.setPointSizeF((globalconfig["fontsize"]))
fm = QFontMetricsF(font)
if getfm:
return fm
return fm.height(), fm.ascent(), font
def _addtag(self, x):
pos = 0
fasall, _, fontorig = self._getfh(False)
fha, fascent, fonthira = self._getfh(True)
for i in range(0, self.textbrowser.document().blockCount()):
b = self.textbrowser.document().findBlockByNumber(i)
tf = b.blockFormat()
if isqt5:
lht = QTextBlockFormat.LineHeightTypes.FixedHeight
else:
lht = 2
tf.setLineHeight(fasall + fha, lht)
self.textcursor.setPosition(b.position())
self.textcursor.setBlockFormat(tf)
self.textbrowser.setTextCursor(self.textcursor)
x = self.nearmerge(x, pos, fonthira, fontorig)
self.settextposcursor(pos)
savetaglabels_idx = 0
for word in x:
l = len(word["orig"])
tl1 = self.textbrowser.cursorRect(self.textcursor).topLeft()
self.settextposcursor(pos + l)
pos += l
tl2 = self.textbrowser.cursorRect(self.textcursor).topLeft()
if word["hira"] == word["orig"]:
continue
# print(tl1,tl2,word['hira'],self.textbrowser.textCursor().position())
if word["orig"] == " ":
continue
if savetaglabels_idx >= len(self.savetaglabels):
self.savetaglabels.append(self.currentclass(self.atback2))
self.solvejiaminglabel(
self.savetaglabels[savetaglabels_idx], word, fonthira, tl1, tl2, fascent
)
savetaglabels_idx += 1
def settextposcursor(self, pos):
self.textcursor.setPosition(pos)
self.textbrowser.setTextCursor(self.textcursor)
def nearmerge(self, x, startpos, fonthira, fontorig):
pos = startpos
linex = []
newline = []
self.settextposcursor(pos)
_metrichira = QFontMetricsF(fonthira)
_metricorig = QFontMetricsF(fontorig)
for i, word in enumerate(x):
word["orig_w"] = _metricorig.size(0, word["orig"]).width()
word["hira_w"] = _metrichira.size(0, word["hira"]).width()
# print(word['hira'],word['hira_w'])
newline.append(word)
l = len(word["orig"])
tl1 = self.textbrowser.cursorRect(self.textcursor).topLeft()
self.settextposcursor(pos + l)
pos += l
tl2 = self.textbrowser.cursorRect(self.textcursor).topLeft()
# print(tl1,tl2,word['hira'],self.textbrowser.textCursor().position())
if tl1.y() != tl2.y() or i == len(x) - 1:
linex.append(newline)
newline = []
res = []
for line in linex:
while True:
allnotbig = True
newline = []
canmerge = False
for word in line:
if (
word["hira"] == word["orig"]
or word["hira"] == ""
or word["orig"] == ""
):
newline.append(word.copy())
canmerge = False
else:
if (
len(newline) > 0
and canmerge
and (
word["hira_w"] + newline[-1]["hira_w"]
> word["orig_w"] + newline[-1]["orig_w"]
)
):
# print(word['hira'],word['hira_w'],newline[-1]['hira_w'],word['orig_w'],newline[-1]['orig_w'])
newline[-1]["hira"] += word["hira"]
newline[-1]["orig"] += word["orig"]
newline[-1]["hira_w"] += word["hira_w"]
newline[-1]["orig_w"] += word["orig_w"]
allnotbig = False
else:
newline.append(word.copy())
canmerge = True
line = newline
if allnotbig:
break
res += newline
newline = []
self.settextposcursor(startpos)
return res
def solvejiaminglabel(self, _: base, word, font, tl1, tl2, fh):
color = self._getkanacolor()
_.setColor(color)
_.setText(word["hira"])
_.setFont(font)
_.adjustSize()
w = _.width()
if tl1.y() != tl2.y():
# print(label,word)
x = tl1.x()
if x + w / 2 < self.textbrowser.width():
x = tl1.x()
y = tl1.y() - fh
else:
x = tl2.x() - w
y = tl2.y() - fh
else:
x = tl1.x() / 2 + tl2.x() / 2 - w / 2
y = tl2.y() - fh
_.move(QPoint(int(x), int(y)))
_.show()
return _
def clear(self):
self.resets()
self.yinyingpos = 0
self.yinyingposline = 0
self.textbrowser.clear()
self.saveiterclasspointer.clear()

View File

@ -0,0 +1,183 @@
from PyQt5.QtWidgets import QWidget
from qtsymbols import *
from rendertext.somefunctions import dataget
import gobject, uuid, json, importlib, base64, os
from urllib.parse import quote, unquote
from myutils.config import globalconfig
from gui.usefulwidget import WebivewWidget
testsavejs = False
# example
def extrastyle(rootdivid):
with open(
r"C:\Users\11737\Pictures\asutoraea\yande.re 289904 astralair_no_shiroki_towa favorite game_cg miko shida_kazuhiro yuuki_(astralair_no_shiroki_towa).png",
"rb",
) as ff:
b64 = base64.b64encode(ff.read()).decode("utf-8")
extra = f"""#{rootdivid}::before
{{
background-image: url('data:image/jpeg;base64,{b64}') ;
opacity: 0.5;
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
}}"""
return extra
class TextBrowser(QWidget, dataget):
contentsChanged = pyqtSignal(QSize)
def resizeEvent(self, event: QResizeEvent):
self.webivewwidget.resize(event.size().width(), event.size().height())
def __init__(self, parent) -> None:
super().__init__(parent)
self.webivewwidget = WebivewWidget(self)
self.webivewwidget.navigate("about:blank")
self.webivewwidget.set_transparent_background()
self.webivewwidget.webview.bind("calllunaclickedword", self.calllunaclickedword)
self.webivewwidget.webview.bind(
"calllunaheightchange", self.calllunaheightchange
)
self.rootdivid = f"luna_{uuid.uuid4()}"
self.saveiterclasspointer = {}
self.testeval(
f"""
document.write(`<div id="{self.rootdivid}"></div>`);
"""
)
self.setglobalstyle(self.rootdivid)
def testeval(self, js):
js += ";\n"
if testsavejs:
with open("1.js", "a", encoding="utf8") as ff:
ff.write(js)
self.webivewwidget.webview.eval(js)
def setglobalstyle(self, rootdivid):
if 0:
extra = extrastyle(rootdivid)
else:
if os.path.exists("userconfig/extrastyle.py"):
extrastyle = importlib.import_module("extrastyle").extrastyle
extra = extrastyle(rootdivid)
else:
extra = ""
self.testeval(
f"""
document.write(`<style>
body{{
overflow:hidden;
margin: 0;
}}
{extra}
</style>`);
"""
)
def setselectable(self, b):
pass
def calllunaheightchange(self, h):
self.contentsChanged.emit(QSize(self.width(), h))
def internalheighchange(self):
self.testeval(
f'calllunaheightchange(document.getElementById("{self.rootdivid}").offsetHeight)'
)
def iter_append(self, iter_context_class, origin, atcenter, text, color, cleared):
if iter_context_class not in self.saveiterclasspointer:
_id = self.createtextlineid()
self.saveiterclasspointer[iter_context_class] = _id
_id = self.saveiterclasspointer[iter_context_class]
self._webview_append(_id, origin, atcenter, text, [], [], color)
self.internalheighchange()
def createtextlineid(self):
_id = f"luna_{uuid.uuid4()}"
ptext = f'<div id="{_id}"></div>'
self.testeval(
f"""
document.getElementById("{self.rootdivid}").innerHTML+=`{ptext}`;
"""
)
return _id
def append(self, origin, atcenter, text, tag, flags, color, cleared):
_id = self.createtextlineid()
self._webview_append(_id, origin, atcenter, text, tag, flags, color)
def calllunaclickedword(self, packedwordinfo):
gobject.baseobject.clickwordcallback(json.loads(unquote(packedwordinfo)), False)
def gen_html(self, text, fm, fs, bold, atcenter, color):
currenttype = globalconfig["rendertext_using_internal"]["webview"]
configs = globalconfig["rendertext"]["webview"][currenttype].get("args", {})
try:
__ = importlib.import_module(f"rendertext.internal.webview.{currenttype}")
except:
globalconfig["rendertext_using_internal"]["webview"] = currenttype = list(
globalconfig["rendertext"]["webview"].keys()
)[0]
__ = importlib.import_module(f"rendertext.internal.webview.{currenttype}")
return __.gen_html(configs, text, fm, fs, bold, atcenter, color)
def _webview_append(self, _id, origin, atcenter, text, tag, flags, color):
if len(tag):
isshowhira, isshow_fenci, isfenciclick = flags
fm, fskana, bold = self._getfontinfo_kana()
kanacolor = self._getkanacolor()
text = ""
for word in tag:
color1 = self._randomcolor(word, ignorealpha=True)
if isshow_fenci and color1:
style = f' style="color: {color1};" '
else:
style = ""
if isfenciclick:
click = f'''onclick="calllunaclickedword('{quote(json.dumps(word))}')"'''
else:
click = ""
text += f"""<div {style} {click}>""" + word["orig"] + "</div>"
if (word["orig"] != word["hira"]) and isshowhira:
text += (
f"<rt>"
+ self.gen_html(word["hira"], fm, fskana, bold, True, kanacolor)
+ "</rt>"
)
else:
text += "<rt></rt>"
text = f"<ruby>" + text + "</ruby>"
fm, fs, bold = self._getfontinfo(origin)
text = self.gen_html(text, fm, fs, bold, atcenter, color)
self.testeval(f"document.getElementById(`{_id}`).innerHTML+=`{text}`")
self.internalheighchange()
def clear(self):
self.testeval(
f"""
document.getElementById("{self.rootdivid}").innerHTML="";
"""
)
self.saveiterclasspointer.clear()

View File

@ -413,6 +413,9 @@ put_ZoomFactor.argtypes = c_void_p, c_double
put_PreferredColorScheme = utilsdll.put_PreferredColorScheme
put_PreferredColorScheme.argtypes = c_void_p, c_int
put_PreferredColorScheme.restype = c_long
set_transparent_background = utilsdll.set_transparent_background
set_transparent_background.argtypes = (c_void_p,)
clipboard_callback = utilsdll.clipboard_callback
clipboard_callback.argtypes = (c_void_p,)

View File

@ -15,8 +15,126 @@
"read_translator": 0,
"disappear_delay": 5,
"network": 1,
"webview_textbrowser": false,
"imagewrapmode": 0,
"primitivtemetaorigin": "vid",
"rendertext_using": "textbrowser",
"rendertext_using_internal": {
"webview": "faguang",
"textbrowser": "faguang"
},
"rendertext": {
"webview": {
"normal": {
"name": "普通字体"
},
"faguang": {
"name": "发光字体",
"args": {
"fillcolor": "#eeeeee",
"shadowforce": 5
},
"argstype": {
"fillcolor": {
"name": "填充颜色",
"type": "colorselect"
},
"shadowforce": {
"name": "发光亮度",
"type": "intspin",
"min": 1,
"max": 100,
"step": 1
}
}
}
},
"textbrowser": {
"normal": {
"name": "普通字体"
},
"miaobian0": {
"name": "描边字体_1",
"args": {
"fillcolor": "#eeeeee",
"width": 1
},
"argstype": {
"fillcolor": {
"name": "填充颜色",
"type": "colorselect"
},
"width": {
"name": "描边宽度",
"type": "spin",
"min": 0.1,
"max": 100,
"step": 0.1
}
}
},
"miaobian1": {
"name": "描边字体_2",
"args": {
"fillcolor": "#eeeeee",
"width": 3
},
"argstype": {
"fillcolor": {
"name": "填充颜色",
"type": "colorselect"
},
"width": {
"name": "描边宽度",
"type": "spin",
"min": 0.1,
"max": 100,
"step": 0.1
}
}
},
"miaobian2": {
"name": "描边字体_3",
"args": {
"fillcolor": "#eeeeee",
"width": 3
},
"argstype": {
"fillcolor": {
"name": "填充颜色",
"type": "colorselect"
},
"width": {
"name": "描边宽度",
"type": "spin",
"min": 0.1,
"max": 100,
"step": 0.1
}
}
},
"faguang": {
"name": "发光字体",
"args": {
"fillcolor": "#eeeeee",
"shadowforce": 5
},
"argstype": {
"fillcolor": {
"name": "填充颜色",
"type": "colorselect"
},
"shadowforce": {
"name": "发光亮度",
"type": "intspin",
"min": 1,
"max": 100,
"step": 1
}
}
}
}
},
"metadata": {
"vndb": {
"name": "vndb",
@ -202,10 +320,6 @@
"extra_space": 0,
"fonttype": "Arial",
"fonttype2": "Arial",
"miaobianwidth2": 3,
"miaobianwidth": 1,
"miaobiancolor": "#eeeeee",
"zitiyangshi2": 5,
"hira_vis_type": 0,
"iskongxin": true,
"isshowrawtext": true,
@ -563,8 +677,6 @@
"showShadow": false,
"shadowcolor": "blue",
"ocr_hori_extend": true,
"shadowforce": 5,
"traceoffset": 2,
"showcixing_touming": 30,
"cixingcolor": {
"形容詞": "aliceblue",

View File

@ -30,7 +30,6 @@
"東北ずん子": "شمال شرق الصين",
"彩云": "سحابة ملونة",
"非管理员": "غير مسؤول",
"空心字体": "خط أجوف",
"用户词典": "قاموس المستخدم",
"预翻译采用模糊匹配": "غامض مطابقة",
"汉语翻译结果繁简转换": "الترجمة الصينية نتيجة التحويل",
@ -206,7 +205,6 @@
"保存路径": "حفظ المسار",
"搜索持续时间(s)": "مدة البحث ( ق )",
"使用代理": "استخدام وكيل",
"特殊字体样式填充颜色": "نمط الخط الخاص ملء اللون",
"使用代理的项目": "استخدام وكيل المشروع",
"优先录制的翻译源": "يفضل تسجيل مصدر الترجمة",
"字体缩小(可长按)": "حجم الخط ( الصحافة طويلة )",
@ -484,7 +482,6 @@
"普通字体": "الخط العادي",
"3D游戏模式": "لعبة وسائط 3D",
"合并多行识别结果": "دمج نتائج تحديد خط متعددة",
"空心线宽": "جوفاء خط العرض",
"显示": "عرض .",
"选取OCR范围后立即进行一次识别": "التعرف على الفور بعد تحديد نطاق التعرف الضوئي على الحروف",
"琴葉葵": "الباذنجان",
@ -710,10 +707,8 @@
"讯飞OCR": "التعرف الضوئي على الحروف",
"发光字体": "خط الانارة",
"发光亮度": "سطوع مضيئة",
"投影距离": "المسافة المتوقعة",
"最大缓冲区长度": "أقصى طول المخزن المؤقت",
"最大缓存文本长度": "أقصى طول النص مخبأ",
"投影": "إسقاطات",
"半径": "نصف قطر",
"圆角": "فيليه",
"立即应用": "التطبيق الفوري",
@ -797,5 +792,6 @@
"超过时截断而非过滤": "اقتطاع بدلا من الترشيح عند تجاوز",
"兼容接口": "واجهة متوافقة",
"调试浏览器": "تصحيح المتصفح",
"手动翻译": "دليل الترجمة"
"手动翻译": "دليل الترجمة",
"显示引擎": "عرض المحرك"
}

View File

@ -88,7 +88,6 @@
"OCR范围框颜色": "OCR範圍框顏色",
"OCR范围框宽度": "OCR範圍框寬度",
"普通字体": "普通字體",
"空心字体": "空心字體",
"描边字体": "描邊字體",
"显示设置": "顯示設定",
"不透明度": "不透明度",
@ -99,11 +98,9 @@
"翻译器字体类型": "翻譯器字體類型",
"设置界面字体类型": "設定介面字體類型",
"字体大小": "字體大小",
"特殊字体样式填充颜色": "特殊字體樣式填充顏色",
"字体样式": "字體樣式",
"加粗字体": "加粗字體",
"居中显示": "居中顯示",
"空心线宽": "空心線寬",
"描边宽度": "描邊寬度",
"显示显示原文按钮": "顯示顯示原文按鈕",
"显示复制原文按钮": "顯示複製原文按鈕",
@ -710,10 +707,8 @@
"讯飞OCR": "訊飛OCR",
"发光字体": "發光字體",
"发光亮度": "發光亮度",
"投影距离": "投影距離",
"最大缓冲区长度": "最大緩衝區長度",
"最大缓存文本长度": "最大緩存文字長度",
"投影": "投影",
"半径": "半徑",
"圆角": "圓角",
"立即应用": "立即應用",
@ -797,5 +792,6 @@
"超过时截断而非过滤": "超過時截斷而非過濾",
"兼容接口": "相容介面",
"调试浏览器": "調試瀏覽器",
"手动翻译": "手動翻譯"
"手动翻译": "手動翻譯",
"显示引擎": "顯示引擎"
}

View File

@ -94,7 +94,6 @@
"替换": "replace",
"補助記号": "Subsidy mark",
"繁体中文": "Traditional Chinese",
"空心线宽": "Void lineweight",
"删除游戏": "Delete Game",
"和源窗口相同": "Same as source window",
"自定义python处理": "Customized python processing",
@ -138,7 +137,6 @@
"翻译结果繁简体显示": "Display of translation results in simplified and complex form",
"显示设置": "Display Settings",
"显示/隐藏原文": "Show/hide original text",
"空心字体": "White Font",
"设置界面字体类型": "Set interface font type",
"小牛api": "Maverick api",
"HOOK设置": "HOOK Settings",
@ -152,7 +150,6 @@
"感動詞": "Moving words",
"字数统计": "word count",
"描边字体": "Stroke font",
"特殊字体样式填充颜色": "Special Font Style Fill Color",
"字体缩小(可长按)": "Reduce font size (long press is allowed)",
"不透明度": "Opacity",
"形容詞": "Adjective",
@ -710,10 +707,8 @@
"讯飞OCR": "IFlytek OCR",
"发光字体": "Luminous font",
"发光亮度": "luminance",
"投影距离": "Projection distance",
"最大缓冲区长度": "Maximum buffer length",
"最大缓存文本长度": "Maximum cached text length",
"投影": "projection",
"半径": "radius",
"圆角": "fillet",
"立即应用": "apply now",
@ -797,5 +792,6 @@
"超过时截断而非过滤": "Truncate instead of filtering when exceeded",
"兼容接口": "Compatible interface",
"调试浏览器": "Debugging browser",
"手动翻译": "Manual translation"
"手动翻译": "Manual translation",
"显示引擎": "Display Engine"
}

View File

@ -88,7 +88,6 @@
"OCR范围框颜色": "Color del cuadro de rango OCR",
"OCR范围框宽度": "Ancho del marco de rango OCR",
"普通字体": "Fuente normal",
"空心字体": "Fuente hueca",
"描边字体": "Fuente de dibujo",
"显示设置": "Configuración de la pantalla",
"不透明度": "Opacidad",
@ -99,11 +98,9 @@
"翻译器字体类型": "Tipo de fuente del traductor",
"设置界面字体类型": "Establecer el tipo de letra de la interfaz",
"字体大小": "Tamaño de la fuente",
"特殊字体样式填充颜色": "Color de relleno de estilo de fuente especial",
"字体样式": "Estilo de fuente",
"加粗字体": "Negrita",
"居中显示": "Mostrar en el Centro",
"空心线宽": "Ancho de línea hueco",
"描边宽度": "Ancho de dibujo",
"显示显示原文按钮": "Mostrar el botón mostrar texto original",
"显示复制原文按钮": "Muestra el botón Copiar texto original",
@ -710,10 +707,8 @@
"讯飞OCR": "IFLYTEK OCR",
"发光字体": "Fuente luminosa",
"发光亮度": "Brillo luminoso",
"投影距离": "Distancia de proyección",
"最大缓冲区长度": "Longitud máxima de la zona de amortiguación",
"最大缓存文本长度": "Longitud máxima del texto en caché",
"投影": "Proyección",
"半径": "Radio",
"圆角": "Redondeado",
"立即应用": "Aplicar de inmediato",
@ -797,5 +792,6 @@
"超过时截断而非过滤": "Cortar en lugar de filtrar cuando se supera el tiempo",
"兼容接口": "Interfaz compatible",
"调试浏览器": "Depurar el navegador",
"手动翻译": "Traducción manual"
"手动翻译": "Traducción manual",
"显示引擎": "Motor de visualización"
}

View File

@ -88,7 +88,6 @@
"OCR范围框颜色": "Couleur de la boîte de plage ocr",
"OCR范围框宽度": "Largeur de la boîte de plage ocr",
"普通字体": "Police normale",
"空心字体": "Polices vides",
"描边字体": "Police de bord",
"显示设置": "Paramètres d 'affichage",
"不透明度": "Opacité",
@ -99,11 +98,9 @@
"翻译器字体类型": "Type de police du traducteur",
"设置界面字体类型": "Définir le type de police de l'interface",
"字体大小": "Taille de la police",
"特殊字体样式填充颜色": "Couleurs de remplissage de style de police spécial",
"字体样式": "Style de police",
"加粗字体": "Police en gras",
"居中显示": "Affichage Central",
"空心线宽": "Poids de ligne creux",
"描边宽度": "Largeur de la bordure",
"显示显示原文按钮": "Afficher le bouton afficher le texte original",
"显示复制原文按钮": "Afficher le bouton copier le texte original",
@ -710,10 +707,8 @@
"讯飞OCR": "OCR volant",
"发光字体": "Polices lumineuses",
"发光亮度": "Luminosité lumineuse",
"投影距离": "Distance de projection",
"最大缓冲区长度": "Longueur maximale du tampon",
"最大缓存文本长度": "Longueur maximale du texte mis en cache",
"投影": "Projection",
"半径": "Rayon",
"圆角": "Coins arrondis",
"立即应用": "Appliquer maintenant",
@ -797,5 +792,6 @@
"超过时截断而非过滤": "Troncation au - delà du temps plutôt que filtrage",
"兼容接口": "Interface compatible",
"调试浏览器": "Déboguer le Navigateur",
"手动翻译": "Traduction manuelle"
"手动翻译": "Traduction manuelle",
"显示引擎": "Moteur d'affichage"
}

View File

@ -88,7 +88,6 @@
"OCR范围框颜色": "Colore casella intervallo OCR",
"OCR范围框宽度": "Larghezza casella intervallo OCR",
"普通字体": "Carattere normale",
"空心字体": "Carattere bianco",
"描边字体": "Carattere tratto",
"显示设置": "Impostazioni di visualizzazione",
"不透明度": "Opacità",
@ -99,11 +98,9 @@
"翻译器字体类型": "Tipo di carattere del traduttore",
"设置界面字体类型": "Imposta tipo di carattere dell'interfaccia",
"字体大小": "dimensione del carattere",
"特殊字体样式填充颜色": "Colore speciale di riempimento stile carattere",
"字体样式": "Stile carattere",
"加粗字体": "Carattere grassetto",
"居中显示": "Centra la visualizzazione",
"空心线宽": "Larghezza della linea vuota",
"描边宽度": "Larghezza tratto",
"游戏最小化时窗口隐藏": "Nascondi finestra quando il gioco è minimizzato",
"游戏窗口移动时同步移动": "Sincronizza il movimento quando la finestra di gioco si muove",
@ -710,10 +707,8 @@
"讯飞OCR": "OCR IFlytek",
"发光字体": "Carattere luminoso",
"发光亮度": "luminanza",
"投影距离": "Distanza di proiezione",
"最大缓冲区长度": "Lunghezza massima del buffer",
"最大缓存文本长度": "Lunghezza massima del testo memorizzato nella cache",
"投影": "proiezione",
"半径": "raggio",
"圆角": "filetto",
"立即应用": "Applica ora",
@ -797,5 +792,6 @@
"超过时截断而非过滤": "Truncare invece di filtrare quando superato",
"兼容接口": "Interfaccia compatibile",
"调试浏览器": "Browser di debug",
"手动翻译": "Traduzione manuale"
"手动翻译": "Traduzione manuale",
"显示引擎": "Motore di visualizzazione"
}

View File

@ -88,7 +88,6 @@
"OCR范围框颜色": "OCR範囲ボックス色",
"OCR范围框宽度": "OCR範囲枠幅",
"普通字体": "標準フォント",
"空心字体": "中空フォント",
"描边字体": "線フォント",
"显示设置": "表示設定",
"不透明度": "不透明度ふとうめいど",
@ -99,11 +98,9 @@
"翻译器字体类型": "翻訳機フォントタイプ",
"设置界面字体类型": "インタフェースフォントタイプの設定",
"字体大小": "フォントサイズ",
"特殊字体样式填充颜色": "特殊フォントスタイルの塗りつぶし色",
"字体样式": "フォントスタイル",
"加粗字体": "太字",
"居中显示": "中央揃え",
"空心线宽": "中空線幅",
"描边宽度": "線の幅",
"显示显示原文按钮": "テキスト表示ボタンを表示",
"显示复制原文按钮": "テキストコピーボタンを表示",
@ -710,10 +707,8 @@
"讯飞OCR": "アイフライテックOCR",
"发光字体": "発光フォント",
"发光亮度": "発光輝度",
"投影距离": "とうえいきょり",
"最大缓冲区长度": "最大バッファ長",
"最大缓存文本长度": "最大キャッシュテキスト長",
"投影": "投影",
"半径": "半径はんけい",
"圆角": "フィレット",
"立即应用": "今すぐ適用",
@ -797,5 +792,6 @@
"超过时截断而非过滤": "フィルタではなく超過時にトランケート",
"兼容接口": "互換インタフェース",
"调试浏览器": "デバッグブラウザ",
"手动翻译": "手動翻訳"
"手动翻译": "手動翻訳",
"显示引擎": "ディスプレイエンジン"
}

View File

@ -88,7 +88,6 @@
"OCR范围框颜色": "OCR 범위 상자 색상",
"OCR范围框宽度": "OCR 범위 상자 폭",
"普通字体": "일반 글꼴",
"空心字体": "빈 글꼴",
"描边字体": "테두리 글꼴",
"显示设置": "디스플레이 설정",
"不透明度": "불투명도",
@ -99,11 +98,9 @@
"翻译器字体类型": "번역기 글꼴 유형",
"设置界面字体类型": "인터페이스 글꼴 유형 설정",
"字体大小": "글꼴 크기",
"特殊字体样式填充颜色": "특수 글꼴 스타일 채우기 색상",
"字体样式": "글꼴 스타일",
"加粗字体": "글꼴 굵게 만들기",
"居中显示": "가운데 표시",
"空心线宽": "빈 선가중치",
"描边宽度": "테두리 너비",
"显示显示原文按钮": "원본 보기 단추 보이기",
"显示复制原文按钮": "원본 복사 단추 보이기",
@ -710,10 +707,8 @@
"讯飞OCR": "아이플라이테크 OCR",
"发光字体": "발광 글꼴",
"发光亮度": "광도",
"投影距离": "투영 거리",
"最大缓冲区长度": "최대 버퍼 길이",
"最大缓存文本长度": "최대 캐시 텍스트 길이",
"投影": "투영",
"半径": "반지름",
"圆角": "필렛",
"立即应用": "지금 적용",
@ -797,5 +792,6 @@
"超过时截断而非过滤": "필터링 대신 시간 초과 자르기",
"兼容接口": "호환 인터페이스",
"调试浏览器": "디버그 브라우저",
"手动翻译": "수동 번역"
"手动翻译": "수동 번역",
"显示引擎": "디스플레이 엔진"
}

View File

@ -88,7 +88,6 @@
"OCR范围框颜色": "Kolor pola zakresu OCR",
"OCR范围框宽度": "Szerokość pola zakresu OCR",
"普通字体": "Normalna czcionka",
"空心字体": "Biała czcionka",
"描边字体": "Czcionka kresu",
"显示设置": "Ustawienia wyświetlania",
"不透明度": "Nieprzezroczystość",
@ -99,11 +98,9 @@
"翻译器字体类型": "Typ czcionki tłumacza",
"设置界面字体类型": "Ustaw typ czcionki interfejsu",
"字体大小": "rozmiar czcionki",
"特殊字体样式填充颜色": "Kolor wypełnienia specjalnego stylu czcionki",
"字体样式": "Styl czcionki",
"加粗字体": "Pogrubiona czcionka",
"居中显示": "Środkowy wyświetlacz",
"空心线宽": "Szerokość linii pustej",
"描边宽度": "Szerokość skoku",
"显示显示原文按钮": "Pokaż przycisk Pokaż oryginalny",
"显示复制原文按钮": "Pokaż przycisk Kopiuj oryginał",
@ -710,10 +707,8 @@
"讯飞OCR": "OCR IFlytek",
"发光字体": "Jasna czcionka",
"发光亮度": "luminancja",
"投影距离": "Odległość projekcji",
"最大缓冲区长度": "Maksymalna długość bufora",
"最大缓存文本长度": "Maksymalna długość buforowanego tekstu",
"投影": "projekcja",
"半径": "promień",
"圆角": "filet",
"立即应用": "aplikuj teraz",
@ -797,5 +792,6 @@
"超过时截断而非过滤": "Przycięcie zamiast filtrowania po przekroczeniu",
"兼容接口": "Kompatybilny interfejs",
"调试浏览器": "Debugowanie przeglądarki",
"手动翻译": "Tłumaczenie ręczne"
"手动翻译": "Tłumaczenie ręczne",
"显示引擎": "Silnik wyświetlania"
}

View File

@ -88,7 +88,6 @@
"OCR范围框颜色": "Цвет рамки распознавания",
"OCR范围框宽度": "Ширина рамки распознавания",
"普通字体": "Обычный шрифт",
"空心字体": "Полый шрифт",
"描边字体": "Жирный шрифт",
"显示设置": "Настройки дисплея",
"不透明度": "Непрозрачность",
@ -99,11 +98,9 @@
"翻译器字体类型": "Тип шрифта",
"设置界面字体类型": "Тип шрифта интерфейса",
"字体大小": "Размер шрифта",
"特殊字体样式填充颜色": "Цвет шрифта",
"字体样式": "Стиль шрифта",
"加粗字体": "Жирный шрифт",
"居中显示": "Центрировать",
"空心线宽": "Ширина полой линии",
"描边宽度": "Ширина обрезки",
"显示显示原文按钮": "Кнопка источника текста",
"显示复制原文按钮": "Кнопка копирования текста",
@ -710,10 +707,8 @@
"讯飞OCR": "Сигнал OCR",
"发光字体": "Светящийся шрифт",
"发光亮度": "Светимость",
"投影距离": "Расстояние проекции",
"最大缓冲区长度": "Максимальная длина буфера",
"最大缓存文本长度": "Максимальная длина текста кэша",
"投影": "Проекция",
"半径": "Радиус",
"圆角": "Круглый угол",
"立即应用": "Немедленное применение",
@ -797,5 +792,6 @@
"超过时截断而非过滤": "Преодоление времени вместо фильтрации",
"兼容接口": "Совместимый интерфейс",
"调试浏览器": "Отладка браузера",
"手动翻译": "Ручной перевод"
"手动翻译": "Ручной перевод",
"显示引擎": "Показать движок"
}

View File

@ -7,7 +7,6 @@
"绑定窗口(部分软件不支持)(点击自己取消)": "หน้าต่างผูกพัน (บางส่วนของซอฟต์แวร์ไม่รองรับ) (คลิกที่ตัวเองเพื่อยกเลิก)",
"OCR最长间隔时间(s)": "ช่วงเวลา OCR สูงสุด (s)",
"文本设置": "การตั้งค่าข้อความ",
"特殊字体样式填充颜色": "รูปแบบตัวอักษรพิเศษสีเติม",
"过滤数字": "กรองตัวเลข",
"插入特殊码": "แทรกรหัสพิเศษ",
"移除非选定hook": "ลบ hook ที่ไม่ได้เลือก",
@ -379,7 +378,6 @@
"字体增大(可长按)": "แบบอักษรขยาย (สามารถกดยาว)",
"时间周期执行": "การดำเนินการตามกรอบเวลา",
"请重新下载并关闭杀毒软件后重试": "โปรดลองอีกครั้งหลังจากดาวน์โหลดและปิดโปรแกรมป้องกันไวรัส",
"空心线宽": "ความกว้างของเส้นกลวง",
"用户词典1": "พจนานุกรมผู้ใช้ 1",
"转义字符串替换": "การแทนที่สตริงแปลงความหมาย",
"相关说明": "คำแนะนำที่เกี่ยวข้อง",
@ -466,7 +464,6 @@
"删除": "ลบ",
"图像一致性阈值": "เกณฑ์ความสอดคล้องของภาพ",
"封面": "ปก",
"空心字体": "Hollow ตัวอักษร",
"显示错误信息": "แสดงข้อมูลผิดพลาด",
"剪裁UWP窗口的标题栏": "ตัดแถบหัวเรื่องของหน้าต่าง UWP",
"自动朗读": "อ่านออกเสียงอัตโนมัติ",
@ -710,10 +707,8 @@
"讯飞OCR": "โปรแกรม iFlytek OCR",
"发光字体": "Luminous ตัวอักษร",
"发光亮度": "ความสว่างส่องสว่าง",
"投影距离": "ระยะการฉาย",
"最大缓冲区长度": "ความยาวบัฟเฟอร์สูงสุด",
"最大缓存文本长度": "ความยาวสูงสุดของข้อความแคช",
"投影": "การฉายภาพ",
"半径": "รัศมี",
"圆角": "มุมกลม",
"立即应用": "สมัครตอนนี้",
@ -797,5 +792,6 @@
"超过时截断而非过滤": "ตัดตอนแทนการกรองเมื่อเกิน",
"兼容接口": "อินเตอร์เฟซที่เข้ากันได้",
"调试浏览器": "ดีบักเบราว์เซอร์",
"手动翻译": "การแปลด้วยตนเอง"
"手动翻译": "การแปลด้วยตนเอง",
"显示引擎": "แสดงเครื่องยนต์"
}

View File

@ -88,7 +88,6 @@
"OCR范围框颜色": "OCR Aralık Kutusu Rengi",
"OCR范围框宽度": "OCR menzili kutu genişliği",
"普通字体": "Normal yazıtipi",
"空心字体": "Beyaz yazıtipi",
"描边字体": "Sıçrama yazıtipi",
"显示设置": "Gösterim ayarları",
"不透明度": "Opacity",
@ -99,11 +98,9 @@
"翻译器字体类型": "Çevirme yazıtipi türü",
"设置界面字体类型": "Arayüz yazıtipini ayarla",
"字体大小": "Yazıtipi boyutu",
"特殊字体样式填充颜色": "Özel yazı tipi tarzı doldurma rengi",
"字体样式": "Yazıtipi stili",
"加粗字体": "Kalın yazıtipi",
"居中显示": "Orta gösterim",
"空心线宽": "Yavaş çizgi ağırlığı",
"描边宽度": "stroke-method",
"显示显示原文按钮": "Metin düğmesini göster",
"显示复制原文按钮": "Orijinal Kopyalama düğmesini göster",
@ -710,10 +707,8 @@
"讯飞OCR": "IFlytek OCR",
"发光字体": "Açık yazıtipi",
"发光亮度": "ışık",
"投影距离": "Projeksyon mesafesi",
"最大缓冲区长度": "Azamik buffer uzunluğu",
"最大缓存文本长度": "Maximum cached text length",
"投影": "projection",
"半径": "radius",
"圆角": "fillet",
"立即应用": "şimdi uygulayın",
@ -797,5 +792,6 @@
"超过时截断而非过滤": "Üstünde filtrelemek yerine küçük",
"兼容接口": "Kompatibil arayüz",
"调试浏览器": "Hata ayıklama tarayıcısı",
"手动翻译": "Elle çevirim"
"手动翻译": "Elle çevirim",
"显示引擎": "Gösterim Motoru"
}

View File

@ -88,7 +88,6 @@
"OCR范围框颜色": "Колір діапазону OCR",
"OCR范围框宽度": "Ширина діапазону OCR",
"普通字体": "Звичайний шрифт",
"空心字体": "Білий шрифт",
"描边字体": "Шрифт удару",
"显示设置": "Параметри показу",
"不透明度": "Непрозорість",
@ -99,11 +98,9 @@
"翻译器字体类型": "Тип шрифту перекладача",
"设置界面字体类型": "Встановити тип шрифту інтерфейсу",
"字体大小": "розмір шрифту",
"特殊字体样式填充颜色": "Спеціальний колір заповнення стилю шрифту",
"字体样式": "Стиль шрифту",
"加粗字体": "Жирий шрифт",
"居中显示": "Центрувати показ",
"空心线宽": "Ширина порожніх ліній",
"描边宽度": "Ширина",
"游戏最小化时窗口隐藏": "Сховати вікно під час мінімізації гри",
"游戏窗口移动时同步移动": "Синхронізувати рух під час пересування вікна гри",
@ -710,10 +707,8 @@
"讯飞OCR": "IFlytek OCR",
"发光字体": "Світливий шрифт",
"发光亮度": "світло",
"投影距离": "Відстань проекту",
"最大缓冲区长度": "Максимальна довжина буфера",
"最大缓存文本长度": "Максимальна довжина кешування тексту",
"投影": "проекція",
"半径": "радіус",
"圆角": "філет",
"立即应用": "застосовувати зараз",
@ -797,5 +792,6 @@
"超过时截断而非过滤": "Вирізати замість фільтрування, якщо перевищено",
"兼容接口": "Сумісний інтерфейс",
"调试浏览器": "Відладка навігатора",
"手动翻译": "Ручний переклад"
"手动翻译": "Ручний переклад",
"显示引擎": "Рушій показу"
}

View File

@ -88,7 +88,6 @@
"OCR范围框颜色": "Màu hộp dải OCR",
"OCR范围框宽度": "Chiều rộng khung dải OCR",
"普通字体": "Phông thường",
"空心字体": "Phông rỗng",
"描边字体": "Phông viền",
"显示设置": "Thiết lập hiển thị",
"不透明度": "Độ mờ",
@ -99,11 +98,9 @@
"翻译器字体类型": "Kiểu phông chữ Translator",
"设置界面字体类型": "Đặt kiểu phông giao diện",
"字体大小": "Cỡ phông chữ",
"特殊字体样式填充颜色": "Màu tô kiểu phông chữ đặc biệt",
"字体样式": "Kiểu phông chữ",
"加粗字体": "Phông đậm",
"居中显示": "Hiện ở giữa",
"空心线宽": "Chiều rộng đường rỗng",
"描边宽度": "Chiều rộng viền",
"显示显示原文按钮": "Hiển thị nút hiển thị gốc",
"显示复制原文按钮": "Hiển thị nút sao chép gốc",
@ -710,10 +707,8 @@
"讯飞OCR": "Máy bay OCR",
"发光字体": "Phông phát sáng",
"发光亮度": "Độ sáng phát sáng",
"投影距离": "Khoảng cách chiếu",
"最大缓冲区长度": "Chiều dài bộ đệm tối đa",
"最大缓存文本长度": "Độ dài văn bản bộ nhớ cache tối đa",
"投影": "Chiếu",
"半径": "Bán kính",
"圆角": "Góc tròn",
"立即应用": "Áp dụng ngay",
@ -797,5 +792,6 @@
"超过时截断而非过滤": "Cắt ngắn thay vì lọc khi vượt quá",
"兼容接口": "Giao diện tương thích",
"调试浏览器": "Gỡ lỗi trình duyệt",
"手动翻译": "Dịch thủ công"
"手动翻译": "Dịch thủ công",
"显示引擎": "Công cụ hiển thị"
}

View File

@ -7,7 +7,6 @@
"绑定窗口(部分软件不支持)(点击自己取消)": "",
"OCR最长间隔时间(s)": "",
"文本设置": "",
"特殊字体样式填充颜色": "",
"过滤数字": "",
"插入特殊码": "",
"移除非选定hook": "",
@ -377,7 +376,6 @@
"字体增大(可长按)": "",
"时间周期执行": "",
"请重新下载并关闭杀毒软件后重试": "",
"空心线宽": "",
"用户词典1": "",
"转义字符串替换": "",
"相关说明": "",
@ -464,7 +462,6 @@
"删除": "",
"图像一致性阈值": "",
"封面": "",
"空心字体": "",
"显示错误信息": "",
"剪裁UWP窗口的标题栏": "",
"自动朗读": "",
@ -712,10 +709,8 @@
"百度OCR": "",
"飞书OCR": "",
"讯飞OCR": "",
"投影": "",
"发光字体": "",
"发光亮度": "",
"投影距离": "",
"最大缓冲区长度": "",
"最大缓存文本长度": "",
"半径": "",
@ -797,5 +792,6 @@
"最小行数": "",
"最大行数": "",
"超过时截断而非过滤": "",
"调试浏览器": ""
"调试浏览器": "",
"显示引擎": ""
}

View File

@ -11,7 +11,7 @@ include_directories(${CMAKE_CURRENT_LIST_DIR}/wil/include)
include_directories(${CMAKE_CURRENT_LIST_DIR}/miniaudio)
include_directories(${CMAKE_CURRENT_LIST_DIR}/tinymp3)
include_directories(${CMAKE_CURRENT_LIST_DIR}/webview2/Microsoft.Web.WebView2.1.0.2478.35/build/native/include)
include_directories(${CMAKE_CURRENT_LIST_DIR}/webview2/Microsoft.Web.WebView2.1.0.2535.41/build/native/include)
if(${CMAKE_SIZEOF_VOID_P} EQUAL 4)
set(LTLPlatform "Win32")

View File

@ -1,4 +1,4 @@
mswebview2_version = "1.0.2478.35"
mswebview2_version = "1.0.2535.41"
import os, subprocess

View File

@ -11,6 +11,17 @@ using namespace Microsoft::WRL;
if (FAILED((x))) \
return x;
DECLARE void set_transparent_background(void* m_host){
COREWEBVIEW2_COLOR color;
ZeroMemory(&color,sizeof(color));
wil::com_ptr<ICoreWebView2Controller> m_controller(reinterpret_cast<ICoreWebView2Controller *>(m_host));
wil::com_ptr<ICoreWebView2Controller2> coreWebView2 =
m_controller.try_query<ICoreWebView2Controller2>();
if(coreWebView2){
coreWebView2->put_DefaultBackgroundColor(color);
}
}
DECLARE HRESULT put_PreferredColorScheme(void *m_host, COREWEBVIEW2_PREFERRED_COLOR_SCHEME scheme)
{