1
0
Fork 0
mirror of synced 2024-06-10 22:54:41 +12:00

Merge pull request #137 from Dummerle/multi-platform

Add support for MacOS and 32 bit games
+ Fix many bugs
This commit is contained in:
Dummerle 2021-12-07 19:12:49 +01:00 committed by GitHub
commit 37e3c624ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 624 additions and 448 deletions

@ -1 +1 @@
Subproject commit 857de50b4e3a05b05de3403d29700af1c83a3144
Subproject commit 1aa43e44e1fe0e5c776b6a217df218240c7dbac2

View file

@ -1,4 +1,5 @@
import os
import platform
from multiprocessing import Queue as MPQueue
from PyQt5.QtCore import Qt, QObject, QRunnable, QThreadPool, pyqtSignal, pyqtSlot
@ -59,6 +60,20 @@ class InstallDialog(QDialog, Ui_InstallDialog):
self.warn_label.setVisible(False)
self.warn_message.setVisible(False)
platforms = ["Windows"]
if dl_item.options.app_name in shared.api_results.bit32_games:
platforms.append("Win32")
if dl_item.options.app_name in shared.api_results.mac_games:
platforms.append("Mac")
self.platform_combo_box.addItems(platforms)
self.platform_combo_box.currentIndexChanged.connect(lambda: self.option_changed(None))
self.platform_combo_box.currentIndexChanged.connect(lambda i: QMessageBox.warning(self, "Warning", self.tr(
"You will not be able to run the Game if you choose {}").format(self.platform_combo_box.itemText(i)))
if (self.platform_combo_box.currentText() == "Mac" and platform.system() != "Darwin") else None)
if platform.system() == "Darwin" and "Mac" in platforms:
self.platform_combo_box.setCurrentIndex(platforms.index("Mac"))
if self.core.lgd.config.has_option("Legendary", "max_workers"):
max_workers = self.core.lgd.config.get("Legendary", "max_workers")
else:
@ -110,6 +125,7 @@ class InstallDialog(QDialog, Ui_InstallDialog):
self.dl_item.options.force = self.force_download_check.isChecked()
self.dl_item.options.ignore_space_req = self.ignore_space_check.isChecked()
self.dl_item.options.no_install = self.download_only_check.isChecked()
self.dl_item.options.platform = self.platform_combo_box.currentText()
self.dl_item.options.sdl_list = ['']
for cb in self.sdl_list_checks:
if data := cb.isChecked():
@ -232,7 +248,7 @@ class InstallInfoWorker(QRunnable):
# override_manifest=,
# override_old_manifest=,
# override_base_url=,
# platform_override=,
platform=self.dl_item.options.platform,
# file_prefix_filter=,
# file_exclude_filter=,
# file_install_tag=,

View file

@ -49,10 +49,34 @@ class ApiRequestWorker(QRunnable):
self.signals.result.emit(result, text)
class AssetWorker(QRunnable):
def __init__(self):
super(AssetWorker, self).__init__()
self.signals = ApiSignals()
self.setAutoDelete(True)
self.assets = dict()
def run(self) -> None:
for platform in shared.core.get_installed_platforms():
self.assets.update({platform: self.get_asset(platform)})
self.signals.result.emit(self.assets, "assets")
@staticmethod
def get_asset(platform):
if not shared.core.egs.user:
return []
assets = [
GameAsset.from_egs_json(a) for a in
shared.core.egs.get_game_assets(platform=platform)
]
return assets
class LaunchDialog(QDialog, Ui_LaunchDialog):
quit_app = pyqtSignal(int)
start_app = pyqtSignal()
finished = False
finished = 0
def __init__(self, parent=None):
super(LaunchDialog, self).__init__(parent=parent)
@ -102,20 +126,23 @@ class LaunchDialog(QDialog, Ui_LaunchDialog):
api_requests = [
["32bit", self.core.get_game_and_dlc_list, (True, "Win32")],
["mac", self.core.get_game_and_dlc_list, (True, "Mac")],
["assets", self.core.egs.get_game_assets, ()],
]
# gamelist and no_asset games are from Image worker
worker = ApiRequestWorker(api_requests)
worker.signals.result.connect(self.handle_api_worker_result)
self.thread_pool.start(worker)
asset_worker = AssetWorker()
asset_worker.signals.result.connect(self.handle_api_worker_result)
self.thread_pool.start(asset_worker)
# cloud save from another worker, because it is used in cloud_save_utils too
cloud_worker = CloudWorker()
cloud_worker.signals.result_ready.connect(lambda x: self.handle_api_worker_result(x, "saves"))
self.thread_pool.start(cloud_worker)
else:
self.finished = True
self.finished = 2
self.api_results.game_list, self.api_results.dlcs = self.core.get_game_and_dlc_list(False)
self.finish()
@ -130,18 +157,16 @@ class LaunchDialog(QDialog, Ui_LaunchDialog):
self.api_results.bit32_games = [i.app_name for i in result[0]] if result else []
elif text == "mac":
self.api_results.mac_games = [i.app_name for i in result[0]] if result else []
elif text == "assets":
if not result:
assets = self.core.lgd.assets
else:
assets = [GameAsset.from_egs_json(a) for a in result]
self.core.lgd.assets = assets
self.api_results.assets = assets
elif text == "no_assets":
self.api_results.no_asset_games = result if result else []
elif text == "saves":
self.api_results.saves = result
elif text == "assets":
self.core.lgd.assets = result
self.finish()
return
if self.api_results:
self.finish()
@ -152,11 +177,11 @@ class LaunchDialog(QDialog, Ui_LaunchDialog):
self.finish()
def finish(self):
if self.finished:
if self.finished == 2:
logger.info("App starting")
self.image_info.setText(self.tr("Starting..."))
shared.args.offline = self.offline
shared.init_api_response(self.api_results)
self.start_app.emit()
else:
self.finished = True
self.finished += 1

View file

@ -1,13 +1,14 @@
import datetime
from logging import getLogger
from typing import List, Dict
from PyQt5.QtCore import QThread, pyqtSignal, QSettings
from PyQt5.QtWidgets import QWidget, QMessageBox, QVBoxLayout, QLabel, QPushButton, \
QGroupBox
from legendary.core import LegendaryCore
from legendary.models.downloading import UIUpdate
from legendary.models.game import Game, InstalledGame
from rare import shared
from rare.components.dialogs.install_dialog import InstallDialog
from rare.components.tabs.downloads.dl_queue_widget import DlQueueWidget, DlWidget
@ -21,7 +22,7 @@ logger = getLogger("Download")
class DownloadsTab(QWidget, Ui_DownloadsTab):
thread: QThread
dl_queue = list()
dl_queue: List[InstallQueueItemModel] = []
dl_status = pyqtSignal(int)
def __init__(self, updates: list):
@ -43,7 +44,7 @@ class DownloadsTab(QWidget, Ui_DownloadsTab):
self.update_layout = QVBoxLayout(self.updates)
self.queue_scroll_contents_layout.addWidget(self.updates)
self.update_widgets = {}
self.update_widgets: Dict[str, UpdateWidget] = {}
self.update_text = QLabel(self.tr("No updates available"))
self.update_layout.addWidget(self.update_text)
@ -59,6 +60,7 @@ class DownloadsTab(QWidget, Ui_DownloadsTab):
self.signals.game_uninstalled.connect(self.remove_update)
self.signals.add_download.connect(lambda app_name: self.add_update(self.core.get_installed_game(app_name)))
shared.signals.game_uninstalled.connect(self.game_uninstalled)
self.reset_infos()
@ -75,6 +77,23 @@ class DownloadsTab(QWidget, Ui_DownloadsTab):
if QSettings().value("auto_update", False, bool):
self.get_install_options(InstallOptionsModel(app_name=igame.app_name, update=True, silent=True))
widget.update_button.setDisabled(True)
self.update_text.setVisible(False)
def game_uninstalled(self, app_name):
# game in dl_queue
for i, item in enumerate(self.dl_queue):
if item.options.app_name == app_name:
self.dl_queue.pop(i)
self.queue_widget.update_queue(self.dl_queue)
break
# game has available update
if app_name in self.update_widgets.keys():
self.remove_update(app_name)
# if game is updating
if self.active_game and self.active_game.app_name == app_name:
self.stop_download()
def remove_update(self, app_name):
if w := self.update_widgets.get(app_name):
@ -128,10 +147,9 @@ class DownloadsTab(QWidget, Ui_DownloadsTab):
self.queue_widget.update_queue(self.dl_queue)
if game.app_name in self.update_widgets.keys():
self.update_widgets[game.app_name].setVisible(False)
self.update_widgets.pop(game.app_name)
if len(self.update_widgets) == 0:
self.update_text.setVisible(True)
igame = self.core.get_installed_game(game.app_name)
if self.core.get_asset(game.app_name, igame.platform, False).build_version == igame.version:
self.remove_update(game.app_name)
self.signals.send_notification.emit(game.app_title)
self.signals.update_gamelist.emit([game.app_name])
@ -207,10 +225,10 @@ class DownloadsTab(QWidget, Ui_DownloadsTab):
class UpdateWidget(QWidget):
update_signal = pyqtSignal(InstallOptionsModel)
def __init__(self, core: LegendaryCore, game: InstalledGame, parent):
def __init__(self, core: LegendaryCore, igame: InstalledGame, parent):
super(UpdateWidget, self).__init__(parent=parent)
self.core = core
self.game = game
self.game = igame
self.layout = QVBoxLayout()
self.title = QLabel(self.game.title)
@ -223,8 +241,8 @@ class UpdateWidget(QWidget):
self.layout.addWidget(self.update_button)
self.layout.addWidget(self.update_with_settings)
self.layout.addWidget(QLabel(
self.tr("Version: ") + self.game.version + " -> " + self.core.get_asset(self.game.app_name,
True).build_version))
self.tr("Version: ") + self.game.version + " -> " +
self.core.get_asset(self.game.app_name, self.game.platform, True).build_version))
self.setLayout(self.layout)

View file

@ -1,4 +1,5 @@
from logging import getLogger
from typing import Tuple, Dict
from PyQt5.QtCore import QSettings, QObjectCleanupHandler
from PyQt5.QtGui import QImage, QPixmap
@ -28,7 +29,7 @@ logger = getLogger("GamesTab")
class GamesTab(QStackedWidget, Ui_GamesTab):
widgets = dict()
widgets: Dict[str, Tuple[InstalledIconWidget, InstalledListWidget]] = dict()
running_games = list()
updates = set()
active_filter = 0
@ -130,8 +131,8 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
self.setCurrentIndex(2)
self.import_sync_tabs.show_egl_sync()
def show_game_info(self, game):
self.game_info_tabs.update_game(game)
def show_game_info(self, app_name):
self.game_info_tabs.update_game(app_name)
self.setCurrentIndex(1)
def show_uninstalled_info(self, game):
@ -237,7 +238,7 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
visible = False
elif filter_name == "32bit" and self.bit32:
visible = w.game.app_name in self.bit32
elif filter_name == "mac":
elif filter_name == "mac" and self.mac_games:
visible = w.game.app_name in self.mac_games
elif filter_name == "installable":
visible = w.game.app_name not in self.no_asset_names
@ -263,7 +264,7 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
igame = self.core.get_installed_game(app_name)
for w in widgets:
w.igame = igame
w.update_available = self.core.get_asset(w.game.app_name,
w.update_available = self.core.get_asset(w.game.app_name, w.igame.platform,
True).build_version != igame.version
widgets[0].leaveEvent(None)
# new installed

View file

@ -80,8 +80,8 @@ class CloudSaveDialog(QDialog, Ui_SyncSaveDialog):
self.title_label.setText(self.title_label.text() + igame.title)
self.date_info_local.setText(dt_local.strftime("%A, %d. %B %Y %I:%M%p"))
self.date_info_remote.setText(dt_remote.strftime("%A, %d. %B %Y %I:%M%p"))
self.date_info_local.setText(dt_local.strftime("%A, %d. %B %Y %X"))
self.date_info_remote.setText(dt_remote.strftime("%A, %d. %B %Y %X"))
new_text = self.tr(" (newer)")
if newer == "remote":

View file

@ -2,7 +2,6 @@ from PyQt5.QtCore import Qt
from PyQt5.QtGui import QKeyEvent
import rare.shared as shared
from legendary.models.game import Game
from rare.utils.extra_widgets import SideTabWidget
from .game_dlc import GameDlc
from .game_info import GameInfo
@ -28,17 +27,17 @@ class GameInfoTabs(SideTabWidget):
self.tabBar().setCurrentIndex(1)
def update_game(self, game: Game):
def update_game(self, app_name: str):
self.setCurrentIndex(1)
self.info.update_game(game)
self.settings.update_game(game)
self.info.update_game(app_name)
self.settings.update_game(app_name)
# DLC Tab: Disable if no dlcs available
if len(self.dlc_list[game.asset_info.catalog_item_id]) == 0:
if len(self.dlc_list[self.core.get_game(app_name).catalog_item_id]) == 0:
self.setTabEnabled(3, False)
else:
self.setTabEnabled(3, True)
self.dlc.update_dlcs(game.app_name)
self.dlc.update_dlcs(app_name)
def keyPressEvent(self, e: QKeyEvent):
if e.key() == Qt.Key_Escape:

View file

@ -31,7 +31,7 @@ class GameDlc(QWidget, Ui_GameDlc):
def update_dlcs(self, app_name):
self.game = self.core.get_game(app_name)
dlcs = self.dlcs[self.game.asset_info.catalog_item_id]
dlcs = self.dlcs[self.game.catalog_item_id]
self.game_title.setText(f"<h2>{self.game.app_title}</h2>")
if self.installed_dlc_widgets:
@ -43,8 +43,8 @@ class GameDlc(QWidget, Ui_GameDlc):
dlc_widget.install.disconnect()
dlc_widget.deleteLater()
self.available_dlc_widgets.clear()
for dlc in sorted(dlcs, key=lambda x: x.app_title):
for dlc in sorted(dlcs, key=lambda x: x.app_title):
if self.core.is_installed(dlc.app_name):
dlc_widget = GameDlcWidget(dlc, True)
self.installed_dlc_contents_layout.addWidget(dlc_widget)
@ -86,7 +86,7 @@ class GameDlcWidget(QFrame, Ui_GameDlcWidget):
self.dlc = dlc
self.dlc_name.setText(dlc.app_title)
self.version.setText(dlc.app_version)
self.version.setText(dlc.app_version())
self.app_name.setText(dlc.app_name)
self.pixmap = get_pixmap(dlc.app_name)

View file

@ -92,6 +92,9 @@ class GameInfo(QWidget, Ui_GameInfo):
igame.needs_verification = False
self.core.lgd.set_installed_game(self.igame.app_name, igame)
self.verification_finished.emit(igame)
elif failed == missing == -1:
QMessageBox.warning(self, "Warning", self.tr("Something went wrong"))
else:
ans = QMessageBox.question(self, "Summary", self.tr(
'Verification failed, {} file(s) corrupted, {} file(s) are missing. Do you want to repair them?').format(
@ -102,18 +105,21 @@ class GameInfo(QWidget, Ui_GameInfo):
self.verify_widget.setCurrentIndex(0)
self.verify_threads.pop(app_name)
def update_game(self, game: Game):
self.game = game
self.igame = self.core.get_installed_game(game.app_name)
def update_game(self, app_name: str):
self.game = self.core.get_game(app_name)
self.igame = self.core.get_installed_game(self.game.app_name)
self.game_title.setText(f'<h2>{self.game.app_title}</h2>')
pixmap = get_pixmap(game.app_name)
pixmap = get_pixmap(self.game.app_name)
w = 200
pixmap = pixmap.scaled(w, int(w * 4 / 3))
self.image.setPixmap(pixmap)
self.app_name.setText(self.game.app_name)
self.version.setText(self.game.app_version)
if self.igame:
self.version.setText(self.igame.version)
else:
self.version.setText(self.game.app_version(self.igame.platform if self.igame else "Windows"))
self.dev.setText(self.game.metadata["developer"])
if self.igame:
@ -121,9 +127,11 @@ class GameInfo(QWidget, Ui_GameInfo):
self.install_path.setText(self.igame.install_path)
self.install_size.setVisible(True)
self.install_path.setVisible(True)
self.platform.setText(self.igame.platform)
else:
self.install_size.setVisible(False)
self.install_path.setVisible(False)
self.platform.setText("Windows")
if not self.igame:
# origin game
@ -139,13 +147,13 @@ class GameInfo(QWidget, Ui_GameInfo):
if platform.system() != "Windows":
self.grade.setText(self.tr("Loading"))
self.steam_worker.set_app_name(game.app_name)
self.steam_worker.set_app_name(self.game.app_name)
QThreadPool.globalInstance().start(self.steam_worker)
if len(self.verify_threads.keys()) == 0 or not self.verify_threads.get(game.app_name):
if len(self.verify_threads.keys()) == 0 or not self.verify_threads.get(self.game.app_name):
self.verify_widget.setCurrentIndex(0)
elif self.verify_threads.get(game.app_name):
elif self.verify_threads.get(self.game.app_name):
self.verify_widget.setCurrentIndex(1)
self.verify_progress.setValue(
self.verify_threads[game.app_name].num / self.verify_threads[game.app_name].total * 100
self.verify_threads[self.game.app_name].num / self.verify_threads[self.game.app_name].total * 100
)

View file

@ -111,10 +111,8 @@ class GameSettings(QWidget, Ui_GameSettings):
self.linux_settings_contents_layout.addWidget(self.linux_settings)
self.linux_settings_contents_layout.setAlignment(Qt.AlignTop)
else:
self.game_settings_layout.setAlignment(Qt.AlignTop)
self.linux_settings_scroll.setVisible(False)
# skip_update_check
self.game_settings_layout.setAlignment(Qt.AlignTop)
def compute_save_path(self):
if self.core.is_installed(self.game.app_name) and self.game.supports_cloud_saves:
@ -252,11 +250,10 @@ class GameSettings(QWidget, Ui_GameSettings):
self.core.lgd.config.set(self.game.app_name + ".env", "STEAM_COMPAT_DATA_PATH", text)
self.core.lgd.save_config()
def update_game(self, game: Game):
def update_game(self, app_name: str):
self.change = False
self.game = game
self.igame = self.core.get_installed_game(game.app_name)
app_name = game.app_name
self.game = self.core.get_game(app_name)
self.igame = self.core.get_installed_game(self.game.app_name)
if self.igame:
if self.igame.can_run_offline:
offline = self.core.lgd.config.get(self.game.app_name, "offline", fallback="unset")
@ -288,6 +285,11 @@ class GameSettings(QWidget, Ui_GameSettings):
if platform.system() != "Windows":
self.linux_settings.update_game(app_name)
if self.igame and self.igame.platform == "Mac":
self.linux_settings_scroll.setVisible(False)
else:
self.linux_settings_scroll.setVisible(True)
proton = self.core.lgd.config.get(f"{app_name}", "wrapper", fallback="").replace('"', "")
if proton and "proton" in proton:
self.proton_prefix.setEnabled(True)

View file

@ -74,6 +74,7 @@ class UninstalledInfo(QWidget, Ui_GameInfo):
self.game_actions_stack.setCurrentIndex(1)
self.game_actions_stack.resize(self.game_actions_stack.minimumSize())
self.lbl_platform.setText(self.tr("Platforms"))
def install_game(self):
self.signals.install_game.emit(InstallOptionsModel(app_name=self.game.app_name))
@ -81,6 +82,12 @@ class UninstalledInfo(QWidget, Ui_GameInfo):
def update_game(self, game: Game):
self.game = game
self.game_title.setText(f"<h2>{self.game.app_title}</h2>")
available_platforms = ["Windows"]
if self.game.app_name in shared.api_results.bit32_games:
available_platforms.append("32 Bit")
if self.game.app_name in shared.api_results.mac_games:
available_platforms.append("macOS")
self.platform.setText(", ".join(available_platforms))
pixmap = get_pixmap(game.app_name)
w = 200
@ -88,7 +95,7 @@ class UninstalledInfo(QWidget, Ui_GameInfo):
self.image.setPixmap(pixmap)
self.app_name.setText(self.game.app_name)
self.version.setText(self.game.app_version)
self.version.setText(self.game.app_version("Windows"))
self.dev.setText(self.game.metadata["developer"])
self.install_size.setText("N/A")
self.install_path.setText("N/A")

View file

@ -1,5 +1,6 @@
import os
import platform
import shutil
import webbrowser
from dataclasses import dataclass
from logging import getLogger
@ -134,7 +135,7 @@ class GameUtils(QObject):
if not skip_update_check and not self.core.is_noupdate_game(app_name):
# check updates
try:
latest = self.core.get_asset(app_name, update=False)
latest = self.core.get_asset(app_name, igame.platform, update=False)
except ValueError:
self.finished.emit(app_name, self.tr("Metadata doesn't exist"))
return
@ -161,6 +162,7 @@ class GameUtils(QObject):
environment.insert(env, value)
if platform.system() != "Windows":
# wine prefixes
for env in ["STEAM_COMPAT_DATA_PATH", "WINEPREFIX"]:
if val := full_env.get(env):
if not os.path.exists(val):
@ -168,18 +170,24 @@ class GameUtils(QObject):
os.makedirs(val)
except PermissionError as e:
logger.error(str(e))
if QMessageBox.question(None, "Error",
self.tr(
"Error while launching {}. No permission to create {} for {}\nLaunch anyway?").format(
game.app_title, val, env),
buttons=QMessageBox.Yes | QMessageBox.No,
defaultButton=QMessageBox.Yes) == QMessageBox.No:
process.deleteLater()
return
QMessageBox.warning(None, "Error",
self.tr(
"Error while launching {}. No permission to create {} for {}").format(
game.app_title, val, env))
process.deleteLater()
return
# check wine executable
if shutil.which(full_params[0]) is None:
# wine binary does not exist
QMessageBox.warning(None, "Warning", self.tr(
"Wine executable '{}' does not exist. Please change it in Settings").format(full_params[0]))
process.deleteLater()
return
process.setProcessEnvironment(environment)
process.game_finished.connect(self.game_finished)
running_game = RunningGameModel(process=process, app_name=app_name, always_ask_sync=ask_always_sync)
process.start(full_params[0], full_params[1:])
self.game_launched.emit(app_name)
logger.info(f"{game.app_title} launched")
@ -197,9 +205,18 @@ class GameUtils(QObject):
fallback=os.path.expanduser("~/.wine"))
if not wine_bin:
wine_bin = self.core.lgd.config.get(game.app_name, 'wine_executable', fallback="/usr/bin/wine")
if shutil.which(wine_bin) is None:
# wine binary does not exist
QMessageBox.warning(None, "Warning",
self.tr("Wine executable '{}' does not exist. Please change it in Settings").format(
wine_bin))
process.deleteLater()
return
env = self.core.get_app_environment(game.app_name, wine_pfx=wine_pfx)
if not wine_bin or not env.get('WINEPREFIX') and not os.path.exists("/usr/bin/wine"):
if not env.get('WINEPREFIX') and not os.path.exists("/usr/bin/wine"):
logger.error(f'In order to launch Origin correctly you must specify the wine binary and prefix '
f'to use in the configuration file or command line. See the README for details.')
self.finished.emit(app_name, self.tr("No wine executable selected. Please set it in settings"))
@ -215,14 +232,9 @@ class GameUtils(QObject):
if QSettings().value("show_console", False, bool):
self.console.show()
process.readyReadStandardOutput.connect(lambda: self.console.log(
bytes(process.readAllStandardOutput()).decode("utf-8", errors="ignore")))
str(process.readAllStandardOutput().data(), "utf-8", "ignore")))
process.readyReadStandardError.connect(lambda: self.console.error(
bytes(process.readAllStandardOutput()).decode("utf-8", errors="ignore")))
else:
process.readyReadStandardOutput.connect(
lambda: print(bytes(process.readAllStandardOutput()).decode("utf-8", errors="ignore")))
process.readyReadStandardError.connect(
lambda: print(bytes(process.readAllStandardError()).decode("utf-8", errors="ignore")))
str(process.readAllStandardError().data(), "utf-8", "ignore")))
def game_finished(self, exit_code, app_name):
logger.info("Game exited with exit code: " + str(exit_code))

View file

@ -6,7 +6,6 @@ from PyQt5.QtCore import pyqtSignal, QProcess, QSettings, Qt, QByteArray
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QGroupBox, QMessageBox, QAction, QLabel
from legendary.models.game import Game
from rare import shared
from rare.components.tabs.games.game_utils import GameUtils
from rare.utils import utils
@ -17,7 +16,7 @@ logger = getLogger("Game")
class BaseInstalledWidget(QGroupBox):
launch_signal = pyqtSignal(str, QProcess, list)
show_info = pyqtSignal(Game)
show_info = pyqtSignal(str)
finish_signal = pyqtSignal(str, int)
proc: QProcess()
@ -55,10 +54,12 @@ class BaseInstalledWidget(QGroupBox):
self.image.setPixmap(pixmap.scaled(200, int(200 * 4 / 3), transformMode=Qt.SmoothTransformation))
self.game_running = False
self.offline = shared.args.offline
if self.game.third_party_store == "Origin":
self.update_available = False
else:
self.update_available = self.core.get_asset(self.game.app_name, False).build_version != self.igame.version
self.update_available = False
if self.game.third_party_store != "Origin" or self.igame:
remote_version = self.core.get_asset(self.game.app_name, platform=self.igame.platform, update=False).build_version
if remote_version != self.igame.version:
self.update_available = True
self.data = QByteArray()
self.setContentsMargins(0, 0, 0, 0)
self.settings = QSettings()

View file

@ -49,7 +49,7 @@ class InstalledIconWidget(BaseInstalledWidget):
self.menu_btn.setObjectName("menu_button")
self.menu_btn.clicked.connect(lambda: self.show_info.emit(self.game))
self.menu_btn.clicked.connect(lambda: self.show_info.emit(self.game.app_name))
self.menu_btn.setFixedWidth(17)
minilayout.addWidget(self.menu_btn)
minilayout.addStretch(1)
@ -86,6 +86,8 @@ class InstalledIconWidget(BaseInstalledWidget):
self.info_label.setText(self.texts["default"]["syncing"])
elif self.update_available:
self.info_label.setText(self.texts["default"]["update_available"])
elif self.igame and self.igame.needs_verification:
self.info_label.setText(self.texts["needs_verification"])
else:
self.info_label.setText("")

View file

@ -1,10 +1,11 @@
from logging import getLogger
from PyQt5.QtCore import QProcess, pyqtSignal
from PyQt5.QtCore import QProcess, pyqtSignal, Qt
from PyQt5.QtWidgets import QHBoxLayout, QLabel, QPushButton, QVBoxLayout
from qtawesome import icon
from rare.components.tabs.games.game_widgets.base_installed_widget import BaseInstalledWidget
from rare.utils.utils import get_size
logger = getLogger("GameWidget")
@ -19,17 +20,16 @@ class InstalledListWidget(BaseInstalledWidget):
self.dev = self.game.metadata["developer"]
if self.game.third_party_store != "Origin":
self.size = self.igame.install_size
self.launch_params = self.igame.launch_parameters
else:
self.size = 0
self.launch_params = ""
self.layout = QHBoxLayout()
self.setLayout(self.layout)
self.layout.addWidget(self.image)
##Layout on the right
self.childLayout = QVBoxLayout()
self.layout.addWidget(self.image)
self.layout.addLayout(self.childLayout)
play_icon = icon("ei.play")
self.title_label = QLabel(f"<h1>{self.game.app_title}</h1>")
@ -41,7 +41,7 @@ class InstalledListWidget(BaseInstalledWidget):
self.launch_button.setFixedWidth(150)
self.info = QPushButton("Info")
self.info.clicked.connect(lambda: self.show_info.emit(self.game))
self.info.clicked.connect(lambda: self.show_info.emit(self.game.app_name))
self.info.setFixedWidth(80)
self.info_label = QLabel("")
@ -57,15 +57,13 @@ class InstalledListWidget(BaseInstalledWidget):
self.childLayout.addWidget(self.developer_label)
if not self.is_origin:
self.version_label = QLabel("Version: " + str(self.igame.version))
self.size_label = QLabel(f"{self.tr('Installed size')}: {round(self.size / (1024 ** 3), 2)} GB")
self.size_label = QLabel(f"{self.tr('Installed size')}: {get_size(self.size)}")
self.childLayout.addWidget(self.version_label)
self.childLayout.addWidget(self.size_label)
self.childLayout.addStretch(1)
self.layout.addLayout(self.childLayout)
self.layout.addStretch(1)
self.setLayout(self.layout)
self.childLayout.setAlignment(Qt.AlignTop)
self.layout.setAlignment(Qt.AlignLeft)
self.game_utils.cloud_save_finished.connect(self.sync_finished)
self.game_utils.finished.connect(self.game_finished)

View file

@ -1,5 +1,6 @@
from logging import getLogger
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QLabel, QHBoxLayout, QVBoxLayout, QPushButton
from legendary.core import LegendaryCore
@ -13,24 +14,21 @@ class ListWidgetUninstalled(BaseUninstalledWidget):
def __init__(self, core: LegendaryCore, game, pixmap):
super(ListWidgetUninstalled, self).__init__(game, core, pixmap)
self.layout = QHBoxLayout()
self.setLayout(self.layout)
self.layout.addWidget(self.image)
self.child_layout = QVBoxLayout()
self.layout.addLayout(self.child_layout)
self.title_label = QLabel(f"<h2>{self.game.app_title}</h2>")
self.app_name_label = QLabel(f"App Name: {self.game.app_name}")
self.version_label = QLabel(f"Version: {self.game.app_version}")
self.install_button = QPushButton(self.tr("Install"))
self.install_button.setFixedWidth(120)
self.install_button.clicked.connect(self.install)
self.child_layout.addWidget(self.title_label)
self.child_layout.addWidget(self.app_name_label)
self.child_layout.addWidget(self.version_label)
self.child_layout.addWidget(self.install_button)
self.child_layout.addStretch(1)
self.layout.addLayout(self.child_layout)
self.layout.addStretch(1)
self.setLayout(self.layout)
self.layout.setAlignment(Qt.AlignLeft)
self.child_layout.setAlignment(Qt.AlignTop)

View file

@ -21,10 +21,11 @@ class GameListHeadBar(QWidget):
self.tr("Installed only"),
self.tr("Offline Games"),
self.tr("32 Bit Games"),
self.tr("Mac games"),
self.tr("Exclude Origin")])
self.layout().addWidget(self.filter)
self.available_filters = ["all", "installed", "offline", "32bit", "installable"]
self.available_filters = ["all", "installed", "offline", "32bit", "mac", "installable"]
try:
self.filter.setCurrentIndex(self.settings.value("filter", 0, int))

View file

@ -127,11 +127,10 @@ class ImportGroup(QGroupBox, Ui_ImportGroup):
for i in os.listdir(os.path.join(path, ".egstore")):
if i.endswith(".mancpn"):
file = os.path.join(path, ".egstore", i)
break
return json.load(open(file, "r")).get("AppName")
else:
logger.warning("File was not found")
return None
return json.load(open(file, "r"))["AppName"]
def import_game(self, path=None):
app_name = self.app_name.text()
@ -145,20 +144,18 @@ class ImportGroup(QGroupBox, Ui_ImportGroup):
self.info_label.setText(self.tr("Could not find app name"))
return
if legendary_utils.import_game(self.core, app_name=app_name, path=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 {}. Reload library").format(
igame.title))
self.info_label.setText(self.tr("Successfully imported {}").format(igame.title))
self.app_name.setText(str())
shared.signals.update_gamelist.emit([app_name])
if igame.version != self.core.get_asset(app_name, False).build_version:
if igame.version != self.core.get_asset(app_name, igame.platform, False).build_version:
# update available
shared.signals.add_download.emit(igame.app_name)
shared.signals.update_download_tab_text.emit()
else:
logger.warning(f'Failed to import "{app_name}"')
self.info_label.setText(self.tr("Failed to import {}").format(app_name))
self.info_label.setText(self.tr("Could not import {}: ").format(app_name) + err)
return

View file

@ -30,8 +30,7 @@ class Shop(QStackedWidget):
self.search_results = SearchResults(self.api_core)
self.addWidget(self.search_results)
self.search_results.show_info.connect(self.show_game_info)
self.info = ShopGameInfo([i.asset_info.namespace for i in shared.api_results.game_list], self.api_core)
self.info = ShopGameInfo([i.asset_infos["Windows"].namespace for i in shared.api_results.game_list], self.api_core)
self.addWidget(self.info)
self.info.back_button.clicked.connect(lambda: self.setCurrentIndex(0))

View file

@ -3,7 +3,7 @@ import webbrowser
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap, QFont
from PyQt5.QtWidgets import QWidget, QLabel, QPushButton, QHBoxLayout, QSpacerItem, QGroupBox
from PyQt5.QtWidgets import QWidget, QLabel, QPushButton, QHBoxLayout, QSpacerItem, QGroupBox, QTabWidget, QGridLayout
from qtawesome import icon
from rare import shared
@ -75,7 +75,9 @@ class ShopGameInfo(QWidget, Ui_shop_info):
self.open_store_button.setText(self.tr("Buy Game in Epic Games Store"))
self.owned_label.setVisible(False)
self.dev.setText(self.tr("Loading"))
for i in range(self.req_group_box.layout().count()):
self.req_group_box.layout().itemAt(i).widget().deleteLater()
self.price.setText(self.tr("Loading"))
self.wishlist_button.setVisible(False)
# self.title.setText(self.tr("Loading"))
@ -124,6 +126,7 @@ class ShopGameInfo(QWidget, Ui_shop_info):
self.dev.setText(self.data.get("seller", {}).get("name", ""))
return
self.title.setText(self.game.title)
self.price.setFont(QFont())
if self.game.price == "0" or self.game.price == 0:
self.price.setText(self.tr("Free"))
@ -141,22 +144,28 @@ class ShopGameInfo(QWidget, Ui_shop_info):
bold_font = QFont()
bold_font.setBold(True)
min_label = QLabel(self.tr("Minimum"))
min_label.setFont(bold_font)
rec_label = QLabel(self.tr("Recommend"))
rec_label.setFont(bold_font)
if self.game.reqs:
self.req_group_box.layout().addWidget(min_label, 0, 1)
self.req_group_box.layout().addWidget(rec_label, 0, 2)
for i, (key, value) in enumerate(self.game.reqs.get("Windows", {}).items()):
self.req_group_box.layout().addWidget(QLabel(key), i + 1, 0)
min_label = QLabel(value[0])
min_label.setWordWrap(True)
self.req_group_box.layout().addWidget(min_label, i + 1, 1)
rec_label = QLabel(value[1])
rec_label.setWordWrap(True)
self.req_group_box.layout().addWidget(rec_label, i + 1, 2)
req_tabs = QTabWidget()
for system in self.game.reqs:
min_label = QLabel(self.tr("Minimum"))
min_label.setFont(bold_font)
rec_label = QLabel(self.tr("Recommend"))
rec_label.setFont(bold_font)
req_widget = QWidget()
req_widget.setLayout(QGridLayout())
req_widget.layout().addWidget(min_label, 0, 1)
req_widget.layout().addWidget(rec_label, 0, 2)
for i, (key, value) in enumerate(self.game.reqs.get(system, {}).items()):
req_widget.layout().addWidget(QLabel(key), i + 1, 0)
min_label = QLabel(value[0])
min_label.setWordWrap(True)
req_widget.layout().addWidget(min_label, i + 1, 1)
rec_label = QLabel(value[1])
rec_label.setWordWrap(True)
req_widget.layout().addWidget(rec_label, i + 1, 2)
req_tabs.addTab(req_widget, system)
self.req_group_box.layout().addWidget(req_tabs)
else:
self.req_group_box.layout().addWidget(QLabel(self.tr("Could not get requirements")))
self.req_group_box.setVisible(True)

Binary file not shown.

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'rare/ui/components/dialogs/install_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,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_InstallDialog(object):
def setupUi(self, InstallDialog):
InstallDialog.setObjectName("InstallDialog")
InstallDialog.resize(324, 296)
InstallDialog.resize(340, 296)
InstallDialog.setWindowTitle("Rare")
self.install_dialog_layout = QtWidgets.QFormLayout(InstallDialog)
self.install_dialog_layout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
@ -62,7 +62,7 @@ class Ui_InstallDialog(object):
self.install_dialog_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.force_download_check)
self.ignore_space_label = QtWidgets.QLabel(InstallDialog)
self.ignore_space_label.setObjectName("ignore_space_label")
self.install_dialog_layout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.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)
@ -79,10 +79,10 @@ class Ui_InstallDialog(object):
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(4, QtWidgets.QFormLayout.FieldRole, self.ignore_space_layout)
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(5, QtWidgets.QFormLayout.LabelRole, self.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)
@ -100,10 +100,10 @@ class Ui_InstallDialog(object):
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(5, QtWidgets.QFormLayout.FieldRole, self.download_only_layout)
self.install_dialog_layout.setLayout(6, QtWidgets.QFormLayout.FieldRole, self.download_only_layout)
self.sdl_list_label = QtWidgets.QLabel(InstallDialog)
self.sdl_list_label.setObjectName("sdl_list_label")
self.install_dialog_layout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.sdl_list_label)
self.install_dialog_layout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.sdl_list_label)
self.sdl_list_frame = QtWidgets.QFrame(InstallDialog)
self.sdl_list_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.sdl_list_frame.setFrameShadow(QtWidgets.QFrame.Raised)
@ -111,35 +111,35 @@ class Ui_InstallDialog(object):
self.sdl_list_layout = QtWidgets.QVBoxLayout(self.sdl_list_frame)
self.sdl_list_layout.setSpacing(0)
self.sdl_list_layout.setObjectName("sdl_list_layout")
self.install_dialog_layout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.sdl_list_frame)
self.install_dialog_layout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.sdl_list_frame)
self.download_size_label = QtWidgets.QLabel(InstallDialog)
self.download_size_label.setObjectName("download_size_label")
self.install_dialog_layout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.download_size_label)
self.install_dialog_layout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.download_size_label)
self.download_size_info_label = QtWidgets.QLabel(InstallDialog)
font = QtGui.QFont()
font.setItalic(True)
self.download_size_info_label.setFont(font)
self.download_size_info_label.setObjectName("download_size_info_label")
self.install_dialog_layout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.download_size_info_label)
self.install_dialog_layout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.download_size_info_label)
self.install_size_label = QtWidgets.QLabel(InstallDialog)
self.install_size_label.setObjectName("install_size_label")
self.install_dialog_layout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.install_size_label)
self.install_dialog_layout.setWidget(9, QtWidgets.QFormLayout.LabelRole, self.install_size_label)
self.install_size_info_label = QtWidgets.QLabel(InstallDialog)
font = QtGui.QFont()
font.setItalic(True)
self.install_size_info_label.setFont(font)
self.install_size_info_label.setObjectName("install_size_info_label")
self.install_dialog_layout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.install_size_info_label)
self.install_dialog_layout.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.install_size_info_label)
self.warn_label = QtWidgets.QLabel(InstallDialog)
self.warn_label.setObjectName("warn_label")
self.install_dialog_layout.setWidget(9, QtWidgets.QFormLayout.LabelRole, self.warn_label)
self.install_dialog_layout.setWidget(10, QtWidgets.QFormLayout.LabelRole, self.warn_label)
self.warn_message = QtWidgets.QLabel(InstallDialog)
font = QtGui.QFont()
font.setItalic(True)
self.warn_message.setFont(font)
self.warn_message.setWordWrap(True)
self.warn_message.setObjectName("warn_message")
self.install_dialog_layout.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.warn_message)
self.install_dialog_layout.setWidget(10, QtWidgets.QFormLayout.FieldRole, self.warn_message)
self.button_layout = QtWidgets.QHBoxLayout()
self.button_layout.setObjectName("button_layout")
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
@ -153,7 +153,13 @@ class Ui_InstallDialog(object):
self.install_button = QtWidgets.QPushButton(InstallDialog)
self.install_button.setObjectName("install_button")
self.button_layout.addWidget(self.install_button)
self.install_dialog_layout.setLayout(12, QtWidgets.QFormLayout.SpanningRole, self.button_layout)
self.install_dialog_layout.setLayout(13, QtWidgets.QFormLayout.SpanningRole, self.button_layout)
self.platform_combo_box = QtWidgets.QComboBox(InstallDialog)
self.platform_combo_box.setObjectName("platform_combo_box")
self.install_dialog_layout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.platform_combo_box)
self.platform_label = QtWidgets.QLabel(InstallDialog)
self.platform_label.setObjectName("platform_label")
self.install_dialog_layout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.platform_label)
self.retranslateUi(InstallDialog)
QtCore.QMetaObject.connectSlotsByName(InstallDialog)
@ -179,6 +185,7 @@ class Ui_InstallDialog(object):
self.cancel_button.setText(_translate("InstallDialog", "Cancel"))
self.verify_button.setText(_translate("InstallDialog", "Verify"))
self.install_button.setText(_translate("InstallDialog", "Install"))
self.platform_label.setText(_translate("InstallDialog", "Platform"))
if __name__ == "__main__":

View file

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>324</width>
<width>340</width>
<height>296</height>
</rect>
</property>
@ -87,14 +87,14 @@
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="ignore_space_label">
<property name="text">
<string>Ignore free space</string>
</property>
</widget>
</item>
<item row="4" column="1">
<item row="5" column="1">
<layout class="QHBoxLayout" name="ignore_space_layout">
<item>
<widget class="QCheckBox" name="ignore_space_check">
@ -120,14 +120,14 @@
</item>
</layout>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QLabel" name="download_only_label">
<property name="text">
<string>Download only</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<layout class="QHBoxLayout" name="download_only_layout">
<item>
<widget class="QCheckBox" name="download_only_check">
@ -156,14 +156,14 @@
</item>
</layout>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QLabel" name="sdl_list_label">
<property name="text">
<string>Optional packs</string>
</property>
</widget>
</item>
<item row="6" column="1">
<item row="7" column="1">
<widget class="QFrame" name="sdl_list_frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
@ -178,14 +178,14 @@
</layout>
</widget>
</item>
<item row="7" column="0">
<item row="8" column="0">
<widget class="QLabel" name="download_size_label">
<property name="text">
<string>Download size</string>
</property>
</widget>
</item>
<item row="7" column="1">
<item row="8" column="1">
<widget class="QLabel" name="download_size_info_label">
<property name="font">
<font>
@ -197,14 +197,14 @@
</property>
</widget>
</item>
<item row="8" column="0">
<item row="9" column="0">
<widget class="QLabel" name="install_size_label">
<property name="text">
<string>Total install size</string>
</property>
</widget>
</item>
<item row="8" column="1">
<item row="9" column="1">
<widget class="QLabel" name="install_size_info_label">
<property name="font">
<font>
@ -216,14 +216,14 @@
</property>
</widget>
</item>
<item row="9" column="0">
<item row="10" column="0">
<widget class="QLabel" name="warn_label">
<property name="text">
<string>Warnings</string>
</property>
</widget>
</item>
<item row="9" column="1">
<item row="10" column="1">
<widget class="QLabel" name="warn_message">
<property name="font">
<font>
@ -238,7 +238,7 @@
</property>
</widget>
</item>
<item row="12" column="0" colspan="2">
<item row="13" column="0" colspan="2">
<layout class="QHBoxLayout" name="button_layout">
<item>
<spacer name="button_hspacer">
@ -276,6 +276,16 @@
</item>
</layout>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="platform_combo_box"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="platform_label">
<property name="text">
<string>Platform</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'rare/ui/components/tabs/games/game_info/game_info.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.
@ -21,11 +21,16 @@ class Ui_GameInfo(object):
self.layout_game_info_form.setContentsMargins(6, 6, 6, 6)
self.layout_game_info_form.setSpacing(12)
self.layout_game_info_form.setObjectName("layout_game_info_form")
self.install_size = QtWidgets.QLabel(GameInfo)
self.install_size.setText("error")
self.install_size.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
self.install_size.setObjectName("install_size")
self.layout_game_info_form.addWidget(self.install_size, 4, 1, 1, 1)
spacerItem = QtWidgets.QSpacerItem(20, 0, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.layout_game_info_form.addItem(spacerItem, 9, 0, 1, 1)
self.lbl_platform = QtWidgets.QLabel(GameInfo)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.lbl_platform.setFont(font)
self.lbl_platform.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
self.lbl_platform.setObjectName("lbl_platform")
self.layout_game_info_form.addWidget(self.lbl_platform, 6, 0, 1, 1)
self.lbl_dev = QtWidgets.QLabel(GameInfo)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
@ -42,19 +47,7 @@ class Ui_GameInfo(object):
self.version.setText("error")
self.version.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
self.version.setObjectName("version")
self.layout_game_info_form.addWidget(self.version, 2, 1, 1, 1)
self.lbl_install_path = QtWidgets.QLabel(GameInfo)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lbl_install_path.sizePolicy().hasHeightForWidth())
self.lbl_install_path.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.lbl_install_path.setFont(font)
self.lbl_install_path.setObjectName("lbl_install_path")
self.layout_game_info_form.addWidget(self.lbl_install_path, 5, 0, 1, 1, QtCore.Qt.AlignRight)
self.layout_game_info_form.addWidget(self.version, 2, 2, 1, 1)
self.lbl_install_size = QtWidgets.QLabel(GameInfo)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
@ -67,74 +60,6 @@ class Ui_GameInfo(object):
self.lbl_install_size.setFont(font)
self.lbl_install_size.setObjectName("lbl_install_size")
self.layout_game_info_form.addWidget(self.lbl_install_size, 4, 0, 1, 1, QtCore.Qt.AlignRight)
spacerItem = QtWidgets.QSpacerItem(0, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.layout_game_info_form.addItem(spacerItem, 7, 1, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(20, 0, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.layout_game_info_form.addItem(spacerItem1, 7, 0, 1, 1)
self.lbl_version = QtWidgets.QLabel(GameInfo)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lbl_version.sizePolicy().hasHeightForWidth())
self.lbl_version.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.lbl_version.setFont(font)
self.lbl_version.setObjectName("lbl_version")
self.layout_game_info_form.addWidget(self.lbl_version, 2, 0, 1, 1, QtCore.Qt.AlignRight)
self.lbl_app_name = QtWidgets.QLabel(GameInfo)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lbl_app_name.sizePolicy().hasHeightForWidth())
self.lbl_app_name.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.lbl_app_name.setFont(font)
self.lbl_app_name.setObjectName("lbl_app_name")
self.layout_game_info_form.addWidget(self.lbl_app_name, 1, 0, 1, 1, QtCore.Qt.AlignRight)
self.dev = QtWidgets.QLabel(GameInfo)
self.dev.setText("error")
self.dev.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
self.dev.setObjectName("dev")
self.layout_game_info_form.addWidget(self.dev, 0, 1, 1, 1)
self.app_name = QtWidgets.QLabel(GameInfo)
self.app_name.setText("error")
self.app_name.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
self.app_name.setObjectName("app_name")
self.layout_game_info_form.addWidget(self.app_name, 1, 1, 1, 1)
self.install_path = QtWidgets.QLabel(GameInfo)
self.install_path.setText("error")
self.install_path.setWordWrap(True)
self.install_path.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
self.install_path.setObjectName("install_path")
self.layout_game_info_form.addWidget(self.install_path, 5, 1, 1, 1)
self.lbl_game_actions = QtWidgets.QLabel(GameInfo)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lbl_game_actions.sizePolicy().hasHeightForWidth())
self.lbl_game_actions.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.lbl_game_actions.setFont(font)
self.lbl_game_actions.setObjectName("lbl_game_actions")
self.layout_game_info_form.addWidget(self.lbl_game_actions, 6, 0, 1, 1, QtCore.Qt.AlignRight)
self.lbl_grade = QtWidgets.QLabel(GameInfo)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.lbl_grade.setFont(font)
self.lbl_grade.setObjectName("lbl_grade")
self.layout_game_info_form.addWidget(self.lbl_grade, 3, 0, 1, 1, QtCore.Qt.AlignRight)
self.grade = QtWidgets.QLabel(GameInfo)
self.grade.setText("error")
self.grade.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
self.grade.setObjectName("grade")
self.layout_game_info_form.addWidget(self.grade, 3, 1, 1, 1)
self.game_actions_stack = QtWidgets.QStackedWidget(GameInfo)
self.game_actions_stack.setMinimumSize(QtCore.QSize(250, 0))
self.game_actions_stack.setObjectName("game_actions_stack")
@ -184,39 +109,127 @@ class Ui_GameInfo(object):
self.install_button.setObjectName("install_button")
self.uninstalled_layout.addWidget(self.install_button)
self.game_actions_stack.addWidget(self.uninstalled_page)
self.layout_game_info_form.addWidget(self.game_actions_stack, 6, 1, 1, 1, QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
self.layout_game_info_form.addWidget(self.game_actions_stack, 8, 2, 1, 1, QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
self.app_name = QtWidgets.QLabel(GameInfo)
self.app_name.setText("error")
self.app_name.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
self.app_name.setObjectName("app_name")
self.layout_game_info_form.addWidget(self.app_name, 1, 2, 1, 1)
self.dev = QtWidgets.QLabel(GameInfo)
self.dev.setText("error")
self.dev.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
self.dev.setObjectName("dev")
self.layout_game_info_form.addWidget(self.dev, 0, 2, 1, 1)
self.lbl_game_actions = QtWidgets.QLabel(GameInfo)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lbl_game_actions.sizePolicy().hasHeightForWidth())
self.lbl_game_actions.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.lbl_game_actions.setFont(font)
self.lbl_game_actions.setObjectName("lbl_game_actions")
self.layout_game_info_form.addWidget(self.lbl_game_actions, 8, 0, 1, 1, QtCore.Qt.AlignRight)
spacerItem1 = QtWidgets.QSpacerItem(0, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.layout_game_info_form.addItem(spacerItem1, 9, 2, 1, 1)
self.install_size = QtWidgets.QLabel(GameInfo)
self.install_size.setText("error")
self.install_size.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
self.install_size.setObjectName("install_size")
self.layout_game_info_form.addWidget(self.install_size, 4, 2, 1, 1)
self.grade = QtWidgets.QLabel(GameInfo)
self.grade.setText("error")
self.grade.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
self.grade.setObjectName("grade")
self.layout_game_info_form.addWidget(self.grade, 3, 2, 1, 1)
self.lbl_grade = QtWidgets.QLabel(GameInfo)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.lbl_grade.setFont(font)
self.lbl_grade.setObjectName("lbl_grade")
self.layout_game_info_form.addWidget(self.lbl_grade, 3, 0, 1, 1, QtCore.Qt.AlignRight)
self.lbl_install_path = QtWidgets.QLabel(GameInfo)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lbl_install_path.sizePolicy().hasHeightForWidth())
self.lbl_install_path.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.lbl_install_path.setFont(font)
self.lbl_install_path.setObjectName("lbl_install_path")
self.layout_game_info_form.addWidget(self.lbl_install_path, 5, 0, 1, 1, QtCore.Qt.AlignRight)
self.lbl_version = QtWidgets.QLabel(GameInfo)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lbl_version.sizePolicy().hasHeightForWidth())
self.lbl_version.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.lbl_version.setFont(font)
self.lbl_version.setObjectName("lbl_version")
self.layout_game_info_form.addWidget(self.lbl_version, 2, 0, 1, 1, QtCore.Qt.AlignRight)
self.lbl_app_name = QtWidgets.QLabel(GameInfo)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.lbl_app_name.sizePolicy().hasHeightForWidth())
self.lbl_app_name.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setBold(True)
font.setWeight(75)
self.lbl_app_name.setFont(font)
self.lbl_app_name.setObjectName("lbl_app_name")
self.layout_game_info_form.addWidget(self.lbl_app_name, 1, 0, 1, 1, QtCore.Qt.AlignRight)
self.install_path = QtWidgets.QLabel(GameInfo)
self.install_path.setText("error")
self.install_path.setWordWrap(True)
self.install_path.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
self.install_path.setObjectName("install_path")
self.layout_game_info_form.addWidget(self.install_path, 5, 2, 1, 1)
self.platform = QtWidgets.QLabel(GameInfo)
self.platform.setObjectName("platform")
self.layout_game_info_form.addWidget(self.platform, 6, 2, 1, 1)
self.layout_game_info.addLayout(self.layout_game_info_form, 2, 1, 1, 1)
self.game_title = QtWidgets.QLabel(GameInfo)
self.game_title.setText("error")
self.game_title.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
self.game_title.setObjectName("game_title")
self.layout_game_info.addWidget(self.game_title, 0, 0, 1, 3)
self.image = QtWidgets.QLabel(GameInfo)
self.image.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.image.setFrameShadow(QtWidgets.QFrame.Sunken)
self.image.setText("")
self.image.setObjectName("image")
self.layout_game_info.addWidget(self.image, 2, 0, 1, 1, QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
self.game_title = QtWidgets.QLabel(GameInfo)
self.game_title.setText("error")
self.game_title.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
self.game_title.setObjectName("game_title")
self.layout_game_info.addWidget(self.game_title, 0, 0, 1, 3)
self.retranslateUi(GameInfo)
self.game_actions_stack.setCurrentIndex(0)
self.game_actions_stack.setCurrentIndex(1)
self.verify_widget.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(GameInfo)
def retranslateUi(self, GameInfo):
_translate = QtCore.QCoreApplication.translate
GameInfo.setWindowTitle(_translate("GameInfo", "Game Info"))
self.lbl_platform.setText(_translate("GameInfo", "Platform"))
self.lbl_dev.setText(_translate("GameInfo", "Developer"))
self.lbl_install_path.setText(_translate("GameInfo", "Installation Path"))
self.lbl_install_size.setText(_translate("GameInfo", "Installation Size"))
self.lbl_version.setText(_translate("GameInfo", "Version"))
self.lbl_app_name.setText(_translate("GameInfo", "Application Name"))
self.lbl_game_actions.setText(_translate("GameInfo", "Actions"))
self.lbl_grade.setText(_translate("GameInfo", "ProtonDB Grade"))
self.verify_button.setText(_translate("GameInfo", "Verify Installation"))
self.repair_button.setText(_translate("GameInfo", "Repair Instalation"))
self.uninstall_button.setText(_translate("GameInfo", "Uninstall Game"))
self.install_button.setText(_translate("GameInfo", "Install Game"))
self.lbl_game_actions.setText(_translate("GameInfo", "Actions"))
self.lbl_grade.setText(_translate("GameInfo", "ProtonDB Grade"))
self.lbl_install_path.setText(_translate("GameInfo", "Installation Path"))
self.lbl_version.setText(_translate("GameInfo", "Version"))
self.lbl_app_name.setText(_translate("GameInfo", "Application Name"))
self.platform.setText(_translate("GameInfo", "error"))
if __name__ == "__main__":

View file

@ -31,13 +31,32 @@
<property name="spacing">
<number>12</number>
</property>
<item row="4" column="1">
<widget class="QLabel" name="install_size">
<property name="text">
<string notr="true">error</string>
<item row="9" column="0">
<spacer name="vs_game_info_form">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="0">
<widget class="QLabel" name="lbl_platform">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Platform</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
@ -60,7 +79,7 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="2" column="2">
<widget class="QLabel" name="version">
<property name="text">
<string notr="true">error</string>
@ -70,25 +89,6 @@
</property>
</widget>
</item>
<item row="5" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="lbl_install_path">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Installation Path</string>
</property>
</widget>
</item>
<item row="4" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="lbl_install_size">
<property name="sizePolicy">
@ -108,146 +108,7 @@
</property>
</widget>
</item>
<item row="7" column="1">
<spacer name="hs_game_info_form">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="7" column="0">
<spacer name="vs_game_info_form">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="lbl_version">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Version</string>
</property>
</widget>
</item>
<item row="1" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="lbl_app_name">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Application Name</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="dev">
<property name="text">
<string notr="true">error</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="app_name">
<property name="text">
<string notr="true">error</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="install_path">
<property name="text">
<string notr="true">error</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="6" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="lbl_game_actions">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Actions</string>
</property>
</widget>
</item>
<item row="3" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="lbl_grade">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>ProtonDB Grade</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="grade">
<property name="text">
<string notr="true">error</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="6" column="1" alignment="Qt::AlignLeft|Qt::AlignTop">
<item row="8" column="2" alignment="Qt::AlignLeft|Qt::AlignTop">
<widget class="QStackedWidget" name="game_actions_stack">
<property name="minimumSize">
<size>
@ -366,8 +227,180 @@
</widget>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="app_name">
<property name="text">
<string notr="true">error</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="dev">
<property name="text">
<string notr="true">error</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="8" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="lbl_game_actions">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Actions</string>
</property>
</widget>
</item>
<item row="9" column="2">
<spacer name="hs_game_info_form">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="2">
<widget class="QLabel" name="install_size">
<property name="text">
<string notr="true">error</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="grade">
<property name="text">
<string notr="true">error</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="3" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="lbl_grade">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>ProtonDB Grade</string>
</property>
</widget>
</item>
<item row="5" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="lbl_install_path">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Installation Path</string>
</property>
</widget>
</item>
<item row="2" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="lbl_version">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Version</string>
</property>
</widget>
</item>
<item row="1" column="0" alignment="Qt::AlignRight">
<widget class="QLabel" name="lbl_app_name">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Application Name</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="install_path">
<property name="text">
<string notr="true">error</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLabel" name="platform">
<property name="text">
<string notr="true">error</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="game_title">
<property name="text">
<string notr="true">error</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="2" column="0" alignment="Qt::AlignLeft|Qt::AlignTop">
<widget class="QLabel" name="image">
<property name="frameShape">
@ -381,16 +414,6 @@
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QLabel" name="game_title">
<property name="text">
<string notr="true">error</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>

View file

@ -100,7 +100,7 @@ class VerifyWorker(QRunnable):
update_manifest(self.app_name, self.core)
manifest_data, _ = self.core.get_installed_manifest(self.app_name)
if not manifest_data:
self.signals.summary.emit(0, 0, self.app_name)
self.signals.summary.emit(-1, -1, self.app_name)
return
manifest = self.core.load_manifest(manifest_data)
@ -160,27 +160,50 @@ class VerifyWorker(QRunnable):
self.signals.summary.emit(len(failed), len(missing), self.app_name)
def import_game(core: LegendaryCore, app_name: str, path: str):
def import_game(core: LegendaryCore, app_name: str, path: str) -> str:
_tr = QCoreApplication.translate
logger.info("Import " + app_name)
game = core.get_game(app_name)
game = core.get_game(app_name, update_meta=False)
if not game:
return _tr("LgdUtils", "Could not get game for {}").format(app_name)
if core.is_installed(app_name):
logger.error(f"{game.app_title} is already installed")
return _tr("LgdUtils", "{} is already installed").format(game.app_title)
if not os.path.exists(path):
logger.error("Path does not exist")
return _tr("LgdUtils", "Path does not exist")
manifest, igame = core.import_game(game, path)
exe_path = os.path.join(path, manifest.meta.launch_exe.lstrip('/'))
if not os.path.exists(exe_path):
logger.error(f"Launch Executable of {game.app_title} does not exist")
return _tr("LgdUtils", "Launch executable of {} does not exist").format(game.app_title)
if game.is_dlc:
release_info = game.metadata.get('mainGameItem', {}).get('releaseInfo')
if release_info:
main_game_appname = release_info[0]['appId']
main_game_title = game.metadata['mainGameItem']['title']
if not core.is_installed(main_game_appname):
return _tr("LgdUtils", "Game is a DLC, but {} is not installed").format(main_game_title)
else:
return _tr("LgdUtils", "Unable to get base game information for DLC")
total = len(manifest.file_manifest_list.elements)
found = sum(os.path.exists(os.path.join(path, f.filename))
for f in manifest.file_manifest_list.elements)
ratio = found / total
if not os.path.exists(exe_path):
logger.error(f"Game {game.app_title} failed to import")
return False
if ratio < 0.95:
logger.error(
"Game files are missing. It may be not the lates version ore it is corrupt")
return False
if ratio < 0.9:
logger.warning(
"Game files are missing. It may be not the latest version or it is corrupt")
# return False
core.install_game(igame)
if igame.needs_verification:
logger.info(logger.info(
f'NOTE: The game installation will have to be verified before it can be updated '
f'with legendary. Run "legendary repair {app_name}" to do so.'))
logger.info(f"{igame.title} needs verification")
logger.info("Successfully imported Game: " + game.app_title)
return True
return ""

View file

@ -23,6 +23,7 @@ class InstallOptionsModel:
sdl_list: list = field(default_factory=lambda: [''])
update: bool = False
silent: bool = False
platform: str = ""
def set_no_install(self, enabled: bool) -> None:
self.no_install = enabled
@ -98,7 +99,6 @@ class ApiResults:
dlcs: list = None
bit32_games: list = None
mac_games: list = None
assets: list = None
no_asset_games: list = None
saves: list = None
@ -107,7 +107,6 @@ class ApiResults:
and self.dlcs is not None \
and self.bit32_games is not None \
and self.mac_games is not None \
and self.assets is not None \
and self.no_asset_games is not None \
and self.saves is not None

View file

@ -13,7 +13,7 @@ import requests
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QRunnable, QSettings, Qt
from PyQt5.QtGui import QPalette, QColor, QPixmap, QImage
from PyQt5.QtWidgets import QApplication, QStyleFactory
from requests import HTTPError
from requests.exceptions import HTTPError
from legendary.models.game import Game
from .models import PathSpec
@ -474,3 +474,11 @@ class CloudWorker(QRunnable):
def get_raw_save_path(game: Game):
if game.supports_cloud_saves:
return game.metadata.get("customAttributes", {}).get("CloudSaveFolder", {}).get("value")
def get_default_platform(app_name):
if platform.system() != "Darwin" or app_name not in shared.api_results.mac_games:
return "Windows"
else:
return "Mac"