expanded information output in the prefix information window

This commit is contained in:
Sergey Palcheh
2025-09-08 15:00:18 +06:00
parent 3e91bcf241
commit aa267ad9ef

View File

@@ -1280,16 +1280,9 @@ class WineHelperGUI(QMainWindow):
self.icon_animators = {}
self.previous_tab_index = 0
self.selected_wine_version_value = None
self.created_prefixes_info = {} # Хранит информацию о префиксах, созданных на вкладке
self.current_managed_prefix_name = None # Имя префикса, выбранного в выпадающем списке
self.pending_prefix_info = None # Временное хранилище информации о создаваемом префиксе
self.prefixes_before_install = set()
# Добавим путь к файлу состояния
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 = ""
self.command_last_line_was_progress = False
# Создаем главный виджет и layout
@@ -1325,7 +1318,7 @@ class WineHelperGUI(QMainWindow):
self.create_help_tab()
# Загружаем состояние после создания всех виджетов
self._load_state()
self._load_created_prefixes()
# Инициализируем состояние, которое будет использоваться для логов
self._reset_log_state()
@@ -2016,69 +2009,61 @@ class WineHelperGUI(QMainWindow):
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)
def _remove_prefix_from_gui_state(self, prefix_name):
"""Удаляет префикс из внутреннего состояния и пользовательского интерфейса вкладки 'Создать префикс'."""
if prefix_name in self.created_prefixes_info:
del self.created_prefixes_info[prefix_name]
def _get_current_prefixes(self):
"""Возвращает множество имен существующих префиксов."""
prefixes_root_path = os.path.join(Var.USER_WORK_PATH, "prefixes")
if not os.path.isdir(prefixes_root_path):
return set()
try:
return {
name for name in os.listdir(prefixes_root_path)
if os.path.isdir(os.path.join(prefixes_root_path, name))
}
except OSError as e:
print(f"Предупреждение: не удалось прочитать директорию префиксов: {e}")
return set()
def _remove_prefix_from_gui_state(self, prefix_name):
"""Удаляет префикс из пользовательского интерфейса вкладки 'Создать префикс'."""
index_to_remove = self.created_prefix_selector.findText(prefix_name)
if index_to_remove != -1:
self.created_prefix_selector.removeItem(index_to_remove)
# Сохраняем состояние после удаления. on_created_prefix_selected также вызовет сохранение,
# но этот вызов гарантирует сохранение, даже если сигналы были заблокированы.
self._save_state()
def _load_state(self):
"""Загружает последнее состояние GUI из файла."""
if not os.path.exists(self.state_file):
def _load_created_prefixes(self):
"""Загружает список созданных префиксов, сканируя файловую систему, и восстанавливает последнее выбранное состояние."""
prefixes_root_path = os.path.join(Var.USER_WORK_PATH, "prefixes")
if not os.path.isdir(prefixes_root_path):
self.management_container_groupbox.setVisible(False)
return
try:
with open(self.state_file, 'r', encoding='utf-8') as f:
state = json.load(f)
prefix_names = sorted([
name for name in os.listdir(prefixes_root_path)
if os.path.isdir(os.path.join(prefixes_root_path, name))
])
except OSError as e:
print(f"Предупреждение: не удалось прочитать директорию префиксов: {e}")
prefix_names = []
loaded_prefixes = state.get('created_prefixes_info', {})
if not loaded_prefixes:
return
self.created_prefix_selector.blockSignals(True)
self.created_prefix_selector.clear()
if prefix_names:
self.created_prefix_selector.addItems(prefix_names)
self.created_prefix_selector.blockSignals(False)
# Блокируем сигналы, чтобы избежать преждевременного срабатывания
self.created_prefix_selector.blockSignals(True)
self.created_prefix_selector.clear()
self.created_prefixes_info.clear()
if not prefix_names:
self.management_container_groupbox.setVisible(False)
self.on_created_prefix_selected(-1) # Убедимся, что панель управления сброшена
return
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.management_container_groupbox.setVisible(True)
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}")
# По умолчанию выбираем первый элемент в списке, если он есть.
if self.created_prefix_selector.count() > 0:
self.created_prefix_selector.setCurrentIndex(0)
else:
# Если список пуст, убедимся, что панель управления сброшена.
self.on_created_prefix_selected(-1)
def on_created_prefix_selected(self, index):
"""Обрабатывает выбор префикса из выпадающего списка."""
@@ -2091,7 +2076,6 @@ class WineHelperGUI(QMainWindow):
self.current_managed_prefix_name = prefix_name
self._setup_prefix_management_panel(prefix_name)
self.delete_prefix_button.setEnabled(True)
self._save_state()
def delete_selected_prefix(self):
"""Удаляет префикс, выбранный в выпадающем списке на вкладке 'Создать префикс'."""
@@ -2165,31 +2149,76 @@ class WineHelperGUI(QMainWindow):
def _setup_prefix_management_panel(self, prefix_name):
"""Настраивает панель управления префиксом на основе текущего состояния."""
if prefix_name and prefix_name in self.created_prefixes_info:
self.prefix_management_groupbox.setEnabled(True)
is_prefix_selected = bool(prefix_name)
self.prefix_management_groupbox.setEnabled(is_prefix_selected)
self.create_launcher_button.setEnabled(is_prefix_selected)
if is_prefix_selected:
self.update_prefix_info_display(prefix_name)
else:
self.prefix_management_groupbox.setEnabled(False)
self.prefix_info_display.clear()
self.prefix_install_path_edit.clear()
# Кнопка "Создать ярлык" должна быть активна, если выбран действительный префикс
is_prefix_selected = bool(prefix_name and prefix_name in self.created_prefixes_info)
self.create_launcher_button.setEnabled(is_prefix_selected)
self.update_prefix_install_button_state()
def update_prefix_info_display(self, prefix_name):
"""Обновляет информационный блок для созданного префикса."""
info = self.created_prefixes_info.get(prefix_name)
if not info:
"""Обновляет информационный блок для созданного префикса, читая данные из last.conf."""
if not prefix_name:
self.prefix_info_display.clear()
return
html_content = f"""
<p style="line-height: 1.3; font-size: 9pt;">
<b>Имя:</b> {html.escape(info['name'])}<br>
<b>Архитектура:</b> {html.escape(info['arch'])}<br>
<b>Версия Wine:</b> {html.escape(info['wine_version'])}<br>
<b>Путь:</b> {html.escape(info['path'])}</p>"""
last_conf_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name, "last.conf")
if not os.path.exists(last_conf_path):
self.prefix_info_display.setHtml(f"<p>Файл конфигурации last.conf не найден для префикса '{prefix_name}'.</p>")
return
# Словарь для хранения всех переменных из файла
all_vars = {}
try:
with open(last_conf_path, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if line.startswith('export '):
parts = line[7:].split('=', 1)
if len(parts) == 2:
key = parts[0].strip()
value = parts[1].strip().strip('"\'')
all_vars[key] = value
except IOError as e:
self.prefix_info_display.setHtml(f"<p>Ошибка чтения last.conf: {e}</p>")
return
# Карта для красивого отображения известных переменных
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 'С рекомендуемыми библиотеками'),
}
display_order = ["WINEPREFIX", "WINEARCH", "WH_WINE_USE", "BASE_PFX"]
html_content = f'<p style="line-height: 1.3; font-size: 9pt;">'
html_content += f"<b>Имя:</b> {html.escape(prefix_name)}<br>"
# Отображаем известные переменные в заданном порядке
for key in display_order:
if key in all_vars:
label, formatter = display_map[key]
value = formatter(all_vars[key])
html_content += f"<b>{html.escape(label)}:</b> {html.escape(value)}<br>"
# Отображаем остальные (неизвестные) переменные
other_vars_html = ""
for key, value in sorted(all_vars.items()):
if key not in display_map:
other_vars_html += f"&nbsp;&nbsp;<b>{html.escape(key)}:</b> {html.escape(value)}<br>"
if other_vars_html:
html_content += "<br><b>Дополнительные параметры:</b><br>"
html_content += other_vars_html
html_content += "</p>"
self.prefix_info_display.setHtml(html_content)
def browse_for_prefix_installer(self):
@@ -2484,15 +2513,6 @@ class WineHelperGUI(QMainWindow):
wine_use = self.selected_wine_version_value
wine_use_display = self.wine_version_edit.text()
# Сохраняем информацию для отображения после создания
self.pending_prefix_info = {
'name': prefix_name,
'path': prefix_path,
'arch': "32-bit" if wine_arch == "win32" else "64-bit",
'type': 'Чистый' if base_pfx else 'С рекомендуемыми библиотеками',
'wine_version': wine_use_display
}
self.command_dialog = QDialog(self)
self.command_dialog.setWindowTitle(f"Создание префикса: {prefix_name}")
self.command_dialog.setMinimumSize(750, 400)
@@ -2556,10 +2576,6 @@ class WineHelperGUI(QMainWindow):
self._handle_command_finished(exit_code, exit_status)
if exit_code == 0:
# Добавляем новый префикс в список и выбираем его
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)
@@ -2568,7 +2584,6 @@ class WineHelperGUI(QMainWindow):
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, "Успех",
@@ -3403,6 +3418,8 @@ class WineHelperGUI(QMainWindow):
if not self._show_license_agreement_dialog():
return # Пользователь отклонил лицензию
self.prefixes_before_install = self._get_current_prefixes()
self.installation_cancelled = False
# Создаем диалоговое окно установки
@@ -3641,11 +3658,33 @@ class WineHelperGUI(QMainWindow):
if exit_code == 0 and exit_status == QProcess.NormalExit:
self.append_log("\n=== Установка успешно завершена ===")
# --- Обновление списка префиксов ---
# Определяем, какой префикс был создан
prefixes_after_install = self._get_current_prefixes()
new_prefixes = prefixes_after_install - getattr(self, 'prefixes_before_install', set())
# Перезагружаем список префиксов на вкладке "Создать префикс"
self._load_created_prefixes()
new_prefix_name = None
if new_prefixes:
# Обычно создается один префикс, берем первый из найденных
new_prefix_name = new_prefixes.pop()
# Находим и выбираем его в выпадающем списке
index = self.created_prefix_selector.findText(new_prefix_name)
if index != -1:
self.created_prefix_selector.setCurrentIndex(index)
# --- Конец обновления списка префиксов ---
# Создаем кастомный диалог, чтобы кнопка была на русском
success_box = QMessageBox(self.install_dialog)
success_box.setWindowTitle("Успех")
title_name = self._get_current_app_title()
success_box.setText(f"Программа «{title_name}» установлена успешно!")
success_text = f"Программа «{title_name}» установлена успешно!"
if new_prefix_name:
success_text += f"\n\nНовый префикс '{new_prefix_name}' был автоматически выбран в списке управления на вкладке 'Создать префикс'."
success_box.setText(success_text)
success_box.setIcon(QMessageBox.Information)
success_box.addButton("Готово", QMessageBox.AcceptRole)
success_box.exec_()