forked from CastroFidel/winehelper
expanded information output in the prefix information window
This commit is contained in:
@@ -1280,16 +1280,9 @@ class WineHelperGUI(QMainWindow):
|
|||||||
self.icon_animators = {}
|
self.icon_animators = {}
|
||||||
self.previous_tab_index = 0
|
self.previous_tab_index = 0
|
||||||
self.selected_wine_version_value = None
|
self.selected_wine_version_value = None
|
||||||
self.created_prefixes_info = {} # Хранит информацию о префиксах, созданных на вкладке
|
|
||||||
self.current_managed_prefix_name = None # Имя префикса, выбранного в выпадающем списке
|
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_output_buffer = ""
|
||||||
self.command_last_line_was_progress = False
|
self.command_last_line_was_progress = False
|
||||||
# Создаем главный виджет и layout
|
# Создаем главный виджет и layout
|
||||||
@@ -1325,7 +1318,7 @@ class WineHelperGUI(QMainWindow):
|
|||||||
self.create_help_tab()
|
self.create_help_tab()
|
||||||
|
|
||||||
# Загружаем состояние после создания всех виджетов
|
# Загружаем состояние после создания всех виджетов
|
||||||
self._load_state()
|
self._load_created_prefixes()
|
||||||
|
|
||||||
# Инициализируем состояние, которое будет использоваться для логов
|
# Инициализируем состояние, которое будет использоваться для логов
|
||||||
self._reset_log_state()
|
self._reset_log_state()
|
||||||
@@ -2016,69 +2009,61 @@ class WineHelperGUI(QMainWindow):
|
|||||||
self.wine_version_edit.textChanged.connect(self.update_create_prefix_button_state)
|
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 _remove_prefix_from_gui_state(self, prefix_name):
|
def _get_current_prefixes(self):
|
||||||
"""Удаляет префикс из внутреннего состояния и пользовательского интерфейса вкладки 'Создать префикс'."""
|
"""Возвращает множество имен существующих префиксов."""
|
||||||
if prefix_name in self.created_prefixes_info:
|
prefixes_root_path = os.path.join(Var.USER_WORK_PATH, "prefixes")
|
||||||
del self.created_prefixes_info[prefix_name]
|
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)
|
index_to_remove = self.created_prefix_selector.findText(prefix_name)
|
||||||
if index_to_remove != -1:
|
if index_to_remove != -1:
|
||||||
self.created_prefix_selector.removeItem(index_to_remove)
|
self.created_prefix_selector.removeItem(index_to_remove)
|
||||||
|
|
||||||
# Сохраняем состояние после удаления. on_created_prefix_selected также вызовет сохранение,
|
def _load_created_prefixes(self):
|
||||||
# но этот вызов гарантирует сохранение, даже если сигналы были заблокированы.
|
"""Загружает список созданных префиксов, сканируя файловую систему, и восстанавливает последнее выбранное состояние."""
|
||||||
self._save_state()
|
prefixes_root_path = os.path.join(Var.USER_WORK_PATH, "prefixes")
|
||||||
|
if not os.path.isdir(prefixes_root_path):
|
||||||
def _load_state(self):
|
self.management_container_groupbox.setVisible(False)
|
||||||
"""Загружает последнее состояние GUI из файла."""
|
|
||||||
if not os.path.exists(self.state_file):
|
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(self.state_file, 'r', encoding='utf-8') as f:
|
prefix_names = sorted([
|
||||||
state = json.load(f)
|
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', {})
|
self.created_prefix_selector.blockSignals(True)
|
||||||
if not loaded_prefixes:
|
self.created_prefix_selector.clear()
|
||||||
return
|
if prefix_names:
|
||||||
|
self.created_prefix_selector.addItems(prefix_names)
|
||||||
|
self.created_prefix_selector.blockSignals(False)
|
||||||
|
|
||||||
# Блокируем сигналы, чтобы избежать преждевременного срабатывания
|
if not prefix_names:
|
||||||
self.created_prefix_selector.blockSignals(True)
|
self.management_container_groupbox.setVisible(False)
|
||||||
self.created_prefix_selector.clear()
|
self.on_created_prefix_selected(-1) # Убедимся, что панель управления сброшена
|
||||||
self.created_prefixes_info.clear()
|
return
|
||||||
|
|
||||||
for prefix_name, prefix_info in loaded_prefixes.items():
|
self.management_container_groupbox.setVisible(True)
|
||||||
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:
|
||||||
if self.created_prefix_selector.count() > 0:
|
self.created_prefix_selector.setCurrentIndex(0)
|
||||||
self.management_container_groupbox.setVisible(True)
|
else:
|
||||||
last_managed = state.get('current_managed_prefix_name')
|
# Если список пуст, убедимся, что панель управления сброшена.
|
||||||
index = self.created_prefix_selector.findText(last_managed)
|
self.on_created_prefix_selected(-1)
|
||||||
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):
|
def on_created_prefix_selected(self, index):
|
||||||
"""Обрабатывает выбор префикса из выпадающего списка."""
|
"""Обрабатывает выбор префикса из выпадающего списка."""
|
||||||
@@ -2091,7 +2076,6 @@ class WineHelperGUI(QMainWindow):
|
|||||||
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)
|
||||||
self.delete_prefix_button.setEnabled(True)
|
self.delete_prefix_button.setEnabled(True)
|
||||||
self._save_state()
|
|
||||||
|
|
||||||
def delete_selected_prefix(self):
|
def delete_selected_prefix(self):
|
||||||
"""Удаляет префикс, выбранный в выпадающем списке на вкладке 'Создать префикс'."""
|
"""Удаляет префикс, выбранный в выпадающем списке на вкладке 'Создать префикс'."""
|
||||||
@@ -2165,31 +2149,76 @@ class WineHelperGUI(QMainWindow):
|
|||||||
|
|
||||||
def _setup_prefix_management_panel(self, prefix_name):
|
def _setup_prefix_management_panel(self, prefix_name):
|
||||||
"""Настраивает панель управления префиксом на основе текущего состояния."""
|
"""Настраивает панель управления префиксом на основе текущего состояния."""
|
||||||
if prefix_name and prefix_name in self.created_prefixes_info:
|
is_prefix_selected = bool(prefix_name)
|
||||||
self.prefix_management_groupbox.setEnabled(True)
|
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)
|
self.update_prefix_info_display(prefix_name)
|
||||||
else:
|
else:
|
||||||
self.prefix_management_groupbox.setEnabled(False)
|
|
||||||
self.prefix_info_display.clear()
|
self.prefix_info_display.clear()
|
||||||
self.prefix_install_path_edit.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()
|
self.update_prefix_install_button_state()
|
||||||
|
|
||||||
def update_prefix_info_display(self, prefix_name):
|
def update_prefix_info_display(self, prefix_name):
|
||||||
"""Обновляет информационный блок для созданного префикса."""
|
"""Обновляет информационный блок для созданного префикса, читая данные из last.conf."""
|
||||||
info = self.created_prefixes_info.get(prefix_name)
|
if not prefix_name:
|
||||||
if not info:
|
|
||||||
self.prefix_info_display.clear()
|
self.prefix_info_display.clear()
|
||||||
return
|
return
|
||||||
|
|
||||||
html_content = f"""
|
last_conf_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name, "last.conf")
|
||||||
<p style="line-height: 1.3; font-size: 9pt;">
|
|
||||||
<b>Имя:</b> {html.escape(info['name'])}<br>
|
if not os.path.exists(last_conf_path):
|
||||||
<b>Архитектура:</b> {html.escape(info['arch'])}<br>
|
self.prefix_info_display.setHtml(f"<p>Файл конфигурации last.conf не найден для префикса '{prefix_name}'.</p>")
|
||||||
<b>Версия Wine:</b> {html.escape(info['wine_version'])}<br>
|
return
|
||||||
<b>Путь:</b> {html.escape(info['path'])}</p>"""
|
|
||||||
|
# Словарь для хранения всех переменных из файла
|
||||||
|
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" <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)
|
self.prefix_info_display.setHtml(html_content)
|
||||||
|
|
||||||
def browse_for_prefix_installer(self):
|
def browse_for_prefix_installer(self):
|
||||||
@@ -2484,15 +2513,6 @@ class WineHelperGUI(QMainWindow):
|
|||||||
wine_use = self.selected_wine_version_value
|
wine_use = self.selected_wine_version_value
|
||||||
wine_use_display = self.wine_version_edit.text()
|
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 = QDialog(self)
|
||||||
self.command_dialog.setWindowTitle(f"Создание префикса: {prefix_name}")
|
self.command_dialog.setWindowTitle(f"Создание префикса: {prefix_name}")
|
||||||
self.command_dialog.setMinimumSize(750, 400)
|
self.command_dialog.setMinimumSize(750, 400)
|
||||||
@@ -2556,10 +2576,6 @@ class WineHelperGUI(QMainWindow):
|
|||||||
self._handle_command_finished(exit_code, exit_status)
|
self._handle_command_finished(exit_code, exit_status)
|
||||||
if exit_code == 0:
|
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:
|
if self.created_prefix_selector.findText(prefix_name) == -1:
|
||||||
self.created_prefix_selector.addItem(prefix_name)
|
self.created_prefix_selector.addItem(prefix_name)
|
||||||
|
|
||||||
@@ -2568,7 +2584,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._save_state()
|
|
||||||
self.prefix_name_edit.clear()
|
self.prefix_name_edit.clear()
|
||||||
self.wine_version_edit.clear()
|
self.wine_version_edit.clear()
|
||||||
QMessageBox.information(self, "Успех",
|
QMessageBox.information(self, "Успех",
|
||||||
@@ -3403,6 +3418,8 @@ class WineHelperGUI(QMainWindow):
|
|||||||
if not self._show_license_agreement_dialog():
|
if not self._show_license_agreement_dialog():
|
||||||
return # Пользователь отклонил лицензию
|
return # Пользователь отклонил лицензию
|
||||||
|
|
||||||
|
self.prefixes_before_install = self._get_current_prefixes()
|
||||||
|
|
||||||
self.installation_cancelled = False
|
self.installation_cancelled = False
|
||||||
|
|
||||||
# Создаем диалоговое окно установки
|
# Создаем диалоговое окно установки
|
||||||
@@ -3641,11 +3658,33 @@ class WineHelperGUI(QMainWindow):
|
|||||||
|
|
||||||
if exit_code == 0 and exit_status == QProcess.NormalExit:
|
if exit_code == 0 and exit_status == QProcess.NormalExit:
|
||||||
self.append_log("\n=== Установка успешно завершена ===")
|
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 = QMessageBox(self.install_dialog)
|
||||||
success_box.setWindowTitle("Успех")
|
success_box.setWindowTitle("Успех")
|
||||||
title_name = self._get_current_app_title()
|
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.setIcon(QMessageBox.Information)
|
||||||
success_box.addButton("Готово", QMessageBox.AcceptRole)
|
success_box.addButton("Готово", QMessageBox.AcceptRole)
|
||||||
success_box.exec_()
|
success_box.exec_()
|
||||||
|
Reference in New Issue
Block a user