@@ -13,7 +13,7 @@ from functools import partial
from PyQt5 . QtWidgets import ( QApplication , QMainWindow , QWidget , QVBoxLayout , QHBoxLayout , QPushButton , QLabel , QTabWidget , QTabBar ,
QTextEdit , QFileDialog , QMessageBox , QLineEdit , QCheckBox , QStackedWidget , QScrollArea , QFormLayout , QGroupBox , QRadioButton , QComboBox ,
QListWidget , QListWidgetItem , QGridLayout , QFrame , QDialog , QTextBrowser , QInputDialog , QDialogButtonBox , QSystemTrayIcon , QMenu )
from PyQt5 . QtCore import Qt , QProcess , QSize , QTimer , QProcessEnvironment , QPropertyAnimation , QEasingCurve , pyqtSignal
from PyQt5 . QtCore import Qt , QProcess , QSize , QTimer , QProcessEnvironment , QPropertyAnimation , QEasingCurve
from PyQt5 . QtGui import QIcon , QFont , QTextCursor , QPixmap , QPainter , QCursor
from PyQt5 . QtNetwork import QLocalServer , QLocalSocket
@@ -428,8 +428,6 @@ class WinetricksManagerDialog(QDialog):
" Для переустановки компонента: Выделите е г о в списке и нажмите кнопку «Переустановить». "
)
installation_complete = pyqtSignal ( )
def __init__ ( self , prefix_path , winetricks_path , parent = None , wine_executable = None ) :
super ( ) . __init__ ( parent )
self . prefix_path = prefix_path
@@ -619,33 +617,12 @@ class WinetricksManagerDialog(QDialog):
self . _log ( f " --- Предупреждение: не удалось прочитать { log_path } : { e } --- " )
return installed_verbs
def _parse_winetricks_list_output ( self , output , installed_verbs , list_widget , category ):
def _parse_winetricks_list_output ( self , output , installed_verbs , list_widget ) :
""" Парсит вывод ' winetricks list ' и заполняет QListWidget. """
# Regex, который обрабатывает строки как с префиксом статуса '[ ]', так и без него.
# 1. `(?:\[(.)]\s+)?` - опциональная группа для статуса (напр. '[x]').
# 2. `([^\s]+)` - имя компонента (без пробелов).
# 3. `(.*)` - оставшаяся часть строки (описание).
# Определяем шаблоны для фильтрации на основе категории
dlls_blacklist_pattern = None
fonts_blacklist_pattern = None
settings_blacklist_pattern = None
if category == ' dlls ' :
# Исключаем d3d*, directx9, dont_use, dxvk*, vkd3d*, galliumnine, faudio*, Foundation
dlls_blacklist_pattern = re . compile (
r ' ^(d3d|directx9|dont_use|dxvk|vkd3d|galliumnine|faudio|foundation) ' , re . IGNORECASE
)
elif category == ' fonts ' :
fonts_blacklist_pattern = re . compile (
r ' ^(dont_use) ' , re . IGNORECASE
)
elif category == ' settings ' :
# Исключаем vista*, alldlls, autostart_*, bad*, good*, win*, videomemory*, vd=*, isolate_home
settings_blacklist_pattern = re . compile (
r ' ^(vista|alldlls|autostart_|bad|good|win|videomemory|vd=|isolate_home) ' , re . IGNORECASE
)
line_re = re . compile ( r " ^ \ s*(?: \ [(.)] \ s+)?([^ \ s]+) \ s*(.*) " )
found_items = False
@@ -666,14 +643,6 @@ class WinetricksManagerDialog(QDialog):
if ' / ' in name or ' \\ ' in name or name . lower ( ) in ( ' executing ' , ' using ' , ' warning: ' ) or name . endswith ( ' : ' ) :
continue
# Применяем фильтры для черных списков
if dlls_blacklist_pattern and dlls_blacklist_pattern . search ( name ) :
continue
if fonts_blacklist_pattern and fonts_blacklist_pattern . search ( name ) :
continue
if settings_blacklist_pattern and settings_blacklist_pattern . search ( name ) :
continue
is_checked = name in installed_verbs
item_text = f " { name . ljust ( 27 ) } { description . strip ( ) } "
item = QListWidgetItem ( item_text )
@@ -712,7 +681,7 @@ class WinetricksManagerDialog(QDialog):
self . _log ( " -------------------------------------------------- " , " red " )
else :
installed_verbs = self . _parse_winetricks_log ( )
found_items = self . _parse_winetricks_list_output ( output , installed_verbs , list_widget , category )
found_items = self . _parse_winetricks_list_output ( output , installed_verbs , list_widget )
if from_cache is None : # Только если мы не читали из кэша
# Сохраняем успешный результат в кэш
@@ -887,7 +856,6 @@ class WinetricksManagerDialog(QDialog):
# Перезагружаем данные, чтобы обновить состояние
self . initial_states . clear ( )
self . load_all_categories ( )
self . installation_complete . emit ( )
self . installation_finished = True
def closeEvent ( self , event ) :
@@ -2633,39 +2601,19 @@ class WineHelperGUI(QMainWindow):
self . esync_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 = {
" WINEPREFIX " : ( " Путь " , lambda v : v ) ,
" WINEARCH " : ( " Архитектура " , lambda v : " 64-bit " if v == " win64 " else " 32-bit " ) ,
" 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 " Н е установлено" ) ,
" VKD3D_VER " : ( " Версия VKD3D " , lambda v : v if v else " Н е установлено" ) ,
" WINEESYNC " : ( " ESync " , 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 " Н е заданы" ) ,
}
display_order = [ " WINEPREFIX " , " WINEARCH " , " WH_WINE_USE " , " DXVK_VER " , " VKD3D_VER " , " WINEESYNC " , " WINEFSYNC " , " WH_XDG_OPEN " ]
display_order = [ " WINEPREFIX " , " WINEARCH " , " WH_WINE_USE " , " BASE_PFX " , " DXVK_VER" , " VKD3D_VER " , " WINEESYNC " , " WINEFSYNC " , " WH_XDG_OPEN " ]
html_content = f ' <p style= " line-height: 1.3; font-size: 9pt; " > '
html_content + = f " <b>Имя:</b> { html . escape ( prefix_name ) } <br> "
@@ -2687,15 +2635,6 @@ class WineHelperGUI(QMainWindow):
html_content + = " <br><b>Дополнительные параметры:</b><br> "
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> "
self . prefix_info_display . setHtml ( html_content )
@@ -3252,6 +3191,9 @@ class WineHelperGUI(QMainWindow):
""" Открывает диалог создания нового префикса. """
dialog = CreatePrefixDialog ( self )
if dialog . exec_ ( ) == QDialog . Accepted :
if not self . _show_license_agreement_dialog ( ) :
return
self . start_prefix_creation (
prefix_name = dialog . prefix_name ,
wine_arch = dialog . wine_arch ,
@@ -3702,7 +3644,6 @@ class WineHelperGUI(QMainWindow):
wine_executable = self . _get_wine_executable_for_prefix ( prefix_name )
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_ ( )
def _get_wine_executable_for_prefix ( self , prefix_name ) :
@@ -4695,7 +4636,6 @@ class WineHelperGUI(QMainWindow):
self . command_process . deleteLater ( )
self . command_process = None
self . command_close_button . setEnabled ( True )
self . command_log_output . ensureCursorVisible ( )
def _handle_launcher_creation_finished ( self , exit_code , exit_status ) :
""" Обрабатывает завершение создания ярлыка. """