Comments (14)
@psobolewskiPhD I understand. I will have a look at it. I think it's just a matter of us explicitly sorting the list of available writers to put the folder writer first. I don't think the dialogs have a default vs. not default option. But will check!
from napari.
But what's worse is it also was used when using builtins Save to Folder. Shouldn't builtins prioritize builtins?
Yeah this, at least, shouldn't be happening, I will have to take a look.
from napari.
CC: @DragaDoncila do you have any thoughts on how to fix this behavior?
from napari.
@psobolewskiPhD just to clarify - the main issue here is what writer is first shown in the dialog?
from napari.
Yeah -- well for me on macOS to see other options I need to click on the dropdown, so it's not first vs second, it's default or not.
By default, I see svg, when I should see builtins
Edit: I added a screenshot.
And just to emphasize, the svg writer is limited and the output cannot be opened by napari, so it's not viable as a way to save ones work. Save to folder
on the other hand works perfectly, modulo issue with loading the folder back #5460
from napari.
Not sure how easy to implement this is but:
default in vanilla fresh install: if builtins and another plugin can work, show builtins, other plugins in dropdown
if the user changes to a plugin, remember that for next time
from napari.
if the user changes to a plugin, remember that for next time
next time what, the user selects Save All Layers...
? Seems too broad to me to remember the preference. Save All Layers
in general I think is so broad that we want to be cautious about remembering any kind of context.
from napari.
I was just thinking -- biased by my own experiences -- that when people are working on a project they probably go through phases where they use the same file types or workflows. So if they're using svg, or some other plugin, rather than builtins, they'd want to keep using it.
Save all layers
is pretty broad, but I suspect the vast majority of GUI users with multiple layers are mixing: image, label, shape, points -- those are the ones available from GUI. Builtins happens to handle them perfectly, if you know to look.
Meanwhile an advanced user doing something with vectors or something else fancy will never want to use builtins in favor of whatever cutting edge thing they use.
When opening a file we already ask what to remember to use, so this the idea would be something similar.
Edit: I could be totally looney though and just biased by helping with a project where there are images, labels, shapes, and points used in regularity.
from napari.
Yeah so the order of the dropdown menus is just determined by how we order the writers. It's a little messy (the dropdown is actually populated by QFileDialog.getOpenFileName
's filter
parameter). But the good news is we can order that filter however we want, once we do decide what we want!
from napari.
The function that's determining the filter is here. A quick and dirty way to bring Save to folder
to the front would be:
def file_extensions_string_for_layers(
layers: Sequence[Layer],
) -> tuple[Optional[str], list[WriterContribution]]:
"""Create extensions string using npe2.
When npe2 can be imported, returns an extension string and the list
of corresponding writers. Otherwise returns (None,[]).
The extension string is a ";;" delimeted string of entries. Each entry
has a brief description of the file type and a list of extensions. For
example:
"Images (*.png *.jpg *.tif);;All Files (*.*)"
The writers, when provided, are the
`npe2.manifest.io.WriterContribution` objects. There is one writer per
entry in the extension string.
"""
layer_types = [layer._type_string for layer in layers]
writers = list(pm.iter_compatible_writers(layer_types))
def _items():
"""Lookup the command name and its supported extensions."""
for writer in writers:
name = pm.get_manifest(writer.command).display_name
title = (
f'{name} {writer.display_name}'
if writer.display_name
else name
)
yield title, writer.filename_extensions
# extension strings are in the format:
# "<name> (*<ext1> *<ext2> *<ext3>);;+"
def _fmt_exts(es):
return ' '.join(f'*{e}' for e in es if e) if es else '*.*'
######## bringing save to folder first ###########
names_and_extensions = list(_items())
default_writer_index = next((i for i, item in enumerate(names_and_extensions) if item[0] == 'napari builtins Save to Folder'), 0)
names_and_extensions.insert(0, names_and_extensions.pop(default_writer_index))
return (
';;'.join(f'{name} ({_fmt_exts(exts)})' for name, exts in names_and_extensions),
writers,
)
It's obviously brittle the way I've done it there, but we could sort earlier if we wanted, when we have all layer and writer information available.
from napari.
Ran into this in a workshop I ran today--obviously solved with attention to detail on the part of the user, but still.
Should builtins just get default prioritization unless the user changes in Prefs/Settings?
from napari.
Ran into this in a different situation -- but again when doing a live code demo -- with napari-threedee.
As it turns out, it has a defunct writer contribution and was the default when saving Points. I didn't realize (read carefully) and got errors.
But what's worse is it also was used when using builtins Save to Folder. Shouldn't builtins prioritize builtins?
from napari.
Maybe we should do split (like Libre Office or Gimp) and add Export
submenu? So save will be, a format that could be loaded and Export
some formats like svg
, pdf
etc that may not be possible to load.
Also, we should add supported dimensionality information to writers.
from napari.
Hmm, I can't reproduce, so I'm not sure what I did in the demo. Seems to be working OK right now.
(and I fixed the non-existent writer in napari-threedee so it shouldn't happen again anyways)
from napari.
Related Issues (20)
- Polygon faces in Shapes layer are not shown in 3D if not contained in an *axis-orthogonal* plane HOT 1
- layer.events.current_symbol callback raises exception in when a widget is launched from the plugin menu HOT 2
- [test-bot] pip install --pre is failing HOT 1
- [test-bot] pip install --pre is failing
- When using 4D data for a mesh an IndexError happens when the selected Shape layer doesn't have any points at the current frame. HOT 1
- [test-bot] pip install --pre is failing
- Surface without points in the current time frame raise "AttributeError: 'NoneType' object has no attribute 'shape'" on main branch. HOT 2
- HiLO LUT HOT 4
- Window leveling and Opacity mapping HOT 3
- Shift camera when drawing HOT 2
- add Shape selection event HOT 1
- [ui/ux] Enabling locking Layer controls, preventing accidental changes HOT 1
- Transform mode of Labels layer pivots wrong when non-empty Shapes/Points present HOT 7
- Default to adding a newline for everything before the `extra_tooltip_text` when binding an action to a button HOT 3
- CI Ubuntu latest py 3.9, pyqt5, pyside 6 hash mismatch HOT 5
- Out-of-slice display of points with scale/size is inconsistent HOT 3
- Napari crashes with lazy segmentation HOT 9
- How to handle headless app-model actions HOT 4
- Shapes layer: `3` keybinding to delete shape is not great and cannot be changed HOT 8
- [Points, vispy] Traceback when toggling Points layer to 3D
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from napari.