mirror of
https://github.com/Minidoracat/mcp-feedback-enhanced.git
synced 2025-07-27 10:42:25 +08:00
✨ 新增視窗定位設置功能,允許用戶選擇總是在主螢幕中心顯示視窗,並更新相關界面及翻譯支持。
This commit is contained in:
parent
c3efd9662c
commit
50cfd67086
@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
|
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
|
||||||
QGroupBox, QComboBox, QRadioButton, QButtonGroup, QMessageBox
|
QGroupBox, QComboBox, QRadioButton, QButtonGroup, QMessageBox,
|
||||||
|
QCheckBox
|
||||||
)
|
)
|
||||||
from PySide6.QtCore import Signal
|
from PySide6.QtCore import Signal
|
||||||
|
|
||||||
@ -21,9 +22,10 @@ class SettingsTab(QWidget):
|
|||||||
language_changed = Signal()
|
language_changed = Signal()
|
||||||
layout_mode_change_requested = Signal(bool) # 佈局模式變更請求信號
|
layout_mode_change_requested = Signal(bool) # 佈局模式變更請求信號
|
||||||
|
|
||||||
def __init__(self, combined_mode: bool, parent=None):
|
def __init__(self, combined_mode: bool, config_manager, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.combined_mode = combined_mode
|
self.combined_mode = combined_mode
|
||||||
|
self.config_manager = config_manager
|
||||||
self.i18n = get_i18n_manager()
|
self.i18n = get_i18n_manager()
|
||||||
self._setup_ui()
|
self._setup_ui()
|
||||||
|
|
||||||
@ -136,6 +138,27 @@ class SettingsTab(QWidget):
|
|||||||
self.layout_button_group.buttonToggled.connect(self._on_layout_mode_changed)
|
self.layout_button_group.buttonToggled.connect(self._on_layout_mode_changed)
|
||||||
|
|
||||||
layout.addWidget(self.layout_group)
|
layout.addWidget(self.layout_group)
|
||||||
|
|
||||||
|
# === 視窗定位設置區域 ===
|
||||||
|
self.window_group = QGroupBox(t('settings.window.title'))
|
||||||
|
self.window_group.setObjectName('window_group')
|
||||||
|
window_layout = QVBoxLayout(self.window_group)
|
||||||
|
window_layout.setSpacing(12)
|
||||||
|
window_layout.setContentsMargins(16, 16, 16, 16)
|
||||||
|
|
||||||
|
# 總是在主螢幕中心顯示視窗選項
|
||||||
|
self.always_center_checkbox = QCheckBox(t('settings.window.alwaysCenter'))
|
||||||
|
self.always_center_checkbox.setChecked(self.config_manager.get_always_center_window())
|
||||||
|
self.always_center_checkbox.setStyleSheet("font-size: 14px; font-weight: bold; color: #e0e0e0;")
|
||||||
|
self.always_center_checkbox.stateChanged.connect(self._on_always_center_changed)
|
||||||
|
window_layout.addWidget(self.always_center_checkbox)
|
||||||
|
|
||||||
|
self.center_desc_label = QLabel(t('settings.window.alwaysCenterDescription'))
|
||||||
|
self.center_desc_label.setStyleSheet("color: #9e9e9e; font-size: 12px; margin-left: 20px; margin-bottom: 8px;")
|
||||||
|
self.center_desc_label.setWordWrap(True)
|
||||||
|
window_layout.addWidget(self.center_desc_label)
|
||||||
|
|
||||||
|
layout.addWidget(self.window_group)
|
||||||
layout.addStretch()
|
layout.addStretch()
|
||||||
|
|
||||||
def _populate_language_selector(self) -> None:
|
def _populate_language_selector(self) -> None:
|
||||||
@ -200,11 +223,17 @@ class SettingsTab(QWidget):
|
|||||||
else:
|
else:
|
||||||
self.separate_mode_radio.setChecked(True)
|
self.separate_mode_radio.setChecked(True)
|
||||||
|
|
||||||
|
def _on_always_center_changed(self, state: int) -> None:
|
||||||
|
"""處理視窗定位設置變更"""
|
||||||
|
always_center = state == 2 # Qt.Checked = 2
|
||||||
|
self.config_manager.set_always_center_window(always_center)
|
||||||
|
|
||||||
def update_texts(self) -> None:
|
def update_texts(self) -> None:
|
||||||
"""更新界面文字(用於語言切換)"""
|
"""更新界面文字(用於語言切換)"""
|
||||||
# 更新GroupBox標題
|
# 更新GroupBox標題
|
||||||
self.language_group.setTitle(t('settings.language.title'))
|
self.language_group.setTitle(t('settings.language.title'))
|
||||||
self.layout_group.setTitle(t('settings.layout.title'))
|
self.layout_group.setTitle(t('settings.layout.title'))
|
||||||
|
self.window_group.setTitle(t('settings.window.title'))
|
||||||
|
|
||||||
# 更新標籤文字
|
# 更新標籤文字
|
||||||
self.language_label.setText(t('settings.language.selector'))
|
self.language_label.setText(t('settings.language.selector'))
|
||||||
@ -218,8 +247,15 @@ class SettingsTab(QWidget):
|
|||||||
self.separate_desc_label.setText(t('settings.layout.separateModeDescription'))
|
self.separate_desc_label.setText(t('settings.layout.separateModeDescription'))
|
||||||
self.combined_desc_label.setText(t('settings.layout.combinedModeDescription'))
|
self.combined_desc_label.setText(t('settings.layout.combinedModeDescription'))
|
||||||
|
|
||||||
|
# 更新視窗設置文字
|
||||||
|
self.always_center_checkbox.setText(t('settings.window.alwaysCenter'))
|
||||||
|
self.center_desc_label.setText(t('settings.window.alwaysCenterDescription'))
|
||||||
|
|
||||||
# 重新填充語言選擇器
|
# 重新填充語言選擇器
|
||||||
self._populate_language_selector()
|
self._populate_language_selector()
|
||||||
|
|
||||||
|
# 重新設置勾選狀態,確保設置被正確保持
|
||||||
|
self.always_center_checkbox.setChecked(self.config_manager.get_always_center_window())
|
||||||
|
|
||||||
def set_layout_mode(self, combined_mode: bool) -> None:
|
def set_layout_mode(self, combined_mode: bool) -> None:
|
||||||
"""設置佈局模式"""
|
"""設置佈局模式"""
|
||||||
|
@ -100,4 +100,13 @@ class ConfigManager:
|
|||||||
def set_window_geometry(self, geometry: dict) -> None:
|
def set_window_geometry(self, geometry: dict) -> None:
|
||||||
"""設置窗口幾何信息"""
|
"""設置窗口幾何信息"""
|
||||||
self.set('window_geometry', geometry)
|
self.set('window_geometry', geometry)
|
||||||
debug_log(f"保存窗口幾何信息: {geometry}")
|
debug_log(f"保存窗口幾何信息: {geometry}")
|
||||||
|
|
||||||
|
def get_always_center_window(self) -> bool:
|
||||||
|
"""獲取總是在主螢幕中心顯示視窗的設置"""
|
||||||
|
return self.get('always_center_window', False)
|
||||||
|
|
||||||
|
def set_always_center_window(self, always_center: bool) -> None:
|
||||||
|
"""設置總是在主螢幕中心顯示視窗"""
|
||||||
|
self.set('always_center_window', always_center)
|
||||||
|
debug_log(f"視窗定位設置: {'總是中心顯示' if always_center else '智能定位'}")
|
@ -49,6 +49,9 @@ class FeedbackWindow(QMainWindow):
|
|||||||
self.setMinimumSize(1000, 800)
|
self.setMinimumSize(1000, 800)
|
||||||
self.resize(1200, 900)
|
self.resize(1200, 900)
|
||||||
|
|
||||||
|
# 智能視窗定位
|
||||||
|
self._apply_window_positioning()
|
||||||
|
|
||||||
# 中央元件
|
# 中央元件
|
||||||
central_widget = QWidget()
|
central_widget = QWidget()
|
||||||
self.setCentralWidget(central_widget)
|
self.setCentralWidget(central_widget)
|
||||||
@ -359,8 +362,80 @@ class FeedbackWindow(QMainWindow):
|
|||||||
# 更新分頁文字
|
# 更新分頁文字
|
||||||
self.tab_manager.update_tab_texts()
|
self.tab_manager.update_tab_texts()
|
||||||
|
|
||||||
|
def _apply_window_positioning(self) -> None:
|
||||||
|
"""根據用戶設置應用視窗定位策略"""
|
||||||
|
always_center = self.config_manager.get_always_center_window()
|
||||||
|
|
||||||
|
if always_center:
|
||||||
|
# 強制在主螢幕中心顯示
|
||||||
|
self._move_to_primary_screen_center()
|
||||||
|
else:
|
||||||
|
# 先嘗試恢復上次位置
|
||||||
|
if self._restore_last_position():
|
||||||
|
# 檢查恢復的位置是否可見
|
||||||
|
if not self._is_window_visible():
|
||||||
|
self._move_to_primary_screen_center()
|
||||||
|
else:
|
||||||
|
# 沒有保存的位置,移到中心
|
||||||
|
self._move_to_primary_screen_center()
|
||||||
|
|
||||||
|
def _is_window_visible(self) -> bool:
|
||||||
|
"""檢查視窗是否在任何螢幕的可見範圍內"""
|
||||||
|
from PySide6.QtWidgets import QApplication
|
||||||
|
|
||||||
|
window_rect = self.frameGeometry()
|
||||||
|
|
||||||
|
for screen in QApplication.screens():
|
||||||
|
if screen.availableGeometry().intersects(window_rect):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _move_to_primary_screen_center(self) -> None:
|
||||||
|
"""將視窗移到主螢幕中心"""
|
||||||
|
from PySide6.QtWidgets import QApplication
|
||||||
|
|
||||||
|
screen = QApplication.primaryScreen()
|
||||||
|
if screen:
|
||||||
|
screen_geometry = screen.availableGeometry()
|
||||||
|
window_geometry = self.frameGeometry()
|
||||||
|
center_point = screen_geometry.center()
|
||||||
|
window_geometry.moveCenter(center_point)
|
||||||
|
self.move(window_geometry.topLeft())
|
||||||
|
debug_log("視窗已移到主螢幕中心")
|
||||||
|
|
||||||
|
def _restore_last_position(self) -> bool:
|
||||||
|
"""嘗試恢復上次保存的視窗位置"""
|
||||||
|
try:
|
||||||
|
geometry = self.config_manager.get_window_geometry()
|
||||||
|
if geometry and 'x' in geometry and 'y' in geometry and 'width' in geometry and 'height' in geometry:
|
||||||
|
self.move(geometry['x'], geometry['y'])
|
||||||
|
self.resize(geometry['width'], geometry['height'])
|
||||||
|
debug_log(f"已恢復視窗位置: ({geometry['x']}, {geometry['y']}) 大小: {geometry['width']}x{geometry['height']}")
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
debug_log(f"恢復視窗位置失敗: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _save_window_position(self) -> None:
|
||||||
|
"""保存當前視窗位置"""
|
||||||
|
try:
|
||||||
|
geometry = {
|
||||||
|
'x': self.x(),
|
||||||
|
'y': self.y(),
|
||||||
|
'width': self.width(),
|
||||||
|
'height': self.height()
|
||||||
|
}
|
||||||
|
self.config_manager.set_window_geometry(geometry)
|
||||||
|
debug_log(f"已保存視窗位置: ({geometry['x']}, {geometry['y']}) 大小: {geometry['width']}x{geometry['height']}")
|
||||||
|
except Exception as e:
|
||||||
|
debug_log(f"保存視窗位置失敗: {e}")
|
||||||
|
|
||||||
def closeEvent(self, event) -> None:
|
def closeEvent(self, event) -> None:
|
||||||
"""窗口關閉事件"""
|
"""窗口關閉事件"""
|
||||||
|
# 保存視窗位置(除非設置為總是中心顯示)
|
||||||
|
if not self.config_manager.get_always_center_window():
|
||||||
|
self._save_window_position()
|
||||||
|
|
||||||
# 清理分頁管理器
|
# 清理分頁管理器
|
||||||
self.tab_manager.cleanup()
|
self.tab_manager.cleanup()
|
||||||
event.accept()
|
event.accept()
|
||||||
|
@ -60,7 +60,7 @@ class TabManager:
|
|||||||
self.tab_widget.addTab(self.command_tab, t('tabs.command'))
|
self.tab_widget.addTab(self.command_tab, t('tabs.command'))
|
||||||
|
|
||||||
# 設置分頁
|
# 設置分頁
|
||||||
self.settings_tab = SettingsTab(self.combined_mode)
|
self.settings_tab = SettingsTab(self.combined_mode, self.config_manager)
|
||||||
self.tab_widget.addTab(self.settings_tab, t('tabs.language'))
|
self.tab_widget.addTab(self.settings_tab, t('tabs.language'))
|
||||||
|
|
||||||
# 關於分頁
|
# 關於分頁
|
||||||
|
@ -91,6 +91,11 @@
|
|||||||
"combinedModeDescription": "Display AI summary and feedback on the same page for easy comparison",
|
"combinedModeDescription": "Display AI summary and feedback on the same page for easy comparison",
|
||||||
"separateMode": "Separate Mode",
|
"separateMode": "Separate Mode",
|
||||||
"separateModeDescription": "AI summary and feedback are in separate tabs"
|
"separateModeDescription": "AI summary and feedback are in separate tabs"
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"title": "Window Positioning",
|
||||||
|
"alwaysCenter": "Always show window at primary screen center",
|
||||||
|
"alwaysCenterDescription": "Recommended for multi-monitor setups or when experiencing window positioning issues"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
|
@ -71,6 +71,11 @@
|
|||||||
"combinedModeDescription": "将 AI 摘要和反馈放在同一页面,便于对照阅读",
|
"combinedModeDescription": "将 AI 摘要和反馈放在同一页面,便于对照阅读",
|
||||||
"separateMode": "分离模式",
|
"separateMode": "分离模式",
|
||||||
"separateModeDescription": "AI 摘要和反馈分别在不同页签"
|
"separateModeDescription": "AI 摘要和反馈分别在不同页签"
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"title": "窗口定位",
|
||||||
|
"alwaysCenter": "总是在主屏幕中心显示窗口",
|
||||||
|
"alwaysCenterDescription": "建议在多屏幕环境或遇到窗口定位问题时开启此选项"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
|
@ -92,6 +92,11 @@
|
|||||||
"combinedModeDescription": "將 AI 摘要和回饋放在同一頁面,便於對照閱讀",
|
"combinedModeDescription": "將 AI 摘要和回饋放在同一頁面,便於對照閱讀",
|
||||||
"separateMode": "分離模式",
|
"separateMode": "分離模式",
|
||||||
"separateModeDescription": "AI 摘要和回饋分別在不同頁籤"
|
"separateModeDescription": "AI 摘要和回饋分別在不同頁籤"
|
||||||
|
},
|
||||||
|
"window": {
|
||||||
|
"title": "視窗定位",
|
||||||
|
"alwaysCenter": "總是在主螢幕中心顯示視窗",
|
||||||
|
"alwaysCenterDescription": "建議在多螢幕環境或遇到視窗定位問題時開啟此選項"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"buttons": {
|
"buttons": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user