diff --git a/.gitignore b/.gitignore
index 7a1d7b74..e6770df0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,11 @@
/images/
/.idea/
/Rare/__pycache__/
-/CountLines.sh
+/Scripts/CountLines.sh
/Rare/utils/__pycache__/
/build/
/dist/
/Rare.egg-info/
-/RareBuild.sh
+/Scripts/RareBuild.sh
/venv/
+Scripts/*
\ No newline at end of file
diff --git a/MANIFEST.in b/MANIFEST.in
index 2762af51..737f3f37 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,3 +1,4 @@
include Rare/Styles/dark.qss
include Rare/Styles/RareStyle.css
-include README.md
\ No newline at end of file
+include README.md
+include Rare/language/de.qm
\ No newline at end of file
diff --git a/README.md b/README.md
index 825be8e7..e76343df 100644
--- a/README.md
+++ b/README.md
@@ -38,9 +38,9 @@ Using the exe-file could cause an error with the stylesheets
- In-app Browser to buy games
- Settings (Legendary and games)
- Sync Cloud Saves
+- Translations (English and German)
## Planned
-- Translations (English and German)
- Design (Pretty Stylesheets, Icons, Icon view for installed Games)
- Download Progressbar
- Offline mode
diff --git a/Rare/Main.py b/Rare/Main.py
index a7baa942..f7f42071 100644
--- a/Rare/Main.py
+++ b/Rare/Main.py
@@ -2,14 +2,16 @@ import logging
import os
import sys
+from PyQt5.QtCore import QTranslator
from PyQt5.QtWidgets import QApplication, QMessageBox
from legendary.core import LegendaryCore
-from Rare import style_path
+from Rare import style_path, lang_path
from Rare.MainWindow import MainWindow
from Rare.Start.Launch import LaunchDialog
from Rare.Start.Login import LoginWindow
from Rare.utils import RareConfig
+from Rare.utils.RareUtils import get_lang
logging.basicConfig(
format='[%(name)s] %(levelname)s: %(message)s',
@@ -21,13 +23,20 @@ core = LegendaryCore()
def main():
app = QApplication(sys.argv)
+ translator = QTranslator()
+ lang = get_lang()
+ if os.path.exists(lang_path + lang + ".qm"):
+ translator.load(lang_path + lang + ".qm")
+ else:
+ logger.info("Your language is not supported")
+ app.installTranslator(translator)
+
if RareConfig.THEME == "default" and os.path.exists(style_path):
app.setStyleSheet(open(style_path).read())
- # app.setStyleSheet(open("Styles/RareStyle.css").read())
+
logger.info("Try if you are logged in")
try:
if core.login():
-
logger.info("You are logged in")
else:
logger.error("Login Failed")
@@ -42,7 +51,7 @@ def main():
QMessageBox.warning(app, "No Internet", "Connection Error, Failed to login. The offine mode is not implemented")
# Start Offline mode
launch_dialog = LaunchDialog(core)
- if RareConfig.THEME == "dark":
+ if RareConfig.THEME == "default":
launch_dialog.setStyleSheet(open(style_path).read())
launch_dialog.exec_()
mainwindow = MainWindow(core)
diff --git a/Rare/MainWindow.py b/Rare/MainWindow.py
index 45e6f0a8..9bfab227 100644
--- a/Rare/MainWindow.py
+++ b/Rare/MainWindow.py
@@ -18,16 +18,16 @@ class TabWidget(QTabWidget):
def __init__(self, core):
super(QWidget, self).__init__()
self.game_list = GameListInstalled(core)
- self.addTab(self.game_list, "Games")
+ self.addTab(self.game_list, self.tr("Games"))
self.uninstalled_games = GameListUninstalled(core)
- self.uninstalled_games.finished.connect(lambda: self.game_list.update_list())
- self.addTab(self.uninstalled_games, "Install Games")
+ self.uninstalled_games.reload.connect(lambda: self.game_list.update_list())
+ self.addTab(self.uninstalled_games, self.tr("Install Games"))
self.update_tab = UpdateTab(core)
- self.addTab(self.update_tab, "Updates")
+ self.addTab(self.update_tab, self.tr("Updates"))
self.browser = BrowserTab()
- self.addTab(self.browser, "Store")
+ self.addTab(self.browser, self.tr("Website"))
self.settings = SettingsTab(core)
- self.addTab(self.settings, "Settings")
\ No newline at end of file
+ self.addTab(self.settings, self.tr("Settings"))
\ No newline at end of file
diff --git a/Rare/Start/Launch.py b/Rare/Start/Launch.py
index fdbf3506..e36c1bbb 100644
--- a/Rare/Start/Launch.py
+++ b/Rare/Start/Launch.py
@@ -24,13 +24,13 @@ class LaunchDialog(QDialog):
def __init__(self, core: LegendaryCore):
super(LaunchDialog, self).__init__()
- self.title = QLabel("
Launching Rare
")
+ self.title = QLabel(""+self.tr("Launching Rare")+"
")
self.thread = LaunchThread(core, self)
self.thread.download_progess.connect(self.update_pb)
self.thread.action.connect(self.info)
self.info_pb = QProgressBar()
self.info_pb.setMaximum(len(core.get_game_list()))
- self.info_text = QLabel("Logging in")
+ self.info_text = QLabel(self.tr("Logging in"))
self.layout = QVBoxLayout()
self.layout.addWidget(self.title)
diff --git a/Rare/Start/Login.py b/Rare/Start/Login.py
index 1fcb3879..941893eb 100644
--- a/Rare/Start/Login.py
+++ b/Rare/Start/Login.py
@@ -35,8 +35,9 @@ class ImportWidget(QWidget):
self.layout = QVBoxLayout()
self.core = core
- self.import_text = QLabel("Import from existing Epic Games Launcher installation
\nYou will get "
- "logged out there")
+ self.import_text = QLabel(
+ "" + self.tr("Import from existing Epic Games Launcher installation") + "
\n" + self.tr(
+ "You will get logged out there"))
self.import_accept_button = QPushButton("Import")
self.import_accept_button.clicked.connect(self.auth)
appdata_paths = self.get_appdata_path()
@@ -45,7 +46,7 @@ class ImportWidget(QWidget):
if len(appdata_paths) == 0:
self.path = QLineEdit()
- self.path.setPlaceholderText("Path to Wineprefix (Not implemented)")
+ self.path.setPlaceholderText(self.tr("Path to Wineprefix"))
self.layout.addWidget(self.path)
else:
self.btn_group = QButtonGroup()
@@ -56,7 +57,7 @@ class ImportWidget(QWidget):
# for i in appdata_paths:
- self.appdata_path_text = QLabel(f"Appdata path: {self.core.egl.appdata_path}")
+ self.appdata_path_text = QLabel(self.tr("Appdata path: ") + {self.core.egl.appdata_path})
self.login_text = QLabel("")
# self.layout.addWidget(self.btn_group)
@@ -109,7 +110,7 @@ class ImportWidget(QWidget):
self.import_accept_button.setDisabled(False)
logger.warning("Error: No valid session found")
- self.login_text.setText("Error: No valid session found")
+ self.login_text.setText(self.tr("Error: No valid session found"))
class SystemBrowserWidget(QWidget):
@@ -120,10 +121,10 @@ class SystemBrowserWidget(QWidget):
self.core = core
self.layout = QVBoxLayout()
- self.text = QLabel("Insert Sid from Browser")
+ self.text = QLabel(self.tr("Insert Sid from Browser"))
self.layout.addWidget(self.text)
self.input = QLineEdit()
- self.input.setPlaceholderText("Insert sid from Browser")
+ self.input.setPlaceholderText(self.tr("Insert sid from Browser"))
self.layout.addWidget(self.input)
self.loading_text = QLabel("")
@@ -133,14 +134,14 @@ class SystemBrowserWidget(QWidget):
self.back_button.clicked.connect(self.back)
self.layout.addWidget(self.back_button)
- self.submit_button = QPushButton("Login")
+ self.submit_button = QPushButton(self.tr("Login"))
self.submit_button.clicked.connect(self.login)
self.layout.addWidget(self.submit_button)
self.setLayout(self.layout)
def login(self):
- self.loading_text.setText("Loading")
+ self.loading_text.setText(self.tr("Loading..."))
token = self.input.text()
if token.startswith("{") and token.endswith("}"):
token = json.loads(token)['sid']
@@ -167,16 +168,18 @@ class LoginWindow(QDialog):
self.setGeometry(0, 0, 200, 300)
self.welcome_layout = QVBoxLayout()
self.title = QLabel(
- "Welcome to Rare the graphical interface for Legendary, an open source Epic Games alternative.
\nSelect one Option to Login
")
- self.browser_btn = QPushButton("Use built in browser to login")
+ "" + self.tr(
+ "Welcome to Rare the graphical interface for Legendary, an open source Epic Games alternative.") + "
\n" + self.tr(
+ "Select an option to Login") + "
")
+ self.browser_btn = QPushButton(self.tr("Use built in browser to login"))
self.browser_btn.clicked.connect(self.browser_login)
- self.browser_btn_normal = QPushButton("Use System browser")
+ self.browser_btn_normal = QPushButton(self.tr("Use System browser"))
self.browser_btn_normal.clicked.connect(self.sys_browser_login)
- self.import_btn = QPushButton("Import from existing Epic Games installation")
+ self.import_btn = QPushButton(self.tr("Import from existing Epic Games installation"))
self.import_btn.clicked.connect(self.import_login)
self.text = QLabel("")
- self.exit_btn = QPushButton("Exit App")
+ self.exit_btn = QPushButton(self.tr("Exit App"))
self.exit_btn.clicked.connect(self.exit_login)
self.welcome_layout.addWidget(self.title)
@@ -209,7 +212,7 @@ class LoginWindow(QDialog):
self.success()
else:
self.layout.setCurrentIndex(0)
- self.text.setText("Login failed
")
+ self.text.setText(""+self.tr("Login failed")+"
")
def login(self):
self.exec_()
@@ -253,4 +256,4 @@ class LoginWindow(QDialog):
self.layout.setCurrentIndex(0)
logger.warning("Login failed")
self.browser.close()
- self.text.setText("Login Failed")
+ self.text.setText(self.tr("Login Failed"))
diff --git a/Rare/Tabs/GamesInstalled/GameWidget.py b/Rare/Tabs/GamesInstalled/GameWidget.py
index 515c589c..8e30f67e 100644
--- a/Rare/Tabs/GamesInstalled/GameWidget.py
+++ b/Rare/Tabs/GamesInstalled/GameWidget.py
@@ -49,22 +49,21 @@ class GameWidget(QWidget):
##Layout on the right
self.childLayout = QVBoxLayout()
-
play_icon = self.style().standardIcon(getattr(QStyle, 'SP_MediaPlay'))
settings_icon = self.style().standardIcon(getattr(QStyle, 'SP_DirIcon'))
self.title_widget = QLabel(f"{self.title}
")
self.app_name_label = QLabel(self.app_name)
- self.launch_button = QPushButton(play_icon, "Launch")
+ self.launch_button = QPushButton(play_icon, self.tr("Launch"))
self.launch_button.setObjectName("launch_game_button")
self.launch_button.setFixedWidth(120)
self.launch_button.clicked.connect(self.launch)
if os.name != "nt":
self.wine_rating = QLabel("Wine Rating: " + self.get_rating())
- self.developer_label = QLabel("Dev: " + self.dev)
+ self.developer_label = QLabel(self.tr("Developer: ") + self.dev)
self.version_label = QLabel("Version: " + str(self.version))
- self.size_label = QLabel(f"Installed size: {round(self.size / (1024 ** 3), 2)} GB")
- self.settings_button = QPushButton(settings_icon, " Settings (Icon TODO)")
+ self.size_label = QLabel(f"{self.tr('Installed size')}: {round(self.size / (1024 ** 3), 2)} GB")
+ self.settings_button = QPushButton(settings_icon, f" {self.tr('Settings')} (Icon TODO)")
self.settings_button.setFixedWidth(200)
self.settings_button.clicked.connect(self.settings)
@@ -92,7 +91,7 @@ class GameWidget(QWidget):
print("Fail")
return
- self.proc.finished.connect(self.finished)
+ self.proc.reload.connect(self.finished)
self.launch_button.setText("Kill")
self.game_running = True
diff --git a/Rare/Tabs/GamesInstalled/InstalledList.py b/Rare/Tabs/GamesInstalled/InstalledList.py
index 7cac61ae..7f55d66c 100644
--- a/Rare/Tabs/GamesInstalled/InstalledList.py
+++ b/Rare/Tabs/GamesInstalled/InstalledList.py
@@ -30,10 +30,10 @@ class GameListInstalled(QScrollArea):
self.layout = QVBoxLayout()
mini_layout = QHBoxLayout()
- self.update_button = QPushButton("Manually reload Games")
+ self.update_button = QPushButton(self.tr("Manually reload Games"))
self.update_button.clicked.connect(self.update_list)
mini_layout.addWidget(self.update_button)
- self.upload_button = QPushButton("Cloud Saves")
+ self.upload_button = QPushButton(self.tr("Cloud Saves"))
mini_layout.addWidget(self.upload_button)
self.upload_button.clicked.connect(self.sync_saves)
self.layout.addLayout(mini_layout)
@@ -47,8 +47,8 @@ class GameListInstalled(QScrollArea):
self.layout.addWidget(widget)
else:
- not_installed_label = QLabel("No Games are installed. Do you want to import them?")
- not_installed_button = QPushButton("Import Games")
+ not_installed_label = QLabel(self.tr("No Games are installed. Do you want to import them?"))
+ not_installed_button = QPushButton(self.tr("Import Games"))
not_installed_button.clicked.connect(self.import_games_prepare)
self.layout.addWidget(not_installed_label)
self.layout.addWidget(not_installed_button)
@@ -79,7 +79,7 @@ class GameListInstalled(QScrollArea):
for wine_prefix in possible_wineprefixes:
imported += self.auto_import_games(f"{wine_prefix}drive_c/Program Files/Epic Games/")
if imported > 0:
- QMessageBox.information(self, "Imported Games", f"Successfully imported {imported} Games")
+ QMessageBox.information(self, "Imported Games", self.tr(f"Successfully imported {imported} Games"))
logger.info("Restarting app to import games")
else:
QMessageBox.information(self, "Imported Games", "No Games were found")
diff --git a/Rare/Tabs/GamesUninstalled/GameListUninstalled.py b/Rare/Tabs/GamesUninstalled/GameListUninstalled.py
index 04f8bde8..9aa39e47 100644
--- a/Rare/Tabs/GamesUninstalled/GameListUninstalled.py
+++ b/Rare/Tabs/GamesUninstalled/GameListUninstalled.py
@@ -7,7 +7,7 @@ from Rare.utils.Dialogs.ImportDialog import ImportDialog
class GameListUninstalled(QScrollArea):
- finished = pyqtSignal()
+ reload = pyqtSignal()
def __init__(self, core: LegendaryCore):
super(GameListUninstalled, self).__init__()
@@ -20,8 +20,8 @@ class GameListUninstalled(QScrollArea):
self.filter = QLineEdit()
self.filter.textChanged.connect(self.filter_games)
- self.filter.setPlaceholderText("Filter Games")
- self.import_button = QPushButton("Import installed Game from Epic Games Store")
+ self.filter.setPlaceholderText(self.tr("Filter Games"))
+ self.import_button = QPushButton(self.tr("Import installed Game from Epic Games Store"))
self.import_button.clicked.connect(self.import_game)
self.layout.addWidget(self.filter)
self.layout.addWidget(self.import_button)
@@ -34,7 +34,7 @@ class GameListUninstalled(QScrollArea):
games = sorted(games, key=lambda x: x.app_title)
for game in games:
game_widget = UninstalledGameWidget(game)
- game_widget.finished.connect(lambda: self.finished.emit())
+ game_widget.finished.connect(lambda: self.reload.emit())
self.layout.addWidget(game_widget)
self.widgets_uninstalled.append(game_widget)
@@ -51,4 +51,5 @@ class GameListUninstalled(QScrollArea):
def import_game(self):
import_dia = ImportDialog(self.core)
- import_dia.import_dialog()
+ if import_dia.import_dialog():
+ self.reload.emit()
diff --git a/Rare/Tabs/GamesUninstalled/GameWidget.py b/Rare/Tabs/GamesUninstalled/GameWidget.py
index 7b9c4ed6..085a43e6 100644
--- a/Rare/Tabs/GamesUninstalled/GameWidget.py
+++ b/Rare/Tabs/GamesUninstalled/GameWidget.py
@@ -53,7 +53,7 @@ class UninstalledGameWidget(QWidget):
self.title_label = QLabel(f"{self.title}
")
self.app_name_label = QLabel(f"App Name: {self.app_name}")
self.version_label = QLabel(f"Version: {self.version}")
- self.install_button = QPushButton("Install")
+ self.install_button = QPushButton(self.tr("Install"))
self.install_button.setFixedWidth(120)
self.install_button.clicked.connect(self.install)
@@ -72,16 +72,15 @@ class UninstalledGameWidget(QWidget):
logger.info("install " + self.title)
dia = InstallDialog(self.game)
data = dia.get_data()
- print(data)
if data != 0:
path = data.get("install_path")
logger.info(f"install {self.app_name} in path {path}")
# TODO
self.install_button.setDisabled(True)
- self.install_button.setText("installing")
+ self.install_button.setText(self.tr("installing"))
self.proc = QProcess()
self.proc.start("legendary", ["-y", "install", self.app_name, "--base-path", path])
- self.proc.finished.connect(self.download_finished)
+ self.proc.reload.connect(self.download_finished)
else:
logger.info("Download canceled")
@@ -89,5 +88,5 @@ class UninstalledGameWidget(QWidget):
def download_finished(self, code):
self.setVisible(False)
logger.info(f"Download finished. code: {code}")
- QMessageBox.information(self, "Download finished", "Download has finished")
+ QMessageBox.information(self, self.tr("Download finished"), self.tr("Download has finished"))
self.finished.emit()
diff --git a/Rare/Tabs/GamesUninstalled/InstallDialog.py b/Rare/Tabs/GamesUninstalled/InstallDialog.py
index b0fa860f..7d368da9 100644
--- a/Rare/Tabs/GamesUninstalled/InstallDialog.py
+++ b/Rare/Tabs/GamesUninstalled/InstallDialog.py
@@ -6,17 +6,17 @@ from PyQt5.QtWidgets import QLineEdit, QPushButton, QLabel, QVBoxLayout, QDialog
class InstallDialog(QDialog):
def __init__(self, game):
super(InstallDialog, self).__init__()
- self.setWindowTitle("Install Game")
+ self.setWindowTitle(self.tr("Install Game"))
self.layout = QVBoxLayout()
self.yes = False
self.install_path = QLineEdit(f"{os.path.expanduser('~')}/legendary")
- self.options = QLabel("Some Settings")
+ self.options = QLabel("Some Settings (Comming soon)")
# self.layout.addWidget(self.options)
self.layout.addStretch(1)
- self.yes_button = QPushButton("Install")
+ self.yes_button = QPushButton(self.tr("Install game ") + game.title)
self.yes_button.clicked.connect(self.close)
- self.cancel_button = QPushButton("cancel")
+ self.cancel_button = QPushButton(self.tr("cancel"))
self.layout.addWidget(self.options)
self.layout.addWidget(self.install_path)
diff --git a/Rare/Tabs/Settings/RareSettingsForm.py b/Rare/Tabs/Settings/RareSettingsForm.py
index a5cd40fc..8cfda866 100644
--- a/Rare/Tabs/Settings/RareSettingsForm.py
+++ b/Rare/Tabs/Settings/RareSettingsForm.py
@@ -17,18 +17,18 @@ class RareSettingsForm(QGroupBox):
self.rare_form = QFormLayout()
self.style_combo_box = QComboBox()
- self.style_combo_box.addItems(["Light", "Dark"])
+ self.style_combo_box.addItems([self.tr("Light"), self.tr("Dark")])
if RareConfig.THEME == "default":
self.style_combo_box.setCurrentIndex(1)
self.rare_form.addRow(QLabel("Style"), self.style_combo_box)
- self.image_dir_edit = PathEdit(RareConfig.IMAGE_DIR, QFileDialog.Directory, "Choose Folder")
- self.image_dir_edit.setPlaceholderText("Image directory")
+ self.image_dir_edit = PathEdit(RareConfig.IMAGE_DIR, QFileDialog.Directory, self.tr("Choose Folder"))
+ self.image_dir_edit.setPlaceholderText(self.tr("Image directory"))
# self.image_dir_edit.setText(RareConfig.IMAGE_DIR)
- self.rare_form.addRow(QLabel("Image Directory"), self.image_dir_edit)
- self.submit_button = QPushButton("Update Rare Settings")
+ self.rare_form.addRow(QLabel(self.tr("Image Directory")), self.image_dir_edit)
+ self.submit_button = QPushButton(self.tr("Update Rare Settings"))
self.submit_button.clicked.connect(self.update_rare_settings)
self.rare_form.addRow(self.submit_button)
self.setLayout(self.rare_form)
diff --git a/Rare/Tabs/Settings/SettingsTab.py b/Rare/Tabs/Settings/SettingsTab.py
index 699a08f6..0b8c47a2 100644
--- a/Rare/Tabs/Settings/SettingsTab.py
+++ b/Rare/Tabs/Settings/SettingsTab.py
@@ -21,16 +21,16 @@ class SettingsTab(QScrollArea):
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
# Settings
self.layout = QVBoxLayout()
- self.layout.addWidget(QLabel("Rare Settings
"))
- self.logged_in_as = QLabel(f"Logged in as {get_name()}")
+ self.layout.addWidget(QLabel(""+self.tr("Settings")+"
"))
+ self.logged_in_as = QLabel(self.tr("Logged in as ")+get_name())
# self.legendary_form =SettingsForm()
- self.default_settings = SettingsForm("default", default_settings, True)
+ self.default_settings = SettingsForm(self.tr("default"), default_settings, True)
self.legendary_form = SettingsForm("Legendary", legendary_settings, False)
self.rare_form = RareSettingsForm()
- self.logout_button = QPushButton("Logout")
+ self.logout_button = QPushButton(self.tr("Logout"))
self.logout_button.clicked.connect(self.update_list)
self.layout.addWidget(self.logged_in_as)
@@ -42,7 +42,7 @@ class SettingsTab(QScrollArea):
self.layout.addWidget(self.logout_button)
self.info_label = QLabel("Credits
")
- self.infotext = QLabel("Developers : Dummerle, CommandMC\nLegendary Dev: Rodney\nLicense: GPL v.3")
+ self.infotext = QLabel(self.tr("Developers : ")+"Dummerle, CommandMC\nLegendary Dev: Rodney\nLicense: GPL v.3")
self.layout.addWidget(self.info_label)
self.layout.addWidget(self.infotext)
diff --git a/Rare/Tabs/Update.py b/Rare/Tabs/Update.py
index 56fa8aa6..f1da237c 100644
--- a/Rare/Tabs/Update.py
+++ b/Rare/Tabs/Update.py
@@ -52,7 +52,7 @@ class UpdateWidget(QWidget):
self.core = core
self.layout = QVBoxLayout()
self.childlayout = QHBoxLayout()
- self.label = QLabel("Update available for " + self.game.title)
+ self.label = QLabel(self.tr("Update available for ") + self.game.title)
self.button = QPushButton("Update")
self.button.clicked.connect(self.update_game2)
@@ -103,14 +103,14 @@ class UpdateWidget(QWidget):
def finished(self, text: str):
if text == "Fail":
- QMessageBox.warning(self, "Update Failed", "Update failed")
+ QMessageBox.warning(self, self.tr("Update Failed"), self.tr("Update failed"))
else:
- QMessageBox.information(self, "Update finished", f"Update finished in {time} ")
- self.setVisible(False)
- self.installed.emit()
+ QMessageBox.information(self, self.tr("Update finished"), self.tr("Update finished in ") + str(time))
+ self.setVisible(False)
+ self.installed.emit()
def start(self):
- self.button.setText("Cancel")
+ self.button.setText(self.tr("Cancel"))
self.updating = True
def get_update_info(self):
@@ -143,7 +143,7 @@ class UpdateTab(QWidget):
widget.installed.connect(lambda: self.__init__(self.core))
self.layout.addWidget(widget)
if len(update_games) == 0:
- self.layout.addWidget(QLabel("No updates available"))
+ self.layout.addWidget(QLabel(self.tr("No updates available")))
self.layout.addStretch(1)
self.setLayout(self.layout)
diff --git a/Rare/__init__.py b/Rare/__init__.py
index a40bf384..955569d9 100644
--- a/Rare/__init__.py
+++ b/Rare/__init__.py
@@ -1,3 +1,4 @@
import os
__version__ = "0.1.5"
style_path = os.path.join(os.path.dirname(__file__), "Styles/dark.qss")
+lang_path = os.path.join(os.path.dirname(__file__), "languages/")
diff --git a/Rare/ext/QtExtensions.py b/Rare/ext/QtExtensions.py
index c5f4aa65..f41a789b 100644
--- a/Rare/ext/QtExtensions.py
+++ b/Rare/ext/QtExtensions.py
@@ -32,8 +32,7 @@ class PathEdit(QWidget):
self.info_text = infotext
self.layout = QHBoxLayout()
self.text_edit = QLineEdit(text)
- self.setObjectName("text_edit")
- self.path_select = QPushButton("Select Path")
+ self.path_select = QPushButton(self.tr("Select Path"))
self.path_select.clicked.connect(self.set_path)
self.layout.addWidget(self.text_edit)
self.layout.addWidget(self.path_select)
@@ -46,7 +45,7 @@ class PathEdit(QWidget):
return self.text_edit.text()
def set_path(self):
- dlg = QFileDialog(self, "Choose Path", os.path.expanduser("~/"))
+ dlg = QFileDialog(self, self.tr("Choose Path"), os.path.expanduser("~/"))
dlg.setFileMode(self.type_of_file)
if self.filter:
dlg.setFilter(self.filter)
diff --git a/Rare/ext/SettingsForm.py b/Rare/ext/SettingsForm.py
index f9631ba3..7207dfce 100644
--- a/Rare/ext/SettingsForm.py
+++ b/Rare/ext/SettingsForm.py
@@ -42,23 +42,23 @@ class SettingsForm(QGroupBox):
else:
self.table = QTableWidget(0, 2)
- self.table.setHorizontalHeaderLabels(["Variable", "Value"])
+ self.table.setHorizontalHeaderLabels(["Variable", self.tr("Value")])
self.table.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.table.setMaximumSize(self._getQTableWidgetSize())
- self.form.addRow(QLabel("Environment Variables"), self.table)
+ self.form.addRow(QLabel(self.tr("Environment Variables")), self.table)
- self.add_button = QPushButton("Add Variable")
+ self.add_button = QPushButton(self.tr("Add Variable"))
self.add_button.clicked.connect(self.add_variable)
- self.delete_button = QPushButton("Delete Variable")
+ self.delete_button = QPushButton(self.tr("Delete Variable"))
self.delete_button.clicked.connect(lambda: self.table.removeRow(self.table.currentRow()))
self.form.addRow(self.add_button)
self.form.addRow(self.delete_button)
- self.update_button = QPushButton("Update Settings")
+ self.update_button = QPushButton(self.tr("Update Settings"))
self.update_button.clicked.connect(self.update_config)
self.form.addRow(self.update_button)
@@ -89,16 +89,16 @@ class SettingsForm(QGroupBox):
if type_of_input == "QLineEdit":
field = QLineEdit(self.config[self.app_name][lgd_name])
- field.setPlaceholderText("Default")
+ field.setPlaceholderText(self.tr("Default"))
if "only_int" in flags:
field.setValidator(QIntValidator())
if "path" in flags:
if lgd_name == "wine_prefix":
field = PathEdit(text=self.config[self.app_name][lgd_name], type_of_file=QFileDialog.DirectoryOnly,
- infotext="Select Wine Prefix")
+ infotext=self.tr("Select Wine Prefix"))
if lgd_name == "install_dir":
field = PathEdit(text=self.config[self.app_name][lgd_name], type_of_file=QFileDialog.DirectoryOnly,
- infotext="Select Default installation directory")
+ infotext=self.tr("Select Default installation directory"))
elif type_of_input == "QComboBox":
combo_list = []
if "binary" in flags:
@@ -192,7 +192,7 @@ class SettingsForm(QGroupBox):
break
else:
logger.error("No Proton found")
- QMessageBox.Warning("Error", "No Proton was found")
+ QMessageBox.Warning("Error", self.tr("No Proton version was found"))
return
field.setText(os.path.join(protonpath, "proton") + " run")
elif lgd_name == "no_wine":
diff --git a/Rare/languages/de.qm b/Rare/languages/de.qm
new file mode 100644
index 00000000..a1f56353
Binary files /dev/null and b/Rare/languages/de.qm differ
diff --git a/Rare/languages/de.ts b/Rare/languages/de.ts
new file mode 100644
index 00000000..1cd5c0d6
--- /dev/null
+++ b/Rare/languages/de.ts
@@ -0,0 +1,559 @@
+
+
+
+
+ GameListInstalled
+
+
+ Manually reload Games
+ Spiele manuell neu laden
+
+
+
+ Cloud Saves
+ Cloud Speicher
+
+
+
+ No Games are installed. Do you want to import them?
+ Keine Spiele sind installiert. Willst du sie importieren?
+
+
+
+ Import Games
+ Spiele importieren
+
+
+
+ GameListUninstalled
+
+
+ Filter Games
+ Spiele suchen
+
+
+
+ Import installed Game from Epic Games Store
+ Installiertes Spiel aus dem Epic Games Store importieren
+
+
+
+ GameWidget
+
+
+ Launch
+ Spielen
+
+
+
+ Developer:
+ Entwickler:
+
+
+
+ ImportDialog
+
+
+ Select Path
+ Wähle Dateipfad
+
+
+
+ Import
+ Importieren
+
+
+
+ Failed to import Game
+ Spiel konnte nicht importiert werden
+
+
+
+ ImportWidget
+
+
+ Import from existing Epic Games Launcher installation
+ Aus einer bestehenden Epic Games Launcher Installation importieren
+
+
+
+ You will get logged out there
+ Du wirst dort ausgeloggt
+
+
+
+ Path to Wineprefix
+ Pfad zum Wine Prefix
+
+
+
+ Appdata path:
+ Appdata Pfad:
+
+
+
+ Error: No valid session found
+ Fehler: Keine Session gefunden
+
+
+
+ InstallDialog
+
+
+ Install Game
+ Spiel installieren
+
+
+
+ Install game
+ Spiel installieren
+
+
+
+ cancel
+ Beenden
+
+
+
+ LaunchDialog
+
+
+ Launching Rare
+ Starte Rare
+
+
+
+ Logging in
+ Einloggen...
+
+
+
+ LoginWindow
+
+
+ Welcome to Rare the graphical interface for Legendary, an open source Epic Games alternative.
+ Willkommen zu Rare, eine grafische Oberfläche für Legendary, eine open source alternative zum Epic Games Launcher.
+
+
+
+ Select an option to Login
+ Wähle eine Möglichkeit zum Einloggen aus
+
+
+
+ Use built in browser to login
+ Den eingebauten Browser benutzen
+
+
+
+ Use System browser
+ Den Systembrowser benutzen
+
+
+
+ Import from existing Epic Games installation
+ Aus einer existierenden Installation importieren
+
+
+
+ Exit App
+ App verlassen
+
+
+
+ Login failed
+ Login fehlgeschlagen
+
+
+
+ Login Failed
+ Login fehlgeschlagen
+
+
+
+ PathEdit
+
+
+ Select Path
+ Wähle Pfad aus
+
+
+
+ Choose Path
+ Wähle Pfad aus
+
+
+
+ PathInputDialog
+
+
+ Select directory
+ Wähle Ordner aus
+
+
+
+ RareSettingsForm
+
+
+ Light
+ Hell
+
+
+
+ Dark
+ Dunkel
+
+
+
+ Choose Folder
+ Wähle Ordner aus
+
+
+
+ Image directory
+ Bilder Ordner
+
+
+
+ Image Directory
+ Bilder Ordner
+
+
+
+ Update Rare Settings
+ Rare Einstellungen speichern
+
+
+
+ SettingsForm
+
+
+ Value
+ Wert
+
+
+
+ Environment Variables
+ Umbebungsvariablen
+
+
+
+ Add Variable
+ Variable hinzufügen
+
+
+
+ Delete Variable
+ Variable löschen
+
+
+
+ Update Settings
+ Einstellungen speichern
+
+
+
+ Default
+ Standard
+
+
+
+ Select Wine Prefix
+ Wähle Wine Prefix aus
+
+
+
+ Select Default installation directory
+ Wähle den Standardordner für Installationen
+
+
+
+ No Proton version was found
+ Keine Proton Version wurde gefunden
+
+
+
+ SettingsTab
+
+
+ Settings
+ Einstellungen
+
+
+
+ Logged in as
+ Eingeloggt als
+
+
+
+ default
+ Standard
+
+
+
+ Logout
+ Ausloggen
+
+
+
+ Developers :
+ Entwickler:
+
+
+
+ SyncSavesDialog
+
+
+ Cloud Saves
+ Cloud Speicher
+
+
+
+ Found Saves for folowing Games
+ Es wurden Speicherstände für folgende Spiele gefunden
+
+
+
+ Sync all games
+ Alle Spiele synchronisieren
+
+
+
+ No Games Found
+ Keine Spiele gefunden
+
+
+
+ Your games don't support cloud save
+ Deine Spiele unterstützen keine Cloud Speicherstände
+
+
+
+ Found no savepath
+ Kein Speicherort gefunden
+
+
+
+ No save path was found. Please select path or skip
+ Kein Speicherort wurde gefunden. Wähle einen Order aus oder überspringe
+
+
+
+ SyncWidget
+
+
+ Path not found
+ Pfad wurde nicht gefunden
+
+
+
+ Local Save date:
+ Lokales Speicherdatum:
+
+
+
+ No Local Save files
+ Keine Lokalen Speicherdateien
+
+
+
+ Cloud save date:
+ Speicherdatum in der Cloud:
+
+
+
+ No Cloud saves
+ Keine Spielstände in der Cloud
+
+
+
+ Game is up to date
+ Spielstand ist aktuell
+
+
+
+ Upload anyway
+ Trotzdem hochladen
+
+
+
+ Download anyway
+ Trotzdem runterladen
+
+
+
+ Cloud save is newer
+ Cloudspeicher ist aktueller
+
+
+
+ Download Cloud saves
+ Cloudspeicherstand herunterladen
+
+
+
+ Upload Saves
+ Speicherstand hochladen
+
+
+
+ Local save is newer
+ Lokaler Speicherstand ist neuer
+
+
+
+ Upload saves
+ Speicherstand hochladen
+
+
+
+ Download saves
+ Speicherstand herunterladen
+
+
+
+ Change path
+ Path ändern
+
+
+
+ Uploading...
+ Lade hoch...
+
+
+
+ Upload finished
+ Hochladen beendet
+
+
+
+ Downloading...
+ Herunterladen...
+
+
+
+ Download finished
+ Download beendet
+
+
+
+ SystemBrowserWidget
+
+
+ Insert Sid from Browser
+ Gebe die SID aus dem Browser ein
+
+
+
+ Insert sid from Browser
+ Gebe die SID aus dem Browser ein
+
+
+
+ Login
+ Einloggen
+
+
+
+ Loading...
+ Laden...
+
+
+
+ TabWidget
+
+
+ Games
+ Spiele
+
+
+
+ Install Games
+ Spiele installieren
+
+
+
+ Updates
+ Updates
+
+
+
+ Store
+ Webseite
+
+
+
+ Settings
+ Einstellungen
+
+
+
+ Website
+ Webseite
+
+
+
+ UninstalledGameWidget
+
+
+ Install
+ Installieren
+
+
+
+ installing
+ Installiert gerade
+
+
+
+ Download finished
+ Download beenden
+
+
+
+ Download has finished
+ Download wurde beendet. Spiel wurde installiert
+
+
+
+ UpdateTab
+
+
+ No updates available
+ Keine Updates verfügbar
+
+
+
+ UpdateWidget
+
+
+ Update available for
+ Updates verfügbar für
+
+
+
+ Update Failed
+ Update fehlgeschlagen
+
+
+
+ Update failed
+ Update fehlgeschlagen
+
+
+
+ Update finished
+ Update beendet
+
+
+
+ Update finished in
+ Update heruntergeladen in
+
+
+
+ Cancel
+ Stoppe Update
+
+
+
diff --git a/Rare/utils/Dialogs/ImportDialog.py b/Rare/utils/Dialogs/ImportDialog.py
index b9f558d3..605d173c 100644
--- a/Rare/utils/Dialogs/ImportDialog.py
+++ b/Rare/utils/Dialogs/ImportDialog.py
@@ -13,11 +13,12 @@ logger = getLogger("ImportDialog")
class ImportDialog(QDialog):
def __init__(self, core: LegendaryCore):
super(ImportDialog, self).__init__()
+ self.imported = False
self.core = core
- self.title_text = QLabel("Select Path")
+ self.title_text = QLabel(self.tr("Select Path"))
self.path_field = QLineEdit()
self.info_text = QLabel("")
- self.import_button = QPushButton("Import")
+ self.import_button = QPushButton(self.tr("Import"))
self.import_button.clicked.connect(self.button_click)
self.layout = QVBoxLayout()
@@ -30,10 +31,10 @@ class ImportDialog(QDialog):
def button_click(self):
if self.import_game():
- QMessageBox.about(self, "Info", "Please restart App to reload installed Games")
+ self.imported = True
self.close()
else:
- self.info_text.setText("Failed to import Game")
+ self.info_text.setText(self.tr("Failed to import Game"))
def import_game(self):
path = self.path_field.text()
@@ -58,3 +59,4 @@ class ImportDialog(QDialog):
def import_dialog(self):
self.exec_()
+ return self.imported
\ No newline at end of file
diff --git a/Rare/utils/Dialogs/PathInputDialog.py b/Rare/utils/Dialogs/PathInputDialog.py
index bd679af6..653072b7 100644
--- a/Rare/utils/Dialogs/PathInputDialog.py
+++ b/Rare/utils/Dialogs/PathInputDialog.py
@@ -16,7 +16,7 @@ class PathInputDialog(QDialog):
self.info_label = CustomQLabel(text)
self.info_label.setWordWrap(True)
- self.input = PathEdit("Select directory", QFileDialog.DirectoryOnly, )
+ self.input = PathEdit(self.tr("Select directory"), QFileDialog.DirectoryOnly)
self.layout = QVBoxLayout()
self.layout.addWidget(self.info_label)
diff --git a/Rare/utils/Dialogs/SyncSaves/SyncSavesDialog.py b/Rare/utils/Dialogs/SyncSaves/SyncSavesDialog.py
index 697e1799..7436dfa7 100644
--- a/Rare/utils/Dialogs/SyncSaves/SyncSavesDialog.py
+++ b/Rare/utils/Dialogs/SyncSaves/SyncSavesDialog.py
@@ -61,8 +61,9 @@ class SyncSavesDialog(QDialog):
self.start_thread.disconnect()
QObjectCleanupHandler().add(self.layout())
self.main_layout = QVBoxLayout()
- self.title = CustomQLabel("Cloud Saves
\nFound Saves for folowing Games")
- self.sync_all_button = QPushButton("Sync all games")
+ self.title = CustomQLabel(
+ f"" + self.tr("Cloud Saves") + "
\n" + self.tr("Found Saves for folowing Games"))
+ self.sync_all_button = QPushButton(self.tr("Sync all games"))
self.sync_all_button.clicked.connect(self.sync_all)
self.main_layout.addWidget(self.title)
self.main_layout.addWidget(self.sync_all_button)
@@ -72,7 +73,7 @@ class SyncSavesDialog(QDialog):
latest_save[i.app_name] = i
logger.info(f'Got {len(latest_save)} remote save game(s)')
if len(latest_save) == 0:
- QMessageBox.information("No Games Found", "Your games don't support cloud save")
+ QMessageBox.information(self.tr("No Games Found"), self.tr("Your games don't support cloud save"))
self.close()
return
self.widgets = []
@@ -97,8 +98,8 @@ class SyncSavesDialog(QDialog):
save_path = self.core.get_save_path(w.igame.app_name)
if '%' in save_path or '{' in save_path:
self.logger.info("Could not find save_path")
- save_path = PathInputDialog("Found no savepath",
- "No save path was found. Please select path or skip")
+ save_path = PathInputDialog(self.tr("Found no savepath"),
+ self.tr("No save path was found. Please select path or skip"))
if save_path == "":
continue
else:
diff --git a/Rare/utils/Dialogs/SyncSaves/SyncWidget.py b/Rare/utils/Dialogs/SyncSaves/SyncWidget.py
index 477c3ec2..e39210c8 100644
--- a/Rare/utils/Dialogs/SyncSaves/SyncWidget.py
+++ b/Rare/utils/Dialogs/SyncSaves/SyncWidget.py
@@ -41,12 +41,7 @@ class SyncWidget(QWidget):
def __init__(self, igame: InstalledGame, save, core: LegendaryCore):
super(SyncWidget, self).__init__()
self.layout = QVBoxLayout()
- self.setObjectName("syncwidget")
- self.setStyleSheet("""
- QWidget#syncwidget{
- border: 2px solid white;
- }
- """)
+
self.core = core
self.save = save
self.logger = getLogger("Sync " + igame.app_name)
@@ -56,8 +51,8 @@ class SyncWidget(QWidget):
if not igame.save_path:
save_path = self.core.get_save_path(igame.app_name)
if '%' in save_path or '{' in save_path:
- status = "PathNotFound"
- self.logger.info("Could not find save_path")
+ status = self.tr("Path not found")
+ self.logger.info("Could not find save path")
else:
igame.save_path = save_path
@@ -70,26 +65,26 @@ class SyncWidget(QWidget):
return
game_title = CustomQLabel(f"{igame.title}
")
if dt_local:
- local_save_date = CustomQLabel(f"Local Save date: {dt_local.strftime('%Y-%m-%d %H:%M:%S')}")
+ local_save_date = CustomQLabel(self.tr("Local Save date: ")+str(dt_local.strftime('%Y-%m-%d %H:%M:%S')))
else:
- local_save_date = CustomQLabel("No Local Save files")
+ local_save_date = CustomQLabel(self.tr("No Local Save files"))
if dt_remote:
- cloud_save_date = CustomQLabel(f"Cloud save date: {dt_remote.strftime('%Y-%m-%d %H:%M:%S')}")
+ cloud_save_date = CustomQLabel(self.tr("Cloud save date: ")+str(dt_remote.strftime('%Y-%m-%d %H:%M:%S')))
else:
- cloud_save_date = CustomQLabel(f"No Cloud saves")
+ cloud_save_date = CustomQLabel(self.tr("No Cloud saves"))
if self.res == SaveGameStatus.SAME_AGE:
self.logger.info(f'Save game for "{igame.title}" is up to date')
- status = "Game is up to date"
- self.upload_button = QPushButton("Upload anyway")
- self.download_button = QPushButton("Download anyway")
+ status = self.tr("Game is up to date")
+ self.upload_button = QPushButton(self.tr("Upload anyway"))
+ self.download_button = QPushButton(self.tr("Download anyway"))
if self.res == SaveGameStatus.REMOTE_NEWER:
- status = "Cloud save is newer"
- self.download_button = QPushButton("Download Cloud saves")
+ status = self.tr("Cloud save is newer")
+ self.download_button = QPushButton(self.tr("Download Cloud saves"))
self.download_button.setStyleSheet("""
QPushButton{ background-color: lime}
""")
- self.upload_button = QPushButton("Upload Saves")
+ self.upload_button = QPushButton(self.tr("Upload Saves"))
self.logger.info(f'Cloud save for "{igame.title}" is newer:')
self.logger.info(f'- Cloud save date: {dt_remote.strftime("%Y-%m-%d %H:%M:%S")}')
if dt_local:
@@ -100,12 +95,12 @@ class SyncWidget(QWidget):
self.upload_button.setToolTip("No local save")
elif self.res == SaveGameStatus.LOCAL_NEWER:
- status = "Local save is newer"
- self.upload_button = QPushButton("Upload saves")
+ status = self.tr("Local save is newer")
+ self.upload_button = QPushButton(self.tr("Upload saves"))
self.upload_button.setStyleSheet("""
QPushButton{ background-color: lime}
""")
- self.download_button = QPushButton("Download saves")
+ self.download_button = QPushButton(self.tr("Download saves"))
self.logger.info(f'Local save for "{igame.title}" is newer')
if dt_remote:
self.logger.info(f'- Cloud save date: {dt_remote.strftime("%Y-%m-%d %H:%M:%S")}')
@@ -126,7 +121,7 @@ class SyncWidget(QWidget):
save_path_layout = QHBoxLayout()
self.save_path_text = CustomQLabel(igame.save_path)
- self.change_save_path = QPushButton("Change path")
+ self.change_save_path = QPushButton(self.tr("Change path"))
save_path_layout.addWidget(self.save_path_text)
save_path_layout.addWidget(self.change_save_path)
self.layout.addWidget(self.info_text)
@@ -139,7 +134,7 @@ class SyncWidget(QWidget):
def upload(self):
self.logger.info("Uploading Saves for game " + self.igame.title)
- self.info_text.setText("Uploading...")
+ self.info_text.setText(self.tr("Uploading..."))
self.upload_button.setDisabled(True)
self.download_button.setDisabled(True)
thr = _UploadThread(self.igame.app_name, self.save, self.igame.save_path, self.core)
@@ -147,7 +142,7 @@ class SyncWidget(QWidget):
thr.start()
def uploaded(self):
- self.info_text.setText("Upload finished")
+ self.info_text.setText(self.tr("Upload finished"))
def download(self):
if not os.path.exists(self.igame.save_path):
@@ -155,13 +150,13 @@ class SyncWidget(QWidget):
self.upload_button.setDisabled(True)
self.download_button.setDisabled(True)
self.logger.info("Downloading Saves for game " + self.igame.title)
- self.info_text.setText("Downloading...")
+ self.info_text.setText(self.tr("Downloading..."))
thr = _DownloadThread(self.igame.app_name, self.save, self.igame.save_path, self.core)
thr.finished.connect(self.downloaded)
thr.start()
def downloaded(self):
- self.info_text.setText("Download finished")
+ self.info_text.setText(self.tr("Download finished"))
self.upload_button.setDisabled(True)
self.download_button.setDisabled(True)
self.download_button.setStyleSheet("QPushButton{background-color: black}")
diff --git a/Rare/utils/RareUtils.py b/Rare/utils/RareUtils.py
index e71a6447..f8977323 100644
--- a/Rare/utils/RareUtils.py
+++ b/Rare/utils/RareUtils.py
@@ -1,13 +1,14 @@
import json
+import locale
import os
-import sys
from logging import getLogger
import requests
from PIL import Image
-from PyQt5.QtCore import pyqtSignal
+from PyQt5.QtCore import pyqtSignal, QLocale
from legendary.core import LegendaryCore
+from Rare.utils import legendaryConfig
from Rare.utils.RareConfig import IMAGE_DIR
logger = getLogger("Utils")
@@ -80,3 +81,11 @@ def download_images(signal: pyqtSignal, core: LegendaryCore):
logger.warning(f"File {IMAGE_DIR}/{game.app_name}/DieselGameBoxTall.png dowsn't exist")
signal.emit(i)
+
+def get_lang():
+ if "locale" in legendaryConfig.get_config()["Legendary"]:
+ logger.info("Found locale in Legendary config: " + legendaryConfig.get_config()["Legendary"]["locale"])
+ return legendaryConfig.get_config()["Legendary"]["locale"].split("-")[0]
+ else:
+ logger.info("Found locale in Legendary config: " + QLocale.system().name())
+ return locale.getdefaultlocale()
diff --git a/Rare/utils/constants.py b/Rare/utils/constants.py
index d473c5e0..76302732 100644
--- a/Rare/utils/constants.py
+++ b/Rare/utils/constants.py
@@ -13,7 +13,6 @@ legendary_settings = [
("Default install dir", "QLineEdit", "install_dir", ["path"]),
("Max Memory", "QLineEdit", "max_memory", ["only_int"]),
("EGL Sync", "QComboBox", "egl_sync", ["binary"]),
- ("No Wine", "QComboBox", "no_wine", ["binary"])
]
game_settings = default_settings + [