package org.esa.snap.rcp.util; import org.esa.snap.core.datamodel.Product; import org.esa.snap.core.datamodel.Resampler; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; import org.openide.util.Lookup; import javax.swing.JComboBox; import javax.swing.JEditorPane; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.UIManager; import javax.swing.event.HyperlinkEvent; import javax.swing.text.html.HTMLDocument; import java.awt.BorderLayout; import java.awt.Desktop; import java.awt.Font; import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * <i>This class is not part of the public API.</i> * <p> * Its purpose is to suggest to use the resampling operator when users invoke a SNAP function * that is not capable to work with multi-size products such as Sentinel-2 MSI L1C or Sentinel-3 SLSTR L1b products. * * @author Tonio Fincke */ public class MultiSizeIssue { public static Product maybeResample(Product product) { String title = Dialogs.getDialogTitle("Resampling Required"); final List<Resampler> availableResamplers = getAvailableResamplers(product); int optionType; int messageType; final StringBuilder msgTextBuilder = new StringBuilder("The functionality you have chosen is not supported for products with bands of different sizes.<br/>"); if (availableResamplers.isEmpty()) { optionType = JOptionPane.OK_CANCEL_OPTION; messageType = JOptionPane.INFORMATION_MESSAGE; } else if (availableResamplers.size() == 1) { msgTextBuilder.append("You can use the ").append(availableResamplers.get(0).getName()). append(" to resample this product so that all bands have the same size, <br/>" + "which will enable you to use this feature.<br/>" + "Do you want to resample the product now?"); optionType = JOptionPane.YES_NO_OPTION; messageType = JOptionPane.QUESTION_MESSAGE; } else { msgTextBuilder.append("You can use one of these resamplers to resample this product so that all bands have the same size, <br/>" + "which will enable you to use this feature.<br/>" + "Do you want to resample the product now?"); optionType = JOptionPane.YES_NO_OPTION; messageType = JOptionPane.QUESTION_MESSAGE; } msgTextBuilder.append("<br/>" + "<br/>" + "More info about this issue and its status can be found in the " + "<a href=\"https://senbox.atlassian.net/browse/SNAP-1\">SNAP Issue Tracker</a>." ); JPanel panel = new JPanel(new BorderLayout(4, 4)); final JEditorPane textPane = new JEditorPane("text/html", msgTextBuilder.toString()); setFont(textPane); textPane.setEditable(false); textPane.setOpaque(false); textPane.addHyperlinkListener(e -> { if (HyperlinkEvent.EventType.ACTIVATED.equals(e.getEventType())) { try { Desktop.getDesktop().browse(e.getURL().toURI()); } catch (IOException | URISyntaxException e1) { Dialogs.showWarning("Could not open URL: " + e.getDescription()); } } }); panel.add(textPane, BorderLayout.CENTER); final JComboBox<Object> resamplerBox = new JComboBox<>(); if (availableResamplers.size() > 1) { String[] resamplerNames = new String[availableResamplers.size()]; for (int i = 0; i < availableResamplers.size(); i++) { resamplerNames[i] = availableResamplers.get(i).getName(); resamplerBox.addItem(resamplerNames[i]); } panel.add(resamplerBox, BorderLayout.SOUTH); } NotifyDescriptor d = new NotifyDescriptor(panel, title, optionType, messageType, null, null); DialogDisplayer.getDefault().notify(d); if (d.getValue() == NotifyDescriptor.YES_OPTION) { Resampler selectedResampler; if (availableResamplers.size() == 1) { selectedResampler = availableResamplers.get(0); } else { selectedResampler = availableResamplers.get(resamplerBox.getSelectedIndex()); } return selectedResampler.resample(product); } return null; } private static List<Resampler> getAvailableResamplers(Product product) { final Collection<? extends Resampler> allResamplers = Lookup.getDefault().lookupAll(Resampler.class); List<Resampler> availableResamplers = new ArrayList<>(); for (Resampler resampler : allResamplers) { if (resampler.canResample(product)) { availableResamplers.add(resampler); } } return availableResamplers; } public static boolean isMultiSize(Product selectedProduct) { return selectedProduct != null && selectedProduct.isMultiSize(); } private static void setFont(JEditorPane textPane) { if (textPane.getDocument() instanceof HTMLDocument) { Font font = UIManager.getFont("Label.font"); String bodyRule = "body { font-family: " + font.getFamily() + "; font-size: " + font.getSize() + "pt; }"; ((HTMLDocument) textPane.getDocument()).getStyleSheet().addRule(bodyRule); } } }