diff --git a/src/mcp_feedback_enhanced/gui/tabs/feedback_tab.py b/src/mcp_feedback_enhanced/gui/tabs/feedback_tab.py index 443575b..c37b0cf 100644 --- a/src/mcp_feedback_enhanced/gui/tabs/feedback_tab.py +++ b/src/mcp_feedback_enhanced/gui/tabs/feedback_tab.py @@ -7,11 +7,12 @@ 專門處理用戶回饋輸入的分頁組件。 """ -from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QSplitter +from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QSplitter, QSizePolicy from PySide6.QtCore import Qt, Signal from ..widgets import SmartTextEdit, ImageUploadWidget from ...i18n import t +from ..window.config_manager import ConfigManager class FeedbackTab(QWidget): @@ -20,6 +21,7 @@ class FeedbackTab(QWidget): def __init__(self, parent=None): super().__init__(parent) + self.config_manager = ConfigManager() self._setup_ui() def _setup_ui(self) -> None: @@ -27,17 +29,56 @@ class FeedbackTab(QWidget): # 主布局 tab_layout = QVBoxLayout(self) tab_layout.setSpacing(12) - tab_layout.setContentsMargins(16, 16, 16, 16) + tab_layout.setContentsMargins(0, 0, 0, 0) # 設置邊距為0,與合併分頁保持一致 + + # 說明文字容器 + description_wrapper = QWidget() + description_layout = QVBoxLayout(description_wrapper) + description_layout.setContentsMargins(16, 16, 16, 10) # 只對說明文字設置邊距 + description_layout.setSpacing(0) # 說明文字 self.feedback_description = QLabel(t('feedback.description')) - self.feedback_description.setStyleSheet("color: #9e9e9e; font-size: 12px; margin-bottom: 10px;") + self.feedback_description.setStyleSheet("color: #9e9e9e; font-size: 12px;") self.feedback_description.setWordWrap(True) - tab_layout.addWidget(self.feedback_description) + description_layout.addWidget(self.feedback_description) + + tab_layout.addWidget(description_wrapper) # 使用分割器來管理回饋輸入和圖片區域 + splitter_wrapper = QWidget() # 創建包裝容器 + splitter_wrapper_layout = QVBoxLayout(splitter_wrapper) + splitter_wrapper_layout.setContentsMargins(16, 0, 16, 16) # 設置左右邊距 + splitter_wrapper_layout.setSpacing(0) + feedback_splitter = QSplitter(Qt.Vertical) feedback_splitter.setChildrenCollapsible(False) + feedback_splitter.setHandleWidth(6) + feedback_splitter.setContentsMargins(0, 0, 0, 0) # 設置分割器邊距為0 + feedback_splitter.setStyleSheet(""" + QSplitter { + border: none; + background: transparent; + } + QSplitter::handle:vertical { + height: 8px; + background-color: #3c3c3c; + border: 1px solid #555555; + border-radius: 4px; + margin-left: 0px; + margin-right: 0px; + margin-top: 2px; + margin-bottom: 2px; + } + QSplitter::handle:vertical:hover { + background-color: #606060; + border-color: #808080; + } + QSplitter::handle:vertical:pressed { + background-color: #007acc; + border-color: #005a9e; + } + """) # 回饋輸入區域 self.feedback_input = SmartTextEdit() @@ -57,13 +98,13 @@ class FeedbackTab(QWidget): """) self.feedback_input.image_paste_requested.connect(self.image_paste_requested) - # 圖片上傳區域 + # 圖片上傳區域(確保固定高度和滾動支持) image_upload_widget = QWidget() - image_upload_widget.setMinimumHeight(140) - image_upload_widget.setMaximumHeight(250) + image_upload_widget.setMinimumHeight(200) # 進一步增加最小高度 + image_upload_widget.setMaximumHeight(320) # 增加最大高度 image_upload_layout = QVBoxLayout(image_upload_widget) image_upload_layout.setSpacing(8) - image_upload_layout.setContentsMargins(0, 8, 0, 0) + image_upload_layout.setContentsMargins(0, 8, 0, 0) # 與回饋輸入區域保持一致的邊距 self.image_upload = ImageUploadWidget() image_upload_layout.addWidget(self.image_upload, 1) @@ -72,15 +113,37 @@ class FeedbackTab(QWidget): feedback_splitter.addWidget(self.feedback_input) feedback_splitter.addWidget(image_upload_widget) - # 設置分割器比例 (70% : 30%) - feedback_splitter.setStretchFactor(0, 3) # 回饋輸入區域較大 - feedback_splitter.setStretchFactor(1, 1) # 圖片上傳區域較小 - feedback_splitter.setSizes([300, 140]) # 設置初始大小 + # 調整分割器比例和設置(確保圖片區域始終可見) + feedback_splitter.setStretchFactor(0, 2) # 回饋輸入區域 + feedback_splitter.setStretchFactor(1, 1) # 圖片上傳區域 - # 設置分割器的最小尺寸,防止子元件被過度壓縮 - feedback_splitter.setMinimumHeight(340) # 設置分割器最小高度 + # 從配置載入分割器位置,如果沒有則使用預設值 + saved_sizes = self.config_manager.get_splitter_sizes('feedback_splitter') + if saved_sizes and len(saved_sizes) == 2: + feedback_splitter.setSizes(saved_sizes) + else: + feedback_splitter.setSizes([220, 200]) # 預設大小 - tab_layout.addWidget(feedback_splitter, 1) + # 連接分割器位置變化信號,自動保存位置 + feedback_splitter.splitterMoved.connect( + lambda pos, index: self._save_feedback_splitter_position(feedback_splitter) + ) + + # 設置分割器的最小尺寸和處理策略 + feedback_splitter.setMinimumHeight(460) # 進一步增加分割器最小高度 + feedback_splitter.setMaximumHeight(2000) # 允許更大的高度以觸發滾動 + + # 確保子控件的最小尺寸(防止過度壓縮) + self.feedback_input.setMinimumHeight(120) + image_upload_widget.setMinimumHeight(200) # 確保圖片區域的最小高度 + + splitter_wrapper_layout.addWidget(feedback_splitter) + + tab_layout.addWidget(splitter_wrapper, 1) + + # 設置分頁的大小策略,確保能夠觸發父容器的滾動條 + self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) + self.setMinimumHeight(500) # 設置最小高度 def get_feedback_text(self) -> str: """獲取回饋文字""" @@ -101,4 +164,9 @@ class FeedbackTab(QWidget): def handle_image_paste_from_textarea(self) -> None: """處理從文字框智能貼上圖片的功能""" - self.image_upload.paste_from_clipboard() \ No newline at end of file + self.image_upload.paste_from_clipboard() + + def _save_feedback_splitter_position(self, splitter: QSplitter) -> None: + """保存分割器的位置""" + sizes = splitter.sizes() + self.config_manager.set_splitter_sizes('feedback_splitter', sizes) \ No newline at end of file diff --git a/src/mcp_feedback_enhanced/gui/tabs/summary_tab.py b/src/mcp_feedback_enhanced/gui/tabs/summary_tab.py index e85c2af..25908ab 100644 --- a/src/mcp_feedback_enhanced/gui/tabs/summary_tab.py +++ b/src/mcp_feedback_enhanced/gui/tabs/summary_tab.py @@ -7,6 +7,7 @@ 專門顯示AI工作摘要的分頁組件。 """ +import json from PySide6.QtWidgets import QWidget, QVBoxLayout, QLabel, QTextEdit from ...i18n import t @@ -17,14 +18,37 @@ class SummaryTab(QWidget): def __init__(self, summary: str, parent=None): super().__init__(parent) - self.summary = summary + self.summary = self._process_summary(summary) self._setup_ui() + def _process_summary(self, summary: str) -> str: + """處理摘要內容,如果是JSON格式則提取實際內容""" + try: + # 嘗試解析JSON + if summary.strip().startswith('{') and summary.strip().endswith('}'): + json_data = json.loads(summary) + # 如果是JSON格式,提取summary字段的內容 + if isinstance(json_data, dict) and 'summary' in json_data: + return json_data['summary'] + # 如果JSON中沒有summary字段,返回原始內容 + return summary + else: + return summary + except (json.JSONDecodeError, TypeError): + # 如果不是有效的JSON,返回原始內容 + return summary + def _setup_ui(self) -> None: """設置用戶介面""" layout = QVBoxLayout(self) layout.setSpacing(12) - layout.setContentsMargins(16, 16, 16, 16) + layout.setContentsMargins(0, 16, 0, 0) # 只保留上邊距,移除左右和底部邊距 + + # 說明文字容器 + description_wrapper = QWidget() + description_layout = QVBoxLayout(description_wrapper) + description_layout.setContentsMargins(16, 0, 16, 0) # 只對說明文字設置左右邊距 + description_layout.setSpacing(0) # 說明文字 if self._is_test_summary(): @@ -34,7 +58,15 @@ class SummaryTab(QWidget): self.summary_description_label.setStyleSheet("color: #9e9e9e; font-size: 12px; margin-bottom: 10px;") self.summary_description_label.setWordWrap(True) - layout.addWidget(self.summary_description_label) + description_layout.addWidget(self.summary_description_label) + + layout.addWidget(description_wrapper) + + # 摘要顯示區域容器 + summary_wrapper = QWidget() + summary_layout = QVBoxLayout(summary_wrapper) + summary_layout.setContentsMargins(16, 0, 16, 0) # 只對摘要區域設置左右邊距 + summary_layout.setSpacing(0) # 摘要顯示區域 self.summary_display = QTextEdit() @@ -56,32 +88,37 @@ class SummaryTab(QWidget): line-height: 1.4; } """) - layout.addWidget(self.summary_display, 1) + summary_layout.addWidget(self.summary_display, 1) + + layout.addWidget(summary_wrapper, 1) def _is_test_summary(self) -> bool: """檢查是否為測試摘要""" - test_indicators = [ - # 繁體中文 - "圖片預覽和視窗調整測試", - "圖片預覽和窗口調整測試", - "這是一個測試會話", - "功能測試項目", + # 更精確的測試摘要檢測 - 必須包含特定的測試指標組合 + test_patterns = [ + # Qt GUI 測試特徵組合 - 必須同時包含多個特徵 + ("圖片預覽和視窗調整測試", "功能測試項目", "🎯"), + ("圖片預覽和窗口調整測試", "功能測試項目", "🎯"), + ("图片预览和窗口调整测试", "功能测试项目", "🎯"), + ("Image Preview and Window Adjustment Test", "Test Items", "🎯"), - # 簡體中文 - "图片预览和窗口调整测试", - "这是一个测试会话", - "功能测试项目", + # Web UI 測試特徵組合 + ("測試 Web UI 功能", "🎯 **功能測試項目", "WebSocket 即時通訊"), + ("测试 Web UI 功能", "🎯 **功能测试项目", "WebSocket 即时通讯"), + ("Test Web UI Functionality", "🎯 **Test Items", "WebSocket real-time communication"), - # 英文 - "Image Preview and Window Adjustment Test", - "This is a test session", - "Test Items", - - # 通用 - "測試", "测试", "test", "Test", - "🎯", "✅", "📋" # 測試摘要特有的 emoji + # 具體的測試步驟特徵 + ("智能 Ctrl+V 圖片貼上功能", "📋 測試步驟", "請測試這些功能並提供回饋"), + ("智能 Ctrl+V 图片粘贴功能", "📋 测试步骤", "请测试这些功能并提供回馈"), + ("Smart Ctrl+V image paste", "📋 Test Steps", "Please test these features"), ] - return any(indicator in self.summary for indicator in test_indicators) + + # 檢查是否匹配任何一個測試模式(必須同時包含模式中的所有關鍵詞) + for pattern in test_patterns: + if all(keyword in self.summary for keyword in pattern): + return True + + return False def update_texts(self) -> None: """更新界面文字(用於語言切換)""" diff --git a/src/mcp_feedback_enhanced/gui/widgets/image_upload.py b/src/mcp_feedback_enhanced/gui/widgets/image_upload.py index 1ccacd3..034a101 100644 --- a/src/mcp_feedback_enhanced/gui/widgets/image_upload.py +++ b/src/mcp_feedback_enhanced/gui/widgets/image_upload.py @@ -19,6 +19,7 @@ from PySide6.QtWidgets import ( ) from PySide6.QtCore import Qt, Signal from PySide6.QtGui import QFont, QDragEnterEvent, QDropEvent +from PySide6.QtWidgets import QSizePolicy # 導入多語系支援 from ...i18n import t @@ -42,7 +43,7 @@ class ImageUploadWidget(QWidget): """設置用戶介面""" layout = QVBoxLayout(self) layout.setSpacing(6) - layout.setContentsMargins(12, 8, 12, 8) + layout.setContentsMargins(0, 8, 0, 8) # 調整邊距使其與其他區域一致 # 標題 self.title = QLabel(t('images.title')) @@ -63,6 +64,9 @@ class ImageUploadWidget(QWidget): # 創建滾動區域 self.preview_scroll = QScrollArea() self.preview_widget = QWidget() + self.preview_widget.setMinimumHeight(140) # 設置預覽部件的最小高度 + # 設置尺寸策略,允許垂直擴展 + self.preview_widget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) self.preview_layout = QVBoxLayout(self.preview_widget) self.preview_layout.setSpacing(6) self.preview_layout.setContentsMargins(8, 8, 8, 8) @@ -73,7 +77,8 @@ class ImageUploadWidget(QWidget): # 創建拖拽提示標籤(初始顯示) self.drop_hint_label = QLabel(t('images.dragHint')) self.drop_hint_label.setAlignment(Qt.AlignCenter) - self.drop_hint_label.setMinimumHeight(60) + self.drop_hint_label.setMinimumHeight(80) # 增加最小高度 + self.drop_hint_label.setMaximumHeight(120) # 設置最大高度 self.drop_hint_label.setStyleSheet(""" QLabel { border: 2px dashed #464647; @@ -82,6 +87,7 @@ class ImageUploadWidget(QWidget): color: #9e9e9e; font-size: 11px; margin: 4px 0; + padding: 16px 8px; } """) @@ -101,17 +107,61 @@ class ImageUploadWidget(QWidget): # 設置滾動區域 self.preview_scroll.setWidget(self.preview_widget) - self.preview_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) + self.preview_scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) # 改回按需顯示滾動條 self.preview_scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) - self.preview_scroll.setMinimumHeight(120) # 增加最小高度以容納按鈕 - self.preview_scroll.setMaximumHeight(200) # 調整最大高度 + self.preview_scroll.setMinimumHeight(160) # 增加最小高度,確保有足夠空間 + self.preview_scroll.setMaximumHeight(300) # 增加最大高度 self.preview_scroll.setWidgetResizable(True) + + # 增強的滾動區域樣式,改善 macOS 兼容性 self.preview_scroll.setStyleSheet(""" QScrollArea { border: 1px solid #464647; border-radius: 4px; background-color: #1e1e1e; } + QScrollArea QScrollBar:vertical { + background-color: #2a2a2a; + width: 14px; + border-radius: 7px; + margin: 0; + } + QScrollArea QScrollBar::handle:vertical { + background-color: #555; + border-radius: 7px; + min-height: 30px; + margin: 2px; + } + QScrollArea QScrollBar::handle:vertical:hover { + background-color: #777; + } + QScrollArea QScrollBar::add-line:vertical, + QScrollArea QScrollBar::sub-line:vertical { + border: none; + background: none; + height: 0px; + } + QScrollArea QScrollBar:horizontal { + background-color: #2a2a2a; + height: 14px; + border-radius: 7px; + margin: 0; + } + QScrollArea QScrollBar::handle:horizontal { + background-color: #555; + border-radius: 7px; + min-width: 30px; + margin: 2px; + } + QScrollArea QScrollBar::handle:horizontal:hover { + background-color: #777; + } + QScrollArea QScrollBar::add-line:horizontal, + QScrollArea QScrollBar::sub-line:horizontal { + border: none; + background: none; + width: 0px; + } """) layout.addWidget(self.preview_scroll) @@ -358,6 +408,14 @@ class ImageUploadWidget(QWidget): row = i // 5 col = i % 5 self.images_grid_layout.addWidget(preview, row, col) + + # 強制更新佈局和滾動區域 + self.preview_widget.updateGeometry() + self.preview_scroll.updateGeometry() + + # 確保滾動區域能正確計算內容大小 + from PySide6.QtWidgets import QApplication + QApplication.processEvents() def _remove_image(self, image_id: str) -> None: """移除圖片""" diff --git a/src/mcp_feedback_enhanced/gui/window/config_manager.py b/src/mcp_feedback_enhanced/gui/window/config_manager.py index 981582b..772ebf6 100644 --- a/src/mcp_feedback_enhanced/gui/window/config_manager.py +++ b/src/mcp_feedback_enhanced/gui/window/config_manager.py @@ -76,4 +76,28 @@ class ConfigManager: def set_language(self, language: str) -> None: """設置語言""" self.set('language', language) - debug_log(f"語言設置: {language}") \ No newline at end of file + debug_log(f"語言設置: {language}") + + def get_splitter_sizes(self, splitter_name: str) -> list: + """獲取分割器尺寸""" + sizes = self.get(f'splitter_sizes.{splitter_name}', []) + if sizes: + debug_log(f"載入分割器 {splitter_name} 尺寸: {sizes}") + return sizes + + def set_splitter_sizes(self, splitter_name: str, sizes: list) -> None: + """設置分割器尺寸""" + self.set(f'splitter_sizes.{splitter_name}', sizes) + debug_log(f"保存分割器 {splitter_name} 尺寸: {sizes}") + + def get_window_geometry(self) -> dict: + """獲取窗口幾何信息""" + geometry = self.get('window_geometry', {}) + if geometry: + debug_log(f"載入窗口幾何信息: {geometry}") + return geometry + + def set_window_geometry(self, geometry: dict) -> None: + """設置窗口幾何信息""" + self.set('window_geometry', geometry) + debug_log(f"保存窗口幾何信息: {geometry}") \ No newline at end of file diff --git a/src/mcp_feedback_enhanced/gui/window/feedback_window.py b/src/mcp_feedback_enhanced/gui/window/feedback_window.py index fef79e6..00bd4ca 100644 --- a/src/mcp_feedback_enhanced/gui/window/feedback_window.py +++ b/src/mcp_feedback_enhanced/gui/window/feedback_window.py @@ -9,7 +9,7 @@ from PySide6.QtWidgets import ( QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QLabel, - QTabWidget, QPushButton, QMessageBox + QTabWidget, QPushButton, QMessageBox, QScrollArea, QSizePolicy ) from PySide6.QtCore import Signal, Qt from PySide6.QtGui import QKeySequence, QShortcut @@ -78,8 +78,69 @@ class FeedbackWindow(QMainWindow): def _create_tab_area(self, layout: QVBoxLayout) -> None: """創建分頁區域""" + # 創建滾動區域來包裝整個分頁組件 + scroll_area = QScrollArea() + scroll_area.setWidgetResizable(True) + scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) + scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) + scroll_area.setMinimumHeight(500) + scroll_area.setStyleSheet(""" + QScrollArea { + border: 1px solid #464647; + border-radius: 4px; + background-color: #2b2b2b; + } + QScrollArea > QWidget > QWidget { + background-color: #2b2b2b; + } + QScrollArea QScrollBar:vertical { + background-color: #2a2a2a; + width: 8px; + border-radius: 4px; + margin: 0; + } + QScrollArea QScrollBar::handle:vertical { + background-color: #555; + border-radius: 4px; + min-height: 20px; + margin: 1px; + } + QScrollArea QScrollBar::handle:vertical:hover { + background-color: #777; + } + QScrollArea QScrollBar::add-line:vertical, + QScrollArea QScrollBar::sub-line:vertical { + border: none; + background: none; + height: 0px; + } + QScrollArea QScrollBar:horizontal { + background-color: #2a2a2a; + height: 8px; + border-radius: 4px; + margin: 0; + } + QScrollArea QScrollBar::handle:horizontal { + background-color: #555; + border-radius: 4px; + min-width: 20px; + margin: 1px; + } + QScrollArea QScrollBar::handle:horizontal:hover { + background-color: #777; + } + QScrollArea QScrollBar::add-line:horizontal, + QScrollArea QScrollBar::sub-line:horizontal { + border: none; + background: none; + width: 0px; + } + """) + self.tab_widget = QTabWidget() self.tab_widget.setMinimumHeight(500) + # 設置分頁組件的大小策略,確保能觸發滾動 + self.tab_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # 初始化分頁管理器 self.tab_manager = TabManager( @@ -92,7 +153,10 @@ class FeedbackWindow(QMainWindow): # 創建分頁 self.tab_manager.create_tabs() - layout.addWidget(self.tab_widget, 1) + # 將分頁組件放入滾動區域 + scroll_area.setWidget(self.tab_widget) + + layout.addWidget(scroll_area, 1) def _create_action_buttons(self, layout: QVBoxLayout) -> None: """創建操作按鈕""" @@ -174,6 +238,7 @@ class FeedbackWindow(QMainWindow): QTabWidget::pane { border: 1px solid #464647; border-radius: 4px; + background-color: #2b2b2b; } QTabBar::tab { background-color: #2d2d30; @@ -185,6 +250,37 @@ class FeedbackWindow(QMainWindow): QTabBar::tab:selected { background-color: #007acc; } + QSplitter { + background-color: #2b2b2b; + } + QSplitter::handle { + background-color: #3c3c3c; + border: 1px solid #555555; + border-radius: 3px; + margin: 0px; + } + QSplitter::handle:horizontal { + width: 6px; + background-color: #3c3c3c; + border: 1px solid #555555; + border-radius: 3px; + margin: 0px; + } + QSplitter::handle:vertical { + height: 6px; + background-color: #3c3c3c; + border: 1px solid #555555; + border-radius: 3px; + margin: 0px; + } + QSplitter::handle:hover { + background-color: #606060; + border-color: #808080; + } + QSplitter::handle:pressed { + background-color: #007acc; + border-color: #005a9e; + } """) def _on_layout_mode_change_requested(self, combined_mode: bool) -> None: diff --git a/src/mcp_feedback_enhanced/gui/window/tab_manager.py b/src/mcp_feedback_enhanced/gui/window/tab_manager.py index 0b2a364..313d307 100644 --- a/src/mcp_feedback_enhanced/gui/window/tab_manager.py +++ b/src/mcp_feedback_enhanced/gui/window/tab_manager.py @@ -8,13 +8,14 @@ """ from typing import Dict, Any -from PySide6.QtWidgets import QTabWidget, QSplitter, QWidget, QVBoxLayout +from PySide6.QtWidgets import QTabWidget, QSplitter, QWidget, QVBoxLayout, QScrollArea, QSizePolicy from PySide6.QtCore import Signal, Qt from ..tabs import FeedbackTab, SummaryTab, CommandTab, SettingsTab from ..widgets import SmartTextEdit, ImageUploadWidget from ...i18n import t from ...debug import gui_debug_log as debug_log +from .config_manager import ConfigManager class TabManager: @@ -26,6 +27,9 @@ class TabManager: self.summary = summary self.combined_mode = combined_mode + # 配置管理器 + self.config_manager = ConfigManager() + # 分頁組件實例 self.feedback_tab = None self.summary_tab = None @@ -67,30 +71,99 @@ class TabManager: # 主布局 tab_layout = QVBoxLayout(self.combined_feedback_tab) tab_layout.setSpacing(12) - tab_layout.setContentsMargins(16, 16, 16, 16) + tab_layout.setContentsMargins(0, 0, 0, 0) # 設置邊距為0 + + # 創建分割器包裝容器 + splitter_wrapper = QWidget() + splitter_wrapper_layout = QVBoxLayout(splitter_wrapper) + splitter_wrapper_layout.setContentsMargins(16, 16, 16, 0) # 恢復左右邊距設置 + splitter_wrapper_layout.setSpacing(0) # 使用垂直分割器管理 AI摘要、回饋輸入和圖片區域 main_splitter = QSplitter(Qt.Vertical) main_splitter.setChildrenCollapsible(False) + main_splitter.setHandleWidth(6) + main_splitter.setContentsMargins(0, 0, 0, 0) # 設置分割器邊距為0 + + # 設置分割器wrapper樣式,確保分割器延伸到邊緣 + splitter_wrapper.setStyleSheet(""" + QWidget { + margin: 0px; + padding: 0px; + } + """) + + main_splitter.setStyleSheet(""" + QSplitter { + border: none; + background: transparent; + } + QSplitter::handle:vertical { + height: 8px; + background-color: #3c3c3c; + border: 1px solid #555555; + border-radius: 4px; + margin-left: 16px; + margin-right: 16px; + margin-top: 2px; + margin-bottom: 2px; + } + QSplitter::handle:vertical:hover { + background-color: #606060; + border-color: #808080; + } + QSplitter::handle:vertical:pressed { + background-color: #007acc; + border-color: #005a9e; + } + """) # 創建AI摘要組件 self.summary_tab = SummaryTab(self.summary) self.summary_tab.setMinimumHeight(150) - self.summary_tab.setMaximumHeight(300) + self.summary_tab.setMaximumHeight(1000) # 允許更大的拖拽範圍 # 創建回饋輸入組件 self.feedback_tab = FeedbackTab() + # 確保回饋分頁有足夠的最小高度來顯示圖片區域 + self.feedback_tab.setMinimumHeight(480) + self.feedback_tab.setMaximumHeight(2000) # 允許更大的拖拽範圍 # 添加到主分割器 main_splitter.addWidget(self.summary_tab) main_splitter.addWidget(self.feedback_tab) - # 設置分割器比例 (摘要:回饋 = 2:3) - main_splitter.setStretchFactor(0, 2) # AI摘要區域 - main_splitter.setStretchFactor(1, 3) # 回饋輸入區域(包含圖片) - main_splitter.setSizes([200, 400]) # 設置初始大小 + # 調整分割器比例和初始大小,確保圖片區域可見 + main_splitter.setStretchFactor(0, 1) # AI摘要區域 + main_splitter.setStretchFactor(1, 2) # 回饋輸入區域(包含圖片)- 給予更多空間 - tab_layout.addWidget(main_splitter, 1) + # 從配置載入分割器位置,如果沒有則使用預設值 + saved_sizes = self.config_manager.get_splitter_sizes('main_splitter') + if saved_sizes and len(saved_sizes) == 2: + main_splitter.setSizes(saved_sizes) + else: + main_splitter.setSizes([160, 480]) # 預設大小 + + # 連接分割器位置變化信號,自動保存位置 + main_splitter.splitterMoved.connect( + lambda pos, index: self._save_main_splitter_position(main_splitter) + ) + + # 設置主分割器的最小高度,確保圖片區域可見 + main_splitter.setMinimumHeight(660) # 進一步增加最小高度 + main_splitter.setMaximumHeight(3000) # 允許更大的高度以觸發滾動 + + splitter_wrapper_layout.addWidget(main_splitter) + + # 添加底部空間以保持完整的邊距 + bottom_spacer = QWidget() + bottom_spacer.setFixedHeight(16) + tab_layout.addWidget(splitter_wrapper, 1) + tab_layout.addWidget(bottom_spacer) + + # 設置合併分頁的大小策略,確保能夠觸發父容器的滾動條 + self.combined_feedback_tab.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) + self.combined_feedback_tab.setMinimumHeight(700) # 設置最小高度 def update_tab_texts(self) -> None: """更新分頁標籤文字""" @@ -183,4 +256,10 @@ class TabManager: """設置佈局模式""" self.combined_mode = combined_mode if self.settings_tab: - self.settings_tab.set_layout_mode(combined_mode) \ No newline at end of file + self.settings_tab.set_layout_mode(combined_mode) + + def _save_main_splitter_position(self, splitter: QSplitter) -> None: + """保存分割器位置""" + sizes = splitter.sizes() + self.config_manager.set_splitter_sizes('main_splitter', sizes) + debug_log(f"分割器位置保存成功,大小: {sizes}") \ No newline at end of file diff --git a/src/mcp_feedback_enhanced/locales/en/translations.json b/src/mcp_feedback_enhanced/locales/en/translations.json index c96829f..6320eb0 100644 --- a/src/mcp_feedback_enhanced/locales/en/translations.json +++ b/src/mcp_feedback_enhanced/locales/en/translations.json @@ -28,13 +28,17 @@ "description": "Please describe your thoughts, suggestions, or modifications needed for the AI's work.", "placeholder": "Please enter your feedback, suggestions, or questions here...\n\n💡 Tips:\n• Press Ctrl+Enter (numpad supported) to submit quickly\n• Press Ctrl+V to paste images from clipboard", "emptyTitle": "Feedback Content Empty", - "emptyMessage": "Please enter feedback content before submitting. You can describe your thoughts, suggestions, or areas that need modification." + "emptyMessage": "Please enter feedback content before submitting. You can describe your thoughts, suggestions, or areas that need modification.", + "outputPlaceholder": "Command output will appear here..." }, "command": { "title": "Command Execution", "description": "You can execute commands to verify results or gather more information.", "placeholder": "Enter command to execute...", - "output": "Command Output" + "output": "Command Output", + "outputPlaceholder": "Command output will appear here...", + "run": "▶️ Run", + "terminate": "⏹️ Stop" }, "images": { "title": "🖼️ Image Attachments (Optional)", diff --git a/src/mcp_feedback_enhanced/locales/zh-CN/translations.json b/src/mcp_feedback_enhanced/locales/zh-CN/translations.json index aeb0a41..10092c0 100644 --- a/src/mcp_feedback_enhanced/locales/zh-CN/translations.json +++ b/src/mcp_feedback_enhanced/locales/zh-CN/translations.json @@ -34,7 +34,10 @@ "title": "命令执行", "description": "您可以执行命令来验证结果或收集更多信息。", "placeholder": "输入要执行的命令...", - "output": "命令输出" + "output": "命令输出", + "outputPlaceholder": "命令输出将在这里显示...", + "run": "▶️ 执行", + "terminate": "⏹️ 停止" }, "images": { "title": "🖼️ 图片附件(可选)", diff --git a/src/mcp_feedback_enhanced/locales/zh-TW/translations.json b/src/mcp_feedback_enhanced/locales/zh-TW/translations.json index 89c216c..a7ae3a2 100644 --- a/src/mcp_feedback_enhanced/locales/zh-TW/translations.json +++ b/src/mcp_feedback_enhanced/locales/zh-TW/translations.json @@ -43,8 +43,8 @@ "placeholder": "輸入要執行的命令...", "output": "命令輸出", "outputPlaceholder": "命令輸出將顯示在這裡...", - "run": "執行", - "terminate": "終止" + "run": "▶️ 執行", + "terminate": "⏹️ 終止" }, "images": { "title": "🖼️ 圖片附件(可選)",