diff options
Diffstat (limited to 'ui/main_window.py')
| -rw-r--r-- | ui/main_window.py | 80 |
1 files changed, 79 insertions, 1 deletions
diff --git a/ui/main_window.py b/ui/main_window.py index 268a9d3..90294ac 100644 --- a/ui/main_window.py +++ b/ui/main_window.py @@ -45,7 +45,7 @@ from ui.windows.settings_window import SettingsWindow from plugins.plugin_manager import PluginManager from plugins.base_plugin import PluginContext -from core.app_settings import load_settings, save_settings +from core.app_settings import load_settings, save_settings, set_developer_mode _DARK_QSS = os.path.join(os.path.dirname(os.path.abspath(__file__)), "style_dark.qss") @@ -68,6 +68,7 @@ class MainWindow(QMainWindow): self._win_channels = None self._win_plot = None self._win_settings = None + self._win_debug = None _plugins_dir = os.path.join(os.path.dirname(os.path.dirname( os.path.abspath(__file__))), "plugins") @@ -171,6 +172,12 @@ class MainWindow(QMainWindow): set_btn.clicked.connect(lambda c: self._toggle_win("settings", c, set_btn)) tb.addWidget(set_btn); self._btn_settings = set_btn + debug_btn = QPushButton("🐞 Debug") + debug_btn.setObjectName("toolbarSectionBtn"); debug_btn.setCheckable(True) + debug_btn.clicked.connect(lambda c: self._toggle_win("debug", c, debug_btn)) + tb.addWidget(debug_btn); self._btn_debug = debug_btn + debug_btn.setVisible(False) # shown/hidden per developer-mode setting + # ── Central ─────────────────────────────────────────────────────── central = QWidget(); self.setCentralWidget(central) @@ -299,11 +306,60 @@ class MainWindow(QMainWindow): def plugin_enable(self, plugin_id: str): """Called by SettingsWindow when user enables a plugin.""" + missing = self._plugin_mgr.get_missing_dependencies(plugin_id) + if missing: + from PyQt6.QtWidgets import QMessageBox + reply = QMessageBox.question( + self, "Missing Plugin Dependencies", + f"This plugin needs packages that aren't installed:\n\n" + f" {', '.join(missing)}\n\n" + f"Install them now with pip?", + QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, + QMessageBox.StandardButton.No, + ) + if reply == QMessageBox.StandardButton.Yes: + if self._pip_install(missing): + self._enable_plugin_now(plugin_id) + else: + self._enable_plugin_now(plugin_id) + if self._win_settings: + self._win_settings.sync_plugin_button(plugin_id) + + def _enable_plugin_now(self, plugin_id: str): ctx = self._make_plugin_context() plugin = self._plugin_mgr.enable(plugin_id, ctx) if plugin: self._install_plugin(plugin) + def _pip_install(self, requirements: list) -> bool: + """Blocking `pip install` of the given requirement strings. + Returns True on success; shows a result dialog either way.""" + import subprocess + import sys + from PyQt6.QtWidgets import QMessageBox + + QApplication.setOverrideCursor(Qt.CursorShape.WaitCursor) + try: + result = subprocess.run( + [sys.executable, "-m", "pip", "install", *requirements], + capture_output=True, text=True, + ) + finally: + QApplication.restoreOverrideCursor() + + if result.returncode == 0: + QMessageBox.information( + self, "Install Complete", + f"Installed: {', '.join(requirements)}" + ) + return True + QMessageBox.critical( + self, "Install Failed", + f"pip install failed for: {', '.join(requirements)}\n\n" + f"{result.stderr.strip()[-1500:]}" + ) + return False + def plugin_disable(self, plugin_id: str): """Called by SettingsWindow when user disables a plugin.""" self._uninstall_plugin(plugin_id) @@ -317,12 +373,14 @@ class MainWindow(QMainWindow): "channels": self._open_channels, "plot": self._open_plot, "settings": self._open_settings, + "debug": self._open_debug, } wins = { "devices": "_win_devices", "channels": "_win_channels", "plot": "_win_plot", "settings": "_win_settings", + "debug": "_win_debug", } if checked: creators[name]() @@ -373,6 +431,22 @@ class MainWindow(QMainWindow): self._win_settings.closed.connect(lambda: self._btn_settings.setChecked(False)) self._show_win(self._win_settings, "right") + def _open_debug(self): + from ui.windows.debug_window import DebugWindow + if self._win_debug is None: + self._win_debug = DebugWindow(self) + self._win_debug.closed.connect(lambda: self._btn_debug.setChecked(False)) + self._show_win(self._win_debug, "right") + + def _update_debug_btn_visibility(self): + from core.app_settings import is_developer_mode + on = is_developer_mode() + self._btn_debug.setVisible(on) + if not on: + self._btn_debug.setChecked(False) + if self._win_debug: + self._win_debug.hide() + def _show_win(self, win: QWidget, position: str = "right"): if not win.isVisible(): screen = QApplication.screenAt(self.geometry().center()) @@ -570,10 +644,14 @@ class MainWindow(QMainWindow): def _apply_settings_on_startup(self): self._apply_theme(self._settings.get("theme", "dark")) self.engine._interval = self._settings.get("poll_ms", 100) / 1000.0 + set_developer_mode(self._settings.get("developer_mode", True)) + self._update_debug_btn_visibility() def _on_settings(self, cfg: dict): self._settings.update(cfg) self.engine._interval = cfg.get("poll_ms", 100) / 1000.0 + set_developer_mode(self._settings.get("developer_mode", True)) + self._update_debug_btn_visibility() save_settings(self._settings) def _tick(self): |
