added display of installed Winetricks components

This commit is contained in:
Sergey Palcheh
2025-10-07 14:28:18 +06:00
parent e3cafee4f5
commit 9d16883e6e

View File

@@ -13,7 +13,7 @@ from functools import partial
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QTabBar, from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTabWidget, QTabBar,
QTextEdit, QFileDialog, QMessageBox, QLineEdit, QCheckBox, QStackedWidget, QScrollArea, QFormLayout, QGroupBox, QRadioButton, QComboBox, QTextEdit, QFileDialog, QMessageBox, QLineEdit, QCheckBox, QStackedWidget, QScrollArea, QFormLayout, QGroupBox, QRadioButton, QComboBox,
QListWidget, QListWidgetItem, QGridLayout, QFrame, QDialog, QTextBrowser, QInputDialog, QDialogButtonBox, QSystemTrayIcon, QMenu) QListWidget, QListWidgetItem, QGridLayout, QFrame, QDialog, QTextBrowser, QInputDialog, QDialogButtonBox, QSystemTrayIcon, QMenu)
from PyQt5.QtCore import Qt, QProcess, QSize, QTimer, QProcessEnvironment, QPropertyAnimation, QEasingCurve from PyQt5.QtCore import Qt, QProcess, QSize, QTimer, QProcessEnvironment, QPropertyAnimation, QEasingCurve, pyqtSignal
from PyQt5.QtGui import QIcon, QFont, QTextCursor, QPixmap, QPainter, QCursor from PyQt5.QtGui import QIcon, QFont, QTextCursor, QPixmap, QPainter, QCursor
from PyQt5.QtNetwork import QLocalServer, QLocalSocket from PyQt5.QtNetwork import QLocalServer, QLocalSocket
@@ -428,6 +428,8 @@ class WinetricksManagerDialog(QDialog):
"Для переустановки компонента: Выделите его в списке и нажмите кнопку «Переустановить»." "Для переустановки компонента: Выделите его в списке и нажмите кнопку «Переустановить»."
) )
installation_complete = pyqtSignal()
def __init__(self, prefix_path, winetricks_path, parent=None, wine_executable=None): def __init__(self, prefix_path, winetricks_path, parent=None, wine_executable=None):
super().__init__(parent) super().__init__(parent)
self.prefix_path = prefix_path self.prefix_path = prefix_path
@@ -885,6 +887,7 @@ class WinetricksManagerDialog(QDialog):
# Перезагружаем данные, чтобы обновить состояние # Перезагружаем данные, чтобы обновить состояние
self.initial_states.clear() self.initial_states.clear()
self.load_all_categories() self.load_all_categories()
self.installation_complete.emit()
self.installation_finished = True self.installation_finished = True
def closeEvent(self, event): def closeEvent(self, event):
@@ -2630,19 +2633,39 @@ class WineHelperGUI(QMainWindow):
self.esync_button.blockSignals(False) self.esync_button.blockSignals(False)
self.fsync_button.blockSignals(False) self.fsync_button.blockSignals(False)
# --- Чтение и отображение установленных компонентов Winetricks ---
winetricks_log_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name, "winetricks.log")
installed_verbs = []
if os.path.exists(winetricks_log_path):
try:
with open(winetricks_log_path, 'r', encoding='utf-8') as f:
for line in f:
verb = line.split('#', 1)[0].strip()
if verb:
installed_verbs.append(verb)
except IOError as e:
print(f"Ошибка чтения winetricks.log: {e}")
# Фильтруем служебные компоненты, чтобы не засорять вывод
verbs_to_ignore = {
'isolate_home', 'winxp', 'win7', 'win10', 'win11',
'vista', 'win2k', 'win2k3', 'win2k8', 'win8', 'win81',
'workaround', 'internal'
}
display_verbs = sorted([v for v in installed_verbs if v not in verbs_to_ignore])
# Карта для красивого отображения известных переменных # Карта для красивого отображения известных переменных
display_map = { display_map = {
"WINEPREFIX": ("Путь", lambda v: v), "WINEPREFIX": ("Путь", lambda v: v),
"WINEARCH": ("Архитектура", lambda v: "64-bit" if v == "win64" else "32-bit"), "WINEARCH": ("Архитектура", lambda v: "64-bit" if v == "win64" else "32-bit"),
"WH_WINE_USE": ("Версия Wine", lambda v: "Системная" if v == "system" else v), "WH_WINE_USE": ("Версия Wine", lambda v: "Системная" if v == "system" else v),
"BASE_PFX": ("Тип", lambda v: 'Чистый' if v == "none" else 'С рекомендуемыми библиотеками'),
"DXVK_VER": ("Версия DXVK", lambda v: v if v else "Не установлено"), "DXVK_VER": ("Версия DXVK", lambda v: v if v else "Не установлено"),
"VKD3D_VER": ("Версия VKD3D", lambda v: v if v else "Не установлено"), "VKD3D_VER": ("Версия VKD3D", lambda v: v if v else "Не установлено"),
"WINEESYNC": ("ESync", lambda v: "Включен" if v == "1" else "Выключен"), "WINEESYNC": ("ESync", lambda v: "Включен" if v == "1" else "Выключен"),
"WINEFSYNC": ("FSync", lambda v: "Включен" if v == "1" else "Выключен"), "WINEFSYNC": ("FSync", lambda v: "Включен" if v == "1" else "Выключен"),
"WH_XDG_OPEN": ("Ассоциации файлов", lambda v: v if v and v != "0" else "Не заданы"), "WH_XDG_OPEN": ("Ассоциации файлов", lambda v: v if v and v != "0" else "Не заданы"),
} }
display_order = ["WINEPREFIX", "WINEARCH", "WH_WINE_USE", "BASE_PFX", "DXVK_VER", "VKD3D_VER", "WINEESYNC", "WINEFSYNC", "WH_XDG_OPEN"] display_order = ["WINEPREFIX", "WINEARCH", "WH_WINE_USE", "DXVK_VER", "VKD3D_VER", "WINEESYNC", "WINEFSYNC", "WH_XDG_OPEN"]
html_content = f'<p style="line-height: 1.3; font-size: 9pt;">' html_content = f'<p style="line-height: 1.3; font-size: 9pt;">'
html_content += f"<b>Имя:</b> {html.escape(prefix_name)}<br>" html_content += f"<b>Имя:</b> {html.escape(prefix_name)}<br>"
@@ -2664,6 +2687,15 @@ class WineHelperGUI(QMainWindow):
html_content += "<br><b>Дополнительные параметры:</b><br>" html_content += "<br><b>Дополнительные параметры:</b><br>"
html_content += other_vars_html html_content += other_vars_html
html_content += "<br><b>Компоненты (Winetricks):</b> "
if display_verbs:
# Используем span вместо div, чтобы избежать лишних отступов
html_content += '<span style="max-height: 120px; overflow-y: auto;">'
html_content += ", ".join(html.escape(v) for v in display_verbs)
html_content += '</span>'
else:
html_content += "Не установлены"
html_content += "</p>" html_content += "</p>"
self.prefix_info_display.setHtml(html_content) self.prefix_info_display.setHtml(html_content)
@@ -3673,6 +3705,7 @@ class WineHelperGUI(QMainWindow):
wine_executable = self._get_wine_executable_for_prefix(prefix_name) wine_executable = self._get_wine_executable_for_prefix(prefix_name)
dialog = WinetricksManagerDialog(prefix_path, winetricks_path, self, wine_executable=wine_executable) dialog = WinetricksManagerDialog(prefix_path, winetricks_path, self, wine_executable=wine_executable)
dialog.installation_complete.connect(lambda: self.update_prefix_info_display(prefix_name))
dialog.exec_() dialog.exec_()
def _get_wine_executable_for_prefix(self, prefix_name): def _get_wine_executable_for_prefix(self, prefix_name):