Refactor: Migrate to QTableView for UserSubsQTableView

Signed-off-by: LorenEteval <loren.eteval@proton.me>
This commit is contained in:
LorenEteval
2026-06-21 15:56:17 +08:00
committed by Loren Eteval
parent 26e8e2d4f1
commit 3118ac0c01
6 changed files with 273 additions and 149 deletions
+21 -21
View File
@@ -3,7 +3,7 @@ TRANSLATION = {
"source": [
"Furious.Qt.QtWidgets",
"Furious.Widget.UserServersQTableView",
"Furious.Widget.UserSubsQTableWidget",
"Furious.Widget.UserSubsQTableView",
"Furious.Widget.XrayAssetViewerQListWidget",
"Furious.Window.UserSubsWindow"
],
@@ -441,7 +441,7 @@ TRANSLATION = {
"Furious.Widget.GuiVLESS",
"Furious.Widget.GuiVMess",
"Furious.Widget.UserServersQTableView",
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Примечание",
"ZH": "别名",
@@ -1491,7 +1491,7 @@ TRANSLATION = {
},
"Auto Update": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Автообновление",
"ZH": "自动更新",
@@ -1499,7 +1499,7 @@ TRANSLATION = {
},
"Auto Update Use Proxy": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Автообновление (используя прокси)",
"ZH": "自动更新使用代理",
@@ -1507,7 +1507,7 @@ TRANSLATION = {
},
"Never": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Никогда",
"ZH": "从不",
@@ -1515,7 +1515,7 @@ TRANSLATION = {
},
"Every 5 mins": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Каждые 5 минут",
"ZH": "每5分钟",
@@ -1523,7 +1523,7 @@ TRANSLATION = {
},
"Every 10 mins": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Каждые 10 минут",
"ZH": "每10分钟",
@@ -1531,7 +1531,7 @@ TRANSLATION = {
},
"Every 15 mins": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Каждые 15 минут",
"ZH": "每15分钟",
@@ -1539,7 +1539,7 @@ TRANSLATION = {
},
"Every 30 mins": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Каждые 30 минут",
"ZH": "每30分钟",
@@ -1547,7 +1547,7 @@ TRANSLATION = {
},
"Every 45 mins": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Каждые 45 минут",
"ZH": "每45分钟",
@@ -1555,7 +1555,7 @@ TRANSLATION = {
},
"Every 1 hour": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Каждый 1 час",
"ZH": "每1小时",
@@ -1563,7 +1563,7 @@ TRANSLATION = {
},
"Every 2 hours": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Каждые 2 часа",
"ZH": "每2小时",
@@ -1571,7 +1571,7 @@ TRANSLATION = {
},
"Every 3 hours": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Каждые 3 часа",
"ZH": "每3小时",
@@ -1579,7 +1579,7 @@ TRANSLATION = {
},
"Every 6 hours": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Каждые 6 часов",
"ZH": "每6小时",
@@ -1587,7 +1587,7 @@ TRANSLATION = {
},
"Every 8 hours": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Каждые 8 часов",
"ZH": "每8小时",
@@ -1595,7 +1595,7 @@ TRANSLATION = {
},
"Every 10 hours": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Каждые 10 часов",
"ZH": "每10小时",
@@ -1603,7 +1603,7 @@ TRANSLATION = {
},
"Every 12 hours": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Каждые 12 часов",
"ZH": "每12小时",
@@ -1611,7 +1611,7 @@ TRANSLATION = {
},
"Every 24 hours": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Каждые 24 часа",
"ZH": "每24小时",
@@ -1619,7 +1619,7 @@ TRANSLATION = {
},
"Use current proxy": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Использовать текущий прокси-сервер",
"ZH": "使用当前代理",
@@ -1627,7 +1627,7 @@ TRANSLATION = {
},
"Force proxy": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Обязательно через прокси-сервер",
"ZH": "强制代理",
@@ -1635,7 +1635,7 @@ TRANSLATION = {
},
"No proxy": {
"source": [
"Furious.Widget.UserSubsQTableWidget"
"Furious.Widget.UserSubsQTableView"
],
"RU": "Не использовать прокси",
"ZH": "无代理",
+4 -4
View File
@@ -46,7 +46,7 @@ import logging
import icmplib
import functools
__all__ = ['UserServersQTableWidget']
__all__ = ['UserServersQTableView']
logger = logging.getLogger(__name__)
@@ -137,7 +137,7 @@ class SubscriptionManager(WebGETManager):
parent = self.parent()
if isinstance(parent, UserServersQTableWidget):
if isinstance(parent, UserServersQTableView):
isConnected = APP().isSystemTrayConnected()
subsIndexes = list(
@@ -450,7 +450,7 @@ class TestDownloadSpeedWorker(WebGETManager):
parent = self.parent()
# parent must be properly set
assert isinstance(parent, UserServersQTableWidget)
assert isinstance(parent, UserServersQTableView)
return parent.testDownloadSpeedMultiSema
@@ -1030,7 +1030,7 @@ _TRANSLATABLE_HEADERS = [
]
class UserServersQTableWidget(Mixins.QTranslatable, AppQTableView):
class UserServersQTableView(Mixins.QTranslatable, AppQTableView):
Headers = [
UserServersQTableViewHeaders('Remark'),
UserServersQTableViewHeaders('Protocol'),
@@ -1,4 +1,4 @@
# Copyright (C) 2024–present Loren Eteval & contributors <loren.eteval@proton.me>
# Copyright (C) 2024-present Loren Eteval & contributors <loren.eteval@proton.me>
#
# This file is part of Furious.
#
@@ -33,24 +33,24 @@ import functools
logger = logging.getLogger(__name__)
__all__ = ['UserSubsQTableWidget']
__all__ = ['UserSubsQTableView']
# Migrate legacy settings
registerAppSettings('SubscriptionWidgetSectionSizeTable')
registerAppSettings('UserSubsHeaderViewState')
class UserSubsQTableWidgetHorizontalHeader(AppQHeaderView):
class UserSubsQTableViewHorizontalHeader(AppQHeaderView):
def __init__(self, *args, **kwargs):
super().__init__(QtCore.Qt.Orientation.Horizontal, *args, **kwargs)
class UserSubsQTableWidgetVerticalHeader(AppQHeaderView):
class UserSubsQTableViewVerticalHeader(AppQHeaderView):
def __init__(self, *args, **kwargs):
super().__init__(QtCore.Qt.Orientation.Vertical, *args, **kwargs)
class UserSubsQTableWidgetHeaders:
class UserSubsQTableViewHeaders:
def __init__(self, name: str, func: Callable[[dict], str] = None):
self.name = name
self.func = func
@@ -78,6 +78,143 @@ class UserSubsAppQComboBox(AppQComboBox):
super().retranslate()
class UserSubsTableModel(QtCore.QAbstractTableModel):
def __init__(
self,
headers: list[UserSubsQTableViewHeaders],
itemKey: list[str],
parent=None,
):
super().__init__(parent)
self.headers = headers
self.itemKey = itemKey
def rowCount(self, parent=QtCore.QModelIndex()) -> int:
if parent.isValid():
return 0
return len(Storage.UserSubs())
def columnCount(self, parent=QtCore.QModelIndex()) -> int:
if parent.isValid():
return 0
return len(self.headers)
def flags(self, index):
if not index.isValid():
return QtCore.Qt.ItemFlag.NoItemFlags
flags = QtCore.Qt.ItemFlag.ItemIsEnabled | QtCore.Qt.ItemFlag.ItemIsSelectable
if self.itemKey[index.column()] not in ['autoupdate', 'proxy']:
flags |= QtCore.Qt.ItemFlag.ItemIsEditable
return flags
def data(self, index, role=QtCore.Qt.ItemDataRole.DisplayRole):
if not index.isValid():
return None
row = index.row()
column = index.column()
if row < 0 or row >= len(Storage.UserSubs()):
return None
if column < 0 or column >= len(self.headers):
return None
subsob = self.subsObjectByRow(row)
text = self.headers[column](subsob)
if role == QtCore.Qt.ItemDataRole.DisplayRole:
if self.itemKey[column] in ['autoupdate', 'proxy']:
return _(text)
return text
if role == QtCore.Qt.ItemDataRole.EditRole:
return text
if role == QtCore.Qt.ItemDataRole.ToolTipRole:
return text
if role == QtCore.Qt.ItemDataRole.FontRole:
return QFont(AppFontName())
return None
def setData(self, index, value, role=QtCore.Qt.ItemDataRole.EditRole) -> bool:
if role != QtCore.Qt.ItemDataRole.EditRole or not index.isValid():
return False
row = index.row()
column = index.column()
if row < 0 or row >= len(Storage.UserSubs()):
return False
mapped = self.itemKey[column]
if mapped in ['autoupdate', 'proxy']:
return False
self.subsObjectByRow(row)[mapped] = str(value)
self.dataChanged.emit(index, index, [])
return True
def headerData(
self,
section: int,
orientation: QtCore.Qt.Orientation,
role=QtCore.Qt.ItemDataRole.DisplayRole,
):
if role != QtCore.Qt.ItemDataRole.DisplayRole:
return None
if orientation == QtCore.Qt.Orientation.Horizontal:
if 0 <= section < len(self.headers):
return _(str(self.headers[section]))
return None
return section + 1
@staticmethod
def uniqueByRow(row: int) -> str:
return list(Storage.UserSubs().keys())[row]
@classmethod
def subsObjectByRow(cls, row: int) -> dict:
return Storage.UserSubs()[cls.uniqueByRow(row)]
def emitRowChanged(self, row: int, column: Union[int, None] = None):
if row < 0 or row >= self.rowCount():
return
if column is None:
left = self.index(row, 0)
right = self.index(row, self.columnCount() - 1)
else:
left = self.index(row, column)
right = left
self.dataChanged.emit(left, right, [])
def emitAllChanged(self):
if self.rowCount() == 0 or self.columnCount() == 0:
return
self.dataChanged.emit(
self.index(0, 0),
self.index(self.rowCount() - 1, self.columnCount() - 1),
[],
)
# Headers VALUE
_TRANSLATABLE_HEADERS = [
_('Never'),
@@ -103,7 +240,7 @@ _TRANSLATABLE_HEADERS = [
]
class UserSubsQTableWidget(Mixins.QTranslatable, AppQTableWidget):
class UserSubsQTableView(Mixins.QTranslatable, AppQTableView):
AutoUpdateOptions = {
'': None,
'Never': None,
@@ -130,12 +267,12 @@ class UserSubsQTableWidget(Mixins.QTranslatable, AppQTableWidget):
}
Headers = [
UserSubsQTableWidgetHeaders('Remark', lambda item: item.get('remark', '')),
UserSubsQTableWidgetHeaders('URL', lambda item: item.get('webURL', '')),
UserSubsQTableWidgetHeaders(
UserSubsQTableViewHeaders('Remark', lambda item: item.get('remark', '')),
UserSubsQTableViewHeaders('URL', lambda item: item.get('webURL', '')),
UserSubsQTableViewHeaders(
'Auto Update', lambda item: item.get('autoupdate', '')
),
UserSubsQTableWidgetHeaders(
UserSubsQTableViewHeaders(
'Auto Update Use Proxy', lambda item: item.get('proxy', '')
),
]
@@ -149,32 +286,29 @@ class UserSubsQTableWidget(Mixins.QTranslatable, AppQTableWidget):
super().__init__(*args, **kwargs)
self.timers = list(QtCore.QTimer() for i in range(len(Storage.UserSubs())))
# Must set before flush all
self.setColumnCount(len(self.Headers))
# Flush all data to table
self.flushAll()
self.timerConnected = list(False for i in range(len(Storage.UserSubs())))
self.sourceModel = UserSubsTableModel(self.Headers, self.ItemKey, parent=self)
self.setModel(self.sourceModel)
# Install custom header
self.setHorizontalHeader(
UserSubsQTableWidgetHorizontalHeader(
UserSubsQTableViewHorizontalHeader(
parent=self,
legacySectionSizeSettingsName='SubscriptionWidgetSectionSizeTable',
sectionSizeSettingsName='UserSubsHeaderViewState',
)
)
self.setVerticalHeader(UserSubsQTableWidgetVerticalHeader(self))
self.setVerticalHeader(UserSubsQTableViewVerticalHeader(self))
self.horizontalHeader().setCustomSectionResizeMode()
self.horizontalHeader().restoreSectionSize()
self.setHorizontalHeaderLabels(list(_(str(header)) for header in self.Headers))
self.setSortingEnabled(False)
# Selection
self.setSelectionColor(AppHue.disconnectedColor())
self.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
self.setSelectionMode(QTableWidget.SelectionMode.ExtendedSelection)
self.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
# No drag and drop
self.setDragEnabled(False)
@@ -193,20 +327,16 @@ class UserSubsQTableWidget(Mixins.QTranslatable, AppQTableWidget):
self.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu)
# Signals
self.itemChanged.connect(self.handleItemChanged)
self.customContextMenuRequested.connect(self.handleCustomContextMenuRequested)
@QtCore.Slot(QTableWidgetItem)
def handleItemChanged(self, item: QTableWidgetItem):
unique = list(Storage.UserSubs().keys())[item.row()]
mapped = UserSubsQTableWidget.ItemKey[item.column()]
# Flush all data to table
self.flushAll()
# 'autoupdate', 'proxy' is not triggered here
assert mapped not in ['autoupdate', 'proxy']
item.setToolTip(item.text())
Storage.UserSubs()[unique][mapped] = item.text()
@property
def selectedIndex(self):
return sorted(
list(set(index.row() for index in self.selectionModel().selectedRows()))
)
@QtCore.Slot(QtCore.QPoint)
def handleCustomContextMenuRequested(self, point):
@@ -227,7 +357,11 @@ class UserSubsQTableWidget(Mixins.QTranslatable, AppQTableWidget):
deleteIndex = _indexes[i] - i
deleteUnique = list(Storage.UserSubs().keys())[deleteIndex]
self.removeRow(deleteIndex)
self.sourceModel.beginRemoveRows(
QtCore.QModelIndex(),
deleteIndex,
deleteIndex,
)
Storage.UserSubs().pop(deleteUnique)
@@ -236,22 +370,28 @@ class UserSubsQTableWidget(Mixins.QTranslatable, AppQTableWidget):
assert isinstance(qtimer, QtCore.QTimer)
try:
qtimer.timeout.disconnect()
except Exception as ex:
# Any non-exit exceptions
if self.timerConnected[deleteIndex]:
try:
qtimer.timeout.disconnect()
except Exception as ex:
# Any non-exit exceptions
# Disconnect all previous signals if possible
pass
# Disconnect all previous signals if possible
pass
qtimer.stop()
# End timer cleanup
# Remove timer from list
self.timers.pop(deleteIndex)
self.timerConnected.pop(deleteIndex)
self.sourceModel.endRemoveRows()
if callable(self.deleteUniqueCallback):
self.deleteUniqueCallback(deleteUnique)
self.flushAll()
else:
# Do not delete
pass
@@ -267,7 +407,10 @@ class UserSubsQTableWidget(Mixins.QTranslatable, AppQTableWidget):
mbox.setWindowModality(QtCore.Qt.WindowModality.WindowModal)
mbox.isMulti = bool(len(indexes) > 1)
mbox.possibleRemark = self.item(indexes[0], 0).text()
mbox.possibleRemark = self.sourceModel.data(
self.sourceModel.index(indexes[0], 0),
QtCore.Qt.ItemDataRole.DisplayRole,
)
mbox.setText(mbox.customText())
mbox.finished.connect(functools.partial(handleResultCode, indexes))
@@ -308,13 +451,14 @@ class UserSubsQTableWidget(Mixins.QTranslatable, AppQTableWidget):
def getHttpProxy(_subsob):
return self.ProxyOptions[_subsob.get('proxy', '')]()
try:
qtimer.timeout.disconnect()
except Exception as ex:
# Any non-exit exceptions
if self.timerConnected[row]:
try:
qtimer.timeout.disconnect()
except Exception as ex:
# Any non-exit exceptions
# Disconnect all previous signals if possible
pass
# Disconnect all previous signals if possible
pass
qtimer.timeout.connect(
functools.partial(
@@ -323,22 +467,27 @@ class UserSubsQTableWidget(Mixins.QTranslatable, AppQTableWidget):
httpProxy=functools.partial(getHttpProxy, subsob),
)
)
self.timerConnected[row] = True
qtimer.start(timems)
else:
logger.info(f'stop auto update job for subscription ({remark}, {webURL})')
try:
qtimer.timeout.disconnect()
except Exception as ex:
# Any non-exit exceptions
if self.timerConnected[row]:
try:
qtimer.timeout.disconnect()
except Exception as ex:
# Any non-exit exceptions
# Disconnect all previous signals if possible
pass
# Disconnect all previous signals if possible
pass
self.timerConnected[row] = False
qtimer.stop()
# Write to subs object
subsob['autoupdate'] = textEnglish
self.sourceModel.emitRowChanged(row, self.Headers.index('Auto Update'))
# Return potentially fixed value
return textEnglish
@@ -366,31 +515,32 @@ class UserSubsQTableWidget(Mixins.QTranslatable, AppQTableWidget):
# Write to subs object
subsob['proxy'] = textEnglish
self.sourceModel.emitRowChanged(
row, self.Headers.index('Auto Update Use Proxy')
)
# Return potentially fixed value
return textEnglish
def flushItem(self, row, column, item):
if row < 0 or row >= self.sourceModel.rowCount():
return
index = self.sourceModel.index(row, column)
if column == self.Headers.index('Auto Update'):
header = self.Headers[column]
oldItem = self.item(row, column)
newItem = UserSubsAppQComboBox()
newItem.addItems(list(_(key) for key in self.AutoUpdateOptions.keys()))
newItem.setFont(QFont(AppFontName()))
if oldItem is None:
# Item does not exist
newItem.setFont(QFont(AppFontName()))
else:
# Use existing
newItem.setFont(oldItem.font())
index = newItem.findText(
itemIndex = newItem.findText(
_(self.handleAutoUpdateComboBoxCurrentTextChanged(header(item), row))
)
if index >= 0:
newItem.setCurrentIndex(index)
if itemIndex >= 0:
newItem.setCurrentIndex(itemIndex)
newItem.currentTextChanged.connect(
functools.partial(
@@ -399,27 +549,21 @@ class UserSubsQTableWidget(Mixins.QTranslatable, AppQTableWidget):
)
)
self.setCellWidget(row, column, newItem)
self.setIndexWidget(index, newItem)
self.sourceModel.emitRowChanged(row, column)
elif column == self.Headers.index('Auto Update Use Proxy'):
header = self.Headers[column]
oldItem = self.item(row, column)
newItem = UserSubsAppQComboBox()
newItem.addItems(list(_(key) for key in self.ProxyOptions.keys()))
newItem.setFont(QFont(AppFontName()))
if oldItem is None:
# Item does not exist
newItem.setFont(QFont(AppFontName()))
else:
# Use existing
newItem.setFont(oldItem.font())
index = newItem.findText(
itemIndex = newItem.findText(
_(self.handleProxyComboBoxCurrentTextChanged(header(item), row))
)
if index >= 0:
newItem.setCurrentIndex(index)
if itemIndex >= 0:
newItem.setCurrentIndex(itemIndex)
newItem.currentTextChanged.connect(
functools.partial(
@@ -428,48 +572,20 @@ class UserSubsQTableWidget(Mixins.QTranslatable, AppQTableWidget):
)
)
self.setCellWidget(row, column, newItem)
self.setIndexWidget(index, newItem)
self.sourceModel.emitRowChanged(row, column)
else:
header = self.Headers[column]
text = header(item)
oldItem = self.item(row, column)
newItem = QTableWidgetItem(text)
newItem.setToolTip(text)
if oldItem is None:
# Item does not exist
newItem.setFont(QFont(AppFontName()))
else:
# Use existing
newItem.setFont(oldItem.font())
newItem.setForeground(oldItem.foreground())
if oldItem.textAlignment() != 0:
newItem.setTextAlignment(oldItem.textAlignment())
# Editable
newItem.setFlags(
QtCore.Qt.ItemFlag.ItemIsEnabled
| QtCore.Qt.ItemFlag.ItemIsSelectable
| QtCore.Qt.ItemFlag.ItemIsEditable
)
self.setItem(row, column, newItem)
self.sourceModel.emitRowChanged(row, column)
def flushRow(self, row, item):
for column in list(range(self.columnCount())):
for column in list(range(self.sourceModel.columnCount())):
self.flushItem(row, column, item)
def flushAll(self):
if self.rowCount() == 0:
# Should insert row
for index, key in enumerate(Storage.UserSubs()):
self.insertRow(index)
self.flushRow(index, Storage.UserSubs()[key])
else:
for index, key in enumerate(Storage.UserSubs()):
self.flushRow(index, Storage.UserSubs()[key])
self.sourceModel.emitAllChanged()
for index, key in enumerate(Storage.UserSubs()):
self.flushRow(index, Storage.UserSubs()[key])
def appendNewItem(self, **kwargs):
unique, remark, webURL, autoupdate, proxy = (
@@ -491,18 +607,22 @@ class UserSubsQTableWidget(Mixins.QTranslatable, AppQTableWidget):
}
}
# 'unique' should be unique in subscription storage,
# but protect it anyway.
if unique not in Storage.UserSubs():
if unique in Storage.UserSubs():
row = list(Storage.UserSubs().keys()).index(unique)
Storage.UserSubs().update(subsob)
self.flushRow(row, subsob[unique])
else:
row = self.sourceModel.rowCount()
# Add timer
self.timers.append(QtCore.QTimer())
self.timerConnected.append(False)
Storage.UserSubs().update(subsob)
self.sourceModel.beginInsertRows(QtCore.QModelIndex(), row, row)
Storage.UserSubs().update(subsob)
self.sourceModel.endInsertRows()
row = self.rowCount()
self.insertRow(row)
self.flushRow(row, subsob[unique])
self.flushRow(row, subsob[unique])
@staticmethod
def updateSubsByUnique(
@@ -530,4 +650,8 @@ class UserSubsQTableWidget(Mixins.QTranslatable, AppQTableWidget):
)
def retranslate(self):
self.setHorizontalHeaderLabels(list(_(str(header)) for header in self.Headers))
self.sourceModel.headerDataChanged.emit(
QtCore.Qt.Orientation.Horizontal,
0,
len(self.Headers) - 1,
)
+1 -1
View File
@@ -29,5 +29,5 @@ from .GuiVMess import *
from .IndentSpinBox import *
from .SystemTrayIcon import *
from .UserServersQTableView import *
from .UserSubsQTableWidget import *
from .UserSubsQTableView import *
from .XrayAssetViewerQListWidget import *
+1 -1
View File
@@ -119,7 +119,7 @@ class AppMainWindow(AppQMainWindow):
self.updatesManager = UpdatesManager(parent=self)
self.networkConnectivityManager = AppNetworkConnectivityManager(parent=self)
self.userServersQTableWidget = UserServersQTableWidget(parent=self)
self.userServersQTableWidget = UserServersQTableView(parent=self)
self.userSubsWindow = UserSubsWindow(
parent=self,
deleteUniqueCallback=lambda unique: self.userServersQTableWidget.deleteItemByIndex(
+2 -2
View File
@@ -20,7 +20,7 @@ from __future__ import annotations
from Furious.Frozenlib import *
from Furious.Qt import *
from Furious.Qt import gettext as _
from Furious.Widget.UserSubsQTableWidget import *
from Furious.Widget.UserSubsQTableView import *
from PySide6 import QtCore
from PySide6.QtWidgets import *
@@ -86,7 +86,7 @@ class UserSubsWindow(AppQMainWindow):
self.setWindowTitle(_('Edit Subscription'))
self.userSubsQTableWidget = UserSubsQTableWidget(
self.userSubsQTableWidget = UserSubsQTableView(
deleteUniqueCallback=callback, parent=self
)