1
0
Fork 0
mirror of synced 2024-06-17 01:54:46 +12:00

Import Games: app_name, Game list: show num games

This commit is contained in:
Dummerle 2021-04-05 17:34:47 +02:00
parent 3525a4f106
commit 1f1ef3e24d
7 changed files with 223 additions and 58 deletions

View file

@ -20,7 +20,7 @@ class LaunchThread(QThread):
def run(self):
self.action.emit("Login")
self.action.emit("Downloading Images")
self.action.emit(self.tr("Downloading Images"))
download_images(self.download_progess, self.core)
self.action.emit("finish")

View file

@ -158,9 +158,6 @@ class DownloadTab(QWidget):
self.layout.addLayout(self.mini_layout)
self.installing_game_widget = QLabel(self.tr("No active Download"))
self.layout.addWidget(self.installing_game_widget)
self.update_title = QLabel(f"<h2>{self.tr('Updates')}</h2>")
self.update_title.setStyleSheet("""
QLabel{

View file

@ -5,10 +5,10 @@ from PyQt5.QtCore import Qt, pyqtSignal, QSettings
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import *
from Rare.Components.Tabs.Games.GameWidgets.UninstalledListWidget import ListWidgetUninstalled
from Rare.Components.Tabs.Games.GameWidgets.UninstalledIconWidget import IconWidgetUninstalled
from Rare.Components.Tabs.Games.GameWidgets.InstalledIconWidget import GameWidgetInstalled
from Rare.Components.Tabs.Games.GameWidgets.InstalledListWidget import InstalledListWidget
from Rare.Components.Tabs.Games.GameWidgets.UninstalledIconWidget import IconWidgetUninstalled
from Rare.Components.Tabs.Games.GameWidgets.UninstalledListWidget import ListWidgetUninstalled
from Rare.utils.Models import InstallOptions
from Rare.utils.QtExtensions import FlowLayout
from Rare.utils.utils import download_image
@ -42,8 +42,15 @@ class GameList(QStackedWidget):
self.list_scrollarea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.info_text = self.tr("Installed Games: {} Available Games: {}").format(
len(self.core.get_installed_list()),
len(self.core.get_game_list(update_assets=True)))
self.icon_parent_layout = QVBoxLayout()
self.icon_parent_layout.addWidget(QLabel(self.info_text))
self.icon_layout = FlowLayout()
self.list_layout = QVBoxLayout()
self.list_layout.addWidget(QLabel(self.info_text))
IMAGE_DIR = self.settings.value("img_dir", os.path.expanduser("~/.cache/rare"), str)
self.updates = []
@ -117,8 +124,9 @@ class GameList(QStackedWidget):
self.widgets[game.app_name] = (icon_widget, list_widget)
self.icon_parent_layout.addLayout(self.icon_layout)
self.list_layout.addStretch(1)
self.icon_widget.setLayout(self.icon_layout)
self.icon_widget.setLayout(self.icon_parent_layout)
self.list_widget.setLayout(self.list_layout)
self.icon_scrollarea.setWidget(self.icon_widget)

View file

@ -4,11 +4,12 @@ import string
from logging import getLogger
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtWidgets import QWidget, QLabel, QHBoxLayout, QPushButton, QVBoxLayout, QFileDialog, QMessageBox
from PyQt5.QtWidgets import QWidget, QLabel, QHBoxLayout, QPushButton, QVBoxLayout, QFileDialog, QMessageBox, QLineEdit
from qtawesome import icon
from Rare.utils import LegendaryApi
from Rare.utils.QtExtensions import PathEdit
from custom_legendary.core import LegendaryCore
logger = getLogger("Import")
@ -16,9 +17,11 @@ logger = getLogger("Import")
class ImportWidget(QWidget):
update_list = pyqtSignal()
def __init__(self, core):
def __init__(self, core: LegendaryCore):
super(ImportWidget, self).__init__()
self.core = core
self.game_list = [i.app_name for i in self.core.get_game_list()]
self.main_layout = QHBoxLayout()
self.back_button = QPushButton(icon("mdi.keyboard-backspace", color="white"), self.tr("Back"))
self.right_layout = QVBoxLayout()
@ -31,15 +34,31 @@ class ImportWidget(QWidget):
self.title = QLabel("<h2>Import Game</h2")
self.layout.addWidget(self.title)
self.import_one_game = QLabel(f"<h3>{self.tr('Import existing game')}</h3>")
self.import_one_game = QLabel(f"<h3>{self.tr('Import existing game from Epic Games Launcher')}</h3>")
self.layout.addWidget(self.import_one_game)
self.import_game_info = QLabel(self.tr("Select path to game"))
self.layout.addWidget(self.import_game_info)
self.override_app_name_label = QLabel(self.tr("Override app name (Only if imported game from legendary or the app could not find the app name)"))
self.app_name_input = QLineEdit()
self.app_name_input.setFixedHeight(32)
minilayout = QHBoxLayout()
minilayout.addStretch(1)
self.indicator_label = QLabel("")
minilayout.addWidget(self.indicator_label)
self.app_name_input.setLayout(minilayout)
self.app_name_input.textChanged.connect(self.app_name_changed)
self.path_edit = PathEdit(os.path.expanduser("~"), QFileDialog.DirectoryOnly)
self.path_edit.text_edit.textChanged.connect(self.path_changed)
self.layout.addWidget(self.path_edit)
self.layout.addWidget(self.override_app_name_label)
self.layout.addWidget(self.app_name_input)
self.info_label = QLabel("")
self.layout.addWidget(self.info_label)
self.import_button = QPushButton(self.tr("Import Game"))
self.layout.addWidget(self.import_button)
self.import_button.clicked.connect(self.import_game)
@ -57,24 +76,48 @@ class ImportWidget(QWidget):
# self.main_layout.addStretch(1)
self.setLayout(self.main_layout)
def import_game(self, path=None):
if not path:
path = self.path_edit.text()
if not path.endswith("/"):
path = path + "/"
def app_name_changed(self, text):
if text in self.game_list:
self.indicator_label.setPixmap(icon("ei.ok-sign", color="green").pixmap(16,16))
else:
self.indicator_label.setPixmap(icon("ei.remove-sign", color="red").pixmap(16,16))
def path_changed(self, path):
if os.path.exists(path):
if os.path.exists(os.path.join(path, ".egstore")):
self.app_name_input.setText(self.find_app_name(path))
def find_app_name(self, path):
if not os.path.exists(os.path.join(path, ".egstore")):
return None
for i in os.listdir(os.path.join(path, ".egstore")):
if i.endswith(".mancpn"):
file = path + ".egstore/" + i
file = os.path.join(path, ".egstore", i)
break
else:
logger.warning("File was not found")
return
app_name = json.load(open(file, "r"))["AppName"]
return None
return json.load(open(file, "r"))["AppName"]
def import_game(self, path=None):
app_name = self.app_name_input.text()
if not path:
path = self.path_edit.text()
if not app_name:
if a_n := self.find_app_name(path):
app_name = a_n
else:
self.info_label.setText(self.tr("Could not find app name"))
return
if LegendaryApi.import_game(self.core, app_name=app_name, path=path):
self.info_label.setText(self.tr("Successfully imported {}. Reload library").format(self.core.get_installed_game(app_name).title))
self.app_name_input.setText("")
self.update_list.emit()
else:
logger.warning("Failed to import" + app_name)
self.info_label.setText(self.tr("Failed to import {}").format(app_name))
return
def auto_import_games(self, game_path):
@ -85,17 +128,17 @@ class ImportWidget(QWidget):
logger.info(f"No Games found in {game_path}")
return 0
for path in os.listdir(game_path):
json_path = game_path + path + "/.egstore"
print(json_path)
json_path = game_path + path
if not os.path.isdir(json_path):
logger.info(f"Game at {game_path + path} doesn't exist")
continue
app_name = self.find_app_name(json_path)
if not app_name:
logger.warning("Could not find app name")
continue
for file in os.listdir(json_path):
if file.endswith(".mancpn"):
app_name = json.load(open(os.path.join(json_path, file)))["AppName"]
if LegendaryApi.import_game(self.core, app_name, game_path + path):
imported += 1
if LegendaryApi.import_game(self.core, app_name, game_path + path):
imported += 1
return imported
def import_games_prepare(self):
@ -109,12 +152,11 @@ class ImportWidget(QWidget):
imported += self.auto_import_games(path)
else:
possible_wineprefixes = [os.path.expanduser("~/.wine/"), os.path.expanduser("~/Games/epic-games-store/")]
possible_wineprefixes = [os.path.expanduser("~/.wine"), os.path.expanduser("~/Games/epic-games-store")]
for wine_prefix in possible_wineprefixes:
imported += self.auto_import_games(f"{wine_prefix}drive_c/Program Files/Epic Games/")
imported += self.auto_import_games(os.path.join(wine_prefix, "drive_c/Program Files/Epic Games/"))
if imported > 0:
QMessageBox.information(self, "Imported Games", self.tr("Successfully imported {} Games").format(imported))
QMessageBox.information(self, "Imported Games", self.tr("Successfully imported {} Games. Reloading Library").format(imported))
self.update_list.emit()
logger.info("Restarting app to import games")
else:
QMessageBox.information(self, "Imported Games", "No Games were found")

View file

@ -50,7 +50,6 @@ class LegendarySettings(QWidget):
self.clean_layout.addWidget(self.clean_button_without_manifests)
self.cleanup_widget.setLayout(self.clean_layout)
self.layout.addWidget(self.cleanup_widget)
self.layout.addStretch(1)
@ -94,6 +93,6 @@ class LegendarySettings(QWidget):
after = self.core.lgd.get_dir_size()
logger.info(f'Cleanup complete! Removed {(before - after) / 1024 / 1024:.02f} MiB.')
if cleaned := (before-after) != 0:
QMessageBox.information(self, "Cleanup", self.tr("Cleanup complete! Successfully removed {} MB").format(round(cleaned / 1024 / 1024, 2)))
QMessageBox.information(self, "Cleanup", self.tr("Cleanup complete! Successfully removed {} MB").format(round(cleaned / 1024 / 1024, 3)))
else:
QMessageBox.information(self, "Cleanup", "Nothing to clean")

Binary file not shown.

View file

@ -16,7 +16,20 @@
<message>
<location filename="../Components/Tabs/Settings/About.py" line="28"/>
<source>This is a beta version, so you can get bugs. If you get a bug, please report it by creating a Issue on &lt;a href=&apos;https://github.com/Dummerle/Rare/issues&apos;&gt;Github&lt;/a&gt;. You can also contact me on Discord (Dummerle#7419). If you have a feature request, please contact me</source>
<translation>Dies ist eine beta version, also können Bugs entstehen. Wenn du einen Bug bemerkst, kontaktiere mich, indem du einen Issue auf &lt;a href=&apos;https://github.com/Dummerle/Rare/issues&apos;&gt;Github&lt;/a&gt; erstellst oder mir auf Discord eine Nachricht schickst. Ebenso bei einem Wunsch für Features</translation>
<translation type="obsolete">Dies ist eine beta version, also können Bugs entstehen. Wenn du einen Bug bemerkst, kontaktiere mich, indem du einen Issue auf &lt;a href=&apos;https://github.com/Dummerle/Rare/issues&apos;&gt;Github&lt;/a&gt; erstellst oder mir auf Discord eine Nachricht schickst. Ebenso bei einem Wunsch für Features</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/About.py" line="28"/>
<source>This is a beta version, so you can get bugs. If you get a bug, please report it by creating a Issue on &lt;a href=&apos;https://github.com/Dummerle/Rare/issues&apos;&gt;Github&lt;/a&gt;. You can also contact me on Discord (Dummerle#7419). Or you can join the &lt;a href=&apos;https://discord.gg/YvmABK9YSk&apos;&gt;Discord server&lt;/a&gt;</source>
<translation>Dies ist eine Betaversion, also können Bugs und andere Unschönheiten auftreten. Falls ein Bug auftritt, bitte auf &lt;a href=&apos;https://github.com/Dummerle/Rare/issues&apos;&gt;Github&lt;/a&gt; melden, indem du einen Issue erstellst oder auf Discord. (Dummerle#7419). Ein Rare &lt;a href=&apos;https://discord.gg/YvmABK9YSk&apos;&gt;Discord server&lt;/a&gt; existiert ebenfalls</translation>
</message>
</context>
<context>
<name>BaseInstalledWidget</name>
<message>
<location filename="../Components/Tabs/Games/GameWidgets/BaseInstalledWidget.py" line="34"/>
<source>Do you want to launch {}</source>
<translation>Möchtest du {} starten</translation>
</message>
</context>
<context>
@ -45,7 +58,7 @@
<context>
<name>DownloadTab</name>
<message>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="161"/>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="133"/>
<source>No active Download</source>
<translation>Kein aktiver Download</translation>
</message>
@ -55,56 +68,94 @@
<translation>Download anhalten</translation>
</message>
<message>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="173"/>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="170"/>
<source>No updates available</source>
<translation>Keine Updates verfügbar</translation>
</message>
<message>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="220"/>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="217"/>
<source>Error preparing download</source>
<translation>Fehler beim Vorbereiten des Downloads</translation>
</message>
<message>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="225"/>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="222"/>
<source>Download size is 0. Game already exists</source>
<translation>Die Größe des Downloads ist 0. Spiel existiert bereits</translation>
</message>
<message>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="290"/>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="287"/>
<source>Installation finished</source>
<translation>Installation abgeschlossen</translation>
</message>
<message>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="314"/>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="311"/>
<source>Installing Game: No active download</source>
<translation>Installierendes Spiel: Kein aktiver Download</translation>
</message>
<message>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="322"/>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="319"/>
<source>Download speed</source>
<translation>Geschwindigkeit</translation>
</message>
<message>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="323"/>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="320"/>
<source>Cache used</source>
<translation>Benutzter Cache</translation>
</message>
<message>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="324"/>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="321"/>
<source>Downloaded</source>
<translation>Runtergeladen</translation>
</message>
<message>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="325"/>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="322"/>
<source>Time left: </source>
<translation>Zeit übrig: </translation>
</message>
<message>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="291"/>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="288"/>
<source>Finished Download of game {}</source>
<translation>Downlaod von {} abgeschlossen</translation>
</message>
</context>
<context>
<name>DxvkWidget</name>
<message>
<location filename="../Components/Tabs/Settings/Dxvk.py" line="18"/>
<source>GPU usage</source>
<translation>GPU nutzung</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/Dxvk.py" line="19"/>
<source>Used Memory</source>
<translation>Benutzter Speicher</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/Dxvk.py" line="20"/>
<source>Device info</source>
<translation>Geräteinfo</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/Dxvk.py" line="21"/>
<source>DXVK version</source>
<translation>DXVK Version</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/Dxvk.py" line="22"/>
<source>D3D Level of application</source>
<translation>D3D Level des Spiels</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/Dxvk.py" line="23"/>
<source>Frame time graph</source>
<translation>Graph über die Frametime</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/Dxvk.py" line="28"/>
<source>dxvk settings</source>
<translation>DXVK Einstellungen</translation>
</message>
</context>
<context>
<name>GameActions</name>
<message>
@ -174,15 +225,20 @@
<context>
<name>GameList</name>
<message>
<location filename="../Components/Tabs/Games/GameList.py" line="140"/>
<location filename="../Components/Tabs/Games/GameList.py" line="148"/>
<source>Launch</source>
<translation>Starten</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/GameList.py" line="145"/>
<location filename="../Components/Tabs/Games/GameList.py" line="153"/>
<source>Game running</source>
<translation>Spiel läuft</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/GameList.py" line="45"/>
<source>Installed Games: {} Available Games: {}</source>
<translation>Installierte Spiele: {} Verfügbare Spiele: {}</translation>
</message>
</context>
<context>
<name>GameListHeadBar</name>
@ -215,7 +271,7 @@
<translation>Überprüfung nach Updates beim Start überspringen</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/GameInfo/GameSettings.py" line="64"/>
<location filename="../Components/Tabs/Games/GameInfo/GameSettings.py" line="65"/>
<source>Save</source>
<translation>Speichern</translation>
</message>
@ -230,17 +286,17 @@
<translation>Proton Version</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/GameInfo/GameSettings.py" line="66"/>
<location filename="../Components/Tabs/Games/GameInfo/GameSettings.py" line="67"/>
<source>Proton prefix</source>
<translation>Protonprefix</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/GameInfo/GameSettings.py" line="172"/>
<location filename="../Components/Tabs/Games/GameInfo/GameSettings.py" line="173"/>
<source>No permission to create folder</source>
<translation>Keine Berechtigung den Ordner zu erstellen</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/GameInfo/GameSettings.py" line="217"/>
<location filename="../Components/Tabs/Games/GameInfo/GameSettings.py" line="218"/>
<source>Please select path for proton prefix</source>
<translation>Bitte wähle den Pfad zum Protonprefix</translation>
</message>
@ -304,29 +360,54 @@
<translation>Keine valide Session gefunden</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/ImportWidget.py" line="23"/>
<location filename="../Components/Tabs/Games/ImportWidget.py" line="26"/>
<source>Back</source>
<translation>Zurück</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/ImportWidget.py" line="37"/>
<location filename="../Components/Tabs/Games/ImportWidget.py" line="40"/>
<source>Select path to game</source>
<translation>Wähle den Pfad zum Spiel</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/ImportWidget.py" line="43"/>
<location filename="../Components/Tabs/Games/ImportWidget.py" line="62"/>
<source>Import Game</source>
<translation>Spiel importieren</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/ImportWidget.py" line="51"/>
<location filename="../Components/Tabs/Games/ImportWidget.py" line="70"/>
<source>Import all games from Epic Games Launcher</source>
<translation>Alle Spiele aus dem Epic Games Launcher importieren</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/ImportWidget.py" line="116"/>
<source>Successfully imported {} Games</source>
<translation>{} Spiele erfolgreich importiert</translation>
<translation type="obsolete">{} Spiele erfolgreich importiert</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/ImportWidget.py" line="43"/>
<source>Override app name (Only if imported game from legendary or the app could not find the app name)</source>
<translation>App Name überschreiben (Nur falls das Spiel von Legendary importiert wird oder der App Name nicht gefunden wird</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/ImportWidget.py" line="110"/>
<source>Could not find app name</source>
<translation>Konnte den Appnamen nicht finden</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/ImportWidget.py" line="114"/>
<source>Successfully imported {}. Reload library</source>
<translation>Erfolgreich {} importiert. Spiele neu laden</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/ImportWidget.py" line="120"/>
<source>Failed to import {}</source>
<translation>{} Konnte nicht importiert werden</translation>
</message>
<message>
<location filename="../Components/Tabs/Games/ImportWidget.py" line="159"/>
<source>Successfully imported {} Games. Reloading Library</source>
<translation>Erfolgreich {} Spiele importiert. Spiele neu laden</translation>
</message>
</context>
<context>
@ -411,6 +492,14 @@ Installationsgröße: {} GB</translation>
<translation>Starten...</translation>
</message>
</context>
<context>
<name>LaunchThread</name>
<message>
<location filename="../Components/Launch/LaunchDialog.py" line="23"/>
<source>Downloading Images</source>
<translation>Bilder runterladen</translation>
</message>
</context>
<context>
<name>LegendarySettings</name>
<message>
@ -428,19 +517,44 @@ Installationsgröße: {} GB</translation>
<source>Max workers for Download (Less: slower download)(0: Default)</source>
<translation>Maximale Anzahl Downloadprozesse (Weniger: langsamer)(Standard: 0)</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/Legendary.py" line="43"/>
<source>Cleanup</source>
<translation>Aufräumen</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/Legendary.py" line="44"/>
<source>Remove everything</source>
<translation>Alles aufräumen</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/Legendary.py" line="48"/>
<source>Clean, but keep manifests</source>
<translation>Aufräumen, aber Manifests behalten</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/Legendary.py" line="96"/>
<source>Cleanup complete! Successfully removed {} MB</source>
<translation>Fertig! Es wurden {} MB entfernt</translation>
</message>
</context>
<context>
<name>LinuxSettings</name>
<message>
<location filename="../Components/Tabs/Settings/Linux.py" line="29"/>
<location filename="../Components/Tabs/Settings/Linux.py" line="28"/>
<source>Default Wine Prefix</source>
<translation>Standard Wineprefix</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/Linux.py" line="37"/>
<location filename="../Components/Tabs/Settings/Linux.py" line="36"/>
<source>Default Wine executable</source>
<translation>Standard Wine</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/Linux.py" line="19"/>
<source>Linux settings</source>
<translation>Linux Einstellungen</translation>
</message>
</context>
<context>
<name>ListWidgetUninstalled</name>
@ -535,10 +649,15 @@ Installationsgröße: {} GB</translation>
<translation>Sprache</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/Rare.py" line="68"/>
<location filename="../Components/Tabs/Settings/Rare.py" line="77"/>
<source>Restart Application to activate changes</source>
<translation>Starte die App neu um die Änderungen zu aktivieren</translation>
</message>
<message>
<location filename="../Components/Tabs/Settings/Rare.py" line="55"/>
<source>Confirm launch of game</source>
<translation>Start des Spiels bestätigen</translation>
</message>
</context>
<context>
<name>SyncSaves</name>
@ -682,7 +801,7 @@ Installationsgröße: {} GB</translation>
<context>
<name>UpdateWidget</name>
<message>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="352"/>
<location filename="../Components/Tabs/Downloads/DownloadTab.py" line="349"/>
<source>Update Game</source>
<translation>Spiel updaten</translation>
</message>