Compare commits

..

11 Commits

Author SHA1 Message Date
Mikhail Tergoev
e2b2c9568c Merge branch 'minergenon-devel' 2025-10-06 13:30:06 +03:00
Sergey Palcheh
7113d864be added the Open Prefix folder button in the file manager 2025-10-03 14:23:48 +06:00
Mikhail Tergoev
9a1a88d01b fixed typos fot tflex manual 2025-10-03 10:17:26 +03:00
Sergey Palcheh
ad775e4644 added the Delete all WineHelper data button 2025-10-02 15:45:24 +06:00
Sergey Palcheh
36f5c306c5 remove-all: added removal of /home/minergenon/winehelper_backup_log 2025-10-02 14:51:37 +06:00
Sergey Palcheh
173a7ae41f README: added a description of creating a log and backup 2025-10-02 14:38:58 +06:00
Sergey Palcheh
32e56879f7 fixed the appearance of the Open folder with the prefix's log/backup button 2025-10-02 13:54:49 +06:00
Sergey Palcheh
b88ea9f478 the Open folder with the log button has been renamed to Open folder with the log/backup prefix 2025-10-02 13:41:59 +06:00
Sergey Palcheh
dd82cee5ea the backup copy of the prefix has been moved to the home directory 2025-10-02 13:22:54 +06:00
Sergey Palcheh
a35efc347d added a button to open the location of the log file 2025-10-02 12:59:07 +06:00
Sergey Palcheh
95a8d370ab winehelper.log moved to the winehelper_backup_log directory 2025-10-02 12:24:21 +06:00
6 changed files with 147 additions and 10 deletions

View File

@@ -298,6 +298,13 @@ WineHelper предоставляет доступ к основным инст
<p><em>Выбранное приложение во вкладке "Установленные"</em></p>
</div>
Расположения лога запуска программы а также резервной копии префикса можно просмотреть с помощью кнопки **«Открыть папку с логом/резервной копией префикса»** которая появляется автоматически после создания лога или резервной копии.
<div align="center">
<img src="image/handbook/folder_log_backup.png">
<p><em>Кнопка "Открыть папку с логом/резервной копией префикса"</em></p>
</div>
### Вкладка «Менеджер префиксов»
Эта вкладка предоставляет мощные инструменты для управления префиксами Wine.

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# info_ru: Ручная установка дополнений для T-FLEX DOCS 17 или 18
# info_ru: Ручная установка дополнений для T-FLEX CAD 17 или 18
########################################################################
export PROG_NAME="T-FLEX CAD 17/18"
export PROG_ICON="tflexcad"

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# info_ru: Ручная установка дополнений для T-FLEX CAD 17 или 18
# info_ru: Ручная установка дополнений для T-FLEX DOCS 17 или 18
########################################################################
export PROG_NAME="T-FLEX CAD 17/18"
export PROG_NAME="T-FLEX DOCS 17/18"
export PROG_ICON="tflexcad"
export WH_WINE_USE="wine_wh_tflex_10-9_amd64"
export BASE_PFX="tflex_pfx_x64_v03"

View File

@@ -102,7 +102,9 @@ else
fi
if [[ $WINEDEBUG != "-all" ]] ; then
export LOG_FILE="$HOME/winehelper.log"
log_dir="$HOME/winehelper_backup_log"
mkdir -p "$log_dir"
export LOG_FILE="$log_dir/winehelper.log"
date > "$LOG_FILE"
print_warning "Включен режим логирования работы WINE."
print_warning "Лог будет сохранен по пути: $LOG_FILE"
@@ -1773,6 +1775,7 @@ remove_winehelper () {
echo " - Все настройки WineHelper"
echo " - Все приложения/программы, установленные через WineHelper"
echo " - Все ярлыки из меню и с рабочего стола, созданные с помощью WineHelper"
echo " - Все резервные копии и логи, созданные WineHelper"
echo "======================================================"
if print_confirmation "Продолжить?" ; then
echo "----------------------------------------------"
@@ -1788,6 +1791,7 @@ remove_winehelper () {
# Удаление рабочих каталогов
try_remove_dir "$USER_WORK_PATH"
try_remove_dir "$HOME/winehelper_backup_log"
# Удаление файлов меню
try_remove_dir "$WH_MENU_DIR"
@@ -1866,7 +1870,8 @@ backup_prefix() {
check_prefix_var
local backup_base_dir backup_archive_name backup_dest_path temp_backup_dir temp_prefix_dir temp_users_dir
backup_base_dir="$(xdg-user-dir DESKTOP)"
backup_base_dir="$HOME/winehelper_backup_log"
create_new_dir "$backup_base_dir"
backup_archive_name="backup_${PREFIX_NAME}_$(date +%d.%m.%Y-%H.%M.%S).whpack"
backup_dest_path="$backup_base_dir/$backup_archive_name"
temp_backup_dir="$WH_TMP_DIR/backup_${PREFIX_NAME}_$(date +%d.%m.%Y-%H.%M.%S)"

View File

@@ -1762,6 +1762,7 @@ class WineHelperGUI(QMainWindow):
if show_global:
self.backup_button.setVisible(False)
self.create_log_button.setVisible(False)
self.open_log_dir_button.setVisible(False)
self.uninstall_button.setVisible(False)
self.current_selected_app = None
@@ -1877,6 +1878,12 @@ class WineHelperGUI(QMainWindow):
self.backup_button.clicked.connect(self.backup_prefix_for_app)
installed_global_layout.addWidget(self.backup_button)
self.open_log_dir_button = QPushButton("Открыть папку с логом/резервной копией префикса")
self.open_log_dir_button.setIcon(QIcon.fromTheme("folder-open"))
self.open_log_dir_button.clicked.connect(self.open_log_directory)
self.open_log_dir_button.setVisible(False) # Скрыта по умолчанию
installed_global_layout.addWidget(self.open_log_dir_button)
self.uninstall_button = QPushButton("Удалить префикс")
self.uninstall_button.setIcon(QIcon.fromTheme("user-trash"))
self.uninstall_button.clicked.connect(self.uninstall_app)
@@ -2172,6 +2179,13 @@ class WineHelperGUI(QMainWindow):
self.created_prefix_selector.currentIndexChanged.connect(self.on_created_prefix_selected)
selector_layout.addWidget(self.created_prefix_selector, 1)
self.open_prefix_folder_button = QPushButton()
self.open_prefix_folder_button.setIcon(QIcon.fromTheme("folder-open"))
self.open_prefix_folder_button.setToolTip("Открыть папку префикса в файловом менеджере")
self.open_prefix_folder_button.setEnabled(False)
self.open_prefix_folder_button.clicked.connect(self.open_selected_prefix_folder)
selector_layout.addWidget(self.open_prefix_folder_button)
self.create_base_pfx_button = QPushButton()
self.create_base_pfx_button.setIcon(QIcon.fromTheme("document-export"))
self.create_base_pfx_button.setToolTip("Создать шаблон из выбранного префикса (для опытных пользователей)")
@@ -2316,6 +2330,24 @@ class WineHelperGUI(QMainWindow):
management_layout.setColumnStretch(2, 2)
container_layout.addWidget(self.prefix_management_groupbox)
# --- Кнопка полного удаления ---
# Добавляем разделитель и кнопку в основной контейнер управления
container_layout.addSpacing(15)
self.remove_all_button = QPushButton("Удалить все данные WineHelper")
self.remove_all_button.setStyleSheet("""
QPushButton:!disabled {
background-color: #d32f2f;
color: white;
padding: 5px;
}
""")
self.remove_all_button.setMinimumHeight(32)
self.remove_all_button.setFont(QFont('Arial', 10, QFont.Bold))
self.remove_all_button.setToolTip("ВНИМАНИЕ: Удаляет ВСЕ данные WineHelper, включая все префиксы, настройки и ярлыки.")
self.remove_all_button.clicked.connect(self.remove_all_data)
container_layout.addWidget(self.remove_all_button)
layout.addWidget(self.management_container_groupbox)
layout.addStretch()
self.add_tab(self.prefix_tab, "Менеджер префиксов")
@@ -2357,6 +2389,7 @@ class WineHelperGUI(QMainWindow):
prefix_names = []
self.created_prefix_selector.blockSignals(True)
self.remove_all_button.setEnabled(bool(prefix_names))
self.created_prefix_selector.clear()
if prefix_names:
self.created_prefix_selector.addItems(prefix_names)
@@ -2372,7 +2405,9 @@ class WineHelperGUI(QMainWindow):
self.current_managed_prefix_name = None
self._setup_prefix_management_panel(None)
self.delete_prefix_button.setEnabled(False)
self.remove_all_button.setEnabled(False)
self.create_base_pfx_button.setEnabled(False)
self.open_prefix_folder_button.setEnabled(False)
else:
# Прокручиваем к выбранному элементу, чтобы он был виден в списке
self.created_prefix_selector.view().scrollTo(
@@ -2382,7 +2417,9 @@ class WineHelperGUI(QMainWindow):
self.current_managed_prefix_name = prefix_name
self._setup_prefix_management_panel(prefix_name)
self.delete_prefix_button.setEnabled(True)
self.remove_all_button.setEnabled(True)
self.create_base_pfx_button.setEnabled(True)
self.open_prefix_folder_button.setEnabled(True)
def delete_selected_prefix(self):
"""Удаляет префикс, выбранный в выпадающем списке на вкладке 'Менеджер префиксов'."""
@@ -2491,6 +2528,21 @@ class WineHelperGUI(QMainWindow):
self._run_simple_command("create-base-pfx", [prefix_name])
self.command_dialog.exec_()
def open_selected_prefix_folder(self):
"""Открывает папку выбранного префикса в системном файловом менеджере."""
prefix_name = self.current_managed_prefix_name
if not prefix_name:
return
prefix_path = os.path.join(Var.USER_WORK_PATH, "prefixes", prefix_name)
if os.path.isdir(prefix_path):
try:
subprocess.Popen(['xdg-open', prefix_path])
except Exception as e:
QMessageBox.warning(self, "Ошибка", f"Не удалось открыть директорию:\n{prefix_path}\n\nОшибка: {e}")
else:
QMessageBox.warning(self, "Ошибка", f"Директория префикса не найдена:\n{prefix_path}")
def _setup_prefix_management_panel(self, prefix_name):
"""Настраивает панель управления префиксом на основе текущего состояния."""
is_prefix_selected = bool(prefix_name)
@@ -3378,6 +3430,7 @@ class WineHelperGUI(QMainWindow):
self.installed_global_action_widget.setVisible(True)
self.backup_button.setVisible(True)
self.create_log_button.setVisible(True)
self.update_open_log_dir_button_visibility()
self.uninstall_button.setVisible(True)
self.manual_install_path_widget.setVisible(False)
@@ -3386,6 +3439,27 @@ class WineHelperGUI(QMainWindow):
self.current_selected_app = None
self.info_panel.setVisible(False)
def update_open_log_dir_button_visibility(self):
"""Проверяет наличие лог-файла или бэкапов и обновляет видимость кнопки."""
log_dir_path = os.path.join(os.path.expanduser("~"), "winehelper_backup_log")
is_visible = False
if os.path.isdir(log_dir_path):
# Кнопка должна быть видна, если директория не пуста.
if os.listdir(log_dir_path):
is_visible = True
self.open_log_dir_button.setVisible(is_visible)
def open_log_directory(self):
"""Открывает директорию с лог-файлами."""
log_dir_path = os.path.join(os.path.expanduser("~"), "winehelper_backup_log")
if os.path.isdir(log_dir_path):
try:
subprocess.Popen(['xdg-open', log_dir_path])
except Exception as e:
QMessageBox.warning(self, "Ошибка", f"Не удалось открыть директорию:\n{log_dir_path}\n\nОшибка: {e}")
else:
QMessageBox.information(self, "Информация", f"Директория с логами не найдена:\n{log_dir_path}")
def _get_prefix_name_for_selected_app(self):
"""Извлекает имя префикса для выбранного приложения."""
if not self.current_selected_app or 'desktop_path' not in self.current_selected_app:
@@ -3426,8 +3500,8 @@ class WineHelperGUI(QMainWindow):
msg_box = QMessageBox(self)
msg_box.setWindowTitle("Создание резервной копии")
msg_box.setText(
f"Будет создана резервная копия префикса '{prefix_name}'.\n"
f"Файл будет сохранен на вашем Рабочем столе в формате .whpack.\n\nПродолжить?"
f"Будет создана резервная копия префикса '{prefix_name}'.\n\n"
f"Файл будет сохранен в домашней директории в папке winehelper_backup_log/ в формате .whpack.\n\nПродолжить?"
)
msg_box.addButton(yes_button, QMessageBox.YesRole)
msg_box.addButton(no_button, QMessageBox.NoRole)
@@ -3460,6 +3534,7 @@ class WineHelperGUI(QMainWindow):
self.command_process.setProcessChannelMode(QProcess.MergedChannels)
self.command_process.readyReadStandardOutput.connect(self._handle_command_output)
self.command_process.finished.connect(self._handle_command_finished)
self.command_process.finished.connect(self.update_open_log_dir_button_visibility)
winehelper_path = self.winehelper_path
args = ["backup-prefix", prefix_name]
@@ -3525,9 +3600,9 @@ class WineHelperGUI(QMainWindow):
msg_box = QMessageBox(self)
msg_box.setWindowTitle("Создание лога")
msg_box.setText(
"Приложение будет запущено в режиме отладки.\n"
"После закрытия приложения лог будет сохранен в вашем домашнем каталоге "
"под именем 'winehelper.log'."
"Приложение будет запущено в режиме отладки.\n\n"
"После закрытия приложения лог будет сохранен в папке 'winehelper_backup_log' "
"в вашем домашнем каталоге под именем 'winehelper.log'."
)
msg_box.addButton(yes_button, QMessageBox.YesRole)
msg_box.addButton(no_button, QMessageBox.NoRole)
@@ -3793,6 +3868,7 @@ class WineHelperGUI(QMainWindow):
# и избегания проблем с замыканием в lambda.
process.finished.connect(partial(self._on_app_process_finished, desktop_path))
process.finished.connect(self.update_open_log_dir_button_visibility)
try:
process.start(program, arguments)
@@ -3811,6 +3887,55 @@ class WineHelperGUI(QMainWindow):
QMessageBox.critical(self, "Ошибка",
f"Не удалось обработать команду запуска:\n{command_str}\n\nОшибка: {str(e)}")
def remove_all_data(self):
"""Запускает процесс полного удаления всех данных WineHelper."""
# Первое подтверждение
msg_box1 = QMessageBox(self)
msg_box1.setIcon(QMessageBox.Critical)
msg_box1.setWindowTitle('Подтверждение полного удаления')
msg_box1.setText(
"<h2>ВНИМАНИЕ!</h2>"
"<p>Это действие полностью и безвозвратно удалит <b>ВСЕ</b> данные, связанные с WineHelper, включая:</p>"
"<ul>"
"<li>Все созданные префиксы и установленные в них программы.</li>"
"<li>Все ярлыки в меню и на рабочем столе.</li>"
"<li>Все настройки, кэш и резервные копии.</li>"
"</ul>"
"<p>Продолжить?</p>"
)
msg_box1.setTextFormat(Qt.RichText)
yes_button1 = msg_box1.addButton("Да, я понимаю", QMessageBox.YesRole)
no_button1 = msg_box1.addButton("Отмена", QMessageBox.NoRole)
msg_box1.setDefaultButton(no_button1)
msg_box1.exec_()
if msg_box1.clickedButton() != yes_button1:
return
# Второе, финальное подтверждение
msg_box2 = QMessageBox(self)
msg_box2.setIcon(QMessageBox.Critical)
msg_box2.setWindowTitle('Последнее предупреждение')
msg_box2.setText("<h3>Вы уверены, что хотите удалить ВСЁ?</h3><p>Это действие необратимо.</p>")
msg_box2.setTextFormat(Qt.RichText)
yes_button2 = msg_box2.addButton("Да, удалить всё", QMessageBox.DestructiveRole)
no_button2 = msg_box2.addButton("Нет, я передумал", QMessageBox.RejectRole)
msg_box2.setDefaultButton(no_button2)
msg_box2.exec_()
if msg_box2.clickedButton() != yes_button2:
return
# Запускаем команду и выходим из приложения
try:
# Запускаем команду в фоне и не ждем ее завершения
subprocess.Popen([self.winehelper_path, "remove-all", "--force"])
# Сообщаем пользователю и закрываем GUI
QMessageBox.information(self, "Удаление", "Запущена процедура удаления WineHelper. Приложение будет закрыто.")
self.quit_application()
except Exception as e:
QMessageBox.critical(self, "Ошибка", f"Не удалось запустить команду удаления: {e}")
def quit_application(self):
"""Инициирует процесс выхода из приложения."""
self.is_quitting = True