1
0
Fork 0
mirror of synced 2024-06-02 18:54:41 +12:00

merge branches

This commit is contained in:
Dummerle 2021-08-16 22:50:31 +02:00
commit 4cfe2bf336
51 changed files with 1382 additions and 581 deletions

View file

@ -1,5 +1,5 @@
include README.md
include rare/languages/*.qm
include rare/styles/*
include rare/styles/qss/*
include rare/styles/colors/*
include rare/resources/images/*
recursive-include rare/resources/stylesheets/* *
include rare/resources/colors/*

View file

@ -2,8 +2,8 @@ import os
__version__ = "1.4.1"
style_path = os.path.join(os.path.dirname(__file__), "styles/")
lang_path = os.path.join(os.path.dirname(__file__), "languages/")
resources_path = os.path.join(os.path.dirname(__file__), "resources")
languages_path = os.path.join(os.path.dirname(__file__), "languages")
# Cache Directory: Store images
if p := os.getenv("XDG_CACHE_HOME"):

View file

@ -10,7 +10,7 @@ from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QStyleFactory
from custom_legendary.core import LegendaryCore
from rare import lang_path, style_path
from rare import languages_path, resources_path
from rare.components.dialogs.launch_dialog import LaunchDialog
from rare.components.main_window import MainWindow
from rare.components.tray_icon import TrayIcon
@ -49,13 +49,21 @@ class App(QApplication):
self.core.lgd.config.add_section("Legendary")
self.core.lgd.save_config()
# workaround if egl sync enabled, but no programdata path
if self.core.egl_sync_enabled and not os.path.exists(self.core.egl.programdata_path):
self.core.lgd.config.remove_option("Legendary", "egl-sync")
self.core.lgd.save_config()
# workaround if egl sync enabled, but no programdata_path
# programdata_path might be unset if logging in through the browser
if self.core.egl_sync_enabled:
if self.core.egl.programdata_path is None:
self.core.lgd.config.remove_option("Legendary", "egl_sync")
self.core.lgd.save_config()
else:
if not os.path.exists(self.core.egl.programdata_path):
self.core.lgd.config.remove_option("Legendary", "egl_sync")
self.core.lgd.save_config()
# set Application name for settings
self.mainwindow = None
self.tray_icon = None
self.launch_dialog = None
self.setApplicationName("Rare")
self.setOrganizationName("Rare")
settings = QSettings()
@ -68,8 +76,8 @@ class App(QApplication):
# Translator
self.translator = QTranslator()
lang = settings.value("language", get_lang(), type=str)
if os.path.exists(lang_path + lang + ".qm"):
self.translator.load(lang_path + lang + ".qm")
if os.path.exists(languages_path + lang + ".qm"):
self.translator.load(languages_path + lang + ".qm")
logger.info("Your language is supported: " + lang)
elif not lang == "en":
logger.info("Your language is not supported")
@ -82,31 +90,40 @@ class App(QApplication):
settings.setValue("style_sheet", "RareStyle")
if color := settings.value("color_scheme", False):
settings.setValue("style_sheet", "")
custom_palette = load_color_scheme(os.path.join(style_path, "colors", color + ".scheme"))
custom_palette = load_color_scheme(os.path.join(resources_path, "colors", color + ".scheme"))
if custom_palette is not None:
self.setPalette(custom_palette)
elif style := settings.value("style_sheet", False):
settings.setValue("color_scheme", "")
self.setStyleSheet(open(os.path.join(style_path, "qss", style + ".qss")).read())
self.setWindowIcon(QIcon(os.path.join(style_path, "Logo.png")))
stylesheet = open(os.path.join(resources_path, "stylesheets", style, "stylesheet.qss")).read()
style_resource_path = os.path.join(resources_path, "stylesheets", style, "")
if os.name == "nt":
style_resource_path = style_resource_path.replace('\\', '/')
self.setStyleSheet(stylesheet.replace("@path@", style_resource_path))
# lk: for qresources stylesheets, not an ideal solution for modability,
# lk: too many extra steps and I don't like binary files in git, even as strings.
# importlib.import_module("rare.resources.stylesheets." + style)
# resource = QFile(f":/{style}/stylesheet.qss")
# resource.open(QIODevice.ReadOnly)
# self.setStyleSheet(QTextStream(resource).readAll())
self.setWindowIcon(QIcon(os.path.join(resources_path, "images", "Rare.png")))
# launch app
self.launch_dialog = LaunchDialog(self.core, args.offline)
# workaround
if self.launch_dialog.offline:
self.start_app(True)
else:
self.launch_dialog.start_app.connect(self.start_app)
self.launch_dialog.quit_app.connect(self.launch_dialog.close)
self.launch_dialog.quit_app.connect(lambda ec: exit(ec))
self.launch_dialog.start_app.connect(self.start_app)
self.launch_dialog.start_app.connect(self.launch_dialog.close)
if not args.silent or args.subparser == "launch":
self.launch_dialog.show()
self.launch_dialog.login()
def start_app(self, offline=False):
self.args.offline = offline
self.mainwindow = MainWindow(self.core, self.args)
self.launch_dialog.close()
self.mainwindow.quit_app.connect(self.exit_app)
self.tray_icon = TrayIcon(self)
self.tray_icon.exit_action.triggered.connect(lambda: exit(0))
self.tray_icon.exit_action.triggered.connect(self.exit_app)
self.tray_icon.start_rare.triggered.connect(self.mainwindow.show)
self.tray_icon.activated.connect(self.tray)
if not offline:
@ -123,13 +140,21 @@ class App(QApplication):
self.mainwindow.show()
logger.info("Show App")
def exit_app(self, exit_code=0):
if self.tray_icon is not None:
self.tray_icon.deleteLater()
if self.mainwindow is not None:
self.mainwindow.close()
self.processEvents()
self.exit(exit_code)
def start(args):
while True:
app = App(args)
exit_code = app.exec_()
# if not restart
if exit_code != -133742:
break
# restart app
del app
if exit_code != -133742:
break

View file

@ -169,12 +169,6 @@ class InstallDialog(QDialog, Ui_InstallDialog):
self.install_size_info_label.setStyleSheet("font-style: normal; font-weight: bold")
self.verify_button.setEnabled(self.options_changed)
self.cancel_button.setEnabled(True)
if dl_item.res.warnings:
self.warn_label.setVisible(True)
self.warn_message.setText("\n".join(str(i) for i in dl_item.res.warnings))
self.warn_message.setVisible(True)
if self.silent:
self.close()
@ -252,7 +246,7 @@ class InstallInfoWorker(QRunnable):
self.signals.result.emit(download)
else:
self.signals.failed.emit("\n".join(str(i) for i in download.res.failures))
except RuntimeError as e:
except Exception as e:
self.signals.failed.emit(str(e))
self.signals.finished.emit()

View file

@ -1,7 +1,7 @@
import os
from logging import getLogger
from PyQt5.QtCore import QThread, pyqtSignal, Qt
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtWidgets import QDialog
from requests.exceptions import ConnectionError
@ -25,74 +25,56 @@ class ImageThread(QThread):
self.download_progess.emit(100)
class LoginThread(QThread):
login = pyqtSignal()
start_app = pyqtSignal(bool) # offline
def __init__(self, core: LegendaryCore):
super(LoginThread, self).__init__()
self.core = core
def run(self):
logger.info("Try if you are logged in")
try:
if self.core.login():
logger.info("You are logged in")
self.start_app.emit(False)
else:
self.run()
except ValueError:
logger.info("You are not logged in. Open Login Window")
self.login.emit()
except ConnectionError as e:
logger.warning(e)
self.start_app.emit(True)
class LaunchDialog(QDialog, Ui_LaunchDialog):
quit_app = pyqtSignal(int)
start_app = pyqtSignal(bool)
finished = False
def __init__(self, core: LegendaryCore, offline: bool = False):
super(LaunchDialog, self).__init__()
def __init__(self, core: LegendaryCore, offline=False, parent=None):
super(LaunchDialog, self).__init__(parent=parent)
self.setupUi(self)
self.offline = offline
self.setAttribute(Qt.WA_DeleteOnClose, True)
self.core = core
if not offline:
self.login_thread = LoginThread(core)
self.login_thread.login.connect(self.login)
self.login_thread.start_app.connect(self.launch)
self.login_thread.start()
else:
self.launch(offline)
self.offline = offline
self.image_thread = None
def login(self):
self.hide()
if LoginDialog(core=self.core).login():
self.show()
self.login_thread.start()
else:
exit(0)
do_launch = True
try:
if self.offline:
pass
else:
if self.core.login():
logger.info("You are logged in")
else:
raise ValueError("You are not logged in. Open Login Window")
except ValueError as e:
logger.info(str(e))
do_launch = LoginDialog(core=self.core, parent=self).login()
except ConnectionError as e:
logger.warning(e)
self.offline = True
finally:
if do_launch:
self.show()
self.launch()
else:
self.quit_app.emit(0)
def launch(self, offline=False):
def launch(self):
# self.core = core
if not os.path.exists(p := os.path.expanduser("~/.cache/rare/images")):
os.makedirs(p)
self.offline = offline
if not offline:
if not self.offline:
self.image_info.setText(self.tr("Downloading Images"))
self.img_thread = ImageThread(self.core, self)
self.img_thread.download_progess.connect(self.update_image_progbar)
self.img_thread.finished.connect(self.finish)
self.img_thread.start()
self.image_thread = ImageThread(self.core, self)
self.image_thread.download_progess.connect(self.update_image_progbar)
self.image_thread.finished.connect(self.finish)
self.image_thread.finished.connect(lambda: self.image_info.setText(self.tr("Ready")))
self.image_thread.finished.connect(self.image_thread.quit)
self.image_thread.finished.connect(self.image_thread.deleteLater)
self.image_thread.start()
else:
self.finished = True
self.finish()
def update_image_progbar(self, i: int):

View file

@ -1,10 +1,9 @@
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QLabel, QStackedLayout, QWidget, QPushButton
from custom_legendary.core import LegendaryCore
# Login Opportunities: Browser, Import
from rare.components.dialogs.login.browser_login import BrowserLogin
from rare.components.dialogs.login.import_widget import ImportWidget
from rare.components.dialogs.login.import_login import ImportLogin
class LoginDialog(QDialog):
@ -17,7 +16,7 @@ class LoginDialog(QDialog):
self.setWindowTitle("Rare - Login")
self.setFixedWidth(350)
self.setFixedHeight(450)
self.setAttribute(Qt.WA_DeleteOnClose, True)
self.init_ui()
def init_ui(self):
@ -54,7 +53,7 @@ class LoginDialog(QDialog):
self.browser_widget.back.clicked.connect(lambda: self.layout.setCurrentIndex(0))
self.layout.addWidget(self.browser_widget)
self.import_widget = ImportWidget(self.core)
self.import_widget = ImportLogin(self.core)
self.import_widget.back.clicked.connect(lambda: self.layout.setCurrentIndex(0))
self.import_widget.success.connect(self.success)
self.layout.addWidget(self.import_widget)

View file

@ -1,54 +1,49 @@
import json
from logging import getLogger
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton, QLabel, QLineEdit
from PyQt5.QtCore import pyqtSignal, QUrl
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtWidgets import QWidget
from custom_legendary.core import LegendaryCore
from rare.ui.components.dialogs.login.browser_login import Ui_BrowserLogin
logger = getLogger("BrowserLogin")
class BrowserLogin(QWidget):
class BrowserLogin(QWidget, Ui_BrowserLogin):
success = pyqtSignal()
url: str = "https://www.epicgames.com/id/login?redirectUrl=https%3A%2F%2Fwww.epicgames.com%2Fid%2Fapi%2Fredirect"
changed = pyqtSignal()
login_url = "https://www.epicgames.com/id/login?redirectUrl=https%3A%2F%2Fwww.epicgames.com%2Fid%2Fapi%2Fredirect"
def __init__(self, core: LegendaryCore, parent=None):
super(BrowserLogin, self).__init__(parent=parent)
self.setupUi(self)
def __init__(self, core: LegendaryCore):
super(BrowserLogin, self).__init__()
self.layout = QVBoxLayout()
self.core = core
self.back = QPushButton("Back") # TODO Icon
self.layout.addWidget(self.back)
self.open_button.clicked.connect(self.open_browser)
self.sid_edit.textChanged.connect(self.changed.emit)
self.info_text = QLabel(self.tr(
"Opens a browser. You login and copy the json code in the field below. Click <a href='{}'>here</a> to open Browser").format(
self.url))
self.info_text.setWordWrap(True)
self.info_text.setOpenExternalLinks(True)
self.layout.addWidget(self.info_text)
def is_valid(self):
return len(self.sid_edit.text()) == 32
self.input_field = QLineEdit()
self.input_field.setPlaceholderText(self.tr("Insert SID here"))
self.layout.addWidget(self.input_field)
self.mini_info = QLabel("")
self.login_btn = QPushButton(self.tr("Login"))
self.login_btn.clicked.connect(self.login)
self.layout.addWidget(self.login_btn)
self.setLayout(self.layout)
def login(self):
self.mini_info.setText(self.tr("Loading..."))
sid = self.input_field.text()
def do_login(self):
self.status_label.setText(self.tr("Logging in..."))
sid = self.sid_edit.text()
# when the text copied
if sid.startswith("{") and sid.endswith("}"):
sid = json.loads(sid)["sid"]
token = self.core.auth_sid(sid)
if self.core.auth_code(token):
logger.info(f"Successfully logged in as {self.core.lgd.userdata['displayName']}")
self.success.emit()
else:
self.mini_info.setText("Login failed")
try:
token = self.core.auth_sid(sid)
if self.core.auth_code(token):
logger.info(f"Successfully logged in as {self.core.lgd.userdata['displayName']}")
self.success.emit()
else:
self.status_label.setText(self.tr("Login failed."))
logger.warning("Failed to login through browser")
except Exception as e:
logger.warning(e)
def open_browser(self):
QDesktopServices.openUrl(QUrl(self.login_url))

View file

@ -0,0 +1,95 @@
import os
from getpass import getuser
from logging import getLogger
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QWidget, QFileDialog
from custom_legendary.core import LegendaryCore
from rare.ui.components.dialogs.login.import_login import Ui_ImportLogin
logger = getLogger("ImportLogin")
class ImportLogin(QWidget, Ui_ImportLogin):
success = pyqtSignal()
changed = pyqtSignal()
if os.name == "nt":
localappdata = os.path.expandvars("%LOCALAPPDATA%")
else:
localappdata = os.path.join("drive_c/users", getuser(), "Local Settings/Application Data")
appdata_path = os.path.join(localappdata, "EpicGamesLauncher/Saved/Config/Windows")
found = False
def __init__(self, core: LegendaryCore, parent=None):
super(ImportLogin, self).__init__(parent=parent)
self.setupUi(self)
self.core = core
self.text_egl_found = self.tr("Found EGL Program Data. Click 'Next' to import them.")
self.text_egl_notfound = self.tr("Could not find EGL Program Data. ")
if os.name == "nt":
if not self.core.egl.appdata_path and os.path.exists(self.egl_data_path):
self.core.egl.appdata_path = self.appdata_path
if not self.core.egl.appdata_path:
self.status_label.setText(self.text_egl_notfound)
else:
self.status_label.setText(self.text_egl_found)
self.found = True
else:
self.info_label.setText(self.tr(
"Please select the Wine prefix"
" where Epic Games Launcher is installed. ") + self.info_label.text()
)
prefixes = self.get_wine_prefixes()
if len(prefixes):
self.prefix_combo.addItems(prefixes)
self.status_label.setText(self.tr("Select the Wine prefix you want to import."))
else:
self.status_label.setText(self.text_egl_notfound)
self.prefix_tool.clicked.connect(self.prefix_path)
self.prefix_combo.editTextChanged.connect(self.changed.emit)
def get_wine_prefixes(self):
possible_prefixes = [
os.path.expanduser("~/.wine"),
os.path.expanduser("~/Games/epic-games-store"),
]
prefixes = []
for prefix in possible_prefixes:
if os.path.exists(os.path.join(prefix, self.appdata_path)):
prefixes.append(prefix)
return prefixes
def prefix_path(self):
prefix_dialog = QFileDialog(self, self.tr("Choose path"), os.path.expanduser("~/"))
prefix_dialog.setFileMode(QFileDialog.DirectoryOnly)
if prefix_dialog.exec_():
names = prefix_dialog.selectedFiles()
self.prefix_combo.setCurrentText(names[0])
def is_valid(self):
if os.name == "nt":
return self.found
else:
return os.path.exists(os.path.join(self.prefix_combo.currentText(), self.appdata_path))
def do_login(self):
self.status_label.setText(self.tr("Loading..."))
if os.name == "nt":
pass
else:
self.core.egl.appdata_path = os.path.join(self.prefix_combo.currentText(), self.appdata_path)
try:
if self.core.auth_import():
logger.info(f"Logged in as {self.core.lgd.userdata['displayName']}")
self.success.emit()
else:
self.status_label.setText(self.tr("Login failed."))
logger.warning("Failed to import existing session.")
except Exception as e:
self.status_label.setText(self.tr("Login failed. ") + str(e))
logger.warning("Failed to import existing session: " + str(e))

View file

@ -1,104 +0,0 @@
from getpass import getuser
from logging import getLogger
import os
import platform
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QPushButton, QLabel, QButtonGroup, QRadioButton
from custom_legendary.core import LegendaryCore
logger = getLogger("Import")
class ImportWidget(QWidget):
success = pyqtSignal()
def __init__(self, core: LegendaryCore):
super(ImportWidget, self).__init__()
self.layout = QVBoxLayout()
self.core = core
self.back = QPushButton("Back")
self.layout.addWidget(self.back)
self.title = QLabel("<h3>Import existing Login session</h3>")
self.title.setWordWrap(True)
self.layout.addWidget(self.title)
self.infoText = QLabel(
"Found Installations here. \nPlease select prefix, where Epic Games Launcher is installed\nNote: You will get logged out there")
self.infoText.setWordWrap(True)
self.layout.addWidget(self.infoText)
self.import_button = QPushButton(self.tr("Import"))
self.data_path = ""
if platform.system() == "Windows":
if not self.core.egl.appdata_path and os.path.exists(
os.path.expandvars("%LOCALAPPDATA%/EpicGamesLauncher/Saved/Config/Windows")):
self.core.egl.appdata_path = os.path.expandvars("%LOCALAPPDATA%/EpicGamesLauncher/Saved/Config/Windows")
if not self.core.egl.appdata_path:
self.text = QLabel(self.tr("Could not find EGL program data"))
else:
self.text = QLabel(self.tr("Found EGL program Data. Do you want to import them?"))
self.layout.addWidget(self.text)
# Linux
else:
self.radio_buttons = []
prefixes = self.get_wine_prefixes()
if len(prefixes) == 0:
self.infoText.setText(self.tr("Could not find any Epic Games login data"))
self.import_button.setDisabled(True)
else:
self.btn_group = QButtonGroup()
for i in prefixes:
radio_button = QRadioButton(i)
self.radio_buttons.append(radio_button)
self.btn_group.addButton(radio_button)
self.layout.addWidget(radio_button)
radio_button.toggled.connect(self.toggle_radiobutton)
self.login_text = QLabel("")
self.layout.addWidget(self.login_text)
self.layout.addWidget(self.import_button)
self.import_button.clicked.connect(self.import_login_data)
self.setLayout(self.layout)
def toggle_radiobutton(self):
if self.sender().isChecked():
self.data_path = self.sender().text()
def get_wine_prefixes(self):
possible_prefixes = [
os.path.expanduser("~/.wine"),
os.path.expanduser("~/Games/epic-games-store")
]
prefixes = []
for i in possible_prefixes:
if os.path.exists(os.path.join(i, "drive_c/users", getuser(),
"Local Settings/Application Data/EpicGamesLauncher/Saved/Config/Windows")):
prefixes.append(i)
return prefixes
def import_login_data(self):
self.import_button.setText(self.tr("Loading..."))
self.import_button.setDisabled(True)
if platform.system() != "Windows":
self.core.egl.appdata_path = os.path.join(self.data_path,
f"drive_c/users/{getuser()}/Local Settings/Application Data/EpicGamesLauncher/Saved/Config/Windows")
try:
if self.core.auth_import():
logger.info(f"Logged in as {self.core.lgd.userdata['displayName']}")
self.success.emit()
else:
logger.warning("Failed to import existing session")
except Exception as e:
logger.warning(e)
logger.warning("Error: No valid session found")
self.login_text.setText(self.tr("Error: No valid session found"))
self.import_button.setText(self.tr("Import"))
self.import_button.setDisabled(False)

View file

@ -1,7 +1,7 @@
import os
from logging import getLogger
from PyQt5.QtCore import QSettings, QTimer
from PyQt5.QtCore import Qt, QSettings, QTimer, pyqtSignal
from PyQt5.QtGui import QCloseEvent
from PyQt5.QtWidgets import QMainWindow, QMessageBox, QApplication
@ -13,9 +13,11 @@ logger = getLogger("Window")
class MainWindow(QMainWindow):
quit_app = pyqtSignal(int)
def __init__(self, core: LegendaryCore, args):
super(MainWindow, self).__init__()
self.setAttribute(Qt.WA_DeleteOnClose)
self.settings = QSettings()
self.core = core
self.offline = args.offline
@ -28,6 +30,7 @@ class MainWindow(QMainWindow):
self.setWindowTitle("Rare - GUI for legendary")
self.tab_widget = TabWidget(core, self, args.offline)
self.tab_widget.quit_app.connect(self.quit_app.emit)
self.setCentralWidget(self.tab_widget)
if not args.offline:
self.rpc = DiscordRPC(core)

View file

@ -18,6 +18,7 @@ from rare.utils.models import InstallQueueItemModel, InstallOptionsModel
class TabWidget(QTabWidget):
quit_app = pyqtSignal(int)
delete_presence = pyqtSignal()
def __init__(self, core: LegendaryCore, parent, offline):
@ -52,8 +53,10 @@ class TabWidget(QTabWidget):
self.addTab(self.account, "")
self.setTabEnabled(disabled_tab + 1, False)
self.mini_widget = MiniWidget(core)
self.mini_widget.quit_app.connect(self.quit_app.emit)
account_action = QWidgetAction(self)
account_action.setDefaultWidget(MiniWidget(core))
account_action.setDefaultWidget(self.mini_widget)
account_button = TabButtonWidget(core, 'mdi.account-circle', 'Account')
account_button.setMenu(QMenu())
account_button.menu().addAction(account_action)
@ -78,13 +81,22 @@ class TabWidget(QTabWidget):
# show uninstalled info
self.games_tab.default_widget.game_list.show_uninstalled_info.connect(self.games_tab.show_uninstalled)
# install dlc
self.games_tab.game_info.dlc_tab.install_dlc.connect(self.install_game)
self.games_tab.game_info.dlc_tab.install_dlc.connect(
lambda app_name, update: self.install_game(
InstallOptionsModel(app_name=app_name),
update=update))
# install game
self.games_tab.uninstalled_info_widget.info.install_game.connect(self.install_game)
self.games_tab.uninstalled_info_widget.info.install_game.connect(
lambda app_name: self.install_game(
InstallOptionsModel(app_name=app_name)))
# repair game
self.games_tab.game_info.info.verify_game.connect(lambda app_name: self.start_download(
InstallOptionsModel(app_name, core.get_installed_game(app_name).install_path, repair=True)))
self.games_tab.game_info.info.verify_game.connect(
lambda app_name: self.install_game(
InstallOptionsModel(app_name=app_name,
base_path=core.get_installed_game(app_name).install_path,
repair=True),
silent=True))
# Finished sync
self.cloud_saves.finished.connect(self.finished_sync)
@ -95,10 +107,11 @@ class TabWidget(QTabWidget):
self.tabBarClicked.connect(lambda x: self.games_tab.layout.setCurrentIndex(0) if x == 0 else None)
self.setIconSize(QSize(25, 25))
def install_game(self, app_name, disable_path=False):
# TODO; maybe pass InstallOptionsModel only, not split arguments
def install_game(self, options: InstallOptionsModel, update=False, silent=False):
install_dialog = InstallDialog(self.core,
InstallQueueItemModel(options=InstallOptionsModel(app_name=app_name)),
update=disable_path, parent=self)
InstallQueueItemModel(options=options),
update=update, silent=silent, parent=self)
install_dialog.result_ready.connect(self.on_install_dialog_closed)
install_dialog.execute()
@ -107,11 +120,11 @@ class TabWidget(QTabWidget):
self.setCurrentIndex(1)
self.start_download(download_item)
def start_download(self, options):
def start_download(self, download_item: InstallQueueItemModel):
downloads = len(self.downloadTab.dl_queue) + len(self.downloadTab.update_widgets.keys()) + 1
self.setTabText(1, "Downloads" + ((" (" + str(downloads) + ")") if downloads != 0 else ""))
self.setCurrentIndex(1)
self.downloadTab.install_game(options)
self.downloadTab.install_game(download_item)
def game_imported(self, app_name: str):
igame = self.core.get_installed_game(app_name)

View file

@ -1,12 +1,14 @@
import webbrowser
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QMessageBox, QLabel, QPushButton
from custom_legendary.core import LegendaryCore
class MiniWidget(QWidget):
quit_app = pyqtSignal(int)
def __init__(self, core: LegendaryCore):
super(MiniWidget, self).__init__()
self.layout = QVBoxLayout()
@ -39,5 +41,4 @@ class MiniWidget(QWidget):
if reply == QMessageBox.Yes:
self.core.lgd.invalidate_userdata()
# restart app
QCoreApplication.instance().exit(-133742) # restart exit code
self.quit_app.emit(-133742) # restart exit code

View file

@ -116,9 +116,7 @@ class SyncWidget(QGroupBox):
elif self.res == SaveGameStatus.REMOTE_NEWER:
status = self.tr("Cloud save is newer")
self.download_button = QPushButton(self.tr("Download Cloud saves"))
self.download_button.setStyleSheet("""
QPushButton{ background-color: lime}
""")
self.download_button.setObjectName("success")
self.upload_button = QPushButton(self.tr("Upload Saves"))
self.logger.info(f'Cloud save for "{igame.title}" is newer:')
self.logger.info(f'- Cloud save date: {dt_remote.strftime("%Y-%m-%d %H:%M:%S")}')
@ -132,9 +130,7 @@ class SyncWidget(QGroupBox):
elif self.res == SaveGameStatus.LOCAL_NEWER:
status = self.tr("Local save is newer")
self.upload_button = QPushButton(self.tr("Upload saves"))
self.upload_button.setStyleSheet("""
QPushButton{ background-color: lime}
""")
self.download_button.setObjectName("success")
self.download_button = QPushButton(self.tr("Download saves"))
self.logger.info(f'Local save for "{igame.title}" is newer')
if dt_remote:

View file

@ -118,9 +118,6 @@ class GameSettings(QWidget, Ui_GameSettings):
if self.change:
# Dont use Proton
if i == 0:
self.proton_prefix.setEnabled(False)
self.wrapper_widget.setEnabled(True)
self.linux_settings.wine_groupbox.setEnabled(True)
if f"{self.game.app_name}" in self.core.lgd.config.sections():
if self.core.lgd.config.get(f"{self.game.app_name}", "wrapper", fallback=False):
self.core.lgd.config.remove_option(self.game.app_name, "wrapper")
@ -133,6 +130,13 @@ class GameSettings(QWidget, Ui_GameSettings):
self.core.lgd.config.remove_option(f"{self.game.app_name}.env", "STEAM_COMPAT_DATA_PATH")
if not self.core.lgd.config[self.game.app_name + ".env"]:
self.core.lgd.config.remove_section(self.game.app_name + ".env")
self.proton_prefix.setEnabled(False)
# lk: TODO: This has to be fixed properly.
# lk: It happens because of the widget update. Mask it for now behind disabling the save button
self.wrapper.setText(self.core.lgd.config.get(f"{self.game.app_name}", "wrapper", fallback=""))
self.wrapper_button.setDisabled(True)
self.wrapper_widget.setEnabled(True)
self.linux_settings.wine_groupbox.setEnabled(True)
else:
self.proton_prefix.setEnabled(True)
self.wrapper_widget.setEnabled(False)

View file

@ -151,19 +151,19 @@ class GameList(QStackedWidget):
return icon_widget, list_widget
def add_installed_widget(self, igame):
if os.path.exists(f"{self.IMAGE_DIR}/{igame.app_name}/FinalArt.png"):
pixmap = QPixmap(f"{self.IMAGE_DIR}/{igame.app_name}/FinalArt.png")
elif os.path.exists(f"{self.IMAGE_DIR}/{igame.app_name}/DieselGameBoxTall.png"):
if os.path.exists(os.path.join(self.IMAGE_DIR, igame.app_name, "FinalArt.png")):
pixmap = QPixmap(os.path.exists(os.path.join(self.IMAGE_DIR, igame.app_name, "FinalArt.png")))
elif os.path.exists(os.path.join(self.IMAGE_DIR, igame.app_name, "DieselGameBoxTall.png")):
pixmap = QPixmap(f"{self.IMAGE_DIR}/{igame.app_name}/DieselGameBoxTall.png")
elif os.path.exists(f"{self.IMAGE_DIR}/{igame.app_name}/DieselGameBoxLogo.png"):
pixmap = QPixmap(f"{self.IMAGE_DIR}/{igame.app_name}/DieselGameBoxLogo.png")
elif os.path.exists(os.path.join(self.IMAGE_DIR, igame.app_name, "DieselGameBoxLogo.png")):
pixmap = QPixmap(os.path.join(self.IMAGE_DIR, igame.app_name, "DieselGameBoxLogo.png"))
else:
logger.warning(f"No Image found: {igame.title}")
pixmap = None
pixmap = QPixmap()
if pixmap.isNull():
logger.info(igame.title + " has a corrupt image.")
download_image(igame, force=True)
download_image(self.core.get_game(igame.app_name), force=True)
pixmap = QPixmap(f"{self.IMAGE_DIR}/{igame.app_name}/DieselGameBoxTall.png")
icon_widget = GameWidgetInstalled(igame, self.core, pixmap, self.offline)

View file

@ -1,13 +1,15 @@
import os
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QSystemTrayIcon, QMenu, QAction
from rare import style_path
from rare import resources_path
class TrayIcon(QSystemTrayIcon):
def __init__(self, parent):
super(TrayIcon, self).__init__(parent)
self.setIcon(QIcon(style_path + "Logo.png"))
self.setIcon(QIcon(os.path.join(resources_path, "images", "Rare.png")))
self.setVisible(True)
self.setToolTip("Rare")

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,3 @@
<svg height="736" viewBox="0 0 736 736" width="736" xmlns="http://www.w3.org/2000/svg">
<path d="m368 120c-137 0-248 111-248 248s111 248 248 248 248-111 248-248-111-248-248-248z" fill="#43474d"/>
</svg>

After

Width:  |  Height:  |  Size: 206 B

View file

@ -0,0 +1,3 @@
<svg height="736" viewBox="0 0 736 736" width="736" xmlns="http://www.w3.org/2000/svg">
<path d="m368 120c-137 0-248 111-248 248s111 248 248 248 248-111 248-248-111-248-248-248z" fill="#483d8b"/>
</svg>

After

Width:  |  Height:  |  Size: 206 B

View file

@ -0,0 +1,4 @@
<svg height="640" viewBox="0 0 320 640" width="320" xmlns="http://www.w3.org/2000/svg">
<path d="m41 236.475h238c21.4 0 32.1 25.9 17 41l-119 119c-9.4 9.4-24.6 9.4-33.9 0l-119.1-119c-15.1-15.1-4.4-41 17-41z"
fill="#eee"/>
</svg>

After

Width:  |  Height:  |  Size: 241 B

View file

@ -0,0 +1,4 @@
<svg height="320" viewBox="0 0 320 320" width="320" xmlns="http://www.w3.org/2000/svg">
<path d="m41 76.475h238c21.4 0 32.1 25.9 17 41l-119 119c-9.4 9.4-24.6 9.4-33.9 0l-119.1-119c-15.1-15.1-4.4-41 17-41z"
fill="#eee"/>
</svg>

After

Width:  |  Height:  |  Size: 240 B

View file

@ -0,0 +1,4 @@
<svg height="320" viewBox="0 0 320 320" width="320" xmlns="http://www.w3.org/2000/svg">
<path d="m279.01546 243.525h-237.999997c-21.4 0-32.1000001-25.9-17-41l118.999997-119c9.4-9.4 24.6-9.4 33.9 0l119 119c15.2 15.1 4.5 41-16.9 41z"
fill="#eee"/>
</svg>

After

Width:  |  Height:  |  Size: 266 B

View file

@ -0,0 +1,4 @@
<svg height="688" viewBox="0 0 688 688" width="688" xmlns="http://www.w3.org/2000/svg">
<path d="m520 120h-352c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-352c0-26.5-21.5-48-48-48z"
fill="#43474d"/>
</svg>

After

Width:  |  Height:  |  Size: 248 B

View file

@ -0,0 +1,4 @@
<svg height="688" viewBox="0 0 688 688" width="688" xmlns="http://www.w3.org/2000/svg">
<path d="m520 120h-352c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-352c0-26.5-21.5-48-48-48z"
fill="#483d8b"/>
</svg>

After

Width:  |  Height:  |  Size: 248 B

View file

@ -0,0 +1,355 @@
/*
$active_base = #202225;
$active_text = #eeeeee;
$widget_base = #333344;
$primary_border = #42474E;
$secondary_border = darkslategrey;
*/
* { background-color: #202225; }
* { color: #eeeeee; }
* { border-color: #483d8b; }
*::disabled,
*::drop-down:disabled {
color: #43474d;
border-color: #43474d;
background-color: #202225;
}
QLabel {
border-width: 0px;
background-color: transparent;
padding: 0px;
}
QMenu,
QListView,
QListWidget,
QFrame[frameShape="6"],
QLineEdit,
QTextEdit,
QTimeEdit,
QDateEdit,
QDateTimeEdit,
QComboBox,
QComboBox:editable,
QComboBox QAbstractItemView,
QSpinBox,
QDoubleSpinBox,
QProgressBar,
QScrollBar {
border-width: 1px;
border-style: solid;
border-radius: 2px;
padding: 2px;
}
QListView,
QListWidget,
QLineEdit,
QTextEdit,
QTimeEdit,
QDateEdit,
QDateTimeEdit,
QComboBox:editable,
QComboBox QAbstractItemView,
QSpinBox,
QDoubleSpinBox,
QProgressBar,
QScrollBar {
border-color: #2f4f4f;
background-color: #333344;
selection-background-color: #2f4f4f;
}
QLineEdit,
QTextEdit,
QTimeEdit,
QDateEdit,
QDateTimeEdit,
QComboBox
QSpinBox,
QDoubleSpinBox,
QProgressBar,
QPushButton {
height: 17px;
}
QToolButton {
height: 14px;
}
QFrame[frameShape="6"] {
border-radius: 4px;
}
QComboBox {
background-color: #3c3f41;
}
*::item:selected,
QComboBox QAbstractItemView {
selection-background-color: #2f4f4f;
}
*::drop-down,
*::drop-down:editable,
*::up-button,
*::down-button {
subcontrol-origin: border;
border-width: 1px;
border-style: solid;
border-radius: 2px;
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
}
*::drop-down {
subcontrol-position: top right;
border-color: #483d8b;
border-left-color: #5246a0; /* #483d8b lighter */
}
*::drop-down:editable,
*::up-button ,
*::down-button {
border-color: #2f4f4f;
background-color: #3c3f41;
}
*::drop-down,
*::drop-down:editable {
width: 14px;
image: url(@path@drop-down.svg);
}
*::up-button ,
*::down-button {
width: 14px; /* 16 + 2*1px border-width = 15px padding + 3px parent border */
}
*::up-button {
subcontrol-position: top right; /* position at the top right corner */
border-bottom-width: 1;
image: url(@path@sort-up.svg);
}
*::down-button {
subcontrol-position: bottom right; /* position at bottom right corner */
border-top-width: 1;
image: url(@path@sort-down.svg);
}
QProgressBar {
text-align: center;
}
QProgressBar::chunk {
width: 9.5%;
margin: 0.5%;
background-color: #2f4f4f;
}
QScrollBar {
border-radius: 6px;
padding: 1px;
}
QScrollBar::add-line:vertical,
QScrollBar::sub-line:vertical,
QScrollBar::add-line:horizontal,
QScrollBar::sub-line:horizontal {
border: none;
height: 0px;
background: transparent;
}
QScrollBar::add-line:vertical {
subcontrol-position: top;
subcontrol-origin: margin;
}
QScrollBar::sub-line:vertical {
subcontrol-position: bottom;
subcontrol-origin: margin;
}
QScrollBar::add-line:horizontal {
subcontrol-position: right;
subcontrol-origin: margin;
}
QScrollBar::sub-line:horizontal {
subcontrol-position: left;
subcontrol-origin: margin;
}
QScrollBar::handle {
border-width: 1px;
border-style: solid;
border-color: lightgray;
background-color: gray;
border-radius: 4px;
min-height: 20px;
min-width: 20px;
}
QPushButton,
QToolButton {
background-color: #3c3f41;
}
QPushButton::hover,
QToolButton::hover {
background-color: #222233;
}
QPushButton,
QToolButton {
border-width: 1px;
border-style: solid;
border-radius: 2px;
padding: 2px;
padding-left: 6px;
padding-right: 6px
}
QPushButton::menu-indicator {
subcontrol-position: right center;
subcontrol-origin: padding;
left: -2px;
border-style: none;
}
QPushButton#menu {
padding: 0px;
margin: 0px;
border-style: none;
}
QPushButton#menu_button {
background-color: transparent;
border: none;
}
QPushButton:hover#menu_button {
background-color: #334;
}
QPushButton#install_button {
background-color: #090;
}
QPushButton::hover#install_button {
background-color: #060;
}
QPushButton::disabled#install_button {
background-color: #020;
}
QPushButton#uninstall_button {
background-color: #900;
}
QPushButton::hover#uninstall_button {
background-color: #600;
}
QPushButton::disabled#uninstall_button {
background-color: #200;
}
QPushButton#success{
background-color: lime;
}
QGroupBox,
QCheckBox,
QRadioButton {
background-color: none;
}
QGroupBox::indicator,
QCheckBox::indicator,
QRadioButton::indicator {
border-color: #2f4f4f;
border-width: 1px;
border-style: solid;
}
QCheckBox::indicator,
QRadioButton::indicator {
width: 11px;
height: 11px;
}
QGroupBox::indicator:disabled,
QCheckBox::indicator:disabled,
QRadioButton::indicator:disabled {
border-color: #43474d;
}
QRadioButton::indicator {
border-radius: 5%;
}
QGroupBox::indicator,
QCheckBox::indicator {
border-radius: 2px;
}
QGroupBox::indicator:checked,
QCheckBox::indicator:checked {
border-radius: 2px;
image: url(@path@square.svg);
}
QRadioButton::indicator:checked {
border-radius: 5%;
image: url(@path@circle.svg);
}
QGroupBox::indicator:checked:disabled,
QCheckBox::indicator:checked:disabled {
image: url(@path@square-disabled.svg);
}
QRadioButton::indicator:checked:disabled {
image: url(@path@circle-disabled.svg);
}
QGroupBox,
QGroupBox#group,
QGroupBox#settings_widget {
border-width: 1px;
border-style: solid;
border-radius: 4px;
font-size: 11px;
font-weight: bold;
margin-top: 3ex;
padding: 1px;
}
QGroupBox#game_widget_icon {
border: none;
padding: 0px;
margin: 0px;
}
QSizeGrip {
image: none;
width: 4px;
height: 4px;
}
#list_widget {
border-top-width: 2px;
}
#search_bar {
padding: 3px;
border-radius: 5px;
background-color: #334;
}
QPushButton:hover#installed_menu_button {
background-color: green;
}
QTabBar#main_tab_bar {
border-bottom: none;
background-color: #2b2b2c;
}
QTabBar::tab#main_tab_bar {
border-top: 2px solid transparent;
border-bottom: none;
}
QTabBar::tab#main_tab_bar {
border-bottom: none;
padding: 5px;
}
QTabBar::tab:selected#main_tab_bar {
background-color: #202225;
border-top: 2px solid #483d8b;
}
QTabBar::tab:hover#main_tab_bar {
border-top: 2px solid #483d8b;
}
QTabBar::tab#settings_bar {
border-radius: 0;
}
QTabBar::tab:hover#settings_bar {
border-left: 2px solid white;
}
QTabBar::tab::selected#settings_bar {
background-color: #2f4f4f;
}
QTabBar::tab:disabled#settings_bar {
color: transparent;
background-color: transparent;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -1,262 +0,0 @@
QWidget {
background-color: #202225;
color: #eee;
}
QLabel {
background-color: transparent;
padding: 4px;
}
QLineEdit {
border: 1px solid darkslategrey;
border-radius: 2px;
background-color: #334;
padding: 2px;
}
QScrollBar {
border: 1px solid darkslategrey;
border-radius: 4px;
background-color: #334;
padding: 1px;
}
QScrollBar::add-line:vertical {
border: none;
background: transparent;
height: 0px;
subcontrol-position: bottom;
subcontrol-origin: margin;
}
QScrollBar::sub-line:vertical {
border: none;
background: transparent;
height: 0px;
subcontrol-position: top;
subcontrol-origin: margin;
}
QScrollBar::add-line:horizontal {
border: none;
background: transparent;
height: 0px;
subcontrol-position: right;
subcontrol-origin: margin;
}
QScrollBar::sub-line:horizontal {
border: none;
background: green;
height: 0px;
subcontrol-position: left;
subcontrol-origin: margin;
}
QScrollBar::handle {
border: 1px solid darkslategrey;
background-color: gray;
border-radius: 4px;
min-height: 20px;
min-width: 20px;
}
QTabBar#main_tab_bar {
border-bottom: none;
background-color: #2b2b2c;
}
QTabBar::tab#main_tab_bar {
border-bottom: none;
}
QTabBar::tab#main_tab_bar {
border-bottom: none;
padding: 5px
}
QTabBar::tab:selected#main_tab_bar {
background-color: gray;
}
QTabBar::tab:hover#main_tab_bar {
border-bottom: 2px solid black;
}
QGroupBox {
border: 1px solid gray;
font-size: 13px;
font-weight: bold;
border-radius: 6px;
margin-top: 3ex;
padding-top: 0px;
padding-bottom: 0px;
padding-left: 0px;
padding-right: 0px;
}
QGroupBox#settings_widget {
border: 1px solid gray;
font-size: 13px;
font-weight: bold;
border-radius: 6px;
margin-top: 3ex;
padding-top: 0px;
padding-bottom: 0px;
padding-left: 0px;
padding-right: 0px;
}
QGroupBox#game_widget_icon {
border: none;
padding: 0;
margin: 0;
}
QGroupBox#group {
border: 1px solid gray;
font-size: 13px;
font-weight: bold;
border-radius: 6px;
margin-top: 3ex;
padding-top: 0px;
padding-bottom: 0px;
padding-left: 0px;
padding-right: 0px;
}
QToolButton {
border: 1px solid gray;
border-radius: 2px;
background-color: #3c3f41;
padding: 4px;
}
QToolButton:hover {
background-color: #223;
}
QPushButton {
border: 1px solid gray;
border-radius: 2px;
background-color: #3c3f41;
padding: 5px;
}
QPushButton:hover {
background-color: #223;
}
QPushButton::menu-indicator {
subcontrol-position: right center;
subcontrol-origin: padding;
left: -2px;
border-style: none;
}
QPushButton#menu {
padding: 0px;
margin: 0px;
border-style: none;
}
QPushButton#menu_button {
background-color: transparent;
border: none;
}
QPushButton:hover#menu_button {
background-color: #334;
}
QRadioButton {
background-color: none;
border-radius: 50%;
}
QRadioButton::indicator {
border: 1px solid gray;
border-radius: 5%;
}
QCheckBox {
background-color: none;
}
QCheckBox::indicator {
border: 1px solid gray;
border-radius: 2px;
}
QCheckBox::indicator:checked {
width: -20ex;
height: -20ex;
background: #5F5F80;
border-radius: 10px;
}
QSpinBox {
border: 1px solid darkslategrey;
border-radius: 2px;
background-color: #334;
padding: 2px;
}
/*
QCheckBox::indicator {
border: 1px solid gray;
}
*/
QComboBox {
border: 1px solid gray;
border-radius: 2px;
background-color: #3c3f41;
padding: 5px;
}
QComboBox::drop-down {
subcontrol-origin: padding;
subcontrol-position: top right;
width: 15px;
/*
border-left-width: 1px;
border-left-color: darkgray;
border-left-style: solid;
*/
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
#list_widget {
border-top: 2px solid white;
}
QPushButton:hover#installed_menu_button {
background-color: green;
}
QTabBar::tab#settings_bar {
border-radius: 0;
}
QTabBar::tab:hover#settings_bar {
border-left: 2px solid white;
}
QTabBar::tab::selected#settings_bar {
background-color: darkslategrey;
}
#search_bar {
padding: 3px;
border-radius: 5px;
background-color: #334;
}
QTabBar::tab:disabled#settings_bar {
color: transparent;
background-color: transparent;
}

View file

@ -0,0 +1,71 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'browser_login.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# 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_BrowserLogin(object):
def setupUi(self, BrowserLogin):
BrowserLogin.setObjectName("BrowserLogin")
BrowserLogin.resize(246, 130)
BrowserLogin.setWindowTitle("BrowserLogin")
self.browser_layout = QtWidgets.QGridLayout(BrowserLogin)
self.browser_layout.setObjectName("browser_layout")
self.open_button = QtWidgets.QPushButton(BrowserLogin)
self.open_button.setObjectName("open_button")
self.browser_layout.addWidget(self.open_button, 1, 0, 1, 1)
self.title_label = QtWidgets.QLabel(BrowserLogin)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.title_label.setFont(font)
self.title_label.setObjectName("title_label")
self.browser_layout.addWidget(self.title_label, 0, 0, 1, 2, QtCore.Qt.AlignTop)
self.sid_edit = QtWidgets.QLineEdit(BrowserLogin)
self.sid_edit.setObjectName("sid_edit")
self.browser_layout.addWidget(self.sid_edit, 1, 1, 1, 1)
self.info_label = QtWidgets.QLabel(BrowserLogin)
font = QtGui.QFont()
font.setItalic(True)
self.info_label.setFont(font)
self.info_label.setWordWrap(True)
self.info_label.setObjectName("info_label")
self.browser_layout.addWidget(self.info_label, 3, 0, 1, 2, QtCore.Qt.AlignBottom)
self.status_label = QtWidgets.QLabel(BrowserLogin)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.status_label.sizePolicy().hasHeightForWidth())
self.status_label.setSizePolicy(sizePolicy)
self.status_label.setText("")
self.status_label.setObjectName("status_label")
self.browser_layout.addWidget(self.status_label, 2, 1, 1, 1)
self.retranslateUi(BrowserLogin)
QtCore.QMetaObject.connectSlotsByName(BrowserLogin)
def retranslateUi(self, BrowserLogin):
_translate = QtCore.QCoreApplication.translate
self.open_button.setText(_translate("BrowserLogin", "Open Browser"))
self.title_label.setText(_translate("BrowserLogin", "Login through browser"))
self.sid_edit.setPlaceholderText(_translate("BrowserLogin", "Insert SID here"))
self.info_label.setText(_translate("BrowserLogin",
"Click the button to open the login page in a browser. After logging in, copy the SID code in the input above."))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
BrowserLogin = QtWidgets.QWidget()
ui = Ui_BrowserLogin()
ui.setupUi(BrowserLogin)
BrowserLogin.show()
sys.exit(app.exec_())

View file

@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BrowserLogin</class>
<widget class="QWidget" name="BrowserLogin">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>246</width>
<height>130</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">BrowserLogin</string>
</property>
<layout class="QGridLayout" name="browser_layout">
<item row="1" column="0">
<widget class="QPushButton" name="open_button">
<property name="text">
<string>Open Browser</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2" alignment="Qt::AlignTop">
<widget class="QLabel" name="title_label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Login through browser</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="sid_edit">
<property name="placeholderText">
<string>Insert SID here</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2" alignment="Qt::AlignBottom">
<widget class="QLabel" name="info_label">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Click the button to open the login page in a browser. After logging in, copy the SID
code in the input above.
</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="status_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'import_login.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# 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_ImportLogin(object):
def setupUi(self, ImportLogin):
ImportLogin.setObjectName("ImportLogin")
ImportLogin.resize(503, 173)
ImportLogin.setWindowTitle("ImportLogin")
self.import_layout = QtWidgets.QGridLayout(ImportLogin)
self.import_layout.setObjectName("import_layout")
self.info_label = QtWidgets.QLabel(ImportLogin)
font = QtGui.QFont()
font.setItalic(True)
self.info_label.setFont(font)
self.info_label.setWordWrap(True)
self.info_label.setObjectName("info_label")
self.import_layout.addWidget(self.info_label, 3, 0, 1, 3, QtCore.Qt.AlignBottom)
self.title_label = QtWidgets.QLabel(ImportLogin)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.title_label.setFont(font)
self.title_label.setObjectName("title_label")
self.import_layout.addWidget(self.title_label, 0, 0, 1, 3, QtCore.Qt.AlignTop)
self.prefix_combo = QtWidgets.QComboBox(ImportLogin)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.prefix_combo.sizePolicy().hasHeightForWidth())
self.prefix_combo.setSizePolicy(sizePolicy)
self.prefix_combo.setEditable(True)
self.prefix_combo.setObjectName("prefix_combo")
self.import_layout.addWidget(self.prefix_combo, 1, 1, 1, 1)
self.prefix_label = QtWidgets.QLabel(ImportLogin)
self.prefix_label.setObjectName("prefix_label")
self.import_layout.addWidget(self.prefix_label, 1, 0, 1, 1)
self.prefix_tool = QtWidgets.QToolButton(ImportLogin)
self.prefix_tool.setObjectName("prefix_tool")
self.import_layout.addWidget(self.prefix_tool, 1, 2, 1, 1)
self.status_label = QtWidgets.QLabel(ImportLogin)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.status_label.sizePolicy().hasHeightForWidth())
self.status_label.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setItalic(True)
self.status_label.setFont(font)
self.status_label.setText("")
self.status_label.setObjectName("status_label")
self.import_layout.addWidget(self.status_label, 2, 1, 1, 2)
self.retranslateUi(ImportLogin)
QtCore.QMetaObject.connectSlotsByName(ImportLogin)
def retranslateUi(self, ImportLogin):
_translate = QtCore.QCoreApplication.translate
self.info_label.setText(_translate("ImportLogin", "You will get logged out from EGL in the process."))
self.title_label.setText(_translate("ImportLogin", "Import existing session from EGL"))
self.prefix_label.setText(_translate("ImportLogin", "Select path"))
self.prefix_tool.setText(_translate("ImportLogin", "Browse"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
ImportLogin = QtWidgets.QWidget()
ui = Ui_ImportLogin()
ui.setupUi(ImportLogin)
ImportLogin.show()
sys.exit(app.exec_())

View file

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ImportLogin</class>
<widget class="QWidget" name="ImportLogin">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>503</width>
<height>173</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">ImportLogin</string>
</property>
<layout class="QGridLayout" name="import_layout">
<item row="3" column="0" colspan="3" alignment="Qt::AlignBottom">
<widget class="QLabel" name="info_label">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>You will get logged out from EGL in the process.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3" alignment="Qt::AlignTop">
<widget class="QLabel" name="title_label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Import existing session from EGL</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="prefix_combo">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="prefix_label">
<property name="text">
<string>Select path</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QToolButton" name="prefix_tool">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QLabel" name="status_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -0,0 +1,132 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'login_dialog.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# 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_LoginDialog(object):
def setupUi(self, LoginDialog):
LoginDialog.setObjectName("LoginDialog")
LoginDialog.resize(492, 311)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(LoginDialog.sizePolicy().hasHeightForWidth())
LoginDialog.setSizePolicy(sizePolicy)
self.dialog_layout = QtWidgets.QVBoxLayout(LoginDialog)
self.dialog_layout.setObjectName("dialog_layout")
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
self.dialog_layout.addItem(spacerItem)
self.welcome_label = QtWidgets.QLabel(LoginDialog)
self.welcome_label.setObjectName("welcome_label")
self.dialog_layout.addWidget(self.welcome_label)
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
self.dialog_layout.addItem(spacerItem1)
self.login_stack = QtWidgets.QStackedWidget(LoginDialog)
self.login_stack.setEnabled(True)
self.login_stack.setMinimumSize(QtCore.QSize(480, 135))
self.login_stack.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.login_stack.setFrameShadow(QtWidgets.QFrame.Raised)
self.login_stack.setObjectName("login_stack")
self.login_page = QtWidgets.QWidget()
self.login_page.setEnabled(True)
self.login_page.setObjectName("login_page")
self.login_page_layout = QtWidgets.QGridLayout(self.login_page)
self.login_page_layout.setObjectName("login_page_layout")
self.login_browser_label = QtWidgets.QLabel(self.login_page)
font = QtGui.QFont()
font.setItalic(True)
self.login_browser_label.setFont(font)
self.login_browser_label.setObjectName("login_browser_label")
self.login_page_layout.addWidget(self.login_browser_label, 1, 1, 1, 1)
self.login_label = QtWidgets.QLabel(self.login_page)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.login_label.setFont(font)
self.login_label.setObjectName("login_label")
self.login_page_layout.addWidget(self.login_label, 0, 0, 1, 3, QtCore.Qt.AlignTop)
self.login_import_label = QtWidgets.QLabel(self.login_page)
font = QtGui.QFont()
font.setItalic(True)
self.login_import_label.setFont(font)
self.login_import_label.setObjectName("login_import_label")
self.login_page_layout.addWidget(self.login_import_label, 2, 1, 1, 1)
self.login_import_radio = QtWidgets.QRadioButton(self.login_page)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.login_import_radio.sizePolicy().hasHeightForWidth())
self.login_import_radio.setSizePolicy(sizePolicy)
self.login_import_radio.setObjectName("login_import_radio")
self.login_page_layout.addWidget(self.login_import_radio, 2, 0, 1, 1)
self.login_browser_radio = QtWidgets.QRadioButton(self.login_page)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.login_browser_radio.sizePolicy().hasHeightForWidth())
self.login_browser_radio.setSizePolicy(sizePolicy)
self.login_browser_radio.setObjectName("login_browser_radio")
self.login_page_layout.addWidget(self.login_browser_radio, 1, 0, 1, 1)
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.login_page_layout.addItem(spacerItem2, 1, 2, 2, 1)
self.login_stack.addWidget(self.login_page)
self.success_page = QtWidgets.QWidget()
self.success_page.setObjectName("success_page")
self.success_page_layout = QtWidgets.QHBoxLayout(self.success_page)
self.success_page_layout.setObjectName("success_page_layout")
self.success_label = QtWidgets.QLabel(self.success_page)
self.success_label.setObjectName("success_label")
self.success_page_layout.addWidget(self.success_label)
self.login_stack.addWidget(self.success_page)
self.dialog_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)
self.button_layout.addItem(spacerItem3)
self.exit_button = QtWidgets.QPushButton(LoginDialog)
self.exit_button.setObjectName("exit_button")
self.button_layout.addWidget(self.exit_button)
self.back_button = QtWidgets.QPushButton(LoginDialog)
self.back_button.setObjectName("back_button")
self.button_layout.addWidget(self.back_button)
self.next_button = QtWidgets.QPushButton(LoginDialog)
self.next_button.setObjectName("next_button")
self.button_layout.addWidget(self.next_button)
self.dialog_layout.addLayout(self.button_layout)
self.retranslateUi(LoginDialog)
self.login_stack.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(LoginDialog)
def retranslateUi(self, LoginDialog):
_translate = QtCore.QCoreApplication.translate
LoginDialog.setWindowTitle(_translate("LoginDialog", "Welcome to Rare"))
self.welcome_label.setText(_translate("LoginDialog", "<h1>Welcome to Rare</h1>"))
self.login_browser_label.setText(_translate("LoginDialog", "Login using a browser."))
self.login_label.setText(_translate("LoginDialog", "Select login method"))
self.login_import_label.setText(_translate("LoginDialog", "Import from Epic Games Launcher"))
self.login_import_radio.setText(_translate("LoginDialog", "Import"))
self.login_browser_radio.setText(_translate("LoginDialog", "Browser"))
self.success_label.setText(_translate("LoginDialog", "<h2>Login Succeful!</h2>"))
self.exit_button.setText(_translate("LoginDialog", "Exit"))
self.back_button.setText(_translate("LoginDialog", "Back"))
self.next_button.setText(_translate("LoginDialog", "Next"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
LoginDialog = QtWidgets.QDialog()
ui = Ui_LoginDialog()
ui.setupUi(LoginDialog)
LoginDialog.show()
sys.exit(app.exec_())

View file

@ -0,0 +1,220 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LoginDialog</class>
<widget class="QDialog" name="LoginDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>492</width>
<height>311</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Welcome to Rare</string>
</property>
<layout class="QVBoxLayout" name="dialog_layout">
<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>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="welcome_label">
<property name="text">
<string>&lt;h1&gt;Welcome to Rare&lt;/h1&gt;</string>
</property>
</widget>
</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>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QStackedWidget" name="login_stack">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>480</width>
<height>135</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="login_page">
<property name="enabled">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="login_page_layout">
<item row="1" column="1">
<widget class="QLabel" name="login_browser_label">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Login using a browser.</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3" alignment="Qt::AlignTop">
<widget class="QLabel" name="login_label">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Select login method</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="login_import_label">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>Import from Epic Games Launcher</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="login_import_radio">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Import</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="login_browser_radio">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Browser</string>
</property>
</widget>
</item>
<item row="1" column="2" rowspan="2">
<spacer name="login_hspacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="success_page">
<layout class="QHBoxLayout" name="success_page_layout">
<item>
<widget class="QLabel" name="success_label">
<property name="text">
<string>&lt;h2&gt;Login Succeful!&lt;/h2&gt;</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="button_layout">
<item>
<spacer name="button_hspacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="exit_button">
<property name="text">
<string>Exit</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="back_button">
<property name="text">
<string>Back</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="next_button">
<property name="text">
<string>Next</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -170,7 +170,7 @@ class Ui_GameInfo(object):
self.repair_button.setObjectName("repair_button")
self.installed_layout.addWidget(self.repair_button)
self.uninstall_button = QtWidgets.QPushButton(self.installed_page)
self.uninstall_button.setStyleSheet("background-color: #900")
self.uninstall_button.setStyleSheet("")
self.uninstall_button.setObjectName("uninstall_button")
self.installed_layout.addWidget(self.uninstall_button)
self.game_actions_stack.addWidget(self.installed_page)
@ -179,7 +179,7 @@ class Ui_GameInfo(object):
self.uninstalled_layout = QtWidgets.QVBoxLayout(self.uninstalled_page)
self.uninstalled_layout.setObjectName("uninstalled_layout")
self.install_button = QtWidgets.QPushButton(self.uninstalled_page)
self.install_button.setStyleSheet("background-color: #090")
self.install_button.setStyleSheet("")
self.install_button.setObjectName("install_button")
self.uninstalled_layout.addWidget(self.install_button)
self.game_actions_stack.addWidget(self.uninstalled_page)

View file

@ -250,17 +250,17 @@
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="installed_page" native="true">
<layout class="QVBoxLayout" name="installed_layout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<widget class="QWidget" name="installed_page">
<layout class="QVBoxLayout" name="installed_layout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
@ -333,7 +333,7 @@
<item>
<widget class="QPushButton" name="uninstall_button">
<property name="styleSheet">
<string notr="true">background-color: #900</string>
<string notr="true"/>
</property>
<property name="text">
<string>Uninstall Game</string>
@ -347,7 +347,7 @@
<item>
<widget class="QPushButton" name="install_button">
<property name="styleSheet">
<string notr="true">background-color: #090</string>
<string notr="true"/>
</property>
<property name="text">
<string>Install Game</string>

View file

@ -6,7 +6,7 @@ from PyQt5.QtWidgets import QLayout, QStyle, QSizePolicy, QLabel, QFileDialog, Q
QStyleOptionTab, QStylePainter, QTabBar
from qtawesome import icon
from rare import style_path
from rare import resources_path
from rare.ui.utils.pathedit import Ui_PathEdit
@ -163,7 +163,7 @@ class PathEdit(QWidget, Ui_PathEdit):
dlg_path = self.text_edit.text()
if not dlg_path:
dlg_path = os.path.expanduser("~/")
dlg = QFileDialog(self, self.tr("Choose Path"), dlg_path)
dlg = QFileDialog(self, self.tr("Choose path"), dlg_path)
dlg.setFileMode(self.file_type)
if self.type_filter:
dlg.setFilter([self.type_filter])
@ -213,7 +213,7 @@ class WaitingSpinner(QLabel):
margin-left: auto;
margin-right: auto;
""")
self.movie = QMovie(os.path.join(style_path, "loader.gif"))
self.movie = QMovie(os.path.join(resources_path, "images", "loader.gif"))
self.setMovie(self.movie)
self.movie.start()

View file

@ -1,37 +1,38 @@
import os
from custom_legendary.models.downloading import ConditionCheckResult
from dataclasses import field, dataclass
from multiprocessing import Queue
from custom_legendary.downloader.manager import DLManager
from custom_legendary.models.downloading import AnalysisResult
from custom_legendary.models.game import Game, InstalledGame
class InstallOptionsModel:
def __init__(self, app_name: str, base_path: str = os.path.expanduser("~/legendary"),
max_workers: int = os.cpu_count() * 2, repair: bool = False, no_install: bool = False,
ignore_space_req: bool = False, force: bool = False, sdl_list: list = ['']
):
self.app_name = app_name
self.base_path = base_path
self.max_workers = max_workers
self.repair = repair
self.no_install = no_install
self.ignore_space_req = ignore_space_req
self.force = force
self.sdl_list = sdl_list
app_name: str
base_path: str = os.path.expanduser("~/legendary")
max_workers: int = os.cpu_count() * 2
repair: bool = False
no_install: bool = False
ignore_space_req: bool = False
force: bool = False
sdl_list: list[str] = field(default_factory=lambda: [''])
@dataclass
class InstallDownloadModel:
def __init__(self, dlmanager, analysis, game, igame, repair: bool, repair_file: str, res: ConditionCheckResult):
self.dlmanager = dlmanager
self.analysis = analysis
self.game = game
self.igame = igame
self.repair = repair
self.repair_file = repair_file
self.res = res
dlmanager: DLManager
analysis: AnalysisResult
game: Game
igame: InstalledGame
repair: bool
repair_file: str
@dataclass
class InstallQueueItemModel:
def __init__(self, status_q=None, download: InstallDownloadModel = None, options: InstallOptionsModel = None):
self.status_q = status_q
self.download = download
self.options = options
status_q: Queue = None
download: InstallDownloadModel = None
options: InstallOptionsModel = None
def __bool__(self):
return (self.status_q is not None) and (self.download is not None) and (self.options is not None)

View file

@ -15,14 +15,14 @@ from PyQt5.QtGui import QPalette, QColor
if platform.system() == "Windows":
from win32com.client import Dispatch
from rare import lang_path, style_path, data_dir
from rare import languages_path, resources_path
# Mac not supported
from custom_legendary.core import LegendaryCore
logger = getLogger("Utils")
s = QSettings("Rare", "Rare")
IMAGE_DIR = os.path.join(data_dir, "images")
IMAGE_DIR = s.value("img_dir", os.path.expanduser("~/.cache/rare/images"), type=str)
def download_images(signal: pyqtSignal, core: LegendaryCore):
@ -79,14 +79,14 @@ def download_image(game, force=False):
logger.warning(e)
# scale and grey
if not os.path.isfile(f'{IMAGE_DIR}/' + game.app_name + '/UninstalledArt.png'):
if not os.path.exists(os.path.join(IMAGE_DIR, game.app_name + '/UninstalledArt.png')):
if os.path.isfile(f'{IMAGE_DIR}/' + game.app_name + '/DieselGameBoxTall.png'):
if os.path.exists(os.path.join(IMAGE_DIR, f"{game.app_name}/DieselGameBoxTall.png")):
# finalArt = Image.open(f'{IMAGE_DIR}/' + game.app_name + '/DieselGameBoxTall.png')
# finalArt.save(f'{IMAGE_DIR}/{game.app_name}/FinalArt.png')
# And same with the grayscale one
bg = Image.open(f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxTall.png")
bg = Image.open(os.path.join(IMAGE_DIR, f"{game.app_name}/DieselGameBoxTall.png"))
uninstalledArt = bg.convert('L')
uninstalledArt = uninstalledArt.resize((200, int(200 * 4 / 3)))
uninstalledArt.save(f'{IMAGE_DIR}/{game.app_name}/UninstalledArt.png')
@ -182,23 +182,23 @@ def load_color_scheme(path: str):
def get_color_schemes():
colors = []
for file in os.listdir(os.path.join(style_path, "colors")):
if file.endswith(".scheme") and os.path.isfile(os.path.join(style_path, "colors", file)):
for file in os.listdir(os.path.join(resources_path, "colors")):
if file.endswith(".scheme") and os.path.isfile(os.path.join(resources_path, "colors", file)):
colors.append(file.replace(".scheme", ""))
return colors
def get_style_sheets():
styles = []
for file in os.listdir(os.path.join(style_path, "qss")):
if file.endswith(".qss") and os.path.isfile(os.path.join(style_path, "qss", file)):
styles.append(file.replace(".qss", ""))
for folder in os.listdir(os.path.join(resources_path, "stylesheets")):
if os.path.isfile(os.path.join(resources_path, "stylesheets", folder, "stylesheet.qss")):
styles.append(folder)
return styles
def get_possible_langs():
langs = ["en"]
for i in os.listdir(lang_path):
for i in os.listdir(languages_path):
if i.endswith(".qm"):
langs.append(i.split(".")[0])
return langs
@ -234,7 +234,7 @@ def create_rare_desktop_link(type_of_link):
desktop_file.write("[Desktop Entry]\n"
f"Name=Rare\n"
f"Type=Application\n"
f"Icon={os.path.join(style_path, 'Logo.png')}\n"
f"Icon={os.path.join(resources_path, 'images', 'Rare.png')}\n"
f"Exec={os.path.abspath(sys.argv[0])}\n"
"Terminal=false\n"
"StartupWMClass=rare\n"
@ -268,7 +268,7 @@ def create_rare_desktop_link(type_of_link):
shortcut.WorkingDirectory = os.getcwd()
# Icon
shortcut.IconLocation = os.path.join(style_path, "Logo.ico")
shortcut.IconLocation = os.path.join(resources_path, "images", "Rare.ico")
shortcut.save()
@ -305,7 +305,6 @@ def create_desktop_link(app_name, core: LegendaryCore, type_of_link="desktop") -
)
desktop_file.close()
os.chmod(os.path.expanduser(f"{path}{igame.title}.desktop"), 0o755)
return True
# Windows
elif platform.system() == "Windows":