class ImplementationListItem(QFrame): """A Widget to render each hook implementation item in a ListWidget. Parameters ---------- item : QListWidgetItem An item instance from a QListWidget. This will most likely come from :meth:`QtHookImplementationListWidget.add_hook_implementation_to_list`. parent : QWidget, optional The parent widget, by default None Attributes ---------- plugin_name_label : QLabel The name of the plugin providing the hook implementation. enabled_checkbox : QCheckBox Checkbox to set the ``enabled`` status of the corresponding hook implementation. opacity : QGraphicsOpacityEffect The opacity of the whole widget. When self.enabled_checkbox is unchecked, the opacity of the item is decreased. """ on_changed = Signal() # when user changes whether plugin is enabled. def __init__(self, item: QListWidgetItem, parent: QWidget = None): super().__init__(parent) self.item = item self.opacity = QGraphicsOpacityEffect(self) self.setGraphicsEffect(self.opacity) layout = QHBoxLayout() self.setLayout(layout) self.position_label = QLabel() self.update_position_label() self.setToolTip(trans._("Click and drag to change call order")) self.plugin_name_label = QElidingLabel() self.plugin_name_label.setObjectName('small_text') self.plugin_name_label.setText(item.hook_implementation.plugin_name) plugin_name_size_policy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred) plugin_name_size_policy.setHorizontalStretch(2) self.plugin_name_label.setSizePolicy(plugin_name_size_policy) self.function_name_label = QLabel( item.hook_implementation.function.__name__) self.enabled_checkbox = QCheckBox(self) self.enabled_checkbox.setToolTip( trans._("Uncheck to disable this plugin")) self.enabled_checkbox.stateChanged.connect(self._set_enabled) self.enabled_checkbox.setChecked( getattr(item.hook_implementation, 'enabled', True)) layout.addWidget(self.position_label) layout.addWidget(self.enabled_checkbox) layout.addWidget(self.function_name_label) layout.addWidget(self.plugin_name_label) layout.setStretch(2, 1) layout.setContentsMargins(0, 0, 0, 0) def _set_enabled(self, state: Union[bool, int]): """Set the enabled state of this hook implementation to ``state``.""" self.item.hook_implementation.enabled = bool(state) self.opacity.setOpacity(1 if state else 0.5) self.on_changed.emit() def update_position_label(self, order=None): """Update the label showing the position of this item in the list. Parameters ---------- order : list, optional A HookOrderType list ... unused by this function, but here for ease of signal connection, by default None. """ position = self.item.listWidget().indexFromItem(self.item).row() + 1 self.position_label.setText(str(position))
class PluginListItem(QFrame): def __init__( self, package_name: str, version: str = '', url: str = '', summary: str = '', author: str = '', license: str = "UNKNOWN", *, plugin_name: str = None, parent: QWidget = None, enabled: bool = True, installed: bool = False, npe_version=1, ): super().__init__(parent) self.setup_ui(enabled) self.plugin_name.setText(package_name) self.package_name.setText(version) self.summary.setText(summary) self.package_author.setText(author) self.cancel_btn.setVisible(False) self.help_button.setText(trans._("Website")) self.help_button.setObjectName("help_button") if npe_version != 1: self._handle_npe2_plugin() if installed: self.enabled_checkbox.show() self.action_button.setText(trans._("uninstall")) self.action_button.setObjectName("remove_button") else: self.enabled_checkbox.hide() self.action_button.setText(trans._("install")) self.action_button.setObjectName("install_button") def _handle_npe2_plugin(self): npe2_icon = QLabel(self) icon = QColoredSVGIcon.from_resources('logo_silhouette') npe2_icon.setPixmap(icon.colored(color='#33F0FF').pixmap(20, 20)) self.row1.insertWidget(2, QLabel('npe2')) self.row1.insertWidget(2, npe2_icon) def _get_dialog(self) -> QDialog: p = self.parent() while not isinstance(p, QDialog) and p.parent(): p = p.parent() return p def set_busy(self, text: str, update: bool = False): self.item_status.setText(text) self.cancel_btn.setVisible(True) if not update: self.action_button.setVisible(False) else: self.update_btn.setVisible(False) def setup_ui(self, enabled=True): self.v_lay = QVBoxLayout(self) self.v_lay.setContentsMargins(-1, 6, -1, 6) self.v_lay.setSpacing(0) self.row1 = QHBoxLayout() self.row1.setSpacing(6) self.enabled_checkbox = QCheckBox(self) self.enabled_checkbox.setChecked(enabled) self.enabled_checkbox.stateChanged.connect(self._on_enabled_checkbox) self.enabled_checkbox.setToolTip(trans._("enable/disable")) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.enabled_checkbox.sizePolicy().hasHeightForWidth()) self.enabled_checkbox.setSizePolicy(sizePolicy) self.enabled_checkbox.setMinimumSize(QSize(20, 0)) self.enabled_checkbox.setText("") self.row1.addWidget(self.enabled_checkbox) self.plugin_name = QLabel(self) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.plugin_name.sizePolicy().hasHeightForWidth()) self.plugin_name.setSizePolicy(sizePolicy) font15 = QFont() font15.setPointSize(15) self.plugin_name.setFont(font15) self.row1.addWidget(self.plugin_name) icon = QColoredSVGIcon.from_resources("warning") self.warning_tooltip = QtToolTipLabel(self) # TODO: This color should come from the theme but the theme needs # to provide the right color. Default warning should be orange, not # red. Code example: # theme_name = get_settings().appearance.theme # napari.utils.theme.get_theme(theme_name, as_dict=False).warning.as_hex() self.warning_tooltip.setPixmap( icon.colored(color="#E3B617").pixmap(15, 15)) self.warning_tooltip.setVisible(False) self.row1.addWidget(self.warning_tooltip) self.item_status = QLabel(self) self.item_status.setObjectName("small_italic_text") self.item_status.setSizePolicy(sizePolicy) self.row1.addWidget(self.item_status) self.row1.addStretch() self.package_name = QLabel(self) self.package_name.setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter) self.row1.addWidget(self.package_name) self.cancel_btn = QPushButton("cancel", self) self.cancel_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.cancel_btn.setObjectName("remove_button") self.row1.addWidget(self.cancel_btn) self.update_btn = QPushButton(self) self.update_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.update_btn.setObjectName("install_button") self.row1.addWidget(self.update_btn) self.update_btn.setVisible(False) self.help_button = QPushButton(self) self.action_button = QPushButton(self) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.action_button.sizePolicy().hasHeightForWidth()) self.help_button.setSizePolicy(sizePolicy) self.action_button.setSizePolicy(sizePolicy) self.row1.addWidget(self.help_button) self.row1.addWidget(self.action_button) self.v_lay.addLayout(self.row1) self.row2 = QHBoxLayout() self.error_indicator = QPushButton() self.error_indicator.setObjectName("warning_icon") self.error_indicator.setCursor(Qt.PointingHandCursor) self.error_indicator.hide() self.row2.addWidget(self.error_indicator) self.row2.setContentsMargins(-1, 4, 0, -1) self.summary = QElidingLabel(parent=self) sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.summary.sizePolicy().hasHeightForWidth()) self.summary.setSizePolicy(sizePolicy) self.summary.setObjectName("small_text") self.row2.addWidget(self.summary) self.package_author = QLabel(self) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.package_author.sizePolicy().hasHeightForWidth()) self.package_author.setSizePolicy(sizePolicy) self.package_author.setObjectName("small_text") self.row2.addWidget(self.package_author) self.v_lay.addLayout(self.row2) def _on_enabled_checkbox(self, state: int): """Called with `state` when checkbox is clicked.""" enabled = bool(state) plugin_name = self.plugin_name.text() pm2 = PluginManager.instance() if plugin_name in pm2: pm2.enable(plugin_name) if state else pm2.disable(plugin_name) return for npe1_name, _, distname in plugin_manager.iter_available(): if distname and (distname == plugin_name): plugin_manager.set_blocked(npe1_name, not enabled) def show_warning(self, message: str = ""): """Show warning icon and tooltip.""" self.warning_tooltip.setVisible(bool(message)) self.warning_tooltip.setToolTip(message)
class PluginListItem(QFrame): def __init__( self, package_name: str, version: str = '', url: str = '', summary: str = '', author: str = '', license: str = "UNKNOWN", *, plugin_name: str = None, parent: QWidget = None, enabled: bool = True, installed: bool = False, npe_version=1, ): super().__init__(parent) self.setup_ui(enabled) self.plugin_name.setText(package_name) self.package_name.setText(version) self.summary.setText(summary) self.package_author.setText(author) self.cancel_btn.setVisible(False) self.help_button.setText(trans._("Website")) self.help_button.setObjectName("help_button") if npe_version != 1: self.enabled_checkbox.setEnabled(False) if installed: self.enabled_checkbox.show() self.action_button.setText(trans._("uninstall")) self.action_button.setObjectName("remove_button") else: self.enabled_checkbox.hide() self.action_button.setText(trans._("install")) self.action_button.setObjectName("install_button") def _get_dialog(self) -> QDialog: p = self.parent() while not isinstance(p, QDialog) and p.parent(): p = p.parent() return p def set_busy(self, text: str, update: bool = False): self.item_status.setText(text) self.cancel_btn.setVisible(True) if not update: self.action_button.setVisible(False) else: self.update_btn.setVisible(False) def setup_ui(self, enabled=True): self.v_lay = QVBoxLayout(self) self.v_lay.setContentsMargins(-1, 6, -1, 6) self.v_lay.setSpacing(0) self.row1 = QHBoxLayout() self.row1.setSpacing(6) self.enabled_checkbox = QCheckBox(self) self.enabled_checkbox.setChecked(enabled) self.enabled_checkbox.stateChanged.connect(self._on_enabled_checkbox) self.enabled_checkbox.setToolTip(trans._("enable/disable")) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.enabled_checkbox.sizePolicy().hasHeightForWidth() ) self.enabled_checkbox.setSizePolicy(sizePolicy) self.enabled_checkbox.setMinimumSize(QSize(20, 0)) self.enabled_checkbox.setText("") self.row1.addWidget(self.enabled_checkbox) self.plugin_name = QLabel(self) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.plugin_name.sizePolicy().hasHeightForWidth() ) self.plugin_name.setSizePolicy(sizePolicy) font15 = QFont() font15.setPointSize(15) self.plugin_name.setFont(font15) self.row1.addWidget(self.plugin_name) self.item_status = QLabel(self) self.item_status.setObjectName("small_italic_text") self.item_status.setSizePolicy(sizePolicy) self.row1.addWidget(self.item_status) self.row1.addStretch() self.package_name = QLabel(self) self.package_name.setAlignment( Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter ) self.row1.addWidget(self.package_name) self.cancel_btn = QPushButton("cancel", self) self.cancel_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.cancel_btn.setObjectName("remove_button") self.row1.addWidget(self.cancel_btn) self.update_btn = QPushButton(self) self.update_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.update_btn.setObjectName("install_button") self.row1.addWidget(self.update_btn) self.update_btn.setVisible(False) self.help_button = QPushButton(self) self.action_button = QPushButton(self) sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.action_button.sizePolicy().hasHeightForWidth() ) self.help_button.setSizePolicy(sizePolicy) self.action_button.setSizePolicy(sizePolicy) self.row1.addWidget(self.help_button) self.row1.addWidget(self.action_button) self.v_lay.addLayout(self.row1) self.row2 = QHBoxLayout() self.error_indicator = QPushButton() self.error_indicator.setObjectName("warning_icon") self.error_indicator.setCursor(Qt.PointingHandCursor) self.error_indicator.hide() self.row2.addWidget(self.error_indicator) self.row2.setContentsMargins(-1, 4, 0, -1) self.summary = QElidingLabel(parent=self) sizePolicy = QSizePolicy( QSizePolicy.MinimumExpanding, QSizePolicy.Preferred ) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.summary.sizePolicy().hasHeightForWidth() ) self.summary.setSizePolicy(sizePolicy) self.summary.setObjectName("small_text") self.row2.addWidget(self.summary) self.package_author = QLabel(self) sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.package_author.sizePolicy().hasHeightForWidth() ) self.package_author.setSizePolicy(sizePolicy) self.package_author.setObjectName("small_text") self.row2.addWidget(self.package_author) self.v_lay.addLayout(self.row2) def _on_enabled_checkbox(self, state: int): """Called with `state` when checkbox is clicked.""" enabled = bool(state) current_distname = self.plugin_name.text() for plugin_name, _, distname in plugin_manager.iter_available(): if distname and distname == current_distname: plugin_manager.set_blocked(plugin_name, not enabled)