diff --git a/src/main/java/net/preibisch/mvrecon/fiji/plugin/XMLSaveAs.java b/src/main/java/net/preibisch/mvrecon/fiji/plugin/XMLSaveAs.java new file mode 100644 index 00000000..81f7065a --- /dev/null +++ b/src/main/java/net/preibisch/mvrecon/fiji/plugin/XMLSaveAs.java @@ -0,0 +1,110 @@ +package net.preibisch.mvrecon.fiji.plugin; + +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; + +import bdv.img.hdf5.Hdf5ImageLoader; +import bdv.img.n5.N5ImageLoader; +import fiji.util.gui.GenericDialogPlus; +import ij.plugin.PlugIn; +import mpicbg.spim.data.sequence.ImgLoader; +import net.preibisch.legacy.io.IOFunctions; +import net.preibisch.mvrecon.fiji.plugin.queryXML.LoadParseQueryXML; +import net.preibisch.mvrecon.fiji.spimdata.SpimData2; +import net.preibisch.mvrecon.fiji.spimdata.XmlIoSpimData2; +import net.preibisch.mvrecon.fiji.spimdata.interestpoints.ViewInterestPointLists; +import util.URITools; + +public class XMLSaveAs implements PlugIn +{ + @Override + public void run( String arg ) + { + final LoadParseQueryXML result = new LoadParseQueryXML(); + + if ( !result.queryXML( "Save XML as ...", "", false, false, false, false, false ) ) + return; + + final SpimData2 data = result.getData(); + final XmlIoSpimData2 io = result.getIO(); + + final URI newXMLPath = saveAs( data, result.getXMLFileName() ); + + if ( newXMLPath != null ) + { + io.save( data, newXMLPath ); + + IOFunctions.println( "Done." ); + } + } + + public static URI saveAs( final SpimData2 data, final String suggestedFileName ) + { + final ImgLoader imgLoader = data.getSequenceDescription().getImgLoader(); + + if ( !N5ImageLoader.class.isInstance( imgLoader ) && !Hdf5ImageLoader.class.isInstance( imgLoader ) ) + { + IOFunctions.println( "Saving the XML in a different location than the image data currently only works when it is re-saved as HDF5/N5/ZARR. Stopping." ); + return null; + } + + final GenericDialogPlus gd = new GenericDialogPlus( "Save BigStitcher project as ..." ); + gd.addFileField( "Dataset location (local or cloud)", URITools.appendName( data.getBasePathURI(), suggestedFileName), 120 ); + + gd.showDialog(); + + if ( gd.wasCanceled() ) + return null; + + final String uriString = gd.getNextString(); + final URI newXMLPath, newBaseDir; + + try + { + newXMLPath = new URI( uriString ); + } + catch ( URISyntaxException ex ) + { + IOFunctions.println( "Could not convert provided XML path into a URI: " + ex ); + return null; + } + + if ( !URITools.isKnownScheme( newXMLPath ) ) + { + IOFunctions.println( "The scheme of the XML path you selected '" + newXMLPath + "' is unknown." ); + return null; + } + + newBaseDir = URITools.getParent( newXMLPath ); + + IOFunctions.println( "New XML: " + newXMLPath ); + IOFunctions.println( "New base path: " + newBaseDir ); + + if ( N5ImageLoader.class.isInstance( imgLoader ) ) + { + final URI n5URI = ((N5ImageLoader)imgLoader).getN5URI(); + + IOFunctions.println( "Path of N5 (stays in old location): " + n5URI ); + data.getSequenceDescription().setImgLoader( new N5ImageLoader( n5URI, data.getSequenceDescription() ) ); + } + else if ( Hdf5ImageLoader.class.isInstance( imgLoader ) ) + { + final Hdf5ImageLoader h5ImgLoader = (Hdf5ImageLoader)imgLoader; + final File h5File = h5ImgLoader.getHdf5File(); + + IOFunctions.println( "HDF5 file (stays in old location): " + h5File ); + data.getSequenceDescription().setImgLoader( new Hdf5ImageLoader(h5File, h5ImgLoader.getPartitions(), data.getSequenceDescription()) ); + } + + data.setBasePathURI( newBaseDir ); + + // make sure interestpoints are saved to the new location as well + for ( final ViewInterestPointLists vipl : data.getViewInterestPoints().getViewInterestPoints().values() ) + vipl.getHashMap().values().forEach( ipl -> ipl.setBaseDir( newBaseDir ) ); + + LoadParseQueryXML.defaultXMLURI = newXMLPath.toString(); + + return newXMLPath; + } +} diff --git a/src/main/java/net/preibisch/mvrecon/fiji/spimdata/explorer/FilteredAndGroupedExplorerPanel.java b/src/main/java/net/preibisch/mvrecon/fiji/spimdata/explorer/FilteredAndGroupedExplorerPanel.java index 122c4bc8..a13fbf76 100644 --- a/src/main/java/net/preibisch/mvrecon/fiji/spimdata/explorer/FilteredAndGroupedExplorerPanel.java +++ b/src/main/java/net/preibisch/mvrecon/fiji/spimdata/explorer/FilteredAndGroupedExplorerPanel.java @@ -34,6 +34,8 @@ import java.util.Set; import java.util.stream.Collectors; +import javax.swing.JLabel; +import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JTable; @@ -46,7 +48,6 @@ import bdv.viewer.DisplayMode; import bdv.viewer.SourceAndConverter; import bdv.viewer.ViewerState; -import mpicbg.spim.data.SpimDataException; import mpicbg.spim.data.generic.AbstractSpimData; import mpicbg.spim.data.generic.base.Entity; import mpicbg.spim.data.generic.base.NamedEntity; @@ -58,6 +59,7 @@ import net.imglib2.realtransform.AffineTransform3D; import net.imglib2.type.numeric.ARGBType; import net.preibisch.legacy.io.IOFunctions; +import net.preibisch.mvrecon.fiji.plugin.XMLSaveAs; import net.preibisch.mvrecon.fiji.spimdata.GroupedViews; import net.preibisch.mvrecon.fiji.spimdata.SpimData2; import net.preibisch.mvrecon.fiji.spimdata.SpimDataTools; @@ -89,11 +91,13 @@ public abstract class FilteredAndGroupedExplorerPanel< AS extends SpimData2 > protected ArrayList< SelectedViewDescriptionListener< AS > > listeners; protected AS data; protected FilteredAndGroupedExplorer< AS > explorer; - protected final URI xml; + protected URI xml; protected final XmlIoSpimData2 io; protected final boolean isMac; protected boolean colorMode = false; + protected JLabel xmlLabel; + final protected HashSet< List< BasicViewDescription< ? > > > selectedRows; protected BasicViewDescription< ? > firstSelectedVD; @@ -489,6 +493,30 @@ public void showInfoBox() new ViewSetupExplorerInfoBox<>( data ); } + public JPopupMenu addRightClickSaveAs() + { + final JPopupMenu popupMenu = new JPopupMenu(); + final JMenuItem item = new JMenuItem( "Save as ..." ); + + item.addActionListener( e -> + { + final SpimData2 data = this.getSpimData(); + + final URI newXMLPath = XMLSaveAs.saveAs( data, this.xml().toString() ); + + if ( newXMLPath != null ) + { + this.xml = newXMLPath; + this.saveXML(); + this.xmlLabel.setText( "XML: " + newXMLPath ); + } + }); + + popupMenu.add( item ); + + return popupMenu; + } + @Override public void saveXML() { diff --git a/src/main/java/net/preibisch/mvrecon/fiji/spimdata/explorer/ViewSetupExplorerPanel.java b/src/main/java/net/preibisch/mvrecon/fiji/spimdata/explorer/ViewSetupExplorerPanel.java index b3e2d6d4..52a19340 100644 --- a/src/main/java/net/preibisch/mvrecon/fiji/spimdata/explorer/ViewSetupExplorerPanel.java +++ b/src/main/java/net/preibisch/mvrecon/fiji/spimdata/explorer/ViewSetupExplorerPanel.java @@ -31,6 +31,7 @@ import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.io.File; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; @@ -45,6 +46,7 @@ import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; +import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; @@ -58,20 +60,24 @@ import bdv.BigDataViewer; import bdv.ViewerImgLoader; +import bdv.img.hdf5.Hdf5ImageLoader; +import bdv.img.n5.N5ImageLoader; import bdv.tools.brightness.ConverterSetup; import bdv.viewer.DisplayMode; import bdv.viewer.VisibilityAndGrouping; -import mpicbg.spim.data.SpimDataException; +import fiji.util.gui.GenericDialogPlus; import mpicbg.spim.data.generic.AbstractSpimData; import mpicbg.spim.data.generic.base.Entity; import mpicbg.spim.data.generic.sequence.BasicViewDescription; import mpicbg.spim.data.generic.sequence.BasicViewSetup; import mpicbg.spim.data.sequence.Illumination; +import mpicbg.spim.data.sequence.ImgLoader; import mpicbg.spim.data.sequence.Tile; import mpicbg.spim.data.sequence.TimePoint; import mpicbg.spim.data.sequence.ViewId; import net.imglib2.type.numeric.ARGBType; import net.preibisch.legacy.io.IOFunctions; +import net.preibisch.mvrecon.fiji.plugin.XMLSaveAs; import net.preibisch.mvrecon.fiji.spimdata.SpimData2; import net.preibisch.mvrecon.fiji.spimdata.XmlIoSpimData2; import net.preibisch.mvrecon.fiji.spimdata.explorer.bdv.ScrollableBrightnessDialog; @@ -105,10 +111,9 @@ import net.preibisch.mvrecon.fiji.spimdata.explorer.popup.VisualizeNonRigid; import net.preibisch.mvrecon.fiji.spimdata.explorer.util.ColorStream; import net.preibisch.mvrecon.fiji.spimdata.imgloaders.filemap2.FileMapImgLoaderLOCI2; -import net.preibisch.mvrecon.fiji.spimdata.interestpoints.InterestPoints; import net.preibisch.mvrecon.fiji.spimdata.interestpoints.ViewInterestPointLists; -import net.preibisch.mvrecon.fiji.spimdata.interestpoints.ViewInterestPoints; import net.preibisch.mvrecon.process.interestpointregistration.pairwise.constellation.grouping.Group; +import util.URITools; public class ViewSetupExplorerPanel< AS extends SpimData2 > extends FilteredAndGroupedExplorerPanel< AS > implements ExplorerWindow< AS > @@ -255,6 +260,7 @@ public void actionPerformed( final ActionEvent e ) saveXML(); } }); + save.setComponentPopupMenu( addRightClickSaveAs() ); final JButton info = new JButton( "Info" ); info.addActionListener( new ActionListener() @@ -272,7 +278,7 @@ public void actionPerformed( final ActionEvent e ) buttons.add( save, BorderLayout.EAST ); final JPanel header = new JPanel( new BorderLayout() ); - header.add( getXMLLabel( xml ), BorderLayout.WEST ); + header.add( xmlLabel = getXMLLabel( xml ), BorderLayout.WEST ); header.add( buttons, BorderLayout.EAST ); this.add( header, BorderLayout.NORTH ); this.add( new JScrollPane( table ), BorderLayout.CENTER );