prefix creation is displayed in a separate window
This commit is contained in:
		| @@ -1227,6 +1227,133 @@ class WineVersionSelectionDialog(QDialog): | |||||||
|             self.selected_display_text = version_name |             self.selected_display_text = version_name | ||||||
|         self.accept() |         self.accept() | ||||||
|  |  | ||||||
|  | class CreatePrefixDialog(QDialog): | ||||||
|  |     """Диалог для создания нового префикса.""" | ||||||
|  |  | ||||||
|  |     def __init__(self, parent=None): | ||||||
|  |         super().__init__(parent) | ||||||
|  |         self.parent_gui = parent  # Store reference to main window | ||||||
|  |         self.setWindowTitle("Создание нового префикса") | ||||||
|  |         self.setMinimumSize(500, 250) | ||||||
|  |         self.setModal(True) | ||||||
|  |  | ||||||
|  |         # Attributes to store results | ||||||
|  |         self.prefix_name = None | ||||||
|  |         self.wine_arch = None | ||||||
|  |         self.base_pfx = None | ||||||
|  |         self.selected_wine_version_value = None | ||||||
|  |         self.selected_wine_version_display = None | ||||||
|  |  | ||||||
|  |         layout = QVBoxLayout(self) | ||||||
|  |         form_layout = QFormLayout() | ||||||
|  |         form_layout.setSpacing(10) | ||||||
|  |  | ||||||
|  |         self.prefix_name_edit = QLineEdit() | ||||||
|  |         self.prefix_name_edit.setPlaceholderText("Например: my_prefix") | ||||||
|  |         form_layout.addRow("<b>Имя нового префикса:</b>", self.prefix_name_edit) | ||||||
|  |  | ||||||
|  |         arch_widget = QWidget() | ||||||
|  |         arch_layout = QHBoxLayout(arch_widget) | ||||||
|  |         arch_layout.setContentsMargins(0, 0, 0, 0) | ||||||
|  |         self.arch_win32_radio = QRadioButton("32-bit") | ||||||
|  |         self.arch_win64_radio = QRadioButton("64-bit") | ||||||
|  |         self.arch_win64_radio.setChecked(True) | ||||||
|  |         arch_layout.addWidget(self.arch_win32_radio) | ||||||
|  |         arch_layout.addWidget(self.arch_win64_radio) | ||||||
|  |         form_layout.addRow("<b>Разрядность:</b>", arch_widget) | ||||||
|  |  | ||||||
|  |         type_widget = QWidget() | ||||||
|  |         type_layout = QHBoxLayout(type_widget) | ||||||
|  |         type_layout.setContentsMargins(0, 0, 0, 0) | ||||||
|  |         self.type_clean_radio = QRadioButton("Чистый") | ||||||
|  |         self.type_clean_radio.setToolTip("Создает пустой префикс Wine без каких-либо дополнительных компонентов.") | ||||||
|  |         self.type_recommended_radio = QRadioButton("С рекомендуемыми библиотеками") | ||||||
|  |         tooltip_text = "Устанавливает базовый набор компонентов, необходимый для большинства приложений" | ||||||
|  |         self.type_recommended_radio.setToolTip(tooltip_text) | ||||||
|  |         self.type_clean_radio.setChecked(True) | ||||||
|  |         type_layout.addWidget(self.type_clean_radio) | ||||||
|  |         type_layout.addWidget(self.type_recommended_radio) | ||||||
|  |         form_layout.addRow("<b>Наполнение:</b>", type_widget) | ||||||
|  |  | ||||||
|  |         self.wine_version_edit = QLineEdit() | ||||||
|  |         self.wine_version_edit.setReadOnly(True) | ||||||
|  |         self.wine_version_edit.setPlaceholderText("Версия не выбрана") | ||||||
|  |  | ||||||
|  |         select_version_button = QPushButton("Выбрать версию...") | ||||||
|  |         select_version_button.clicked.connect(self.open_wine_version_dialog) | ||||||
|  |  | ||||||
|  |         version_layout = QHBoxLayout() | ||||||
|  |         version_layout.addWidget(self.wine_version_edit) | ||||||
|  |         version_layout.addWidget(select_version_button) | ||||||
|  |         form_layout.addRow("<b>Версия Wine/Proton:</b>", version_layout) | ||||||
|  |  | ||||||
|  |         layout.addLayout(form_layout) | ||||||
|  |  | ||||||
|  |         # Buttons | ||||||
|  |         button_layout = QHBoxLayout() | ||||||
|  |         self.create_button = QPushButton("Создать") | ||||||
|  |         self.create_button.setFont(QFont('Arial', 11, QFont.Bold)) | ||||||
|  |         self.create_button.setStyleSheet("background-color: #0078d7; color: white;") | ||||||
|  |         self.create_button.setEnabled(False) | ||||||
|  |         self.create_button.clicked.connect(self.accept_creation) | ||||||
|  |  | ||||||
|  |         cancel_button = QPushButton("Отмена") | ||||||
|  |         cancel_button.clicked.connect(self.reject) | ||||||
|  |  | ||||||
|  |         button_layout.addStretch() | ||||||
|  |         button_layout.addWidget(self.create_button) | ||||||
|  |         button_layout.addWidget(cancel_button) | ||||||
|  |         layout.addLayout(button_layout) | ||||||
|  |  | ||||||
|  |         # Connect signals | ||||||
|  |         self.arch_win32_radio.toggled.connect(self.clear_wine_version_selection) | ||||||
|  |         self.prefix_name_edit.textChanged.connect(self.update_create_button_state) | ||||||
|  |         self.wine_version_edit.textChanged.connect(self.update_create_button_state) | ||||||
|  |  | ||||||
|  |     def open_wine_version_dialog(self): | ||||||
|  |         """Открывает диалог выбора версии Wine.""" | ||||||
|  |         architecture = "win32" if self.arch_win32_radio.isChecked() else "win64" | ||||||
|  |         dialog = WineVersionSelectionDialog(architecture, self) | ||||||
|  |         if dialog.exec_() == QDialog.Accepted and dialog.selected_version: | ||||||
|  |             self.wine_version_edit.setText(dialog.selected_display_text) | ||||||
|  |             self.selected_wine_version_value = dialog.selected_version | ||||||
|  |  | ||||||
|  |     def clear_wine_version_selection(self): | ||||||
|  |         """Сбрасывает выбор версии Wine.""" | ||||||
|  |         self.wine_version_edit.clear() | ||||||
|  |         self.selected_wine_version_value = None | ||||||
|  |  | ||||||
|  |     def update_create_button_state(self): | ||||||
|  |         """Включает или выключает кнопку 'Создать'.""" | ||||||
|  |         name_ok = bool(self.prefix_name_edit.text().strip()) | ||||||
|  |         version_ok = bool(self.wine_version_edit.text().strip()) | ||||||
|  |         self.create_button.setEnabled(name_ok and version_ok) | ||||||
|  |  | ||||||
|  |     def accept_creation(self): | ||||||
|  |         """Валидирует данные, сохраняет их и закрывает диалог с успехом.""" | ||||||
|  |         prefix_name = self.prefix_name_edit.text().strip() | ||||||
|  |  | ||||||
|  |         if not prefix_name: | ||||||
|  |             QMessageBox.warning(self, "Ошибка", "Имя префикса не может быть пустым.") | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         if not re.match(r'^[a-zA-Z0-9_.-]+$', prefix_name): | ||||||
|  |             QMessageBox.warning(self, "Ошибка", "Имя префикса может содержать только латинские буквы, цифры, точки, дефисы и подчеркивания.") | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         prefix_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name) | ||||||
|  |         if os.path.exists(prefix_path): | ||||||
|  |             QMessageBox.warning(self, "Ошибка", f"Префикс с именем '{prefix_name}' уже существует.") | ||||||
|  |             return | ||||||
|  |  | ||||||
|  |         # Save data | ||||||
|  |         self.prefix_name = prefix_name | ||||||
|  |         self.wine_arch = "win32" if self.arch_win32_radio.isChecked() else "win64" | ||||||
|  |         self.base_pfx = "none" if self.type_clean_radio.isChecked() else "" | ||||||
|  |         self.selected_wine_version_display = self.wine_version_edit.text() | ||||||
|  |  | ||||||
|  |         self.accept() | ||||||
|  |  | ||||||
| class WineHelperGUI(QMainWindow): | class WineHelperGUI(QMainWindow): | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|         super().__init__() |         super().__init__() | ||||||
| @@ -1279,7 +1406,6 @@ class WineHelperGUI(QMainWindow): | |||||||
|         self.current_selected_app = None |         self.current_selected_app = None | ||||||
|         self.icon_animators = {} |         self.icon_animators = {} | ||||||
|         self.previous_tab_index = 0 |         self.previous_tab_index = 0 | ||||||
|         self.selected_wine_version_value = None |  | ||||||
|         self.current_managed_prefix_name = None  # Имя префикса, выбранного в выпадающем списке |         self.current_managed_prefix_name = None  # Имя префикса, выбранного в выпадающем списке | ||||||
|         self.prefixes_before_install = set() |         self.prefixes_before_install = set() | ||||||
|  |  | ||||||
| @@ -1804,81 +1930,25 @@ class WineHelperGUI(QMainWindow): | |||||||
|         ) |         ) | ||||||
|         self.add_tab(installed_tab, "Установленные") |         self.add_tab(installed_tab, "Установленные") | ||||||
|  |  | ||||||
|     def open_wine_version_dialog(self): |  | ||||||
|         """Открывает диалог выбора версии Wine.""" |  | ||||||
|         architecture = "win32" if self.arch_win32_radio.isChecked() else "win64" |  | ||||||
|         dialog = WineVersionSelectionDialog(architecture, self) |  | ||||||
|         if dialog.exec_() == QDialog.Accepted and dialog.selected_version: |  | ||||||
|             self.wine_version_edit.setText(dialog.selected_display_text) |  | ||||||
|             self.selected_wine_version_value = dialog.selected_version |  | ||||||
|  |  | ||||||
|     def clear_wine_version_selection(self): |  | ||||||
|         """ |  | ||||||
|         Сбрасывает выбор версии Wine при смене архитектуры, |  | ||||||
|         чтобы заставить пользователя выбрать заново. |  | ||||||
|         """ |  | ||||||
|         self.wine_version_edit.clear() |  | ||||||
|         self.selected_wine_version_value = None |  | ||||||
|  |  | ||||||
|     def create_prefix_tab(self): |     def create_prefix_tab(self): | ||||||
|         """Создает вкладку 'Менеджер префиксов'""" |         """Создает вкладку 'Менеджер префиксов'""" | ||||||
|         self.prefix_tab = QWidget() |         self.prefix_tab = QWidget() | ||||||
|         layout = QVBoxLayout(self.prefix_tab) |         layout = QVBoxLayout(self.prefix_tab) | ||||||
|         layout.setContentsMargins(10, 10, 10, 10) |         layout.setContentsMargins(10, 10, 10, 10) | ||||||
|  |         layout.setSpacing(10) | ||||||
|  |  | ||||||
|         form_layout = QFormLayout() |         # --- Контейнер для создания нового префикса --- | ||||||
|         form_layout.setSpacing(10) |         creation_groupbox = QGroupBox() | ||||||
|  |         creation_layout = QVBoxLayout(creation_groupbox) | ||||||
|         self.prefix_name_edit = QLineEdit() |         create_prefix_button = QPushButton("Создать новый префикс") | ||||||
|         self.prefix_name_edit.setPlaceholderText("Например: my_prefix") |         create_prefix_button.setFont(QFont('Arial', 12, QFont.Bold)) | ||||||
|         form_layout.addRow("<b>Имя нового префикса:</b>", self.prefix_name_edit) |         create_prefix_button.setStyleSheet("background-color: #0078d7; color: white; padding: 5px;") | ||||||
|  |         create_prefix_button.clicked.connect(self.open_create_prefix_dialog) | ||||||
|         arch_widget = QWidget() |         creation_layout.addWidget(create_prefix_button) | ||||||
|         arch_layout = QHBoxLayout(arch_widget) |         layout.addWidget(creation_groupbox) | ||||||
|         arch_layout.setContentsMargins(0, 0, 0, 0) |  | ||||||
|         self.arch_win32_radio = QRadioButton("32-bit") |  | ||||||
|         self.arch_win64_radio = QRadioButton("64-bit") |  | ||||||
|         self.arch_win64_radio.setChecked(True) |  | ||||||
|         arch_layout.addWidget(self.arch_win32_radio) |  | ||||||
|         arch_layout.addWidget(self.arch_win64_radio) |  | ||||||
|         form_layout.addRow("<b>Разрядность:</b>", arch_widget) |  | ||||||
|  |  | ||||||
|         type_widget = QWidget() |  | ||||||
|         type_layout = QHBoxLayout(type_widget) |  | ||||||
|         type_layout.setContentsMargins(0, 0, 0, 0) |  | ||||||
|         self.type_clean_radio = QRadioButton("Чистый") |  | ||||||
|         self.type_clean_radio.setToolTip("Создает пустой префикс Wine без каких-либо дополнительных компонентов.") |  | ||||||
|         self.type_recommended_radio = QRadioButton("С рекомендуемыми библиотеками") |  | ||||||
|         tooltip_text = "Устанавливает базовый набор компонентов, необходимый для большинства приложений" |  | ||||||
|         self.type_recommended_radio.setToolTip(tooltip_text) |  | ||||||
|         self.type_clean_radio.setChecked(True) |  | ||||||
|         type_layout.addWidget(self.type_clean_radio) |  | ||||||
|         type_layout.addWidget(self.type_recommended_radio) |  | ||||||
|         form_layout.addRow("<b>Наполнение:</b>", type_widget) |  | ||||||
|  |  | ||||||
|         self.wine_version_edit = QLineEdit() |  | ||||||
|         self.wine_version_edit.setReadOnly(True) |  | ||||||
|         self.wine_version_edit.setPlaceholderText("Версия не выбрана") |  | ||||||
|  |  | ||||||
|         select_version_button = QPushButton("Выбрать версию...") |  | ||||||
|         select_version_button.clicked.connect(self.open_wine_version_dialog) |  | ||||||
|  |  | ||||||
|         version_layout = QHBoxLayout() |  | ||||||
|         version_layout.addWidget(self.wine_version_edit) |  | ||||||
|         version_layout.addWidget(select_version_button) |  | ||||||
|         form_layout.addRow("<b>Версия Wine/Proton:</b>", version_layout) |  | ||||||
|  |  | ||||||
|         self.create_prefix_button = QPushButton("Создать префикс") |  | ||||||
|         self.create_prefix_button.setFont(QFont('Arial', 12, QFont.Bold)) |  | ||||||
|         self.create_prefix_button.setStyleSheet("background-color: #0078d7; color: white;") |  | ||||||
|         self.create_prefix_button.setEnabled(False) |  | ||||||
|         self.create_prefix_button.clicked.connect(self.start_prefix_creation) |  | ||||||
|  |  | ||||||
|         layout.addLayout(form_layout) |  | ||||||
|         layout.addWidget(self.create_prefix_button) |  | ||||||
|  |  | ||||||
|         # --- Контейнер для выбора и управления созданными префиксами --- |         # --- Контейнер для выбора и управления созданными префиксами --- | ||||||
|         self.management_container_groupbox = QGroupBox("Управление созданными префиксами") |         self.management_container_groupbox = QGroupBox() | ||||||
|         self.management_container_groupbox.setVisible(False)  # Скрыт, пока нет префиксов |         self.management_container_groupbox.setVisible(False)  # Скрыт, пока нет префиксов | ||||||
|         container_layout = QVBoxLayout(self.management_container_groupbox) |         container_layout = QVBoxLayout(self.management_container_groupbox) | ||||||
|  |  | ||||||
| @@ -2003,10 +2073,6 @@ class WineHelperGUI(QMainWindow): | |||||||
|         layout.addStretch() |         layout.addStretch() | ||||||
|         self.add_tab(self.prefix_tab, "Менеджер префиксов") |         self.add_tab(self.prefix_tab, "Менеджер префиксов") | ||||||
|  |  | ||||||
|         self.arch_win32_radio.toggled.connect(self.clear_wine_version_selection) |  | ||||||
|         self.prefix_name_edit.textChanged.connect(self.update_create_prefix_button_state) |  | ||||||
|         self.prefix_name_edit.textChanged.connect(self.on_prefix_name_edited) |  | ||||||
|         self.wine_version_edit.textChanged.connect(self.update_create_prefix_button_state) |  | ||||||
|         self.prefix_install_path_edit.textChanged.connect(self.update_prefix_install_button_state) |         self.prefix_install_path_edit.textChanged.connect(self.update_prefix_install_button_state) | ||||||
|  |  | ||||||
|     def _get_current_prefixes(self): |     def _get_current_prefixes(self): | ||||||
| @@ -2072,6 +2138,10 @@ class WineHelperGUI(QMainWindow): | |||||||
|             self._setup_prefix_management_panel(None) |             self._setup_prefix_management_panel(None) | ||||||
|             self.delete_prefix_button.setEnabled(False) |             self.delete_prefix_button.setEnabled(False) | ||||||
|         else: |         else: | ||||||
|  |             # Прокручиваем к выбранному элементу, чтобы он был виден в списке | ||||||
|  |             self.created_prefix_selector.view().scrollTo( | ||||||
|  |                 self.created_prefix_selector.model().index(index, 0) | ||||||
|  |             ) | ||||||
|             prefix_name = self.created_prefix_selector.itemText(index) |             prefix_name = self.created_prefix_selector.itemText(index) | ||||||
|             self.current_managed_prefix_name = prefix_name |             self.current_managed_prefix_name = prefix_name | ||||||
|             self._setup_prefix_management_panel(prefix_name) |             self._setup_prefix_management_panel(prefix_name) | ||||||
| @@ -2141,12 +2211,6 @@ class WineHelperGUI(QMainWindow): | |||||||
|         else: |         else: | ||||||
|             QMessageBox.critical(self, "Ошибка удаления", f"Не удалось удалить префикс '{prefix_name}'.\nПодробности смотрите в логе.") |             QMessageBox.critical(self, "Ошибка удаления", f"Не удалось удалить префикс '{prefix_name}'.\nПодробности смотрите в логе.") | ||||||
|  |  | ||||||
|     def on_prefix_name_edited(self, text): |  | ||||||
|         """Сбрасывает состояние управления префиксом, когда пользователь вводит новое имя.""" |  | ||||||
|         if text: |  | ||||||
|             if self.created_prefix_selector.currentIndex() != -1: |  | ||||||
|                 self.created_prefix_selector.setCurrentIndex(-1) |  | ||||||
|  |  | ||||||
|     def _setup_prefix_management_panel(self, prefix_name): |     def _setup_prefix_management_panel(self, prefix_name): | ||||||
|         """Настраивает панель управления префиксом на основе текущего состояния.""" |         """Настраивает панель управления префиксом на основе текущего состояния.""" | ||||||
|         is_prefix_selected = bool(prefix_name) |         is_prefix_selected = bool(prefix_name) | ||||||
| @@ -2478,40 +2542,29 @@ class WineHelperGUI(QMainWindow): | |||||||
|  |  | ||||||
|         self.add_tab(help_tab, "Справка") |         self.add_tab(help_tab, "Справка") | ||||||
|  |  | ||||||
|     def update_create_prefix_button_state(self): |     def open_create_prefix_dialog(self): | ||||||
|         """Включает или выключает кнопку 'Создать префикс' в зависимости от заполнения полей.""" |         """Открывает диалог создания нового префикса.""" | ||||||
|         name_ok = bool(self.prefix_name_edit.text().strip()) |         dialog = CreatePrefixDialog(self) | ||||||
|         version_ok = bool(self.wine_version_edit.text().strip()) |         if dialog.exec_() == QDialog.Accepted: | ||||||
|         self.create_prefix_button.setEnabled(name_ok and version_ok) |             if not self._show_license_agreement_dialog(): | ||||||
|  |                 return | ||||||
|  |  | ||||||
|     def start_prefix_creation(self): |             self.start_prefix_creation( | ||||||
|         """Запускает создание префикса после валидации.""" |                 prefix_name=dialog.prefix_name, | ||||||
|         if not self._show_license_agreement_dialog(): |                 wine_arch=dialog.wine_arch, | ||||||
|             return |                 base_pfx=dialog.base_pfx, | ||||||
|  |                 wine_use=dialog.selected_wine_version_value, | ||||||
|  |                 wine_use_display=dialog.selected_wine_version_display | ||||||
|  |             ) | ||||||
|  |  | ||||||
|  |     def start_prefix_creation(self, prefix_name, wine_arch, base_pfx, wine_use, wine_use_display): | ||||||
|  |         """Запускает создание префикса с заданными параметрами.""" | ||||||
|  |  | ||||||
|         # Сбрасываем выбор в выпадающем списке, чтобы панель управления скрылась на время создания |         # Сбрасываем выбор в выпадающем списке, чтобы панель управления скрылась на время создания | ||||||
|         if self.created_prefix_selector.count() > 0: |         if self.created_prefix_selector.count() > 0: | ||||||
|             self.created_prefix_selector.setCurrentIndex(-1) |             self.created_prefix_selector.setCurrentIndex(-1) | ||||||
|  |  | ||||||
|         prefix_name = self.prefix_name_edit.text().strip() |  | ||||||
|  |  | ||||||
|         if not prefix_name: |  | ||||||
|             QMessageBox.warning(self, "Ошибка", "Имя префикса не может быть пустым.") |  | ||||||
|             return |  | ||||||
|  |  | ||||||
|         if not re.match(r'^[a-zA-Z0-9_.-]+$', prefix_name): |  | ||||||
|             QMessageBox.warning(self, "Ошибка", "Имя префикса может содержать только латинские буквы, цифры, точки, дефисы и подчеркивания.") |  | ||||||
|             return |  | ||||||
|  |  | ||||||
|         prefix_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name) |         prefix_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name) | ||||||
|         if os.path.exists(prefix_path): |  | ||||||
|             QMessageBox.warning(self, "Ошибка", f"Префикс с именем '{prefix_name}' уже существует.") |  | ||||||
|             return |  | ||||||
|  |  | ||||||
|         wine_arch = "win32" if self.arch_win32_radio.isChecked() else "win64" |  | ||||||
|         base_pfx = "none" if self.type_clean_radio.isChecked() else "" |  | ||||||
|         wine_use = self.selected_wine_version_value |  | ||||||
|         wine_use_display = self.wine_version_edit.text() |  | ||||||
|  |  | ||||||
|         self.command_dialog = QDialog(self) |         self.command_dialog = QDialog(self) | ||||||
|         self.command_dialog.setWindowTitle(f"Создание префикса: {prefix_name}") |         self.command_dialog.setWindowTitle(f"Создание префикса: {prefix_name}") | ||||||
| @@ -2584,8 +2637,6 @@ class WineHelperGUI(QMainWindow): | |||||||
|             if not self.management_container_groupbox.isVisible(): |             if not self.management_container_groupbox.isVisible(): | ||||||
|                 self.management_container_groupbox.setVisible(True) |                 self.management_container_groupbox.setVisible(True) | ||||||
|  |  | ||||||
|             self.prefix_name_edit.clear() |  | ||||||
|             self.wine_version_edit.clear() |  | ||||||
|             QMessageBox.information(self, "Успех", |             QMessageBox.information(self, "Успех", | ||||||
|                                     f"Префикс '{prefix_name}' успешно создан.\n" |                                     f"Префикс '{prefix_name}' успешно создан.\n" | ||||||
|                                     "Теперь вы можете управлять им, выбрав его из выпадающего списка.") |                                     "Теперь вы можете управлять им, выбрав его из выпадающего списка.") | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user