diff --git a/Furious/Externals/GenTranslation.py b/Furious/Externals/GenTranslation.py index 7e3a0e1..7397d61 100644 --- a/Furious/Externals/GenTranslation.py +++ b/Furious/Externals/GenTranslation.py @@ -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": "无代理", diff --git a/Furious/Widget/UserServersQTableView.py b/Furious/Widget/UserServersQTableView.py index d681f33..2fbe5d9 100644 --- a/Furious/Widget/UserServersQTableView.py +++ b/Furious/Widget/UserServersQTableView.py @@ -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'), diff --git a/Furious/Widget/UserSubsQTableWidget.py b/Furious/Widget/UserSubsQTableView.py similarity index 59% rename from Furious/Widget/UserSubsQTableWidget.py rename to Furious/Widget/UserSubsQTableView.py index b0a32a3..8519043 100644 --- a/Furious/Widget/UserSubsQTableWidget.py +++ b/Furious/Widget/UserSubsQTableView.py @@ -1,4 +1,4 @@ -# Copyright (C) 2024–present Loren Eteval & contributors +# Copyright (C) 2024-present Loren Eteval & contributors # # 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, + ) diff --git a/Furious/Widget/__init__.py b/Furious/Widget/__init__.py index 2c887cc..af0201a 100644 --- a/Furious/Widget/__init__.py +++ b/Furious/Widget/__init__.py @@ -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 * diff --git a/Furious/Window/AppMainWindow.py b/Furious/Window/AppMainWindow.py index fc95d96..d6eb6e4 100644 --- a/Furious/Window/AppMainWindow.py +++ b/Furious/Window/AppMainWindow.py @@ -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( diff --git a/Furious/Window/UserSubsWindow.py b/Furious/Window/UserSubsWindow.py index 14d9715..682aad5 100644 --- a/Furious/Window/UserSubsWindow.py +++ b/Furious/Window/UserSubsWindow.py @@ -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 )