mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-09-30 19:08:03 +03:00
Refactor QMainWindow to MainWindow
Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
@@ -66,8 +66,6 @@ SUPPORTED_SETTINGS = (
|
||||
Settings('MainWidgetWindowSize'),
|
||||
# Edit Routing Widget Window Size
|
||||
Settings('RoutesWidgetWindowSize'),
|
||||
# Edit Routing Widget Editor Window Size
|
||||
Settings('RoutesEditorWindowSize'),
|
||||
# Main Widget Section Size
|
||||
Settings('ServerWidgetSectionSizeTable'),
|
||||
# Edit Routing Widget Section Size
|
||||
|
||||
@@ -156,6 +156,25 @@ class SupportConnectedCallback:
|
||||
ob.disconnectedCallback()
|
||||
|
||||
|
||||
class NeedSyncSettings:
|
||||
Object = list()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
NeedSyncSettings.Object.append(self)
|
||||
|
||||
def syncSettings(self):
|
||||
raise NotImplementedError
|
||||
|
||||
@staticmethod
|
||||
def syncAll():
|
||||
for ob in NeedSyncSettings.Object:
|
||||
assert isinstance(ob, NeedSyncSettings)
|
||||
|
||||
ob.syncSettings()
|
||||
|
||||
|
||||
class SupportThemeChangedCallback:
|
||||
Object = list()
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ from Furious.Utility.Constants import (
|
||||
SYSTEM_LANGUAGE,
|
||||
DATA_DIR,
|
||||
)
|
||||
from Furious.Utility.Utility import SupportThemeChangedCallback
|
||||
from Furious.Utility.Utility import SupportThemeChangedCallback, NeedSyncSettings
|
||||
from Furious.Utility.Proxy import Proxy
|
||||
from Furious.Utility.Settings import Settings
|
||||
from Furious.Utility.Translator import gettext as _
|
||||
@@ -265,14 +265,7 @@ class Application(SingletonApplication):
|
||||
# if self.tray is not None:
|
||||
# self.tray.ConnectAction.stopCore()
|
||||
|
||||
if self.MainWidget is not None:
|
||||
self.MainWidget.syncSettings()
|
||||
|
||||
if self.editRoutingWidget is not None:
|
||||
self.editRoutingWidget.syncSettings()
|
||||
|
||||
if self.logViewerWidget is not None:
|
||||
self.logViewerWidget.syncSettings()
|
||||
NeedSyncSettings.syncAll()
|
||||
|
||||
def exit(self, exitcode=0):
|
||||
if self.MainWidget is not None:
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from Furious.Gui.Action import Action, Seperator
|
||||
from Furious.Widget.Widget import ListWidget, Menu, MessageBox
|
||||
from Furious.Widget.Widget import ListWidget, MainWindow, Menu, MessageBox
|
||||
from Furious.Utility.Constants import APPLICATION_NAME, PLATFORM, GOLDEN_RATIO, ROOT_DIR
|
||||
from Furious.Utility.Utility import (
|
||||
StateContext,
|
||||
@@ -14,7 +14,7 @@ from Furious.Utility.Translator import Translatable, gettext as _
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtGui import QFont
|
||||
from PySide6.QtWidgets import QFileDialog, QListWidget, QListWidgetItem, QMainWindow
|
||||
from PySide6.QtWidgets import QFileDialog, QListWidget, QListWidgetItem
|
||||
|
||||
import os
|
||||
import shutil
|
||||
@@ -136,9 +136,7 @@ class ExitAction(Action):
|
||||
self.parent().hide()
|
||||
|
||||
|
||||
class AssetViewerWidget(
|
||||
Translatable, SupportConnectedCallback, SupportThemeChangedCallback, QMainWindow
|
||||
):
|
||||
class AssetViewerWidget(SupportThemeChangedCallback, MainWindow):
|
||||
AssetDir = ROOT_DIR / APPLICATION_NAME / 'Data' / 'xray'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -251,17 +249,6 @@ class AssetViewerWidget(
|
||||
else:
|
||||
self.flushItemByTheme(darkdetect.theme())
|
||||
|
||||
def closeEvent(self, event):
|
||||
event.ignore()
|
||||
|
||||
self.hide()
|
||||
|
||||
def connectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-connected-dark.svg'))
|
||||
|
||||
def disconnectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-window.svg'))
|
||||
|
||||
def themeChangedCallback(self, theme):
|
||||
if PLATFORM == 'Linux' and getUbuntuRelease() == '20.04':
|
||||
# Ubuntu 20.04 system dark theme does not
|
||||
@@ -269,7 +256,3 @@ class AssetViewerWidget(
|
||||
pass
|
||||
else:
|
||||
self.flushItemByTheme(theme)
|
||||
|
||||
def retranslate(self):
|
||||
with StateContext(self):
|
||||
self.setWindowTitle(_(self.windowTitle()))
|
||||
|
||||
@@ -5,6 +5,7 @@ from Furious.Core.Configuration import Configuration
|
||||
from Furious.Gui.Action import Action, Seperator
|
||||
from Furious.Widget.Widget import (
|
||||
HeaderView,
|
||||
MainWindow,
|
||||
Menu,
|
||||
MessageBox,
|
||||
PushButton,
|
||||
@@ -47,10 +48,8 @@ from PySide6.QtWidgets import (
|
||||
QHBoxLayout,
|
||||
QHeaderView,
|
||||
QLabel,
|
||||
QLineEdit,
|
||||
QListWidget,
|
||||
QListWidgetItem,
|
||||
QMainWindow,
|
||||
QPlainTextEdit,
|
||||
QSplitter,
|
||||
QStyledItemDelegate,
|
||||
@@ -1607,7 +1606,7 @@ class NormalServerWidget(Translatable, SupportConnectedCallback, TableWidget):
|
||||
)
|
||||
|
||||
|
||||
class EditConfigurationWidget(Translatable, SupportConnectedCallback, QMainWindow):
|
||||
class EditConfigurationWidget(MainWindow):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -1975,12 +1974,6 @@ class EditConfigurationWidget(Translatable, SupportConnectedCallback, QMainWindo
|
||||
)
|
||||
APP().EditorWidgetPointSize = str(self.plainTextEdit.font().pointSize())
|
||||
|
||||
def connectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-connected-dark.svg'))
|
||||
|
||||
def disconnectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-window.svg'))
|
||||
|
||||
def retranslate(self):
|
||||
with StateContext(self):
|
||||
if self.modified:
|
||||
|
||||
@@ -9,6 +9,7 @@ from Furious.Gui.Action import Action, Seperator
|
||||
from Furious.Widget.Widget import (
|
||||
HeaderView,
|
||||
Menu,
|
||||
MainWindow,
|
||||
MessageBox,
|
||||
PushButton,
|
||||
StyledItemDelegate,
|
||||
@@ -39,14 +40,15 @@ from PySide6 import QtCore
|
||||
from PySide6.QtGui import QFont
|
||||
from PySide6.QtWidgets import (
|
||||
QAbstractItemView,
|
||||
QDialog,
|
||||
QDialogButtonBox,
|
||||
QFileDialog,
|
||||
QFormLayout,
|
||||
QGridLayout,
|
||||
QHBoxLayout,
|
||||
QHeaderView,
|
||||
QInputDialog,
|
||||
QLabel,
|
||||
QLineEdit,
|
||||
QMainWindow,
|
||||
QPlainTextEdit,
|
||||
QSplitter,
|
||||
QStyledItemDelegate,
|
||||
@@ -204,7 +206,7 @@ BUILTIN_ROUTING_TEXT = {
|
||||
f'# \n'
|
||||
f'# This rule is read-only.\n'
|
||||
f'# \n'
|
||||
f'# If no rule file or mmdb file is provided, hysteria\n'
|
||||
f'# If no rule file or mmdb file is provided, {APPLICATION_NAME}\n'
|
||||
f'# will fall back to proxy all traffic.\n\n'
|
||||
)
|
||||
+ ujson.dumps(
|
||||
@@ -289,7 +291,7 @@ USER_ROUTING_TEXT = {
|
||||
f'# by {APPLICATION_NAME} forever.\n'
|
||||
f'# \n'
|
||||
f'# Note: If any one of filepath is given but\n'
|
||||
f'# does not exist, hysteria will fall back to\n'
|
||||
f'# does not exist, {APPLICATION_NAME} will fall back to\n'
|
||||
f'# proxy all traffic.\n\n'
|
||||
)
|
||||
+ ujson.dumps(
|
||||
@@ -515,7 +517,7 @@ class RoutingPlainTextEdit(ZoomablePlainTextEdit):
|
||||
super().wheelEvent(event)
|
||||
|
||||
|
||||
class RoutingEditor(Translatable, SupportConnectedCallback, QMainWindow):
|
||||
class RoutingEditor(MainWindow):
|
||||
def __init__(self, isBuiltin, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -669,12 +671,6 @@ class RoutingEditor(Translatable, SupportConnectedCallback, QMainWindow):
|
||||
|
||||
self.questionSave()
|
||||
|
||||
def connectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-connected-dark.svg'))
|
||||
|
||||
def disconnectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-window.svg'))
|
||||
|
||||
def retranslate(self):
|
||||
if self.isBuiltin:
|
||||
# Built-in routing is translatable
|
||||
@@ -852,17 +848,7 @@ class EditRoutingTableWidget(Translatable, SupportConnectedCallback, TableWidget
|
||||
routingEditor = RoutingEditor(isBuiltin)
|
||||
routingEditor.title = title
|
||||
routingEditor.setWindowTitle(title)
|
||||
|
||||
try:
|
||||
routingEditor.setGeometry(
|
||||
100,
|
||||
100,
|
||||
*list(int(size) for size in APP().RoutesEditorWindowSize.split(',')),
|
||||
)
|
||||
except Exception:
|
||||
# Any non-exit exceptions
|
||||
|
||||
routingEditor.setGeometry(100, 100, 728 * GOLDEN_RATIO, 728)
|
||||
routingEditor.setGeometry(100, 100, 656, 856)
|
||||
|
||||
moveToCenter(routingEditor)
|
||||
|
||||
@@ -970,7 +956,52 @@ class EditRoutingTableWidget(Translatable, SupportConnectedCallback, TableWidget
|
||||
item.setText(_(item.text()))
|
||||
|
||||
|
||||
class EditRoutingWidget(Translatable, SupportConnectedCallback, QMainWindow):
|
||||
class AddRoutingDialog(Translatable, SupportConnectedCallback, QDialog):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.setWindowTitle(_('Add routing'))
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-window.svg'))
|
||||
|
||||
self.remarkText = QLabel(_('Enter routing remark:'))
|
||||
self.remarkEdit = QLineEdit()
|
||||
|
||||
self.dialogBtns = QDialogButtonBox(QtCore.Qt.Orientation.Horizontal)
|
||||
|
||||
self.dialogBtns.addButton(_('OK'), QDialogButtonBox.ButtonRole.AcceptRole)
|
||||
self.dialogBtns.addButton(_('Cancel'), QDialogButtonBox.ButtonRole.RejectRole)
|
||||
self.dialogBtns.accepted.connect(self.accept)
|
||||
self.dialogBtns.rejected.connect(self.reject)
|
||||
|
||||
layout = QFormLayout()
|
||||
|
||||
layout.addRow(self.remarkText)
|
||||
layout.addRow(self.remarkEdit)
|
||||
layout.addRow(self.dialogBtns)
|
||||
layout.setFormAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
def routingRemark(self):
|
||||
return self.remarkEdit.text()
|
||||
|
||||
def connectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-connected-dark.svg'))
|
||||
|
||||
def disconnectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-window.svg'))
|
||||
|
||||
def retranslate(self):
|
||||
with StateContext(self):
|
||||
self.setWindowTitle(_(self.windowTitle()))
|
||||
|
||||
self.remarkText.setText(_(self.remarkText.text()))
|
||||
|
||||
for button in self.dialogBtns.buttons():
|
||||
button.setText(_(button.text()))
|
||||
|
||||
|
||||
class EditRoutingWidget(MainWindow):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -978,6 +1009,7 @@ class EditRoutingWidget(Translatable, SupportConnectedCallback, QMainWindow):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-window.svg'))
|
||||
|
||||
self.assetViewer = AssetViewerWidget()
|
||||
self.addRoutingDialog = AddRoutingDialog()
|
||||
|
||||
try:
|
||||
self.StorageObj = RoutesStorage.toObject(APP().CustomRouting)
|
||||
@@ -1048,36 +1080,44 @@ class EditRoutingWidget(Translatable, SupportConnectedCallback, QMainWindow):
|
||||
moveToCenter(self)
|
||||
|
||||
def addRoute(self):
|
||||
# Get text for a new item from the user
|
||||
text, ok = QInputDialog.getText(
|
||||
self, _('Add routing'), _('Enter routing remark:')
|
||||
)
|
||||
choice = self.addRoutingDialog.exec()
|
||||
|
||||
if text and ok:
|
||||
self.editRoutingTableWidget.appendDataByColumn(
|
||||
lambda column: EditRoutingTableWidget.USER_ITEM_GET_FUNC[column](text)
|
||||
)
|
||||
if choice == QDialog.DialogCode.Accepted.value:
|
||||
routingRemark = self.addRoutingDialog.routingRemark()
|
||||
|
||||
routingEditor = self.editRoutingTableWidget.appendRoutingEditor(
|
||||
text, isBuiltin=False
|
||||
)
|
||||
|
||||
for core in [XrayCore.name(), Hysteria.name()]:
|
||||
routingEditor.addTabWithData(
|
||||
core,
|
||||
USER_ROUTING_TEXT[core],
|
||||
if routingRemark:
|
||||
self.editRoutingTableWidget.appendDataByColumn(
|
||||
lambda column: EditRoutingTableWidget.USER_ITEM_GET_FUNC[column](
|
||||
routingRemark
|
||||
)
|
||||
)
|
||||
|
||||
self.RoutesList.append({'remark': text, **DEFAULT_USER_ROUTING})
|
||||
routingEditor = self.editRoutingTableWidget.appendRoutingEditor(
|
||||
routingRemark, isBuiltin=False
|
||||
)
|
||||
|
||||
# Sync it
|
||||
RoutesStorage.sync()
|
||||
for core in [XrayCore.name(), Hysteria.name()]:
|
||||
routingEditor.addTabWithData(
|
||||
core,
|
||||
USER_ROUTING_TEXT[core],
|
||||
)
|
||||
|
||||
routingAction = APP().tray.RoutingAction
|
||||
# Add entry in routing menu
|
||||
routingAction.addAction(
|
||||
RoutingChildAction(text, checkable=True, checked=False)
|
||||
)
|
||||
self.RoutesList.append(
|
||||
{'remark': routingRemark, **DEFAULT_USER_ROUTING}
|
||||
)
|
||||
|
||||
# Sync it
|
||||
RoutesStorage.sync()
|
||||
|
||||
routingAction = APP().tray.RoutingAction
|
||||
# Add entry in routing menu
|
||||
routingAction.addAction(
|
||||
RoutingChildAction(routingRemark, checkable=True, checked=False)
|
||||
)
|
||||
|
||||
else:
|
||||
# Do nothing
|
||||
pass
|
||||
|
||||
def deleteSelectedItem(self):
|
||||
self.editRoutingTableWidget.deleteSelectedItem()
|
||||
@@ -1090,12 +1130,6 @@ class EditRoutingWidget(Translatable, SupportConnectedCallback, QMainWindow):
|
||||
f'{self.geometry().width()},{self.geometry().height()}'
|
||||
)
|
||||
|
||||
if len(self.editRoutingTableWidget.routingEditorRef):
|
||||
APP().RoutesEditorWindowSize = (
|
||||
f'{self.editRoutingTableWidget.routingEditorRef[0].geometry().width()},'
|
||||
f'{self.editRoutingTableWidget.routingEditorRef[0].geometry().height()}'
|
||||
)
|
||||
|
||||
APP().RoutesWidgetSectionSizeTable = ujson.dumps(
|
||||
self.editRoutingTableWidget.sectionSizeTable,
|
||||
ensure_ascii=False,
|
||||
@@ -1107,19 +1141,3 @@ class EditRoutingWidget(Translatable, SupportConnectedCallback, QMainWindow):
|
||||
self.deleteSelectedItem()
|
||||
else:
|
||||
super().keyPressEvent(event)
|
||||
|
||||
def closeEvent(self, event):
|
||||
event.ignore()
|
||||
|
||||
self.syncSettings()
|
||||
self.hide()
|
||||
|
||||
def connectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-connected-dark.svg'))
|
||||
|
||||
def disconnectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-window.svg'))
|
||||
|
||||
def retranslate(self):
|
||||
with StateContext(self):
|
||||
self.setWindowTitle(_(self.windowTitle()))
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
from Furious.Widget.Widget import MainWindow
|
||||
|
||||
from Furious.Utility.Constants import APPLICATION_NAME
|
||||
from Furious.Utility.Utility import SupportConnectedCallback, bootstrapIcon
|
||||
from Furious.Utility.Translator import gettext as _
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtGui import QPixmap
|
||||
from PySide6.QtWidgets import QLabel, QMainWindow, QTabWidget
|
||||
from PySide6.QtWidgets import QLabel, QTabWidget
|
||||
|
||||
import io
|
||||
import pyqrcode
|
||||
|
||||
|
||||
class ExportQRCode(SupportConnectedCallback, QMainWindow):
|
||||
class ExportQRCode(MainWindow):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
@@ -47,9 +49,3 @@ class ExportQRCode(SupportConnectedCallback, QMainWindow):
|
||||
|
||||
if self.editorTab.count() == 0:
|
||||
self.hide()
|
||||
|
||||
def connectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-connected-dark.svg'))
|
||||
|
||||
def disconnectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-window.svg'))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from Furious.Gui.Action import Action, Seperator
|
||||
from Furious.Widget.Widget import Menu, MessageBox, ZoomableTextBrowser
|
||||
from Furious.Widget.Widget import MainWindow, Menu, MessageBox, ZoomableTextBrowser
|
||||
from Furious.Utility.Constants import APP
|
||||
from Furious.Utility.Utility import (
|
||||
StateContext,
|
||||
@@ -10,7 +10,7 @@ from Furious.Utility.Translator import Translatable, gettext as _
|
||||
from Furious.Utility.Theme import DraculaTheme
|
||||
|
||||
from PySide6 import QtCore
|
||||
from PySide6.QtWidgets import QFileDialog, QMainWindow, QTextBrowser
|
||||
from PySide6.QtWidgets import QFileDialog, QTextBrowser
|
||||
|
||||
import logging
|
||||
|
||||
@@ -134,7 +134,7 @@ class ZoomOutAction(Action):
|
||||
self.parent().textBrowser.zoomOut()
|
||||
|
||||
|
||||
class LogViewerWidget(Translatable, SupportConnectedCallback, QMainWindow):
|
||||
class LogViewerWidget(MainWindow):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -201,19 +201,3 @@ class LogViewerWidget(Translatable, SupportConnectedCallback, QMainWindow):
|
||||
|
||||
def syncSettings(self):
|
||||
APP().ViewerWidgetPointSize = str(self.textBrowser.font().pointSize())
|
||||
|
||||
def closeEvent(self, event):
|
||||
event.ignore()
|
||||
|
||||
self.syncSettings()
|
||||
self.hide()
|
||||
|
||||
def connectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-connected-dark.svg'))
|
||||
|
||||
def disconnectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-window.svg'))
|
||||
|
||||
def retranslate(self):
|
||||
with StateContext(self):
|
||||
self.setWindowTitle(_(self.windowTitle()))
|
||||
|
||||
@@ -3,6 +3,7 @@ from Furious.Utility.Constants import APP
|
||||
from Furious.Utility.Utility import (
|
||||
StateContext,
|
||||
SupportConnectedCallback,
|
||||
NeedSyncSettings,
|
||||
bootstrapIcon,
|
||||
moveToCenter,
|
||||
)
|
||||
@@ -15,6 +16,7 @@ from PySide6.QtWidgets import (
|
||||
QInputDialog,
|
||||
QLineEdit,
|
||||
QListWidget,
|
||||
QMainWindow,
|
||||
QMenu,
|
||||
QMessageBox,
|
||||
QPlainTextEdit,
|
||||
@@ -56,6 +58,31 @@ class ListWidget(QListWidget):
|
||||
return sorted(list(set(index.row() for index in self.selectedIndexes())))
|
||||
|
||||
|
||||
class MainWindow(Translatable, SupportConnectedCallback, NeedSyncSettings, QMainWindow):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def syncSettings(self):
|
||||
pass
|
||||
|
||||
def closeEvent(self, event):
|
||||
event.ignore()
|
||||
|
||||
# Sync partial
|
||||
self.syncSettings()
|
||||
self.hide()
|
||||
|
||||
def connectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-connected-dark.svg'))
|
||||
|
||||
def disconnectedCallback(self):
|
||||
self.setWindowIcon(bootstrapIcon('rocket-takeoff-window.svg'))
|
||||
|
||||
def retranslate(self):
|
||||
with StateContext(self):
|
||||
self.setWindowTitle(_(self.windowTitle()))
|
||||
|
||||
|
||||
class Menu(Translatable, QMenu):
|
||||
def __init__(self, *actions, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
|
||||
Reference in New Issue
Block a user