""" EU-Utility - Plugins View (Core Framework Component) Built-in plugins interface with Installed and Store tabs. """ from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QCheckBox, QTabWidget, QFrame, QScrollArea, QGridLayout, QSizePolicy ) from PyQt6.QtCore import Qt from core.icon_manager import get_icon_manager class PluginsView(QWidget): """Main plugins interface - built into the framework. Features: - Installed tab: Manage installed plugins (enable/disable) - Store tab: Browse and install new plugins """ def __init__(self, overlay_window, parent=None): super().__init__(parent) self.overlay = overlay_window self.plugin_manager = overlay_window.plugin_manager if hasattr(overlay_window, 'plugin_manager') else None self.icon_manager = get_icon_manager() self._setup_ui() def _setup_ui(self): """Create the plugins UI.""" layout = QVBoxLayout(self) layout.setSpacing(16) layout.setContentsMargins(24, 24, 24, 24) # Header with icon header_layout = QHBoxLayout() header_layout.setSpacing(12) header_icon = QLabel() header_pixmap = self.icon_manager.get_pixmap("plugins", size=28) header_icon.setPixmap(header_pixmap) header_layout.addWidget(header_icon) header = QLabel("Plugins") header.setStyleSheet("font-size: 24px; font-weight: bold; color: white;") header_layout.addWidget(header) header_layout.addStretch() layout.addLayout(header_layout) # Tabs - Installed and Store self.tabs = QTabWidget() self.tabs.setStyleSheet(""" QTabBar::tab { background-color: rgba(20, 31, 35, 0.95); color: rgba(255,255,255,150); padding: 10px 20px; border-top-left-radius: 6px; border-top-right-radius: 6px; } QTabBar::tab:selected { background-color: #ff8c42; color: white; font-weight: bold; } """) # Add tabs self.tabs.addTab(self._create_installed_tab(), "Installed") self.tabs.addTab(self._create_store_tab(), "Store") layout.addWidget(self.tabs) def _create_installed_tab(self): """Create installed plugins tab.""" tab = QWidget() layout = QVBoxLayout(tab) layout.setSpacing(16) # Info label info = QLabel("Manage your installed plugins. Enable or disable as needed.") info.setStyleSheet("color: rgba(255,255,255,150); font-size: 13px;") info.setWordWrap(True) layout.addWidget(info) # Scroll area for plugin list scroll = QScrollArea() scroll.setWidgetResizable(True) scroll.setStyleSheet("background: transparent; border: none;") scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff) self.installed_container = QWidget() self.installed_layout = QVBoxLayout(self.installed_container) self.installed_layout.setAlignment(Qt.AlignmentFlag.AlignTop) self.installed_layout.setSpacing(8) self._populate_installed_plugins() scroll.setWidget(self.installed_container) layout.addWidget(scroll) return tab def _populate_installed_plugins(self): """Populate the installed plugins list.""" # Clear existing while self.installed_layout.count(): item = self.installed_layout.takeAt(0) if item.widget(): item.widget().deleteLater() if not self.plugin_manager: error = QLabel("Plugin Manager not available") error.setStyleSheet("color: #ff4757;") self.installed_layout.addWidget(error) return # Get discovered plugins try: all_plugins = self.plugin_manager.get_all_discovered_plugins() except AttributeError: # Fallback - try different method try: all_plugins = {p.plugin_id: p for p in self.plugin_manager.plugins.values()} except: all_plugins = {} if not all_plugins: no_plugins = QLabel("No plugins installed.\n\nVisit the Store tab to install plugins.") no_plugins.setStyleSheet("color: rgba(255,255,255,100); padding: 40px;") no_plugins.setAlignment(Qt.AlignmentFlag.AlignCenter) self.installed_layout.addWidget(no_plugins) return # Sort by name sorted_plugins = sorted(all_plugins.items(), key=lambda x: x[1].name if hasattr(x[1], 'name') else str(x[0])) for plugin_id, plugin_class in sorted_plugins: row = QHBoxLayout() row.setSpacing(12) # Enable/Disable checkbox cb = QCheckBox() try: is_enabled = self.plugin_manager.is_plugin_enabled(plugin_id) except: is_enabled = True cb.setChecked(is_enabled) cb.stateChanged.connect(lambda state, pid=plugin_id: self._toggle_plugin(pid, state)) row.addWidget(cb) # Plugin info info_layout = QVBoxLayout() info_layout.setSpacing(2) name_layout = QHBoxLayout() # Name name = QLabel(getattr(plugin_class, 'name', str(plugin_id))) name.setStyleSheet("color: white; font-size: 14px; font-weight: 500;") name_layout.addWidget(name) # Version version = getattr(plugin_class, 'version', '?.?.?') version_label = QLabel(f"v{version}") version_label.setStyleSheet("color: rgba(255,255,255,100); font-size: 11px;") name_layout.addWidget(version_label) name_layout.addStretch() info_layout.addLayout(name_layout) # Description desc = getattr(plugin_class, 'description', 'No description available') desc_label = QLabel(desc) desc_label.setStyleSheet("color: rgba(255,255,255,120); font-size: 12px;") desc_label.setWordWrap(True) info_layout.addWidget(desc_label) row.addLayout(info_layout, 1) self.installed_layout.addLayout(row) # Separator sep = QFrame() sep.setFrameShape(QFrame.Shape.HLine) sep.setStyleSheet("background-color: rgba(255, 140, 66, 0.1);") sep.setFixedHeight(1) self.installed_layout.addWidget(sep) self.installed_layout.addStretch() def _toggle_plugin(self, plugin_id: str, state: int): """Enable or disable a plugin.""" if not self.plugin_manager: return try: if state == Qt.CheckState.Checked.value: self.plugin_manager.enable_plugin(plugin_id) print(f"[PluginsView] Enabled plugin: {plugin_id}") else: self.plugin_manager.disable_plugin(plugin_id) print(f"[PluginsView] Disabled plugin: {plugin_id}") except Exception as e: print(f"[PluginsView] Error toggling plugin {plugin_id}: {e}") def _create_store_tab(self): """Create plugin store tab.""" try: from core.plugin_store import PluginStoreUI if self.plugin_manager: return PluginStoreUI(self.plugin_manager) except ImportError: pass # Fallback tab = QWidget() layout = QVBoxLayout(tab) info = QLabel("Plugin Store") info.setStyleSheet("font-size: 18px; font-weight: bold; color: white;") layout.addWidget(info) desc = QLabel("Browse and install plugins from the community repository.") desc.setStyleSheet("color: rgba(255,255,255,150);") desc.setWordWrap(True) layout.addWidget(desc) # Placeholder placeholder = QLabel("Plugin Store interface will appear here.") placeholder.setStyleSheet("color: rgba(255,255,255,100); padding: 40px;") placeholder.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.addWidget(placeholder) layout.addStretch() return tab