forked from CastroFidel/winehelper
		
	added the choice of a prefix to be created for management
This commit is contained in:
		| @@ -1268,8 +1268,14 @@ class WineHelperGUI(QMainWindow): | ||||
|         self.icon_animators = {} | ||||
|         self.previous_tab_index = 0 | ||||
|         self.selected_wine_version_value = None | ||||
|         self.last_created_prefix_name = None | ||||
|         self.last_created_prefix_info = None | ||||
|         self.created_prefixes_info = {}  # Хранит информацию о префиксах, созданных на вкладке | ||||
|         self.current_managed_prefix_name = None  # Имя префикса, выбранного в выпадающем списке | ||||
|         self.pending_prefix_info = None  # Временное хранилище информации о создаваемом префиксе | ||||
|  | ||||
|         # Добавим путь к файлу состояния | ||||
|         self.config_dir = os.path.join(os.path.expanduser("~"), ".config", "winehelper") | ||||
|         os.makedirs(self.config_dir, exist_ok=True) | ||||
|         self.state_file = os.path.join(self.config_dir, "gui_state.json") | ||||
|  | ||||
|         # State for command dialog log processing (specifically for prefix creation) | ||||
|         self.command_output_buffer = "" | ||||
| @@ -1306,6 +1312,9 @@ class WineHelperGUI(QMainWindow): | ||||
|         self.create_prefix_tab() | ||||
|         self.create_help_tab() | ||||
|  | ||||
|         # Загружаем состояние после создания всех виджетов | ||||
|         self._load_state() | ||||
|  | ||||
|         # Инициализируем состояние, которое будет использоваться для логов | ||||
|         self._reset_log_state() | ||||
|  | ||||
| @@ -1819,18 +1828,19 @@ class WineHelperGUI(QMainWindow): | ||||
|         self.prefix_name_edit.setPlaceholderText("Например: my_prefix") | ||||
|         form_layout.addRow("<b>Имя нового префикса:</b>", self.prefix_name_edit) | ||||
|  | ||||
|         self.arch_groupbox = QGroupBox("Архитектура") | ||||
|         arch_layout = QHBoxLayout() | ||||
|         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) | ||||
|         self.arch_groupbox.setLayout(arch_layout) | ||||
|         form_layout.addRow("<b>Разрядность:</b>", self.arch_groupbox) | ||||
|         form_layout.addRow("<b>Разрядность:</b>", arch_widget) | ||||
|  | ||||
|         self.type_groupbox = QGroupBox("Тип префикса") | ||||
|         type_layout = QHBoxLayout() | ||||
|         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("С рекомендуемыми библиотеками") | ||||
| @@ -1839,8 +1849,7 @@ class WineHelperGUI(QMainWindow): | ||||
|         self.type_clean_radio.setChecked(True) | ||||
|         type_layout.addWidget(self.type_clean_radio) | ||||
|         type_layout.addWidget(self.type_recommended_radio) | ||||
|         self.type_groupbox.setLayout(type_layout) | ||||
|         form_layout.addRow("<b>Наполнение:</b>", self.type_groupbox) | ||||
|         form_layout.addRow("<b>Наполнение:</b>", type_widget) | ||||
|  | ||||
|         self.wine_version_edit = QLineEdit() | ||||
|         self.wine_version_edit.setReadOnly(True) | ||||
| @@ -1854,63 +1863,6 @@ class WineHelperGUI(QMainWindow): | ||||
|         version_layout.addWidget(select_version_button) | ||||
|         form_layout.addRow("<b>Версия Wine/Proton:</b>", version_layout) | ||||
|  | ||||
|         # --- GroupBox for managing the created prefix --- | ||||
|         self.prefix_management_groupbox = QGroupBox("Управление префиксом") | ||||
|         self.prefix_management_groupbox.setEnabled(False)  # Disabled by default | ||||
|         management_layout = QGridLayout(self.prefix_management_groupbox) | ||||
|         management_layout.setSpacing(5) | ||||
|  | ||||
|         # --- Left side: Buttons --- | ||||
|         self.prefix_winetricks_button = QPushButton("Менеджер компонентов") | ||||
|         self.prefix_winetricks_button.clicked.connect( | ||||
|             lambda: self.open_winetricks_manager(prefix_name=self.last_created_prefix_name)) | ||||
|         self.prefix_winetricks_button.setToolTip( | ||||
|             "Установка компонентов, библиотек и шрифтов в префикс с помощью Winetricks.") | ||||
|         management_layout.addWidget(self.prefix_winetricks_button, 0, 0) | ||||
|  | ||||
|         self.prefix_winecfg_button = QPushButton("Редактор настроек") | ||||
|         self.prefix_winecfg_button.clicked.connect( | ||||
|             lambda: self._run_wine_util('winecfg', prefix_name=self.last_created_prefix_name)) | ||||
|         self.prefix_winecfg_button.setToolTip( | ||||
|             "Запуск утилиты winecfg для настройки параметров Wine (версия Windows, диски, аудио и т.д.).") | ||||
|         management_layout.addWidget(self.prefix_winecfg_button, 0, 1) | ||||
|  | ||||
|         self.prefix_regedit_button = QPushButton("Редактор реестра") | ||||
|         self.prefix_regedit_button.clicked.connect( | ||||
|             lambda: self._run_wine_util('regedit', prefix_name=self.last_created_prefix_name)) | ||||
|         self.prefix_regedit_button.setToolTip( | ||||
|             "Запуск редактора реестра Wine (regedit) для просмотра и изменения ключей реестра в префиксе.") | ||||
|         management_layout.addWidget(self.prefix_regedit_button, 1, 0) | ||||
|  | ||||
|         self.prefix_uninstaller_button = QPushButton("Удаление программ") | ||||
|         self.prefix_uninstaller_button.clicked.connect( | ||||
|             lambda: self._run_wine_util('uninstaller', prefix_name=self.last_created_prefix_name)) | ||||
|         self.prefix_uninstaller_button.setToolTip( | ||||
|             "Запуск стандартного деинсталлятора Wine для удаления установленных в префикс Windows-программ.") | ||||
|         management_layout.addWidget(self.prefix_uninstaller_button, 1, 1) | ||||
|  | ||||
|         self.prefix_cmd_button = QPushButton("Командная строка") | ||||
|         self.prefix_cmd_button.clicked.connect(lambda: self._run_wine_util('cmd', prefix_name=self.last_created_prefix_name)) | ||||
|         self.prefix_cmd_button.setToolTip("Запуск командной строки (cmd) в окружении выбранного префикса.") | ||||
|         management_layout.addWidget(self.prefix_cmd_button, 2, 0) | ||||
|  | ||||
|         self.prefix_winefile_button = QPushButton("Файловый менеджер") | ||||
|         self.prefix_winefile_button.clicked.connect( | ||||
|             lambda: self._run_wine_util('winefile', prefix_name=self.last_created_prefix_name)) | ||||
|         self.prefix_winefile_button.setToolTip("Запуск файлового менеджера Wine (winefile) для просмотра файлов внутри префикса.") | ||||
|         management_layout.addWidget(self.prefix_winefile_button, 2, 1) | ||||
|  | ||||
|         # --- Right side: Info display --- | ||||
|         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) | ||||
|  | ||||
|         # Устанавливаем растяжение колонок, чтобы область кнопок и область информации были примерно равны | ||||
|         management_layout.setColumnStretch(0, 1) | ||||
|         management_layout.setColumnStretch(1, 1) | ||||
|         management_layout.setColumnStretch(2, 2) | ||||
|  | ||||
|         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;") | ||||
| @@ -1919,7 +1871,75 @@ class WineHelperGUI(QMainWindow): | ||||
|  | ||||
|         layout.addLayout(form_layout) | ||||
|         layout.addWidget(self.create_prefix_button) | ||||
|         layout.addWidget(self.prefix_management_groupbox) | ||||
|  | ||||
|         # --- Контейнер для выбора и управления созданными префиксами --- | ||||
|         self.management_container_groupbox = QGroupBox("Управление созданными префиксами") | ||||
|         self.management_container_groupbox.setVisible(False)  # Скрыт, пока нет префиксов | ||||
|         container_layout = QVBoxLayout(self.management_container_groupbox) | ||||
|  | ||||
|         self.created_prefix_selector = QComboBox() | ||||
|         self.created_prefix_selector.setPlaceholderText("Выберите префикс для управления") | ||||
|         self.created_prefix_selector.currentIndexChanged.connect(self.on_created_prefix_selected) | ||||
|         container_layout.addWidget(self.created_prefix_selector) | ||||
|  | ||||
|         # --- GroupBox для управления выбранным префиксом --- | ||||
|         self.prefix_management_groupbox = QGroupBox("Управление")  # Заголовок будет меняться | ||||
|         self.prefix_management_groupbox.setEnabled(False) | ||||
|         management_layout = QGridLayout(self.prefix_management_groupbox) | ||||
|         management_layout.setSpacing(5) | ||||
|  | ||||
|         # --- Левая сторона: Кнопки --- | ||||
|         self.prefix_winetricks_button = QPushButton("Менеджер компонентов") | ||||
|         self.prefix_winetricks_button.clicked.connect( | ||||
|             lambda: self.open_winetricks_manager(prefix_name=self.current_managed_prefix_name)) | ||||
|         self.prefix_winetricks_button.setToolTip( | ||||
|             "Установка компонентов, библиотек и шрифтов в префикс с помощью Winetricks.") | ||||
|         management_layout.addWidget(self.prefix_winetricks_button, 0, 0) | ||||
|  | ||||
|         self.prefix_winecfg_button = QPushButton("Редактор настроек") | ||||
|         self.prefix_winecfg_button.clicked.connect( | ||||
|             lambda: self._run_wine_util('winecfg', prefix_name=self.current_managed_prefix_name)) | ||||
|         self.prefix_winecfg_button.setToolTip( | ||||
|             "Запуск утилиты winecfg для настройки параметров Wine (версия Windows, диски, аудио и т.д.).") | ||||
|         management_layout.addWidget(self.prefix_winecfg_button, 0, 1) | ||||
|  | ||||
|         self.prefix_regedit_button = QPushButton("Редактор реестра") | ||||
|         self.prefix_regedit_button.clicked.connect( | ||||
|             lambda: self._run_wine_util('regedit', prefix_name=self.current_managed_prefix_name)) | ||||
|         self.prefix_regedit_button.setToolTip( | ||||
|             "Запуск редактора реестра Wine (regedit) для просмотра и изменения ключей реестра в префиксе.") | ||||
|         management_layout.addWidget(self.prefix_regedit_button, 1, 0) | ||||
|  | ||||
|         self.prefix_uninstaller_button = QPushButton("Удаление программ") | ||||
|         self.prefix_uninstaller_button.clicked.connect( | ||||
|             lambda: self._run_wine_util('uninstaller', prefix_name=self.current_managed_prefix_name)) | ||||
|         self.prefix_uninstaller_button.setToolTip( | ||||
|             "Запуск стандартного деинсталлятора Wine для удаления установленных в префикс Windows-программ.") | ||||
|         management_layout.addWidget(self.prefix_uninstaller_button, 1, 1) | ||||
|  | ||||
|         self.prefix_cmd_button = QPushButton("Командная строка") | ||||
|         self.prefix_cmd_button.clicked.connect(lambda: self._run_wine_util('cmd', prefix_name=self.current_managed_prefix_name)) | ||||
|         self.prefix_cmd_button.setToolTip("Запуск командной строки (cmd) в окружении выбранного префикса.") | ||||
|         management_layout.addWidget(self.prefix_cmd_button, 2, 0) | ||||
|  | ||||
|         self.prefix_winefile_button = QPushButton("Файловый менеджер") | ||||
|         self.prefix_winefile_button.clicked.connect( | ||||
|             lambda: self._run_wine_util('winefile', prefix_name=self.current_managed_prefix_name)) | ||||
|         self.prefix_winefile_button.setToolTip("Запуск файлового менеджера Wine (winefile) для просмотра файлов внутри префикса.") | ||||
|         management_layout.addWidget(self.prefix_winefile_button, 2, 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) | ||||
|  | ||||
|         management_layout.setColumnStretch(0, 1) | ||||
|         management_layout.setColumnStretch(1, 1) | ||||
|         management_layout.setColumnStretch(2, 2) | ||||
|  | ||||
|         container_layout.addWidget(self.prefix_management_groupbox) | ||||
|         layout.addWidget(self.management_container_groupbox) | ||||
|         layout.addStretch() | ||||
|         self.add_tab(self.prefix_tab, "Создать префикс") | ||||
|  | ||||
| @@ -1928,22 +1948,92 @@ class WineHelperGUI(QMainWindow): | ||||
|         self.prefix_name_edit.textChanged.connect(self.on_prefix_name_edited) | ||||
|         self.wine_version_edit.textChanged.connect(self.update_create_prefix_button_state) | ||||
|  | ||||
|     def _load_state(self): | ||||
|         """Загружает последнее состояние GUI из файла.""" | ||||
|         if not os.path.exists(self.state_file): | ||||
|             return | ||||
|         try: | ||||
|             with open(self.state_file, 'r', encoding='utf-8') as f: | ||||
|                 state = json.load(f) | ||||
|  | ||||
|             loaded_prefixes = state.get('created_prefixes_info', {}) | ||||
|             if not loaded_prefixes: | ||||
|                 return | ||||
|  | ||||
|             # Блокируем сигналы, чтобы избежать преждевременного срабатывания | ||||
|             self.created_prefix_selector.blockSignals(True) | ||||
|             self.created_prefix_selector.clear() | ||||
|             self.created_prefixes_info.clear() | ||||
|  | ||||
|             for prefix_name, prefix_info in loaded_prefixes.items(): | ||||
|                 prefix_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name) | ||||
|                 if os.path.isdir(prefix_path): | ||||
|                     self.created_prefixes_info[prefix_name] = prefix_info | ||||
|                     self.created_prefix_selector.addItem(prefix_name) | ||||
|  | ||||
|             self.created_prefix_selector.blockSignals(False) | ||||
|  | ||||
|             if self.created_prefix_selector.count() > 0: | ||||
|                 self.management_container_groupbox.setVisible(True) | ||||
|                 last_managed = state.get('current_managed_prefix_name') | ||||
|                 index = self.created_prefix_selector.findText(last_managed) | ||||
|                 if index != -1: | ||||
|                     self.created_prefix_selector.setCurrentIndex(index) | ||||
|                 else: | ||||
|                     self.created_prefix_selector.setCurrentIndex(0) # Выбираем первый, если предыдущий не найден | ||||
|             else: | ||||
|                 self.management_container_groupbox.setVisible(False) | ||||
|  | ||||
|         except (IOError, json.JSONDecodeError, TypeError) as e: | ||||
|             print(f"Предупреждение: не удалось загрузить состояние GUI: {e}") | ||||
|  | ||||
|     def _save_state(self): | ||||
|         """Сохраняет текущее состояние GUI в файл.""" | ||||
|         state = { | ||||
|             'created_prefixes_info': self.created_prefixes_info, | ||||
|             'current_managed_prefix_name': self.current_managed_prefix_name | ||||
|         } | ||||
|         try: | ||||
|             with open(self.state_file, 'w', encoding='utf-8') as f: | ||||
|                 json.dump(state, f, indent=2, ensure_ascii=False) | ||||
|         except IOError as e: | ||||
|             print(f"Предупреждение: не удалось сохранить состояние GUI: {e}") | ||||
|  | ||||
|     def on_created_prefix_selected(self, index): | ||||
|         """Обрабатывает выбор префикса из выпадающего списка.""" | ||||
|         if index == -1: | ||||
|             self.current_managed_prefix_name = None | ||||
|             self._setup_prefix_management_panel(None) | ||||
|         else: | ||||
|             prefix_name = self.created_prefix_selector.itemText(index) | ||||
|             self.current_managed_prefix_name = prefix_name | ||||
|             self._setup_prefix_management_panel(prefix_name) | ||||
|         self._save_state() | ||||
|  | ||||
|     def on_prefix_name_edited(self, text): | ||||
|         """Сбрасывает состояние управления префиксом, когда пользователь вводит новое имя.""" | ||||
|         if text and self.prefix_management_groupbox.isEnabled(): | ||||
|         if text: | ||||
|             if self.created_prefix_selector.currentIndex() != -1: | ||||
|                 self.created_prefix_selector.setCurrentIndex(-1) | ||||
|  | ||||
|     def _setup_prefix_management_panel(self, prefix_name): | ||||
|         """Настраивает панель управления префиксом на основе текущего состояния.""" | ||||
|         if prefix_name and prefix_name in self.created_prefixes_info: | ||||
|             self.prefix_management_groupbox.setTitle(f"Управление «{prefix_name}»") | ||||
|             self.prefix_management_groupbox.setEnabled(True) | ||||
|             self.update_prefix_info_display(prefix_name) | ||||
|         else: | ||||
|             self.prefix_management_groupbox.setTitle("Управление") | ||||
|             self.prefix_management_groupbox.setEnabled(False) | ||||
|             self.prefix_management_groupbox.setTitle("Управление префиксом") | ||||
|             self.last_created_prefix_name = None | ||||
|             self.last_created_prefix_info = None | ||||
|             self.prefix_info_display.clear() | ||||
|  | ||||
|     def update_prefix_info_display(self): | ||||
|     def update_prefix_info_display(self, prefix_name): | ||||
|         """Обновляет информационный блок для созданного префикса.""" | ||||
|         if not self.last_created_prefix_info: | ||||
|         info = self.created_prefixes_info.get(prefix_name) | ||||
|         if not info: | ||||
|             self.prefix_info_display.clear() | ||||
|             return | ||||
|  | ||||
|         info = self.last_created_prefix_info | ||||
|         html_content = f""" | ||||
|             <p style="line-height: 1.3; font-size: 9pt;"> | ||||
|             <b>Имя:</b> {html.escape(info['name'])}<br> | ||||
| @@ -2083,12 +2173,9 @@ class WineHelperGUI(QMainWindow): | ||||
|         if not self._show_license_agreement_dialog(): | ||||
|             return | ||||
|  | ||||
|         # Сбрасываем состояние управления предыдущим созданным префиксом | ||||
|         self.last_created_prefix_name = None | ||||
|         self.last_created_prefix_info = None | ||||
|         self.prefix_info_display.clear() | ||||
|         self.prefix_management_groupbox.setEnabled(False) | ||||
|         self.prefix_management_groupbox.setTitle("Управление префиксом") | ||||
|         # Сбрасываем выбор в выпадающем списке, чтобы панель управления скрылась на время создания | ||||
|         if self.created_prefix_selector.count() > 0: | ||||
|             self.created_prefix_selector.setCurrentIndex(-1) | ||||
|  | ||||
|         prefix_name = self.prefix_name_edit.text().strip() | ||||
|  | ||||
| @@ -2111,7 +2198,7 @@ class WineHelperGUI(QMainWindow): | ||||
|         wine_use_display = self.wine_version_edit.text() | ||||
|  | ||||
|         # Сохраняем информацию для отображения после создания | ||||
|         self.last_created_prefix_info = { | ||||
|         self.pending_prefix_info = { | ||||
|             'name': prefix_name, | ||||
|             'path': prefix_path, | ||||
|             'arch': "32-bit" if wine_arch == "win32" else "64-bit", | ||||
| @@ -2181,14 +2268,25 @@ class WineHelperGUI(QMainWindow): | ||||
|  | ||||
|         self._handle_command_finished(exit_code, exit_status) | ||||
|         if exit_code == 0: | ||||
|             self.last_created_prefix_name = prefix_name | ||||
|             self.prefix_management_groupbox.setTitle(f"Управление префиксом «{prefix_name}»") | ||||
|             self.prefix_management_groupbox.setEnabled(True) | ||||
|             self.update_prefix_info_display() | ||||
|             # Добавляем новый префикс в список и выбираем его | ||||
|             if self.pending_prefix_info: | ||||
|                 self.created_prefixes_info[prefix_name] = self.pending_prefix_info | ||||
|                 self.pending_prefix_info = None | ||||
|  | ||||
|             if self.created_prefix_selector.findText(prefix_name) == -1: | ||||
|                 self.created_prefix_selector.addItem(prefix_name) | ||||
|  | ||||
|             self.created_prefix_selector.setCurrentText(prefix_name) | ||||
|  | ||||
|             if not self.management_container_groupbox.isVisible(): | ||||
|                 self.management_container_groupbox.setVisible(True) | ||||
|  | ||||
|             self._save_state() | ||||
|             self.prefix_name_edit.clear() | ||||
|             self.wine_version_edit.clear() | ||||
|             QMessageBox.information(self, "Успех", | ||||
|                                     f"Префикс '{prefix_name}' успешно создан.\nТеперь вы можете управлять им с помощью кнопок ниже.") | ||||
|                                     f"Префикс '{prefix_name}' успешно создан.\n" | ||||
|                                     "Теперь вы можете управлять им, выбрав его из выпадающего списка.") | ||||
|  | ||||
|     def update_installed_apps(self): | ||||
|         """Обновляет список установленных приложений в виде кнопок""" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user