added the wine/proton control button to the created prefix

This commit is contained in:
Sergey Palcheh
2025-09-11 12:52:04 +06:00
parent aa591112ff
commit bab49377a3
2 changed files with 135 additions and 11 deletions

View File

@@ -1652,8 +1652,8 @@ select_wine_version() {
read -p "Введите номер для выбора wine/proton (0-$max_choice): " user_choice
if [[ "$user_choice" =~ ^[0-9]+$ ]] && (( user_choice >= 0 && user_choice <= max_choice )); then
if [[ "$user_choice" == "0" ]]; then
print_info "Создание префикса отменено."
exit 0
print_info "Операция отменена."
return 1
fi
local selected_opt
selected_opt="${selectable_options[$user_choice]}"
@@ -1667,6 +1667,7 @@ select_wine_version() {
print_error "Неверный выбор. Введите число от 0 до $max_choice."
fi
done
return 0
}
create_prefix() {
@@ -1716,7 +1717,7 @@ create_prefix() {
*) fatal "Неверный выбор. Операция отменена." ;;
esac
select_wine_version
select_wine_version || exit 0
print_info "Выберите тип создаваемого префикса:"
echo " 0) Отмена создания префикса"
@@ -2171,6 +2172,27 @@ run_install_vkd3d() {
wait_wineserver
}
run_change_wine_version() {
local new_version="$1"
check_prefix_var
init_database
if [[ -z "$new_version" ]]; then
select_wine_version || exit 0
new_version="$WH_WINE_USE"
else
export WH_WINE_USE="$new_version"
fi
init_wine_ver
init_wineprefix
wait_wineserver
print_ok "Версия Wine для префикса $PREFIX_NAME успешно изменена на $WH_WINE_USE."
}
wh_info () {
echo "Использование: $SCRIPT_NAME [команда]
@@ -2181,6 +2203,7 @@ wh_info () {
install-dxvk [версия|none|list] установить, удалить или показать версии DXVK
install-vkd3d [версия|none|list] установить, удалить или показать версии VKD3D
change-wine [версия] изменить версию Wine/Proton для текущего префикса
installed список установленных программ
run [программа] запуск программы (отладка)
@@ -2231,6 +2254,7 @@ case "$arg1" in
install|-i) run_autoinstall "$@" ;;
install-dxvk) run_install_dxvk "$@" ;;
install-vkd3d) run_install_vkd3d "$@" ;;
change-wine) run_change_wine_version "$@" ;;
installed) check_installed_programs "$1" ;;
run|-r) run_installed_programs "$1" ;;
backup-prefix) backup_prefix "$@" ;;

View File

@@ -2105,29 +2105,35 @@ class WineHelperGUI(QMainWindow):
self.prefix_winefile_button.setToolTip("Запуск файлового менеджера Wine (winefile) для просмотра файлов внутри префикса.")
management_layout.addWidget(self.prefix_winefile_button, 2, 1)
self.change_wine_version_button = QPushButton("Управление Wine/Proton")
self.change_wine_version_button.setMinimumHeight(32)
self.change_wine_version_button.clicked.connect(self.open_wine_version_manager)
self.change_wine_version_button.setToolTip("Изменение версии Wine или Proton для выбранного префикса.")
management_layout.addWidget(self.change_wine_version_button, 3, 0, 1, 2)
# Добавляем небольшой отступ
spacer_widget = QWidget()
spacer_widget.setFixedHeight(5)
management_layout.addWidget(spacer_widget, 3, 0, 1, 2)
management_layout.addWidget(spacer_widget, 4, 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)
management_layout.addWidget(self.dxvk_manage_button, 5, 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)
management_layout.addWidget(self.vkd3d_manage_button, 5, 1)
# --- Правая сторона: Информационный блок ---
self.prefix_info_display = QTextBrowser()
self.prefix_info_display.setReadOnly(True)
self.prefix_info_display.setFrameStyle(QFrame.StyledPanel)
# Увеличиваем rowspan, чтобы учесть добавленный отступ
management_layout.addWidget(self.prefix_info_display, 0, 2, 5, 1)
management_layout.addWidget(self.prefix_info_display, 0, 2, 6, 1)
management_layout.setColumnStretch(0, 1)
management_layout.setColumnStretch(1, 1)
@@ -2137,7 +2143,7 @@ class WineHelperGUI(QMainWindow):
separator = QFrame()
separator.setFrameShape(QFrame.HLine)
separator.setFrameShadow(QFrame.Sunken)
management_layout.addWidget(separator, 5, 0, 1, 3)
management_layout.addWidget(separator, 6, 0, 1, 3)
install_group = QWidget()
install_layout = QVBoxLayout(install_group)
@@ -2169,8 +2175,7 @@ class WineHelperGUI(QMainWindow):
self.create_launcher_button.setEnabled(False) # Изначально неактивна
action_buttons_layout.addWidget(self.create_launcher_button)
install_layout.addLayout(action_buttons_layout)
management_layout.addWidget(install_group, 6, 0, 1, 3)
management_layout.addWidget(install_group, 7, 0, 1, 3)
container_layout.addWidget(self.prefix_management_groupbox)
layout.addWidget(self.management_container_groupbox)
@@ -2528,6 +2533,81 @@ class WineHelperGUI(QMainWindow):
# Если лицензия принята, запускаем установку.
self.run_component_install_command(prefix_name, command, version)
def open_wine_version_manager(self):
"""Открывает диалог для смены версии Wine/Proton для префикса."""
prefix_name = self.current_managed_prefix_name
if not prefix_name:
QMessageBox.warning(self, "Ошибка", "Сначала выберите префикс.")
return
# Определяем архитектуру префикса
prefix_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name)
last_conf_path = os.path.join(prefix_path, "last.conf")
architecture = "win64" # По умолчанию
if os.path.exists(last_conf_path):
try:
with open(last_conf_path, 'r', encoding='utf-8') as f:
for line in f:
if 'WINEARCH=' in line:
arch_val = line.split('=', 1)[1].strip().strip('"\'')
if arch_val:
architecture = arch_val
break
except Exception as e:
print(f"Предупреждение: не удалось прочитать архитектуру из {last_conf_path}: {e}")
dialog = WineVersionSelectionDialog(architecture, self)
if dialog.exec_() == QDialog.Accepted and dialog.selected_version:
new_version = dialog.selected_version
new_version_display = dialog.selected_display_text
if not self._show_license_agreement_dialog():
return # Пользователь отклонил лицензию
self.run_change_wine_version_command(prefix_name, new_version, new_version_display)
def run_change_wine_version_command(self, prefix_name, new_version, new_version_display):
"""Выполняет команду смены версии Wine/Proton через winehelper."""
self.command_dialog = QDialog(self)
self.command_dialog.setWindowTitle(f"Смена версии Wine на: {new_version_display}")
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_output_buffer = ""
self.command_last_line_was_progress = False
self.command_process = QProcess(self.command_dialog)
self.command_process.setProcessChannelMode(QProcess.MergedChannels)
self.command_process.readyReadStandardOutput.connect(self._handle_prefix_creation_output)
self.command_process.finished.connect(
lambda exit_code, exit_status: self._handle_change_wine_version_finished(
prefix_name, exit_code, exit_status
)
)
env = QProcessEnvironment.systemEnvironment()
env.insert("WINEPREFIX", os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name))
self.command_process.setProcessEnvironment(env)
args = ["change-wine", new_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 run_component_install_command(self, prefix_name, command, version):
"""Выполняет команду установки компонента (DXVK/VKD3D) через winehelper."""
prefix_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name)
@@ -2568,11 +2648,31 @@ class WineHelperGUI(QMainWindow):
self.command_process.start(self.winehelper_path, args)
self.command_dialog.exec_()
def _handle_change_wine_version_finished(self, prefix_name, exit_code, exit_status):
"""Обрабатывает завершение смены версии Wine и обновляет информацию о префиксе."""
# Обрабатываем остаток в буфере, если он есть
if self.command_output_buffer:
self._process_command_log_line(self.command_output_buffer)
self.command_output_buffer = ""
# Если последней строкой был прогресс, "завершаем" его переносом строки.
if self.command_last_line_was_progress:
cursor = self.command_log_output.textCursor()
cursor.movePosition(QTextCursor.End)
cursor.insertText("\n")
self.command_last_line_was_progress = False
# Вызываем общий обработчик для обновления лога и кнопки закрытия
self._handle_command_finished(exit_code, exit_status)
# В случае успеха обновляем панель информации о префиксе
if exit_code == 0:
self.update_prefix_info_display(prefix_name)
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)