Merge branch 'main' into dev
This commit is contained in:
commit
f7f7f83101
6
.github/GenPKG.sh
vendored
6
.github/GenPKG.sh
vendored
|
@ -1,6 +0,0 @@
|
||||||
export PYTHONPATH=$PWD
|
|
||||||
version=$(python3 rare --version)
|
|
||||||
cd .github
|
|
||||||
git clone https://aur.archlinux.org/rare.git
|
|
||||||
cd ..
|
|
||||||
sed -i "s/.*pkgver=.*/pkgver=$version/" .github/rare/PKGBUILD
|
|
1
.github/rare
vendored
1
.github/rare
vendored
|
@ -1 +0,0 @@
|
||||||
Subproject commit f689dacef1b8902da34aae7eff85a1bbe8e0a0a4
|
|
62
.github/workflows/release.yml
vendored
62
.github/workflows/release.yml
vendored
|
@ -76,7 +76,7 @@ jobs:
|
||||||
- name: Build Appimage
|
- name: Build Appimage
|
||||||
run: |
|
run: |
|
||||||
appimage-builder --skip-test
|
appimage-builder --skip-test
|
||||||
mv Rare-*.AppImage ../Rare.AppImage
|
mv Rare-*.AppImage Rare.AppImage
|
||||||
|
|
||||||
- name: Upload to GitHub
|
- name: Upload to GitHub
|
||||||
uses: svenstaro/upload-release-action@2.2.1
|
uses: svenstaro/upload-release-action@2.2.1
|
||||||
|
@ -87,5 +87,65 @@ jobs:
|
||||||
tag: ${{ github.ref }}
|
tag: ${{ github.ref }}
|
||||||
overwrite: true
|
overwrite: true
|
||||||
|
|
||||||
|
cx_freeze:
|
||||||
|
runs-on: "windows-latest"
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
|
||||||
|
- name: Dependencies
|
||||||
|
run: pip3 install -r requirements.txt
|
||||||
|
|
||||||
|
- name: cx_freeze
|
||||||
|
run: pip3 install --upgrade cx_freeze wheel
|
||||||
|
|
||||||
|
- name: prepare Files
|
||||||
|
run: mv rare/__main__.py rare/Rare.py
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: python freeze.py bdist_msi
|
||||||
|
|
||||||
|
- name: Rename File
|
||||||
|
run: mv dist/* dist/Rare.msi
|
||||||
|
|
||||||
|
- name: Upload to GitHub
|
||||||
|
uses: svenstaro/upload-release-action@2.2.1
|
||||||
|
with:
|
||||||
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
file: dist/Rare.msi
|
||||||
|
asset_name: Rare.msi
|
||||||
|
tag: ${{ github.ref }}
|
||||||
|
overwrite: true
|
||||||
|
|
||||||
|
mac_os:
|
||||||
|
runs-on: macos-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: '3.9'
|
||||||
|
|
||||||
|
- name: Rare Dependencies
|
||||||
|
run: pip install -r requirements.txt
|
||||||
|
|
||||||
|
- name: install pyinstaller
|
||||||
|
run: pip install pyinstaller
|
||||||
|
|
||||||
|
- name: copy files
|
||||||
|
run: mv rare/__main__.py __main__.py
|
||||||
|
|
||||||
|
- name: run pyinstaller
|
||||||
|
run: pyinstaller -F --name Rare --add-data "rare/languages/*:rare/languages" --add-data "rare/resources/colors/*:rare/resources/colors" --add-data "rare/resources/images/*:rare/resources/images/" --add-data "rare/resources/stylesheets/RareStyle/*:rare/resources/stylesheets/RareStyle/" --windowed --icon rare/resources/images/Rare.icns __main__.py
|
||||||
|
|
||||||
|
- name: upload to GitHub
|
||||||
|
uses: svenstaro/upload-release-action@2.2.1
|
||||||
|
with:
|
||||||
|
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
file: dist/Rare.app
|
||||||
|
asset_name: Rare_MacOS.app
|
||||||
|
tag: ${{ github.ref }}
|
||||||
|
overwrite: true
|
67
.github/workflows/tests.yml
vendored
Normal file
67
.github/workflows/tests.yml
vendored
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
# For most projects, this workflow file will not need changing; you simply need
|
||||||
|
# to commit it to your repository.
|
||||||
|
#
|
||||||
|
# You may wish to alter this file to override the set of languages analyzed,
|
||||||
|
# or to provide custom queries or build logic.
|
||||||
|
#
|
||||||
|
# ******** NOTE ********
|
||||||
|
# We have attempted to detect the languages in your repository. Please check
|
||||||
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
|
# supported CodeQL languages.
|
||||||
|
#
|
||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [ main ]
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
|
||||||
|
# Learn more:
|
||||||
|
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v1
|
||||||
|
with:
|
||||||
|
languages: 'python'
|
||||||
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
# By default, queries listed here will override any specified in a config file.
|
||||||
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||||
|
|
||||||
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v1
|
||||||
|
|
||||||
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
|
# 📚 https://git.io/JvXDl
|
||||||
|
|
||||||
|
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||||
|
# and modify them (or add more) to build your code if your project
|
||||||
|
# uses a compiled language
|
||||||
|
|
||||||
|
#- run: |
|
||||||
|
# make bootstrap
|
||||||
|
# make release
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v1
|
20
README.md
20
README.md
|
@ -2,9 +2,8 @@
|
||||||
|
|
||||||
## A frontend for legendary, the open source Epic Games Launcher alternative
|
## A frontend for legendary, the open source Epic Games Launcher alternative
|
||||||
|
|
||||||
Rare is a GUI for Legendary, a command line aternative to Epic Games launcher. It is currently considered beta software.
|
Rare is a GUI for Legendary, a command line alternative to Epic Games launcher. If you run into an issue, please report
|
||||||
You will probably run into issues, so it is recommend to make a backup. If you run into an issue, please report it by
|
it by creating an issue on GitHub or on Discord: https://discord.gg/YvmABK9YSk
|
||||||
creating an issue on github or on Discord: https://discord.gg/YvmABK9YSk
|
|
||||||
|
|
||||||
![Discord Shield](https://discordapp.com/api/guilds/826881530310819914/widget.png?style=shield)
|
![Discord Shield](https://discordapp.com/api/guilds/826881530310819914/widget.png?style=shield)
|
||||||
|
|
||||||
|
@ -18,7 +17,8 @@ Linux: execute `rare` in your terminal.
|
||||||
|
|
||||||
Windows: execute `pythonw -m rare` in cmd
|
Windows: execute `pythonw -m rare` in cmd
|
||||||
|
|
||||||
It is possible to create a desktop link, or a start menu link. Execute the command above with `--desktop-shortcut` or `--startmenu-shortcut` option
|
It is possible to create a desktop link, or a start menu link. Execute the command above with `--desktop-shortcut`
|
||||||
|
or `--startmenu-shortcut` option
|
||||||
|
|
||||||
**Note**: On Linux must be `/home/user/.local/bin` in PATH and on Windows must be `PythonInstallationDirectory\Scripts`
|
**Note**: On Linux must be `/home/user/.local/bin` in PATH and on Windows must be `PythonInstallationDirectory\Scripts`
|
||||||
in PATH.
|
in PATH.
|
||||||
|
@ -32,16 +32,16 @@ There are some AUR packages available:
|
||||||
- [rare](https://aur.archlinux.org/packages/rare) - for stable releases
|
- [rare](https://aur.archlinux.org/packages/rare) - for stable releases
|
||||||
- [rare-git](https://aur.archlinux.org/packages/rare-git) - for the latest features, which are not in a stable release
|
- [rare-git](https://aur.archlinux.org/packages/rare-git) - for the latest features, which are not in a stable release
|
||||||
|
|
||||||
#### Debian based
|
|
||||||
|
|
||||||
There is a `.deb` package available from
|
|
||||||
the [releases page](https://github.com/Dummerle/Rare/releases): `sudo apt install ./Rare.deb`
|
|
||||||
|
|
||||||
#### Other
|
#### Other
|
||||||
|
|
||||||
Install via `pip`.
|
Install via `pip`.
|
||||||
|
|
||||||
## Run from source
|
### Packages
|
||||||
|
|
||||||
|
In [releases page](https://github.com/Dummerle/Rare/releases) are AppImages for Linux and a msi file for windows
|
||||||
|
available
|
||||||
|
|
||||||
|
### Run from source
|
||||||
|
|
||||||
1. Run `pip install -r requirements.txt` to get dependencies. If you use `pacman` you can
|
1. Run `pip install -r requirements.txt` to get dependencies. If you use `pacman` you can
|
||||||
run `sudo pacman --needed -S python-wheel python-setuptools python-pyqt5 python-qtawesome python-requests python-pillow`
|
run `sudo pacman --needed -S python-wheel python-setuptools python-pyqt5 python-qtawesome python-requests python-pillow`
|
||||||
|
|
|
@ -293,6 +293,37 @@ class LegendaryCore:
|
||||||
def _get_installed_game(self, app_name) -> InstalledGame:
|
def _get_installed_game(self, app_name) -> InstalledGame:
|
||||||
return self.lgd.get_installed_game(app_name)
|
return self.lgd.get_installed_game(app_name)
|
||||||
|
|
||||||
|
def get_non_asset_library_items(self, skip_ue=True) -> (List[Game], Dict[str, List[Game]]):
|
||||||
|
"""
|
||||||
|
Gets a list of Games without assets for installation, for instance Games delivered via
|
||||||
|
third-party stores that do not have assets for installation
|
||||||
|
:param skip_ue: Ingore Unreal Marketplace entries
|
||||||
|
:return: List of Games and DLC that do not have assets
|
||||||
|
"""
|
||||||
|
_ret = []
|
||||||
|
_dlc = defaultdict(list)
|
||||||
|
# get all the appnames we have to ignore
|
||||||
|
ignore = set(i.app_name for i in self.get_assets())
|
||||||
|
|
||||||
|
for libitem in self.egs.get_library_items():
|
||||||
|
if libitem['namespace'] == 'ue' and skip_ue:
|
||||||
|
continue
|
||||||
|
if libitem['appName'] in ignore:
|
||||||
|
continue
|
||||||
|
|
||||||
|
game = self.lgd.get_game_meta(libitem['appName'])
|
||||||
|
if not game:
|
||||||
|
eg_meta = self.egs.get_game_info(libitem['namespace'], libitem['catalogItemId'])
|
||||||
|
game = Game(app_name=libitem['appName'], app_version=None,
|
||||||
|
app_title=eg_meta['title'], asset_info=None, metadata=eg_meta)
|
||||||
|
self.lgd.set_game_meta(game.app_name, game)
|
||||||
|
if game.is_dlc:
|
||||||
|
_dlc[game.metadata['mainGameItem']['id']].append(game)
|
||||||
|
elif not any(i['path'] == 'mods' for i in game.metadata.get('categories', [])):
|
||||||
|
_ret.append(game)
|
||||||
|
|
||||||
|
return _ret, _dlc
|
||||||
|
|
||||||
def get_launch_parameters(self, app_name: str, offline: bool = False,
|
def get_launch_parameters(self, app_name: str, offline: bool = False,
|
||||||
user: str = None, extra_args: list = None,
|
user: str = None, extra_args: list = None,
|
||||||
wine_bin: str = None, wine_pfx: str = None,
|
wine_bin: str = None, wine_pfx: str = None,
|
||||||
|
|
82
freeze.py
Normal file
82
freeze.py
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from cx_Freeze import setup, Executable
|
||||||
|
|
||||||
|
from rare import __version__
|
||||||
|
|
||||||
|
# Packages to include
|
||||||
|
python_packages = [
|
||||||
|
"PyQt5",
|
||||||
|
'requests',
|
||||||
|
'PIL',
|
||||||
|
'qtawesome',
|
||||||
|
'psutil',
|
||||||
|
'pypresence',
|
||||||
|
'win32com'
|
||||||
|
]
|
||||||
|
|
||||||
|
# Modules to include
|
||||||
|
python_modules = []
|
||||||
|
|
||||||
|
base = None
|
||||||
|
name = None
|
||||||
|
build_options = {}
|
||||||
|
build_exe_options = {}
|
||||||
|
shortcutName = None
|
||||||
|
shortcutDir = None
|
||||||
|
bdist_msi_options = None
|
||||||
|
src_files = []
|
||||||
|
external_so_files = []
|
||||||
|
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
base = 'Win32GUI'
|
||||||
|
name = 'Rare.exe'
|
||||||
|
shortcut_table = [
|
||||||
|
('DesktopShortcut', # Shortcut
|
||||||
|
'DesktopFolder', # Directory
|
||||||
|
'Rare', # Name
|
||||||
|
'TARGETDIR', # Component
|
||||||
|
'[TARGETDIR]' + name, # Target
|
||||||
|
None, # Arguments
|
||||||
|
'A gui for Legendary.', # Description
|
||||||
|
None, # Hotkey
|
||||||
|
None, # Icon
|
||||||
|
None, # IconIndex
|
||||||
|
None, # ShowCmd
|
||||||
|
'TARGETDIR' # Working Directory
|
||||||
|
)]
|
||||||
|
msi_data = {"Shortcut": shortcut_table}
|
||||||
|
bdist_msi_options = {'data': msi_data, "all_users": False}
|
||||||
|
build_options["bdist_msi"] = bdist_msi_options
|
||||||
|
else:
|
||||||
|
name = 'Rare'
|
||||||
|
|
||||||
|
src_files += [
|
||||||
|
'LICENSE',
|
||||||
|
'README.md',
|
||||||
|
'rare/resources/images/Rare.ico',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Dependencies are automatically detected, but it might need fine tuning.
|
||||||
|
build_exe_options["packages"] = python_packages
|
||||||
|
build_exe_options["include_files"] = src_files + external_so_files
|
||||||
|
build_exe_options["includes"] = python_modules
|
||||||
|
build_exe_options["excludes"] = ["setuptools", "tkinter", "pkg_resources"]
|
||||||
|
|
||||||
|
# Set options
|
||||||
|
build_options["build_exe"] = build_exe_options
|
||||||
|
|
||||||
|
setup(name='Rare',
|
||||||
|
version=__version__,
|
||||||
|
description='A gui for Legendary.',
|
||||||
|
options=build_options,
|
||||||
|
executables=[
|
||||||
|
Executable('rare/Rare.py',
|
||||||
|
targetName=name,
|
||||||
|
icon='rare/resources/images/Rare.ico',
|
||||||
|
base=base,
|
||||||
|
shortcutName=shortcutName,
|
||||||
|
shortcutDir=shortcutDir,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
|
@ -1,6 +1,6 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
__version__ = "1.5.0"
|
__version__ = "1.6.2"
|
||||||
|
|
||||||
resources_path = os.path.join(os.path.dirname(__file__), "resources")
|
resources_path = os.path.join(os.path.dirname(__file__), "resources")
|
||||||
languages_path = os.path.join(os.path.dirname(__file__), "languages")
|
languages_path = os.path.join(os.path.dirname(__file__), "languages")
|
||||||
|
|
|
@ -36,7 +36,7 @@ def main():
|
||||||
|
|
||||||
if args.version:
|
if args.version:
|
||||||
print(__version__)
|
print(__version__)
|
||||||
exit(0)
|
return
|
||||||
try:
|
try:
|
||||||
# this object only allows one instance per machine
|
# this object only allows one instance per machine
|
||||||
me = singleton.SingleInstance()
|
me = singleton.SingleInstance()
|
||||||
|
@ -49,14 +49,16 @@ def main():
|
||||||
else:
|
else:
|
||||||
file.write("start")
|
file.write("start")
|
||||||
file.close()
|
file.close()
|
||||||
|
return
|
||||||
exit(0)
|
|
||||||
|
|
||||||
if args.subparser == "launch":
|
if args.subparser == "launch":
|
||||||
args.silent = True
|
args.silent = True
|
||||||
|
|
||||||
# start app
|
|
||||||
# Import start now, to not import everything
|
# fix error in cx_freeze
|
||||||
|
import multiprocessing
|
||||||
|
multiprocessing.freeze_support()
|
||||||
|
|
||||||
from rare.app import start
|
from rare.app import start
|
||||||
start(args)
|
start(args)
|
||||||
|
|
||||||
|
|
13
rare/app.py
13
rare/app.py
|
@ -4,8 +4,9 @@ import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
import qtawesome
|
||||||
from PyQt5.QtCore import QSettings, QTranslator
|
from PyQt5.QtCore import QSettings, QTranslator
|
||||||
from PyQt5.QtGui import QIcon
|
from PyQt5.QtGui import QIcon, QPalette
|
||||||
from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QStyleFactory
|
from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QStyleFactory
|
||||||
|
|
||||||
from custom_legendary.core import LegendaryCore
|
from custom_legendary.core import LegendaryCore
|
||||||
|
@ -72,8 +73,8 @@ class App(QApplication):
|
||||||
# Translator
|
# Translator
|
||||||
self.translator = QTranslator()
|
self.translator = QTranslator()
|
||||||
lang = settings.value("language", get_lang(), type=str)
|
lang = settings.value("language", get_lang(), type=str)
|
||||||
if os.path.exists(languages_path + lang + ".qm"):
|
if os.path.exists(p := os.path.join(languages_path, lang + ".qm")):
|
||||||
self.translator.load(languages_path + lang + ".qm")
|
self.translator.load(p)
|
||||||
logger.info("Your language is supported: " + lang)
|
logger.info("Your language is supported: " + lang)
|
||||||
elif not lang == "en":
|
elif not lang == "en":
|
||||||
logger.info("Your language is not supported")
|
logger.info("Your language is not supported")
|
||||||
|
@ -89,6 +90,8 @@ class App(QApplication):
|
||||||
custom_palette = load_color_scheme(os.path.join(resources_path, "colors", color + ".scheme"))
|
custom_palette = load_color_scheme(os.path.join(resources_path, "colors", color + ".scheme"))
|
||||||
if custom_palette is not None:
|
if custom_palette is not None:
|
||||||
self.setPalette(custom_palette)
|
self.setPalette(custom_palette)
|
||||||
|
qtawesome.set_defaults(color=custom_palette.color(QPalette.Text))
|
||||||
|
|
||||||
elif style := settings.value("style_sheet", False):
|
elif style := settings.value("style_sheet", False):
|
||||||
settings.setValue("color_scheme", "")
|
settings.setValue("color_scheme", "")
|
||||||
stylesheet = open(os.path.join(resources_path, "stylesheets", style, "stylesheet.qss")).read()
|
stylesheet = open(os.path.join(resources_path, "stylesheets", style, "stylesheet.qss")).read()
|
||||||
|
@ -96,6 +99,7 @@ class App(QApplication):
|
||||||
if os.name == "nt":
|
if os.name == "nt":
|
||||||
style_resource_path = style_resource_path.replace('\\', '/')
|
style_resource_path = style_resource_path.replace('\\', '/')
|
||||||
self.setStyleSheet(stylesheet.replace("@path@", style_resource_path))
|
self.setStyleSheet(stylesheet.replace("@path@", style_resource_path))
|
||||||
|
qtawesome.set_defaults(color="white")
|
||||||
# lk: for qresources stylesheets, not an ideal solution for modability,
|
# lk: for qresources stylesheets, not an ideal solution for modability,
|
||||||
# lk: too many extra steps and I don't like binary files in git, even as strings.
|
# lk: too many extra steps and I don't like binary files in git, even as strings.
|
||||||
# importlib.import_module("rare.resources.stylesheets." + style)
|
# importlib.import_module("rare.resources.stylesheets." + style)
|
||||||
|
@ -126,7 +130,8 @@ class App(QApplication):
|
||||||
self.mainwindow.tab_widget.downloadTab.finished.connect(lambda x: self.tray_icon.showMessage(
|
self.mainwindow.tab_widget.downloadTab.finished.connect(lambda x: self.tray_icon.showMessage(
|
||||||
self.tr("Download finished"),
|
self.tr("Download finished"),
|
||||||
self.tr("Download finished. {} is playable now").format(self.core.get_game(x[1]).app_title),
|
self.tr("Download finished. {} is playable now").format(self.core.get_game(x[1]).app_title),
|
||||||
QSystemTrayIcon.Information, 4000) if x[0] else None)
|
QSystemTrayIcon.Information, 4000) if (
|
||||||
|
x[0] and QSettings().value("notification", True, bool)) else None)
|
||||||
|
|
||||||
if not self.args.silent:
|
if not self.args.silent:
|
||||||
self.mainwindow.show()
|
self.mainwindow.show()
|
||||||
|
|
|
@ -27,6 +27,6 @@ class TabButtonWidget(QToolButton):
|
||||||
super(TabButtonWidget, self).__init__()
|
super(TabButtonWidget, self).__init__()
|
||||||
self.setText("Icon")
|
self.setText("Icon")
|
||||||
self.setPopupMode(QToolButton.InstantPopup)
|
self.setPopupMode(QToolButton.InstantPopup)
|
||||||
self.setIcon(icon(button_icon, color="white", scale_factor=1.25))
|
self.setIcon(icon(button_icon, scale_factor=1.25))
|
||||||
self.setToolTip(tool_tip)
|
self.setToolTip(tool_tip)
|
||||||
self.setIconSize(QSize(25, 25))
|
self.setIconSize(QSize(25, 25))
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from PyQt5.QtCore import QSize, pyqtSignal
|
from PyQt5.QtCore import QSize, pyqtSignal
|
||||||
from PyQt5.QtWidgets import QMenu, QTabWidget, QWidget, QWidgetAction
|
from PyQt5.QtWidgets import QMenu, QTabWidget, QWidget, QWidgetAction, QShortcut
|
||||||
from qtawesome import icon
|
from qtawesome import icon
|
||||||
|
|
||||||
from custom_legendary.core import LegendaryCore
|
from custom_legendary.core import LegendaryCore
|
||||||
|
@ -55,7 +55,7 @@ class TabWidget(QTabWidget):
|
||||||
account_button.menu().addAction(account_action)
|
account_button.menu().addAction(account_action)
|
||||||
self.tabBar().setTabButton(disabled_tab + 1, self.tabBar().RightSide, account_button)
|
self.tabBar().setTabButton(disabled_tab + 1, self.tabBar().RightSide, account_button)
|
||||||
|
|
||||||
self.addTab(self.settings, icon("fa.gear", color='white'),
|
self.addTab(self.settings, icon("fa.gear"),
|
||||||
"(!)" if self.settings.about.update_available else "")
|
"(!)" if self.settings.about.update_available else "")
|
||||||
|
|
||||||
# Signals
|
# Signals
|
||||||
|
@ -100,6 +100,16 @@ class TabWidget(QTabWidget):
|
||||||
# Open game list on click on Games tab button
|
# Open game list on click on Games tab button
|
||||||
self.tabBarClicked.connect(self.mouse_clicked)
|
self.tabBarClicked.connect(self.mouse_clicked)
|
||||||
self.setIconSize(QSize(25, 25))
|
self.setIconSize(QSize(25, 25))
|
||||||
|
|
||||||
|
# shortcuts
|
||||||
|
QShortcut("Alt+1", self).activated.connect(lambda: self.setCurrentIndex(0))
|
||||||
|
QShortcut("Alt+2", self).activated.connect(lambda: self.setCurrentIndex(1))
|
||||||
|
QShortcut("Alt+3", self).activated.connect(lambda: self.setCurrentIndex(2))
|
||||||
|
QShortcut("Alt+4", self).activated.connect(lambda: self.setCurrentIndex(5))
|
||||||
|
|
||||||
|
self.downloadTab.dl_status.connect(
|
||||||
|
self.games_tab.default_widget.game_list.installing_widget.image_widget.set_status)
|
||||||
|
|
||||||
def mouse_clicked(self, tab_num):
|
def mouse_clicked(self, tab_num):
|
||||||
if tab_num == 0:
|
if tab_num == 0:
|
||||||
self.games_tab.layout.setCurrentIndex(0)
|
self.games_tab.layout.setCurrentIndex(0)
|
||||||
|
@ -125,6 +135,7 @@ class TabWidget(QTabWidget):
|
||||||
self.setTabText(1, "Downloads" + ((" (" + str(downloads) + ")") if downloads != 0 else ""))
|
self.setTabText(1, "Downloads" + ((" (" + str(downloads) + ")") if downloads != 0 else ""))
|
||||||
self.setCurrentIndex(1)
|
self.setCurrentIndex(1)
|
||||||
self.downloadTab.install_game(download_item)
|
self.downloadTab.install_game(download_item)
|
||||||
|
self.games_tab.default_widget.game_list.start_download(download_item.options.app_name)
|
||||||
|
|
||||||
def game_imported(self, app_name: str):
|
def game_imported(self, app_name: str):
|
||||||
igame = self.core.get_installed_game(app_name)
|
igame = self.core.get_installed_game(app_name)
|
||||||
|
@ -159,6 +170,7 @@ class TabWidget(QTabWidget):
|
||||||
if update_list[0]:
|
if update_list[0]:
|
||||||
self.games_tab.default_widget.game_list.update_list(update_list[1])
|
self.games_tab.default_widget.game_list.update_list(update_list[1])
|
||||||
self.cloud_saves.reload(update_list[1])
|
self.cloud_saves.reload(update_list[1])
|
||||||
|
self.games_tab.default_widget.game_list.installing_widget.setVisible(False)
|
||||||
downloads = len(self.downloadTab.dl_queue) + len(self.downloadTab.update_widgets.keys())
|
downloads = len(self.downloadTab.dl_queue) + len(self.downloadTab.update_widgets.keys())
|
||||||
self.setTabText(1, "Downloads" + ((" (" + str(downloads) + ")") if downloads != 0 else ""))
|
self.setTabText(1, "Downloads" + ((" (" + str(downloads) + ")") if downloads != 0 else ""))
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,9 @@ class SyncWidget(QGroupBox):
|
||||||
|
|
||||||
if not igame.save_path:
|
if not igame.save_path:
|
||||||
igame.save_path = os.path.expanduser(f"~/{igame.app_name}/")
|
igame.save_path = os.path.expanduser(f"~/{igame.app_name}/")
|
||||||
QMessageBox.warning(self, "Savepath error", self.tr("Please edit save path of game {} manually in Cload saves tab").format(igame.title))
|
QMessageBox.warning(self, "Savepath error",
|
||||||
|
self.tr("Please edit save path of game {} manually in Cload saves tab").format(
|
||||||
|
igame.title))
|
||||||
if igame.save_path and not os.path.exists(igame.save_path):
|
if igame.save_path and not os.path.exists(igame.save_path):
|
||||||
os.makedirs(igame.save_path)
|
os.makedirs(igame.save_path)
|
||||||
self.core.lgd.set_installed_game(self.igame.app_name, self.igame)
|
self.core.lgd.set_installed_game(self.igame.app_name, self.igame)
|
||||||
|
|
|
@ -21,6 +21,7 @@ class DownloadTab(QWidget):
|
||||||
finished = pyqtSignal(tuple)
|
finished = pyqtSignal(tuple)
|
||||||
thread: QThread
|
thread: QThread
|
||||||
dl_queue = []
|
dl_queue = []
|
||||||
|
dl_status = pyqtSignal(int)
|
||||||
|
|
||||||
def __init__(self, core: LegendaryCore, updates: list, parent):
|
def __init__(self, core: LegendaryCore, updates: list, parent):
|
||||||
super(DownloadTab, self).__init__(parent=parent)
|
super(DownloadTab, self).__init__(parent=parent)
|
||||||
|
@ -120,16 +121,6 @@ class DownloadTab(QWidget):
|
||||||
pass
|
pass
|
||||||
elif text == "finish":
|
elif text == "finish":
|
||||||
self.installing_game.setText(self.tr("Download finished. Reload library"))
|
self.installing_game.setText(self.tr("Download finished. Reload library"))
|
||||||
if QSettings().value("notification", True, bool):
|
|
||||||
try:
|
|
||||||
from notifypy import Notify
|
|
||||||
except ModuleNotFoundError:
|
|
||||||
logger.warning("No Notification Module found")
|
|
||||||
else:
|
|
||||||
notification = Notify()
|
|
||||||
notification.title = self.tr("Installation finished")
|
|
||||||
notification.message = self.tr("Finished Download of game {}").format(self.active_game.app_title)
|
|
||||||
notification.send()
|
|
||||||
# QMessageBox.information(self, "Info", "Download finished")
|
# QMessageBox.information(self, "Info", "Download finished")
|
||||||
logger.info("Download finished: " + self.active_game.app_title)
|
logger.info("Download finished: " + self.active_game.app_title)
|
||||||
|
|
||||||
|
@ -184,6 +175,7 @@ class DownloadTab(QWidget):
|
||||||
self.downloaded.setText(
|
self.downloaded.setText(
|
||||||
self.tr("Downloaded") + f": {get_size(ui_update.total_downloaded)} / {get_size(self.analysis.dl_size)}")
|
self.tr("Downloaded") + f": {get_size(ui_update.total_downloaded)} / {get_size(self.analysis.dl_size)}")
|
||||||
self.time_left.setText(self.tr("Time left: ") + self.get_time(ui_update.estimated_time_left))
|
self.time_left.setText(self.tr("Time left: ") + self.get_time(ui_update.estimated_time_left))
|
||||||
|
self.dl_status.emit(int(100 * ui_update.total_downloaded / self.analysis.dl_size))
|
||||||
|
|
||||||
def get_time(self, seconds: int) -> str:
|
def get_time(self, seconds: int) -> str:
|
||||||
return str(datetime.timedelta(seconds=seconds))
|
return str(datetime.timedelta(seconds=seconds))
|
||||||
|
|
|
@ -20,14 +20,14 @@ class DlWidget(QWidget):
|
||||||
self.layout = QHBoxLayout()
|
self.layout = QHBoxLayout()
|
||||||
|
|
||||||
self.left_layout = QVBoxLayout()
|
self.left_layout = QVBoxLayout()
|
||||||
self.move_up_button = QPushButton(icon("fa.arrow-up", color="white"), "")
|
self.move_up_button = QPushButton(icon("fa.arrow-up"), "")
|
||||||
if index == 0:
|
if index == 0:
|
||||||
self.move_up_button.setDisabled(True)
|
self.move_up_button.setDisabled(True)
|
||||||
self.move_up_button.clicked.connect(lambda: self.move_up.emit(self.app_name))
|
self.move_up_button.clicked.connect(lambda: self.move_up.emit(self.app_name))
|
||||||
self.move_up_button.setFixedWidth(20)
|
self.move_up_button.setFixedWidth(20)
|
||||||
self.left_layout.addWidget(self.move_up_button)
|
self.left_layout.addWidget(self.move_up_button)
|
||||||
|
|
||||||
self.move_down_buttton = QPushButton(icon("fa.arrow-down", color="white"), "")
|
self.move_down_buttton = QPushButton(icon("fa.arrow-down"), "")
|
||||||
self.move_down_buttton.clicked.connect(lambda: self.move_down.emit(self.app_name))
|
self.move_down_buttton.clicked.connect(lambda: self.move_down.emit(self.app_name))
|
||||||
self.left_layout.addWidget(self.move_down_buttton)
|
self.left_layout.addWidget(self.move_down_buttton)
|
||||||
self.move_down_buttton.setFixedWidth(20)
|
self.move_down_buttton.setFixedWidth(20)
|
||||||
|
|
|
@ -95,12 +95,13 @@ class GameListHeadBar(QWidget):
|
||||||
self.filter.addItems([self.tr("All"),
|
self.filter.addItems([self.tr("All"),
|
||||||
self.tr("Installed only"),
|
self.tr("Installed only"),
|
||||||
self.tr("Offline Games"),
|
self.tr("Offline Games"),
|
||||||
self.tr("32 Bit Games")])
|
self.tr("32 Bit Games"),
|
||||||
|
self.tr("Installable Games")])
|
||||||
self.filter.currentIndexChanged.connect(self.filter_changed)
|
self.filter.currentIndexChanged.connect(self.filter_changed)
|
||||||
self.layout.addWidget(self.filter)
|
self.layout.addWidget(self.filter)
|
||||||
self.layout.addStretch(1)
|
self.layout.addStretch(1)
|
||||||
|
|
||||||
self.import_game = QPushButton(icon("mdi.import", color="white"), self.tr("Import Game"))
|
self.import_game = QPushButton(icon("mdi.import"), self.tr("Import Game"))
|
||||||
self.layout.addWidget(self.import_game)
|
self.layout.addWidget(self.import_game)
|
||||||
|
|
||||||
self.layout.addStretch(1)
|
self.layout.addStretch(1)
|
||||||
|
@ -109,24 +110,23 @@ class GameListHeadBar(QWidget):
|
||||||
self.search_bar.setObjectName("search_bar")
|
self.search_bar.setObjectName("search_bar")
|
||||||
self.search_bar.setFrame(False)
|
self.search_bar.setFrame(False)
|
||||||
icon_label = QLabel()
|
icon_label = QLabel()
|
||||||
icon_label.setPixmap(icon("fa.search", color="white").pixmap(QSize(20, 20)))
|
icon_label.setPixmap(icon("fa.search").pixmap(QSize(20, 20)))
|
||||||
self.layout.addWidget(icon_label)
|
self.layout.addWidget(icon_label)
|
||||||
self.search_bar.setMinimumWidth(200)
|
self.search_bar.setMinimumWidth(200)
|
||||||
self.search_bar.setPlaceholderText(self.tr("Search Game"))
|
self.search_bar.setPlaceholderText(self.tr("Search Game"))
|
||||||
self.layout.addWidget(self.search_bar)
|
self.layout.addWidget(self.search_bar)
|
||||||
|
|
||||||
self.layout.addStretch(2)
|
self.layout.addStretch(2)
|
||||||
|
|
||||||
checked = QSettings().value("icon_view", True, bool)
|
checked = QSettings().value("icon_view", True, bool)
|
||||||
|
|
||||||
self.view = SelectViewWidget(checked)
|
self.view = SelectViewWidget(checked)
|
||||||
self.layout.addWidget(self.view)
|
self.layout.addWidget(self.view)
|
||||||
self.layout.addStretch(1)
|
self.layout.addStretch(1)
|
||||||
self.refresh_list = QPushButton()
|
self.refresh_list = QPushButton()
|
||||||
self.refresh_list.setIcon(icon("fa.refresh", color="white")) # Reload icon
|
self.refresh_list.setIcon(icon("fa.refresh")) # Reload icon
|
||||||
self.layout.addWidget(self.refresh_list)
|
self.layout.addWidget(self.refresh_list)
|
||||||
|
|
||||||
self.setLayout(self.layout)
|
self.setLayout(self.layout)
|
||||||
|
|
||||||
def filter_changed(self, i):
|
def filter_changed(self, i):
|
||||||
self.filter_changed_signal.emit(["", "installed", "offline", "32bit"][i])
|
self.filter_changed_signal.emit(["", "installed", "offline", "32bit", "installable"][i])
|
||||||
|
|
|
@ -27,7 +27,7 @@ class InfoTabs(QTabWidget):
|
||||||
self.setTabBar(SideTabBar())
|
self.setTabBar(SideTabBar())
|
||||||
self.setTabPosition(QTabWidget.West)
|
self.setTabPosition(QTabWidget.West)
|
||||||
|
|
||||||
self.addTab(QWidget(), icon("mdi.keyboard-backspace", color="white"), self.tr("Back"))
|
self.addTab(QWidget(), icon("mdi.keyboard-backspace"), self.tr("Back"))
|
||||||
self.tabBarClicked.connect(lambda x: self.parent().layout.setCurrentIndex(0) if x == 0 else None)
|
self.tabBarClicked.connect(lambda x: self.parent().layout.setCurrentIndex(0) if x == 0 else None)
|
||||||
|
|
||||||
self.info = GameInfo(core, self)
|
self.info = GameInfo(core, self)
|
||||||
|
@ -60,7 +60,6 @@ class InfoTabs(QTabWidget):
|
||||||
self.parent().layout.setCurrentIndex(0)
|
self.parent().layout.setCurrentIndex(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class GameInfo(QWidget, Ui_GameInfo):
|
class GameInfo(QWidget, Ui_GameInfo):
|
||||||
igame: InstalledGame
|
igame: InstalledGame
|
||||||
game: Game
|
game: Game
|
||||||
|
|
|
@ -25,7 +25,7 @@ class UninstalledTabInfo(QTabWidget):
|
||||||
self.setTabBar(SideTabBar())
|
self.setTabBar(SideTabBar())
|
||||||
self.setTabPosition(QTabWidget.West)
|
self.setTabPosition(QTabWidget.West)
|
||||||
|
|
||||||
self.addTab(QWidget(), icon("mdi.keyboard-backspace", color="white"), self.tr("Back"))
|
self.addTab(QWidget(), icon("mdi.keyboard-backspace"), self.tr("Back"))
|
||||||
self.tabBarClicked.connect(lambda x: self.parent().layout.setCurrentIndex(0) if x == 0 else None)
|
self.tabBarClicked.connect(lambda x: self.parent().layout.setCurrentIndex(0) if x == 0 else None)
|
||||||
|
|
||||||
self.info = UninstalledInfo(core, self)
|
self.info = UninstalledInfo(core, self)
|
||||||
|
@ -46,7 +46,10 @@ class UninstalledTabInfo(QTabWidget):
|
||||||
def update_game(self, app_name):
|
def update_game(self, app_name):
|
||||||
self.info.update_game(app_name)
|
self.info.update_game(app_name)
|
||||||
self.model.clear()
|
self.model.clear()
|
||||||
self.model.load(json.load(open(os.path.expanduser(f"~/.config/legendary/metadata/{app_name}.json"), "r")))
|
try:
|
||||||
|
self.model.load(json.load(open(os.path.expanduser(f"~/.config/legendary/metadata/{app_name}.json"), "r")))
|
||||||
|
except: # ignore if no metadata
|
||||||
|
pass
|
||||||
|
|
||||||
def keyPressEvent(self, e: QKeyEvent):
|
def keyPressEvent(self, e: QKeyEvent):
|
||||||
if e.key() == Qt.Key_Escape:
|
if e.key() == Qt.Key_Escape:
|
||||||
|
@ -62,6 +65,8 @@ class UninstalledInfo(QWidget, Ui_GameInfo):
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.core = core
|
self.core = core
|
||||||
|
|
||||||
|
self.no_install_label.setVisible(False)
|
||||||
|
|
||||||
if platform.system() != "Windows":
|
if platform.system() != "Windows":
|
||||||
self.steam_worker = SteamWorker(self.core)
|
self.steam_worker = SteamWorker(self.core)
|
||||||
self.steam_worker.rating_signal.connect(self.grade.setText)
|
self.steam_worker.rating_signal.connect(self.grade.setText)
|
||||||
|
@ -71,6 +76,8 @@ class UninstalledInfo(QWidget, Ui_GameInfo):
|
||||||
self.lbl_grade.setVisible(False)
|
self.lbl_grade.setVisible(False)
|
||||||
self.grade.setVisible(False)
|
self.grade.setVisible(False)
|
||||||
|
|
||||||
|
self.non_asset_games = [i.app_name for i in self.core.get_non_asset_library_items()[0]]
|
||||||
|
|
||||||
self.install_size.setEnabled(False)
|
self.install_size.setEnabled(False)
|
||||||
self.lbl_install_size.setEnabled(False)
|
self.lbl_install_size.setEnabled(False)
|
||||||
self.install_path.setEnabled(False)
|
self.install_path.setEnabled(False)
|
||||||
|
@ -83,6 +90,7 @@ class UninstalledInfo(QWidget, Ui_GameInfo):
|
||||||
|
|
||||||
def update_game(self, app_name):
|
def update_game(self, app_name):
|
||||||
self.game = self.core.get_game(app_name)
|
self.game = self.core.get_game(app_name)
|
||||||
|
|
||||||
self.game_title.setText(f"<h2>{self.game.app_title}</h2>")
|
self.game_title.setText(f"<h2>{self.game.app_title}</h2>")
|
||||||
|
|
||||||
pixmap = get_pixmap(app_name)
|
pixmap = get_pixmap(app_name)
|
||||||
|
@ -96,6 +104,13 @@ class UninstalledInfo(QWidget, Ui_GameInfo):
|
||||||
self.install_size.setText("N/A")
|
self.install_size.setText("N/A")
|
||||||
self.install_path.setText("N/A")
|
self.install_path.setText("N/A")
|
||||||
|
|
||||||
|
if app_name in self.non_asset_games:
|
||||||
|
self.no_install_label.setVisible(True)
|
||||||
|
self.install_button.setEnabled(False)
|
||||||
|
else:
|
||||||
|
self.no_install_label.setVisible(False)
|
||||||
|
self.install_button.setEnabled(True)
|
||||||
|
|
||||||
if platform.system() != "Windows":
|
if platform.system() != "Windows":
|
||||||
self.grade.setText(self.tr("Loading"))
|
self.grade.setText(self.tr("Loading"))
|
||||||
self.steam_worker.set_app_name(app_name)
|
self.steam_worker.set_app_name(app_name)
|
||||||
|
|
|
@ -9,6 +9,7 @@ from rare import data_dir
|
||||||
from rare.components.tabs.games.game_widgets.base_installed_widget import BaseInstalledWidget
|
from rare.components.tabs.games.game_widgets.base_installed_widget import BaseInstalledWidget
|
||||||
from rare.components.tabs.games.game_widgets.installed_icon_widget import GameWidgetInstalled
|
from rare.components.tabs.games.game_widgets.installed_icon_widget import GameWidgetInstalled
|
||||||
from rare.components.tabs.games.game_widgets.installed_list_widget import InstalledListWidget
|
from rare.components.tabs.games.game_widgets.installed_list_widget import InstalledListWidget
|
||||||
|
from rare.components.tabs.games.game_widgets.installing_game_widget import InstallingGameWidget
|
||||||
from rare.components.tabs.games.game_widgets.uninstalled_icon_widget import IconWidgetUninstalled
|
from rare.components.tabs.games.game_widgets.uninstalled_icon_widget import IconWidgetUninstalled
|
||||||
from rare.components.tabs.games.game_widgets.uninstalled_list_widget import ListWidgetUninstalled
|
from rare.components.tabs.games.game_widgets.uninstalled_list_widget import ListWidgetUninstalled
|
||||||
from rare.utils.extra_widgets import FlowLayout
|
from rare.utils.extra_widgets import FlowLayout
|
||||||
|
@ -34,7 +35,7 @@ class GameList(QStackedWidget):
|
||||||
self.core = core
|
self.core = core
|
||||||
self.setObjectName("list_widget")
|
self.setObjectName("list_widget")
|
||||||
self.offline = offline
|
self.offline = offline
|
||||||
|
self.installing_widget = InstallingGameWidget()
|
||||||
self.settings = QSettings()
|
self.settings = QSettings()
|
||||||
icon_view = self.settings.value("icon_view", True, bool)
|
icon_view = self.settings.value("icon_view", True, bool)
|
||||||
self.procs = []
|
self.procs = []
|
||||||
|
@ -77,11 +78,16 @@ class GameList(QStackedWidget):
|
||||||
if not self.offline:
|
if not self.offline:
|
||||||
self.bit32 = [i.app_name for i in self.core.get_game_and_dlc_list(True, "Win32")[0]]
|
self.bit32 = [i.app_name for i in self.core.get_game_and_dlc_list(True, "Win32")[0]]
|
||||||
self.mac_games = [i.app_name for i in self.core.get_game_and_dlc_list(True, "Mac")[0]]
|
self.mac_games = [i.app_name for i in self.core.get_game_and_dlc_list(True, "Mac")[0]]
|
||||||
|
self.no_assets = [i.app_name for i in self.core.get_non_asset_library_items()[0]]
|
||||||
else:
|
else:
|
||||||
self.bit32 = []
|
self.bit32 = []
|
||||||
self.mac_games = []
|
self.mac_games = []
|
||||||
self.installed = sorted(self.core.get_installed_list(), key=lambda x: x.title)
|
self.installed = sorted(self.core.get_installed_list(), key=lambda x: x.title)
|
||||||
|
|
||||||
|
self.installing_widget = InstallingGameWidget()
|
||||||
|
self.icon_layout.addWidget(self.installing_widget)
|
||||||
|
self.installing_widget.setVisible(False)
|
||||||
|
|
||||||
# Installed Games
|
# Installed Games
|
||||||
for igame in self.installed:
|
for igame in self.installed:
|
||||||
icon_widget, list_widget = self.add_installed_widget(igame)
|
icon_widget, list_widget = self.add_installed_widget(igame)
|
||||||
|
@ -92,13 +98,13 @@ class GameList(QStackedWidget):
|
||||||
installed = [i.app_name for i in self.core.get_installed_list()]
|
installed = [i.app_name for i in self.core.get_installed_list()]
|
||||||
# get Uninstalled games
|
# get Uninstalled games
|
||||||
games, self.dlcs = self.core.get_game_and_dlc_list(update_assets=not self.offline)
|
games, self.dlcs = self.core.get_game_and_dlc_list(update_assets=not self.offline)
|
||||||
for game in sorted(games, key=lambda x: x.app_title):
|
for game in games:
|
||||||
if not game.app_name in installed:
|
if not game.app_name in installed:
|
||||||
self.uninstalled_games.append(game)
|
self.uninstalled_games.append(game)
|
||||||
|
|
||||||
# add uninstalled games
|
# add uninstalled games
|
||||||
|
self.uninstalled_games += self.core.get_non_asset_library_items()[0]
|
||||||
for game in self.uninstalled_games:
|
for game in sorted(self.uninstalled_games, key=lambda x: x.app_title):
|
||||||
icon_widget, list_widget = self.add_uninstalled_widget(game)
|
icon_widget, list_widget = self.add_uninstalled_widget(game)
|
||||||
|
|
||||||
self.icon_layout.addWidget(icon_widget)
|
self.icon_layout.addWidget(icon_widget)
|
||||||
|
@ -124,6 +130,10 @@ class GameList(QStackedWidget):
|
||||||
if filter_games := self.settings.value("filter", "", str):
|
if filter_games := self.settings.value("filter", "", str):
|
||||||
self.filter(filter_games)
|
self.filter(filter_games)
|
||||||
|
|
||||||
|
def start_download(self, app_name):
|
||||||
|
self.installing_widget.set_game(self.core.get_game(app_name))
|
||||||
|
self.installing_widget.setVisible(True)
|
||||||
|
|
||||||
def add_uninstalled_widget(self, game):
|
def add_uninstalled_widget(self, game):
|
||||||
pixmap = get_uninstalled_pixmap(game.app_name)
|
pixmap = get_uninstalled_pixmap(game.app_name)
|
||||||
if pixmap.isNull():
|
if pixmap.isNull():
|
||||||
|
@ -256,6 +266,8 @@ class GameList(QStackedWidget):
|
||||||
w.setVisible(w.game.app_name in self.bit32)
|
w.setVisible(w.game.app_name in self.bit32)
|
||||||
elif filter == "mac":
|
elif filter == "mac":
|
||||||
w.setVisible(w.game.app_name in self.mac_games)
|
w.setVisible(w.game.app_name in self.mac_games)
|
||||||
|
elif filter == "installable":
|
||||||
|
w.setVisible(w.game.app_name not in self.no_assets)
|
||||||
else:
|
else:
|
||||||
# All visible
|
# All visible
|
||||||
w.setVisible(True)
|
w.setVisible(True)
|
||||||
|
@ -348,6 +360,7 @@ class GameList(QStackedWidget):
|
||||||
i_widget, list_widget = self.widgets[name]
|
i_widget, list_widget = self.widgets[name]
|
||||||
self.icon_layout.addWidget(i_widget)
|
self.icon_layout.addWidget(i_widget)
|
||||||
self.list_layout.addWidget(list_widget)
|
self.list_layout.addWidget(list_widget)
|
||||||
|
self.installing_widget.setVisible(False)
|
||||||
|
|
||||||
def _update_games(self):
|
def _update_games(self):
|
||||||
# new layouts to remove from old layout
|
# new layouts to remove from old layout
|
||||||
|
@ -355,6 +368,7 @@ class GameList(QStackedWidget):
|
||||||
# QWidget().setLayout(self.list_layout)
|
# QWidget().setLayout(self.list_layout)
|
||||||
list_layout = QVBoxLayout()
|
list_layout = QVBoxLayout()
|
||||||
|
|
||||||
|
icon_layout.addWidget(self.installing_widget)
|
||||||
for igame in sorted(self.core.get_installed_list(), key=lambda x: x.title):
|
for igame in sorted(self.core.get_installed_list(), key=lambda x: x.title):
|
||||||
i_widget, l_widget = self.widgets[igame.app_name]
|
i_widget, l_widget = self.widgets[igame.app_name]
|
||||||
icon_layout.addWidget(i_widget)
|
icon_layout.addWidget(i_widget)
|
||||||
|
|
|
@ -50,7 +50,7 @@ class GameWidgetInstalled(BaseInstalledWidget):
|
||||||
|
|
||||||
# Info Button
|
# Info Button
|
||||||
self.menu_btn = QPushButton()
|
self.menu_btn = QPushButton()
|
||||||
self.menu_btn.setIcon(icon("ei.info-circle", color="white"))
|
self.menu_btn.setIcon(icon("ei.info-circle"))
|
||||||
# self.menu_btn.setObjectName("installed_menu_button")
|
# self.menu_btn.setObjectName("installed_menu_button")
|
||||||
self.menu_btn.setIconSize(QSize(18, 18))
|
self.menu_btn.setIconSize(QSize(18, 18))
|
||||||
self.menu_btn.enterEvent = lambda x: self.info_label.setText("Information")
|
self.menu_btn.enterEvent = lambda x: self.info_label.setText("Information")
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import os
|
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
from PyQt5.QtCore import QProcess, pyqtSignal, Qt
|
from PyQt5.QtCore import QProcess, pyqtSignal, Qt
|
||||||
|
@ -34,7 +33,7 @@ class InstalledListWidget(BaseInstalledWidget):
|
||||||
self.image.setPixmap(self.pixmap)
|
self.image.setPixmap(self.pixmap)
|
||||||
self.layout.addWidget(self.image)
|
self.layout.addWidget(self.image)
|
||||||
|
|
||||||
play_icon = icon("ei.play", color="white")
|
play_icon = icon("ei.play")
|
||||||
self.title_widget = QLabel(f"<h1>{self.igame.title}</h1>")
|
self.title_widget = QLabel(f"<h1>{self.igame.title}</h1>")
|
||||||
self.app_name_label = QLabel(self.igame.app_name)
|
self.app_name_label = QLabel(self.igame.app_name)
|
||||||
self.launch_button = QPushButton(play_icon, self.tr("Launch"))
|
self.launch_button = QPushButton(play_icon, self.tr("Launch"))
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
from PyQt5.QtCore import Qt, QRect
|
||||||
|
from PyQt5.QtGui import QPaintEvent, QPainter, QPixmap, QPen, QFont, QColor
|
||||||
|
from PyQt5.QtWidgets import QGroupBox, QVBoxLayout, QLabel, QHBoxLayout, QWidget
|
||||||
|
|
||||||
|
from custom_legendary.models.game import Game
|
||||||
|
from rare.utils.utils import get_pixmap, get_uninstalled_pixmap, optimal_text_background, text_color_for_background
|
||||||
|
|
||||||
|
|
||||||
|
class InstallingGameWidget(QGroupBox):
|
||||||
|
def __init__(self):
|
||||||
|
super(InstallingGameWidget, self).__init__()
|
||||||
|
self.setObjectName("game_widget_icon")
|
||||||
|
|
||||||
|
self.setLayout(QVBoxLayout())
|
||||||
|
|
||||||
|
self.pixmap = QPixmap()
|
||||||
|
w = 200
|
||||||
|
# self.pixmap = self.pixmap.scaled(w, int(w * 4 / 3), transformMode=Qt.SmoothTransformation)
|
||||||
|
self.image_widget = PaintWidget()
|
||||||
|
self.image_widget.setFixedSize(w, int(w * 4 / 3))
|
||||||
|
self.layout().addWidget(self.image_widget)
|
||||||
|
|
||||||
|
self.title_label = QLabel(f"<h4>Error</h4>")
|
||||||
|
self.title_label.setAutoFillBackground(False)
|
||||||
|
self.title_label.setWordWrap(True)
|
||||||
|
self.title_label.setFixedWidth(175)
|
||||||
|
minilayout = QHBoxLayout()
|
||||||
|
self.setObjectName("game_widget")
|
||||||
|
minilayout.addWidget(self.title_label)
|
||||||
|
self.layout().addLayout(minilayout)
|
||||||
|
|
||||||
|
def set_game(self, game: Game):
|
||||||
|
self.title_label.setText(f"<h4>{game.app_title}</h4>")
|
||||||
|
self.pixmap = get_pixmap(game.app_name)
|
||||||
|
w = 200
|
||||||
|
self.pixmap = self.pixmap.scaled(w, int(w * 4 / 3), transformMode=Qt.SmoothTransformation)
|
||||||
|
self.image_widget.set_game(self.pixmap, game.app_name)
|
||||||
|
|
||||||
|
|
||||||
|
class PaintWidget(QWidget):
|
||||||
|
def __init__(self):
|
||||||
|
super(PaintWidget, self).__init__()
|
||||||
|
|
||||||
|
def set_game(self, pixmap: QPixmap, app_name):
|
||||||
|
self.image = pixmap
|
||||||
|
self.setFixedSize(self.image.size())
|
||||||
|
self.new_image = get_uninstalled_pixmap(app_name)
|
||||||
|
self.status = 0
|
||||||
|
pixel_list = []
|
||||||
|
for x in range(self.image.width()):
|
||||||
|
for y in range(self.image.height()):
|
||||||
|
# convert pixmap to qimage, get pixel and remove alpha channel
|
||||||
|
pixel_list.append(self.image.toImage().pixelColor(x, y).getRgb()[:-1])
|
||||||
|
|
||||||
|
self.rgb_tuple = optimal_text_background(pixel_list)
|
||||||
|
|
||||||
|
def paintEvent(self, a0: QPaintEvent) -> None:
|
||||||
|
painter = QPainter()
|
||||||
|
painter.begin(self)
|
||||||
|
painter.drawPixmap(self.rect(), self.image)
|
||||||
|
|
||||||
|
w = self.image.width() * (1 - self.status / 100)
|
||||||
|
painter.drawPixmap(self.image.width() - w, 0, w, self.image.height(),
|
||||||
|
self.new_image.copy(QRect(self.image.width() - w, 0, w, self.image.height())))
|
||||||
|
|
||||||
|
# Draw Circle
|
||||||
|
pen = QPen(QColor(*self.rgb_tuple), 3)
|
||||||
|
painter.setPen(pen)
|
||||||
|
painter.setBrush(QColor(*self.rgb_tuple))
|
||||||
|
painter.drawEllipse(int(self.width() / 2) - 20, int(self.height() / 2) - 20, 40, 40)
|
||||||
|
|
||||||
|
# draw text
|
||||||
|
painter.setPen(QColor(*text_color_for_background(self.rgb_tuple)))
|
||||||
|
painter.setFont(QFont(None, 16))
|
||||||
|
painter.drawText(a0.rect(), Qt.AlignCenter, str(self.status) + "%")
|
||||||
|
painter.end()
|
||||||
|
|
||||||
|
def set_status(self, s: int):
|
||||||
|
self.status = s
|
||||||
|
self.repaint()
|
|
@ -23,7 +23,7 @@ class ImportWidget(QWidget):
|
||||||
self.game_list = [i.app_name for i in self.core.get_game_list()]
|
self.game_list = [i.app_name for i in self.core.get_game_list()]
|
||||||
|
|
||||||
self.main_layout = QHBoxLayout()
|
self.main_layout = QHBoxLayout()
|
||||||
self.back_button = QPushButton(icon("mdi.keyboard-backspace", color="white"), self.tr("Back"))
|
self.back_button = QPushButton(icon("mdi.keyboard-backspace"), self.tr("Back"))
|
||||||
self.right_layout = QVBoxLayout()
|
self.right_layout = QVBoxLayout()
|
||||||
self.right_layout.addWidget(self.back_button)
|
self.right_layout.addWidget(self.back_button)
|
||||||
self.right_layout.addStretch(1)
|
self.right_layout.addStretch(1)
|
||||||
|
|
|
@ -42,7 +42,7 @@ class LegendarySettings(QStackedWidget, Ui_legendary_settings):
|
||||||
|
|
||||||
self.back_button.clicked.connect(lambda: self.setCurrentIndex(0))
|
self.back_button.clicked.connect(lambda: self.setCurrentIndex(0))
|
||||||
|
|
||||||
self.path_info.setText(self.tr(r"EGL path is at C:\ProgramData\Epic\EpicGamesLauncher\Data\Manifests"))
|
self.path_info.setText(self.tr("EGL path is at C:\\ProgramData\\Epic\\EpicGamesLauncher\\Data\\Manifests"))
|
||||||
path = os.path.expanduser("~/")
|
path = os.path.expanduser("~/")
|
||||||
if self.core.egl.programdata_path:
|
if self.core.egl.programdata_path:
|
||||||
path = self.core.egl.programdata_path
|
path = self.core.egl.programdata_path
|
||||||
|
|
|
@ -45,6 +45,7 @@ class RareSettings(QWidget, Ui_RareSettings):
|
||||||
language = self.settings.value("language", get_lang(), type=str)
|
language = self.settings.value("language", get_lang(), type=str)
|
||||||
self.logdir = os.path.join(cache_dir, "logs")
|
self.logdir = os.path.join(cache_dir, "logs")
|
||||||
|
|
||||||
|
|
||||||
# Select Image directory
|
# Select Image directory
|
||||||
# self.img_dir = PathEdit(self.img_dir_path, file_type=QFileDialog.DirectoryOnly, save_func=self.save_path)
|
# self.img_dir = PathEdit(self.img_dir_path, file_type=QFileDialog.DirectoryOnly, save_func=self.save_path)
|
||||||
# self.img_dir_layout.addWidget(self.img_dir)
|
# self.img_dir_layout.addWidget(self.img_dir)
|
||||||
|
|
Binary file not shown.
3834
rare/languages/de.ts
3834
rare/languages/de.ts
File diff suppressed because it is too large
Load diff
BIN
rare/resources/images/Rare.icns
Normal file
BIN
rare/resources/images/Rare.icns
Normal file
Binary file not shown.
|
@ -14,6 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
class Ui_GameInfo(object):
|
class Ui_GameInfo(object):
|
||||||
def setupUi(self, GameInfo):
|
def setupUi(self, GameInfo):
|
||||||
GameInfo.setObjectName("GameInfo")
|
GameInfo.setObjectName("GameInfo")
|
||||||
|
GameInfo.resize(571, 326)
|
||||||
self.layout_game_info = QtWidgets.QGridLayout(GameInfo)
|
self.layout_game_info = QtWidgets.QGridLayout(GameInfo)
|
||||||
self.layout_game_info.setObjectName("layout_game_info")
|
self.layout_game_info.setObjectName("layout_game_info")
|
||||||
self.layout_game_info_form = QtWidgets.QGridLayout()
|
self.layout_game_info_form = QtWidgets.QGridLayout()
|
||||||
|
@ -182,15 +183,20 @@ class Ui_GameInfo(object):
|
||||||
self.install_button.setStyleSheet("")
|
self.install_button.setStyleSheet("")
|
||||||
self.install_button.setObjectName("install_button")
|
self.install_button.setObjectName("install_button")
|
||||||
self.uninstalled_layout.addWidget(self.install_button)
|
self.uninstalled_layout.addWidget(self.install_button)
|
||||||
|
self.no_install_label = QtWidgets.QLabel(self.uninstalled_page)
|
||||||
|
self.no_install_label.setWordWrap(True)
|
||||||
|
self.no_install_label.setObjectName("no_install_label")
|
||||||
|
self.uninstalled_layout.addWidget(self.no_install_label)
|
||||||
self.game_actions_stack.addWidget(self.uninstalled_page)
|
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, 6, 1, 1, 1,
|
||||||
|
QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
|
||||||
self.layout_game_info.addLayout(self.layout_game_info_form, 2, 1, 1, 1)
|
self.layout_game_info.addLayout(self.layout_game_info_form, 2, 1, 1, 1)
|
||||||
self.image = QtWidgets.QLabel(GameInfo)
|
self.image = QtWidgets.QLabel(GameInfo)
|
||||||
self.image.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
self.image.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
||||||
self.image.setFrameShadow(QtWidgets.QFrame.Sunken)
|
self.image.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||||
self.image.setText("")
|
self.image.setText("")
|
||||||
self.image.setObjectName("image")
|
self.image.setObjectName("image")
|
||||||
self.layout_game_info.addWidget(self.image, 2, 0, 1, 1, QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
|
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 = QtWidgets.QLabel(GameInfo)
|
||||||
self.game_title.setText("error")
|
self.game_title.setText("error")
|
||||||
self.game_title.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
self.game_title.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||||
|
@ -198,7 +204,7 @@ class Ui_GameInfo(object):
|
||||||
self.layout_game_info.addWidget(self.game_title, 0, 0, 1, 3)
|
self.layout_game_info.addWidget(self.game_title, 0, 0, 1, 3)
|
||||||
|
|
||||||
self.retranslateUi(GameInfo)
|
self.retranslateUi(GameInfo)
|
||||||
self.game_actions_stack.setCurrentIndex(0)
|
self.game_actions_stack.setCurrentIndex(1)
|
||||||
self.verify_widget.setCurrentIndex(0)
|
self.verify_widget.setCurrentIndex(0)
|
||||||
QtCore.QMetaObject.connectSlotsByName(GameInfo)
|
QtCore.QMetaObject.connectSlotsByName(GameInfo)
|
||||||
|
|
||||||
|
@ -216,6 +222,8 @@ class Ui_GameInfo(object):
|
||||||
self.repair_button.setText(_translate("GameInfo", "Repair Instalation"))
|
self.repair_button.setText(_translate("GameInfo", "Repair Instalation"))
|
||||||
self.uninstall_button.setText(_translate("GameInfo", "Uninstall Game"))
|
self.uninstall_button.setText(_translate("GameInfo", "Uninstall Game"))
|
||||||
self.install_button.setText(_translate("GameInfo", "Install Game"))
|
self.install_button.setText(_translate("GameInfo", "Install Game"))
|
||||||
|
self.no_install_label.setText(
|
||||||
|
_translate("GameInfo", "It is not possible to install the Game. It could be from a third party store"))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -2,16 +2,24 @@
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>GameInfo</class>
|
<class>GameInfo</class>
|
||||||
<widget class="QWidget" name="GameInfo">
|
<widget class="QWidget" name="GameInfo">
|
||||||
<property name="windowTitle">
|
<property name="geometry">
|
||||||
<string>Game Info</string>
|
<rect>
|
||||||
</property>
|
<x>0</x>
|
||||||
<layout class="QGridLayout" name="layout_game_info">
|
<y>0</y>
|
||||||
<item row="2" column="1">
|
<width>571</width>
|
||||||
<layout class="QGridLayout" name="layout_game_info_form">
|
<height>326</height>
|
||||||
<property name="leftMargin">
|
</rect>
|
||||||
<number>6</number>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<property name="windowTitle">
|
||||||
|
<string>Game Info</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="layout_game_info">
|
||||||
|
<item row="2" column="1">
|
||||||
|
<layout class="QGridLayout" name="layout_game_info_form">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>6</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="rightMargin">
|
<property name="rightMargin">
|
||||||
|
@ -248,29 +256,29 @@
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="installed_page">
|
<widget class="QWidget" name="installed_page">
|
||||||
<layout class="QVBoxLayout" name="installed_layout">
|
<layout class="QVBoxLayout" name="installed_layout">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="topMargin">
|
<property name="topMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="rightMargin">
|
<property name="rightMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QStackedWidget" name="verify_widget">
|
<widget class="QStackedWidget" name="verify_widget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page_verify_button">
|
<widget class="QWidget" name="page_verify_button">
|
||||||
<layout class="QVBoxLayout" name="layout_verify_button">
|
<layout class="QVBoxLayout" name="layout_verify_button">
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
@ -343,18 +351,28 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="uninstalled_page">
|
<widget class="QWidget" name="uninstalled_page">
|
||||||
<layout class="QVBoxLayout" name="uninstalled_layout">
|
<layout class="QVBoxLayout" name="uninstalled_layout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="install_button">
|
<widget class="QPushButton" name="install_button">
|
||||||
<property name="styleSheet">
|
<property name="styleSheet">
|
||||||
<string notr="true"/>
|
<string notr="true"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Install Game</string>
|
<string>Install Game</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
<item>
|
||||||
|
<widget class="QLabel" name="no_install_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>It is not possible to install the Game. It could be from a third party store</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -14,51 +14,13 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
class Ui_RareSettings(object):
|
class Ui_RareSettings(object):
|
||||||
def setupUi(self, RareSettings):
|
def setupUi(self, RareSettings):
|
||||||
RareSettings.setObjectName("RareSettings")
|
RareSettings.setObjectName("RareSettings")
|
||||||
RareSettings.resize(544, 532)
|
|
||||||
self.rare_layout = QtWidgets.QGridLayout(RareSettings)
|
RareSettings.resize(694, 532)
|
||||||
self.rare_layout.setObjectName("rare_layout")
|
self.gridLayout = QtWidgets.QGridLayout(RareSettings)
|
||||||
self.rpc_layout = QtWidgets.QVBoxLayout()
|
self.gridLayout.setObjectName("gridLayout")
|
||||||
self.rpc_layout.setObjectName("rpc_layout")
|
self.verticalLayout_4 = QtWidgets.QVBoxLayout()
|
||||||
self.rare_layout.addLayout(self.rpc_layout, 1, 1, 1, 1)
|
self.verticalLayout_4.setObjectName("verticalLayout_4")
|
||||||
self.groupBox = QtWidgets.QGroupBox(RareSettings)
|
|
||||||
self.groupBox.setObjectName("groupBox")
|
|
||||||
self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox)
|
|
||||||
self.verticalLayout.setObjectName("verticalLayout")
|
|
||||||
self.desktop_link = QtWidgets.QPushButton(self.groupBox)
|
|
||||||
self.desktop_link.setObjectName("desktop_link")
|
|
||||||
self.verticalLayout.addWidget(self.desktop_link)
|
|
||||||
self.startmenu_link = QtWidgets.QPushButton(self.groupBox)
|
|
||||||
self.startmenu_link.setObjectName("startmenu_link")
|
|
||||||
self.verticalLayout.addWidget(self.startmenu_link)
|
|
||||||
self.rare_layout.addWidget(self.groupBox, 2, 1, 1, 1, QtCore.Qt.AlignTop)
|
|
||||||
self.settings_group = QtWidgets.QGroupBox(RareSettings)
|
|
||||||
self.settings_group.setObjectName("settings_group")
|
|
||||||
self.behavior_layout = QtWidgets.QGridLayout(self.settings_group)
|
|
||||||
self.behavior_layout.setObjectName("behavior_layout")
|
|
||||||
self.confirm_start = QtWidgets.QCheckBox(self.settings_group)
|
|
||||||
self.confirm_start.setObjectName("confirm_start")
|
|
||||||
self.behavior_layout.addWidget(self.confirm_start, 2, 0, 1, 1)
|
|
||||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
|
||||||
self.behavior_layout.addItem(spacerItem, 2, 1, 2, 1)
|
|
||||||
self.auto_sync_cloud = QtWidgets.QCheckBox(self.settings_group)
|
|
||||||
self.auto_sync_cloud.setObjectName("auto_sync_cloud")
|
|
||||||
self.behavior_layout.addWidget(self.auto_sync_cloud, 3, 0, 1, 1)
|
|
||||||
self.sys_tray = QtWidgets.QCheckBox(self.settings_group)
|
|
||||||
self.sys_tray.setObjectName("sys_tray")
|
|
||||||
self.behavior_layout.addWidget(self.sys_tray, 0, 0, 1, 1)
|
|
||||||
self.save_size = QtWidgets.QCheckBox(self.settings_group)
|
|
||||||
self.save_size.setObjectName("save_size")
|
|
||||||
self.behavior_layout.addWidget(self.save_size, 5, 0, 1, 1)
|
|
||||||
self.notification = QtWidgets.QCheckBox(self.settings_group)
|
|
||||||
self.notification.setObjectName("notification")
|
|
||||||
self.behavior_layout.addWidget(self.notification, 4, 0, 1, 1)
|
|
||||||
self.auto_update = QtWidgets.QCheckBox(self.settings_group)
|
|
||||||
self.auto_update.setObjectName("auto_update")
|
|
||||||
self.behavior_layout.addWidget(self.auto_update, 1, 0, 1, 1)
|
|
||||||
self.log_games = QtWidgets.QCheckBox(self.settings_group)
|
|
||||||
self.log_games.setObjectName("log_games")
|
|
||||||
self.behavior_layout.addWidget(self.log_games, 6, 0, 1, 1)
|
|
||||||
self.rare_layout.addWidget(self.settings_group, 2, 0, 1, 1, QtCore.Qt.AlignTop)
|
|
||||||
self.log_dir_group = QtWidgets.QGroupBox(RareSettings)
|
self.log_dir_group = QtWidgets.QGroupBox(RareSettings)
|
||||||
self.log_dir_group.setObjectName("log_dir_group")
|
self.log_dir_group.setObjectName("log_dir_group")
|
||||||
self.log_dir_layout = QtWidgets.QVBoxLayout(self.log_dir_group)
|
self.log_dir_layout = QtWidgets.QVBoxLayout(self.log_dir_group)
|
||||||
|
@ -70,11 +32,36 @@ class Ui_RareSettings(object):
|
||||||
self.log_dir_clean_button.setObjectName("log_dir_clean_button")
|
self.log_dir_clean_button.setObjectName("log_dir_clean_button")
|
||||||
self.log_dir_layout.addWidget(self.log_dir_clean_button)
|
self.log_dir_layout.addWidget(self.log_dir_clean_button)
|
||||||
self.log_dir_size_label = QtWidgets.QLabel(self.log_dir_group)
|
self.log_dir_size_label = QtWidgets.QLabel(self.log_dir_group)
|
||||||
|
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.log_dir_size_label.sizePolicy().hasHeightForWidth())
|
||||||
|
|
||||||
self.log_dir_size_label.setText("")
|
self.log_dir_size_label.setText("")
|
||||||
self.log_dir_size_label.setWordWrap(True)
|
self.log_dir_size_label.setWordWrap(True)
|
||||||
self.log_dir_size_label.setObjectName("log_dir_size_label")
|
self.log_dir_size_label.setObjectName("log_dir_size_label")
|
||||||
self.log_dir_layout.addWidget(self.log_dir_size_label)
|
self.log_dir_layout.addWidget(self.log_dir_size_label)
|
||||||
self.rare_layout.addWidget(self.log_dir_group, 0, 1, 1, 1, QtCore.Qt.AlignTop)
|
|
||||||
|
self.verticalLayout_4.addWidget(self.log_dir_group)
|
||||||
|
self.rpc_layout = QtWidgets.QVBoxLayout()
|
||||||
|
self.rpc_layout.setObjectName("rpc_layout")
|
||||||
|
self.verticalLayout_4.addLayout(self.rpc_layout)
|
||||||
|
self.groupBox = QtWidgets.QGroupBox(RareSettings)
|
||||||
|
self.groupBox.setObjectName("groupBox")
|
||||||
|
self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox)
|
||||||
|
self.verticalLayout.setObjectName("verticalLayout")
|
||||||
|
self.desktop_link = QtWidgets.QPushButton(self.groupBox)
|
||||||
|
self.desktop_link.setObjectName("desktop_link")
|
||||||
|
self.verticalLayout.addWidget(self.desktop_link)
|
||||||
|
self.startmenu_link = QtWidgets.QPushButton(self.groupBox)
|
||||||
|
self.startmenu_link.setObjectName("startmenu_link")
|
||||||
|
self.verticalLayout.addWidget(self.startmenu_link)
|
||||||
|
self.verticalLayout_4.addWidget(self.groupBox)
|
||||||
|
self.gridLayout.addLayout(self.verticalLayout_4, 0, 1, 1, 1)
|
||||||
|
self.verticalLayout_3 = QtWidgets.QVBoxLayout()
|
||||||
|
self.verticalLayout_3.setObjectName("verticalLayout_3")
|
||||||
|
|
||||||
self.interface_group = QtWidgets.QGroupBox(RareSettings)
|
self.interface_group = QtWidgets.QGroupBox(RareSettings)
|
||||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
|
||||||
sizePolicy.setHorizontalStretch(0)
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
@ -84,6 +71,16 @@ class Ui_RareSettings(object):
|
||||||
self.interface_group.setObjectName("interface_group")
|
self.interface_group.setObjectName("interface_group")
|
||||||
self.interface_layout = QtWidgets.QGridLayout(self.interface_group)
|
self.interface_layout = QtWidgets.QGridLayout(self.interface_group)
|
||||||
self.interface_layout.setObjectName("interface_layout")
|
self.interface_layout.setObjectName("interface_layout")
|
||||||
|
|
||||||
|
self.style_label = QtWidgets.QLabel(self.interface_group)
|
||||||
|
self.style_label.setObjectName("style_label")
|
||||||
|
self.interface_layout.addWidget(self.style_label, 2, 0, 1, 1, QtCore.Qt.AlignRight)
|
||||||
|
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||||
|
self.interface_layout.addItem(spacerItem, 1, 2, 1, 1)
|
||||||
|
self.lang_select = QtWidgets.QComboBox(self.interface_group)
|
||||||
|
self.lang_select.setObjectName("lang_select")
|
||||||
|
self.interface_layout.addWidget(self.lang_select, 0, 1, 1, 1)
|
||||||
|
|
||||||
self.color_select = QtWidgets.QComboBox(self.interface_group)
|
self.color_select = QtWidgets.QComboBox(self.interface_group)
|
||||||
self.color_select.setObjectName("color_select")
|
self.color_select.setObjectName("color_select")
|
||||||
self.color_select.addItem("")
|
self.color_select.addItem("")
|
||||||
|
@ -104,23 +101,40 @@ class Ui_RareSettings(object):
|
||||||
self.interface_info.setWordWrap(True)
|
self.interface_info.setWordWrap(True)
|
||||||
self.interface_info.setObjectName("interface_info")
|
self.interface_info.setObjectName("interface_info")
|
||||||
self.interface_layout.addWidget(self.interface_info, 3, 0, 1, 3)
|
self.interface_layout.addWidget(self.interface_info, 3, 0, 1, 3)
|
||||||
self.lang_label = QtWidgets.QLabel(self.interface_group)
|
|
||||||
self.lang_label.setObjectName("lang_label")
|
self.verticalLayout_3.addWidget(self.interface_group)
|
||||||
self.interface_layout.addWidget(self.lang_label, 0, 0, 1, 1, QtCore.Qt.AlignRight)
|
self.settings_group = QtWidgets.QGroupBox(RareSettings)
|
||||||
self.lang_select = QtWidgets.QComboBox(self.interface_group)
|
self.settings_group.setObjectName("settings_group")
|
||||||
self.lang_select.setObjectName("lang_select")
|
self.behavior_layout = QtWidgets.QGridLayout(self.settings_group)
|
||||||
self.interface_layout.addWidget(self.lang_select, 0, 1, 1, 1)
|
self.behavior_layout.setObjectName("behavior_layout")
|
||||||
self.color_label = QtWidgets.QLabel(self.interface_group)
|
self.save_size = QtWidgets.QCheckBox(self.settings_group)
|
||||||
self.color_label.setObjectName("color_label")
|
self.save_size.setObjectName("save_size")
|
||||||
self.interface_layout.addWidget(self.color_label, 1, 0, 1, 1, QtCore.Qt.AlignRight)
|
self.behavior_layout.addWidget(self.save_size, 5, 0, 1, 1)
|
||||||
self.rare_layout.addWidget(self.interface_group, 1, 0, 1, 1, QtCore.Qt.AlignTop)
|
self.notification = QtWidgets.QCheckBox(self.settings_group)
|
||||||
self.img_dir_group = QtWidgets.QGroupBox(RareSettings)
|
self.notification.setObjectName("notification")
|
||||||
self.img_dir_group.setObjectName("img_dir_group")
|
self.behavior_layout.addWidget(self.notification, 4, 0, 1, 1)
|
||||||
self.img_dir_layout = QtWidgets.QVBoxLayout(self.img_dir_group)
|
self.auto_sync_cloud = QtWidgets.QCheckBox(self.settings_group)
|
||||||
self.img_dir_layout.setObjectName("img_dir_layout")
|
self.auto_sync_cloud.setObjectName("auto_sync_cloud")
|
||||||
self.rare_layout.addWidget(self.img_dir_group, 0, 0, 1, 1, QtCore.Qt.AlignTop)
|
self.behavior_layout.addWidget(self.auto_sync_cloud, 3, 0, 1, 1)
|
||||||
|
self.auto_update = QtWidgets.QCheckBox(self.settings_group)
|
||||||
|
self.auto_update.setObjectName("auto_update")
|
||||||
|
self.behavior_layout.addWidget(self.auto_update, 1, 0, 1, 1)
|
||||||
|
self.sys_tray = QtWidgets.QCheckBox(self.settings_group)
|
||||||
|
self.sys_tray.setObjectName("sys_tray")
|
||||||
|
self.behavior_layout.addWidget(self.sys_tray, 0, 0, 1, 1)
|
||||||
|
self.log_games = QtWidgets.QCheckBox(self.settings_group)
|
||||||
|
self.log_games.setObjectName("log_games")
|
||||||
|
self.behavior_layout.addWidget(self.log_games, 6, 0, 1, 1)
|
||||||
|
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||||
|
self.behavior_layout.addItem(spacerItem1, 2, 1, 2, 1)
|
||||||
|
self.confirm_start = QtWidgets.QCheckBox(self.settings_group)
|
||||||
|
self.confirm_start.setObjectName("confirm_start")
|
||||||
|
self.behavior_layout.addWidget(self.confirm_start, 2, 0, 1, 1)
|
||||||
|
self.verticalLayout_3.addWidget(self.settings_group)
|
||||||
|
self.gridLayout.addLayout(self.verticalLayout_3, 0, 0, 1, 1)
|
||||||
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
spacerItem2 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||||
self.rare_layout.addItem(spacerItem2, 3, 0, 1, 2)
|
self.gridLayout.addItem(spacerItem2, 1, 0, 1, 2)
|
||||||
|
|
||||||
|
|
||||||
self.retranslateUi(RareSettings)
|
self.retranslateUi(RareSettings)
|
||||||
QtCore.QMetaObject.connectSlotsByName(RareSettings)
|
QtCore.QMetaObject.connectSlotsByName(RareSettings)
|
||||||
|
@ -128,20 +142,14 @@ class Ui_RareSettings(object):
|
||||||
def retranslateUi(self, RareSettings):
|
def retranslateUi(self, RareSettings):
|
||||||
_translate = QtCore.QCoreApplication.translate
|
_translate = QtCore.QCoreApplication.translate
|
||||||
RareSettings.setWindowTitle(_translate("RareSettings", "RareSettings"))
|
RareSettings.setWindowTitle(_translate("RareSettings", "RareSettings"))
|
||||||
self.groupBox.setTitle(_translate("RareSettings", "Shortcuts"))
|
|
||||||
self.desktop_link.setText(_translate("RareSettings", "Create Desktop link"))
|
|
||||||
self.startmenu_link.setText(_translate("RareSettings", "Create start menu link"))
|
|
||||||
self.settings_group.setTitle(_translate("RareSettings", "Behavior"))
|
|
||||||
self.confirm_start.setText(_translate("RareSettings", "Confirm game launch"))
|
|
||||||
self.auto_sync_cloud.setText(_translate("RareSettings", "Automatically sync with cloud"))
|
|
||||||
self.sys_tray.setText(_translate("RareSettings", "Exit to System tray"))
|
|
||||||
self.save_size.setText(_translate("RareSettings", "Restore window size on application startup"))
|
|
||||||
self.notification.setText(_translate("RareSettings", "Show notification on download completion"))
|
|
||||||
self.auto_update.setText(_translate("RareSettings", "Update games on application startup"))
|
|
||||||
self.log_games.setText(_translate("RareSettings", "Open console for game output"))
|
|
||||||
self.log_dir_group.setTitle(_translate("RareSettings", "Logs"))
|
self.log_dir_group.setTitle(_translate("RareSettings", "Logs"))
|
||||||
self.log_dir_open_button.setText(_translate("RareSettings", "Open Log directory"))
|
self.log_dir_open_button.setText(_translate("RareSettings", "Open Log directory"))
|
||||||
self.log_dir_clean_button.setText(_translate("RareSettings", "Clean Log directory"))
|
self.log_dir_clean_button.setText(_translate("RareSettings", "Clean Log directory"))
|
||||||
|
self.groupBox.setTitle(_translate("RareSettings", "Shortcuts"))
|
||||||
|
self.desktop_link.setText(_translate("RareSettings", "Create Desktop link"))
|
||||||
|
self.startmenu_link.setText(_translate("RareSettings", "Create start menu link"))
|
||||||
|
|
||||||
self.interface_group.setTitle(_translate("RareSettings", "Interface"))
|
self.interface_group.setTitle(_translate("RareSettings", "Interface"))
|
||||||
self.color_select.setItemText(0, _translate("RareSettings", "None"))
|
self.color_select.setItemText(0, _translate("RareSettings", "None"))
|
||||||
self.style_label.setText(_translate("RareSettings", "Style Sheet"))
|
self.style_label.setText(_translate("RareSettings", "Style Sheet"))
|
||||||
|
@ -149,7 +157,17 @@ class Ui_RareSettings(object):
|
||||||
self.interface_info.setText(_translate("RareSettings", "Restart Rare to apply."))
|
self.interface_info.setText(_translate("RareSettings", "Restart Rare to apply."))
|
||||||
self.lang_label.setText(_translate("RareSettings", "Language"))
|
self.lang_label.setText(_translate("RareSettings", "Language"))
|
||||||
self.color_label.setText(_translate("RareSettings", "Color Scheme"))
|
self.color_label.setText(_translate("RareSettings", "Color Scheme"))
|
||||||
self.img_dir_group.setTitle(_translate("RareSettings", "Image Cache Directory"))
|
|
||||||
|
self.interface_info.setText(_translate("RareSettings", "Restart Rare to apply."))
|
||||||
|
self.settings_group.setTitle(_translate("RareSettings", "Behavior"))
|
||||||
|
self.save_size.setText(_translate("RareSettings", "Restore window size on application startup"))
|
||||||
|
self.notification.setText(_translate("RareSettings", "Show notification on download completion"))
|
||||||
|
self.auto_sync_cloud.setText(_translate("RareSettings", "Automatically sync with cloud"))
|
||||||
|
self.auto_update.setText(_translate("RareSettings", "Update games on application startup"))
|
||||||
|
self.sys_tray.setText(_translate("RareSettings", "Exit to System tray"))
|
||||||
|
self.log_games.setText(_translate("RareSettings", "Show console for game debug"))
|
||||||
|
self.confirm_start.setText(_translate("RareSettings", "Confirm game launch"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -13,134 +13,251 @@
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>RareSettings</string>
|
<string>RareSettings</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="rare_layout">
|
|
||||||
<item row="1" column="1">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<layout class="QVBoxLayout" name="rpc_layout"/>
|
<item row="0" column="1">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="log_dir_group">
|
||||||
|
<property name="title">
|
||||||
|
<string>Logs</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="log_dir_layout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="log_dir_open_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Open Log directory</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="log_dir_clean_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clean Log directory</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="log_dir_size_label">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="rpc_layout"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Shortcuts</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="desktop_link">
|
||||||
|
<property name="text">
|
||||||
|
<string>Create Desktop link</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="startmenu_link">
|
||||||
|
<property name="text">
|
||||||
|
<string>Create start menu link</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1" alignment="Qt::AlignTop">
|
<item row="0" column="0">
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<property name="title">
|
<item>
|
||||||
<string>Shortcuts</string>
|
<widget class="QGroupBox" name="interface_group">
|
||||||
</property>
|
<property name="sizePolicy">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
<item>
|
<horstretch>0</horstretch>
|
||||||
<widget class="QPushButton" name="desktop_link">
|
<verstretch>0</verstretch>
|
||||||
<property name="text">
|
</sizepolicy>
|
||||||
<string>Create Desktop link</string>
|
</property>
|
||||||
</property>
|
<property name="title">
|
||||||
</widget>
|
<string>Interface</string>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<layout class="QGridLayout" name="interface_layout">
|
||||||
<widget class="QPushButton" name="startmenu_link">
|
<item row="2" column="0" alignment="Qt::AlignRight">
|
||||||
<property name="text">
|
<widget class="QLabel" name="style_label">
|
||||||
<string>Create start menu link</string>
|
<property name="text">
|
||||||
</property>
|
<string>Style Sheet</string>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
</layout>
|
</item>
|
||||||
</widget>
|
<item row="1" column="2">
|
||||||
</item>
|
<spacer name="interface_hspacer">
|
||||||
<item row="2" column="0" alignment="Qt::AlignTop">
|
<property name="orientation">
|
||||||
<widget class="QGroupBox" name="settings_group">
|
<enum>Qt::Horizontal</enum>
|
||||||
<property name="title">
|
</property>
|
||||||
<string>Behavior</string>
|
<property name="sizeHint" stdset="0">
|
||||||
</property>
|
<size>
|
||||||
<layout class="QGridLayout" name="behavior_layout">
|
<width>40</width>
|
||||||
<item row="2" column="0">
|
<height>20</height>
|
||||||
<widget class="QCheckBox" name="confirm_start">
|
</size>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Confirm game launch</string>
|
</spacer>
|
||||||
</property>
|
</item>
|
||||||
</widget>
|
<item row="0" column="1">
|
||||||
</item>
|
<widget class="QComboBox" name="lang_select"/>
|
||||||
<item row="2" column="1" rowspan="2">
|
</item>
|
||||||
<spacer name="settings_hspacer">
|
<item row="1" column="1">
|
||||||
<property name="orientation">
|
<widget class="QComboBox" name="color_select">
|
||||||
<enum>Qt::Horizontal</enum>
|
<item>
|
||||||
</property>
|
<property name="text">
|
||||||
<property name="sizeHint" stdset="0">
|
<string>None</string>
|
||||||
<size>
|
</property>
|
||||||
<width>40</width>
|
</item>
|
||||||
<height>20</height>
|
</widget>
|
||||||
</size>
|
</item>
|
||||||
</property>
|
<item row="2" column="1">
|
||||||
</spacer>
|
<widget class="QComboBox" name="style_select">
|
||||||
</item>
|
<item>
|
||||||
<item row="3" column="0">
|
<property name="text">
|
||||||
<widget class="QCheckBox" name="auto_sync_cloud">
|
<string>None</string>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Automatically sync with cloud</string>
|
</item>
|
||||||
</property>
|
</widget>
|
||||||
</widget>
|
</item>
|
||||||
</item>
|
<item row="0" column="0" alignment="Qt::AlignRight">
|
||||||
<item row="0" column="0">
|
<widget class="QLabel" name="lang_label">
|
||||||
<widget class="QCheckBox" name="sys_tray">
|
<property name="text">
|
||||||
<property name="text">
|
<string>Language</string>
|
||||||
<string>Exit to System tray</string>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
</widget>
|
</item>
|
||||||
</item>
|
<item row="1" column="0" alignment="Qt::AlignRight">
|
||||||
<item row="5" column="0">
|
<widget class="QLabel" name="color_label">
|
||||||
<widget class="QCheckBox" name="save_size">
|
<property name="text">
|
||||||
<property name="text">
|
<string>Color Scheme</string>
|
||||||
<string>Restore window size on application startup</string>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
</widget>
|
</item>
|
||||||
</item>
|
<item row="3" column="0" colspan="3">
|
||||||
<item row="4" column="0">
|
<widget class="QLabel" name="interface_info">
|
||||||
<widget class="QCheckBox" name="notification">
|
<property name="font">
|
||||||
<property name="text">
|
<font>
|
||||||
<string>Show notification on download completion</string>
|
<italic>true</italic>
|
||||||
</property>
|
</font>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
<property name="text">
|
||||||
<item row="1" column="0">
|
<string>Restart Rare to apply.</string>
|
||||||
<widget class="QCheckBox" name="auto_update">
|
</property>
|
||||||
<property name="text">
|
<property name="wordWrap">
|
||||||
<string>Update games on application startup</string>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0">
|
</layout>
|
||||||
<widget class="QCheckBox" name="log_games">
|
</widget>
|
||||||
<property name="text">
|
</item>
|
||||||
<string>Open console for game output</string>
|
<item>
|
||||||
</property>
|
<widget class="QGroupBox" name="settings_group">
|
||||||
</widget>
|
<property name="title">
|
||||||
</item>
|
<string>Behavior</string>
|
||||||
</layout>
|
</property>
|
||||||
</widget>
|
<layout class="QGridLayout" name="behavior_layout">
|
||||||
</item>
|
<item row="5" column="0">
|
||||||
<item row="0" column="1" alignment="Qt::AlignTop">
|
<widget class="QCheckBox" name="save_size">
|
||||||
<widget class="QGroupBox" name="log_dir_group">
|
<property name="text">
|
||||||
<property name="title">
|
<string>Restore window size on application startup</string>
|
||||||
<string>Logs</string>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
<layout class="QVBoxLayout" name="log_dir_layout">
|
</item>
|
||||||
<item>
|
<item row="4" column="0">
|
||||||
<widget class="QPushButton" name="log_dir_open_button">
|
<widget class="QCheckBox" name="notification">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Open Log directory</string>
|
<string>Show notification on download completion</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="3" column="0">
|
||||||
<widget class="QPushButton" name="log_dir_clean_button">
|
<widget class="QCheckBox" name="auto_sync_cloud">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Clean Log directory</string>
|
<string>Automatically sync with cloud</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="log_dir_size_label">
|
<widget class="QCheckBox" name="auto_update">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string notr="true"/>
|
<string>Update games on application startup</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
</widget>
|
||||||
<bool>true</bool>
|
</item>
|
||||||
</property>
|
<item row="0" column="0">
|
||||||
</widget>
|
<widget class="QCheckBox" name="sys_tray">
|
||||||
</item>
|
<property name="text">
|
||||||
|
<string>Exit to System tray</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QCheckBox" name="log_games">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show console for game debug</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1" rowspan="2">
|
||||||
|
<spacer name="settings_hspacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QCheckBox" name="confirm_start">
|
||||||
|
<property name="text">
|
||||||
|
<string>Confirm game launch</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -88,6 +88,8 @@ class FlowLayout(QLayout):
|
||||||
lineheight = 0
|
lineheight = 0
|
||||||
for item in self._items:
|
for item in self._items:
|
||||||
widget = item.widget()
|
widget = item.widget()
|
||||||
|
if not widget.isVisible():
|
||||||
|
continue
|
||||||
hspace = self.horizontalSpacing()
|
hspace = self.horizontalSpacing()
|
||||||
if hspace == -1:
|
if hspace == -1:
|
||||||
hspace = widget.style().layoutSpacing(
|
hspace = widget.style().layoutSpacing(
|
||||||
|
@ -229,9 +231,9 @@ class SelectViewWidget(QWidget):
|
||||||
self.list_view = QPushButton()
|
self.list_view = QPushButton()
|
||||||
if icon_view:
|
if icon_view:
|
||||||
self.icon_view_button.setIcon(icon("mdi.view-grid-outline", color="orange"))
|
self.icon_view_button.setIcon(icon("mdi.view-grid-outline", color="orange"))
|
||||||
self.list_view.setIcon(icon("fa5s.list", color="white"))
|
self.list_view.setIcon(icon("fa5s.list"))
|
||||||
else:
|
else:
|
||||||
self.icon_view_button.setIcon(icon("mdi.view-grid-outline", color="white"))
|
self.icon_view_button.setIcon(icon("mdi.view-grid-outline"))
|
||||||
self.list_view.setIcon(icon("fa5s.list", color="orange"))
|
self.list_view.setIcon(icon("fa5s.list", color="orange"))
|
||||||
|
|
||||||
self.icon_view_button.clicked.connect(self.icon)
|
self.icon_view_button.clicked.connect(self.icon)
|
||||||
|
@ -248,12 +250,12 @@ class SelectViewWidget(QWidget):
|
||||||
|
|
||||||
def icon(self):
|
def icon(self):
|
||||||
self.icon_view_button.setIcon(icon("mdi.view-grid-outline", color="orange"))
|
self.icon_view_button.setIcon(icon("mdi.view-grid-outline", color="orange"))
|
||||||
self.list_view.setIcon(icon("fa5s.list", color="white"))
|
self.list_view.setIcon(icon("fa5s.list"))
|
||||||
self.icon_view = False
|
self.icon_view = False
|
||||||
self.toggled.emit()
|
self.toggled.emit()
|
||||||
|
|
||||||
def list(self):
|
def list(self):
|
||||||
self.icon_view_button.setIcon(icon("mdi.view-grid-outline", color="white"))
|
self.icon_view_button.setIcon(icon("mdi.view-grid-outline"))
|
||||||
self.list_view.setIcon(icon("fa5s.list", color="orange"))
|
self.list_view.setIcon(icon("fa5s.list", color="orange"))
|
||||||
self.icon_view = True
|
self.icon_view = True
|
||||||
self.toggled.emit()
|
self.toggled.emit()
|
||||||
|
|
|
@ -87,6 +87,13 @@ def uninstall(app_name: str, core: LegendaryCore, options=None):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f'Removing game failed: {e!r}, please remove {igame.install_path} manually.')
|
logger.warning(f'Removing game failed: {e!r}, please remove {igame.install_path} manually.')
|
||||||
|
|
||||||
|
logger.info("Removing sections in config file")
|
||||||
|
if core.lgd.config.has_section(app_name):
|
||||||
|
core.lgd.config.remove_section(app_name)
|
||||||
|
if core.lgd.config.has_section(app_name + ".env"):
|
||||||
|
core.lgd.config.remove_section(app_name + ".env")
|
||||||
|
core.lgd.save_config()
|
||||||
|
|
||||||
|
|
||||||
class VerifyThread(QThread):
|
class VerifyThread(QThread):
|
||||||
status = pyqtSignal(tuple)
|
status = pyqtSignal(tuple)
|
||||||
|
|
|
@ -46,7 +46,9 @@ def get_rating(app_name: str, core: LegendaryCore):
|
||||||
grades = {}
|
grades = {}
|
||||||
|
|
||||||
if not grades.get(app_name):
|
if not grades.get(app_name):
|
||||||
steam_id = get_steam_id(core.get_game(app_name).app_title)
|
game = core.get_game(app_name)
|
||||||
|
|
||||||
|
steam_id = get_steam_id(game.app_title)
|
||||||
grade = get_grade(steam_id)
|
grade = get_grade(steam_id)
|
||||||
grades[app_name] = {
|
grades[app_name] = {
|
||||||
"steam_id": steam_id,
|
"steam_id": steam_id,
|
||||||
|
@ -118,7 +120,6 @@ def get_steam_id(title: str):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def check_time(): # this function check if it's time to update
|
def check_time(): # this function check if it's time to update
|
||||||
global file
|
global file
|
||||||
text = open(file, 'r')
|
text = open(file, 'r')
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import json
|
import json
|
||||||
|
import math
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
from PIL import Image, UnidentifiedImageError
|
from PIL import Image, UnidentifiedImageError
|
||||||
|
@ -21,7 +23,7 @@ from rare import languages_path, resources_path, image_dir
|
||||||
from custom_legendary.core import LegendaryCore
|
from custom_legendary.core import LegendaryCore
|
||||||
|
|
||||||
logger = getLogger("Utils")
|
logger = getLogger("Utils")
|
||||||
s = QSettings("Rare", "Rare")
|
settings = QSettings("Rare", "Rare")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,7 +37,10 @@ def download_images(signal: pyqtSignal, core: LegendaryCore):
|
||||||
dlc_list = []
|
dlc_list = []
|
||||||
for i in dlcs.values():
|
for i in dlcs.values():
|
||||||
dlc_list.append(i[0])
|
dlc_list.append(i[0])
|
||||||
game_list = games + dlc_list
|
|
||||||
|
no_assets = core.get_non_asset_library_items()[0]
|
||||||
|
|
||||||
|
game_list = games + dlc_list + no_assets
|
||||||
for i, game in enumerate(game_list):
|
for i, game in enumerate(game_list):
|
||||||
try:
|
try:
|
||||||
download_image(game)
|
download_image(game)
|
||||||
|
@ -377,3 +382,38 @@ def get_uninstalled_pixmap(app_name: str) -> QPixmap:
|
||||||
pixmap = QPixmap()
|
pixmap = QPixmap()
|
||||||
return pixmap
|
return pixmap
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def optimal_text_background(image: list) -> Tuple[int, int, int]:
|
||||||
|
"""
|
||||||
|
Finds an optimal background color for text on the image by calculating the
|
||||||
|
average color of the image and inverting it.
|
||||||
|
|
||||||
|
The image list is supposed to be a one-dimensional list of arbitrary length
|
||||||
|
containing RGB tuples, ranging from 0 to 255.
|
||||||
|
"""
|
||||||
|
# cursed, I know
|
||||||
|
average = map(lambda value: value / len(image), map(sum, zip(*image)))
|
||||||
|
inverted = map(lambda value: 255 - value, average)
|
||||||
|
return tuple(inverted)
|
||||||
|
|
||||||
|
|
||||||
|
def text_color_for_background(background: Tuple[int, int, int]) -> Tuple[int,
|
||||||
|
int,
|
||||||
|
int]:
|
||||||
|
"""
|
||||||
|
Calculates whether a black or white text color would fit better for the
|
||||||
|
given background, and returns that color. This is done by calculating the
|
||||||
|
luminance and simple comparing of bounds
|
||||||
|
"""
|
||||||
|
# see https://alienryderflex.com/hsp.html
|
||||||
|
(red, green, blue) = background
|
||||||
|
luminance = math.sqrt(
|
||||||
|
0.299 * red ** 2 +
|
||||||
|
0.587 * green ** 2 +
|
||||||
|
0.114 * blue ** 2)
|
||||||
|
if luminance < 127:
|
||||||
|
return 255, 255, 255
|
||||||
|
else:
|
||||||
|
return 0, 0, 0
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ requests
|
||||||
Pillow
|
Pillow
|
||||||
PyQt5
|
PyQt5
|
||||||
QtAwesome
|
QtAwesome
|
||||||
notify-py
|
|
||||||
psutil
|
psutil
|
||||||
pypresence
|
pypresence
|
||||||
pywin32; platform_system == "Windows"
|
pywin32; platform_system == "Windows"
|
||||||
|
|
Loading…
Reference in a new issue