/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package org.esa.snap.rcp.session; import com.bc.ceres.core.CanceledException; import com.bc.ceres.core.ProgressMonitor; import com.bc.ceres.grender.Viewport; import com.bc.ceres.swing.progress.ProgressMonitorSwingWorker; import org.esa.snap.core.dataio.ProductIO; import org.esa.snap.core.datamodel.Product; import org.esa.snap.rcp.SnapApp; import org.esa.snap.rcp.actions.file.CloseAllProductsAction; import org.esa.snap.rcp.util.Dialogs; import org.esa.snap.ui.product.ProductNodeView; import org.esa.snap.ui.product.ProductSceneView; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; import org.openide.awt.ActionRegistration; import org.openide.util.NbBundle; import javax.swing.AbstractAction; import javax.swing.JInternalFrame; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.io.File; import java.io.IOException; import java.net.URI; import java.text.MessageFormat; import java.util.concurrent.ExecutionException; @ActionID(category = "File", id = "org.esa.snap.rcp.session.OpenSessionAction") @ActionRegistration(displayName = "#CTL_OpenSessionAction_MenuText") @ActionReference(path = "Menu/File/Session", position = 15) @NbBundle.Messages({ "CTL_OpenSessionAction_MenuText=Open Session...", "CTL_OpenSessionAction_ShortDescription=Open a SNAP session." }) public class OpenSessionAction extends AbstractAction { public static final String ID = "openSession"; public static final String LAST_SESSION_DIR_KEY = "beam.lastSessionDir"; private static final String TITLE = "Open Session"; @Override public void actionPerformed(ActionEvent event) { final SessionManager manager = SessionManager.getDefault(); if (manager.getSessionFile() != null) { Dialogs.Answer answer = Dialogs.requestDecision(TITLE, "This will close or reopen the current session.\n" + "Do you want to continue?", true, null); if (answer != Dialogs.Answer.YES) { return; } } final File sessionFile = Dialogs.requestFileForOpen(TITLE, false, SessionManager.getDefault().getSessionFileFilter(), LAST_SESSION_DIR_KEY); if (sessionFile == null) { return; } openSession(sessionFile); } public void openSession(File sessionFile) { final SessionManager manager = SessionManager.getDefault(); manager.setSessionFile(sessionFile); CloseAllProductsAction closeProductAction = new CloseAllProductsAction(); closeProductAction.execute(); SwingWorker<RestoredSession, Object> worker = new OpenSessionWorker(manager, sessionFile); worker.execute(); } private static class OpenSessionWorker extends ProgressMonitorSwingWorker<RestoredSession, Object> { private final SessionManager app; private final File sessionFile; public OpenSessionWorker(SessionManager app, File sessionFile) { super(SnapApp.getDefault().getMainFrame(), TITLE); this.app = app; this.sessionFile = sessionFile; } @Override protected RestoredSession doInBackground(ProgressMonitor pm) throws Exception { final Session session = SessionIO.getInstance().readSession(sessionFile); final File parentFile = sessionFile.getParentFile(); final URI rootURI; if (parentFile != null) { rootURI = parentFile.toURI(); } else { rootURI = new File(".").toURI(); } return session.restore(SnapApp.getDefault().getAppContext(), rootURI, pm, new SessionProblemSolver()); } @Override protected void done() { final RestoredSession restoredSession; try { restoredSession = get(); } catch (InterruptedException e) { return; } catch (ExecutionException e) { if (e.getCause() instanceof CanceledException) { return; } Dialogs.showError(MessageFormat.format("An unexpected exception occurred!\nMessage: {0}", e.getCause().getMessage())); e.printStackTrace(); return; } final Exception[] problems = restoredSession.getProblems(); if (problems.length > 0) { StringBuilder sb = new StringBuilder(); sb.append("The following problem(s) occurred while opening a session:\n"); for (Exception problem : problems) { problem.printStackTrace(); sb.append(" "); sb.append(problem.getMessage()); sb.append("\n"); } Dialogs.showWarning(sb.toString()); } final Product[] products = restoredSession.getProducts(); for (Product product : products) { SnapApp.getDefault().getProductManager().addProduct(product); } // todo - Handle view persistence in a generic way. (nf - 08.05.2009) // These are the only 3 views currently known in BEAM. final ProductNodeView[] nodeViews = restoredSession.getViews(); for (ProductNodeView nodeView : nodeViews) { Rectangle bounds = nodeView.getBounds(); JInternalFrame internalFrame = null; if (nodeView instanceof ProductSceneView) { ProductSceneView sceneView = (ProductSceneView) nodeView; sceneView.getLayerCanvas().setInitiallyZoomingAll(false); Viewport viewport = sceneView.getLayerCanvas().getViewport().clone(); // ######### 06.07.2015 ######## // Comment out by Muhammad until tool window persistance is solved for SNAP on NetBeans platform. // if (sceneView.isRGB()) { // internalFrame = null;// showImageViewRGBAction.openInternalFrame(sceneView, false); // } else { // internalFrame = null;//showImageViewAction.openInternalFrame(sceneView, false); // } // sceneView.getLayerCanvas().getViewport().setTransform(viewport); // } else if (nodeView instanceof ProductMetadataView) { // ProductMetadataView metadataView = (ProductMetadataView) nodeView; // internalFrame = showMetadataViewAction.openInternalFrame(metadataView); // } // if (internalFrame != null) { // try { // internalFrame.setMaximum(false); // } catch (PropertyVetoException e) { // // ok to ignore // } // internalFrame.setBounds(bounds); // } } } } private <T> T getAction(String actionId) { T action = null; if (action == null) { throw new IllegalStateException("Action not found: actionId=" + actionId); } return action; } private class SessionProblemSolver implements Session.ProblemSolver { @Override public Product solveProductNotFound(int id, File file) throws CanceledException { final File[] newFile = new File[1]; final Dialogs.Answer[] answer = new Dialogs.Answer[1]; final String title = MessageFormat.format(TITLE + " - Resolving [{0}]", file); final String msg = MessageFormat.format("Product [{0}] has been renamed or (re-)moved.\n" + "Its location was [{1}].\n" + "Do you wish to provide its new location?\n" + "(Select ''No'' if the product shall no longer be part of the session.)", id, file); try { SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { answer[0] = Dialogs.requestDecision(title, msg, true, null); if (answer[0] == Dialogs.Answer.YES) { newFile[0] = Dialogs.requestFileForOpen(title, false, null, null); } } }); } catch (Exception e) { throw new CanceledException(); } if (answer[0] == Dialogs.Answer.YES) { throw new CanceledException(); } if (newFile[0] != null) { try { return ProductIO.readProduct(newFile[0]); } catch (IOException e) { } } return null; } } } }