Skip to content

Commit

Permalink
Merge pull request #96 from goanpeca/enh/direct-entry
Browse files Browse the repository at this point in the history
  • Loading branch information
goanpeca authored Aug 19, 2024
2 parents 5b49d7c + a0ee0f1 commit 7ab6096
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 7 deletions.
3 changes: 3 additions & 0 deletions napari_plugin_manager/_tests/test_npe2api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from flaky import flaky

from napari_plugin_manager.npe2api import (
_user_agent,
cache_clear,
Expand All @@ -11,6 +13,7 @@ def test_user_agent():
assert _user_agent()


@flaky(max_runs=3, min_passes=2)
def test_plugin_summaries():
keys = [
"name",
Expand Down
22 changes: 22 additions & 0 deletions napari_plugin_manager/_tests/test_qt_plugin_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,28 @@ def test_cancel_all(qtbot, tmp_virtualenv, plugin_dialog, request):
assert plugin_dialog.installed_list.count() == 2


@pytest.mark.skipif(
qtpy.API_NAME.lower().startswith('pyside'), reason='pyside specific bug'
)
def test_direct_entry_installs(qtbot, tmp_virtualenv, plugin_dialog, request):
if "[constructor]" in request.node.name:
pytest.skip(
reason="This test is only relevant for constructor-based installs"
)

plugin_dialog.set_prefix(str(tmp_virtualenv))
with qtbot.waitSignal(
plugin_dialog.installer.processFinished, timeout=60_000
) as blocker:
plugin_dialog.direct_entry_edit.setText('requests')
plugin_dialog.direct_entry_btn.click()

process_finished_data = blocker.args[0]
assert process_finished_data['action'] == InstallerActions.INSTALL
assert process_finished_data['pkgs'][0].startswith("requests")
qtbot.wait(5000)


def test_shortcut_close(plugin_dialog, qtbot):
qtbot.keyClicks(
plugin_dialog, 'W', modifier=Qt.KeyboardModifier.ControlModifier
Expand Down
65 changes: 59 additions & 6 deletions napari_plugin_manager/qt_plugin_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@
from napari.utils.notifications import show_info, show_warning
from napari.utils.translations import trans
from qtpy.QtCore import QPoint, QSize, Qt, QTimer, Signal, Slot
from qtpy.QtGui import QAction, QFont, QKeySequence, QMovie, QShortcut
from qtpy.QtGui import (
QAction,
QActionGroup,
QFont,
QKeySequence,
QMovie,
QShortcut,
)
from qtpy.QtWidgets import (
QCheckBox,
QComboBox,
Expand All @@ -35,10 +42,12 @@
QLineEdit,
QListWidget,
QListWidgetItem,
QMenu,
QPushButton,
QSizePolicy,
QSplitter,
QTextEdit,
QToolButton,
QVBoxLayout,
QWidget,
)
Expand Down Expand Up @@ -914,6 +923,11 @@ def _quit(self):
self._parent.close(quit_app=True, confirm_need=True)

def _setup_shortcuts(self):
self._refresh_styles_action = QAction(trans._('Refresh Styles'), self)
self._refresh_styles_action.setShortcut('Ctrl+R')
self._refresh_styles_action.triggered.connect(self._update_theme)
self.addAction(self._refresh_styles_action)

self._quit_action = QAction(trans._('Exit'), self)
self._quit_action.setShortcut('Ctrl+Q')
self._quit_action.setMenuRole(QAction.QuitRole)
Expand Down Expand Up @@ -1181,13 +1195,34 @@ def _setup_ui(self):
visibility_direct_entry = not running_as_constructor_app()
self.direct_entry_edit = QLineEdit(self)
self.direct_entry_edit.installEventFilter(self)
self.direct_entry_edit.setPlaceholderText(
trans._('install by name/url, or drop file...')
)
self.direct_entry_edit.returnPressed.connect(self._install_packages)
self.direct_entry_edit.setVisible(visibility_direct_entry)
self.direct_entry_btn = QPushButton(trans._("Install"), self)
self.direct_entry_btn = QToolButton(self)
self.direct_entry_btn.setVisible(visibility_direct_entry)
self.direct_entry_btn.clicked.connect(self._install_packages)
self.direct_entry_btn.setText(trans._("Install"))

self._action_conda = QAction(trans._('Conda'), self)
self._action_conda.setCheckable(True)
self._action_conda.triggered.connect(self._update_direct_entry_text)

self._action_pypi = QAction(trans._('pip'), self)
self._action_pypi.setCheckable(True)
self._action_pypi.triggered.connect(self._update_direct_entry_text)

self._action_group = QActionGroup(self)
self._action_group.addAction(self._action_pypi)
self._action_group.addAction(self._action_conda)
self._action_group.setExclusive(True)

self._menu = QMenu(self)
self._menu.addAction(self._action_conda)
self._menu.addAction(self._action_pypi)

if IS_NAPARI_CONDA_INSTALLED:
self.direct_entry_btn.setPopupMode(QToolButton.MenuButtonPopup)
self._action_conda.setChecked(True)
self.direct_entry_btn.setMenu(self._menu)

self.show_status_btn = QPushButton(trans._("Show Status"), self)
self.show_status_btn.setFixedWidth(100)
Expand Down Expand Up @@ -1224,6 +1259,19 @@ def _setup_ui(self):
self.h_splitter.setStretchFactor(0, 2)

self.packages_filter.setFocus()
self._update_direct_entry_text()

def _update_direct_entry_text(self):
tool = (
str(InstallerTools.CONDA)
if self._action_conda.isChecked()
else str(InstallerTools.PIP)
)
self.direct_entry_edit.setPlaceholderText(
trans._(
"install with '{tool}' by name/url, or drop file...", tool=tool
)
)

def _update_plugin_count(self):
"""Update count labels for both installed and available plugin lists.
Expand Down Expand Up @@ -1278,7 +1326,12 @@ def _install_packages(
self.direct_entry_edit.clear()

if packages:
self.installer.install(InstallerTools.PIP, packages)
tool = (
InstallerTools.CONDA
if self._action_conda.isChecked()
else InstallerTools.PIP
)
self.installer.install(tool, packages)

def _tag_outdated_plugins(self):
"""Tag installed plugins that might be outdated."""
Expand Down
31 changes: 31 additions & 0 deletions napari_plugin_manager/styles.qss
Original file line number Diff line number Diff line change
Expand Up @@ -350,3 +350,34 @@ QtLayerList::indicator:checked {
min-height: 36px;
min-width: 36px;
}

QToolButton {
background-color: {{ darken(foreground, 20) }};
color: {{ darken(text, 15) }};
padding: 3 12px;
font: 14px;
}

QToolButton:hover {
background-color: {{ lighten(foreground, 10) }}
}

QToolButton:pressed {
background-color: {{ lighten(foreground, 20) }}
}

QToolButton::menu-arrow {
image: url("theme_{{ id }}:/down_arrow.svg");
top: 0px;
left: 0px;
width: 8px;
height: 8px;
}

QToolButton[popupMode="1"]{
padding-right: 20px;
}

QToolButton::menu-button {
width: 16px;
}
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,11 @@ dev = [
]

testing = [
"flaky",
"pytest",
"virtualenv",
"pytest-cov",
"pytest-qt",
"virtualenv"
]

docs = [
Expand Down

0 comments on commit 7ab6096

Please sign in to comment.