#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
智能音频处理助手主程序
"""

import sys
import os

try:
    from PyQt5.QtWidgets import (
        QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
        QPushButton, QLabel, QFileDialog, QSlider, QComboBox, 
        QProgressBar, QMessageBox, QTabWidget, QStyle, QFrame, QGroupBox, QToolTip
    )
    from PyQt5.QtCore import Qt, QThread, pyqtSignal, QDir
    from PyQt5.QtGui import QIcon, QFont, QPixmap, QCursor

    # 导入功能模块
    from audio_processor import (
        VolumeEnhancer, SpeechToText, NoiseReducer, 
        VoiceExtractor, AudioRestorer
    )
    from utils import AudioPlayer, FileOperations
    
    # 设置为True表示成功导入所有模块
    ALL_MODULES_IMPORTED = True
except ImportError as e:
    ALL_MODULES_IMPORTED = False
    # 解析错误消息，获取缺失的模块名
    error_msg = str(e)
    if "'" in error_msg:
        missing_module = error_msg.split("'")[1]
    else:
        # 如果错误消息格式不同，尝试别的方式解析
        parts = error_msg.split()
        if len(parts) > 1:
            missing_module = parts[-1]
        else:
            missing_module = "未知模块"
    
    # 忽略PyQt5内部组件
    if missing_module in ['QToolTip', 'QIcon', 'QPixmap', 'QCursor']:
        # 这些通常是PyQt5子模块内部导入问题，尝试继续运行
        try:
            # 再次尝试导入核心模块
            from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout
            from audio_processor import VolumeEnhancer, SpeechToText, NoiseReducer, VoiceExtractor, AudioRestorer
            from utils import AudioPlayer, FileOperations
            
            ALL_MODULES_IMPORTED = True
        except ImportError:
            ALL_MODULES_IMPORTED = False
    
    def show_error_message():
        """显示错误信息并提供解决方案"""
        error_message = f"""
缺少必要的依赖模块: {missing_module}

请按照以下步骤安装所需依赖:

1. 打开命令提示符或PowerShell
2. 输入以下命令安装依赖:
   pip install -r requirements.txt
   
或者运行 setup_and_run.bat 脚本自动配置环境。

如果仍然遇到问题，可以尝试手动安装单个依赖:
pip install {missing_module}

程序即将退出。
"""
        print(error_message)
        
        try:
            # 尝试使用tkinter显示图形化错误消息
            import tkinter as tk
            from tkinter import messagebox
            
            root = tk.Tk()
            root.withdraw()
            messagebox.showerror("缺少依赖", error_message)
            root.destroy()
        except:
            # 如果tkinter不可用，只使用控制台输出
            pass

# 如果所有模块都成功导入，继续定义类
if ALL_MODULES_IMPORTED:
    class ProcessingThread(QThread):
        """处理音频的后台线程"""
        progress_updated = pyqtSignal(int)
        processing_finished = pyqtSignal(str)
        processing_error = pyqtSignal(str)
        
        def __init__(self, processor, input_file, output_file, params=None):
            super().__init__()
            self.processor = processor
            self.input_file = input_file
            self.output_file = output_file
            self.params = params or {}
            
        def run(self):
            try:
                self.processor.process(
                    self.input_file, 
                    self.output_file, 
                    self.params,
                    progress_callback=self.progress_updated.emit
                )
                self.processing_finished.emit(self.output_file)
            except Exception as e:
                self.processing_error.emit(str(e))

    class MainWindow(QMainWindow):
        """主窗口类"""
        
        def __init__(self):
            super().__init__()
            self.init_ui()
            self.input_file = None
            self.output_file = None
            self.processing_thread = None
            self.is_slider_being_dragged = False
            
            # 初始化处理器
            self.volume_enhancer = VolumeEnhancer()
            self.speech_to_text = SpeechToText()
            self.noise_reducer = NoiseReducer()
            self.voice_extractor = VoiceExtractor()
            self.audio_restorer = AudioRestorer()
            
            # 初始化音频播放器
            self.audio_player = AudioPlayer()
            
            # 初始化文件操作工具
            self.file_ops = FileOperations()
            
        def init_ui(self):
            """初始化UI界面"""
            self.setWindowTitle('智能音频处理助手')
            self.setMinimumSize(800, 600)
            
            # 主布局
            main_widget = QWidget()
            self.setCentralWidget(main_widget)
            main_layout = QVBoxLayout(main_widget)
            
            # 文件选择区域
            file_group = QGroupBox("音频文件")
            file_layout = QHBoxLayout()
            
            self.file_path_label = QLabel("未选择文件")
            self.file_path_label.setStyleSheet("background-color: #f0f0f0; padding: 5px;")
            
            self.browse_button = QPushButton("浏览...")
            self.browse_button.clicked.connect(self.browse_file)
            
            file_layout.addWidget(self.file_path_label, 3)
            file_layout.addWidget(self.browse_button, 1)
            file_group.setLayout(file_layout)
            main_layout.addWidget(file_group)
            
            # 功能选项卡
            tabs = QTabWidget()
            tabs.addTab(self.create_volume_tab(), "音量增强")
            tabs.addTab(self.create_speech_to_text_tab(), "语音转文字")
            tabs.addTab(self.create_noise_reduction_tab(), "音频降噪")
            tabs.addTab(self.create_voice_extraction_tab(), "人声提取")
            tabs.addTab(self.create_audio_restoration_tab(), "音频修复")
            main_layout.addWidget(tabs)
            
            # 进度条
            progress_layout = QHBoxLayout()
            self.progress_bar = QProgressBar()
            self.progress_bar.setRange(0, 100)
            self.progress_bar.setValue(0)
            self.status_label = QLabel("就绪")
            
            progress_layout.addWidget(QLabel("进度:"))
            progress_layout.addWidget(self.progress_bar)
            progress_layout.addWidget(self.status_label)
            main_layout.addLayout(progress_layout)
            
            # 播放控制区域
            player_group = QGroupBox("音频播放")
            player_layout = QVBoxLayout()  # 改为垂直布局
            
            # 播放按钮区域
            buttons_layout = QHBoxLayout()
            
            self.play_original_button = QPushButton("播放原始音频")
            self.play_original_button.clicked.connect(self.play_original)
            self.play_original_button.setEnabled(False)
            
            self.play_processed_button = QPushButton("播放处理后音频")
            self.play_processed_button.clicked.connect(self.play_processed)
            self.play_processed_button.setEnabled(False)
            
            self.stop_button = QPushButton("停止播放")
            self.stop_button.clicked.connect(self.stop_playback)
            self.stop_button.setEnabled(False)
            
            buttons_layout.addWidget(self.play_original_button)
            buttons_layout.addWidget(self.play_processed_button)
            buttons_layout.addWidget(self.stop_button)
            player_layout.addLayout(buttons_layout)
            
            # 添加播放进度条
            playback_layout = QHBoxLayout()
            self.time_label = QLabel("00:00 / 00:00")
            self.time_label.setMinimumWidth(100)  # 固定宽度避免布局跳动
            
            self.playback_slider = QSlider(Qt.Horizontal)
            self.playback_slider.setRange(0, 100)  # 使用0-100范围，对应百分比
            self.playback_slider.setValue(0)
            self.playback_slider.setEnabled(False)
            self.playback_slider.setStyleSheet("""
                QSlider::groove:horizontal {
                    height: 8px;
                    background: #d0d0d0;
                    border-radius: 4px;
                }
                
                QSlider::handle:horizontal {
                    background: #4a86e8;
                    border: 2px solid #4a86e8;
                    width: 16px;
                    height: 16px;
                    margin: -4px 0;
                    border-radius: 8px;
                }
                
                QSlider::sub-page:horizontal {
                    background: #4a86e8;
                    border-radius: 4px;
                }
            """)
            # 当用户拖动进度条时跳转
            self.playback_slider.sliderPressed.connect(self.on_slider_pressed)
            self.playback_slider.sliderReleased.connect(self.on_slider_released)
            # 添加鼠标跟踪，显示时间点提示
            self.playback_slider.setMouseTracking(True)
            self.playback_slider.mouseMoveEvent = self.slider_mouse_move
            
            playback_layout.addWidget(QLabel("进度:"))
            playback_layout.addWidget(self.playback_slider, 1)  # 让滑块占据更多空间
            playback_layout.addWidget(self.time_label)
            player_layout.addLayout(playback_layout)
            
            player_group.setLayout(player_layout)
            main_layout.addWidget(player_group)
            
            # 底部操作按钮
            bottom_layout = QHBoxLayout()
            
            self.save_button = QPushButton("保存结果")
            self.save_button.clicked.connect(self.save_result)
            self.save_button.setEnabled(False)
            
            self.exit_button = QPushButton("退出")
            self.exit_button.clicked.connect(self.close)
            
            bottom_layout.addWidget(self.save_button)
            bottom_layout.addStretch()
            bottom_layout.addWidget(self.exit_button)
            main_layout.addLayout(bottom_layout)
            
            # 设置样式
            self.setStyleSheet("""
                QMainWindow {
                    background-color: #f5f5f5;
                }
                QGroupBox {
                    font-weight: bold;
                    border: 1px solid #cccccc;
                    border-radius: 5px;
                    margin-top: 10px;
                    padding-top: 10px;
                }
                QGroupBox::title {
                    subcontrol-origin: margin;
                    subcontrol-position: top center;
                    padding: 0 5px;
                }
                QPushButton {
                    background-color: #4a86e8;
                    color: white;
                    padding: 5px 10px;
                    border-radius: 3px;
                    font-weight: bold;
                }
                QPushButton:hover {
                    background-color: #3a76d8;
                }
                QPushButton:disabled {
                    background-color: #cccccc;
                }
                QLabel {
                    font-size: 10pt;
                }
                QProgressBar {
                    border: 1px solid #cccccc;
                    border-radius: 3px;
                    text-align: center;
                }
                QProgressBar::chunk {
                    background-color: #4a86e8;
                }
            """)
            
        def create_volume_tab(self):
            """创建音量增强选项卡"""
            tab = QWidget()
            layout = QVBoxLayout(tab)
            
            # 参数设置
            param_layout = QHBoxLayout()
            param_layout.addWidget(QLabel("增益值:"))
            
            self.gain_slider = QSlider(Qt.Horizontal)
            self.gain_slider.setRange(100, 300)
            self.gain_slider.setValue(150)
            self.gain_slider.setTickPosition(QSlider.TicksBelow)
            self.gain_slider.setTickInterval(50)
            
            self.gain_label = QLabel("1.5")
            self.gain_slider.valueChanged.connect(
                lambda v: self.gain_label.setText(str(v/100))
            )
            
            param_layout.addWidget(self.gain_slider)
            param_layout.addWidget(self.gain_label)
            layout.addLayout(param_layout)
            
            # 处理按钮
            self.enhance_button = QPushButton("增强音量")
            self.enhance_button.clicked.connect(self.enhance_volume)
            self.enhance_button.setEnabled(False)
            
            layout.addWidget(self.enhance_button)
            layout.addStretch()
            
            return tab
        
        def create_speech_to_text_tab(self):
            """创建语音转文字选项卡"""
            tab = QWidget()
            layout = QVBoxLayout(tab)
            
            # 参数设置
            param_layout = QHBoxLayout()
            param_layout.addWidget(QLabel("语言:"))
            
            self.language_combo = QComboBox()
            self.language_combo.addItems(["中文", "英语", "自动检测"])
            
            param_layout.addWidget(self.language_combo)
            layout.addLayout(param_layout)
            
            # 处理按钮
            self.transcribe_button = QPushButton("转换为文本")
            self.transcribe_button.clicked.connect(self.transcribe_audio)
            self.transcribe_button.setEnabled(False)
            
            layout.addWidget(self.transcribe_button)
            layout.addStretch()
            
            return tab
        
        def create_noise_reduction_tab(self):
            """创建音频降噪选项卡"""
            tab = QWidget()
            layout = QVBoxLayout(tab)
            
            # 参数设置
            param_layout = QHBoxLayout()
            param_layout.addWidget(QLabel("降噪强度:"))
            
            self.noise_reduction_combo = QComboBox()
            self.noise_reduction_combo.addItems(["低", "中", "高"])
            self.noise_reduction_combo.setCurrentIndex(1)
            
            param_layout.addWidget(self.noise_reduction_combo)
            layout.addLayout(param_layout)
            
            # 处理按钮
            self.reduce_noise_button = QPushButton("降噪处理")
            self.reduce_noise_button.clicked.connect(self.reduce_noise)
            self.reduce_noise_button.setEnabled(False)
            
            layout.addWidget(self.reduce_noise_button)
            layout.addStretch()
            
            return tab
        
        def create_voice_extraction_tab(self):
            """创建人声提取选项卡"""
            tab = QWidget()
            layout = QVBoxLayout(tab)
            
            # 参数设置
            param_layout = QHBoxLayout()
            param_layout.addWidget(QLabel("分离程度:"))
            
            self.extraction_slider = QSlider(Qt.Horizontal)
            self.extraction_slider.setRange(1, 5)
            self.extraction_slider.setValue(3)
            self.extraction_slider.setTickPosition(QSlider.TicksBelow)
            self.extraction_slider.setTickInterval(1)
            
            self.extraction_label = QLabel("3")
            self.extraction_slider.valueChanged.connect(
                lambda v: self.extraction_label.setText(str(v))
            )
            
            param_layout.addWidget(self.extraction_slider)
            param_layout.addWidget(self.extraction_label)
            layout.addLayout(param_layout)
            
            # 处理按钮
            self.extract_voice_button = QPushButton("提取人声")
            self.extract_voice_button.clicked.connect(self.extract_voice)
            self.extract_voice_button.setEnabled(False)
            
            layout.addWidget(self.extract_voice_button)
            layout.addStretch()
            
            return tab
        
        def create_audio_restoration_tab(self):
            """创建音频修复选项卡"""
            tab = QWidget()
            layout = QVBoxLayout(tab)
            
            # 参数设置
            param_layout = QHBoxLayout()
            param_layout.addWidget(QLabel("修复强度:"))
            
            self.restoration_combo = QComboBox()
            self.restoration_combo.addItems(["轻度", "中度", "深度"])
            self.restoration_combo.setCurrentIndex(1)
            
            param_layout.addWidget(self.restoration_combo)
            layout.addLayout(param_layout)
            
            # 处理按钮
            self.restore_audio_button = QPushButton("修复音频")
            self.restore_audio_button.clicked.connect(self.restore_audio)
            self.restore_audio_button.setEnabled(False)
            
            layout.addWidget(self.restore_audio_button)
            layout.addStretch()
            
            return tab
        
        def browse_file(self):
            """选择输入音频文件"""
            file_path, _ = QFileDialog.getOpenFileName(
                self, "选择音频文件", "", 
                "音频文件 (*.wav *.mp3 *.flac *.ogg);;所有文件 (*)"
            )
            
            if file_path:
                self.input_file = file_path
                self.file_path_label.setText(os.path.basename(file_path))
                
                self.enable_processing_buttons(True)
                self.play_original_button.setEnabled(True)
                self.play_processed_button.setEnabled(False)
                self.save_button.setEnabled(False)
                
                self.status_label.setText("已加载音频文件")
        
        def enable_processing_buttons(self, enabled=True):
            """启用或禁用处理按钮"""
            self.enhance_button.setEnabled(enabled)
            self.transcribe_button.setEnabled(enabled)
            self.reduce_noise_button.setEnabled(enabled)
            self.extract_voice_button.setEnabled(enabled)
            self.restore_audio_button.setEnabled(enabled)
        
        def play_original(self):
            """播放原始音频"""
            try:
                if not self.input_file or not os.path.exists(self.input_file):
                    self.show_message("错误", "没有选择音频文件或文件不存在")
                    return
                
                # 如果当前正在播放同一个文件，则停止播放
                if self.audio_player.is_playing_file(self.input_file):
                    self.stop_playback()
                    return
                
                # 停止任何正在播放的内容
                self.audio_player.stop()
                
                # 重置播放进度条
                self.playback_slider.setValue(0)
                self.playback_slider.setEnabled(True)  # 启用进度条
                self.time_label.setText("00:00 / 00:00")
                
                # 更新UI状态
                self.play_original_button.setEnabled(False)
                self.play_processed_button.setEnabled(False)
                self.stop_button.setEnabled(True)
                
                # 开始播放
                self.audio_player.play(self.input_file, self.update_playback_progress)
                
            except Exception as e:
                print(f"播放原始音频时出错: {str(e)}")
                self.show_message("播放错误", f"无法播放音频: {str(e)}")
        
        def play_processed(self):
            """播放处理后的音频"""
            try:
                if not self.output_file or not os.path.exists(self.output_file):
                    self.show_message("错误", "没有处理结果或结果文件不存在")
                    return
                
                # 如果当前正在播放同一个文件，则停止播放
                if self.audio_player.is_playing_file(self.output_file):
                    self.stop_playback()
                    return
                
                # 停止任何正在播放的内容
                self.audio_player.stop()
                
                # 重置播放进度条
                self.playback_slider.setValue(0)
                self.playback_slider.setEnabled(True)  # 启用进度条
                self.time_label.setText("00:00 / 00:00")
                
                # 更新UI状态
                self.play_original_button.setEnabled(False)
                self.play_processed_button.setEnabled(False)
                self.stop_button.setEnabled(True)
                
                # 开始播放
                self.audio_player.play(self.output_file, self.update_playback_progress)
                
            except Exception as e:
                print(f"播放处理后音频时出错: {str(e)}")
                self.show_message("播放错误", f"无法播放音频: {str(e)}")
        
        def stop_playback(self):
            """停止音频播放"""
            try:
                # 停止播放
                if self.audio_player.playing:
                    self.audio_player.stop()
                
                # 更新UI状态
                self.play_original_button.setEnabled(True)
                self.play_processed_button.setEnabled(self.output_file is not None and os.path.exists(self.output_file))
                self.stop_button.setEnabled(False)
                
                # 重置进度条
                self.playback_slider.setValue(0)
                self.playback_slider.setEnabled(False)
                self.time_label.setText("00:00 / 00:00")
                
            except Exception as e:
                print(f"停止播放时出错: {str(e)}")
        
        def update_playback_progress(self, percent):
            """
            更新播放进度条
            
            Args:
                percent: 播放进度百分比(0-100)
            """
            try:
                # 设置进度条值（现在范围已经是0-100，不需要转换）
                if not self.is_slider_being_dragged:
                    self.playback_slider.setValue(int(percent))
                
                # 更新时间标签
                duration = self.audio_player.get_duration()
                position = self.audio_player.get_position()
                
                time_text = f"{self.format_time(position)} / {self.format_time(duration)}"
                self.time_label.setText(time_text)
                
                # 检查播放状态
                if percent >= 99.5 or not self.audio_player.playing:
                    if not self.audio_player.playing:
                        # 播放完成，重置UI状态
                        self.play_original_button.setEnabled(True)
                        self.play_processed_button.setEnabled(self.output_file is not None and os.path.exists(self.output_file))
                        self.stop_button.setEnabled(False)
            except Exception as e:
                print(f"更新播放进度时出错: {str(e)}")
        
        def on_slider_pressed(self):
            """用户按下进度条时的处理"""
            self.is_slider_being_dragged = True
        
        def on_slider_released(self):
            """用户释放进度条时的处理"""
            try:
                if self.audio_player.playing:
                    # 获取新的位置百分比 (slider值范围是0-100)
                    percent = self.playback_slider.value()
                    
                    print(f"用户拖动进度条到: {percent}%")
                    
                    # 跳转到新位置
                    result = self.audio_player.seek(percent)
                    if not result:
                        print("跳转失败，重置进度条")
                        # 如果跳转失败，重置进度条到当前播放位置
                        current_percent = self.audio_player.get_position_percent()
                        self.playback_slider.setValue(int(current_percent))
                
                self.is_slider_being_dragged = False
            except Exception as e:
                print(f"处理进度条释放事件时出错: {str(e)}")
                self.is_slider_being_dragged = False
        
        def slider_mouse_move(self, event):
            """处理鼠标在滑块上移动的事件，显示时间点提示"""
            if self.audio_player.playing and self.audio_player.get_duration() > 0:
                # 计算鼠标位置对应的时间点
                width = self.playback_slider.width()
                x = event.x()
                if width > 0:
                    fraction = max(0, min(1, x / width))
                    time_point = fraction * self.audio_player.get_duration()
                    time_str = self.format_time(time_point)
                    
                    # 设置工具提示
                    pos = self.playback_slider.mapToGlobal(event.pos())
                    QToolTip.showText(
                        pos,
                        f"跳转到: {time_str}",
                        self.playback_slider
                    )
            # 传递给原始事件处理
            QSlider.mouseMoveEvent(self.playback_slider, event)
        
        def format_time(self, seconds):
            """将秒数格式化为 MM:SS 格式"""
            minutes = int(seconds // 60)
            secs = int(seconds % 60)
            return f"{minutes:02d}:{secs:02d}"
        
        def save_result(self):
            """保存处理结果"""
            if not self.output_file:
                return
                
            output_dir = QFileDialog.getExistingDirectory(
                self, "选择保存目录", QDir.homePath()
            )
            
            if output_dir:
                try:
                    new_file = os.path.join(
                        output_dir, 
                        os.path.basename(self.output_file)
                    )
                    self.file_ops.copy_file(self.output_file, new_file)
                    QMessageBox.information(
                        self, "保存成功", 
                        f"文件已保存至:\n{new_file}"
                    )
                except Exception as e:
                    QMessageBox.critical(
                        self, "保存失败", 
                        f"保存文件时出错:\n{str(e)}"
                    )
        
        def on_processing_start(self):
            """处理开始时的操作"""
            self.progress_bar.setValue(0)
            self.status_label.setText("正在处理...")
            self.enable_processing_buttons(False)
            self.play_original_button.setEnabled(False)
            self.play_processed_button.setEnabled(False)
            self.save_button.setEnabled(False)
        
        def on_progress_update(self, value):
            """更新进度条"""
            self.progress_bar.setValue(value)
        
        def on_processing_finished(self, output_file):
            """处理完成时的操作"""
            self.output_file = output_file
            self.status_label.setText("处理完成")
            self.progress_bar.setValue(100)
            
            self.enable_processing_buttons(True)
            self.play_original_button.setEnabled(True)
            self.play_processed_button.setEnabled(True)
            self.save_button.setEnabled(True)
        
        def on_processing_error(self, error_msg):
            """处理出错时的操作"""
            self.status_label.setText("处理失败")
            self.progress_bar.setValue(0)
            self.enable_processing_buttons(True)
            self.play_original_button.setEnabled(True)
            
            QMessageBox.critical(
                self, "处理失败", 
                f"处理音频时出错:\n{error_msg}"
            )
        
        def get_output_file(self, suffix):
            """生成输出文件路径"""
            if not self.input_file:
                return None
                
            filename, ext = os.path.splitext(os.path.basename(self.input_file))
            return os.path.join(
                os.path.dirname(self.input_file),
                f"{filename}_{suffix}{ext}"
            )
        
        def enhance_volume(self):
            """执行音量增强"""
            if not self.input_file:
                return
                
            self.on_processing_start()
            gain = self.gain_slider.value() / 100
            
            output_file = self.get_output_file("enhanced")
            self.processing_thread = ProcessingThread(
                self.volume_enhancer,
                self.input_file,
                output_file,
                {"gain": gain}
            )
            
            self.processing_thread.progress_updated.connect(self.on_progress_update)
            self.processing_thread.processing_finished.connect(self.on_processing_finished)
            self.processing_thread.processing_error.connect(self.on_processing_error)
            
            self.processing_thread.start()
        
        def transcribe_audio(self):
            """执行语音转文字"""
            if not self.input_file:
                return
                
            self.on_processing_start()
            language = self.language_combo.currentText()
            
            output_file = self.get_output_file("transcript").replace(
                os.path.splitext(self.input_file)[1], 
                ".txt"
            )
            
            self.processing_thread = ProcessingThread(
                self.speech_to_text,
                self.input_file,
                output_file,
                {"language": language}
            )
            
            self.processing_thread.progress_updated.connect(self.on_progress_update)
            self.processing_thread.processing_finished.connect(self.on_processing_finished)
            self.processing_thread.processing_error.connect(self.on_processing_error)
            
            self.processing_thread.start()
        
        def reduce_noise(self):
            """执行音频降噪"""
            if not self.input_file:
                return
                
            self.on_processing_start()
            strength = self.noise_reduction_combo.currentText()
            
            output_file = self.get_output_file("denoise")
            self.processing_thread = ProcessingThread(
                self.noise_reducer,
                self.input_file,
                output_file,
                {"strength": strength}
            )
            
            self.processing_thread.progress_updated.connect(self.on_progress_update)
            self.processing_thread.processing_finished.connect(self.on_processing_finished)
            self.processing_thread.processing_error.connect(self.on_processing_error)
            
            self.processing_thread.start()
        
        def extract_voice(self):
            """执行人声提取"""
            if not self.input_file:
                return
                
            self.on_processing_start()
            level = self.extraction_slider.value()
            
            output_file = self.get_output_file("vocals")
            self.processing_thread = ProcessingThread(
                self.voice_extractor,
                self.input_file,
                output_file,
                {"level": level}
            )
            
            self.processing_thread.progress_updated.connect(self.on_progress_update)
            self.processing_thread.processing_finished.connect(self.on_processing_finished)
            self.processing_thread.processing_error.connect(self.on_processing_error)
            
            self.processing_thread.start()
        
        def restore_audio(self):
            """执行音频修复"""
            if not self.input_file:
                return
                
            self.on_processing_start()
            intensity = self.restoration_combo.currentText()
            
            output_file = self.get_output_file("restored")
            self.processing_thread = ProcessingThread(
                self.audio_restorer,
                self.input_file,
                output_file,
                {"intensity": intensity}
            )
            
            self.processing_thread.progress_updated.connect(self.on_progress_update)
            self.processing_thread.processing_finished.connect(self.on_processing_finished)
            self.processing_thread.processing_error.connect(self.on_processing_error)
            
            self.processing_thread.start()

        def show_message(self, title, message):
            """显示消息框
            
            Args:
                title: 消息框标题
                message: 消息内容
            """
            QMessageBox.information(self, title, message)

    def main():
        """程序入口点"""
        app = QApplication(sys.argv)
        window = MainWindow()
        window.show()
        sys.exit(app.exec_())
else:
    # 如果导入模块失败，显示错误消息
    def main():
        show_error_message()
        sys.exit(1)

if __name__ == "__main__":
    main() 