added control buttons for dxvk/vkd3d
This commit is contained in:
86
winehelper
86
winehelper
@@ -776,9 +776,10 @@ init_wined3d () {
|
||||
init_dxvk () {
|
||||
check_variables USE_DXVK_VER "$1"
|
||||
|
||||
get_dxvk () {
|
||||
DXVK_URL="$1"
|
||||
DXVK_PACKAGE="${WH_VULKAN_LIBDIR}/dxvk-${DXVK_VAR_VER}.tar.$(echo ${DXVK_URL#*.tar.})"
|
||||
get_dxvk() {
|
||||
local DXVK_URL="$1"
|
||||
local DXVK_VAR_VER="$2"
|
||||
local DXVK_PACKAGE="${WH_VULKAN_LIBDIR}/${DXVK_VAR_VER}.tar.$(echo "${DXVK_URL#*.tar.}")"
|
||||
if try_download "$DXVK_URL" "$DXVK_PACKAGE" check256sum \
|
||||
&& unpack "$DXVK_PACKAGE" "$WH_VULKAN_LIBDIR"
|
||||
then
|
||||
@@ -789,8 +790,8 @@ init_dxvk () {
|
||||
}
|
||||
|
||||
for DXVK_VAR_VER in "$USE_DXVK_VER" $@ ; do
|
||||
if [[ ! -d "${WH_VULKAN_LIBDIR}/dxvk-$DXVK_VAR_VER" ]] ; then
|
||||
get_dxvk "$CLOUD_URL/dxvk-${DXVK_VAR_VER}.tar.xz"
|
||||
if [[ ! -d "${WH_VULKAN_LIBDIR}/${DXVK_VAR_VER}" ]] ; then
|
||||
get_dxvk "$CLOUD_URL/${DXVK_VAR_VER}.tar.xz" "$DXVK_VAR_VER"
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -803,8 +804,8 @@ init_dxvk () {
|
||||
fi
|
||||
|
||||
for dxvkfiles in $DXVK_FILES ; do
|
||||
try_copy_other_dll_to_pfx_64 "${WH_VULKAN_LIBDIR}/dxvk-$USE_DXVK_VER/x64/$dxvkfiles.dll"
|
||||
if try_copy_other_dll_to_pfx_32 "${WH_VULKAN_LIBDIR}/dxvk-$USE_DXVK_VER/x32/$dxvkfiles.dll"
|
||||
try_copy_other_dll_to_pfx_64 "${WH_VULKAN_LIBDIR}/${USE_DXVK_VER}/x64/$dxvkfiles.dll"
|
||||
if try_copy_other_dll_to_pfx_32 "${WH_VULKAN_LIBDIR}/${USE_DXVK_VER}/x32/$dxvkfiles.dll"
|
||||
then var_winedlloverride_update "$dxvkfiles=n"
|
||||
fi
|
||||
done
|
||||
@@ -813,9 +814,10 @@ init_dxvk () {
|
||||
init_vkd3d () {
|
||||
check_variables USE_VKD3D_VER "$1"
|
||||
|
||||
get_vkd3d () {
|
||||
VKD3D_URL="$1"
|
||||
VKD3D_PACKAGE="${WH_VULKAN_LIBDIR}/vkd3d-proton-${VKD3D_VAR_VER}.tar.$(echo ${VKD3D_URL#*.tar.})"
|
||||
get_vkd3d() {
|
||||
local VKD3D_URL="$1"
|
||||
local VKD3D_VAR_VER="$2"
|
||||
local VKD3D_PACKAGE="${WH_VULKAN_LIBDIR}/${VKD3D_VAR_VER}.tar.$(echo "${VKD3D_URL#*.tar.}")"
|
||||
if try_download "$VKD3D_URL" "$VKD3D_PACKAGE" check256sum \
|
||||
&& unpack "$VKD3D_PACKAGE" "$WH_VULKAN_LIBDIR"
|
||||
then
|
||||
@@ -826,15 +828,15 @@ init_vkd3d () {
|
||||
}
|
||||
|
||||
for VKD3D_VAR_VER in "$USE_VKD3D_VER" $@ ; do
|
||||
if [[ ! -d "${WH_VULKAN_LIBDIR}/vkd3d-proton-$VKD3D_VAR_VER" ]] ; then
|
||||
get_vkd3d "$CLOUD_URL/vkd3d-proton-${VKD3D_VAR_VER}.tar.xz"
|
||||
if [[ ! -d "${WH_VULKAN_LIBDIR}/${VKD3D_VAR_VER}" ]] ; then
|
||||
get_vkd3d "$CLOUD_URL/${VKD3D_VAR_VER}.tar.xz" "$VKD3D_VAR_VER"
|
||||
fi
|
||||
done
|
||||
|
||||
VKD3D_FILES="d3d12 d3d12core libvkd3d-shader-1 libvkd3d-1" # libvkd3d-proton-utils-3
|
||||
for vkd3dfiles in $VKD3D_FILES ; do
|
||||
try_copy_other_dll_to_pfx_64 "${WH_VULKAN_LIBDIR}/vkd3d-proton-$USE_VKD3D_VER/x64/$vkd3dfiles.dll"
|
||||
if try_copy_other_dll_to_pfx_32 "${WH_VULKAN_LIBDIR}/vkd3d-proton-$USE_VKD3D_VER/x86/$vkd3dfiles.dll"
|
||||
try_copy_other_dll_to_pfx_64 "${WH_VULKAN_LIBDIR}/${USE_VKD3D_VER}/x64/$vkd3dfiles.dll"
|
||||
if try_copy_other_dll_to_pfx_32 "${WH_VULKAN_LIBDIR}/${USE_VKD3D_VER}/x86/$vkd3dfiles.dll"
|
||||
then var_winedlloverride_update "$vkd3dfiles=n"
|
||||
fi
|
||||
done
|
||||
@@ -2011,6 +2013,57 @@ restore_prefix() {
|
||||
return 0
|
||||
}
|
||||
|
||||
update_last_conf_var() {
|
||||
local var_name="$1"
|
||||
local new_value="$2"
|
||||
local conf_file="$WINEPREFIX/last.conf"
|
||||
|
||||
if [[ ! -f "$conf_file" ]]; then
|
||||
print_warning "Файл last.conf не найден, не могу обновить переменную $var_name."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if grep -q "export $var_name=" "$conf_file"; then
|
||||
sed -i "s|^export $var_name=.*|export $var_name=\"$new_value\"|" "$conf_file"
|
||||
else
|
||||
echo "export $var_name=\"$new_value\"" >> "$conf_file"
|
||||
fi
|
||||
}
|
||||
|
||||
run_install_dxvk() {
|
||||
local version="$1"
|
||||
check_prefix_var
|
||||
init_database
|
||||
init_wine_ver
|
||||
init_wineprefix
|
||||
if [[ "$version" == "none" ]] ; then
|
||||
print_info "Удаление DXVK..."
|
||||
init_wined3d
|
||||
update_last_conf_var "DXVK_VER" ""
|
||||
else
|
||||
init_dxvk "$version"
|
||||
update_last_conf_var "DXVK_VER" "$USE_DXVK_VER"
|
||||
fi
|
||||
wait_wineserver
|
||||
}
|
||||
|
||||
run_install_vkd3d() {
|
||||
local version="$1"
|
||||
check_prefix_var
|
||||
init_database
|
||||
init_wine_ver
|
||||
init_wineprefix
|
||||
if [[ "$version" == "none" ]] ; then
|
||||
print_info "Удаление VKD3D..."
|
||||
init_wined3d
|
||||
update_last_conf_var "VKD3D_VER" ""
|
||||
else
|
||||
init_vkd3d "$version"
|
||||
update_last_conf_var "VKD3D_VER" "$USE_VKD3D_VER"
|
||||
fi
|
||||
wait_wineserver
|
||||
}
|
||||
|
||||
wh_info () {
|
||||
echo "Использование: $SCRIPT_NAME [команда]
|
||||
|
||||
@@ -2019,6 +2072,9 @@ wh_info () {
|
||||
install [скрипт] запустить скрипт установки программы
|
||||
install [скрипт] --clear-pfx не использовать готовый префикс для установки ПО
|
||||
|
||||
install-dxvk [версия|none] установить/удалить DXVK в выбранный префикс
|
||||
install-vkd3d [версия|none] установить/удалить VKD3D в выбранный префикс
|
||||
|
||||
installed список установленных программ
|
||||
run [программа] запуск программы (отладка)
|
||||
remove-all удалить WineHelper и все связанные данные
|
||||
@@ -2066,6 +2122,8 @@ case "$arg1" in
|
||||
winetricks) prepair_wine ; "$WH_WINETRICKS" -q "$@" ;;
|
||||
desktop) create_desktop "$@" ; exit 0 ;;
|
||||
install|-i) run_autoinstall "$@" ;;
|
||||
install-dxvk) run_install_dxvk "$@" ;;
|
||||
install-vkd3d) run_install_vkd3d "$@" ;;
|
||||
installed) check_installed_programs "$1" ;;
|
||||
run|-r) run_installed_programs "$1" ;;
|
||||
backup-prefix) backup_prefix "$@" ;;
|
||||
|
@@ -1078,7 +1078,7 @@ class WineVersionSelectionDialog(QDialog):
|
||||
if not line:
|
||||
continue
|
||||
|
||||
match = re.match(r'^#+\s+([A-Z_]+)\s+#*$', line)
|
||||
match = re.match(r'^#+\s*([^#]+?)\s*#*$', line)
|
||||
if match:
|
||||
group_name = match.group(1)
|
||||
allowed_groups = {"WINE", "WINE_LG", "PROTON_LG", "PROTON_STEAM"}
|
||||
@@ -1354,6 +1354,118 @@ class CreatePrefixDialog(QDialog):
|
||||
|
||||
self.accept()
|
||||
|
||||
class ComponentVersionSelectionDialog(QDialog):
|
||||
"""Диалог для выбора версии компонента (DXVK, VKD3D)."""
|
||||
|
||||
def __init__(self, component_group, title, parent=None, add_extra_options=True):
|
||||
super().__init__(parent)
|
||||
self.component_group = component_group
|
||||
self.selected_version = None
|
||||
self.versions_data = []
|
||||
|
||||
self.setWindowTitle(title)
|
||||
self.setMinimumSize(600, 400)
|
||||
self.setModal(True)
|
||||
|
||||
main_layout = QVBoxLayout(self)
|
||||
|
||||
self.search_edit = QLineEdit()
|
||||
self.search_edit.setPlaceholderText("Поиск версии...")
|
||||
self.search_edit.textChanged.connect(self.filter_versions)
|
||||
main_layout.addWidget(self.search_edit)
|
||||
|
||||
self.scroll_area = QScrollArea()
|
||||
self.scroll_area.setWidgetResizable(True)
|
||||
main_layout.addWidget(self.scroll_area)
|
||||
|
||||
scroll_content = QWidget()
|
||||
self.scroll_area.setWidget(scroll_content)
|
||||
|
||||
self.grid_layout = QGridLayout(scroll_content)
|
||||
self.grid_layout.setAlignment(Qt.AlignTop)
|
||||
|
||||
self.buttons = []
|
||||
# Кнопка "Удалить" теперь находится вне сетки, поэтому начинаем с 0 строки.
|
||||
self.load_versions(start_row=0)
|
||||
|
||||
# --- Панель с кнопками действий внизу диалога ---
|
||||
button_layout = QHBoxLayout()
|
||||
|
||||
if add_extra_options:
|
||||
uninstall_btn = QPushButton("Удалить из префикса")
|
||||
uninstall_btn.setToolTip("Удаляет текущую установленную версию компонента из префикса.")
|
||||
uninstall_btn.clicked.connect(partial(self.on_version_selected, "none"))
|
||||
# Добавляем кнопку слева
|
||||
button_layout.addWidget(uninstall_btn)
|
||||
|
||||
button_layout.addStretch(1) # Растягиваем пространство, чтобы разнести кнопки
|
||||
|
||||
cancel_button = QPushButton("Отмена")
|
||||
cancel_button.clicked.connect(self.reject)
|
||||
button_layout.addWidget(cancel_button)
|
||||
|
||||
main_layout.addLayout(button_layout)
|
||||
|
||||
def load_versions(self, start_row):
|
||||
"""Загружает и отображает версии."""
|
||||
self._parse_sha256_list()
|
||||
self.populate_ui(start_row)
|
||||
|
||||
def _parse_sha256_list(self):
|
||||
"""Парсит sha256sum.list для получения списка версий."""
|
||||
sha256_path = os.path.join(Var.DATA_PATH, "sha256sum.list")
|
||||
if not os.path.exists(sha256_path):
|
||||
self.versions_data = []
|
||||
return
|
||||
|
||||
current_group = None
|
||||
try:
|
||||
with open(sha256_path, 'r', encoding='utf-8') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
match = re.match(r'^#+\s*([^#]+?)\s*#*$', line)
|
||||
if match:
|
||||
current_group = match.group(1).strip()
|
||||
continue
|
||||
if current_group == self.component_group and re.match(r'^[a-f0-9]{64}', line):
|
||||
parts = line.split(maxsplit=1)
|
||||
if len(parts) == 2:
|
||||
filename = parts[1]
|
||||
if filename.endswith('.tar.xz'):
|
||||
version_name = filename[:-7]
|
||||
self.versions_data.append(version_name)
|
||||
except IOError:
|
||||
self.versions_data = []
|
||||
|
||||
def populate_ui(self, start_row):
|
||||
"""Заполняет UI кнопками версий."""
|
||||
versions = sorted(self.versions_data, reverse=True)
|
||||
num_columns = 3
|
||||
row, col = start_row, 0
|
||||
for version_name in versions:
|
||||
btn = QPushButton(version_name)
|
||||
btn.clicked.connect(partial(self.on_version_selected, version_name))
|
||||
self.grid_layout.addWidget(btn, row, col)
|
||||
self.buttons.append(btn)
|
||||
col += 1
|
||||
if col >= num_columns:
|
||||
col = 0
|
||||
row += 1
|
||||
|
||||
def filter_versions(self):
|
||||
"""Фильтрует видимость кнопок версий на основе текста поиска."""
|
||||
search_text = self.search_edit.text().lower()
|
||||
for btn_widget in self.buttons:
|
||||
is_match = search_text in btn_widget.text().lower()
|
||||
btn_widget.setVisible(is_match)
|
||||
|
||||
def on_version_selected(self, version_name):
|
||||
"""Обрабатывает выбор версии."""
|
||||
self.selected_version = version_name
|
||||
self.accept()
|
||||
|
||||
class WineHelperGUI(QMainWindow):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
@@ -1980,11 +2092,29 @@ class WineHelperGUI(QMainWindow):
|
||||
self.prefix_winefile_button.setToolTip("Запуск файлового менеджера Wine (winefile) для просмотра файлов внутри префикса.")
|
||||
management_layout.addWidget(self.prefix_winefile_button, 2, 1)
|
||||
|
||||
# Добавляем небольшой отступ
|
||||
spacer_widget = QWidget()
|
||||
spacer_widget.setFixedHeight(5)
|
||||
management_layout.addWidget(spacer_widget, 3, 0, 1, 2)
|
||||
|
||||
self.dxvk_manage_button = QPushButton("Управление DXVK")
|
||||
self.dxvk_manage_button.setMinimumHeight(32)
|
||||
self.dxvk_manage_button.clicked.connect(lambda: self.open_component_version_manager('dxvk'))
|
||||
self.dxvk_manage_button.setToolTip("Установка или удаление определенной версии DXVK в префиксе.")
|
||||
management_layout.addWidget(self.dxvk_manage_button, 4, 0)
|
||||
|
||||
self.vkd3d_manage_button = QPushButton("Управление VKD3D")
|
||||
self.vkd3d_manage_button.setMinimumHeight(32)
|
||||
self.vkd3d_manage_button.clicked.connect(lambda: self.open_component_version_manager('vkd3d-proton'))
|
||||
self.vkd3d_manage_button.setToolTip("Установка или удаление определенной версии vkd3d-proton в префиксе.")
|
||||
management_layout.addWidget(self.vkd3d_manage_button, 4, 1)
|
||||
|
||||
# --- Правая сторона: Информационный блок ---
|
||||
self.prefix_info_display = QTextBrowser()
|
||||
self.prefix_info_display.setReadOnly(True)
|
||||
self.prefix_info_display.setFrameStyle(QFrame.StyledPanel)
|
||||
management_layout.addWidget(self.prefix_info_display, 0, 2, 3, 1)
|
||||
# Увеличиваем rowspan, чтобы учесть добавленный отступ
|
||||
management_layout.addWidget(self.prefix_info_display, 0, 2, 5, 1)
|
||||
|
||||
management_layout.setColumnStretch(0, 1)
|
||||
management_layout.setColumnStretch(1, 1)
|
||||
@@ -1994,7 +2124,7 @@ class WineHelperGUI(QMainWindow):
|
||||
separator = QFrame()
|
||||
separator.setFrameShape(QFrame.HLine)
|
||||
separator.setFrameShadow(QFrame.Sunken)
|
||||
management_layout.addWidget(separator, 3, 0, 1, 3)
|
||||
management_layout.addWidget(separator, 5, 0, 1, 3)
|
||||
|
||||
install_group = QWidget()
|
||||
install_layout = QVBoxLayout(install_group)
|
||||
@@ -2027,7 +2157,7 @@ class WineHelperGUI(QMainWindow):
|
||||
action_buttons_layout.addWidget(self.create_launcher_button)
|
||||
install_layout.addLayout(action_buttons_layout)
|
||||
|
||||
management_layout.addWidget(install_group, 4, 0, 1, 3)
|
||||
management_layout.addWidget(install_group, 6, 0, 1, 3)
|
||||
|
||||
container_layout.addWidget(self.prefix_management_groupbox)
|
||||
layout.addWidget(self.management_container_groupbox)
|
||||
@@ -2220,8 +2350,10 @@ class WineHelperGUI(QMainWindow):
|
||||
"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 "Не установлено"),
|
||||
}
|
||||
display_order = ["WINEPREFIX", "WINEARCH", "WH_WINE_USE", "BASE_PFX"]
|
||||
display_order = ["WINEPREFIX", "WINEARCH", "WH_WINE_USE", "BASE_PFX", "DXVK_VER", "VKD3D_VER"]
|
||||
|
||||
html_content = f'<p style="line-height: 1.3; font-size: 9pt;">'
|
||||
html_content += f"<b>Имя:</b> {html.escape(prefix_name)}<br>"
|
||||
@@ -2310,6 +2442,128 @@ class WineHelperGUI(QMainWindow):
|
||||
self.command_process.start(wine_executable, args)
|
||||
self.command_dialog.exec_()
|
||||
|
||||
def _get_prefix_component_version(self, prefix_name, component_key):
|
||||
"""
|
||||
Читает last.conf префикса и возвращает версию указанного компонента.
|
||||
:param prefix_name: Имя префикса.
|
||||
:param component_key: Ключ компонента (например, 'DXVK_VER').
|
||||
:return: Строку с версией или None, если не найдено или значение пустое.
|
||||
"""
|
||||
if not prefix_name:
|
||||
return None
|
||||
|
||||
last_conf_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name, "last.conf")
|
||||
if not os.path.exists(last_conf_path):
|
||||
return None
|
||||
|
||||
try:
|
||||
with open(last_conf_path, 'r', encoding='utf-8') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
# Ищем строку вида 'export KEY="value"' или 'export KEY=value'
|
||||
if line.startswith('export '):
|
||||
parts = line[7:].split('=', 1)
|
||||
if len(parts) == 2:
|
||||
key = parts[0].strip()
|
||||
if key == component_key:
|
||||
value = parts[1].strip().strip('"\'')
|
||||
# Возвращаем значение, только если оно не пустое.
|
||||
return value if value else None
|
||||
except IOError as e:
|
||||
print(f"Ошибка чтения last.conf для {prefix_name}: {e}")
|
||||
return None
|
||||
return None
|
||||
|
||||
def open_component_version_manager(self, component):
|
||||
"""Открывает диалог выбора версии для DXVK/VKD3D и запускает установку."""
|
||||
prefix_name = self.current_managed_prefix_name
|
||||
if not prefix_name:
|
||||
QMessageBox.warning(self, "Ошибка", "Сначала выберите префикс.")
|
||||
return
|
||||
|
||||
component_key = None
|
||||
if component == 'dxvk':
|
||||
group = 'DXVK'
|
||||
title = f"Управление DXVK для префикса: {prefix_name}"
|
||||
command = 'install-dxvk'
|
||||
component_key = 'DXVK_VER'
|
||||
elif component == 'vkd3d-proton':
|
||||
group = 'VKD3D'
|
||||
title = f"Управление vkd3d для префикса: {prefix_name}"
|
||||
command = 'install-vkd3d'
|
||||
component_key = 'VKD3D_VER'
|
||||
else:
|
||||
return
|
||||
|
||||
dialog = ComponentVersionSelectionDialog(group, title, self)
|
||||
if dialog.exec_() == QDialog.Accepted and dialog.selected_version:
|
||||
version = dialog.selected_version
|
||||
|
||||
if version == "none":
|
||||
# Удаление: сначала проверяем, есть ли что удалять.
|
||||
installed_version = self._get_prefix_component_version(prefix_name, component_key)
|
||||
if not installed_version:
|
||||
QMessageBox.information(self, "Информация", "Установленных версий нет.")
|
||||
return # Прерываем выполнение, т.к. удалять нечего
|
||||
# Для удаления лицензия не нужна, запускаем сразу.
|
||||
self.run_component_install_command(prefix_name, command, version)
|
||||
else:
|
||||
# Установка: сначала показываем лицензионное соглашение.
|
||||
if not self._show_license_agreement_dialog():
|
||||
return # Пользователь отклонил лицензию
|
||||
|
||||
# Если лицензия принята, запускаем установку.
|
||||
self.run_component_install_command(prefix_name, command, version)
|
||||
|
||||
def run_component_install_command(self, prefix_name, command, version):
|
||||
"""Выполняет команду установки компонента (DXVK/VKD3D) через winehelper."""
|
||||
prefix_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name)
|
||||
|
||||
self.command_dialog = QDialog(self)
|
||||
self.command_dialog.setWindowTitle(f"Выполнение: {command} {version}")
|
||||
self.command_dialog.setMinimumSize(750, 400)
|
||||
self.command_dialog.setModal(True)
|
||||
self.command_dialog.setWindowFlags(self.command_dialog.windowFlags() & ~Qt.WindowCloseButtonHint)
|
||||
|
||||
layout = QVBoxLayout()
|
||||
self.command_log_output = QTextEdit()
|
||||
self.command_log_output.setReadOnly(True)
|
||||
self.command_log_output.setFont(QFont('DejaVu Sans Mono', 10))
|
||||
layout.addWidget(self.command_log_output)
|
||||
|
||||
self.command_close_button = QPushButton("Закрыть")
|
||||
self.command_close_button.setEnabled(False)
|
||||
self.command_close_button.clicked.connect(self.command_dialog.close)
|
||||
layout.addWidget(self.command_close_button)
|
||||
self.command_dialog.setLayout(layout)
|
||||
|
||||
self.command_process = QProcess(self.command_dialog)
|
||||
self.command_process.setProcessChannelMode(QProcess.MergedChannels)
|
||||
self.command_process.readyReadStandardOutput.connect(self._handle_command_output)
|
||||
self.command_process.finished.connect(
|
||||
lambda exit_code, exit_status: self._handle_component_install_finished(
|
||||
prefix_name, exit_code, exit_status
|
||||
)
|
||||
)
|
||||
|
||||
env = QProcessEnvironment.systemEnvironment()
|
||||
env.insert("WINEPREFIX", prefix_path)
|
||||
self.command_process.setProcessEnvironment(env)
|
||||
|
||||
args = [command, version]
|
||||
self.command_log_output.append(f"Выполнение: {shlex.quote(self.winehelper_path)} {' '.join(shlex.quote(a) for a in args)}")
|
||||
self.command_process.start(self.winehelper_path, args)
|
||||
self.command_dialog.exec_()
|
||||
|
||||
def _handle_component_install_finished(self, prefix_name, exit_code, exit_status):
|
||||
"""Обрабатывает завершение установки компонента и обновляет информацию о префиксе."""
|
||||
# Вызываем общий обработчик для обновления лога и кнопки закрытия
|
||||
self._handle_command_finished(exit_code, exit_status)
|
||||
|
||||
# В случае успеха обновляем панель информации о префиксе
|
||||
if exit_code == 0:
|
||||
self.update_prefix_info_display(prefix_name)
|
||||
|
||||
def create_launcher_for_prefix(self):
|
||||
"""
|
||||
Открывает диалог для создания ярлыка для приложения внутри выбранного префикса.
|
||||
|
Reference in New Issue
Block a user