1
0
Fork 0
mirror of synced 2024-06-22 04:20:25 +12:00
Rare/rare/components/tabs/settings/widgets/wrapper.py

203 lines
7 KiB
Python
Raw Normal View History

2022-02-27 12:14:47 +13:00
import re
2022-03-10 08:47:52 +13:00
import shutil
2022-02-27 12:14:47 +13:00
from logging import getLogger
from typing import Dict
2022-03-10 08:47:52 +13:00
from PyQt5.QtCore import pyqtSignal, QSettings, QSize, Qt, QMimeData
from PyQt5.QtGui import QDrag, QPixmap, QDropEvent, QMouseEvent, QDragEnterEvent, QDragMoveEvent, QFont
from PyQt5.QtWidgets import QGroupBox, QHBoxLayout, QLabel, QPushButton, QInputDialog, QFrame, QMessageBox, QSizePolicy, \
QWidget
2022-02-27 12:14:47 +13:00
from rare import shared
from rare.ui.components.tabs.settings.wrapper import Ui_WrapperSettings
from rare.utils import config_helper
from rare.utils.utils import icon
logger = getLogger("Wrapper Settings")
extra_wrapper_regex = {
"proton": "\".*proton\" run", # proton
"mangohud": "mangohud" # mangohud
}
class WrapperWidget(QFrame):
2022-02-27 12:14:47 +13:00
delete_wrapper = pyqtSignal(str)
def __init__(self, text: str):
super(WrapperWidget, self).__init__()
self.setLayout(QHBoxLayout())
self.text = text
2022-03-10 08:47:52 +13:00
self.image_lbl = QLabel()
self.text_lbl = QLabel(text)
self.text_lbl.setFont(QFont("monospace"))
self.image_lbl.setPixmap(icon("mdi.drag-vertical").pixmap(QSize(20, 20)))
self.layout().addWidget(self.image_lbl)
self.layout().addWidget(self.text_lbl)
self.setProperty("frameShape", 6)
2022-02-27 12:14:47 +13:00
self.delete_button = QPushButton(icon("ei.remove"), "")
self.layout().addWidget(self.delete_button)
self.delete_button.clicked.connect(self.delete)
2022-03-10 08:47:52 +13:00
self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
2022-02-27 12:14:47 +13:00
def delete(self):
self.delete_wrapper.emit(self.text)
2022-03-10 08:47:52 +13:00
def mouseMoveEvent(self, e):
if e.buttons() == Qt.LeftButton:
drag = QDrag(self)
mime = QMimeData()
drag.setMimeData(mime)
drag.exec_(Qt.MoveAction)
2022-02-27 12:14:47 +13:00
2022-03-10 08:47:52 +13:00
class WrapperSettings(QFrame, Ui_WrapperSettings):
2022-02-27 12:14:47 +13:00
wrappers: Dict[str, WrapperWidget] = dict()
extra_wrappers: Dict[str, str] = dict()
app_name: str
2022-03-10 08:47:52 +13:00
drag_widget: QWidget
2022-02-27 12:14:47 +13:00
def __init__(self):
2022-03-10 08:47:52 +13:00
super(WrapperSettings, self).__init__()
2022-02-27 12:14:47 +13:00
self.setupUi(self)
2022-03-10 08:47:52 +13:00
self.setProperty("frameShape", 6)
self.widget_stack.insertWidget(0, self.scroll_area)
self.placeholder.deleteLater()
self.scroll_area.setProperty("noBorder", 1)
self.scroll_content.layout().setAlignment(Qt.AlignLeft)
self.core = shared.LegendaryCoreSingleton()
2022-02-27 12:14:47 +13:00
self.add_button.clicked.connect(self.add_button_pressed)
2022-03-07 07:48:35 +13:00
self.settings = QSettings()
2022-02-27 12:14:47 +13:00
2022-03-10 08:47:52 +13:00
self.setStyleSheet("""QFrame{padding: 0px}""")
self.setAcceptDrops(True)
2022-02-27 12:14:47 +13:00
def get_wrapper_string(self):
2022-03-07 07:48:35 +13:00
return " ".join(self.get_wrapper_list())
def get_wrapper_list(self):
2022-03-10 08:47:52 +13:00
data = list(self.extra_wrappers.values())
for n in range(self.scroll_content.layout().count()):
# Get the widget at each index in turn.
w = self.scroll_content.layout().itemAt(n).widget()
try:
data.append(w.text)
except AttributeError:
pass
return data
2022-02-27 12:14:47 +13:00
def add_button_pressed(self):
wrapper, done = QInputDialog.getText(self, "Input Dialog", self.tr("Insert name of wrapper"))
if not done:
return
self.add_wrapper(wrapper)
2022-03-10 08:47:52 +13:00
def add_wrapper(self, text: str, from_load=False):
2022-02-27 12:14:47 +13:00
for key, extra_wrapper in extra_wrapper_regex.items():
if re.match(extra_wrapper, text):
self.extra_wrappers[key] = text
2022-03-10 08:47:52 +13:00
if not from_load:
self.save()
2022-02-27 12:14:47 +13:00
return
2022-03-10 08:47:52 +13:00
# validate
if not text.strip(): # is empty
return
2022-03-10 08:47:52 +13:00
if not from_load:
if self.wrappers.get(text):
QMessageBox.warning(self, "Warning", self.tr("Wrapper is already in the list"))
return
if not shutil.which(text.split()[0]):
if QMessageBox.question(self, "Warning", self.tr("Wrapper is not in $PATH. Ignore? "),
QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == QMessageBox.No:
return
self.widget_stack.setCurrentIndex(0)
2022-02-27 12:14:47 +13:00
widget = WrapperWidget(text)
2022-03-10 08:47:52 +13:00
self.scroll_content.layout().addWidget(widget)
2022-02-27 12:14:47 +13:00
widget.delete_wrapper.connect(self.delete_wrapper)
2022-03-10 08:47:52 +13:00
self.scroll_content.layout().addWidget(widget)
2022-02-27 12:14:47 +13:00
self.wrappers[text] = widget
2022-03-10 08:47:52 +13:00
if not from_load:
self.save()
2022-02-27 12:14:47 +13:00
def delete_wrapper(self, text: str):
widget = self.wrappers.get(text, None)
if not widget and self.extra_wrappers.get(text, None):
self.extra_wrappers.pop(text)
elif widget:
widget.deleteLater()
self.wrappers.pop(text)
if not self.wrappers:
2022-02-27 12:14:47 +13:00
self.widget_stack.setCurrentIndex(1)
2022-02-27 12:14:47 +13:00
self.save()
def save(self):
2022-03-07 07:48:35 +13:00
# save wrappers twice, to support wrappers with spaces
if len(self.wrappers) == 0 and len(self.extra_wrappers) == 0:
config_helper.remove_option(self.app_name, "wrapper")
2022-03-07 07:48:35 +13:00
self.settings.remove(f"{self.app_name}/wrapper")
else:
config_helper.add_option(self.app_name, "wrapper", self.get_wrapper_string())
2022-03-07 07:48:35 +13:00
self.settings.setValue(f"{self.app_name}/wrapper", self.get_wrapper_list())
2022-02-27 12:14:47 +13:00
2022-03-07 07:48:35 +13:00
def load_settings(self, app_name: str):
2022-02-27 12:14:47 +13:00
self.app_name = app_name
for i in self.wrappers.values():
i.deleteLater()
self.wrappers.clear()
self.extra_wrappers.clear()
2022-03-07 07:48:35 +13:00
wrappers = self.settings.value(f"{self.app_name}/wrapper", [], str)
if not wrappers and (cfg := self.core.lgd.config.get(self.app_name, "wrapper", fallback="")):
logger.info("Loading wrappers from legendary config")
# no qt wrapper, but legendary wrapper, to have backward compatibility
pattern = re.compile(r'''((?:[^ "']|"[^"]*"|'[^']*')+)''')
wrappers = pattern.split(cfg)[1::2]
for wrapper in wrappers:
2022-03-10 08:47:52 +13:00
self.add_wrapper(wrapper, True)
2022-03-07 07:48:35 +13:00
if not self.wrappers:
2022-02-27 12:14:47 +13:00
self.widget_stack.setCurrentIndex(1)
else:
self.widget_stack.setCurrentIndex(0)
2022-03-10 08:47:52 +13:00
self.save()
def dragEnterEvent(self, e: QDragEnterEvent):
widget = e.source()
self.drag_widget = widget
e.accept()
def _get_drop_index(self, x):
for n in range(self.scroll_content.layout().count()):
# Get the widget at each index in turn.
w = self.scroll_content.layout().itemAt(n).widget()
if x < w.x() + w.size().width() // 2:
return n
return self.scroll_content.layout().count()
def dragMoveEvent(self, e: QDragMoveEvent) -> None:
i = self._get_drop_index(e.pos().x())
self.scroll_content.layout().insertWidget(i, self.drag_widget)
def dropEvent(self, e: QDropEvent):
pos = e.pos()
widget = e.source()
index = self._get_drop_index(pos.x())
self.scroll_content.layout().insertWidget(index, widget)
self.drag_widget = None
e.accept()
self.save()