ExtraWidgets: Remove IndicatorLineEdit and PathEdit and update imports
This commit is contained in:
parent
97def45a7e
commit
5938835249
12 changed files with 13 additions and 325 deletions
|
@ -15,9 +15,9 @@ from rare.shared.workers.install_info import InstallInfoWorker
|
|||
from rare.ui.components.dialogs.install_dialog import Ui_InstallDialog
|
||||
from rare.ui.components.dialogs.install_dialog_advanced import Ui_InstallDialogAdvanced
|
||||
from rare.utils import config_helper
|
||||
from rare.utils.extra_widgets import PathEdit, IndicatorReasonsCommon
|
||||
from rare.utils.misc import get_size
|
||||
from rare.widgets.collapsible_widget import CollapsibleFrame
|
||||
from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon
|
||||
|
||||
|
||||
class InstallDialogAdvanced(CollapsibleFrame):
|
||||
|
|
|
@ -9,8 +9,8 @@ from legendary.core import LegendaryCore
|
|||
from legendary.utils import webview_login
|
||||
|
||||
from rare.ui.components.dialogs.login.browser_login import Ui_BrowserLogin
|
||||
from rare.utils.extra_widgets import IndicatorLineEdit, IndicatorReasonsCommon
|
||||
from rare.utils.misc import icon
|
||||
from rare.widgets.indicator_edit import IndicatorLineEdit, IndicatorReasonsCommon
|
||||
|
||||
logger = getLogger("BrowserLogin")
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ from PyQt5.QtWidgets import (
|
|||
QFileDialog,
|
||||
)
|
||||
|
||||
from rare.utils.extra_widgets import PathEdit
|
||||
from rare.widgets.indicator_edit import PathEdit
|
||||
|
||||
|
||||
class PathInputDialog(QDialog):
|
||||
|
|
|
@ -11,7 +11,7 @@ from rare.components.tabs.settings.widgets.pre_launch import PreLaunchSettings
|
|||
from rare.models.game import RareGame
|
||||
from rare.shared.workers.wine_resolver import WineResolver
|
||||
from rare.utils import config_helper
|
||||
from rare.utils.extra_widgets import PathEdit, IndicatorReasonsCommon
|
||||
from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon
|
||||
from rare.utils.misc import icon, get_raw_save_path
|
||||
|
||||
logger = getLogger("GameSettings")
|
||||
|
|
|
@ -9,9 +9,9 @@ from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLab
|
|||
|
||||
from rare.models.game import RareGame
|
||||
from rare.shared import RareCore
|
||||
from rare.utils.extra_widgets import PathEdit, IndicatorReasons, IndicatorReasonsCommon
|
||||
from rare.utils.misc import get_size
|
||||
from rare.widgets.elide_label import ElideLabel
|
||||
from rare.widgets.indicator_edit import PathEdit, IndicatorReasons, IndicatorReasonsCommon
|
||||
|
||||
logger = getLogger("MoveGame")
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ from rare.shared import RareCore
|
|||
from rare.shared.workers.wine_resolver import WineResolver
|
||||
from rare.ui.components.tabs.games.integrations.egl_sync_group import Ui_EGLSyncGroup
|
||||
from rare.ui.components.tabs.games.integrations.egl_sync_list_group import Ui_EGLSyncListGroup
|
||||
from rare.utils.extra_widgets import PathEdit, IndicatorReasonsCommon
|
||||
from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon
|
||||
|
||||
logger = getLogger("EGLSync")
|
||||
|
||||
|
|
|
@ -17,8 +17,8 @@ from rare.lgndr.glue.arguments import LgndrImportGameArgs
|
|||
from rare.lgndr.glue.monkeys import LgndrIndirectStatus
|
||||
from rare.shared import RareCore
|
||||
from rare.ui.components.tabs.games.integrations.import_group import Ui_ImportGroup
|
||||
from rare.utils.extra_widgets import IndicatorLineEdit, IndicatorReasonsCommon, PathEdit
|
||||
from rare.widgets.elide_label import ElideLabel
|
||||
from rare.widgets.indicator_edit import IndicatorLineEdit, IndicatorReasonsCommon, PathEdit
|
||||
|
||||
logger = getLogger("Import")
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ from PyQt5.QtWidgets import QSizePolicy, QWidget, QFileDialog, QMessageBox
|
|||
|
||||
from rare.shared import LegendaryCoreSingleton
|
||||
from rare.ui.components.tabs.settings.legendary import Ui_LegendarySettings
|
||||
from rare.utils.extra_widgets import PathEdit, IndicatorLineEdit, IndicatorReasonsCommon
|
||||
from rare.utils.misc import get_size
|
||||
from rare.widgets.indicator_edit import PathEdit, IndicatorLineEdit, IndicatorReasonsCommon
|
||||
|
||||
logger = getLogger("LegendarySettings")
|
||||
|
||||
|
|
|
@ -7,9 +7,8 @@ from PyQt5.QtWidgets import QFileDialog, QWidget
|
|||
from rare.components.tabs.settings.widgets.dxvk import DxvkSettings
|
||||
from rare.components.tabs.settings.widgets.mangohud import MangoHudSettings
|
||||
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton
|
||||
|
||||
from rare.ui.components.tabs.settings.linux import Ui_LinuxSettings
|
||||
from rare.utils.extra_widgets import PathEdit, IndicatorReasonsCommon
|
||||
from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon
|
||||
|
||||
logger = getLogger("LinuxSettings")
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ from PyQt5.QtWidgets import QHBoxLayout, QCheckBox, QFileDialog
|
|||
|
||||
from rare.shared import LegendaryCoreSingleton
|
||||
from rare.utils import config_helper
|
||||
from rare.utils.extra_widgets import PathEdit, IndicatorReasonsCommon
|
||||
from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon
|
||||
|
||||
|
||||
class PreLaunchSettings(QHBoxLayout):
|
||||
|
|
|
@ -6,11 +6,11 @@ from typing import Tuple
|
|||
from PyQt5.QtWidgets import QGroupBox, QFileDialog
|
||||
|
||||
from rare.components.tabs.settings import LinuxSettings
|
||||
from .wrapper import WrapperSettings
|
||||
from rare.shared import LegendaryCoreSingleton
|
||||
from rare.ui.components.tabs.settings.proton import Ui_ProtonSettings
|
||||
from rare.utils import config_helper
|
||||
from rare.utils.extra_widgets import PathEdit, IndicatorReasonsCommon
|
||||
from rare.shared import LegendaryCoreSingleton
|
||||
from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon
|
||||
from .wrapper import WrapperSettings
|
||||
|
||||
logger = getLogger("Proton")
|
||||
|
||||
|
|
|
@ -1,27 +1,17 @@
|
|||
import os
|
||||
from enum import IntEnum
|
||||
from logging import getLogger
|
||||
from typing import Callable, Tuple, Optional, Dict
|
||||
|
||||
from PyQt5.QtCore import (
|
||||
Qt,
|
||||
QCoreApplication,
|
||||
QRect,
|
||||
QSize,
|
||||
QPoint,
|
||||
pyqtSignal,
|
||||
QFileInfo,
|
||||
QRunnable,
|
||||
QObject,
|
||||
QThreadPool,
|
||||
pyqtSlot,
|
||||
)
|
||||
from PyQt5.QtGui import QMovie, QPixmap, QFontMetrics, QImage
|
||||
from PyQt5.QtWidgets import (
|
||||
QStyle,
|
||||
QSizePolicy,
|
||||
QLabel,
|
||||
QFileDialog,
|
||||
QHBoxLayout,
|
||||
QWidget,
|
||||
QPushButton,
|
||||
|
@ -31,10 +21,6 @@ from PyQt5.QtWidgets import (
|
|||
QLineEdit,
|
||||
QToolButton,
|
||||
QTabWidget,
|
||||
QCompleter,
|
||||
QFileSystemModel,
|
||||
QStyledItemDelegate,
|
||||
QFileIconProvider,
|
||||
QVBoxLayout,
|
||||
QScrollArea,
|
||||
)
|
||||
|
@ -46,303 +32,6 @@ from rare.utils.qt_requests import QtRequestManager
|
|||
logger = getLogger("ExtraWidgets")
|
||||
|
||||
|
||||
class IndicatorReasonsCommon(IntEnum):
|
||||
VALID = 0
|
||||
UNDEFINED = 1
|
||||
WRONG_FORMAT = 2
|
||||
WRONG_PATH = 3
|
||||
DIR_NOT_EMPTY = 4
|
||||
DIR_NOT_EXISTS = 5
|
||||
FILE_NOT_EXISTS = 6
|
||||
NOT_INSTALLED = 7
|
||||
|
||||
|
||||
class IndicatorReasons(IntEnum):
|
||||
"""
|
||||
Empty enumeration with auto-generated enumeration values.
|
||||
Extend this class per-case to implement dedicated message types.
|
||||
Types should be assigned using `auto()` from enum
|
||||
|
||||
example:
|
||||
MyReasons(IndicatorReasons):
|
||||
MY_REASON = auto()
|
||||
"""
|
||||
@staticmethod
|
||||
def _generate_next_value_(name, start, count, last_values):
|
||||
"""generate consecutive automatic numbers starting from zero"""
|
||||
start = len(IndicatorReasonsCommon)
|
||||
return IntEnum._generate_next_value_(name, start, count, last_values)
|
||||
|
||||
|
||||
class IndicatorReasonsStrings(QObject):
|
||||
def __init__(self, parent=None):
|
||||
super(IndicatorReasonsStrings, self).__init__(parent=parent)
|
||||
self.__text = {
|
||||
IndicatorReasonsCommon.VALID: self.tr("Ok!"),
|
||||
IndicatorReasonsCommon.UNDEFINED: self.tr("Unknown error occured"),
|
||||
IndicatorReasonsCommon.WRONG_FORMAT: self.tr("Wrong format"),
|
||||
IndicatorReasonsCommon.WRONG_PATH: self.tr("Wrong directory"),
|
||||
IndicatorReasonsCommon.DIR_NOT_EMPTY: self.tr("Directory is not empty"),
|
||||
IndicatorReasonsCommon.DIR_NOT_EXISTS: self.tr("Directory does not exist"),
|
||||
IndicatorReasonsCommon.FILE_NOT_EXISTS: self.tr("File does not exist"),
|
||||
IndicatorReasonsCommon.NOT_INSTALLED: self.tr("Game is not installed or does not exist"),
|
||||
}
|
||||
|
||||
def __getitem__(self, item: int) -> str:
|
||||
return self.__text[item]
|
||||
|
||||
def __setitem__(self, key: int, value: str):
|
||||
self.__text[key] = value
|
||||
|
||||
def extend(self, reasons: Dict):
|
||||
for k in self.__text.keys():
|
||||
if k in reasons.keys():
|
||||
raise RuntimeError(f"{reasons} contains existing values")
|
||||
self.__text.update(reasons)
|
||||
|
||||
|
||||
class EditFuncRunnable(QRunnable):
|
||||
class Signals(QObject):
|
||||
result = pyqtSignal(bool, str, int)
|
||||
|
||||
def __init__(self, func: Callable[[str], Tuple[bool, str, int]], args: str):
|
||||
super(EditFuncRunnable, self).__init__()
|
||||
self.setAutoDelete(True)
|
||||
self.signals = EditFuncRunnable.Signals()
|
||||
self.func = func
|
||||
self.args = args
|
||||
|
||||
def run(self):
|
||||
o0, o1, o2 = self.func(self.args)
|
||||
self.signals.result.emit(o0, o1, o2)
|
||||
self.signals.deleteLater()
|
||||
|
||||
|
||||
class IndicatorLineEdit(QWidget):
|
||||
textChanged = pyqtSignal(str)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
text: str = "",
|
||||
placeholder: str = "",
|
||||
completer: QCompleter = None,
|
||||
edit_func: Callable[[str], Tuple[bool, str, int]] = None,
|
||||
save_func: Callable[[str], None] = None,
|
||||
horiz_policy: QSizePolicy.Policy = QSizePolicy.Expanding,
|
||||
parent=None,
|
||||
):
|
||||
super(IndicatorLineEdit, self).__init__(parent=parent)
|
||||
self.setObjectName(type(self).__name__)
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setObjectName(f"{self.objectName()}Layout")
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
# Add line_edit
|
||||
self.line_edit = QLineEdit(self)
|
||||
self.line_edit.setObjectName(f"{type(self).__name__}Edit")
|
||||
self.line_edit.setPlaceholderText(placeholder)
|
||||
self.line_edit.setSizePolicy(horiz_policy, QSizePolicy.Fixed)
|
||||
# Add hint_label to line_edit
|
||||
self.line_edit.setLayout(QHBoxLayout())
|
||||
self.hint_label = QLabel()
|
||||
self.hint_label.setObjectName(f"{type(self).__name__}Label")
|
||||
self.hint_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
|
||||
self.line_edit.layout().setContentsMargins(0, 0, 10, 0)
|
||||
self.line_edit.layout().addWidget(self.hint_label)
|
||||
# Add completer
|
||||
if completer is not None:
|
||||
completer.popup().setItemDelegate(QStyledItemDelegate(self))
|
||||
completer.popup().setAlternatingRowColors(True)
|
||||
self.line_edit.setCompleter(completer)
|
||||
layout.addWidget(self.line_edit)
|
||||
if edit_func is not None:
|
||||
self.indicator_label = QLabel()
|
||||
self.indicator_label.setPixmap(qta_icon("ei.info-circle", color="gray").pixmap(16, 16))
|
||||
self.indicator_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
||||
layout.addWidget(self.indicator_label)
|
||||
|
||||
if not placeholder:
|
||||
_translate = QCoreApplication.instance().translate
|
||||
self.line_edit.setPlaceholderText(_translate(self.__class__.__name__, "Default"))
|
||||
|
||||
self.__reasons = IndicatorReasonsStrings(self)
|
||||
|
||||
self.__threadpool = QThreadPool(self)
|
||||
self.__threadpool.setMaxThreadCount(1)
|
||||
self.__thread: Optional[EditFuncRunnable] = None
|
||||
|
||||
self.is_valid = False
|
||||
self.edit_func = edit_func
|
||||
self.save_func = save_func
|
||||
self.line_edit.textChanged.connect(self.__edit)
|
||||
if self.edit_func is None:
|
||||
self.line_edit.textChanged.connect(self.__save)
|
||||
|
||||
# lk: this can be placed here to trigger __edit
|
||||
# lk: it is going to save the input again if it is valid which
|
||||
# lk: is ok to do given the checks don't misbehave (they shouldn't)
|
||||
# lk: however it is going to edit any "understood" bad input to good input
|
||||
# lk: and we might not want that (but the validity check reports on the edited string)
|
||||
# lk: it is also going to trigger this widget's textChanged signal but that gets lost
|
||||
if text:
|
||||
self.line_edit.setText(text)
|
||||
|
||||
def text(self) -> str:
|
||||
return self.line_edit.text()
|
||||
|
||||
def setText(self, text: str):
|
||||
self.line_edit.setText(text)
|
||||
|
||||
def setHintText(self, text: str):
|
||||
self.hint_label.setFrameRect(self.line_edit.rect())
|
||||
self.hint_label.setText(text)
|
||||
|
||||
def extend_reasons(self, reasons: Dict):
|
||||
self.__reasons.extend(reasons)
|
||||
|
||||
def __indicator(self, valid, reason: int = 0):
|
||||
color = "green" if valid else "red"
|
||||
self.indicator_label.setPixmap(qta_icon("ei.info-circle", color=color).pixmap(16, 16))
|
||||
if not valid:
|
||||
self.indicator_label.setToolTip(self.__reasons[reason])
|
||||
else:
|
||||
self.indicator_label.setToolTip(self.__reasons[IndicatorReasonsCommon.VALID])
|
||||
|
||||
@pyqtSlot(bool, str, int)
|
||||
def __edit_handler(self, is_valid: bool, text: str, reason: int):
|
||||
self.__thread = None
|
||||
self.line_edit.blockSignals(True)
|
||||
if text != self.line_edit.text():
|
||||
self.line_edit.setText(text)
|
||||
self.line_edit.blockSignals(False)
|
||||
self.__indicator(is_valid, reason)
|
||||
if is_valid:
|
||||
self.__save(text)
|
||||
self.is_valid = is_valid
|
||||
self.textChanged.emit(text)
|
||||
|
||||
def __edit(self, text):
|
||||
if self.edit_func is not None:
|
||||
if self.__thread is not None:
|
||||
self.__thread.signals.result.disconnect(self.__edit_handler)
|
||||
self.__thread = EditFuncRunnable(self.edit_func, text)
|
||||
self.__thread.signals.result.connect(self.__edit_handler)
|
||||
self.__threadpool.start(self.__thread)
|
||||
|
||||
def __save(self, text):
|
||||
if self.save_func is not None:
|
||||
self.save_func(text)
|
||||
|
||||
|
||||
class PathEditIconProvider(QFileIconProvider):
|
||||
icons = [
|
||||
("mdi.file-cancel", "fa.file-excel-o"), # Unknown
|
||||
("mdi.desktop-classic", "fa.desktop"), # Computer
|
||||
("mdi.desktop-mac", "fa.desktop"), # Desktop
|
||||
("mdi.trash-can", "fa.trash"), # Trashcan
|
||||
("mdi.server-network", "fa.server"), # Network
|
||||
("mdi.harddisk", "fa.desktop"), # Drive
|
||||
("mdi.folder", "fa.folder"), # Folder
|
||||
("mdi.file", "fa.file"), # File
|
||||
("mdi.cog", "fa.cog"), # Executable
|
||||
]
|
||||
|
||||
def __init__(self):
|
||||
super(PathEditIconProvider, self).__init__()
|
||||
self.icon_types = {}
|
||||
for idx, (icn, fallback) in enumerate(PathEditIconProvider.icons):
|
||||
self.icon_types.update({idx - 1: qta_icon(icn, fallback, color="#eeeeee")})
|
||||
|
||||
def icon(self, info_type):
|
||||
if isinstance(info_type, QFileInfo):
|
||||
if info_type.isRoot():
|
||||
return self.icon_types[4]
|
||||
if info_type.isDir():
|
||||
return self.icon_types[5]
|
||||
if info_type.isFile():
|
||||
return self.icon_types[6]
|
||||
if info_type.isExecutable():
|
||||
return self.icon_types[7]
|
||||
return self.icon_types[-1]
|
||||
return self.icon_types[int(info_type)]
|
||||
|
||||
|
||||
class PathEdit(IndicatorLineEdit):
|
||||
def __init__(
|
||||
self,
|
||||
path: str = "",
|
||||
file_type: QFileDialog.FileType = QFileDialog.AnyFile,
|
||||
type_filter: str = "",
|
||||
name_filter: str = "",
|
||||
placeholder: str = "",
|
||||
edit_func: Callable[[str], Tuple[bool, str, int]] = None,
|
||||
save_func: Callable[[str], None] = None,
|
||||
horiz_policy: QSizePolicy.Policy = QSizePolicy.Expanding,
|
||||
parent=None,
|
||||
):
|
||||
self.completer = QCompleter()
|
||||
self.compl_model = QFileSystemModel()
|
||||
|
||||
try:
|
||||
self.compl_model.setOptions(
|
||||
QFileSystemModel.DontWatchForChanges
|
||||
| QFileSystemModel.DontResolveSymlinks
|
||||
| QFileSystemModel.DontUseCustomDirectoryIcons
|
||||
)
|
||||
except AttributeError as e: # Error on Ubuntu
|
||||
logger.warning(e)
|
||||
self.compl_model.setIconProvider(PathEditIconProvider())
|
||||
self.compl_model.setRootPath(path)
|
||||
self.completer.setModel(self.compl_model)
|
||||
|
||||
edit_func = self.__wrap_edit_function(edit_func)
|
||||
|
||||
super(PathEdit, self).__init__(
|
||||
text=path,
|
||||
placeholder=placeholder,
|
||||
completer=self.completer,
|
||||
edit_func=edit_func,
|
||||
save_func=save_func,
|
||||
horiz_policy=horiz_policy,
|
||||
parent=parent,
|
||||
)
|
||||
self.setObjectName(type(self).__name__)
|
||||
self.line_edit.setMinimumSize(QSize(250, 0))
|
||||
self.path_select = QToolButton(self)
|
||||
self.path_select.setObjectName(f"{type(self).__name__}Button")
|
||||
layout = self.layout()
|
||||
layout.addWidget(self.path_select)
|
||||
|
||||
self.path_select.setText(self.tr("Browse..."))
|
||||
|
||||
self.type_filter = type_filter
|
||||
self.name_filter = name_filter
|
||||
self.file_type = file_type
|
||||
|
||||
self.path_select.clicked.connect(self.__set_path)
|
||||
|
||||
def __set_path(self):
|
||||
dlg_path = self.line_edit.text()
|
||||
if not dlg_path:
|
||||
dlg_path = os.path.expanduser("~/")
|
||||
dlg = QFileDialog(self, self.tr("Choose path"), dlg_path)
|
||||
dlg.setFileMode(self.file_type)
|
||||
if self.type_filter:
|
||||
dlg.setFilter([self.type_filter])
|
||||
if self.name_filter:
|
||||
dlg.setNameFilter(self.name_filter)
|
||||
if dlg.exec_():
|
||||
names = dlg.selectedFiles()
|
||||
self.line_edit.setText(names[0])
|
||||
self.compl_model.setRootPath(names[0])
|
||||
|
||||
@staticmethod
|
||||
def __wrap_edit_function(func: Callable[[str], Tuple[bool, str, int]]):
|
||||
if func:
|
||||
return lambda text: func(os.path.expanduser(text) if text.startswith("~") else text)
|
||||
else:
|
||||
return func
|
||||
|
||||
|
||||
class SideTabBar(QTabBar):
|
||||
def __init__(self, padding: int = -1, parent=None):
|
||||
super(SideTabBar, self).__init__(parent=parent)
|
||||
|
|
Loading…
Reference in a new issue