EU-Utility/core/ui/plugins_view.py

243 lines
8.5 KiB
Python

"""
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