1
0
Fork 0
mirror of synced 2024-06-26 18:20:50 +12:00

Merge pull request #203 from loathingKernel/import_install_etc

Add a bunch of accumulated fixes.
This commit is contained in:
Dummerle 2022-05-13 20:31:06 +02:00 committed by GitHub
commit 8a5bc0e675
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 761 additions and 471 deletions

11
pyproject.toml Normal file
View file

@ -0,0 +1,11 @@
[tool.black]
line-length = 110
target-version = ['py39', 'py310']
include = '\.py$'
force-exclude = '''
/(
| rare/ui
| rare/legendary
| rare/resources
)/
'''

View file

@ -68,7 +68,7 @@ class App(QApplication):
# init Legendary
try:
self.core = LegendaryCoreSingleton()
self.core = LegendaryCoreSingleton(init=True)
except configparser.MissingSectionHeaderError as e:
logger.warning(f"Config is corrupt: {e}")
if config_path := os.environ.get("XDG_CONFIG_HOME"):
@ -77,7 +77,7 @@ class App(QApplication):
path = os.path.expanduser("~/.config/legendary")
with open(os.path.join(path, "config.ini"), "w") as config_file:
config_file.write("[Legendary]")
self.core = LegendaryCoreSingleton()
self.core = LegendaryCoreSingleton(init=True)
if "Legendary" not in self.core.lgd.config.sections():
self.core.lgd.config.add_section("Legendary")
self.core.lgd.save_config()
@ -101,7 +101,7 @@ class App(QApplication):
self.setOrganizationName("Rare")
self.settings = QSettings()
self.signals = GlobalSignalsSingleton()
self.signals = GlobalSignalsSingleton(init=True)
self.signals.exit_app.connect(self.exit_app)
self.signals.send_notification.connect(

View file

@ -141,11 +141,9 @@ class InstallDialog(QDialog, Ui_InstallDialog):
if self.dl_item.options.overlay:
self.platform_label.setVisible(False)
self.platform_combo_box.setVisible(False)
self.ignore_space_info_label.setVisible(False)
self.ignore_space_check.setVisible(False)
self.ignore_space_label.setVisible(False)
self.download_only_check.setVisible(False)
self.download_only_info_label.setVisible(False)
self.download_only_label.setVisible(False)
self.shortcut_cb.setVisible(False)
self.shortcut_lbl.setVisible(False)
@ -306,16 +304,16 @@ class InstallDialog(QDialog, Ui_InstallDialog):
self.cancel_clicked()
class InstallInfoSignals(QObject):
result = pyqtSignal(InstallDownloadModel)
failed = pyqtSignal(str)
finished = pyqtSignal()
class InstallInfoWorker(QRunnable):
class Signals(QObject):
result = pyqtSignal(InstallDownloadModel)
failed = pyqtSignal(str)
finished = pyqtSignal()
def __init__(self, core: LegendaryCore, dl_item: InstallQueueItemModel, game: Game = None):
super(InstallInfoWorker, self).__init__()
self.signals = InstallInfoSignals()
self.signals = InstallInfoWorker.Signals()
self.core = core
self.dl_item = dl_item
self.is_overlay_install = self.dl_item.options.overlay

View file

@ -23,11 +23,11 @@ class LaunchDialogSignals(QObject):
class ImageWorker(QRunnable):
def __init__(self, core: LegendaryCore):
def __init__(self):
super(ImageWorker, self).__init__()
self.signals = LaunchDialogSignals()
self.setAutoDelete(True)
self.core = core
self.core = LegendaryCoreSingleton()
def run(self):
download_images(self.signals.image_progress, self.signals.result, self.core)
@ -45,16 +45,16 @@ class ApiRequestWorker(QRunnable):
def run(self) -> None:
if self.settings.value("mac_meta", platform.system() == "Darwin", bool):
try:
result = self.core.get_game_and_dlc_list(True, "Mac")
result = self.core.get_game_and_dlc_list(update_assets=True, platform="Mac")
except HTTPError:
result = [], {}
self.signals.result.emit(result, "mac")
else:
self.signals.result.emit(([], {}), "mac")
result = [], {}
self.signals.result.emit(result, "mac")
if self.settings.value("win32_meta", False, bool):
try:
result = self.core.get_game_and_dlc_list(True, "Win32")
result = self.core.get_game_and_dlc_list(update_assets=True, platform="Win32")
except HTTPError:
result = [], {}
else:
@ -65,7 +65,7 @@ class ApiRequestWorker(QRunnable):
class LaunchDialog(QDialog, Ui_LaunchDialog):
quit_app = pyqtSignal(int)
start_app = pyqtSignal()
finished = 0
completed = 0
def __init__(self, parent=None):
super(LaunchDialog, self).__init__(parent=parent)
@ -76,8 +76,7 @@ class LaunchDialog(QDialog, Ui_LaunchDialog):
self.core = LegendaryCoreSingleton()
self.args = ArgumentsSingleton()
self.thread_pool = QThreadPool()
self.thread_pool.setMaxThreadCount(2)
self.thread_pool = QThreadPool().globalInstance()
self.api_results = ApiResults()
def login(self):
@ -113,15 +112,15 @@ class LaunchDialog(QDialog, Ui_LaunchDialog):
if not self.args.offline:
self.image_info.setText(self.tr("Downloading Images"))
image_worker = ImageWorker(self.core)
image_worker = ImageWorker()
image_worker.signals.image_progress.connect(self.update_image_progbar)
image_worker.signals.result.connect(self.handle_api_worker_result)
self.thread_pool.start(image_worker)
# gamelist and no_asset games are from Image worker
worker = ApiRequestWorker()
worker.signals.result.connect(self.handle_api_worker_result)
self.thread_pool.start(worker)
api_worker = ApiRequestWorker()
api_worker.signals.result.connect(self.handle_api_worker_result)
self.thread_pool.start(api_worker)
# cloud save from another worker, because it is used in cloud_save_utils too
cloud_worker = CloudWorker()
@ -131,7 +130,7 @@ class LaunchDialog(QDialog, Ui_LaunchDialog):
self.thread_pool.start(cloud_worker)
else:
self.finished = 2
self.completed = 2
if self.core.lgd.assets:
(
self.api_results.game_list,
@ -183,10 +182,10 @@ class LaunchDialog(QDialog, Ui_LaunchDialog):
self.finish()
def finish(self):
if self.finished == 1:
if self.completed == 1:
logger.info("App starting")
self.image_info.setText(self.tr("Starting..."))
ApiResultsSingleton(self.api_results)
self.start_app.emit()
else:
self.finished += 1
self.completed += 1

View file

@ -1,32 +1,52 @@
from PyQt5.QtCore import QProcessEnvironment
from PyQt5.QtGui import QTextCursor, QFont
from PyQt5.QtWidgets import (
QPlainTextEdit,
QWidget,
QDialog,
QPushButton,
QFileDialog,
QVBoxLayout,
QHBoxLayout,
QSpacerItem,
QSizePolicy, QTableWidgetItem, QHeaderView,
)
from rare.ui.components.extra.console_env import Ui_ConsoleEnv
class ConsoleWindow(QWidget):
def __init__(self):
super(ConsoleWindow, self).__init__()
self.layout = QVBoxLayout()
self.setWindowTitle("Rare Console")
class Console(QDialog):
env: QProcessEnvironment
def __init__(self, parent=None):
super(Console, self).__init__(parent=parent)
self.setWindowTitle("Rare - Console")
self.setGeometry(0, 0, 600, 400)
layout = QVBoxLayout()
self.console = Console()
self.layout.addWidget(self.console)
self.console = ConsoleEdit(self)
layout.addWidget(self.console)
button_layout = QHBoxLayout()
button_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Fixed))
self.env_button = QPushButton(self.tr("Show environment"))
button_layout.addWidget(self.env_button)
self.env_button.clicked.connect(self.show_env)
self.save_button = QPushButton(self.tr("Save output to file"))
self.layout.addWidget(self.save_button)
button_layout.addWidget(self.save_button)
self.save_button.clicked.connect(self.save)
self.clear_button = QPushButton(self.tr("Clear"))
self.layout.addWidget(self.clear_button)
self.clear_button = QPushButton(self.tr("Clear console"))
button_layout.addWidget(self.clear_button)
self.clear_button.clicked.connect(self.console.clear)
self.setLayout(self.layout)
layout.addLayout(button_layout)
self.setLayout(layout)
self.env_variables = ConsoleEnv(self)
self.env_variables.hide()
def save(self):
file, ok = QFileDialog.getSaveFileName(
@ -40,6 +60,13 @@ class ConsoleWindow(QWidget):
f.close()
self.save_button.setText(self.tr("Saved"))
def set_env(self, env: QProcessEnvironment):
self.env = env
def show_env(self):
self.env_variables.setTable(self.env)
self.env_variables.show()
def log(self, text: str, end: str = "\n"):
self.console.log(text + end)
@ -47,9 +74,27 @@ class ConsoleWindow(QWidget):
self.console.error(text + end)
class Console(QPlainTextEdit):
def __init__(self):
super().__init__()
class ConsoleEnv(QDialog):
def __init__(self, parent=None):
super(ConsoleEnv, self).__init__(parent=parent)
self.ui = Ui_ConsoleEnv()
self.ui.setupUi(self)
def setTable(self, env: QProcessEnvironment):
self.ui.table.clearContents()
self.ui.table.setRowCount(len(env.keys()))
for idx, key in enumerate(env.keys()):
self.ui.table.setItem(idx, 0, QTableWidgetItem(env.keys()[idx]))
self.ui.table.setItem(idx, 1, QTableWidgetItem(env.value(env.keys()[idx])))
self.ui.table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
class ConsoleEdit(QPlainTextEdit):
def __init__(self, parent=None):
super(ConsoleEdit, self).__init__(parent=parent)
self.setReadOnly(True)
self.setFont(QFont("monospace"))
self._cursor_output = self.textCursor()

View file

@ -11,7 +11,7 @@ from PyQt5.QtWidgets import QMessageBox, QPushButton
from legendary.models.game import LaunchParameters, InstalledGame
from rare.components.dialogs.uninstall_dialog import UninstallDialog
from rare.components.extra.console import ConsoleWindow
from rare.components.extra.console import Console
from rare.components.tabs.games import CloudSaveUtils
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton
from rare.utils import legendary_utils
@ -58,7 +58,7 @@ class GameUtils(QObject):
self.signals = GlobalSignalsSingleton()
self.args = ArgumentsSingleton()
self.console = ConsoleWindow()
self.console = Console()
self.cloud_save_utils = CloudSaveUtils()
self.cloud_save_utils.sync_finished.connect(self.sync_finished)
self.game_meta = RareGameMeta()
@ -245,7 +245,7 @@ class GameUtils(QObject):
def _launch_pre_command(self, env: dict):
proc = QProcess()
environment = QProcessEnvironment()
environment = QProcessEnvironment().systemEnvironment()
for e in env:
environment.insert(e, env[e])
proc.setProcessEnvironment(environment)
@ -260,12 +260,13 @@ class GameUtils(QObject):
str(proc.readAllStandardError().data(), "utf-8", "ignore")
)
)
self.console.set_env(environment)
return proc
def _get_process(self, app_name, env):
process = GameProcess(app_name)
environment = QProcessEnvironment()
environment = QProcessEnvironment().systemEnvironment()
for e in env:
environment.insert(e, env[e])
process.setProcessEnvironment(environment)
@ -287,6 +288,7 @@ class GameUtils(QObject):
and QSettings().value("show_console", False, bool))
else None
)
self.console.set_env(environment)
return process
def _launch_origin(self, app_name, process: QProcess):

View file

@ -19,7 +19,6 @@ class GameListHeadBar(QWidget):
def __init__(self, parent=None):
super(GameListHeadBar, self).__init__(parent=parent)
self.api_results = ApiResultsSingleton()
self.setLayout(QHBoxLayout())
# self.installed_only = QCheckBox(self.tr("Installed only"))
self.settings = QSettings()
# self.installed_only.setChecked(self.settings.value("installed_only", False, bool))
@ -32,7 +31,6 @@ class GameListHeadBar(QWidget):
self.tr("Installed only"),
self.tr("Offline Games"),
])
self.layout().addWidget(self.filter)
self.available_filters = [
"all",
@ -61,40 +59,43 @@ class GameListHeadBar(QWidget):
self.filter.setCurrentIndex(0)
self.filter.currentIndexChanged.connect(self.filter_changed)
self.layout().addStretch(1)
self.import_game = QPushButton(icon("mdi.import", "fa.arrow-down"), self.tr("Import Game"))
self.import_clicked = self.import_game.clicked
self.layout().addWidget(self.import_game)
self.egl_sync = QPushButton(icon("mdi.sync", "fa.refresh"), self.tr("Sync with EGL"))
self.egl_sync_clicked = self.egl_sync.clicked
self.layout().addWidget(self.egl_sync)
# FIXME: Until it is ready
# self.egl_sync.setEnabled(False)
self.layout().addStretch(1)
icon_label = QLabel()
icon_label.setPixmap(icon("fa.search").pixmap(QSize(20, 20)))
self.layout().addWidget(icon_label)
self.search_bar = QLineEdit()
self.search_bar.setObjectName("search_bar")
self.search_bar.setFrame(False)
self.search_bar.setMinimumWidth(200)
self.search_bar.setPlaceholderText(self.tr("Search Game"))
self.layout().addWidget(self.search_bar)
self.layout().addStretch(2)
checked = QSettings().value("icon_view", True, bool)
self.view = SelectViewWidget(checked)
self.layout().addWidget(self.view)
self.layout().addStretch(1)
self.refresh_list = QPushButton()
self.refresh_list.setIcon(icon("fa.refresh")) # Reload icon
self.layout().addWidget(self.refresh_list)
layout = QHBoxLayout()
layout.addWidget(self.filter)
layout.addStretch(1)
layout.addWidget(self.import_game)
layout.addWidget(self.egl_sync)
layout.addStretch(1)
layout.addWidget(icon_label)
layout.addWidget(self.search_bar)
layout.addStretch(3)
layout.addWidget(self.view)
layout.addStretch(1)
layout.addWidget(self.refresh_list)
self.setLayout(layout)
def filter_changed(self, i):
self.filterChanged.emit(self.available_filters[i])

View file

@ -1,7 +1,8 @@
import json
import os
from logging import getLogger
from typing import List, Tuple
from pathlib import Path
from typing import List, Tuple, Optional
from PyQt5.QtCore import Qt, QModelIndex, pyqtSignal
from PyQt5.QtGui import QStandardItemModel
@ -21,9 +22,7 @@ class AppNameCompleter(QCompleter):
def __init__(self, app_names: List, parent=None):
super(AppNameCompleter, self).__init__(parent)
# pylint: disable=E1136
super(AppNameCompleter, self).activated[QModelIndex].connect(
self.__activated_idx
)
super(AppNameCompleter, self).activated[QModelIndex].connect(self.__activated_idx)
model = QStandardItemModel(len(app_names), 2)
for idx, game in enumerate(app_names):
@ -52,18 +51,17 @@ class AppNameCompleter(QCompleter):
# lk: Note to self, the completer and popup models are different.
# lk: Getting the index from the popup and trying to use it in the completer will return invalid results
if isinstance(idx, QModelIndex):
self.activated.emit(
self.popup().model().data(self.popup().model().index(idx.row(), 1))
)
self.activated.emit(self.popup().model().data(self.popup().model().index(idx.row(), 1)))
# TODO: implement conversion from app_name to app_title (signal loop here)
# if isinstance(idx_str, str):
# self.activated.emit(idx_str)
class ImportGroup(QGroupBox, Ui_ImportGroup):
class ImportGroup(QGroupBox):
def __init__(self, parent=None):
super(ImportGroup, self).__init__(parent=parent)
self.setupUi(self)
self.ui = Ui_ImportGroup()
self.ui.setupUi(self)
self.core = LegendaryCoreSingleton()
self.signals = GlobalSignalsSingleton()
self.api_results = ApiResultsSingleton()
@ -84,23 +82,32 @@ class ImportGroup(QGroupBox, Ui_ImportGroup):
parent=self,
)
self.path_edit.textChanged.connect(self.path_changed)
self.path_edit_layout.addWidget(self.path_edit)
self.ui.path_edit_layout.addWidget(self.path_edit)
self.app_name = IndicatorLineEdit(
self.app_name_edit = IndicatorLineEdit(
placeholder=self.tr("Use in case the app name was not found automatically"),
completer=AppNameCompleter(
app_names=[
(i.app_name, i.app_title) for i in self.api_results.game_list
]
app_names=[(i.app_name, i.app_title) for i in self.api_results.game_list]
),
edit_func=self.app_name_edit_cb,
parent=self,
)
self.app_name.textChanged.connect(self.app_name_changed)
self.app_name_layout.addWidget(self.app_name)
self.app_name_edit.textChanged.connect(self.app_name_changed)
self.ui.app_name_layout.addWidget(self.app_name_edit)
self.import_button.setEnabled(False)
self.import_button.clicked.connect(self.import_game)
self.ui.import_button.setEnabled(False)
self.ui.import_button.clicked.connect(
lambda: self.import_games(self.path_edit.text())
if self.ui.import_folder_check.isChecked()
else self.import_game(self.path_edit.text())
)
self.ui.import_folder_check.stateChanged.connect(
lambda s: self.ui.import_button.setEnabled(s or (not s and self.app_name_edit.is_valid))
)
self.ui.import_folder_check.stateChanged.connect(
lambda s: self.app_name_edit.setEnabled(not s)
)
def path_edit_cb(self, path) -> Tuple[bool, str, str]:
if os.path.exists(path):
@ -113,11 +120,12 @@ class ImportGroup(QGroupBox, Ui_ImportGroup):
return False, path, ""
def path_changed(self, path):
self.info_label.setText(str())
self.ui.info_label.setText(str())
self.ui.import_folder_check.setChecked(False)
if self.path_edit.is_valid:
self.app_name.setText(self.find_app_name(path))
self.app_name_edit.setText(self.find_app_name(path))
else:
self.app_name.setText(str())
self.app_name_edit.setText(str())
def app_name_edit_cb(self, text) -> Tuple[bool, str, str]:
if not text:
@ -128,56 +136,59 @@ class ImportGroup(QGroupBox, Ui_ImportGroup):
return False, text, IndicatorLineEdit.reasons.game_not_installed
def app_name_changed(self, text):
self.info_label.setText(str())
if self.app_name.is_valid:
self.import_button.setEnabled(True)
self.ui.info_label.setText(str())
if self.app_name_edit.is_valid:
self.ui.import_button.setEnabled(True)
else:
self.import_button.setEnabled(False)
self.ui.import_button.setEnabled(False)
def find_app_name(self, path):
if not os.path.exists(os.path.join(path, ".egstore")):
return None
for i in os.listdir(os.path.join(path, ".egstore")):
if i.endswith(".mancpn"):
file = os.path.join(path, ".egstore", i)
return json.load(open(file, "r")).get("AppName")
def find_app_name(self, path: str) -> Optional[str]:
if os.path.exists(os.path.join(path, ".egstore")):
for i in os.listdir(os.path.join(path, ".egstore")):
if i.endswith(".mancpn"):
file = os.path.join(path, ".egstore", i)
return json.load(open(file, "r")).get("AppName")
elif app_name := legendary_utils.resolve_aliases(
self.core, os.path.basename(os.path.normpath(path))):
return app_name
else:
logger.warning("File was not found")
return None
logger.warning(f"Could not find AppName for {path}")
return None
def import_game(self, path=None):
app_name = self.app_name.text()
if not path:
path = self.path_edit.text()
if not app_name:
if not (app_name := self.app_name_edit.text()):
# try to find app name
if a_n := self.find_app_name(path):
app_name = a_n
else:
self.info_label.setText(self.tr("Could not find app name"))
self.ui.info_label.setText(self.tr("Could not find AppName"))
return
self.__import_game(app_name, path)
if not (
err := legendary_utils.import_game(self.core, app_name=app_name, path=path)
):
def import_games(self, path=None):
if not path:
path = self.path_edit.text()
path = Path(path)
for child in path.iterdir():
if child.is_dir():
if (app_name := self.find_app_name(str(child))) is not None:
self.__import_game(app_name, str(child))
def __import_game(self, app_name, path):
if not (err := legendary_utils.import_game(self.core, app_name=app_name, path=path)):
igame = self.core.get_installed_game(app_name)
self.info_label.setText(
self.tr("Successfully imported {}").format(igame.title)
)
self.app_name.setText(str())
logger.info(f"Successfully imported {igame.title}")
self.ui.info_label.setText(self.tr("Successfully imported {}").format(igame.title))
self.signals.update_gamelist.emit([app_name])
if (
igame.version
!= self.core.get_asset(app_name, igame.platform, False).build_version
):
if igame.version != self.core.get_asset(app_name, igame.platform, False).build_version:
# update available
self.signals.add_download.emit(igame.app_name)
self.signals.update_download_tab_text.emit()
else:
logger.warning(f'Failed to import "{app_name}"')
self.info_label.setText(
self.tr("Could not import {}: {}").format(app_name, err)
)
self.ui.info_label.setText(self.tr("Could not import {}: {}").format(app_name, err))
return

View file

@ -202,9 +202,11 @@ class EosWidget(QGroupBox, Ui_EosWidget):
def install_overlay(self, update=False):
if platform.system() != "Windows":
if QMessageBox.No == QMessageBox.question(self, "Warning",
self.tr("Epic overlay is currently not supported by wine, so it won't work. Install anyway? "),
QMessageBox.Yes | QMessageBox.No, QMessageBox.No):
if QMessageBox.No == QMessageBox.question(
self,
self.tr("Warning"),
self.tr("Epic overlay is currently not supported by wine, so it won't work. Install anyway? "),
QMessageBox.Yes | QMessageBox.No, QMessageBox.No):
return
base_path = os.path.expanduser("~/legendary/.overlay")

Binary file not shown.

View file

@ -1,42 +1,44 @@
/*
[Text]
normal: #eeeeee -- main font color
disabled: #43474d -- disabled font color
normal: #eeeeee rgb(238, 238, 238) -- main font color
disabled: #43474d rgb( 67, 71, 77) -- disabled font color
rgba( 67, 71, 77, 55%) == rgb( 51, 54, 59)
rgba( 67, 71, 77, 25%) == rgb( 41, 43, 47)
[Background]
normal: #202225 -- main background color
editable: #333344 -- background color for reactive/editable widgets (TextEdits, ProgressBars etc)
hover: #222233 -- background color when hovering over reactive widgets (Buttons, Headers)
selection: #2f4f4f -- background color for selectable widgets
alternate: #282a2e -- background color for alternating rows in List/Tree/TableViews and for ScrollBars
normal: #202225 rgb( 32, 34, 37) -- main background color
editable: #333344 rgb( 51, 51, 68) -- background color for reactive/editable widgets (TextEdits, ProgressBars etc)
hover: #222233 rgb( 34, 34, 51) -- background color when hovering over reactive widgets (Buttons, Headers)
selection: #2f4f4f rgb( 47, 79, 79) -- background color for selectable widgets
alternate: #282a2e rgb( 40, 42, 46) -- background color for alternating rows in List/Tree/TableViews and for ScrollBars
[Border]
normal: #483d8b -- border color for most widgets
editable: #2f4f4f -- border color for editable widgets (TextEdits, ProgressBars etc)
highlight: #5246a0 -- border color for dropdown widgets, a bit lighter than border for more separation
disabled: #43474d -- border for disabled widgets
alternate: #3c3f41 -- border color for gradient backgrounds on widgets like Tabs and Popups
normal: #483d8b rgb( 72, 61, 139) -- border color for most widgets
rgba( 72, 61, 139, 25%) == rgb( 42, 40, 63)
editable: #2f4f4f rgb( 47, 79, 79) -- border color for editable widgets (TextEdits, ProgressBars etc)
highlight: #5246a0 rgb( 82, 70, 160) -- border color for dropdown widgets, a bit lighter than border for more separation
disabled: #43474d rgb( 67, 71, 77) -- border for disabled widgets
alternate: #3c3f41 rgb( 60, 63, 65) -- border color for gradient backgrounds on widgets like Tabs and Popups
[Special]
info-normal: #bbb -- infoLabel
install-normal: #090 -- install
install-hover: #060 -- install
install-disabled: #020 -- install
uninstall-normal: #900 -- uninstall
uninstall-hover: #600 -- uninstall
uninstall-disabled: #200 -- uninstall
info-normal: #bbb rgb(187, 187, 187) -- infoLabel
install-normal: #070 rgb( 0, 119, 0) -- install
install-hover: #050 rgb( 0, 85, 0) -- install
install-disabled: #020 rgb( 0, 34, 0) -- install
uninstall-normal: #700 rgb(119, 0, 0) -- uninstall
uninstall-hover: #500 rgb( 85, 0, 0) -- uninstall
uninstall-disabled: #200 rgb( 34, 0, 0) -- uninstall
*/
* {
color: #eeeeee;
border-color: #483d8b;
background-color: #202225;
color: rgb(238, 238, 238);
border-color: rgb( 72, 61, 139);
background-color: rgb( 32, 34, 37);
}
*:disabled,
*:editable:disabled {
color: #43474d;
border-color: #43474d;
background-color: #202225;
color: rgb( 67, 71, 77);
border-color: rgb( 67, 71, 77);
background-color: rgb( 32, 34, 37);
}
QLabel,
@ -44,10 +46,10 @@ QLabel:disabled {
border-width: 0px;
background-color: transparent;
padding: 0px;
selection-background-color: #2f4f4f;
selection-background-color: rgb( 47, 79, 79);
}
QLabel[infoLabel="1"] {
color: #bbb;
color: rgb(187, 187, 187);
font-style: italic;
font-weight: normal;
}
@ -94,9 +96,9 @@ QSpinBox,
QDoubleSpinBox,
QProgressBar,
QScrollBar {
border-color: #2f4f4f;
background-color: #333344;
selection-background-color: #2f4f4f;
border-color: rgb( 47, 79, 79);
background-color: rgb( 51, 51, 68);
selection-background-color: rgb( 47, 79, 79);
}
QLineEdit,
QTextEdit,
@ -123,17 +125,17 @@ QStackedWidget[noBorder="1"] {
border-color: transparent;
}
QComboBox {
background-color: rgba(67, 71, 77, 55%);
background-color: rgb( 51, 54, 59);
}
QComboBox:disabled {
background-color: rgba(67, 71, 77, 25%);
background-color: rgb( 41, 43, 47);
}
QComboBox:!editable:hover {
background-color: #222233;
background-color: rgb( 34, 34, 51);
}
*::item:selected,
QComboBox QAbstractItemView {
selection-background-color: #2f4f4f;
selection-background-color: rgb( 47, 79, 79);
}
*::drop-down,
*::drop-down:editable,
@ -150,19 +152,19 @@ QComboBox QAbstractItemView {
*::drop-down:editable:disabled,
*::up-button:disabled,
*::down-button:disabled {
border-color: #43474d;
border-color: rgb( 67, 71, 77);
background-color: transparent;
}
*::drop-down {
subcontrol-position: top right;
border-color: #483d8b;
border-left-color: #5246a0; /* #483d8b lighter */
border-color: rgb( 72, 61, 139);
border-left-color: rgb( 82, 70, 160); /* rgb( 72, 61, 139) lighter */
}
*::drop-down:editable,
*::up-button,
*::down-button {
border-color: #2f4f4f;
background-color: #3c3f41;
border-color: rgb( 47, 79, 79);
background-color: rgb( 60, 63, 65);
}
*::drop-down,
*::drop-down:editable {
@ -189,12 +191,12 @@ QProgressBar {
QProgressBar::chunk {
width: 2%;
margin: 0%;
background-color: #2f4f4f;
background-color: rgb( 47, 79, 79);
}
QScrollBar {
border-radius: 4px;
padding: 1px;
background-color: #282a2e;
background-color: rgb( 40, 42, 46);
}
QScrollBar:vertical {
width: 11px;
@ -229,8 +231,8 @@ QScrollBar::sub-line:horizontal {
QScrollBar::handle {
border-width: 1px;
border-style: solid;
border-color: #483d8b;
background-color: #333344;
border-color: rgb( 72, 61, 139);
background-color: rgb( 51, 51, 68);
border-radius: 2px;
min-height: 30px;
min-width: 30px;
@ -259,11 +261,11 @@ QListView,
QTreeView,
QTableView {
outline: 0;
gridline-color: #282a2e;
gridline-color: rgb( 40, 42, 46);
show-decoration-selected: 0;
selection-background-color: transparent;
background-color: #202225;
alternate-background-color: #282a2e;
background-color: rgb( 32, 34, 37);
alternate-background-color: rgb( 40, 42, 46);
}
QListView::item,
@ -282,28 +284,28 @@ QTableView[currentRow="0"]::item {
QListView::item:hover,
QTreeView::item:hover,
QTableView::item:hover {
border-color: #483d8b;
background-color: #222233;
border-color: rgb( 72, 61, 139);
background-color: rgb( 34, 34, 51);
}
QListView::item:selected,
QTreeView::item:selected,
QTableView::item:selected {
border-color: #483d8b;
background-color: #2f4f4f;
border-color: rgb( 72, 61, 139);
background-color: rgb( 47, 79, 79);
}
QPushButton,
QToolButton {
background-color: rgba(67, 71, 77, 55%);
background-color: rgb( 51, 54, 59);
}
QPushButton:disabled,
QToolButton:disabled {
background-color: rgba(67, 71, 77, 25%);
background-color: rgb( 41, 43, 47);
}
QPushButton:hover,
QToolButton:hover,
QHeaderView::section:hover {
background-color: #222233;
background-color: rgb( 34, 34, 51);
}
QPushButton,
QToolButton {
@ -327,36 +329,36 @@ QPushButton#menu {
}
QPushButton#menu_button {
border-width: 0px;
background-color: #3c3f41;
background-color: rgb( 60, 63, 65);
width: 18px;
height: 18px;
}
QPushButton#menu_button:hover {
background-color: "#333344";
background-color: rgb( 51, 51, 68);
}
QPushButton[install="1"],
QPushButton#install_button {
background-color: "#070";
background-color: rgb( 0, 119, 0);
}
QPushButton[install="1"]:hover,
QPushButton#install_button:hover {
background-color: "#050";
background-color: rgb( 0, 85, 0);
}
QPushButton[install="1"]:disabled,
QPushButton#install_button:disabled {
background-color: "#020";
background-color: rgb( 0, 34, 0);
}
QPushButton[uninstall="1"],
QPushButton#uninstall_button {
background-color: "#900";
background-color: rgb(119, 0, 0);
}
QPushButton[uninstall="1"]:hover,
QPushButton#uninstall_button:hover {
background-color: "#600";
background-color: rgb( 85, 0, 0);
}
QPushButton[uninstall="1"]:disabled,
QPushButton#uninstall_button:disabled {
background-color: "#200";
background-color: rgb( 34, 0, 0);
}
QPushButton#success{
background-color: lime;
@ -376,10 +378,10 @@ QRadioButton::indicator,
QListView::indicator,
QTreeView::indicator,
QTableView::indicator {
border-color: #2f4f4f;
border-color: rgb( 47, 79, 79);
border-width: 1px;
border-style: solid;
background-color: #202225;
background-color: rgb( 32, 34, 37);
}
QCheckBox::indicator,
QRadioButton::indicator,
@ -395,7 +397,7 @@ QRadioButton::indicator:disabled,
QListView::indicator:disabled,
QTreeView::indicator:disabled,
QTableView::indicator:disabled {
border-color: #43474d;
border-color: rgb( 67, 71, 77);
}
QRadioButton::indicator {
border-radius: 5%;
@ -469,17 +471,20 @@ QGroupBox::title {
border-style: solid;
border-top-left-radius: 4px;
border-bottom-right-radius: 4px;
border-color: #483d8b;
border-color: rgb( 72, 61, 139);
padding: 1px;
/*
background: qlineargradient(
x1: -2, y1: 0, x2: 1, y2: 1, stop: 0 #483d8b, stop: 1 #202225);
x1: -2, y1: 0,
x2: 1, y2: 1,
stop: 0 rgb( 72, 61, 139),
stop: 1 rgb( 32, 34, 37));
*/
background-color: rgba(72, 61, 139, 25%);
background-color: rgb( 42, 40, 63);
}
QGroupBox::title:disabled {
border-color: #43474d;
background-color: rgba(67, 71, 77, 25%);
border-color: rgb( 67, 71, 77);
background-color: rgb( 41, 43, 47);
}
QSizeGrip {
@ -495,7 +500,7 @@ QSizeGrip {
#search_bar {
padding: 3px;
border-radius: 5px;
background-color: "#333344";
background-color: rgb( 51, 51, 68);
}
QTabWidget::pane {
@ -519,54 +524,66 @@ QTabBar::tab:bottom {
}
QTabBar::tab:top:hover,
QTabBar::tab:bottom:hover {
border-color: #483d8b;
border-color: rgb( 72, 61, 139);
border-left-color: transparent;
border-right-color: transparent;
}
QTabBar::tab:top {
border-top-width: 3px;
border-top-color: #3c3f41;
border-bottom-color: #483d8b;
border-top-color: rgb( 60, 63, 65);
border-bottom-color: rgb( 72, 61, 139);
background: qlineargradient(
x1: 0, y1: -1, x2: 0, y2: 1, stop: 0 #3c3f41, stop: 1 #202225);
x1: 0, y1: -1,
x2: 0, y2: 1,
stop: 0 rgb( 60, 63, 65),
stop: 1 rgb( 32, 34, 37));
}
QTabBar::tab:bottom {
border-bottom-width: 3px;
border-top-color: #483d8b;
border-bottom-color: #3c3f41;
border-top-color: rgb( 72, 61, 139);
border-bottom-color: rgb( 60, 63, 65);
background: qlineargradient(
x1: 0, y1: 2, x2: 0, y2: 0, stop: 0 #3c3f41, stop: 1 #202225);
x1: 0, y1: 2,
x2: 0, y2: 0,
stop: 0 rgb( 60, 63, 65),
stop: 1 rgb( 32, 34, 37));
}
QTabBar::tab:top:hover {
background: qlineargradient(
x1: 0, y1: -1, x2: 0, y2: 1, stop: 0 #483d8b, stop: 1 #202225);
x1: 0, y1: -1,
x2: 0, y2: 1,
stop: 0 rgb( 72, 61, 139),
stop: 1 rgb( 32, 34, 37));
}
QTabBar::tab:bottom:hover {
background: qlineargradient(
x1: 0, y1: 2, x2: 0, y2: 0, stop: 0 #483d8b, stop: 1 #202225);
x1: 0, y1: 2,
x2: 0, y2: 0,
stop: 0 rgb( 72, 61, 139),
stop: 1 rgb( 32, 34, 37));
}
QTabBar::tab:top:selected {
border-color: #483d8b;
border-color: rgb( 72, 61, 139);
border-bottom-color: transparent;
background: #202225;
background: rgb( 32, 34, 37);
}
QTabBar::tab:bottom:selected {
border-color: #483d8b;
border-color: rgb( 72, 61, 139);
border-top-color: transparent;
background: #202225;
background: rgb( 32, 34, 37);
}
QTabBar::tab:top:disabled {
border-bottom-color: #3c3f41;
border-bottom-color: rgb( 60, 63, 65);
}
QTabBar::tab:bottom:disabled {
border-top-color: #3c3f41;
border-top-color: rgb( 60, 63, 65);
}
QTabBar::tab:top:selected:disabled {
border-color: #3c3f41;
border-color: rgb( 60, 63, 65);
border-bottom-color: transparent;
}
QTabBar::tab:bottom:selected:disabled {
border-color: #3c3f41;
border-color: rgb( 60, 63, 65);
border-top-color: transparent;
}
QTabBar::tab:left,
@ -576,54 +593,66 @@ QTabBar::tab:right {
}
QTabBar::tab:left:hover,
QTabBar::tab:right:hover {
border-color: #483d8b;
border-color: rgb( 72, 61, 139);
border-top-color: transparent;
border-bottom-color: transparent;
}
QTabBar::tab:left {
border-left-width: 3px;
border-left-color: #3c3f41;
border-right-color: #483d8b;
border-left-color: rgb( 60, 63, 65);
border-right-color: rgb( 72, 61, 139);
background: qlineargradient(
x1: -1, y1: 0, x2: 1, y2: 0, stop: 0 #3c3f41, stop: 1 #202225);
x1: -1, y1: 0,
x2: 1, y2: 0,
stop: 0 rgb( 60, 63, 65),
stop: 1 rgb( 32, 34, 37));
}
QTabBar::tab:right {
border-right-width: 3px;
border-right-color: #3c3f41;
border-left-color: #483d8b;
border-right-color: rgb( 60, 63, 65);
border-left-color: rgb( 72, 61, 139);
background: qlineargradient(
x1: 2, y1: 0, x2: 0, y2: 0, stop: 0 #3c3f41, stop: 1 #202225);
x1: 2, y1: 0,
x2: 0, y2: 0,
stop: 0 rgb( 60, 63, 65),
stop: 1 rgb( 32, 34, 37));
}
QTabBar::tab:left:hover {
background: qlineargradient(
x1: -1, y1: 0, x2: 1, y2: 0, stop: 0 #483d8b, stop: 1 #202225);
x1: -1, y1: 0,
x2: 1, y2: 0,
stop: 0 rgb( 72, 61, 139),
stop: 1 rgb( 32, 34, 37));
}
QTabBar::tab:right:hover {
background: qlineargradient(
x1: 2, y1: 0, x2: 0, y2: 0, stop: 0 #483d8b, stop: 1 #202225);
x1: 2, y1: 0,
x2: 0, y2: 0,
stop: 0 rgb( 72, 61, 139),
stop: 1 rgb( 32, 34, 37));
}
QTabBar::tab:left:selected {
border-color: #483d8b;
border-color: rgb( 72, 61, 139);
border-right-color: transparent;
background: #202225;
background: rgb( 32, 34, 37);
}
QTabBar::tab:right:selected {
border-color: #483d8b;
border-color: rgb( 72, 61, 139);
border-left-color: transparent;
background: #202225;
background: rgb( 32, 34, 37);
}
QTabBar::tab:left:disabled {
border-right-color: #3c3f41;
border-right-color: rgb( 60, 63, 65);
}
QTabBar::tab:right:disabled {
border-left-color: #3c3f41;
border-left-color: rgb( 60, 63, 65);
}
QTabBar::tab:left:selected:disabled {
border-color: #3c3f41;
border-color: rgb( 60, 63, 65);
border-right-color: transparent;
}
QTabBar::tab:right:selected:disabled {
border-color: #3c3f41;
border-color: rgb( 60, 63, 65);
border-left-color: transparent;
}
@ -631,21 +660,24 @@ QTabBar#MainTabBar {
border-width: 1px;
border-style: solid;
border-color: transparent;
border-bottom-color: #483d8b;
border-bottom-color: rgb( 72, 61, 139);
/*
background: qlineargradient(
x1: 0, y1: -3, x2: 0, y2: 1, stop: 0 #3c3f41, stop: 1 #202225);
x1: 0, y1: -3,
x2: 0, y2: 1,
stop: 0 rgb( 60, 63, 65),
stop: 1 rgb( 32, 34, 37));
*/
}
QTabBar#MainTabBar:disabled {
border-color: transparent;
border-bottom-color: #3c3f41;
border-bottom-color: rgb( 60, 63, 65);
}
QTabBar#MainTabBar::tab {
margin-left: 3px;
margin-right: 3px;
border-top-color: transparent;
border-bottom-color: #483d8b;
border-bottom-color: rgb( 72, 61, 139);
padding: 5px;
}/*
QTabBar#MainTabBar::tab:top:first,
@ -659,25 +691,28 @@ QTabBar#MainTabBar::tab:bottom:last {
border-right: transparent;
}*/
QTabBar#MainTabBar::tab:top:hover {
border-top-color: #483d8b;
border-top-color: rgb( 72, 61, 139);
}
QTabBar#MainTabBar::tab:top:selected {
border-color: #483d8b;
border-bottom-color: #202225;
border-color: rgb( 72, 61, 139);
border-bottom-color: rgb( 32, 34, 37);
}
QTabBar#SideTabBar {
border-width: 1px;
border-style: solid;
border-color: transparent;
border-right-color: #483d8b;
border-right-color: rgb( 72, 61, 139);
/*
background: qlineargradient(
x1: -3, y1: 0, x2: 1, y2: 0, stop: 0 #3c3f41, stop: 1 #202225);
x1: -3, y1: 0,
x2: 1, y2: 0,
stop: 0 rgb( 60, 63, 65),
stop: 1 rgb( 32, 34, 37));
*/
}
QTabBar#SideTabBar:disabled {
border-color: transparent;
border-right-color: #3c3f41;
border-right-color: rgb( 60, 63, 65);
}
QTabBar#SideTabBar::tab {
margin-top: 3px;
@ -703,44 +738,47 @@ QStatusBar {
border-width: 1px;
border-style: solid;
border-color: transparent;
border-top-color: #483d8b;
border-bottom-color: #3c3f41;
border-top-color: rgb( 72, 61, 139);
border-bottom-color: rgb( 60, 63, 65);
background: qlineargradient(
x1: 0, y1: 3, x2: 0, y2: 0, stop: 0 #3c3f41, stop: 1 #202225);
x1: 0, y1: 3,
x2: 0, y2: 0,
stop: 0 rgb( 60, 63, 65),
stop: 1 rgb( 32, 34, 37));
}
QToolTip {
border-width: 1px;
border-style: solid;
border-color: #483d8b;
border-color: rgb( 72, 61, 139);
border-radius: 4px;
padding: 1px;
opacity: 200;
}
QBalloonTip {
color: #eeeeee;
background-color: #202225;
color: rgb(238, 238, 238);
background-color: rgb( 32, 34, 37);
border-width: 1px;
border-style: solid;
border-color: #483d8b;
border-color: rgb( 72, 61, 139);
border-radius: 4px;
padding: 1px;
}
/* Wrapper settings styling */
QPushButton#WrapperWidgetButton {
border-color: rgba(67, 71, 77, 55%);
border-color: rgb( 51, 54, 59);
}
QPushButton#WrapperWidgetButton:disabled {
border-color: rgba(67, 71, 77, 25%);
border-color: rgb( 41, 43, 47);
}
QScrollArea#WrapperSettingsScroll {
border-color: #2f4f4f;
background-color: #282a2e;
border-color: rgb( 47, 79, 79);
background-color: rgb( 40, 42, 46);
}
QScrollBar#WrapperSettingsScrollBar {
background-color: #282a2e;
background-color: rgb( 40, 42, 46);
}
QLabel#WrapperSettingsLabel {
border-width: 1px;
@ -748,6 +786,6 @@ QLabel#WrapperSettingsLabel {
border-radius: 2px;
padding: 2px;
color: #999;
border-color: #2f4f4f;
background-color: #282a2e;
border-color: rgb( 47, 79, 79);
background-color: rgb( 40, 42, 46);
}

View file

@ -1,37 +1,47 @@
from argparse import Namespace
from typing import Optional
from legendary.core import LegendaryCore
from rare.utils.models import ApiResults, GlobalSignals
_legendary_core_singleton: LegendaryCore = None
_global_signals_singleton: GlobalSignals = None
_arguments_singleton: Namespace = None
_api_results_singleton: ApiResults = None
_legendary_core_singleton: Optional[LegendaryCore] = None
_global_signals_singleton: Optional[GlobalSignals] = None
_arguments_singleton: Optional[Namespace] = None
_api_results_singleton: Optional[ApiResults] = None
def LegendaryCoreSingleton() -> LegendaryCore:
def LegendaryCoreSingleton(init: bool = False) -> LegendaryCore:
global _legendary_core_singleton
if _legendary_core_singleton is None and not init:
raise RuntimeError("Uninitialized use of LegendaryCoreSingleton")
if _legendary_core_singleton is None:
_legendary_core_singleton = LegendaryCore()
return _legendary_core_singleton
def GlobalSignalsSingleton() -> GlobalSignals:
def GlobalSignalsSingleton(init: bool = False) -> GlobalSignals:
global _global_signals_singleton
if _global_signals_singleton is None and not init:
raise RuntimeError("Uninitialized use of GlobalSignalsSingleton")
if _global_signals_singleton is None:
_global_signals_singleton = GlobalSignals()
return _global_signals_singleton
def ArgumentsSingleton(args: Namespace = None) -> Namespace:
def ArgumentsSingleton(args: Namespace = None) -> Optional[Namespace]:
global _arguments_singleton
if _arguments_singleton is None and args is None:
raise RuntimeError("Uninitialized use of ArgumentsSingleton")
if _arguments_singleton is None:
_arguments_singleton = args
return _arguments_singleton
def ApiResultsSingleton(res: ApiResults = None) -> ApiResults:
def ApiResultsSingleton(res: ApiResults = None) -> Optional[ApiResults]:
global _api_results_singleton
if _api_results_singleton is None and res is None:
raise RuntimeError("Uninitialized use of ApiResultsSingleton")
if _api_results_singleton is None:
_api_results_singleton = res
return _api_results_singleton

View file

@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_InstallDialog(object):
def setupUi(self, InstallDialog):
InstallDialog.setObjectName("InstallDialog")
InstallDialog.resize(324, 347)
InstallDialog.resize(337, 372)
InstallDialog.setWindowTitle("Rare")
self.install_dialog_layout = QtWidgets.QFormLayout(InstallDialog)
self.install_dialog_layout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
@ -58,6 +58,7 @@ class Ui_InstallDialog(object):
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.force_download_check.sizePolicy().hasHeightForWidth())
self.force_download_check.setSizePolicy(sizePolicy)
self.force_download_check.setText("")
self.force_download_check.setObjectName("force_download_check")
self.install_dialog_layout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.force_download_check)
self.platform_label = QtWidgets.QLabel(InstallDialog)
@ -74,50 +75,14 @@ class Ui_InstallDialog(object):
self.ignore_space_label = QtWidgets.QLabel(InstallDialog)
self.ignore_space_label.setObjectName("ignore_space_label")
self.install_dialog_layout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.ignore_space_label)
self.ignore_space_layout = QtWidgets.QHBoxLayout()
self.ignore_space_layout.setObjectName("ignore_space_layout")
self.ignore_space_check = QtWidgets.QCheckBox(InstallDialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.ignore_space_check.sizePolicy().hasHeightForWidth())
self.ignore_space_check.setSizePolicy(sizePolicy)
self.ignore_space_check.setObjectName("ignore_space_check")
self.ignore_space_layout.addWidget(self.ignore_space_check)
self.ignore_space_info_label = QtWidgets.QLabel(InstallDialog)
font = QtGui.QFont()
font.setItalic(True)
self.ignore_space_info_label.setFont(font)
self.ignore_space_info_label.setObjectName("ignore_space_info_label")
self.ignore_space_layout.addWidget(self.ignore_space_info_label)
self.install_dialog_layout.setLayout(5, QtWidgets.QFormLayout.FieldRole, self.ignore_space_layout)
self.download_only_label = QtWidgets.QLabel(InstallDialog)
self.download_only_label.setObjectName("download_only_label")
self.install_dialog_layout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.download_only_label)
self.download_only_layout = QtWidgets.QHBoxLayout()
self.download_only_layout.setObjectName("download_only_layout")
self.download_only_check = QtWidgets.QCheckBox(InstallDialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.download_only_check.sizePolicy().hasHeightForWidth())
self.download_only_check.setSizePolicy(sizePolicy)
self.download_only_check.setText("")
self.download_only_check.setObjectName("download_only_check")
self.download_only_layout.addWidget(self.download_only_check)
self.download_only_info_label = QtWidgets.QLabel(InstallDialog)
font = QtGui.QFont()
font.setItalic(True)
self.download_only_info_label.setFont(font)
self.download_only_info_label.setObjectName("download_only_info_label")
self.download_only_layout.addWidget(self.download_only_info_label)
self.install_dialog_layout.setLayout(6, QtWidgets.QFormLayout.FieldRole, self.download_only_layout)
self.shortcut_lbl = QtWidgets.QLabel(InstallDialog)
self.shortcut_lbl.setObjectName("shortcut_lbl")
self.install_dialog_layout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.shortcut_lbl)
self.shortcut_cb = QtWidgets.QCheckBox(InstallDialog)
self.shortcut_cb.setText("")
self.shortcut_cb.setChecked(True)
self.shortcut_cb.setObjectName("shortcut_cb")
self.install_dialog_layout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.shortcut_cb)
self.sdl_list_label = QtWidgets.QLabel(InstallDialog)
@ -181,6 +146,28 @@ class Ui_InstallDialog(object):
self.install_preqs_check.setText("")
self.install_preqs_check.setObjectName("install_preqs_check")
self.install_dialog_layout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.install_preqs_check)
self.ignore_space_check = QtWidgets.QCheckBox(InstallDialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.ignore_space_check.sizePolicy().hasHeightForWidth())
self.ignore_space_check.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setItalic(True)
self.ignore_space_check.setFont(font)
self.ignore_space_check.setObjectName("ignore_space_check")
self.install_dialog_layout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.ignore_space_check)
self.download_only_check = QtWidgets.QCheckBox(InstallDialog)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.download_only_check.sizePolicy().hasHeightForWidth())
self.download_only_check.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setItalic(True)
self.download_only_check.setFont(font)
self.download_only_check.setObjectName("download_only_check")
self.install_dialog_layout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.download_only_check)
self.retranslateUi(InstallDialog)
QtCore.QMetaObject.connectSlotsByName(InstallDialog)
@ -194,9 +181,7 @@ class Ui_InstallDialog(object):
self.force_download_label.setText(_translate("InstallDialog", "Force redownload"))
self.platform_label.setText(_translate("InstallDialog", "Platform"))
self.ignore_space_label.setText(_translate("InstallDialog", "Ignore free space"))
self.ignore_space_info_label.setText(_translate("InstallDialog", "Use with caution!"))
self.download_only_label.setText(_translate("InstallDialog", "Download only"))
self.download_only_info_label.setText(_translate("InstallDialog", "Do not try to install."))
self.shortcut_lbl.setText(_translate("InstallDialog", "Create shortcut"))
self.sdl_list_label.setText(_translate("InstallDialog", "Optional packs"))
self.download_size_label.setText(_translate("InstallDialog", "Download size"))
@ -209,6 +194,8 @@ class Ui_InstallDialog(object):
self.verify_button.setText(_translate("InstallDialog", "Verify"))
self.install_button.setText(_translate("InstallDialog", "Install"))
self.install_preqs_lbl.setText(_translate("InstallDialog", "Install prerequisites"))
self.ignore_space_check.setText(_translate("InstallDialog", "Use with caution!"))
self.download_only_check.setText(_translate("InstallDialog", "Do not try to install."))
if __name__ == "__main__":

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>324</width>
<height>347</height>
<width>337</width>
<height>372</height>
</rect>
</property>
<property name="windowTitle">
@ -85,6 +85,9 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item row="2" column="0">
@ -111,32 +114,6 @@
</property>
</widget>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="ignore_space_layout">
<item>
<widget class="QCheckBox" name="ignore_space_check">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="ignore_space_info_label">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Use with caution!</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="0">
<widget class="QLabel" name="download_only_label">
<property name="text">
@ -144,35 +121,6 @@
</property>
</widget>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="download_only_layout">
<item>
<widget class="QCheckBox" name="download_only_check">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="download_only_info_label">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Do not try to install.</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="0">
<widget class="QLabel" name="shortcut_lbl">
<property name="text">
@ -185,9 +133,6 @@
<property name="text">
<string notr="true"/>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="9" column="0">
@ -323,7 +268,43 @@
<item row="8" column="1">
<widget class="QCheckBox" name="install_preqs_check">
<property name="text">
<string/>
<string notr="true"/>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="ignore_space_check">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Use with caution!</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="download_only_check">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Do not try to install.</string>
</property>
</widget>
</item>

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'rare/ui/components/dialogs/login/login_dialog.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
# Created by: PyQt5 UI code generator 5.15.6
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
@ -14,16 +14,17 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_LoginDialog(object):
def setupUi(self, LoginDialog):
LoginDialog.setObjectName("LoginDialog")
LoginDialog.resize(498, 269)
self.verticalLayout = QtWidgets.QVBoxLayout(LoginDialog)
self.verticalLayout.setObjectName("verticalLayout")
spacerItem = QtWidgets.QSpacerItem(477, 17, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
self.verticalLayout.addItem(spacerItem)
LoginDialog.resize(492, 267)
self.login_layout = QtWidgets.QVBoxLayout(LoginDialog)
self.login_layout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
self.login_layout.setObjectName("login_layout")
spacerItem = QtWidgets.QSpacerItem(0, 17, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.login_layout.addItem(spacerItem)
self.welcome_label = QtWidgets.QLabel(LoginDialog)
self.welcome_label.setObjectName("welcome_label")
self.verticalLayout.addWidget(self.welcome_label)
spacerItem1 = QtWidgets.QSpacerItem(477, 17, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
self.verticalLayout.addItem(spacerItem1)
self.login_layout.addWidget(self.welcome_label)
spacerItem1 = QtWidgets.QSpacerItem(0, 17, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.login_layout.addItem(spacerItem1)
self.login_stack = QtWidgets.QStackedWidget(LoginDialog)
self.login_stack.setEnabled(True)
self.login_stack.setMinimumSize(QtCore.QSize(480, 135))
@ -73,7 +74,7 @@ class Ui_LoginDialog(object):
self.login_browser_radio.setObjectName("login_browser_radio")
self.login_page_layout.addWidget(self.login_browser_radio, 1, 0, 1, 1)
self.login_stack.addWidget(self.login_page)
self.verticalLayout.addWidget(self.login_stack)
self.login_layout.addWidget(self.login_stack)
self.button_layout = QtWidgets.QHBoxLayout()
self.button_layout.setObjectName("button_layout")
spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
@ -87,7 +88,7 @@ class Ui_LoginDialog(object):
self.next_button = QtWidgets.QPushButton(LoginDialog)
self.next_button.setObjectName("next_button")
self.button_layout.addWidget(self.next_button)
self.verticalLayout.addLayout(self.button_layout)
self.login_layout.addLayout(self.button_layout)
self.retranslateUi(LoginDialog)
self.login_stack.setCurrentIndex(0)

View file

@ -6,25 +6,22 @@
<rect>
<x>0</x>
<y>0</y>
<width>498</width>
<height>269</height>
<width>492</width>
<height>267</height>
</rect>
</property>
<property name="windowTitle">
<string>Rare Login</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<layout class="QVBoxLayout" name="login_layout">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item>
<spacer name="login_vspacer_top">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>477</width>
<width>0</width>
<height>17</height>
</size>
</property>
@ -39,15 +36,9 @@
</item>
<item>
<spacer name="login_vspacer_bottom">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>477</width>
<width>0</width>
<height>17</height>
</size>
</property>

View file

View file

@ -0,0 +1,67 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'rare/ui/components/extra/console_env.ui'
#
# Created by: PyQt5 UI code generator 5.15.6
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_ConsoleEnv(object):
def setupUi(self, ConsoleEnv):
ConsoleEnv.setObjectName("ConsoleEnv")
ConsoleEnv.resize(600, 400)
self.layout = QtWidgets.QVBoxLayout(ConsoleEnv)
self.layout.setObjectName("layout")
self.table = QtWidgets.QTableWidget(ConsoleEnv)
font = QtGui.QFont()
font.setFamily("Monospace")
self.table.setFont(font)
self.table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.table.setAlternatingRowColors(True)
self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.table.setCornerButtonEnabled(True)
self.table.setColumnCount(2)
self.table.setObjectName("table")
self.table.setRowCount(0)
item = QtWidgets.QTableWidgetItem()
self.table.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.table.setHorizontalHeaderItem(1, item)
self.table.horizontalHeader().setVisible(True)
self.table.horizontalHeader().setStretchLastSection(True)
self.table.verticalHeader().setVisible(False)
self.layout.addWidget(self.table)
self.buttons = QtWidgets.QDialogButtonBox(ConsoleEnv)
self.buttons.setOrientation(QtCore.Qt.Horizontal)
self.buttons.setStandardButtons(QtWidgets.QDialogButtonBox.Close)
self.buttons.setObjectName("buttons")
self.layout.addWidget(self.buttons)
self.retranslateUi(ConsoleEnv)
self.buttons.accepted.connect(ConsoleEnv.accept) # type: ignore
self.buttons.rejected.connect(ConsoleEnv.reject) # type: ignore
QtCore.QMetaObject.connectSlotsByName(ConsoleEnv)
def retranslateUi(self, ConsoleEnv):
_translate = QtCore.QCoreApplication.translate
ConsoleEnv.setWindowTitle(_translate("ConsoleEnv", "Rare - Console Environment"))
self.table.setSortingEnabled(True)
item = self.table.horizontalHeaderItem(0)
item.setText(_translate("ConsoleEnv", "Variable"))
item = self.table.horizontalHeaderItem(1)
item.setText(_translate("ConsoleEnv", "Value"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
ConsoleEnv = QtWidgets.QDialog()
ui = Ui_ConsoleEnv()
ui.setupUi(ConsoleEnv)
ConsoleEnv.show()
sys.exit(app.exec_())

View file

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ConsoleEnv</class>
<widget class="QDialog" name="ConsoleEnv">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>Rare - Console Environment</string>
</property>
<layout class="QVBoxLayout" name="layout">
<item>
<widget class="QTableWidget" name="table">
<property name="font">
<font>
<family>Monospace</family>
</font>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="cornerButtonEnabled">
<bool>true</bool>
</property>
<property name="columnCount">
<number>2</number>
</property>
<attribute name="horizontalHeaderVisible">
<bool>true</bool>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string>Variable</string>
</property>
</column>
<column>
<property name="text">
<string>Value</string>
</property>
</column>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttons">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttons</sender>
<signal>accepted()</signal>
<receiver>ConsoleEnv</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttons</sender>
<signal>rejected()</signal>
<receiver>ConsoleEnv</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -16,7 +16,6 @@ class Ui_GameInfo(object):
GameInfo.setObjectName("GameInfo")
GameInfo.resize(791, 583)
self.layout_game_info = QtWidgets.QHBoxLayout(GameInfo)
self.layout_game_info.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
self.layout_game_info.setObjectName("layout_game_info")
self.image = QtWidgets.QLabel(GameInfo)
self.image.setFrameShape(QtWidgets.QFrame.StyledPanel)

View file

@ -14,9 +14,6 @@
<string>Game Info</string>
</property>
<layout class="QHBoxLayout" name="layout_game_info">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
<item alignment="Qt::AlignTop">
<widget class="QLabel" name="image">
<property name="frameShape">

View file

@ -8,30 +8,37 @@
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtWidgets
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_ImportGroup(object):
def setupUi(self, ImportGroup):
ImportGroup.setObjectName("ImportGroup")
ImportGroup.resize(235, 127)
ImportGroup.resize(501, 154)
ImportGroup.setWindowTitle("ImportGroup")
ImportGroup.setWindowFilePath("")
self.import_layout = QtWidgets.QFormLayout(ImportGroup)
self.import_layout.setLabelAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTrailing | QtCore.Qt.AlignVCenter)
self.import_layout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.import_layout.setObjectName("import_layout")
self.path_edit_label = QtWidgets.QLabel(ImportGroup)
self.path_edit_label.setObjectName("path_edit_label")
self.import_layout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.path_edit_label)
self.app_name_label = QtWidgets.QLabel(ImportGroup)
self.app_name_label.setObjectName("app_name_label")
self.import_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.app_name_label)
self.path_edit_layout = QtWidgets.QHBoxLayout()
self.path_edit_layout.setObjectName("path_edit_layout")
self.import_layout.setLayout(0, QtWidgets.QFormLayout.FieldRole, self.path_edit_layout)
self.app_name_label = QtWidgets.QLabel(ImportGroup)
self.app_name_label.setObjectName("app_name_label")
self.import_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.app_name_label)
self.app_name_layout = QtWidgets.QHBoxLayout()
self.app_name_layout.setObjectName("app_name_layout")
self.import_layout.setLayout(1, QtWidgets.QFormLayout.FieldRole, self.app_name_layout)
self.import_folder_label = QtWidgets.QLabel(ImportGroup)
self.import_folder_label.setObjectName("import_folder_label")
self.import_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.import_folder_label)
self.info_label = QtWidgets.QLabel(ImportGroup)
self.info_label.setText("")
self.info_label.setObjectName("info_label")
self.import_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.info_label)
self.import_button = QtWidgets.QPushButton(ImportGroup)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
@ -39,11 +46,13 @@ class Ui_ImportGroup(object):
sizePolicy.setHeightForWidth(self.import_button.sizePolicy().hasHeightForWidth())
self.import_button.setSizePolicy(sizePolicy)
self.import_button.setObjectName("import_button")
self.import_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.import_button)
self.info_label = QtWidgets.QLabel(ImportGroup)
self.info_label.setText("")
self.info_label.setObjectName("info_label")
self.import_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.info_label)
self.import_layout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.import_button)
self.import_folder_check = QtWidgets.QCheckBox(ImportGroup)
font = QtGui.QFont()
font.setItalic(True)
self.import_folder_check.setFont(font)
self.import_folder_check.setObjectName("import_folder_check")
self.import_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.import_folder_check)
self.retranslateUi(ImportGroup)
QtCore.QMetaObject.connectSlotsByName(ImportGroup)
@ -53,7 +62,9 @@ class Ui_ImportGroup(object):
ImportGroup.setTitle(_translate("ImportGroup", "Import EGL game from a directory"))
self.path_edit_label.setText(_translate("ImportGroup", "Installation path"))
self.app_name_label.setText(_translate("ImportGroup", "Override app name"))
self.import_folder_label.setText(_translate("ImportGroup", "Import all folders"))
self.import_button.setText(_translate("ImportGroup", "Import Game"))
self.import_folder_check.setText(_translate("ImportGroup", "Scan the installation path for game folders and import them"))
if __name__ == "__main__":

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>235</width>
<height>127</height>
<width>501</width>
<height>154</height>
</rect>
</property>
<property name="windowTitle">
@ -30,6 +30,9 @@
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="path_edit_layout"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="app_name_label">
<property name="text">
@ -37,13 +40,24 @@
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="path_edit_layout"/>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="app_name_layout"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="import_folder_label">
<property name="text">
<string>Import all folders</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="info_label">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QPushButton" name="import_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@ -57,9 +71,14 @@
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="info_label">
<widget class="QCheckBox" name="import_folder_check">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string/>
<string>Scan the installation path for game folders and import them</string>
</property>
</widget>
</item>

View file

@ -4,6 +4,7 @@ from typing import Callable, Tuple
from PyQt5.QtCore import (
Qt,
QEvent,
QCoreApplication,
QRect,
QSize,
@ -49,6 +50,7 @@ class FlowLayout(QLayout):
self._vspacing = vspacing
self._items = []
self.setContentsMargins(margin, margin, margin, margin)
self.setObjectName(type(self).__name__)
def __del__(self):
del self._items[:]
@ -148,7 +150,9 @@ class FlowLayout(QLayout):
class IndicatorReasons:
dir_not_empty = QCoreApplication.translate("IndicatorReasons", "Directory is not empty")
wrong_format = QCoreApplication.translate("IndicatorReasons", "Given text has wrong format")
game_not_installed = QCoreApplication.translate("IndicatorReasons", "Game is not installed or does not exist")
game_not_installed = QCoreApplication.translate(
"IndicatorReasons", "Game is not installed or does not exist"
)
dir_not_exist = QCoreApplication.translate("IndicatorReasons", "Directory does not exist")
file_not_exist = QCoreApplication.translate("IndicatorReasons", "File does not exist")
wrong_path = QCoreApplication.translate("IndicatorReasons", "Wrong Directory")
@ -160,29 +164,29 @@ class IndicatorLineEdit(QWidget):
reasons = IndicatorReasons()
def __init__(
self,
text: str = "",
placeholder: str = "",
completer: QCompleter = None,
edit_func: Callable[[str], Tuple[bool, str, str]] = None,
save_func: Callable[[str], None] = None,
horiz_policy: QSizePolicy = QSizePolicy.Expanding,
parent=None,
self,
text: str = "",
placeholder: str = "",
completer: QCompleter = None,
edit_func: Callable[[str], Tuple[bool, str, str]] = None,
save_func: Callable[[str], None] = None,
horiz_policy: QSizePolicy = QSizePolicy.Expanding,
parent=None,
):
super(IndicatorLineEdit, self).__init__(parent=parent)
self.setObjectName("IndicatorLineEdit")
self.layout = QHBoxLayout(self)
self.layout.setObjectName("layout")
self.layout.setContentsMargins(0, 0, 0, 0)
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("line_edit")
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("HintLabel")
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)
@ -191,20 +195,16 @@ class IndicatorLineEdit(QWidget):
completer.popup().setItemDelegate(QStyledItemDelegate(self))
completer.popup().setAlternatingRowColors(True)
self.line_edit.setCompleter(completer)
self.layout.addWidget(self.line_edit)
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.setPixmap(qta_icon("ei.info-circle", color="gray").pixmap(16, 16))
self.indicator_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
self.layout.addWidget(self.indicator_label)
layout.addWidget(self.indicator_label)
if not placeholder:
_translate = QCoreApplication.translate
self.line_edit.setPlaceholderText(
_translate(self.__class__.__name__, "Default")
)
self.line_edit.setPlaceholderText(_translate(self.__class__.__name__, "Default"))
self.edit_func = edit_func
self.save_func = save_func
@ -233,9 +233,7 @@ class IndicatorLineEdit(QWidget):
def __indicator(self, res, reason=None):
color = "green" if res else "red"
self.indicator_label.setPixmap(
qta_icon("ei.info-circle", color=color).pixmap(16, 16)
)
self.indicator_label.setPixmap(qta_icon("ei.info-circle", color=color).pixmap(16, 16))
if reason:
self.indicator_label.setToolTip(reason)
else:
@ -297,16 +295,16 @@ class PathEdit(IndicatorLineEdit):
compl_model = QFileSystemModel()
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, str]] = None,
save_func: Callable[[str], None] = None,
horiz_policy: QSizePolicy = QSizePolicy.Expanding,
parent=None,
self,
path: str = "",
file_type: QFileDialog.FileType = QFileDialog.AnyFile,
type_filter: str = "",
name_filter: str = "",
placeholder: str = "",
edit_func: Callable[[str], Tuple[bool, str, str]] = None,
save_func: Callable[[str], None] = None,
horiz_policy: QSizePolicy = QSizePolicy.Expanding,
parent=None,
):
try:
self.compl_model.setOptions(
@ -320,7 +318,7 @@ class PathEdit(IndicatorLineEdit):
self.compl_model.setRootPath(path)
self.completer.setModel(self.compl_model)
edit_func = self._wrap_edit_function(edit_func)
edit_func = self.__wrap_edit_function(edit_func)
super(PathEdit, self).__init__(
text=path,
@ -331,11 +329,12 @@ class PathEdit(IndicatorLineEdit):
horiz_policy=horiz_policy,
parent=parent,
)
self.setObjectName("PathEdit")
self.line_edit.setMinimumSize(QSize(300, 0))
self.setObjectName(type(self).__name__)
self.line_edit.setMinimumSize(QSize(250, 0))
self.path_select = QToolButton(self)
self.path_select.setObjectName("path_select")
self.layout.addWidget(self.path_select)
self.path_select.setObjectName(f"{type(self).__name__}Button")
layout = self.layout()
layout.addWidget(self.path_select)
_translate = QCoreApplication.translate
self.path_select.setText(_translate("PathEdit", "Browse..."))
@ -361,7 +360,7 @@ class PathEdit(IndicatorLineEdit):
self.line_edit.setText(names[0])
self.compl_model.setRootPath(names[0])
def _wrap_edit_function(self, edit_function: Callable[[str], Tuple[bool, str, str]]):
def __wrap_edit_function(self, edit_function: Callable[[str], Tuple[bool, str, str]]):
if edit_function:
return lambda text: edit_function(os.path.expanduser(text)
if text.startswith("~") else text)
@ -478,9 +477,7 @@ class SelectViewWidget(QWidget):
def __init__(self, icon_view: bool):
super(SelectViewWidget, self).__init__()
self.icon_view = icon_view
self.setStyleSheet(
"""QPushButton{border: none; background-color: transparent}"""
)
self.setStyleSheet("""QPushButton{border: none; background-color: transparent}""")
self.icon_view_button = QPushButton()
self.list_view = QPushButton()
if icon_view:
@ -505,7 +502,9 @@ class SelectViewWidget(QWidget):
return self.icon_view
def icon(self):
self.icon_view_button.setIcon(qta_icon("mdi.view-grid-outline", "ei.th-large", color="orange"))
self.icon_view_button.setIcon(
qta_icon("mdi.view-grid-outline", "ei.th-large", color="orange")
)
self.list_view.setIcon(qta_icon("fa5s.list", "ei.th-list"))
self.icon_view = False
self.toggled.emit()
@ -589,9 +588,7 @@ class ButtonLineEdit(QLineEdit):
"QLineEdit {padding-right: %dpx; }" % (buttonSize.width() + frameWidth + 1)
)
self.setMinimumSize(
max(
self.minimumSizeHint().width(), buttonSize.width() + frameWidth * 2 + 2
),
max(self.minimumSizeHint().width(), buttonSize.width() + frameWidth * 2 + 2),
max(
self.minimumSizeHint().height(),
buttonSize.height() + frameWidth * 2 + 2,

View file

@ -157,6 +157,19 @@ class VerifyWorker(QRunnable):
self.signals.summary.emit(len(failed), len(missing), self.app_name)
# FIXME: lk: ah ef me sideways, we can't even import this thing properly
# FIXME: lk: so copy it here
def resolve_aliases(core: LegendaryCore, name):
# make sure aliases exist if not yet created
core.update_aliases(force=False)
name = name.strip()
# resolve alias (if any) to real app name
return core.lgd.config.get(
section='Legendary.aliases', option=name,
fallback=core.lgd.aliases.get(name.lower(), name)
)
def import_game(core: LegendaryCore, app_name: str, path: str) -> str:
_tr = QCoreApplication.translate
logger.info(f"Import {app_name}")

View file

@ -2,7 +2,7 @@ import os
import platform
from dataclasses import field, dataclass
from multiprocessing import Queue
from typing import Union, List
from typing import Union, List, Optional
from PyQt5.QtCore import QObject, pyqtSignal
@ -46,9 +46,9 @@ class InstallDownloadModel:
@dataclass
class InstallQueueItemModel:
status_q: Queue = None
download: InstallDownloadModel = None
options: InstallOptionsModel = None
status_q: Optional[Queue] = None
download: Optional[InstallDownloadModel] = None
options: Optional[InstallOptionsModel] = None
def __bool__(self):
return (
@ -105,12 +105,12 @@ class PathSpec:
@dataclass
class ApiResults:
game_list: list = None
dlcs: dict = None
bit32_games: list = None
mac_games: list = None
no_asset_games: list = None
saves: list = None
game_list: Optional[list] = None
dlcs: Optional[dict] = None
bit32_games: Optional[list] = None
mac_games: Optional[list] = None
no_asset_games: Optional[list] = None
saves: Optional[list] = None
def __bool__(self):
return (

View file

@ -1,13 +1,13 @@
import os
import pathlib
from pathlib import Path
from PyQt5.QtCore import QStandardPaths
resources_path = pathlib.Path(__file__).absolute().parent.parent.joinpath("resources")
data_dir = os.path.join(QStandardPaths.writableLocation(QStandardPaths.DataLocation), "rare")
cache_dir = os.path.join(QStandardPaths.writableLocation(QStandardPaths.CacheLocation), "rare")
image_dir = os.path.join(data_dir, "images")
tmp_dir = os.path.join(cache_dir, "tmp")
resources_path = Path(__file__).absolute().parent.parent.joinpath("resources")
data_dir = Path(QStandardPaths.writableLocation(QStandardPaths.DataLocation), "rare")
cache_dir = Path(QStandardPaths.writableLocation(QStandardPaths.CacheLocation), "rare")
image_dir = data_dir.joinpath("images")
tmp_dir = cache_dir.joinpath("tmp")
for path in (data_dir, cache_dir, image_dir, tmp_dir):
if not os.path.exists(path):
os.makedirs(path)
if not path.exists():
path.mkdir(parents=True)

View file

@ -13,13 +13,13 @@ requirements = [
"QtAwesome",
"psutil",
"pypresence",
'pywin32; platform_system == "Windows"'
'pywin32; platform_system == "Windows"',
]
optional_reqs = dict(
webview=[
'pywebview[gtk]; platform_system == "Linux"',
'pywebview[cef]; platform_system == "Windows"'
'pywebview[cef]; platform_system == "Windows"',
]
)