diff --git a/auto_completion/bash_completion/winehelper b/auto_completion/bash_completion/winehelper index e27bf5b..a0a9a84 100644 --- a/auto_completion/bash_completion/winehelper +++ b/auto_completion/bash_completion/winehelper @@ -4,7 +4,7 @@ _winehelper_completions() { COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" - opts="--help --version --debug install installed install-dxvk install-vkd3d -r -i remove-all --clear-pfx killall remove-prefix backup-prefix restore-prefix create-prefix --changelog changelog change-wine" + opts="--help --version --debug install installed install-dxvk install-vkd3d -r -i remove-all --clear-pfx killall remove-prefix backup-prefix restore-prefix create-prefix --changelog changelog change-wine clear-winetricks-cache" wine_cmd="winecfg winereg winefile wineconsole winetricks desktop regedit explorer cmd run" case "${prev}" in diff --git a/auto_completion/zsh_completion/_winehelper b/auto_completion/zsh_completion/_winehelper index 41a49df..9550545 100644 --- a/auto_completion/zsh_completion/_winehelper +++ b/auto_completion/zsh_completion/_winehelper @@ -21,6 +21,7 @@ _winehelper() { 'backup-prefix[Создать резерную копию префикса]' 'restore-prefix[восстановить префикс из резервной копии "путь/до/whpack"]' 'change-wine[Изменить версию Wine/Proton для префикса]' + 'clear-winetricks-cache[Очистить кэш Winetricks]' ) wine_cmd=( diff --git a/winehelper b/winehelper index e67dbd4..a53220f 100755 --- a/winehelper +++ b/winehelper @@ -2293,6 +2293,30 @@ run_change_wine_version() { print_ok "Версия Wine для префикса $PREFIX_NAME успешно изменена на $WH_WINE_USE." } +clear_winetricks_cache() { + local winetricks_cache_dir="$HOME/.cache/winetricks" + local winehelper_wt_cache_dir="$HOME/.cache/winehelper/winetricks" + + if [[ ! -d "$winetricks_cache_dir" ]] && [[ ! -d "$winehelper_wt_cache_dir" ]]; then + print_info "Кэш Winetricks не найден. Очистка не требуется." + return 0 + fi + + if [[ ! $1 =~ --force|-y ]] ; then + print_warning "Вы собираетесь очистить кэш Winetricks." + echo "Будут удалены все скачанные установщики Winetricks и списки компонентов." + if ! print_confirmation "Продолжить?" + then + print_info "Операция отменена." + exit 1 + fi + fi + print_info "Очистка кэша Winetricks..." + try_remove_dir "$winetricks_cache_dir" + try_remove_dir "$winehelper_wt_cache_dir" + print_ok "Кэш Winetricks успешно очищен." +} + wh_info () { echo "Использование: $SCRIPT_NAME [команда] @@ -2312,6 +2336,7 @@ wh_info () { remove-prefix [имя_префикса] удалить префикс и все связанные данные backup-prefix [имя_префикса] создать резервную копию префикса restore-prefix \"путь/до/whpack\" восстановить префикс из резервной копии + clear-winetricks-cache очистить кэш Winetricks Параметры: --help показать эту справку и выйти @@ -2370,6 +2395,7 @@ case "$arg1" in remove-prefix) remove_prefix "$@" ;; create-base-pfx) create_base_pfx "$@" ;; init-prefix) prepair_wine ; wait_wineserver ;; + clear-winetricks-cache) clear_winetricks_cache "$@" ;; *) if [[ -f "$arg1" ]] ; then WIN_FILE_EXEC="$(readlink -f "$arg1")" diff --git a/winehelper_gui.py b/winehelper_gui.py index 3441a1d..5d5b7d9 100644 --- a/winehelper_gui.py +++ b/winehelper_gui.py @@ -446,6 +446,7 @@ class WinetricksManagerDialog(QDialog): self.previous_tab_widget = None self.cache_dir = os.path.join(os.path.expanduser("~"), ".cache", "winehelper", "winetricks") os.makedirs(self.cache_dir, exist_ok=True) + self.is_reloading_after_cache_clear = False self.setWindowTitle(f"Менеджер компонентов для префикса: {os.path.basename(prefix_path)}") self.setMinimumSize(800, 500) @@ -478,8 +479,14 @@ class WinetricksManagerDialog(QDialog): self.log_output.setText(self.INFO_TEXT) main_layout.addWidget(self.log_output) - # Кнопки управления, выровненные по правому краю + # Кнопки управления button_layout = QHBoxLayout() + + self.clear_cache_button = QPushButton("Очистить кеш") + self.clear_cache_button.setStyleSheet("background-color: red; color: white;") + self.clear_cache_button.clicked.connect(self.clear_winetricks_cache) + button_layout.addWidget(self.clear_cache_button) + button_layout.addStretch(1) self.apply_button = QPushButton("Применить") @@ -736,9 +743,18 @@ class WinetricksManagerDialog(QDialog): self._log(output) self._log("--------------------------------------------------") + # Проверяем, были ли ошибки во время загрузки какой-либо из категорий + has_errors = any(status == 'error' for status in self.category_statuses.values()) + self.loading_count -= 1 if self.loading_count == 0: self._update_ui_state() + if self.is_reloading_after_cache_clear: + if has_errors: + self._log("\n=== Ошибка при обновлении списков. Проверьте лог выше. ===", "red") + else: + self._log("\n=== Списки успешно обновлены ===") + self.is_reloading_after_cache_clear = False # Сбрасываем флаг def _on_item_changed(self, item): """Обрабатывает изменение состояния чекбокса, предотвращая снятие галочки с установленных.""" @@ -895,6 +911,64 @@ class WinetricksManagerDialog(QDialog): self.installation_complete.emit() self.installation_finished = True + def clear_winetricks_cache(self): + """Запускает очистку кэша Winetricks.""" + reply = self._show_message_box( + "Очистка кэша Winetricks", + "Вы собираетесь удалить все скачанные установщики и списки компонентов Winetricks.\n\n" + "Это действие может потребоваться, если у вас возникают проблемы со скачиванием или установкой компонентов.\n\n" + "Продолжить?", + QMessageBox.Question, + {"buttons": {"Да": QMessageBox.YesRole, "Нет": QMessageBox.NoRole}, "default": "Нет"} + ) + + if reply != "Да": + return + + # Блокируем UI на время выполнения + self.tabs.setEnabled(False) + self.clear_cache_button.setEnabled(False) + self.apply_button.setEnabled(False) + self.reinstall_button.setEnabled(False) + self.close_button.setEnabled(False) + + self.log_output.clear() + + self.cache_clear_process = QProcess(self) + self.cache_clear_process.setProcessChannelMode(QProcess.MergedChannels) + + def handle_output(): + output = self.cache_clear_process.readAll().data().decode('utf-8', 'ignore').strip() + if output: + self._log(output) + + def handle_finish(exit_code, exit_status): + if exit_code == 0: + self.is_reloading_after_cache_clear = True # Устанавливаем флаг перед перезагрузкой + self.category_statuses.clear() # Очищаем статусы перед новой загрузкой + # Воссоздаем директорию кэша, так как скрипт ее полностью удалил + os.makedirs(self.cache_dir, exist_ok=True) + self._log("Обновление списков...") + self.initial_states.clear() + self.load_all_categories() + else: + self._log(f"\n=== Ошибка (код: {exit_code}) ===", "red") + + # Восстанавливаем UI + self.tabs.setEnabled(True) + self.clear_cache_button.setEnabled(True) + self.close_button.setEnabled(True) + self._update_ui_state() # Обновляем состояние кнопок Применить/Переустановить + + self.cache_clear_process.readyRead.connect(handle_output) + self.cache_clear_process.finished.connect(handle_finish) + + winehelper_path = self.parent().winehelper_path if hasattr(self.parent(), 'winehelper_path') else Var.RUN_SCRIPT + args = ["clear-winetricks-cache", "--force"] + + self._log(f"Выполнение: {shlex.quote(winehelper_path)} {' '.join(args)}\n") + self.cache_clear_process.start(winehelper_path, args) + def closeEvent(self, event): """Обрабатывает закрытие окна, чтобы предотвратить выход во время установки.""" # Проверяем, запущен ли процесс установки/переустановки @@ -938,6 +1012,8 @@ class WinetricksManagerDialog(QDialog): """Добавляет сообщение в лог с возможностью указания цвета.""" if color: self.log_output.append(f'{message}') + # Сбрасываем формат, чтобы следующий текст не наследовал цвет + self.log_output.setCurrentCharFormat(QTextCharFormat()) else: self.log_output.append(message) self.log_output.moveCursor(QTextCursor.End)