diff options
| author | Christian Kolset <ckolset@colostate.edu> | 2026-07-29 14:21:40 -0600 |
|---|---|---|
| committer | Christian Kolset <ckolset@colostate.edu> | 2026-07-29 14:21:40 -0600 |
| commit | c98885f503a8a2eb4b691b41404231da8d2aeda5 (patch) | |
| tree | c48e40b1357e2857a98b4b28293aca643b688bb6 /ui/main_window.py | |
| parent | 1d66acf29dd88acce5f3f7c5fee0c305147173a2 (diff) | |
| parent | 2298f779fdf7d828c1a84ca933b4eee9e8103212 (diff) | |
Merge branch 'feat/plugin-pip-install-prompt'
Diffstat (limited to 'ui/main_window.py')
| -rw-r--r-- | ui/main_window.py | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/ui/main_window.py b/ui/main_window.py index ca4274c..d585a83 100644 --- a/ui/main_window.py +++ b/ui/main_window.py @@ -303,11 +303,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) |
