7 Commits

Author SHA1 Message Date
e57770f796 chore(changelog): update
All checks were successful
Check Translations / check-translations (push) Successful in 18s
Code and build check / Check code (push) Successful in 1m43s
Code and build check / Build with uv (push) Successful in 1m0s
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-06 17:58:30 +05:00
49cd77ee38 chore(localization): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-06 17:56:57 +05:00
d26b9774a0 feat(add_game): download cover if link is provided
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-06 17:54:53 +05:00
9a27d67dc0 chore(changelog): update
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-06 17:14:29 +05:00
b0fff5af0c ci(pre-commit): exclude QSS themes from pyright and target them in qss check
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-06 17:11:35 +05:00
e54fac8aa4 feat: exclude custom_data from package
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-06 17:08:40 +05:00
f111674260 feat: rename launchers custom_data
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
2025-07-06 17:05:07 +05:00
43 changed files with 95 additions and 37 deletions

View File

@@ -1,6 +1,6 @@
# See https://pre-commit.com for more information # See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks # See https://pre-commit.com/hooks.html for more hooks
exclude: '(data/|documentation/|portprotonqt/locales/|dev-scripts/|\.venv/|venv/|.*\.svg$)' exclude: '(data/|documentation/|portprotonqt/locales/|portprotonqt/custom_data/|dev-scripts/|\.venv/|venv/|.*\.svg$)'
repos: repos:
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0 rev: v5.0.0
@@ -27,8 +27,9 @@ repos:
name: pyright name: pyright
entry: pyright entry: pyright
language: system language: system
'types_or': [python, pyi] types_or: [python, pyi]
require_serial: true require_serial: true
exclude: '^portprotonqt/themes/[^/]+/styles\.py$'
- repo: local - repo: local
hooks: hooks:
@@ -37,5 +38,5 @@ repos:
entry: ./dev-scripts/check_qss_properties.py entry: ./dev-scripts/check_qss_properties.py
language: system language: system
types: [file] types: [file]
files: \.py$ files: ^portprotonqt/themes/[^/]+/styles\.py$
pass_filenames: false pass_filenames: false

View File

@@ -7,15 +7,15 @@
### Added ### Added
- Переводы в переопределениях (за подробностями в документацию) - Переводы в переопределениях (за подробностями в документацию)
- Обложки и описания для всех автоинсталлов
- Возможность указать ссылку для скачивания обложки в диалоге добавления игры
### Changed ### Changed
- Оптимизированны обложки автоинсталлов - Оптимизированны обложки автоинсталлов
- Папка custom_data исключена из сборки модуля для уменьшение его размера
### Fixed ### Fixed
### Contributors ### Contributors
- @Vector_null - @Vector_null

View File

@@ -20,9 +20,9 @@ Current translation status:
| Locale | Progress | Translated | | Locale | Progress | Translated |
| :----- | -------: | ---------: | | :----- | -------: | ---------: |
| [de_DE](./de_DE/LC_MESSAGES/messages.po) | 0% | 0 of 192 | | [de_DE](./de_DE/LC_MESSAGES/messages.po) | 0% | 0 of 194 |
| [es_ES](./es_ES/LC_MESSAGES/messages.po) | 0% | 0 of 192 | | [es_ES](./es_ES/LC_MESSAGES/messages.po) | 0% | 0 of 194 |
| [ru_RU](./ru_RU/LC_MESSAGES/messages.po) | 100% | 192 of 192 | | [ru_RU](./ru_RU/LC_MESSAGES/messages.po) | 100% | 194 of 194 |
--- ---

View File

@@ -20,9 +20,9 @@
| Локаль | Прогресс | Переведено | | Локаль | Прогресс | Переведено |
| :----- | -------: | ---------: | | :----- | -------: | ---------: |
| [de_DE](./de_DE/LC_MESSAGES/messages.po) | 0% | 0 из 192 | | [de_DE](./de_DE/LC_MESSAGES/messages.po) | 0% | 0 из 194 |
| [es_ES](./es_ES/LC_MESSAGES/messages.po) | 0% | 0 из 192 | | [es_ES](./es_ES/LC_MESSAGES/messages.po) | 0% | 0 из 194 |
| [ru_RU](./ru_RU/LC_MESSAGES/messages.po) | 100% | 192 из 192 | | [ru_RU](./ru_RU/LC_MESSAGES/messages.po) | 100% | 194 из 194 |
--- ---

View File

Before

Width:  |  Height:  |  Size: 720 KiB

After

Width:  |  Height:  |  Size: 720 KiB

View File

Before

Width:  |  Height:  |  Size: 655 KiB

After

Width:  |  Height:  |  Size: 655 KiB

View File

Before

Width:  |  Height:  |  Size: 315 KiB

After

Width:  |  Height:  |  Size: 315 KiB

View File

Before

Width:  |  Height:  |  Size: 978 KiB

After

Width:  |  Height:  |  Size: 978 KiB

View File

Before

Width:  |  Height:  |  Size: 650 KiB

After

Width:  |  Height:  |  Size: 650 KiB

View File

Before

Width:  |  Height:  |  Size: 391 KiB

After

Width:  |  Height:  |  Size: 391 KiB

View File

Before

Width:  |  Height:  |  Size: 710 KiB

After

Width:  |  Height:  |  Size: 710 KiB

View File

Before

Width:  |  Height:  |  Size: 670 KiB

After

Width:  |  Height:  |  Size: 670 KiB

View File

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 58 KiB

View File

Before

Width:  |  Height:  |  Size: 814 KiB

After

Width:  |  Height:  |  Size: 814 KiB

View File

Before

Width:  |  Height:  |  Size: 566 KiB

After

Width:  |  Height:  |  Size: 566 KiB

View File

Before

Width:  |  Height:  |  Size: 895 KiB

After

Width:  |  Height:  |  Size: 895 KiB

View File

Before

Width:  |  Height:  |  Size: 627 KiB

After

Width:  |  Height:  |  Size: 627 KiB

View File

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

Before

Width:  |  Height:  |  Size: 722 KiB

After

Width:  |  Height:  |  Size: 722 KiB

View File

@@ -1,5 +1,6 @@
import os import os
import tempfile import tempfile
import re
from typing import cast, TYPE_CHECKING from typing import cast, TYPE_CHECKING
from PySide6.QtGui import QPixmap, QIcon from PySide6.QtGui import QPixmap, QIcon
from PySide6.QtWidgets import ( from PySide6.QtWidgets import (
@@ -14,6 +15,7 @@ from portprotonqt.logger import get_logger
import portprotonqt.themes.standart.styles as default_styles import portprotonqt.themes.standart.styles as default_styles
from portprotonqt.theme_manager import ThemeManager from portprotonqt.theme_manager import ThemeManager
from portprotonqt.custom_widgets import AutoSizeButton from portprotonqt.custom_widgets import AutoSizeButton
from portprotonqt.downloader import Downloader
if TYPE_CHECKING: if TYPE_CHECKING:
from portprotonqt.main_window import MainWindow from portprotonqt.main_window import MainWindow
@@ -449,6 +451,7 @@ class AddGameDialog(QDialog):
self.original_name = game_name self.original_name = game_name
self.last_exe_path = exe_path # Store last selected exe path self.last_exe_path = exe_path # Store last selected exe path
self.last_cover_path = cover_path # Store last selected cover path self.last_cover_path = cover_path # Store last selected cover path
self.downloader = Downloader(max_workers=4) # Initialize Downloader
self.setWindowTitle(_("Edit Game") if edit_mode else _("Add Game")) self.setWindowTitle(_("Edit Game") if edit_mode else _("Add Game"))
self.setModal(True) self.setModal(True)
@@ -472,8 +475,7 @@ class AddGameDialog(QDialog):
# Exe path # Exe path
exe_label = QLabel(_("Path to Executable:")) exe_label = QLabel(_("Path to Executable:"))
exe_label.setStyleSheet( exe_label.setStyleSheet(self.theme.PARAMS_TITLE_STYLE)
self.theme.PARAMS_TITLE_STYLE)
self.exeEdit = CustomLineEdit(self, theme=self.theme) self.exeEdit = CustomLineEdit(self, theme=self.theme)
self.exeEdit.setStyleSheet(self.theme.ADDGAME_INPUT_STYLE) self.exeEdit.setStyleSheet(self.theme.ADDGAME_INPUT_STYLE)
@@ -550,7 +552,7 @@ class AddGameDialog(QDialog):
exeBrowseButton.setFixedWidth(self.exeEdit.width()) exeBrowseButton.setFixedWidth(self.exeEdit.width())
coverBrowseButton.setFixedWidth(self.coverEdit.width()) coverBrowseButton.setFixedWidth(self.coverEdit.width())
# Вызываем после отображения окна, когда размеры установлены, чтобы реально дождаться, когда всё сформируется # Вызываем после отображения окна, когда размеры установлены
QTimer.singleShot(0, update_button_widths) QTimer.singleShot(0, update_button_widths)
# Обновляем превью, если в режиме редактирования # Обновляем превью, если в режиме редактирования
@@ -615,15 +617,46 @@ class AddGameDialog(QDialog):
"""Обработчик выбора файла обложки в FileExplorer""" """Обработчик выбора файла обложки в FileExplorer"""
if file_path and os.path.splitext(file_path)[1].lower() in ('.png', '.jpg', '.jpeg', '.bmp'): if file_path and os.path.splitext(file_path)[1].lower() in ('.png', '.jpg', '.jpeg', '.bmp'):
self.coverEdit.setText(file_path) self.coverEdit.setText(file_path)
self.last_cover_path = file_path # Update last selected cover path self.last_cover_path = file_path
self.updatePreview()
else: else:
logger.warning(f"Selected file is not a valid image: {file_path}") logger.warning(f"Selected file is not a valid image: {file_path}")
def handleDownloadedCover(self, file_path):
"""Handle the downloaded cover image and update the preview."""
if file_path and os.path.isfile(file_path):
self.last_cover_path = file_path
pixmap = QPixmap(file_path)
if not pixmap.isNull():
self.coverPreview.setPixmap(pixmap.scaled(250, 250, Qt.AspectRatioMode.KeepAspectRatio))
else:
self.coverPreview.setText(_("Invalid image"))
else:
self.coverPreview.setText(_("Failed to download cover"))
logger.warning(f"Failed to download cover to {file_path}")
def updatePreview(self): def updatePreview(self):
"""Update the cover preview image.""" """Update the cover preview image."""
cover_path = self.coverEdit.text().strip() cover_path = self.coverEdit.text().strip()
exe_path = self.exeEdit.text().strip() exe_path = self.exeEdit.text().strip()
if cover_path and os.path.isfile(cover_path):
# Check if cover_path is a URL
url_pattern = r'^https?://[^\s/$.?#].[^\s]*$'
if re.match(url_pattern, cover_path):
# Create a temporary file for the downloaded image
fd, local_path = tempfile.mkstemp(suffix=".png")
os.close(fd)
os.unlink(local_path)
# Start asynchronous download
self.downloader.download_async(
url=cover_path,
local_path=local_path,
timeout=10,
callback=self.handleDownloadedCover
)
self.coverPreview.setText(_("Downloading cover..."))
elif cover_path and os.path.isfile(cover_path):
pixmap = QPixmap(cover_path) pixmap = QPixmap(cover_path)
if not pixmap.isNull(): if not pixmap.isNull():
self.coverPreview.setPixmap(pixmap.scaled(250, 250, Qt.AspectRatioMode.KeepAspectRatio)) self.coverPreview.setPixmap(pixmap.scaled(250, 250, Qt.AspectRatioMode.KeepAspectRatio))
@@ -666,8 +699,8 @@ class AddGameDialog(QDialog):
os.makedirs(os.path.dirname(icon_path), exist_ok=True) os.makedirs(os.path.dirname(icon_path), exist_ok=True)
# Generate thumbnail (128x128) from exe # Generate thumbnail (128x128) from exe if no cover is provided
if not generate_thumbnail(exe_path, icon_path, size=128): if not self.last_cover_path and not generate_thumbnail(exe_path, icon_path, size=128):
logger.error(f"Failed to generate thumbnail from exe: {exe_path}") logger.error(f"Failed to generate thumbnail from exe: {exe_path}")
icon_path = "" # Set empty icon if generation fails icon_path = "" # Set empty icon if generation fails

View File

@@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-07-03 19:29+0700\n" "POT-Creation-Date: 2025-07-06 17:56+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: de_DE\n" "Language: de_DE\n"
@@ -296,6 +296,12 @@ msgstr ""
msgid "Invalid image" msgid "Invalid image"
msgstr "" msgstr ""
msgid "Failed to download cover"
msgstr ""
msgid "Downloading cover..."
msgstr ""
msgid "No cover selected" msgid "No cover selected"
msgstr "" msgstr ""
@@ -338,6 +344,9 @@ msgstr ""
msgid "Pending" msgid "Pending"
msgstr "" msgstr ""
msgid "Unknown Game"
msgstr ""
msgid "Library" msgid "Library"
msgstr "" msgstr ""
@@ -362,9 +371,6 @@ msgstr ""
msgid "Loading PortProton games..." msgid "Loading PortProton games..."
msgstr "" msgstr ""
msgid "Unknown Game"
msgstr ""
msgid "Game Library" msgid "Game Library"
msgstr "" msgstr ""

View File

@@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-07-03 19:29+0700\n" "POT-Creation-Date: 2025-07-06 17:56+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: es_ES\n" "Language: es_ES\n"
@@ -296,6 +296,12 @@ msgstr ""
msgid "Invalid image" msgid "Invalid image"
msgstr "" msgstr ""
msgid "Failed to download cover"
msgstr ""
msgid "Downloading cover..."
msgstr ""
msgid "No cover selected" msgid "No cover selected"
msgstr "" msgstr ""
@@ -338,6 +344,9 @@ msgstr ""
msgid "Pending" msgid "Pending"
msgstr "" msgstr ""
msgid "Unknown Game"
msgstr ""
msgid "Library" msgid "Library"
msgstr "" msgstr ""
@@ -362,9 +371,6 @@ msgstr ""
msgid "Loading PortProton games..." msgid "Loading PortProton games..."
msgstr "" msgstr ""
msgid "Unknown Game"
msgstr ""
msgid "Game Library" msgid "Game Library"
msgstr "" msgstr ""

View File

@@ -9,7 +9,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PortProtonQt 0.1.1\n" "Project-Id-Version: PortProtonQt 0.1.1\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-07-03 19:29+0700\n" "POT-Creation-Date: 2025-07-06 17:56+0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -294,6 +294,12 @@ msgstr ""
msgid "Invalid image" msgid "Invalid image"
msgstr "" msgstr ""
msgid "Failed to download cover"
msgstr ""
msgid "Downloading cover..."
msgstr ""
msgid "No cover selected" msgid "No cover selected"
msgstr "" msgstr ""
@@ -336,6 +342,9 @@ msgstr ""
msgid "Pending" msgid "Pending"
msgstr "" msgstr ""
msgid "Unknown Game"
msgstr ""
msgid "Library" msgid "Library"
msgstr "" msgstr ""
@@ -360,9 +369,6 @@ msgstr ""
msgid "Loading PortProton games..." msgid "Loading PortProton games..."
msgstr "" msgstr ""
msgid "Unknown Game"
msgstr ""
msgid "Game Library" msgid "Game Library"
msgstr "" msgstr ""

View File

@@ -9,8 +9,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2025-07-03 19:29+0700\n" "POT-Creation-Date: 2025-07-06 17:56+0500\n"
"PO-Revision-Date: 2025-07-03 19:28+0700\n" "PO-Revision-Date: 2025-07-06 17:56+0500\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language: ru_RU\n" "Language: ru_RU\n"
"Language-Team: ru_RU <LL@li.org>\n" "Language-Team: ru_RU <LL@li.org>\n"
@@ -303,6 +303,12 @@ msgstr "Применить"
msgid "Invalid image" msgid "Invalid image"
msgstr "Недопустимое изображение" msgstr "Недопустимое изображение"
msgid "Failed to download cover"
msgstr "Не удалось скачать обложку"
msgid "Downloading cover..."
msgstr "Скачивание обложки..."
msgid "No cover selected" msgid "No cover selected"
msgstr "Обложка не выбрана" msgstr "Обложка не выбрана"
@@ -345,6 +351,9 @@ msgstr "Бронза"
msgid "Pending" msgid "Pending"
msgstr "В ожидании" msgstr "В ожидании"
msgid "Unknown Game"
msgstr "Неизвестная игра"
msgid "Library" msgid "Library"
msgstr "Библиотека" msgstr "Библиотека"
@@ -369,9 +378,6 @@ msgstr "Загрузка игр из Steam..."
msgid "Loading PortProton games..." msgid "Loading PortProton games..."
msgstr "Загрузка игр из PortProton..." msgstr "Загрузка игр из PortProton..."
msgid "Unknown Game"
msgstr "Неизвестная игра"
msgid "Game Library" msgid "Game Library"
msgstr "Игровая библиотека" msgstr "Игровая библиотека"

View File

@@ -44,7 +44,7 @@ dependencies = [
portprotonqt = "portprotonqt.app:main" portprotonqt = "portprotonqt.app:main"
[tool.setuptools.package-data] [tool.setuptools.package-data]
"portprotonqt" = ["themes/**/*", "locales/**/*", "custom_data/**/*"] "portprotonqt" = ["themes/**/*", "locales/**/*"]
[tool.setuptools.packages.find] [tool.setuptools.packages.find]
exclude = ["build-aux", "dev-scripts", "documentation", "data"] exclude = ["build-aux", "dev-scripts", "documentation", "data"]