1227 lines
41 KiB
Python
1227 lines
41 KiB
Python
"""
|
||
语音编辑器模块
|
||
提供可视化界面用于配置和测试语音控制功能
|
||
"""
|
||
|
||
import time
|
||
from typing import Dict, Any, List, Optional
|
||
import threading
|
||
|
||
class EditorMode:
|
||
"""编辑器模式枚举"""
|
||
CONFIGURATION = "configuration"
|
||
COMMAND_MAPPING = "command_mapping"
|
||
VOICE_TRAINING = "voice_training"
|
||
TESTING = "testing"
|
||
MONITORING = "monitoring"
|
||
PRESETS = "presets"
|
||
|
||
class VoiceEditor:
|
||
"""
|
||
语音编辑器
|
||
提供可视化界面用于配置和测试语音控制功能
|
||
"""
|
||
|
||
def __init__(self, plugin):
|
||
"""
|
||
初始化语音编辑器
|
||
|
||
Args:
|
||
plugin: 语音控制插件实例
|
||
"""
|
||
self.plugin = plugin
|
||
self.enabled = False
|
||
self.initialized = False
|
||
|
||
# 编辑器配置
|
||
self.editor_config = {
|
||
"window_width": 1024,
|
||
"window_height": 768,
|
||
"refresh_rate": 30.0,
|
||
"enable_preview": True,
|
||
"enable_realtime_update": True,
|
||
"show_debug_info": False,
|
||
"theme": "dark"
|
||
}
|
||
|
||
# 当前编辑器状态
|
||
self.editor_state = {
|
||
"current_mode": EditorMode.CONFIGURATION,
|
||
"selected_tab": "general",
|
||
"is_recording": False,
|
||
"is_testing": False,
|
||
"preview_active": False,
|
||
"monitoring_active": True
|
||
}
|
||
|
||
# UI组件
|
||
self.ui_components = {
|
||
"main_window": None,
|
||
"toolbar": None,
|
||
"property_panel": None,
|
||
"preview_panel": None,
|
||
"status_bar": None,
|
||
"config_view": None,
|
||
"command_view": None,
|
||
"training_view": None,
|
||
"test_view": None,
|
||
"monitor_view": None,
|
||
"preset_view": None
|
||
}
|
||
|
||
# 编辑器数据
|
||
self.editor_data = {
|
||
"config_cache": {},
|
||
"command_cache": {},
|
||
"preset_cache": {},
|
||
"live_data": {},
|
||
"test_history": []
|
||
}
|
||
|
||
# 编辑器操作历史
|
||
self.operation_history = []
|
||
self.history_pointer = -1
|
||
self.max_history_size = 100
|
||
|
||
# 实时监控数据
|
||
self.monitor_data = {
|
||
"audio_levels": [],
|
||
"recognition_results": [],
|
||
"synthesis_events": [],
|
||
"command_executions": [],
|
||
"performance_metrics": {}
|
||
}
|
||
|
||
# 测试数据
|
||
self.test_data = {
|
||
"test_cases": [],
|
||
"test_results": [],
|
||
"current_test": None
|
||
}
|
||
|
||
# 回调函数
|
||
self.editor_callbacks = {
|
||
"mode_changed": [],
|
||
"tab_changed": [],
|
||
"data_updated": [],
|
||
"test_started": [],
|
||
"test_completed": [],
|
||
"recording_started": [],
|
||
"recording_stopped": []
|
||
}
|
||
|
||
# 统计信息
|
||
self.editor_stats = {
|
||
"windows_opened": 0,
|
||
"operations_performed": 0,
|
||
"undo_operations": 0,
|
||
"redo_operations": 0,
|
||
"data_refreshed": 0,
|
||
"preview_updates": 0,
|
||
"tests_run": 0
|
||
}
|
||
|
||
# 线程管理
|
||
self.editor_thread = None
|
||
self.monitor_thread = None
|
||
self.running = False
|
||
|
||
# 时间戳记录
|
||
self.last_refresh_time = 0.0
|
||
self.last_preview_update = 0.0
|
||
self.last_monitor_update = 0.0
|
||
|
||
print("✓ 语音编辑器已创建")
|
||
|
||
def initialize(self) -> bool:
|
||
"""
|
||
初始化语音编辑器
|
||
|
||
Returns:
|
||
是否初始化成功
|
||
"""
|
||
try:
|
||
# 初始化UI组件(模拟)
|
||
self._initialize_ui_components()
|
||
|
||
# 加载缓存数据
|
||
self._load_editor_cache()
|
||
|
||
self.initialized = True
|
||
print("✓ 语音编辑器初始化完成")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 语音编辑器初始化失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def enable(self) -> bool:
|
||
"""
|
||
启用语音编辑器
|
||
|
||
Returns:
|
||
是否启用成功
|
||
"""
|
||
try:
|
||
if not self.initialized:
|
||
print("✗ 语音编辑器未初始化")
|
||
return False
|
||
|
||
self.enabled = True
|
||
self.running = True
|
||
|
||
# 启动编辑器线程
|
||
self.editor_thread = threading.Thread(target=self._editor_update_loop, daemon=True)
|
||
self.editor_thread.start()
|
||
|
||
# 启动监控线程
|
||
if self.editor_config["enable_realtime_update"]:
|
||
self.monitor_thread = threading.Thread(target=self._monitor_update_loop, daemon=True)
|
||
self.monitor_thread.start()
|
||
|
||
print("✓ 语音编辑器已启用")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 语音编辑器启用失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def disable(self):
|
||
"""禁用语音编辑器"""
|
||
try:
|
||
self.enabled = False
|
||
self.running = False
|
||
|
||
# 等待线程结束
|
||
if self.editor_thread and self.editor_thread.is_alive():
|
||
self.editor_thread.join(timeout=2.0)
|
||
|
||
if self.monitor_thread and self.monitor_thread.is_alive():
|
||
self.monitor_thread.join(timeout=2.0)
|
||
|
||
# 关闭UI组件
|
||
self._close_ui_components()
|
||
|
||
print("✓ 语音编辑器已禁用")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 语音编辑器禁用失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def finalize(self):
|
||
"""清理语音编辑器资源"""
|
||
try:
|
||
self.disable()
|
||
self.ui_components.clear()
|
||
self.editor_data.clear()
|
||
self.operation_history.clear()
|
||
self.monitor_data.clear()
|
||
self.test_data.clear()
|
||
self.editor_callbacks.clear()
|
||
self.initialized = False
|
||
print("✓ 语音编辑器资源已清理")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 语音编辑器资源清理失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def update(self, dt: float):
|
||
"""
|
||
更新语音编辑器状态
|
||
|
||
Args:
|
||
dt: 时间增量
|
||
"""
|
||
try:
|
||
if not self.enabled:
|
||
return
|
||
|
||
# 更新统计信息
|
||
pass
|
||
|
||
except Exception as e:
|
||
print(f"✗ 语音编辑器更新失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def _editor_update_loop(self):
|
||
"""编辑器更新循环"""
|
||
try:
|
||
refresh_interval = 1.0 / self.editor_config["refresh_rate"]
|
||
|
||
while self.running:
|
||
if self.enabled:
|
||
self._update_editor_display()
|
||
|
||
time.sleep(refresh_interval)
|
||
|
||
except Exception as e:
|
||
print(f"✗ 编辑器更新循环失败: {e}")
|
||
|
||
def _monitor_update_loop(self):
|
||
"""监控更新循环"""
|
||
try:
|
||
monitor_interval = 0.1 # 100ms
|
||
|
||
while self.running:
|
||
if self.enabled and self.editor_config["enable_realtime_update"]:
|
||
self._update_monitor_data()
|
||
|
||
time.sleep(monitor_interval)
|
||
|
||
except Exception as e:
|
||
print(f"✗ 监控更新循环失败: {e}")
|
||
|
||
def _initialize_ui_components(self):
|
||
"""初始化UI组件"""
|
||
try:
|
||
# 在实际实现中,这里会创建实际的UI组件
|
||
# 由于这是模拟实现,我们只创建占位符
|
||
self.ui_components["main_window"] = "MainWindow"
|
||
self.ui_components["toolbar"] = "Toolbar"
|
||
self.ui_components["property_panel"] = "PropertyPanel"
|
||
self.ui_components["preview_panel"] = "PreviewPanel"
|
||
self.ui_components["status_bar"] = "StatusBar"
|
||
self.ui_components["config_view"] = "ConfigView"
|
||
self.ui_components["command_view"] = "CommandView"
|
||
self.ui_components["training_view"] = "TrainingView"
|
||
self.ui_components["test_view"] = "TestView"
|
||
self.ui_components["monitor_view"] = "MonitorView"
|
||
self.ui_components["preset_view"] = "PresetView"
|
||
|
||
print("✓ UI组件初始化完成")
|
||
except Exception as e:
|
||
print(f"✗ UI组件初始化失败: {e}")
|
||
|
||
def _close_ui_components(self):
|
||
"""关闭UI组件"""
|
||
try:
|
||
# 在实际实现中,这里会关闭实际的UI组件
|
||
self.ui_components.clear()
|
||
print("✓ UI组件已关闭")
|
||
except Exception as e:
|
||
print(f"✗ UI组件关闭失败: {e}")
|
||
|
||
def _load_editor_cache(self):
|
||
"""加载编辑器缓存"""
|
||
try:
|
||
# 模拟加载缓存数据
|
||
if self.plugin.config_manager:
|
||
self.editor_data["config_cache"] = self.plugin.config_manager.get_config()
|
||
|
||
if self.plugin.command_processor:
|
||
self.editor_data["command_cache"] = self.plugin.command_processor.get_command_mappings()
|
||
|
||
print("✓ 编辑器缓存加载完成")
|
||
except Exception as e:
|
||
print(f"✗ 编辑器缓存加载失败: {e}")
|
||
|
||
def _update_editor_display(self):
|
||
"""更新编辑器显示"""
|
||
try:
|
||
current_time = time.time()
|
||
|
||
# 检查是否需要刷新
|
||
if current_time - self.last_refresh_time >= 1.0 / self.editor_config["refresh_rate"]:
|
||
# 更新配置视图
|
||
self._refresh_config_view()
|
||
|
||
# 更新属性面板
|
||
self._refresh_property_panel()
|
||
|
||
# 更新预览面板
|
||
if self.editor_config["enable_preview"]:
|
||
self._update_preview_panel()
|
||
|
||
# 更新状态栏
|
||
self._update_status_bar()
|
||
|
||
self.last_refresh_time = current_time
|
||
self.editor_stats["data_refreshed"] += 1
|
||
|
||
except Exception as e:
|
||
print(f"✗ 编辑器显示更新失败: {e}")
|
||
|
||
def _update_monitor_data(self):
|
||
"""更新监控数据"""
|
||
try:
|
||
# 收集实时数据
|
||
current_time = time.time()
|
||
|
||
# 收集音频级别数据
|
||
if self.plugin.audio_manager:
|
||
input_level = self.plugin.audio_manager.get_audio_level("input")
|
||
output_level = self.plugin.audio_manager.get_audio_level("output")
|
||
|
||
self.monitor_data["audio_levels"].append({
|
||
"input": input_level,
|
||
"output": output_level,
|
||
"timestamp": current_time
|
||
})
|
||
|
||
# 保持数据大小
|
||
if len(self.monitor_data["audio_levels"]) > 100:
|
||
self.monitor_data["audio_levels"] = self.monitor_data["audio_levels"][-100:]
|
||
|
||
# 收集识别结果
|
||
if self.plugin.voice_manager:
|
||
recognition_state = self.plugin.voice_manager.get_recognition_state()
|
||
if recognition_state.get("current_text"):
|
||
self.monitor_data["recognition_results"].append({
|
||
"text": recognition_state["current_text"],
|
||
"confidence": recognition_state["confidence"],
|
||
"timestamp": current_time
|
||
})
|
||
|
||
# 保持数据大小
|
||
if len(self.monitor_data["recognition_results"]) > 50:
|
||
self.monitor_data["recognition_results"] = self.monitor_data["recognition_results"][-50:]
|
||
|
||
# 收集合成事件
|
||
if self.plugin.voice_manager:
|
||
synthesis_state = self.plugin.voice_manager.get_synthesis_state()
|
||
if synthesis_state.get("current_text"):
|
||
# 这里只是示例,实际应该监听合成事件
|
||
pass
|
||
|
||
# 收集性能指标
|
||
self._collect_performance_metrics()
|
||
|
||
except Exception as e:
|
||
print(f"✗ 监控数据更新失败: {e}")
|
||
|
||
def _collect_performance_metrics(self):
|
||
"""收集性能指标"""
|
||
try:
|
||
metrics = {}
|
||
|
||
# 收集各模块统计信息
|
||
if self.plugin.voice_manager:
|
||
metrics["voice_manager"] = self.plugin.voice_manager.get_stats()
|
||
|
||
if self.plugin.speech_recognizer:
|
||
metrics["speech_recognizer"] = self.plugin.speech_recognizer.get_stats()
|
||
|
||
if self.plugin.speech_synthesizer:
|
||
metrics["speech_synthesizer"] = self.plugin.speech_synthesizer.get_stats()
|
||
|
||
if self.plugin.command_processor:
|
||
metrics["command_processor"] = self.plugin.command_processor.get_stats()
|
||
|
||
if self.plugin.audio_manager:
|
||
metrics["audio_manager"] = self.plugin.audio_manager.get_device_stats()
|
||
|
||
if self.plugin.nlp_processor:
|
||
metrics["nlp_processor"] = self.plugin.nlp_processor.get_stats()
|
||
|
||
if self.plugin.event_handler:
|
||
metrics["event_handler"] = self.plugin.event_handler.get_stats()
|
||
|
||
if self.plugin.config_manager:
|
||
metrics["config_manager"] = self.plugin.config_manager.get_config_stats()
|
||
|
||
self.monitor_data["performance_metrics"] = metrics
|
||
|
||
except Exception as e:
|
||
print(f"✗ 性能指标收集失败: {e}")
|
||
|
||
def _refresh_config_view(self):
|
||
"""刷新配置视图"""
|
||
try:
|
||
# 在实际实现中,这里会更新配置视图的显示内容
|
||
pass
|
||
except Exception as e:
|
||
print(f"✗ 配置视图刷新失败: {e}")
|
||
|
||
def _refresh_property_panel(self):
|
||
"""刷新属性面板"""
|
||
try:
|
||
# 根据当前模式更新属性面板
|
||
current_mode = self.editor_state["current_mode"]
|
||
|
||
# 在实际实现中,这里会更新属性面板的显示内容
|
||
pass
|
||
except Exception as e:
|
||
print(f"✗ 属性面板刷新失败: {e}")
|
||
|
||
def _update_preview_panel(self):
|
||
"""更新预览面板"""
|
||
try:
|
||
current_time = time.time()
|
||
if current_time - self.last_preview_update >= 0.1: # 100ms
|
||
# 更新预览数据
|
||
self.editor_data["live_data"] = self._collect_live_data()
|
||
|
||
# 在实际实现中,这里会更新预览面板的显示
|
||
self.editor_stats["preview_updates"] += 1
|
||
self.last_preview_update = current_time
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预览面板更新失败: {e}")
|
||
|
||
def _collect_live_data(self) -> Dict[str, Any]:
|
||
"""
|
||
收集实时数据
|
||
|
||
Returns:
|
||
实时数据字典
|
||
"""
|
||
try:
|
||
live_data = {
|
||
"timestamp": time.time(),
|
||
"audio": {},
|
||
"recognition": {},
|
||
"synthesis": {},
|
||
"commands": {},
|
||
"performance": {}
|
||
}
|
||
|
||
# 收集音频数据
|
||
if self.plugin.audio_manager:
|
||
live_data["audio"] = {
|
||
"input_level": self.plugin.audio_manager.get_audio_level("input"),
|
||
"output_level": self.plugin.audio_manager.get_audio_level("output"),
|
||
"is_recording": self.plugin.audio_manager.is_recording(),
|
||
"is_playing": self.plugin.audio_manager.is_playing()
|
||
}
|
||
|
||
# 收集识别数据
|
||
if self.plugin.voice_manager:
|
||
live_data["recognition"] = self.plugin.voice_manager.get_recognition_state()
|
||
|
||
# 收集合成数据
|
||
if self.plugin.voice_manager:
|
||
live_data["synthesis"] = self.plugin.voice_manager.get_synthesis_state()
|
||
|
||
# 收集命令数据
|
||
if self.plugin.command_processor:
|
||
live_data["commands"] = {
|
||
"history": self.plugin.command_processor.get_command_history()[-10:] # 最近10条
|
||
}
|
||
|
||
# 收集性能数据
|
||
live_data["performance"] = self._collect_performance_metrics()
|
||
|
||
return live_data
|
||
|
||
except Exception as e:
|
||
print(f"✗ 实时数据收集失败: {e}")
|
||
return {}
|
||
|
||
def _update_status_bar(self):
|
||
"""更新状态栏"""
|
||
try:
|
||
# 在实际实现中,这里会更新状态栏的显示内容
|
||
pass
|
||
except Exception as e:
|
||
print(f"✗ 状态栏更新失败: {e}")
|
||
|
||
def set_editor_mode(self, mode: str) -> bool:
|
||
"""
|
||
设置编辑器模式
|
||
|
||
Args:
|
||
mode: 编辑器模式
|
||
|
||
Returns:
|
||
是否设置成功
|
||
"""
|
||
try:
|
||
old_mode = self.editor_state["current_mode"]
|
||
self.editor_state["current_mode"] = mode
|
||
|
||
# 触发模式变更回调
|
||
self._trigger_editor_callback("mode_changed", {
|
||
"old_mode": old_mode,
|
||
"new_mode": mode
|
||
})
|
||
|
||
print(f"✓ 编辑器模式已设置: {mode}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 编辑器模式设置失败: {e}")
|
||
return False
|
||
|
||
def set_selected_tab(self, tab: str) -> bool:
|
||
"""
|
||
设置选中标签页
|
||
|
||
Args:
|
||
tab: 标签页名称
|
||
|
||
Returns:
|
||
是否设置成功
|
||
"""
|
||
try:
|
||
old_tab = self.editor_state["selected_tab"]
|
||
self.editor_state["selected_tab"] = tab
|
||
|
||
# 触发标签页变更回调
|
||
self._trigger_editor_callback("tab_changed", {
|
||
"old_tab": old_tab,
|
||
"new_tab": tab
|
||
})
|
||
|
||
print(f"✓ 选中标签页已设置: {tab}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 选中标签页设置失败: {e}")
|
||
return False
|
||
|
||
def start_recording(self) -> bool:
|
||
"""
|
||
开始录制
|
||
|
||
Returns:
|
||
是否开始成功
|
||
"""
|
||
try:
|
||
if not self.plugin.audio_manager:
|
||
print("✗ 音频管理器未初始化")
|
||
return False
|
||
|
||
if self.plugin.audio_manager.start_recording():
|
||
self.editor_state["is_recording"] = True
|
||
|
||
# 触发录制开始回调
|
||
self._trigger_editor_callback("recording_started", {
|
||
"timestamp": time.time()
|
||
})
|
||
|
||
print("✓ 录制已开始")
|
||
return True
|
||
else:
|
||
print("✗ 录制开始失败")
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ 录制开始失败: {e}")
|
||
return False
|
||
|
||
def stop_recording(self) -> bool:
|
||
"""
|
||
停止录制
|
||
|
||
Returns:
|
||
是否停止成功
|
||
"""
|
||
try:
|
||
if not self.plugin.audio_manager:
|
||
print("✗ 音频管理器未初始化")
|
||
return False
|
||
|
||
if self.plugin.audio_manager.stop_recording():
|
||
self.editor_state["is_recording"] = False
|
||
|
||
# 触发录制停止回调
|
||
self._trigger_editor_callback("recording_stopped", {
|
||
"timestamp": time.time()
|
||
})
|
||
|
||
print("✓ 录制已停止")
|
||
return True
|
||
else:
|
||
print("✗ 录制停止失败")
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ 录制停止失败: {e}")
|
||
return False
|
||
|
||
def start_testing(self, test_case: Dict[str, Any] = None) -> bool:
|
||
"""
|
||
开始测试
|
||
|
||
Args:
|
||
test_case: 测试用例
|
||
|
||
Returns:
|
||
是否开始成功
|
||
"""
|
||
try:
|
||
self.editor_state["is_testing"] = True
|
||
|
||
# 添加到测试历史
|
||
if test_case:
|
||
self.test_data["current_test"] = test_case
|
||
self.test_data["test_cases"].append(test_case)
|
||
|
||
# 触发测试开始回调
|
||
self._trigger_editor_callback("test_started", {
|
||
"test_case": test_case,
|
||
"timestamp": time.time()
|
||
})
|
||
|
||
self.editor_stats["tests_run"] += 1
|
||
print("✓ 测试已开始")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 测试开始失败: {e}")
|
||
return False
|
||
|
||
def stop_testing(self) -> bool:
|
||
"""
|
||
停止测试
|
||
|
||
Returns:
|
||
是否停止成功
|
||
"""
|
||
try:
|
||
self.editor_state["is_testing"] = False
|
||
|
||
# 记录测试结果
|
||
if self.test_data["current_test"]:
|
||
test_result = {
|
||
"test_case": self.test_data["current_test"],
|
||
"end_time": time.time(),
|
||
"status": "completed"
|
||
}
|
||
self.test_data["test_results"].append(test_result)
|
||
self.test_data["current_test"] = None
|
||
|
||
# 触发测试完成回调
|
||
self._trigger_editor_callback("test_completed", {
|
||
"timestamp": time.time()
|
||
})
|
||
|
||
print("✓ 测试已停止")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 测试停止失败: {e}")
|
||
return False
|
||
|
||
def test_speech_recognition(self, audio_file: str = None) -> bool:
|
||
"""
|
||
测试语音识别
|
||
|
||
Args:
|
||
audio_file: 音频文件路径(None表示使用麦克风输入)
|
||
|
||
Returns:
|
||
是否测试成功
|
||
"""
|
||
try:
|
||
print("✓ 语音识别测试已开始")
|
||
|
||
# 在实际实现中,这里会执行语音识别测试
|
||
# 可能包括加载音频文件、执行识别、验证结果等
|
||
|
||
# 添加到测试历史
|
||
test_entry = {
|
||
"type": "speech_recognition",
|
||
"audio_file": audio_file,
|
||
"start_time": time.time(),
|
||
"parameters": {
|
||
"language": self.plugin.config_manager.get_config("recognition", "language", "zh-CN") if self.plugin.config_manager else "zh-CN"
|
||
}
|
||
}
|
||
|
||
self.editor_data["test_history"].append(test_entry)
|
||
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 语音识别测试失败: {e}")
|
||
return False
|
||
|
||
def test_speech_synthesis(self, text: str, language: str = None) -> bool:
|
||
"""
|
||
测试语音合成
|
||
|
||
Args:
|
||
text: 要合成的文本
|
||
language: 语言代码
|
||
|
||
Returns:
|
||
是否测试成功
|
||
"""
|
||
try:
|
||
if not self.plugin.speech_synthesizer:
|
||
print("✗ 语音合成器未初始化")
|
||
return False
|
||
|
||
if not language:
|
||
language = self.plugin.config_manager.get_config("synthesis", "language", "zh-CN") if self.plugin.config_manager else "zh-CN"
|
||
|
||
print(f"✓ 语音合成测试已开始: '{text}'")
|
||
|
||
# 执行语音合成
|
||
result = self.plugin.speech_synthesizer.synthesize_speech(
|
||
text,
|
||
blocking=False,
|
||
speed=self.plugin.config_manager.get_config("synthesis", "speed", 1.0) if self.plugin.config_manager else 1.0,
|
||
volume=self.plugin.config_manager.get_config("synthesis", "volume", 1.0) if self.plugin.config_manager else 1.0
|
||
)
|
||
|
||
# 添加到测试历史
|
||
test_entry = {
|
||
"type": "speech_synthesis",
|
||
"text": text,
|
||
"language": language,
|
||
"start_time": time.time(),
|
||
"success": result,
|
||
"parameters": {
|
||
"speed": self.plugin.config_manager.get_config("synthesis", "speed", 1.0) if self.plugin.config_manager else 1.0,
|
||
"volume": self.plugin.config_manager.get_config("synthesis", "volume", 1.0) if self.plugin.config_manager else 1.0
|
||
}
|
||
}
|
||
|
||
self.editor_data["test_history"].append(test_entry)
|
||
|
||
return result
|
||
|
||
except Exception as e:
|
||
print(f"✗ 语音合成测试失败: {e}")
|
||
return False
|
||
|
||
def test_command_execution(self, command_text: str) -> bool:
|
||
"""
|
||
测试命令执行
|
||
|
||
Args:
|
||
command_text: 命令文本
|
||
|
||
Returns:
|
||
是否测试成功
|
||
"""
|
||
try:
|
||
if not self.plugin.command_processor:
|
||
print("✗ 命令处理器未初始化")
|
||
return False
|
||
|
||
print(f"✓ 命令执行测试已开始: '{command_text}'")
|
||
|
||
# 执行命令处理
|
||
result = self.plugin.command_processor.process_command(command_text, 1.0)
|
||
|
||
# 添加到测试历史
|
||
test_entry = {
|
||
"type": "command_execution",
|
||
"command": command_text,
|
||
"start_time": time.time(),
|
||
"success": result
|
||
}
|
||
|
||
self.editor_data["test_history"].append(test_entry)
|
||
|
||
return result
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令执行测试失败: {e}")
|
||
return False
|
||
|
||
def toggle_preview(self, enable: bool = None) -> bool:
|
||
"""
|
||
切换预览
|
||
|
||
Args:
|
||
enable: 是否启用预览(None表示切换)
|
||
|
||
Returns:
|
||
是否切换成功
|
||
"""
|
||
try:
|
||
if enable is None:
|
||
enable = not self.editor_state["preview_active"]
|
||
|
||
self.editor_state["preview_active"] = enable
|
||
self.editor_config["enable_preview"] = enable
|
||
|
||
status = "启用" if enable else "禁用"
|
||
print(f"✓ 预览已{status}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 预览切换失败: {e}")
|
||
return False
|
||
|
||
def toggle_monitoring(self, enable: bool = None) -> bool:
|
||
"""
|
||
切换监控
|
||
|
||
Args:
|
||
enable: 是否启用监控(None表示切换)
|
||
|
||
Returns:
|
||
是否切换成功
|
||
"""
|
||
try:
|
||
if enable is None:
|
||
enable = not self.editor_state["monitoring_active"]
|
||
|
||
self.editor_state["monitoring_active"] = enable
|
||
|
||
status = "启用" if enable else "禁用"
|
||
print(f"✓ 监控已{status}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 监控切换失败: {e}")
|
||
return False
|
||
|
||
def undo_operation(self) -> bool:
|
||
"""
|
||
撤销操作
|
||
|
||
Returns:
|
||
是否撤销成功
|
||
"""
|
||
try:
|
||
if self.history_pointer >= 0 and self.operation_history:
|
||
# 执行撤销操作
|
||
operation = self.operation_history[self.history_pointer]
|
||
self.history_pointer -= 1
|
||
self.editor_stats["undo_operations"] += 1
|
||
|
||
print("✓ 操作已撤销")
|
||
return True
|
||
else:
|
||
print("⚠ 没有可撤销的操作")
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ 操作撤销失败: {e}")
|
||
return False
|
||
|
||
def redo_operation(self) -> bool:
|
||
"""
|
||
重做操作
|
||
|
||
Returns:
|
||
是否重做成功
|
||
"""
|
||
try:
|
||
if self.history_pointer < len(self.operation_history) - 1:
|
||
# 执行重做操作
|
||
self.history_pointer += 1
|
||
operation = self.operation_history[self.history_pointer]
|
||
self.editor_stats["redo_operations"] += 1
|
||
|
||
print("✓ 操作已重做")
|
||
return True
|
||
else:
|
||
print("⚠ 没有可重做的操作")
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ 操作重做失败: {e}")
|
||
return False
|
||
|
||
def add_operation_to_history(self, operation: Dict[str, Any]):
|
||
"""
|
||
添加操作到历史
|
||
|
||
Args:
|
||
operation: 操作数据
|
||
"""
|
||
try:
|
||
# 添加到历史记录
|
||
self.operation_history.append(operation)
|
||
self.history_pointer = len(self.operation_history) - 1
|
||
|
||
# 保持历史记录大小
|
||
if len(self.operation_history) > self.max_history_size:
|
||
remove_count = len(self.operation_history) - self.max_history_size
|
||
self.operation_history = self.operation_history[remove_count:]
|
||
self.history_pointer -= remove_count
|
||
self.history_pointer = max(0, self.history_pointer)
|
||
|
||
self.editor_stats["operations_performed"] += 1
|
||
|
||
except Exception as e:
|
||
print(f"✗ 操作添加到历史失败: {e}")
|
||
|
||
def _trigger_editor_callback(self, callback_type: str, data: Dict[str, Any]):
|
||
"""
|
||
触发编辑器回调
|
||
|
||
Args:
|
||
callback_type: 回调类型
|
||
data: 回调数据
|
||
"""
|
||
try:
|
||
if callback_type in self.editor_callbacks:
|
||
for callback in self.editor_callbacks[callback_type]:
|
||
try:
|
||
callback(data)
|
||
except Exception as e:
|
||
print(f"✗ 编辑器回调执行失败: {e}")
|
||
except Exception as e:
|
||
print(f"✗ 编辑器回调触发失败: {e}")
|
||
|
||
def register_editor_callback(self, callback_type: str, callback: callable):
|
||
"""
|
||
注册编辑器回调
|
||
|
||
Args:
|
||
callback_type: 回调类型
|
||
callback: 回调函数
|
||
"""
|
||
try:
|
||
if callback_type in self.editor_callbacks:
|
||
self.editor_callbacks[callback_type].append(callback)
|
||
print(f"✓ 编辑器回调已注册: {callback_type}")
|
||
else:
|
||
print(f"✗ 无效的回调类型: {callback_type}")
|
||
except Exception as e:
|
||
print(f"✗ 编辑器回调注册失败: {e}")
|
||
|
||
def unregister_editor_callback(self, callback_type: str, callback: callable):
|
||
"""
|
||
注销编辑器回调
|
||
|
||
Args:
|
||
callback_type: 回调类型
|
||
callback: 回调函数
|
||
"""
|
||
try:
|
||
if callback_type in self.editor_callbacks:
|
||
if callback in self.editor_callbacks[callback_type]:
|
||
self.editor_callbacks[callback_type].remove(callback)
|
||
print(f"✓ 编辑器回调已注销: {callback_type}")
|
||
except Exception as e:
|
||
print(f"✗ 编辑器回调注销失败: {e}")
|
||
|
||
def get_editor_state(self) -> Dict[str, Any]:
|
||
"""
|
||
获取编辑器状态
|
||
|
||
Returns:
|
||
编辑器状态字典
|
||
"""
|
||
return self.editor_state.copy()
|
||
|
||
def get_editor_config(self) -> Dict[str, Any]:
|
||
"""
|
||
获取编辑器配置
|
||
|
||
Returns:
|
||
编辑器配置字典
|
||
"""
|
||
return self.editor_config.copy()
|
||
|
||
def set_editor_config(self, config: Dict[str, Any]) -> bool:
|
||
"""
|
||
设置编辑器配置
|
||
|
||
Args:
|
||
config: 编辑器配置字典
|
||
|
||
Returns:
|
||
是否设置成功
|
||
"""
|
||
try:
|
||
self.editor_config.update(config)
|
||
print(f"✓ 编辑器配置已更新: {self.editor_config}")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 编辑器配置设置失败: {e}")
|
||
return False
|
||
|
||
def get_editor_data(self, data_type: str) -> Optional[Dict[str, Any]]:
|
||
"""
|
||
获取编辑器数据
|
||
|
||
Args:
|
||
data_type: 数据类型
|
||
|
||
Returns:
|
||
数据字典或None
|
||
"""
|
||
return self.editor_data.get(data_type)
|
||
|
||
def get_monitor_data(self) -> Dict[str, Any]:
|
||
"""
|
||
获取监控数据
|
||
|
||
Returns:
|
||
监控数据字典
|
||
"""
|
||
return self.monitor_data.copy()
|
||
|
||
def get_test_data(self) -> Dict[str, Any]:
|
||
"""
|
||
获取测试数据
|
||
|
||
Returns:
|
||
测试数据字典
|
||
"""
|
||
return self.test_data.copy()
|
||
|
||
def get_editor_stats(self) -> Dict[str, int]:
|
||
"""
|
||
获取编辑器统计信息
|
||
|
||
Returns:
|
||
编辑器统计字典
|
||
"""
|
||
return self.editor_stats.copy()
|
||
|
||
def reset_editor_stats(self):
|
||
"""重置编辑器统计信息"""
|
||
try:
|
||
self.editor_stats = {
|
||
"windows_opened": 0,
|
||
"operations_performed": 0,
|
||
"undo_operations": 0,
|
||
"redo_operations": 0,
|
||
"data_refreshed": 0,
|
||
"preview_updates": 0,
|
||
"tests_run": 0
|
||
}
|
||
print("✓ 编辑器统计信息已重置")
|
||
except Exception as e:
|
||
print(f"✗ 编辑器统计信息重置失败: {e}")
|
||
|
||
def refresh_editor_data(self):
|
||
"""刷新编辑器数据"""
|
||
try:
|
||
self._load_editor_cache()
|
||
self._update_editor_display()
|
||
print("✓ 编辑器数据已刷新")
|
||
except Exception as e:
|
||
print(f"✗ 编辑器数据刷新失败: {e}")
|
||
|
||
def show_editor_window(self) -> bool:
|
||
"""
|
||
显示编辑器窗口
|
||
|
||
Returns:
|
||
是否显示成功
|
||
"""
|
||
try:
|
||
# 在实际实现中,这里会显示实际的编辑器窗口
|
||
self.editor_stats["windows_opened"] += 1
|
||
print("✓ 编辑器窗口已显示")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 编辑器窗口显示失败: {e}")
|
||
return False
|
||
|
||
def hide_editor_window(self) -> bool:
|
||
"""
|
||
隐藏编辑器窗口
|
||
|
||
Returns:
|
||
是否隐藏成功
|
||
"""
|
||
try:
|
||
# 在实际实现中,这里会隐藏实际的编辑器窗口
|
||
print("✓ 编辑器窗口已隐藏")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 编辑器窗口隐藏失败: {e}")
|
||
return False
|
||
|
||
def export_editor_data(self, file_path: str) -> bool:
|
||
"""
|
||
导出编辑器数据
|
||
|
||
Args:
|
||
file_path: 导出文件路径
|
||
|
||
Returns:
|
||
是否导出成功
|
||
"""
|
||
try:
|
||
# 在实际实现中,这里会导出编辑器数据到文件
|
||
print(f"✓ 编辑器数据已导出: {file_path}")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 编辑器数据导出失败: {e}")
|
||
return False
|
||
|
||
def import_editor_data(self, file_path: str) -> bool:
|
||
"""
|
||
导入编辑器数据
|
||
|
||
Args:
|
||
file_path: 导入文件路径
|
||
|
||
Returns:
|
||
是否导入成功
|
||
"""
|
||
try:
|
||
# 在实际实现中,这里会从文件导入编辑器数据
|
||
print(f"✓ 编辑器数据已导入: {file_path}")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 编辑器数据导入失败: {e}")
|
||
return False
|
||
|
||
def run_comprehensive_test(self) -> Dict[str, Any]:
|
||
"""
|
||
运行综合测试
|
||
|
||
Returns:
|
||
测试结果字典
|
||
"""
|
||
try:
|
||
print("✓ 开始综合测试...")
|
||
|
||
test_results = {
|
||
"timestamp": time.time(),
|
||
"tests": {},
|
||
"summary": {
|
||
"total_tests": 0,
|
||
"passed_tests": 0,
|
||
"failed_tests": 0,
|
||
"success_rate": 0.0
|
||
}
|
||
}
|
||
|
||
# 测试语音识别
|
||
test_results["tests"]["speech_recognition"] = {
|
||
"status": "passed" if self.test_speech_recognition() else "failed",
|
||
"details": "语音识别功能测试"
|
||
}
|
||
|
||
# 测试语音合成
|
||
test_results["tests"]["speech_synthesis"] = {
|
||
"status": "passed" if self.test_speech_synthesis("测试语音合成功能") else "failed",
|
||
"details": "语音合成功能测试"
|
||
}
|
||
|
||
# 测试命令执行
|
||
test_results["tests"]["command_execution"] = {
|
||
"status": "passed" if self.test_command_execution("前进") else "failed",
|
||
"details": "命令执行功能测试"
|
||
}
|
||
|
||
# 统计结果
|
||
total_tests = len(test_results["tests"])
|
||
passed_tests = sum(1 for test in test_results["tests"].values() if test["status"] == "passed")
|
||
|
||
test_results["summary"]["total_tests"] = total_tests
|
||
test_results["summary"]["passed_tests"] = passed_tests
|
||
test_results["summary"]["failed_tests"] = total_tests - passed_tests
|
||
test_results["summary"]["success_rate"] = passed_tests / total_tests if total_tests > 0 else 0.0
|
||
|
||
print(f"✓ 综合测试完成: {passed_tests}/{total_tests} 通过")
|
||
return test_results
|
||
|
||
except Exception as e:
|
||
print(f"✗ 综合测试失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return {
|
||
"timestamp": time.time(),
|
||
"tests": {},
|
||
"summary": {
|
||
"total_tests": 0,
|
||
"passed_tests": 0,
|
||
"failed_tests": 0,
|
||
"success_rate": 0.0,
|
||
"error": str(e)
|
||
}
|
||
} |