mirror of
https://github.com/Minidoracat/mcp-feedback-enhanced.git
synced 2025-07-27 10:42:25 +08:00
194 lines
7.3 KiB
Python
194 lines
7.3 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
命令分頁組件
|
|
============
|
|
|
|
專門處理命令執行的分頁組件。
|
|
"""
|
|
|
|
from PySide6.QtWidgets import (
|
|
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
|
|
QTextEdit, QLineEdit, QPushButton
|
|
)
|
|
from PySide6.QtCore import Signal
|
|
from PySide6.QtGui import QFont
|
|
|
|
from ..utils import apply_widget_styles
|
|
from ..window.command_executor import CommandExecutor
|
|
from ...i18n import t
|
|
|
|
|
|
class CommandTab(QWidget):
|
|
"""命令分頁組件"""
|
|
|
|
def __init__(self, project_dir: str, parent=None):
|
|
super().__init__(parent)
|
|
self.project_dir = project_dir
|
|
self.command_executor = CommandExecutor(project_dir, self)
|
|
self._setup_ui()
|
|
self._connect_signals()
|
|
|
|
def _setup_ui(self) -> None:
|
|
"""設置用戶介面"""
|
|
command_layout = QVBoxLayout(self)
|
|
command_layout.setSpacing(0) # 緊湊佈局
|
|
command_layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
# 命令說明區域(頂部,只保留說明文字)
|
|
header_widget = QWidget()
|
|
header_layout = QVBoxLayout(header_widget)
|
|
header_layout.setSpacing(6)
|
|
header_layout.setContentsMargins(12, 8, 12, 8)
|
|
|
|
self.command_description_label = QLabel(t('command.description'))
|
|
self.command_description_label.setStyleSheet("color: #9e9e9e; font-size: 11px; margin-bottom: 6px;")
|
|
self.command_description_label.setWordWrap(True)
|
|
header_layout.addWidget(self.command_description_label)
|
|
|
|
command_layout.addWidget(header_widget)
|
|
|
|
# 命令輸出區域(中間,佔大部分空間)
|
|
output_widget = QWidget()
|
|
output_layout = QVBoxLayout(output_widget)
|
|
output_layout.setSpacing(6)
|
|
output_layout.setContentsMargins(12, 4, 12, 8)
|
|
|
|
self.command_output = QTextEdit()
|
|
self.command_output.setReadOnly(True)
|
|
self.command_output.setFont(QFont("Consolas", 11))
|
|
self.command_output.setPlaceholderText(t('command.outputPlaceholder'))
|
|
# 終端機風格樣式
|
|
self.command_output.setStyleSheet("""
|
|
QTextEdit {
|
|
background-color: #1a1a1a;
|
|
border: 1px solid #333;
|
|
border-radius: 6px;
|
|
padding: 12px;
|
|
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
|
|
font-size: 11px;
|
|
color: #00ff00;
|
|
line-height: 1.4;
|
|
}
|
|
QScrollBar:vertical {
|
|
background-color: #2a2a2a;
|
|
width: 12px;
|
|
border-radius: 6px;
|
|
}
|
|
QScrollBar::handle:vertical {
|
|
background-color: #555;
|
|
border-radius: 6px;
|
|
min-height: 20px;
|
|
}
|
|
QScrollBar::handle:vertical:hover {
|
|
background-color: #666;
|
|
}
|
|
""")
|
|
output_layout.addWidget(self.command_output, 1) # 佔據剩餘空間
|
|
|
|
command_layout.addWidget(output_widget, 1) # 輸出區域佔大部分空間
|
|
|
|
# 命令輸入區域(底部,固定高度)
|
|
input_widget = QWidget()
|
|
input_widget.setFixedHeight(70) # 固定高度
|
|
input_layout = QVBoxLayout(input_widget)
|
|
input_layout.setSpacing(6)
|
|
input_layout.setContentsMargins(12, 8, 12, 12)
|
|
|
|
# 命令輸入和執行按鈕(水平布局)
|
|
input_row_layout = QHBoxLayout()
|
|
input_row_layout.setSpacing(8)
|
|
|
|
# 提示符號標籤
|
|
prompt_label = QLabel("$")
|
|
prompt_label.setStyleSheet("color: #00ff00; font-family: 'Consolas', 'Monaco', monospace; font-size: 14px; font-weight: bold;")
|
|
prompt_label.setFixedWidth(20)
|
|
input_row_layout.addWidget(prompt_label)
|
|
|
|
self.command_input = QLineEdit()
|
|
self.command_input.setPlaceholderText(t('command.placeholder'))
|
|
self.command_input.setMinimumHeight(36)
|
|
# 終端機風格輸入框
|
|
self.command_input.setStyleSheet("""
|
|
QLineEdit {
|
|
background-color: #1a1a1a;
|
|
border: 2px solid #333;
|
|
border-radius: 4px;
|
|
padding: 8px 12px;
|
|
color: #00ff00;
|
|
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
|
|
font-size: 12px;
|
|
}
|
|
QLineEdit:focus {
|
|
border-color: #007acc;
|
|
background-color: #1e1e1e;
|
|
}
|
|
""")
|
|
self.command_input.returnPressed.connect(self._run_command)
|
|
input_row_layout.addWidget(self.command_input, 1) # 佔據大部分空間
|
|
|
|
self.command_run_button = QPushButton(t('command.run'))
|
|
self.command_run_button.clicked.connect(self._run_command)
|
|
self.command_run_button.setFixedSize(80, 36)
|
|
apply_widget_styles(self.command_run_button, "primary_button")
|
|
input_row_layout.addWidget(self.command_run_button)
|
|
|
|
self.command_terminate_button = QPushButton(t('command.terminate'))
|
|
self.command_terminate_button.clicked.connect(self._terminate_command)
|
|
self.command_terminate_button.setFixedSize(80, 36)
|
|
apply_widget_styles(self.command_terminate_button, "danger_button")
|
|
input_row_layout.addWidget(self.command_terminate_button)
|
|
|
|
input_layout.addLayout(input_row_layout)
|
|
|
|
command_layout.addWidget(input_widget) # 輸入區域在底部
|
|
|
|
def _connect_signals(self) -> None:
|
|
"""連接信號"""
|
|
self.command_executor.output_received.connect(self._append_command_output)
|
|
|
|
def _run_command(self) -> None:
|
|
"""執行命令"""
|
|
command = self.command_input.text().strip()
|
|
if command:
|
|
self.command_executor.run_command(command)
|
|
self.command_input.clear()
|
|
|
|
def _terminate_command(self) -> None:
|
|
"""終止命令"""
|
|
self.command_executor.terminate_command()
|
|
|
|
def _append_command_output(self, text: str) -> None:
|
|
"""添加命令輸出並自動滾動到底部"""
|
|
# 移動光標到最後
|
|
cursor = self.command_output.textCursor()
|
|
cursor.movePosition(cursor.MoveOperation.End)
|
|
self.command_output.setTextCursor(cursor)
|
|
|
|
# 插入文本
|
|
self.command_output.insertPlainText(text)
|
|
|
|
# 確保滾動到最底部
|
|
scrollbar = self.command_output.verticalScrollBar()
|
|
scrollbar.setValue(scrollbar.maximum())
|
|
|
|
# 刷新界面
|
|
from PySide6.QtWidgets import QApplication
|
|
QApplication.processEvents()
|
|
|
|
def get_command_logs(self) -> str:
|
|
"""獲取命令日誌"""
|
|
return self.command_output.toPlainText().strip()
|
|
|
|
def update_texts(self) -> None:
|
|
"""更新界面文字(用於語言切換)"""
|
|
self.command_description_label.setText(t('command.description'))
|
|
self.command_input.setPlaceholderText(t('command.placeholder'))
|
|
self.command_output.setPlaceholderText(t('command.outputPlaceholder'))
|
|
self.command_run_button.setText(t('command.run'))
|
|
self.command_terminate_button.setText(t('command.terminate'))
|
|
|
|
def cleanup(self) -> None:
|
|
"""清理資源"""
|
|
if self.command_executor:
|
|
self.command_executor.cleanup() |