Skip to content

Commit

Permalink
Add preference saving from dialog for folders with extensions (napari…
Browse files Browse the repository at this point in the history
…#4535)

Co-authored-by: Juan Nunez-Iglesias <[email protected]>
  • Loading branch information
DragaDoncila and jni authored May 19, 2022
1 parent c82e440 commit 75a4df4
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 14 deletions.
33 changes: 29 additions & 4 deletions docs/release/release_0_4_16.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,38 @@ After discussion in [#4102](https://github.com/napari/napari/pull/4102) and [#41


- Calling `viewer.open` *without* passing a plugin will result in an error if you have not saved a reader preference for that file pattern *and* multiple plugins can claim the file
- You can address this error by associating a preference for the file pattern, or calling `viewer.open(file_path, plugin=...)
- A preferred reader failing to read your file will result in an error
- To save a preference for a file pattern in Python, use:

```python
from napari.settings import get_settings
get_settings().plugins.extension2reader['*.tif'] = 'napari_tifffile'
get_settings().plugins.extension2reader['*.zarr'] = 'napari-ome-zarr'
```

- To specify a plugin in a Python script:

```python
import napari

viewer = napari.Viewer()
viewer.open('my-path.tif') # this will throw MultipleReaderError if napari_tifffile is installed as both it and builtins could open the file
viewer.open('my-path.tif', plugin='napari_tifffile') # this won't
```

- To specify a plugin at the command line, use:

```sh
napari my-path.tif --plugin napari_tifffile
```
- A preferred reader failing to read your file will result in an error e.g. if you saved `napari_tifffile` as a preference for TIFFs but then tried to open a broken file
- When opening a file through a GUI pathway (drag & drop, File -> Open, Open Sample) you are provided with a dialog allowing you to choose among the various plugins that are compatible with your file
- This dialog also allows you to save a preference for files with extensions
- This dialog also allows you to save a preference for files and folders with extensions
- This dialog also pops up if a preferred reader fails to open your file
- Preference saving for file reading is now supported for filename patterns accepted by `npe2` readers, rather than strictly file extensions
- Existing preferences for file extensions will be automatically updated e.g. `.tif` will become `*.tif`
- Reader preferences for filename patterns can be saved in the GUI via the preference dialog

- Reader preferences for folders are not yet supported in the GUI preference dialog - use the Python method above
- This will be addressed by the next release

We have thought carefully about these choices, but there are still some open questions to address, and features to implement. Some of these are captured across the issues listed below, and we'd love to hear any feedback you have about the new behavior!

Expand Down Expand Up @@ -150,6 +173,8 @@ We have thought carefully about these choices, but there are still some open que
console, so this is strictly an improvement!)
- Allow resizing left dock widgets (#4368)
- Add filename pattern to reader associations to preference dialog (#4459)
- Add preference saving from dialog for folders with extensions #4535

## Deprecations


Expand Down
10 changes: 10 additions & 0 deletions napari/_qt/dialogs/_tests/test_reader_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ def test_reader_dir(tmpdir, reader_dialog):
assert not hasattr(widg, 'persist_checkbox')


def test_reader_dir_with_extension(tmpdir, reader_dialog):
dir = tmpdir.mkdir('my_dir.zarr')
widg = reader_dialog(pth=dir, readers={'p1': 'p1', 'p2': 'p2'})
assert hasattr(widg, 'persist_checkbox')
assert (
widg.persist_checkbox.text()
== "Remember this choice for files with a .zarr extension"
)


def test_get_plugin_choice(tmpdir, reader_dialog):
file_pth = tmpdir.join('my_file.tif')
widg = reader_dialog(pth=file_pth, readers={'p1': 'p1', 'p2': 'p2'})
Expand Down
24 changes: 15 additions & 9 deletions napari/_qt/dialogs/qt_reader_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,18 @@ def __init__(
self,
pth: str = '',
parent: QWidget = None,
extension: str = '',
readers: Dict[str, str] = {},
error_message: str = '',
):
super().__init__(parent)
self.setObjectName('Choose reader')
self.setWindowTitle(trans._('Choose reader'))
self._current_file = pth
self._extension = extension

if os.path.isdir(pth) and str(pth).endswith('/'):
pth = os.path.dirname(pth)
self._extension = os.path.splitext(pth)[1]

self._reader_buttons = []
self.setup_ui(error_message, readers)

Expand Down Expand Up @@ -62,11 +65,10 @@ def setup_ui(self, error_message, readers):
self.btn_box.accepted.connect(self.accept)
self.btn_box.rejected.connect(self.reject)

# checkbox to remember the choice (doesn't pop up for folders)
extension = os.path.splitext(self._current_file)[1]
if extension:
# checkbox to remember the choice (doesn't pop up for folders with no extension)
if self._extension:
self.persist_checkbox = QCheckBox(
f'Remember this choice for files with a {extension} extension'
f'Remember this choice for files with a {self._extension} extension'
)
self.persist_checkbox.toggle()
layout.addWidget(self.persist_checkbox)
Expand Down Expand Up @@ -142,18 +144,22 @@ def handle_gui_reading(
readers = prepare_remaining_readers(paths, plugin_name, error)
error_message = str(error) if error else ''

_, extension = os.path.splitext(_path)
readerDialog = QtReaderDialog(
parent=qt_viewer,
pth=_path,
extension=extension,
error_message=error_message,
readers=readers,
)
display_name, persist = readerDialog.get_user_choices()
if display_name:
open_with_dialog_choices(
display_name, persist, extension, readers, paths, stack, qt_viewer
display_name,
persist,
readerDialog._extension,
readers,
paths,
stack,
qt_viewer,
)


Expand Down
4 changes: 3 additions & 1 deletion napari/_qt/qt_viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import logging
import traceback
import warnings
from pathlib import Path
from typing import TYPE_CHECKING, List, Optional, Sequence, Tuple
from weakref import WeakSet

Expand Down Expand Up @@ -1072,7 +1073,8 @@ def dropEvent(self, event):
filenames = []
for url in event.mimeData().urls():
if url.isLocalFile():
filenames.append(url.toLocalFile())
# directories get a trailing "/", Path conversion removes it
filenames.append(str(Path(url.toLocalFile())))
else:
filenames.append(url.toString())

Expand Down

0 comments on commit 75a4df4

Please sign in to comment.