mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-28 08:04:13 +08:00
fix
This commit is contained in:
parent
714c31846e
commit
833ca891d3
@ -14,7 +14,6 @@ from myutils.config import (
|
||||
set_font_default,
|
||||
)
|
||||
from ctypes import c_int, CFUNCTYPE, c_void_p
|
||||
import sqlite3
|
||||
from myutils.utils import (
|
||||
minmaxmoveobservefunc,
|
||||
parsemayberegexreplace,
|
||||
@ -33,7 +32,7 @@ from textsource.copyboard import copyboard
|
||||
from textsource.texthook import texthook
|
||||
from textsource.ocrtext import ocrtext
|
||||
from gui.selecthook import hookselect
|
||||
from gui.translatorUI import QUnFrameWindow
|
||||
from gui.translatorUI import TranslatorWindow
|
||||
import zhconv, functools
|
||||
from gui.transhist import transhist
|
||||
from gui.edittext import edittext
|
||||
@ -48,6 +47,7 @@ import winsharedutils
|
||||
from winsharedutils import collect_running_pids
|
||||
from myutils.post import POSTSOLVE
|
||||
from myutils.utils import nowisdark
|
||||
from myutils.traceplaytime import playtimemanager
|
||||
from myutils.audioplayer import series_audioplayer
|
||||
from gui.dynalang import LAction, LMenu
|
||||
|
||||
@ -86,7 +86,6 @@ class MAINUI:
|
||||
self.edittextui = None
|
||||
self.edittextui_cached = None
|
||||
self.edittextui_sync = True
|
||||
self.sqlsavegameinfo = None
|
||||
self.notifyonce = set()
|
||||
self.audioplayer = series_audioplayer()
|
||||
self._internal_reader = None
|
||||
@ -463,9 +462,9 @@ class MAINUI:
|
||||
if len(res) == 0:
|
||||
return
|
||||
if onlytrans == False:
|
||||
if globalconfig["read_trans"] and (
|
||||
list(globalconfig["fanyi"].keys())[globalconfig["read_translator"]]
|
||||
== classname
|
||||
if (
|
||||
globalconfig["read_trans"]
|
||||
and globalconfig["read_translator2"] == classname
|
||||
):
|
||||
self.currentread = res
|
||||
self.readcurrent()
|
||||
@ -955,121 +954,13 @@ class MAINUI:
|
||||
|
||||
time.sleep(0.5)
|
||||
|
||||
def setdarktheme(self, widget, dark):
|
||||
if widget.testAttribute(Qt.WidgetAttribute.WA_TranslucentBackground):
|
||||
def setdarkandbackdrop(self, widget, dark):
|
||||
if self.__dontshowintaborsetbackdrop(widget):
|
||||
return
|
||||
winsharedutils.SetTheme(
|
||||
int(widget.winId()), dark, globalconfig["WindowBackdrop"]
|
||||
)
|
||||
|
||||
def createsavegamedb(self):
|
||||
self.sqlsavegameinfo = sqlite3.connect(
|
||||
gobject.getuserconfigdir("savegame.db"),
|
||||
check_same_thread=False,
|
||||
isolation_level=None,
|
||||
)
|
||||
try:
|
||||
self.sqlsavegameinfo.execute(
|
||||
"CREATE TABLE gameinternalid(gameinternalid INTEGER PRIMARY KEY AUTOINCREMENT,gamepath TEXT);"
|
||||
)
|
||||
self.sqlsavegameinfo.execute(
|
||||
"CREATE TABLE traceplaytime_v4(id INTEGER PRIMARY KEY AUTOINCREMENT,gameinternalid INT,timestart BIGINT,timestop BIGINT);"
|
||||
)
|
||||
except:
|
||||
pass
|
||||
|
||||
def querytraceplaytime_v4(self, gameuid):
|
||||
gameinternalid = self.get_gameinternalid(uid2gamepath[gameuid])
|
||||
return self.sqlsavegameinfo.execute(
|
||||
"SELECT timestart,timestop FROM traceplaytime_v4 WHERE gameinternalid = ?",
|
||||
(gameinternalid,),
|
||||
).fetchall()
|
||||
|
||||
def get_gameinternalid(self, gamepath):
|
||||
while True:
|
||||
ret = self.sqlsavegameinfo.execute(
|
||||
"SELECT gameinternalid FROM gameinternalid WHERE gamepath = ?",
|
||||
(gamepath,),
|
||||
).fetchone()
|
||||
if ret is None:
|
||||
self.sqlsavegameinfo.execute(
|
||||
"INSERT INTO gameinternalid VALUES(NULL,?)", (gamepath,)
|
||||
)
|
||||
else:
|
||||
return ret[0]
|
||||
|
||||
def resetgameinternal(self, fr, to):
|
||||
_id = self.get_gameinternalid(fr)
|
||||
self.sqlsavegameinfo.execute(
|
||||
"UPDATE gameinternalid SET gamepath = ? WHERE (gameinternalid = ?)",
|
||||
(to, _id),
|
||||
)
|
||||
|
||||
def traceplaytime(self, gamepath, start, end, new):
|
||||
|
||||
gameinternalid = self.get_gameinternalid(gamepath)
|
||||
if new:
|
||||
self.sqlsavegameinfo.execute(
|
||||
"INSERT INTO traceplaytime_v4 VALUES(NULL,?,?,?)",
|
||||
(gameinternalid, start, end),
|
||||
)
|
||||
else:
|
||||
self.sqlsavegameinfo.execute(
|
||||
"UPDATE traceplaytime_v4 SET timestop = ? WHERE (gameinternalid = ? and timestart = ?)",
|
||||
(end, gameinternalid, start),
|
||||
)
|
||||
|
||||
def checkgameplayingthread(self):
|
||||
self.__currentexe = None
|
||||
self.__statistictime = time.time()
|
||||
while True:
|
||||
__t = time.time()
|
||||
time.sleep(1)
|
||||
_t = time.time()
|
||||
|
||||
def isok(gameuid):
|
||||
# 可能开着程序进行虚拟机暂停,导致一下子多了很多时间。不过测试vbox上应该没问题
|
||||
maybevmpaused = (_t - __t) > 60
|
||||
if not maybevmpaused:
|
||||
savehook_new_data[gameuid]["statistic_playtime"] += _t - __t
|
||||
if (not maybevmpaused) and (self.__currentexe == name_):
|
||||
self.traceplaytime(
|
||||
uid2gamepath[gameuid], self.__statistictime - 1, _t, False
|
||||
)
|
||||
|
||||
else:
|
||||
self.__statistictime = time.time()
|
||||
self.__currentexe = name_
|
||||
self.traceplaytime(
|
||||
uid2gamepath[gameuid],
|
||||
self.__statistictime - 1,
|
||||
self.__statistictime,
|
||||
True,
|
||||
)
|
||||
|
||||
_hwnd = windows.GetForegroundWindow()
|
||||
_pid = windows.GetWindowThreadProcessId(_hwnd)
|
||||
try:
|
||||
if len(self.textsource.pids) == 0:
|
||||
raise Exception()
|
||||
if _pid in self.textsource.pids or _pid == os.getpid():
|
||||
isok(self.textsource.gameuid)
|
||||
else:
|
||||
self.__currentexe = None
|
||||
except:
|
||||
name_ = getpidexe(_pid)
|
||||
if not name_:
|
||||
return
|
||||
uids = findgameuidofpath(name_, findall=True)
|
||||
try:
|
||||
if len(uids):
|
||||
for uid in uids:
|
||||
isok(uid)
|
||||
else:
|
||||
self.__currentexe = None
|
||||
except:
|
||||
print_exc()
|
||||
|
||||
@threader
|
||||
def clickwordcallback(self, word, append):
|
||||
if globalconfig["usewordorigin"] == False:
|
||||
@ -1085,6 +976,15 @@ class MAINUI:
|
||||
if globalconfig["usesearchword"]:
|
||||
self.searchwordW.search_word.emit(word, append)
|
||||
|
||||
def __dontshowintaborsetbackdrop(self, widget):
|
||||
window_flags = widget.windowFlags()
|
||||
if (
|
||||
Qt.WindowType.FramelessWindowHint & window_flags
|
||||
== Qt.WindowType.FramelessWindowHint
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
def setshowintab_checked(self, widget):
|
||||
try:
|
||||
self.translation_ui
|
||||
@ -1095,11 +995,7 @@ class MAINUI:
|
||||
int(widget.winId()), globalconfig["showintab"], True
|
||||
)
|
||||
return
|
||||
window_flags = widget.windowFlags()
|
||||
if (
|
||||
Qt.WindowType.FramelessWindowHint & window_flags
|
||||
== Qt.WindowType.FramelessWindowHint
|
||||
):
|
||||
if self.__dontshowintaborsetbackdrop(widget):
|
||||
return
|
||||
if isinstance(widget, (QMenu, QFrame)):
|
||||
return
|
||||
@ -1160,7 +1056,7 @@ class MAINUI:
|
||||
self.currentisdark = dark
|
||||
|
||||
for widget in QApplication.topLevelWidgets():
|
||||
self.setdarktheme(widget, dark)
|
||||
self.setdarkandbackdrop(widget, dark)
|
||||
style = ""
|
||||
for _ in (0,):
|
||||
try:
|
||||
@ -1209,7 +1105,7 @@ class MAINUI:
|
||||
self.installeventfillter()
|
||||
self.parsedefaultfont()
|
||||
self.loadmetadatas()
|
||||
self.translation_ui = QUnFrameWindow()
|
||||
self.translation_ui = TranslatorWindow()
|
||||
winsharedutils.showintab(
|
||||
int(self.translation_ui.winId()), globalconfig["showintab"], True
|
||||
)
|
||||
@ -1236,11 +1132,10 @@ class MAINUI:
|
||||
threading.Thread(
|
||||
target=minmaxmoveobservefunc, args=(self.translation_ui,)
|
||||
).start()
|
||||
threading.Thread(target=self.checkgameplayingthread).start()
|
||||
self.messagecallback__ = CFUNCTYPE(None, c_int, c_void_p)(self.messagecallback)
|
||||
winsharedutils.globalmessagelistener(self.messagecallback__)
|
||||
self.inittray()
|
||||
self.createsavegamedb()
|
||||
self.playtimemanager = playtimemanager()
|
||||
self.__count = 0
|
||||
|
||||
def openlink(self, file):
|
||||
@ -1264,6 +1159,20 @@ class MAINUI:
|
||||
elif msg == 2:
|
||||
self.translation_ui.closesignal.emit()
|
||||
|
||||
def _dowhenwndcreate(self, obj):
|
||||
hwnd = obj.winId()
|
||||
if not hwnd: # window create/destroy,when destroy winId is None
|
||||
return
|
||||
windows.SetProp(
|
||||
int(obj.winId()),
|
||||
"Magpie.ToolWindow",
|
||||
windows.HANDLE(1),
|
||||
)
|
||||
winsharedutils.setdwmextendframe(int(hwnd))
|
||||
if self.currentisdark is not None:
|
||||
self.setdarkandbackdrop(obj, self.currentisdark)
|
||||
self.setshowintab_checked(obj)
|
||||
|
||||
def installeventfillter(self):
|
||||
class WindowEventFilter(QObject):
|
||||
def eventFilter(_, obj: QObject, event: QEvent):
|
||||
@ -1271,17 +1180,8 @@ class MAINUI:
|
||||
if "updatelangtext" in dir(obj):
|
||||
obj.updatelangtext()
|
||||
elif event.type() == QEvent.Type.WinIdChange:
|
||||
self._dowhenwndcreate(obj)
|
||||
|
||||
hwnd = obj.winId()
|
||||
if hwnd: # window create/destroy,when destroy winId is None
|
||||
if self.currentisdark is not None:
|
||||
self.setdarktheme(obj, self.currentisdark)
|
||||
windows.SetProp(
|
||||
int(obj.winId()),
|
||||
"Magpie.ToolWindow",
|
||||
windows.HANDLE(1),
|
||||
)
|
||||
self.setshowintab_checked(obj)
|
||||
return False
|
||||
|
||||
self.currentisdark = None
|
||||
|
@ -1,4 +1,6 @@
|
||||
baseobject = None
|
||||
global_dialog_savedgame_new = None
|
||||
global_dialog_setting_game = None
|
||||
import io, sys, platform, os
|
||||
from ctypes import windll, wintypes
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
649
LunaTranslator/LunaTranslator/gui/dialog_savedgame_common.py
Normal file
649
LunaTranslator/LunaTranslator/gui/dialog_savedgame_common.py
Normal file
@ -0,0 +1,649 @@
|
||||
from qtsymbols import *
|
||||
import os, functools
|
||||
from traceback import print_exc
|
||||
from myutils.wrapper import tryprint, threader, Singleton_close
|
||||
from myutils.utils import str2rgba, find_or_create_uid, duplicateconfig
|
||||
from myutils.hwnd import getExeIcon
|
||||
import gobject, hashlib
|
||||
from gui.inputdialog import autoinitdialog
|
||||
from gui.dynalang import LFormLayout, LDialog
|
||||
from myutils.localetools import localeswitchedrun
|
||||
from myutils.config import (
|
||||
savehook_new_data,
|
||||
savegametaged,
|
||||
uid2gamepath,
|
||||
_TR,
|
||||
savehook_new_list,
|
||||
globalconfig,
|
||||
)
|
||||
from gui.usefulwidget import (
|
||||
yuitsu_switch,
|
||||
getIconButton,
|
||||
FocusCombo,
|
||||
getsimplecombobox,
|
||||
getspinbox,
|
||||
getcolorbutton,
|
||||
getsimpleswitch,
|
||||
FQLineEdit,
|
||||
getspinbox,
|
||||
selectcolor,
|
||||
)
|
||||
|
||||
|
||||
class ItemWidget(QWidget):
|
||||
focuschanged = pyqtSignal(bool, str)
|
||||
doubleclicked = pyqtSignal(str)
|
||||
globallashfocus = None
|
||||
|
||||
@classmethod
|
||||
def clearfocus(cls):
|
||||
try: # 可能已被删除
|
||||
if ItemWidget.globallashfocus:
|
||||
ItemWidget.globallashfocus.focusOut()
|
||||
except:
|
||||
pass
|
||||
ItemWidget.globallashfocus = None
|
||||
|
||||
def click(self):
|
||||
try:
|
||||
self.bottommask.setStyleSheet(
|
||||
f'background-color: {str2rgba(globalconfig["dialog_savegame_layout"]["onselectcolor1"],globalconfig["dialog_savegame_layout"]["transparentselect"])};'
|
||||
)
|
||||
|
||||
if self != ItemWidget.globallashfocus:
|
||||
ItemWidget.clearfocus()
|
||||
ItemWidget.globallashfocus = self
|
||||
self.focuschanged.emit(True, self.gameuid)
|
||||
except:
|
||||
print_exc()
|
||||
|
||||
def mousePressEvent(self, ev) -> None:
|
||||
self.click()
|
||||
|
||||
def focusOut(self):
|
||||
self.bottommask.setStyleSheet("background-color: rgba(255,255,255, 0);")
|
||||
self.focuschanged.emit(False, self.gameuid)
|
||||
|
||||
def mouseDoubleClickEvent(self, e):
|
||||
self.doubleclicked.emit(self.gameuid)
|
||||
|
||||
def resizeEvent(self, a0: QResizeEvent) -> None:
|
||||
self.bottommask.resize(a0.size())
|
||||
self.maskshowfileexists.resize(a0.size())
|
||||
|
||||
def __init__(self, gameuid, pixmap, file) -> None:
|
||||
super().__init__()
|
||||
self.itemw = globalconfig["dialog_savegame_layout"]["itemw"]
|
||||
self.itemh = globalconfig["dialog_savegame_layout"]["itemh"]
|
||||
# self.imgw = globalconfig["dialog_savegame_layout"]["imgw"]
|
||||
# self.imgh = globalconfig["dialog_savegame_layout"]["imgh"]
|
||||
# margin = (
|
||||
# self.itemw - self.imgw
|
||||
# ) // 2 # globalconfig['dialog_savegame_layout']['margin']
|
||||
margin = globalconfig["dialog_savegame_layout"]["margin"]
|
||||
if globalconfig["showgametitle"]:
|
||||
textH = globalconfig["dialog_savegame_layout"]["textH"]
|
||||
else:
|
||||
textH = 0
|
||||
self.imgw = self.itemw - 2 * margin
|
||||
self.imgh = self.itemh - textH - 2 * margin
|
||||
#
|
||||
self.setFixedSize(QSize(self.itemw, self.itemh))
|
||||
# self.setFocusPolicy(Qt.StrongFocus)
|
||||
self.maskshowfileexists = QLabel(self)
|
||||
self.bottommask = QLabel(self)
|
||||
self.bottommask.setStyleSheet("background-color: rgba(255,255,255, 0);")
|
||||
layout = QVBoxLayout()
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
self._img = IMGWidget(self.imgw, self.imgh, pixmap)
|
||||
_w = QWidget()
|
||||
_w.setStyleSheet("background-color: rgba(255,255,255, 0);")
|
||||
wrap = QVBoxLayout()
|
||||
_w.setLayout(wrap)
|
||||
_w.setFixedHeight(self.imgh + 2 * margin)
|
||||
wrap.setContentsMargins(margin, margin, margin, margin)
|
||||
wrap.addWidget(self._img)
|
||||
layout.addWidget(_w)
|
||||
layout.setSpacing(0)
|
||||
self._lb = QLabel()
|
||||
if globalconfig["showgametitle"]:
|
||||
self._lb.setText(file)
|
||||
self._lb.setWordWrap(True)
|
||||
self._lb.setStyleSheet("background-color: rgba(255,255,255, 0);")
|
||||
self._lb.setAlignment(Qt.AlignmentFlag.AlignHCenter)
|
||||
layout.addWidget(self._lb)
|
||||
self.setLayout(layout)
|
||||
self.gameuid = gameuid
|
||||
c = globalconfig["dialog_savegame_layout"][
|
||||
("onfilenoexistscolor1", "backcolor1")[
|
||||
os.path.exists(uid2gamepath[gameuid])
|
||||
]
|
||||
]
|
||||
c = str2rgba(
|
||||
c,
|
||||
globalconfig["dialog_savegame_layout"][
|
||||
("transparentnotexits", "transparent")[
|
||||
os.path.exists(uid2gamepath[gameuid])
|
||||
]
|
||||
],
|
||||
)
|
||||
self.maskshowfileexists.setStyleSheet(f"background-color:{c};")
|
||||
|
||||
|
||||
class IMGWidget(QLabel):
|
||||
|
||||
def adaptsize(self, size: QSize):
|
||||
|
||||
if globalconfig["imagewrapmode"] == 0:
|
||||
h, w = size.height(), size.width()
|
||||
r = float(w) / h
|
||||
max_r = float(self.width()) / self.height()
|
||||
if r < max_r:
|
||||
new_w = self.width()
|
||||
new_h = int(new_w / r)
|
||||
else:
|
||||
new_h = self.height()
|
||||
new_w = int(new_h * r)
|
||||
return QSize(new_w, new_h)
|
||||
elif globalconfig["imagewrapmode"] == 1:
|
||||
h, w = size.height(), size.width()
|
||||
r = float(w) / h
|
||||
max_r = float(self.width()) / self.height()
|
||||
if r > max_r:
|
||||
new_w = self.width()
|
||||
new_h = int(new_w / r)
|
||||
else:
|
||||
new_h = self.height()
|
||||
new_w = int(new_h * r)
|
||||
return QSize(new_w, new_h)
|
||||
elif globalconfig["imagewrapmode"] == 2:
|
||||
return self.size()
|
||||
elif globalconfig["imagewrapmode"] == 3:
|
||||
return size
|
||||
|
||||
def setimg(self, pixmap):
|
||||
if type(pixmap) != QPixmap:
|
||||
pixmap = pixmap()
|
||||
|
||||
rate = self.devicePixelRatioF()
|
||||
newpixmap = QPixmap(self.size() * rate)
|
||||
newpixmap.setDevicePixelRatio(rate)
|
||||
newpixmap.fill(Qt.GlobalColor.transparent)
|
||||
painter = QPainter(newpixmap)
|
||||
painter.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform)
|
||||
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
|
||||
painter.drawPixmap(self.getrect(pixmap.size()), pixmap)
|
||||
painter.end()
|
||||
|
||||
self.setPixmap(newpixmap)
|
||||
|
||||
def getrect(self, size):
|
||||
size = self.adaptsize(size)
|
||||
rect = QRect()
|
||||
rect.setX(int((self.width() - size.width()) / 2))
|
||||
rect.setY(int((self.height() - size.height()) / 2))
|
||||
rect.setSize(size)
|
||||
return rect
|
||||
|
||||
def __init__(self, w, h, pixmap) -> None:
|
||||
super().__init__()
|
||||
self.setFixedSize(QSize(w, h))
|
||||
self.setScaledContents(True)
|
||||
self.setimg(pixmap)
|
||||
|
||||
|
||||
class ClickableLabel(QLabel):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setClickable(True)
|
||||
|
||||
def setClickable(self, clickable):
|
||||
self._clickable = clickable
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
if self._clickable and event.button() == Qt.MouseButton.LeftButton:
|
||||
self.clicked.emit()
|
||||
|
||||
clicked = pyqtSignal()
|
||||
|
||||
|
||||
class tagitem(QWidget):
|
||||
# website
|
||||
TYPE_GLOABL_LIKE = 3
|
||||
TYPE_GAME_LIKE = 1
|
||||
# search game
|
||||
TYPE_RAND = 0
|
||||
TYPE_DEVELOPER = 1
|
||||
TYPE_TAG = 2
|
||||
TYPE_USERTAG = 3
|
||||
TYPE_EXISTS = 4
|
||||
removesignal = pyqtSignal(tuple)
|
||||
labelclicked = pyqtSignal(tuple)
|
||||
|
||||
def remove(self):
|
||||
self.hide()
|
||||
_lay = self.layout()
|
||||
_ws = []
|
||||
for i in range(_lay.count()):
|
||||
witem = _lay.itemAt(i)
|
||||
_ws.append(witem.widget())
|
||||
for w in _ws:
|
||||
_lay.removeWidget(w)
|
||||
|
||||
def paintEvent(self, event):
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
|
||||
if self._type == tagitem.TYPE_RAND:
|
||||
border_color = Qt.GlobalColor.black
|
||||
elif self._type == tagitem.TYPE_DEVELOPER:
|
||||
border_color = Qt.GlobalColor.red
|
||||
elif self._type == tagitem.TYPE_TAG:
|
||||
border_color = Qt.GlobalColor.green
|
||||
elif self._type == tagitem.TYPE_USERTAG:
|
||||
border_color = Qt.GlobalColor.blue
|
||||
elif self._type == tagitem.TYPE_EXISTS:
|
||||
border_color = Qt.GlobalColor.yellow
|
||||
border_width = 1
|
||||
pen = QPen(border_color)
|
||||
pen.setWidth(border_width)
|
||||
painter.setPen(pen)
|
||||
painter.drawRect(self.rect())
|
||||
|
||||
def __init__(self, tag, removeable=True, _type=TYPE_RAND, refdata=None) -> None:
|
||||
super().__init__()
|
||||
tagLayout = QHBoxLayout()
|
||||
tagLayout.setContentsMargins(0, 0, 0, 0)
|
||||
tagLayout.setSpacing(0)
|
||||
self._type = _type
|
||||
key = (tag, _type, refdata)
|
||||
self.setLayout(tagLayout)
|
||||
lb = ClickableLabel()
|
||||
lb.setStyleSheet("background: transparent;")
|
||||
lb.setText(tag)
|
||||
lb.clicked.connect(functools.partial(self.labelclicked.emit, key))
|
||||
tagLayout.addWidget(lb)
|
||||
if removeable:
|
||||
button = getIconButton(
|
||||
functools.partial(self.removesignal.emit, key), icon="fa.times"
|
||||
)
|
||||
tagLayout.addWidget(button)
|
||||
|
||||
|
||||
class TagWidget(QWidget):
|
||||
tagschanged = pyqtSignal(tuple) # ((tag,type,refdata),)
|
||||
linepressedenter = pyqtSignal(str)
|
||||
tagclicked = pyqtSignal(tuple) # tag,type,refdata
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
layout = QHBoxLayout()
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
self.lineEdit = FocusCombo()
|
||||
self.lineEdit.setLineEdit(FQLineEdit())
|
||||
|
||||
self.lineEdit.lineEdit().returnPressed.connect(
|
||||
lambda: self.linepressedenter.emit(self.lineEdit.currentText())
|
||||
)
|
||||
|
||||
self.lineEdit.setSizePolicy(
|
||||
QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Maximum
|
||||
)
|
||||
|
||||
layout.addWidget(self.lineEdit)
|
||||
self.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Fixed)
|
||||
|
||||
self.tag2widget = {}
|
||||
|
||||
def addTags(self, tags, signal=True):
|
||||
for key in tags:
|
||||
self.__addTag(key)
|
||||
self.__calltagschanged(signal)
|
||||
|
||||
@tryprint
|
||||
def __addTag(self, key):
|
||||
tag, _type, refdata = key
|
||||
if not tag:
|
||||
return
|
||||
if key in self.tag2widget:
|
||||
return
|
||||
qw = tagitem(tag, _type=_type, refdata=refdata)
|
||||
qw.removesignal.connect(self.removeTag)
|
||||
qw.labelclicked.connect(self.tagclicked.emit)
|
||||
layout = self.layout()
|
||||
layout.insertWidget(layout.count() - 1, qw)
|
||||
self.tag2widget[key] = qw
|
||||
self.lineEdit.setFocus()
|
||||
|
||||
def addTag(self, tag, _type, refdata=None, signal=True):
|
||||
self.__addTag((tag, _type, refdata))
|
||||
self.__calltagschanged(signal)
|
||||
|
||||
@tryprint
|
||||
def __removeTag(self, key):
|
||||
_w = self.tag2widget[key]
|
||||
_w.remove()
|
||||
|
||||
self.layout().removeWidget(_w)
|
||||
self.tag2widget.pop(key)
|
||||
|
||||
def removeTag(self, key, signal=True):
|
||||
self.__removeTag(key)
|
||||
self.__calltagschanged(signal)
|
||||
|
||||
def __calltagschanged(self, signal):
|
||||
if signal:
|
||||
self.tagschanged.emit(tuple(self.tag2widget.keys()))
|
||||
|
||||
def clearTag(self, signal=True):
|
||||
for key in self.tag2widget.copy():
|
||||
self.__removeTag(key)
|
||||
self.__calltagschanged(signal)
|
||||
|
||||
|
||||
def opendirforgameuid(gameuid):
|
||||
f = uid2gamepath[gameuid]
|
||||
f = os.path.dirname(f)
|
||||
if os.path.exists(f) and os.path.isdir(f):
|
||||
os.startfile(f)
|
||||
|
||||
|
||||
@threader
|
||||
def startgame(gameuid):
|
||||
try:
|
||||
game = uid2gamepath[gameuid]
|
||||
if os.path.exists(game):
|
||||
mode = savehook_new_data[gameuid]["onloadautochangemode2"]
|
||||
if mode > 0:
|
||||
_ = {1: "texthook", 2: "copy", 3: "ocr"}
|
||||
if globalconfig["sourcestatus2"][_[mode]]["use"] == False:
|
||||
globalconfig["sourcestatus2"][_[mode]]["use"] = True
|
||||
|
||||
yuitsu_switch(
|
||||
gobject.baseobject.settin_ui,
|
||||
globalconfig["sourcestatus2"],
|
||||
"sourceswitchs",
|
||||
_[mode],
|
||||
None,
|
||||
True,
|
||||
)
|
||||
gobject.baseobject.starttextsource(use=_[mode], checked=True)
|
||||
|
||||
localeswitchedrun(gameuid)
|
||||
|
||||
except:
|
||||
print_exc()
|
||||
|
||||
|
||||
def __b64string(a: str):
|
||||
return hashlib.md5(a.encode("utf8")).hexdigest()
|
||||
|
||||
|
||||
def __scaletosize(_pix: QPixmap, tgt):
|
||||
|
||||
if min(_pix.width(), _pix.height()) > 400:
|
||||
|
||||
if _pix.height() < 400:
|
||||
sz = QSize(_pix.width() * 400 // _pix.height(), 400)
|
||||
else:
|
||||
sz = QSize(400, _pix.height() * 400 // _pix.width())
|
||||
_pix = _pix.scaled(
|
||||
sz,
|
||||
Qt.AspectRatioMode.KeepAspectRatio,
|
||||
Qt.TransformationMode.SmoothTransformation,
|
||||
)
|
||||
_pix.save(tgt)
|
||||
|
||||
|
||||
def getcachedimage(src, small):
|
||||
if not small:
|
||||
_pix = QPixmap(src)
|
||||
if _pix.isNull():
|
||||
return None
|
||||
return _pix
|
||||
if not os.path.exists(src):
|
||||
return None
|
||||
src2 = gobject.getcachedir(f"icon2/{__b64string(src)}.jpg")
|
||||
_pix = QPixmap(src2)
|
||||
if not _pix.isNull():
|
||||
return _pix
|
||||
_pix = QPixmap(src)
|
||||
if _pix.isNull():
|
||||
return None
|
||||
__scaletosize(_pix, src2)
|
||||
return _pix
|
||||
|
||||
|
||||
def getpixfunction(kk, small=False):
|
||||
if (
|
||||
savehook_new_data[kk]["currentmainimage"]
|
||||
in savehook_new_data[kk]["imagepath_all"]
|
||||
):
|
||||
src = savehook_new_data[kk]["currentmainimage"]
|
||||
pix = getcachedimage(src, small)
|
||||
if pix:
|
||||
return pix
|
||||
for _ in savehook_new_data[kk]["imagepath_all"]:
|
||||
pix = getcachedimage(_, small)
|
||||
if pix:
|
||||
return pix
|
||||
_pix = getExeIcon(uid2gamepath[kk], False, cache=True)
|
||||
return _pix
|
||||
|
||||
|
||||
def startgamecheck(self, gameuid):
|
||||
if not gameuid:
|
||||
return
|
||||
if not os.path.exists(uid2gamepath[gameuid]):
|
||||
return
|
||||
if globalconfig["startgamenototop"] == False:
|
||||
idx = savehook_new_list.index(gameuid)
|
||||
savehook_new_list.insert(0, savehook_new_list.pop(idx))
|
||||
self.parent().parent().close()
|
||||
startgame(gameuid)
|
||||
|
||||
|
||||
def addgamesingle(parent, callback, targetlist):
|
||||
f = QFileDialog.getOpenFileName(options=QFileDialog.Option.DontResolveSymlinks)
|
||||
|
||||
res = f[0]
|
||||
if res == "":
|
||||
return
|
||||
res = os.path.normpath(res)
|
||||
uid = find_or_create_uid(targetlist, res)
|
||||
if uid in targetlist:
|
||||
idx = targetlist.index(uid)
|
||||
response = QMessageBox.question(
|
||||
parent,
|
||||
"",
|
||||
_TR("游戏已存在,是否重复添加?"),
|
||||
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
|
||||
QMessageBox.StandardButton.No,
|
||||
)
|
||||
if response == QMessageBox.StandardButton.No:
|
||||
if idx == 0:
|
||||
return
|
||||
targetlist.pop(idx)
|
||||
else:
|
||||
uid = duplicateconfig(uid)
|
||||
targetlist.insert(0, uid)
|
||||
callback(uid)
|
||||
|
||||
|
||||
def addgamebatch(callback, targetlist):
|
||||
res = QFileDialog.getExistingDirectory(
|
||||
options=QFileDialog.Option.DontResolveSymlinks
|
||||
)
|
||||
if res == "":
|
||||
return
|
||||
for _dir, _, _fs in os.walk(res):
|
||||
for _f in _fs:
|
||||
path = os.path.normpath(os.path.abspath(os.path.join(_dir, _f)))
|
||||
if path.lower().endswith(".exe") == False:
|
||||
continue
|
||||
uid = find_or_create_uid(targetlist, path)
|
||||
if uid in targetlist:
|
||||
targetlist.pop(targetlist.index(uid))
|
||||
targetlist.insert(0, uid)
|
||||
callback(uid)
|
||||
|
||||
|
||||
def loadvisinternal(skipid=False, skipidid=None):
|
||||
__vis = []
|
||||
__uid = []
|
||||
for _ in savegametaged:
|
||||
if _ is None:
|
||||
__vis.append("GLOBAL")
|
||||
__uid.append(None)
|
||||
else:
|
||||
__vis.append(_["title"])
|
||||
__uid.append(_["uid"])
|
||||
if skipid:
|
||||
if skipidid == __uid[-1]:
|
||||
__uid.pop(-1)
|
||||
__vis.pop(-1)
|
||||
return __vis, __uid
|
||||
|
||||
|
||||
def getalistname(parent, callback, skipid=False, skipidid=None):
|
||||
__d = {"k": 0}
|
||||
__vis, __uid = loadvisinternal(skipid, skipidid)
|
||||
|
||||
def __wrap(callback, __d, __uid):
|
||||
if len(__uid) == 0:
|
||||
return
|
||||
|
||||
uid = __uid[__d["k"]]
|
||||
callback(uid)
|
||||
|
||||
if len(__uid) > 1:
|
||||
autoinitdialog(
|
||||
parent,
|
||||
"目标",
|
||||
600,
|
||||
[
|
||||
{
|
||||
"type": "combo",
|
||||
"name": "目标",
|
||||
"d": __d,
|
||||
"k": "k",
|
||||
"list": __vis,
|
||||
},
|
||||
{
|
||||
"type": "okcancel",
|
||||
"callback": functools.partial(__wrap, callback, __d, __uid),
|
||||
},
|
||||
],
|
||||
)
|
||||
elif len(__uid):
|
||||
|
||||
callback(__uid[0])
|
||||
|
||||
|
||||
def calculatetagidx(tagid):
|
||||
i = 0
|
||||
for save in savegametaged:
|
||||
if save is None and tagid is None:
|
||||
return i
|
||||
elif save and tagid and save["uid"] == tagid:
|
||||
return i
|
||||
i += 1
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def getreflist(reftagid):
|
||||
_idx = calculatetagidx(reftagid)
|
||||
if _idx is None:
|
||||
return None
|
||||
tag = savegametaged[_idx]
|
||||
if tag is None:
|
||||
return savehook_new_list
|
||||
return tag["games"]
|
||||
|
||||
|
||||
@Singleton_close
|
||||
class dialog_syssetting(LDialog):
|
||||
|
||||
def __init__(self, parent, type_=1) -> None:
|
||||
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
|
||||
self.setWindowTitle("其他设置")
|
||||
formLayout = LFormLayout(self)
|
||||
|
||||
formLayout.addRow(
|
||||
"隐藏不存在的游戏",
|
||||
getsimpleswitch(globalconfig, "hide_not_exists"),
|
||||
)
|
||||
if type_ == 1:
|
||||
for key, name in [
|
||||
("itemw", "宽度"),
|
||||
("itemh", "高度"),
|
||||
# ("imgw", "图片宽度"),
|
||||
# ("imgh", "图片高度"),
|
||||
("margin", "边距"),
|
||||
("textH", "文字区高度"),
|
||||
]:
|
||||
formLayout.addRow(
|
||||
name,
|
||||
getspinbox(0, 1000, globalconfig["dialog_savegame_layout"], key),
|
||||
)
|
||||
elif type_ == 2:
|
||||
for key, name in [
|
||||
("listitemheight", "文字区高度"),
|
||||
("listitemwidth", "高度"),
|
||||
]:
|
||||
formLayout.addRow(
|
||||
name,
|
||||
getspinbox(0, 1000, globalconfig["dialog_savegame_layout"], key),
|
||||
)
|
||||
|
||||
for key, key2, name in [
|
||||
("backcolor1", "transparent", "颜色"),
|
||||
("onselectcolor1", "transparentselect", "选中时颜色"),
|
||||
("onfilenoexistscolor1", "transparentnotexits", "游戏不存在时颜色"),
|
||||
]:
|
||||
formLayout.addRow(
|
||||
name,
|
||||
getcolorbutton(
|
||||
globalconfig["dialog_savegame_layout"],
|
||||
key,
|
||||
callback=functools.partial(
|
||||
selectcolor,
|
||||
self,
|
||||
globalconfig["dialog_savegame_layout"],
|
||||
key,
|
||||
None,
|
||||
self,
|
||||
key,
|
||||
),
|
||||
name=key,
|
||||
parent=self,
|
||||
),
|
||||
)
|
||||
formLayout.addRow(
|
||||
name + "_" + "不透明度",
|
||||
getspinbox(0, 100, globalconfig["dialog_savegame_layout"], key2),
|
||||
)
|
||||
if type_ == 1:
|
||||
formLayout.addRow(
|
||||
"缩放",
|
||||
getsimplecombobox(
|
||||
["填充", "适应", "拉伸", "居中"],
|
||||
globalconfig,
|
||||
"imagewrapmode",
|
||||
),
|
||||
)
|
||||
formLayout.addRow(
|
||||
"启动游戏不修改顺序",
|
||||
getsimpleswitch(globalconfig, "startgamenototop"),
|
||||
)
|
||||
|
||||
if type_ == 1:
|
||||
formLayout.addRow(
|
||||
"显示标题",
|
||||
getsimpleswitch(globalconfig, "showgametitle"),
|
||||
)
|
||||
self.show()
|
219
LunaTranslator/LunaTranslator/gui/dialog_savedgame_legacy.py
Normal file
219
LunaTranslator/LunaTranslator/gui/dialog_savedgame_legacy.py
Normal file
@ -0,0 +1,219 @@
|
||||
from PyQt5.QtWidgets import QWidget
|
||||
from qtsymbols import *
|
||||
import functools, threading
|
||||
from myutils.config import savehook_new_list, savehook_new_data, uid2gamepath
|
||||
from myutils.hwnd import getExeIcon
|
||||
from gui.usefulwidget import (
|
||||
TableViewW,
|
||||
D_getsimpleswitch,
|
||||
D_getIconButton,
|
||||
getcolorbutton,
|
||||
)
|
||||
from gui.dialog_savedgame_setting import dialog_setting_game
|
||||
from gui.dynalang import LPushButton, LStandardItemModel
|
||||
from gui.dialog_savedgame_common import opendirforgameuid, startgamecheck, addgamesingle
|
||||
|
||||
|
||||
class LazyLoadTableView(TableViewW):
|
||||
def __init__(self, model: LStandardItemModel) -> None:
|
||||
super().__init__()
|
||||
self.widgetfunction = []
|
||||
self.lock = threading.Lock()
|
||||
self.setModel(model)
|
||||
self.started = False
|
||||
|
||||
def starttraceir(self):
|
||||
self.started = True
|
||||
self.model().rowsRemoved.connect(functools.partial(self.insertremove))
|
||||
self.model().rowsInserted.connect(functools.partial(self.insert))
|
||||
|
||||
def resizeEvent(self, e):
|
||||
self.loadVisibleRows()
|
||||
super().resizeEvent(e)
|
||||
|
||||
def insertremove(self, index, start, end):
|
||||
off = end - start + 1
|
||||
with self.lock:
|
||||
collect = []
|
||||
for i in range(len(self.widgetfunction)):
|
||||
if self.widgetfunction[i][0] > end:
|
||||
self.widgetfunction[i][0] -= off
|
||||
elif (
|
||||
self.widgetfunction[i][0] >= start
|
||||
and self.widgetfunction[i][0] <= end
|
||||
):
|
||||
collect.append(i)
|
||||
for i in collect:
|
||||
self.widgetfunction.pop(i)
|
||||
|
||||
self.loadVisibleRows()
|
||||
|
||||
def insert(self, index, start, end):
|
||||
off = end - start + 1
|
||||
with self.lock:
|
||||
for i in range(len(self.widgetfunction)):
|
||||
if self.widgetfunction[i][0] >= start:
|
||||
self.widgetfunction[i][0] += off
|
||||
# print(self.widgetfunction[i])
|
||||
|
||||
self.loadVisibleRows()
|
||||
|
||||
def setIndexWidget(self, index: QModelIndex, widgetf):
|
||||
if not self.started:
|
||||
self.widgetfunction.append([index.row(), index.column(), widgetf])
|
||||
return
|
||||
if self.visualRect(index).intersects(self.viewport().rect()):
|
||||
w = widgetf()
|
||||
super().setIndexWidget(index, w)
|
||||
else:
|
||||
with self.lock:
|
||||
self.widgetfunction.append([index.row(), index.column(), widgetf])
|
||||
|
||||
def scrollContentsBy(self, dx, dy):
|
||||
super().scrollContentsBy(dx, dy)
|
||||
self.loadVisibleRows()
|
||||
|
||||
def loadVisibleRows(self):
|
||||
with self.lock:
|
||||
collect = []
|
||||
for i, index in enumerate(self.widgetfunction):
|
||||
row, col, wf = index
|
||||
if self.visualRect(self.model().index(row, col)).intersects(
|
||||
self.viewport().rect()
|
||||
):
|
||||
collect.insert(0, i)
|
||||
|
||||
for i in collect:
|
||||
row, col, wf = self.widgetfunction.pop(i)
|
||||
|
||||
w = wf()
|
||||
super().setIndexWidget(self.model().index(row, col), w)
|
||||
|
||||
|
||||
class dialog_savedgame_legacy(QWidget):
|
||||
|
||||
def directshow(self):
|
||||
pass
|
||||
|
||||
def showsettingdialog(self, k):
|
||||
dialog_setting_game(self, k)
|
||||
|
||||
def clicked2(self):
|
||||
try:
|
||||
|
||||
idx = self.table.currentIndex().row()
|
||||
savehook_new_list.pop(idx)
|
||||
self.savelist.pop(idx)
|
||||
self.model.removeRow(self.table.currentIndex().row())
|
||||
except:
|
||||
pass
|
||||
|
||||
def clicked3(self):
|
||||
def call(uid):
|
||||
if uid in self.savelist:
|
||||
idx = self.savelist.index(uid)
|
||||
self.savelist.pop(idx)
|
||||
self.model.removeRow(idx)
|
||||
self.newline(0, uid)
|
||||
self.table.setCurrentIndex(self.model.index(0, 0))
|
||||
|
||||
addgamesingle(self, call, savehook_new_list)
|
||||
|
||||
def clicked(self):
|
||||
startgamecheck(
|
||||
self, self.model.item(self.table.currentIndex().row(), 2).savetext
|
||||
)
|
||||
|
||||
def delayloadicon(self, k):
|
||||
return getcolorbutton(
|
||||
"",
|
||||
"",
|
||||
functools.partial(opendirforgameuid, k),
|
||||
qicon=getExeIcon(uid2gamepath[k], cache=True),
|
||||
)
|
||||
|
||||
def callback_leuse(self, k, use):
|
||||
if use:
|
||||
savehook_new_data[k]["launch_method"] = None
|
||||
else:
|
||||
savehook_new_data[k]["launch_method"] = "direct"
|
||||
|
||||
def newline(self, row, k):
|
||||
keyitem = QStandardItem()
|
||||
keyitem.savetext = k
|
||||
self.model.insertRow(
|
||||
row,
|
||||
[
|
||||
QStandardItem(),
|
||||
QStandardItem(),
|
||||
keyitem,
|
||||
QStandardItem((savehook_new_data[k]["title"])),
|
||||
],
|
||||
)
|
||||
self.table.setIndexWidget(
|
||||
self.model.index(row, 0),
|
||||
D_getsimpleswitch(
|
||||
{"1": savehook_new_data[k].get("launch_method") != "direct"},
|
||||
"1",
|
||||
callback=functools.partial(self.callback_leuse, k),
|
||||
),
|
||||
)
|
||||
self.table.setIndexWidget(
|
||||
self.model.index(row, 1),
|
||||
functools.partial(self.delayloadicon, k),
|
||||
)
|
||||
|
||||
self.table.setIndexWidget(
|
||||
self.model.index(row, 2),
|
||||
D_getIconButton(
|
||||
functools.partial(self.showsettingdialog, k), icon="fa.gear"
|
||||
),
|
||||
)
|
||||
|
||||
def __init__(self, parent) -> None:
|
||||
# if dialog_savedgame._sigleton :
|
||||
# return
|
||||
# dialog_savedgame._sigleton=True
|
||||
super().__init__(parent)
|
||||
|
||||
formLayout = QVBoxLayout(self) #
|
||||
model = LStandardItemModel()
|
||||
model.setHorizontalHeaderLabels(["转区", "", "设置", "游戏"]) # ,'HOOK'])
|
||||
|
||||
self.model = model
|
||||
|
||||
table = LazyLoadTableView(model)
|
||||
table.horizontalHeader().setSectionResizeMode(
|
||||
QHeaderView.ResizeMode.ResizeToContents
|
||||
)
|
||||
table.horizontalHeader().setStretchLastSection(True)
|
||||
# table.setEditTriggers(QAbstractItemView.NoEditTriggers);
|
||||
table.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
|
||||
table.setSelectionMode((QAbstractItemView.SelectionMode.SingleSelection))
|
||||
table.setWordWrap(False)
|
||||
self.table = table
|
||||
self.savelist = []
|
||||
for row, k in enumerate(savehook_new_list): # 2
|
||||
self.newline(row, k)
|
||||
self.savelist.append(k)
|
||||
self.table.starttraceir()
|
||||
bottom = QHBoxLayout()
|
||||
|
||||
button = LPushButton("开始游戏")
|
||||
self.button = button
|
||||
button.clicked.connect(self.clicked)
|
||||
button3 = LPushButton("添加游戏")
|
||||
|
||||
button3.clicked.connect(self.clicked3)
|
||||
button2 = LPushButton("删除游戏")
|
||||
|
||||
button2.clicked.connect(self.clicked2)
|
||||
bottom.addWidget(button)
|
||||
bottom.addWidget(button2)
|
||||
bottom.addWidget(button3)
|
||||
_ = QLabel()
|
||||
_.setFixedHeight(20)
|
||||
_.setStyleSheet("background: transparent;")
|
||||
formLayout.addWidget(_)
|
||||
formLayout.addWidget(table)
|
||||
formLayout.addLayout(bottom)
|
1168
LunaTranslator/LunaTranslator/gui/dialog_savedgame_setting.py
Normal file
1168
LunaTranslator/LunaTranslator/gui/dialog_savedgame_setting.py
Normal file
File diff suppressed because it is too large
Load Diff
1097
LunaTranslator/LunaTranslator/gui/dialog_savedgame_v3.py
Normal file
1097
LunaTranslator/LunaTranslator/gui/dialog_savedgame_v3.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -139,10 +139,10 @@ class rangeadjust(Mainw):
|
||||
# 由于使用movewindow而非qt函数,导致内部执行绪有问题。
|
||||
|
||||
|
||||
class rangeselct(QMainWindow):
|
||||
class rangeselect(QMainWindow):
|
||||
def __init__(self, parent=None):
|
||||
|
||||
super(rangeselct, self).__init__(parent)
|
||||
super(rangeselect, self).__init__(parent)
|
||||
self.setWindowFlags(
|
||||
Qt.WindowType.FramelessWindowHint
|
||||
| Qt.WindowType.WindowStaysOnTopHint
|
||||
@ -254,7 +254,7 @@ screen_shot_ui = None
|
||||
def rangeselct_function(callback, clickrelease, startauto):
|
||||
global screen_shot_ui
|
||||
if screen_shot_ui is None:
|
||||
screen_shot_ui = rangeselct()
|
||||
screen_shot_ui = rangeselect()
|
||||
# 可能是由于使用win32移动窗口,导致父翻译show/hide影响到他
|
||||
screen_shot_ui.show()
|
||||
screen_shot_ui.reset()
|
||||
|
@ -229,7 +229,7 @@ def setTab5lz(self):
|
||||
D_getsimplecombobox(
|
||||
alltransvis,
|
||||
globalconfig,
|
||||
"read_translator",
|
||||
"read_translator2",
|
||||
internal=alltrans,
|
||||
),
|
||||
"",
|
||||
|
@ -31,7 +31,8 @@ from gui.textbrowser import Textbrowser
|
||||
from gui.rangeselect import rangeselct_function
|
||||
from gui.usefulwidget import resizableframeless, getQMessageBox, LIconLabel
|
||||
from gui.edittext import edittrans
|
||||
from gui.dialog_savedgame import browserdialog, dialog_savedgame_integrated
|
||||
from gui.dialog_savedgame import dialog_savedgame_integrated
|
||||
from gui.dialog_savedgame_setting import browserdialog
|
||||
from gui.dynalang import LDialog
|
||||
|
||||
|
||||
@ -221,7 +222,7 @@ class ButtonBar(QFrame):
|
||||
self.parent().setMinimumWidth(int(w))
|
||||
|
||||
|
||||
class QUnFrameWindow(resizableframeless):
|
||||
class TranslatorWindow(resizableframeless):
|
||||
displayglobaltooltip = pyqtSignal(str)
|
||||
displaylink = pyqtSignal(str)
|
||||
displaymessagebox = pyqtSignal(str, str)
|
||||
@ -831,7 +832,7 @@ class QUnFrameWindow(resizableframeless):
|
||||
|
||||
def __init__(self):
|
||||
|
||||
super(QUnFrameWindow, self).__init__(
|
||||
super(TranslatorWindow, self).__init__(
|
||||
None,
|
||||
flags=Qt.WindowType.FramelessWindowHint
|
||||
| Qt.WindowType.WindowMinimizeButtonHint,
|
||||
|
126
LunaTranslator/LunaTranslator/myutils/traceplaytime.py
Normal file
126
LunaTranslator/LunaTranslator/myutils/traceplaytime.py
Normal file
@ -0,0 +1,126 @@
|
||||
import sqlite3, gobject, threading, time, windows
|
||||
import time
|
||||
import os, threading
|
||||
from qtsymbols import *
|
||||
from traceback import print_exc
|
||||
from myutils.config import (
|
||||
uid2gamepath,
|
||||
findgameuidofpath,
|
||||
savehook_new_data,
|
||||
)
|
||||
from myutils.hwnd import getpidexe
|
||||
import windows
|
||||
import gobject
|
||||
|
||||
|
||||
class playtimemanager:
|
||||
def __init__(self):
|
||||
|
||||
self.sqlsavegameinfo = sqlite3.connect(
|
||||
gobject.getuserconfigdir("savegame.db"),
|
||||
check_same_thread=False,
|
||||
isolation_level=None,
|
||||
)
|
||||
try:
|
||||
self.sqlsavegameinfo.execute(
|
||||
"CREATE TABLE gameinternalid(gameinternalid INTEGER PRIMARY KEY AUTOINCREMENT,gamepath TEXT);"
|
||||
)
|
||||
self.sqlsavegameinfo.execute(
|
||||
"CREATE TABLE traceplaytime_v4(id INTEGER PRIMARY KEY AUTOINCREMENT,gameinternalid INT,timestart BIGINT,timestop BIGINT);"
|
||||
)
|
||||
except:
|
||||
pass
|
||||
|
||||
threading.Thread(target=self.checkgameplayingthread).start()
|
||||
|
||||
def querytraceplaytime_v4(self, gameuid):
|
||||
gameinternalid = self.get_gameinternalid(uid2gamepath[gameuid])
|
||||
return self.sqlsavegameinfo.execute(
|
||||
"SELECT timestart,timestop FROM traceplaytime_v4 WHERE gameinternalid = ?",
|
||||
(gameinternalid,),
|
||||
).fetchall()
|
||||
|
||||
def get_gameinternalid(self, gamepath):
|
||||
while True:
|
||||
ret = self.sqlsavegameinfo.execute(
|
||||
"SELECT gameinternalid FROM gameinternalid WHERE gamepath = ?",
|
||||
(gamepath,),
|
||||
).fetchone()
|
||||
if ret is None:
|
||||
self.sqlsavegameinfo.execute(
|
||||
"INSERT INTO gameinternalid VALUES(NULL,?)", (gamepath,)
|
||||
)
|
||||
else:
|
||||
return ret[0]
|
||||
|
||||
def resetgameinternal(self, fr, to):
|
||||
_id = self.get_gameinternalid(fr)
|
||||
self.sqlsavegameinfo.execute(
|
||||
"UPDATE gameinternalid SET gamepath = ? WHERE (gameinternalid = ?)",
|
||||
(to, _id),
|
||||
)
|
||||
|
||||
def traceplaytime(self, gamepath, start, end, new):
|
||||
|
||||
gameinternalid = self.get_gameinternalid(gamepath)
|
||||
if new:
|
||||
self.sqlsavegameinfo.execute(
|
||||
"INSERT INTO traceplaytime_v4 VALUES(NULL,?,?,?)",
|
||||
(gameinternalid, start, end),
|
||||
)
|
||||
else:
|
||||
self.sqlsavegameinfo.execute(
|
||||
"UPDATE traceplaytime_v4 SET timestop = ? WHERE (gameinternalid = ? and timestart = ?)",
|
||||
(end, gameinternalid, start),
|
||||
)
|
||||
|
||||
def checkgameplayingthread(self):
|
||||
self.__currentexe = None
|
||||
self.__statistictime = time.time()
|
||||
while True:
|
||||
__t = time.time()
|
||||
time.sleep(1)
|
||||
_t = time.time()
|
||||
|
||||
def isok(gameuid):
|
||||
# 可能开着程序进行虚拟机暂停,导致一下子多了很多时间。不过测试vbox上应该没问题
|
||||
maybevmpaused = (_t - __t) > 60
|
||||
if not maybevmpaused:
|
||||
savehook_new_data[gameuid]["statistic_playtime"] += _t - __t
|
||||
if (not maybevmpaused) and (self.__currentexe == name_):
|
||||
self.traceplaytime(
|
||||
uid2gamepath[gameuid], self.__statistictime - 1, _t, False
|
||||
)
|
||||
|
||||
else:
|
||||
self.__statistictime = time.time()
|
||||
self.__currentexe = name_
|
||||
self.traceplaytime(
|
||||
uid2gamepath[gameuid],
|
||||
self.__statistictime - 1,
|
||||
self.__statistictime,
|
||||
True,
|
||||
)
|
||||
|
||||
_hwnd = windows.GetForegroundWindow()
|
||||
_pid = windows.GetWindowThreadProcessId(_hwnd)
|
||||
try:
|
||||
if len(gobject.baseobject.textsource.pids) == 0:
|
||||
raise Exception()
|
||||
if _pid in gobject.baseobject.textsource.pids or _pid == os.getpid():
|
||||
isok(gobject.baseobject.textsource.gameuid)
|
||||
else:
|
||||
self.__currentexe = None
|
||||
except:
|
||||
name_ = getpidexe(_pid)
|
||||
if not name_:
|
||||
return
|
||||
uids = findgameuidofpath(name_, findall=True)
|
||||
try:
|
||||
if len(uids):
|
||||
for uid in uids:
|
||||
isok(uid)
|
||||
else:
|
||||
self.__currentexe = None
|
||||
except:
|
||||
print_exc()
|
@ -243,13 +243,11 @@ globalmessagelistener = utilsdll.globalmessagelistener
|
||||
globalmessagelistener.argtypes = (c_void_p,)
|
||||
dispatchcloseevent = utilsdll.dispatchcloseevent
|
||||
|
||||
setdwmextendframe = utilsdll.setdwmextendframe
|
||||
setdwmextendframe.argtypes = (HWND,)
|
||||
|
||||
_SetTheme = utilsdll._SetTheme
|
||||
_SetTheme.argtypes = HWND, c_bool, c_int
|
||||
|
||||
|
||||
def SetTheme(hwnd, dark, backdrop):
|
||||
_SetTheme(hwnd, dark, backdrop)
|
||||
SetTheme = utilsdll._SetTheme
|
||||
SetTheme.argtypes = HWND, c_bool, c_int
|
||||
|
||||
|
||||
getprocesses = utilsdll.getprocesses
|
||||
|
@ -14,7 +14,7 @@
|
||||
"read_raw": true,
|
||||
"global_list_opened": true,
|
||||
"read_trans": false,
|
||||
"read_translator": 0,
|
||||
"read_translator2": "",
|
||||
"disappear_delay": 5,
|
||||
"network": 1,
|
||||
"useextrahtml": true,
|
||||
|
@ -29,7 +29,7 @@ include(generate_product_version)
|
||||
|
||||
set(VERSION_MAJOR 5)
|
||||
set(VERSION_MINOR 26)
|
||||
set(VERSION_PATCH 3)
|
||||
set(VERSION_PATCH 4)
|
||||
|
||||
add_library(pch pch.cpp)
|
||||
target_precompile_headers(pch PUBLIC pch.h)
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "define.h"
|
||||
#include <dwmapi.h>
|
||||
|
||||
typedef enum _WINDOWCOMPOSITIONATTRIB
|
||||
{
|
||||
@ -85,6 +86,13 @@ typedef BOOL(WINAPI *pfnSetWindowCompositionAttribute)(HWND, WINDOWCOMPOSITIONAT
|
||||
|
||||
DECLARE bool setAcrylicEffect(HWND hwnd, bool isEnableShadow)
|
||||
{
|
||||
// win7全都用areo
|
||||
DWM_BLURBEHIND bb = {0};
|
||||
bb.dwFlags = DWM_BB_ENABLE;
|
||||
bb.fEnable = true;
|
||||
bb.hRgnBlur = NULL;
|
||||
DwmEnableBlurBehindWindow(hwnd, &bb);
|
||||
|
||||
DWORD gradientColor = 0x00FfFfFf; // ABGR
|
||||
common
|
||||
|
||||
@ -94,9 +102,14 @@ DECLARE bool setAcrylicEffect(HWND hwnd, bool isEnableShadow)
|
||||
accentPolicy.AccentFlags = accentFlags;
|
||||
return setWindowCompositionAttribute(hwnd, &winCompAttrData);
|
||||
}
|
||||
|
||||
DECLARE bool setAeroEffect(HWND hwnd, bool isEnableShadow)
|
||||
{
|
||||
DWM_BLURBEHIND bb = {0};
|
||||
bb.dwFlags = DWM_BB_ENABLE;
|
||||
bb.fEnable = true;
|
||||
bb.hRgnBlur = NULL;
|
||||
DwmEnableBlurBehindWindow(hwnd, &bb);
|
||||
|
||||
common
|
||||
|
||||
accentPolicy.AccentState = ACCENT_ENABLE_BLURBEHIND;
|
||||
@ -106,6 +119,11 @@ DECLARE bool setAeroEffect(HWND hwnd, bool isEnableShadow)
|
||||
}
|
||||
DECLARE bool clearEffect(HWND hwnd)
|
||||
{
|
||||
DWM_BLURBEHIND bb = {0};
|
||||
bb.dwFlags = DWM_BB_ENABLE;
|
||||
bb.fEnable = false;
|
||||
bb.hRgnBlur = NULL;
|
||||
DwmEnableBlurBehindWindow(hwnd, &bb);
|
||||
|
||||
common
|
||||
accentPolicy.AccentState = ACCENT_DISABLED;
|
||||
|
@ -150,6 +150,12 @@ static void SetWindowTheme(HWND hWnd, bool darkBorder, bool darkMenu) noexcept
|
||||
RefreshImmersiveColorPolicyState();
|
||||
FlushMenuThemes();
|
||||
}
|
||||
DECLARE void setdwmextendframe(HWND hwnd)
|
||||
{
|
||||
MARGINS mar{-1, -1, -1, -1};
|
||||
DwmExtendFrameIntoClientArea(hwnd, &mar);
|
||||
}
|
||||
|
||||
DECLARE void _SetTheme(
|
||||
HWND _hWnd,
|
||||
bool dark,
|
||||
@ -176,11 +182,6 @@ DECLARE void _SetTheme(
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// 非常诡异,这里mar,BACKDROP_MAP,value的声明顺序会导致在win7-32位上崩溃,原因未知。
|
||||
MARGINS mar{-1, -1, -1, -1};
|
||||
// 这个最重要,不可以跳过,否则transaprent会黑。win7无效,仍然是黑的,所以win7不可以使用QTWIN11主题。
|
||||
DwmExtendFrameIntoClientArea(_hWnd, &mar);
|
||||
|
||||
// https://learn.microsoft.com/zh-cn/windows/win32/api/dwmapi/ne-dwmapi-dwm_systembackdrop_type
|
||||
// 设置背景
|
||||
static const DWM_SYSTEMBACKDROP_TYPE BACKDROP_MAP[] = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user