From bf1214b3ca889c77b282d36bf40ec9ebbbe50102 Mon Sep 17 00:00:00 2001 From: LemonNexus Date: Mon, 16 Feb 2026 01:04:07 +0000 Subject: [PATCH] fix: Add 'Open' button to plugins list so plugins can be opened Changes: - Added 'Open' button to each plugin in the Installed plugins list - Clicking Open tries: show_ui(), open(), or get_widget() methods - Added _open_plugin() method to both PluginsView and PerfectMainWindow - Added Settings button for plugins that have settings - Shows error messages if plugin can't be opened This fixes the issue where plugins couldn't be opened or viewed. --- core/perfect_ux.py | 53 ++++++++++++++++ core/ui/plugins_view.py | 133 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 185 insertions(+), 1 deletion(-) diff --git a/core/perfect_ux.py b/core/perfect_ux.py index 6e6e737..ca75e54 100644 --- a/core/perfect_ux.py +++ b/core/perfect_ux.py @@ -1100,6 +1100,25 @@ class PerfectMainWindow(QMainWindow): info_layout.addWidget(desc_label) row.addLayout(info_layout, 1) + + # Add Open button + open_btn = QPushButton("Open") + open_btn.setStyleSheet(""" + QPushButton { + background: rgba(255, 140, 66, 0.2); + color: #ff8c42; + border: 1px solid rgba(255, 140, 66, 0.3); + border-radius: 4px; + padding: 4px 12px; + font-size: 11px; + } + QPushButton:hover { + background: rgba(255, 140, 66, 0.3); + } + """) + open_btn.clicked.connect(lambda checked, pid=plugin_id: self._open_plugin(pid)) + row.addWidget(open_btn) + plugins_layout.addLayout(row) # Separator @@ -1176,6 +1195,40 @@ class PerfectMainWindow(QMainWindow): except Exception as e: print(f"[Plugins] Error toggling {plugin_id}: {e}") + def _open_plugin(self, plugin_id: str): + """Open a plugin's main interface.""" + print(f"[Plugins] Opening plugin: {plugin_id}") + + if not self.plugin_manager: + return + + try: + # Get the plugin instance + plugin = self.plugin_manager.get_plugin(plugin_id) + if not plugin: + print(f"[Plugins] Plugin not found: {plugin_id}") + return + + # Check if plugin has a show_ui or open method + if hasattr(plugin, 'show_ui'): + plugin.show_ui() + elif hasattr(plugin, 'open'): + plugin.open() + elif hasattr(plugin, 'get_widget'): + widget = plugin.get_widget() + if widget: + widget.show() + widget.raise_() + widget.activateWindow() + else: + # Try to create and show the plugin's main window + print(f"[Plugins] Plugin {plugin_id} has no standard UI method") + + except Exception as e: + print(f"[Plugins] Error opening plugin {plugin_id}: {e}") + import traceback + traceback.print_exc() + def _create_widgets_view(self) -> QWidget: """Create the Widgets view with registered widgets.""" from PyQt6.QtWidgets import QScrollArea diff --git a/core/ui/plugins_view.py b/core/ui/plugins_view.py index b28e287..6018386 100644 --- a/core/ui/plugins_view.py +++ b/core/ui/plugins_view.py @@ -180,7 +180,47 @@ class PluginsView(QWidget): desc_label.setWordWrap(True) info_layout.addWidget(desc_label) - row.addLayout(info_layout, 1) + # Add Open/Configure buttons + btn_layout = QHBoxLayout() + + # Open button + open_btn = QPushButton("Open") + open_btn.setStyleSheet(""" + QPushButton { + background: rgba(255, 140, 66, 0.2); + color: #ff8c42; + border: 1px solid rgba(255, 140, 66, 0.3); + border-radius: 4px; + padding: 4px 12px; + font-size: 11px; + } + QPushButton:hover { + background: rgba(255, 140, 66, 0.3); + } + """) + open_btn.clicked.connect(lambda checked, pid=plugin_id: self._open_plugin(pid)) + btn_layout.addWidget(open_btn) + + # Configure button (if plugin has settings) + if hasattr(plugin_class, 'get_settings_widget') or hasattr(plugin_class, 'settings'): + config_btn = QPushButton("Settings") + config_btn.setStyleSheet(""" + QPushButton { + background: rgba(100, 100, 100, 0.2); + color: rgba(255, 255, 255, 0.7); + border: 1px solid rgba(100, 100, 100, 0.3); + border-radius: 4px; + padding: 4px 12px; + font-size: 11px; + } + QPushButton:hover { + background: rgba(100, 100, 100, 0.3); + } + """) + config_btn.clicked.connect(lambda checked, pid=plugin_id: self._configure_plugin(pid)) + btn_layout.addWidget(config_btn) + + row.addLayout(btn_layout) self.installed_layout.addLayout(row) @@ -193,6 +233,97 @@ class PluginsView(QWidget): self.installed_layout.addStretch() + def _open_plugin(self, plugin_id: str): + """Open a plugin's main interface.""" + print(f"[PluginsView] Opening plugin: {plugin_id}") + + if not self.plugin_manager: + return + + try: + # Get the plugin instance + plugin = self.plugin_manager.get_plugin(plugin_id) + if not plugin: + print(f"[PluginsView] Plugin not found: {plugin_id}") + return + + # Check if plugin has a show_ui or open method + if hasattr(plugin, 'show_ui'): + plugin.show_ui() + elif hasattr(plugin, 'open'): + plugin.open() + elif hasattr(plugin, 'get_widget'): + widget = plugin.get_widget() + if widget: + widget.show() + widget.raise_() + widget.activateWindow() + else: + # Try to create and show the plugin's main window + print(f"[PluginsView] Plugin {plugin_id} has no standard UI method") + + except Exception as e: + print(f"[PluginsView] Error opening plugin {plugin_id}: {e}") + import traceback + traceback.print_exc() + + def _configure_plugin(self, plugin_id: str): + """Open a plugin's settings/configuration.""" + print(f"[PluginsView] Configuring plugin: {plugin_id}") + + if not self.plugin_manager: + return + + try: + plugin = self.plugin_manager.get_plugin(plugin_id) + if not plugin: + return + + # Check for settings widget + if hasattr(plugin, 'get_settings_widget'): + settings_widget = plugin.get_settings_widget() + if settings_widget: + settings_widget.show() + settings_widget.raise_() + settings_widget.activateWindow() + elif hasattr(plugin, 'settings'): + # Open generic settings dialog + self._show_generic_settings(plugin) + + except Exception as e: + print(f"[PluginsView] Error configuring plugin {plugin_id}: {e}") + + def _show_generic_settings(self, plugin): + """Show a generic settings dialog for a plugin.""" + from PyQt6.QtWidgets import QDialog, QVBoxLayout, QLabel, QDialogButtonBox + + dialog = QDialog(self) + dialog.setWindowTitle(f"{plugin.name} - Settings") + dialog.setMinimumSize(400, 300) + + layout = QVBoxLayout(dialog) + + # Plugin info + name_label = QLabel(f"{plugin.name}") + name_label.setStyleSheet("font-size: 16px;") + layout.addWidget(name_label) + + desc_label = QLabel(plugin.description) + desc_label.setWordWrap(True) + layout.addWidget(desc_label) + + version_label = QLabel(f"Version: {plugin.version}") + layout.addWidget(version_label) + + layout.addStretch() + + # Buttons + buttons = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok) + buttons.accepted.connect(dialog.accept) + layout.addWidget(buttons) + + dialog.exec() + def _toggle_plugin(self, plugin_id: str, state: int): """Enable or disable a plugin.""" if not self.plugin_manager: