/* * * * Copyright (C) 2015 CS SI * * * * 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.ui.tooladapter.dialogs; import com.bc.ceres.binding.Property; import com.bc.ceres.binding.PropertySet; import com.bc.ceres.binding.ValidationException; import com.bc.ceres.swing.binding.PropertyPane; import com.bc.ceres.swing.selection.AbstractSelectionChangeListener; import com.bc.ceres.swing.selection.SelectionChangeEvent; import org.esa.snap.core.datamodel.Product; import org.esa.snap.core.gpf.descriptor.TemplateParameterDescriptor; import org.esa.snap.core.gpf.descriptor.ToolAdapterOperatorDescriptor; import org.esa.snap.core.gpf.descriptor.ToolParameterDescriptor; import org.esa.snap.core.gpf.operators.tooladapter.ToolAdapterConstants; import org.esa.snap.core.gpf.ui.DefaultIOParametersPanel; import org.esa.snap.core.gpf.ui.SourceProductSelector; import org.esa.snap.core.gpf.ui.TargetProductSelector; import org.esa.snap.core.gpf.ui.TargetProductSelectorModel; import org.esa.snap.core.util.io.FileUtils; import org.esa.snap.rcp.util.Dialogs; import org.esa.snap.ui.AppContext; import org.esa.snap.ui.tooladapter.preferences.ToolAdapterOptionsController; import org.esa.snap.utils.SpringUtilities; import org.openide.util.NbPreferences; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Logger; import java.util.stream.Collectors; /** * Form for displaying execution parameters. * This form is part of <code>ToolAdapterExecutionDialog</code>. * * @author Ramona Manda */ class ToolExecutionForm extends JTabbedPane { private AppContext appContext; private ToolAdapterOperatorDescriptor operatorDescriptor; private PropertySet propertySet; private TargetProductSelector targetProductSelector; private DefaultIOParametersPanel ioParamPanel; private String fileExtension; private JCheckBox checkDisplayOutput; ConsolePane console; private final String TIF_EXTENSION = ".tif"; JSplitPane bottomPane; public ToolExecutionForm(AppContext appContext, ToolAdapterOperatorDescriptor descriptor, PropertySet propertySet, TargetProductSelector targetProductSelector) { this.appContext = appContext; this.operatorDescriptor = descriptor; this.propertySet = propertySet; this.targetProductSelector = targetProductSelector; //before executing, the sourceProduct and sourceProductFile must be removed from the list, since they cannot be edited Property sourceProperty = this.propertySet.getProperty(ToolAdapterConstants.TOOL_SOURCE_PRODUCT_FILE); if(sourceProperty != null) { this.propertySet.removeProperty(sourceProperty); } sourceProperty = this.propertySet.getProperty(ToolAdapterConstants.TOOL_SOURCE_PRODUCT_ID); if(sourceProperty != null) { this.propertySet.removeProperty(sourceProperty); } // if the tool is handling by itself the output product name, then remove targetProductFile from the list, // since it may bring only confusion in this case if (operatorDescriptor.isHandlingOutputName()) { sourceProperty = this.propertySet.getProperty(ToolAdapterConstants.TOOL_TARGET_PRODUCT_FILE); if (sourceProperty != null) { this.propertySet.removeProperty(sourceProperty); } } //initialise the target product's directory to the working directory final TargetProductSelectorModel targetProductSelectorModel = targetProductSelector.getModel(); targetProductSelectorModel.setProductDir(operatorDescriptor.resolveVariables(operatorDescriptor.getWorkingDir())); if(!operatorDescriptor.isHandlingOutputName() || operatorDescriptor.getSourceProductCount() > 0) { ioParamPanel = createIOParamTab(); addTab("I/O Parameters", ioParamPanel); } JPanel processingParamPanel = new JPanel(new SpringLayout()); checkDisplayOutput = new JCheckBox("Display execution output"); checkDisplayOutput.setSelected(Boolean.parseBoolean(NbPreferences.forModule(Dialogs.class).get(ToolAdapterOptionsController.PREFERENCE_KEY_SHOW_EXECUTION_OUTPUT, "false"))); processingParamPanel.add(checkDisplayOutput); bottomPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); bottomPane.setTopComponent(createProcessingParamTab()); console = new ConsolePane(); if (checkDisplayOutput.isSelected()) { bottomPane.setBottomComponent(console); bottomPane.setDividerLocation(0.6); } processingParamPanel.add(bottomPane); checkDisplayOutput.addActionListener((ActionEvent e) -> { if (!checkDisplayOutput.isSelected()) { bottomPane.remove(console); } else { bottomPane.setBottomComponent(console); } refreshDimension(); }); Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); setPreferredSize(new Dimension((int)(screen.getWidth() / 3), (int)(screen.getHeight() / 2.5))); setMinimumSize(new Dimension(200, 200)); SpringUtilities.makeCompactGrid(processingParamPanel, 2, 1, 2, 2, 2, 2); addTab("Processing Parameters", processingParamPanel); updateTargetProductFields(); } /** * Reset the split procentage to 60%. */ public void refreshDimension(){ bottomPane.setDividerLocation(0.6); bottomPane.revalidate(); bottomPane.repaint(); } /** * Method called before actually showing the form, in which additional * initialisation may occur. */ public void prepareShow() { if (ioParamPanel != null) { ioParamPanel.initSourceProductSelectors(); } } /** * Method called before hiding the form, in which additional * cleanup may be performed. */ public void prepareHide() { if (ioParamPanel != null) { ioParamPanel.releaseSourceProductSelectors(); } } /** * Fetches the list of products selected in UI * * @return The list of selected products to be used as input source */ public Product[] getSourceProducts() { List<Product> sourceProducts = new ArrayList<>(); if (ioParamPanel != null){ ArrayList<SourceProductSelector> sourceProductSelectorList = ioParamPanel.getSourceProductSelectorList(); sourceProducts.addAll(sourceProductSelectorList.stream().map(SourceProductSelector::getSelectedProduct).collect(Collectors.toList())); } return sourceProducts.toArray(new Product[sourceProducts.size()]); } public Object getPropertyValue(String propertyName) { Object result = null; if (propertySet.isPropertyDefined(propertyName)) { result = propertySet.getProperty(propertyName).getValue(); } return result; } /** * Gets the target (destination) product file * * @return The target product file */ public File getTargetProductFile() { return targetProductSelector.getModel().getProductFile(); } public boolean shouldDisplayOutput() { return checkDisplayOutput.isSelected(); } private DefaultIOParametersPanel createIOParamTab() { final DefaultIOParametersPanel ioPanel = new DefaultIOParametersPanel(appContext, operatorDescriptor, targetProductSelector, !operatorDescriptor.isHandlingOutputName()); final ArrayList<SourceProductSelector> sourceProductSelectorList = ioPanel.getSourceProductSelectorList(); if (!sourceProductSelectorList.isEmpty()) { final SourceProductSelector sourceProductSelector = sourceProductSelectorList.get(0); sourceProductSelector.addSelectionChangeListener(new SourceProductChangeListener()); } return ioPanel; } private JScrollPane createProcessingParamTab() { Arrays.stream(operatorDescriptor.getToolParameterDescriptors().toArray()).filter(p -> !((ToolParameterDescriptor)p).isTemplateParameter()).forEach(p -> { ToolParameterDescriptor param = (ToolParameterDescriptor)p; String label = param.getAlias(); String propName = param.getName(); if (label != null && !label.isEmpty() && propertySet.isPropertyDefined(propName)) { Property property = propertySet.getProperty(propName); property.getDescriptor().setDisplayName(label); } }); Arrays.stream(operatorDescriptor.getToolParameterDescriptors().toArray()).filter(p -> ((ToolParameterDescriptor)p).isTemplateParameter()).forEach(p -> { TemplateParameterDescriptor param = (TemplateParameterDescriptor)p; propertySet.getProperty(param.getName()).getDescriptor().setAttribute("visible", false); Arrays.stream(param.getParameterDescriptors().toArray()).forEach(pp -> { ToolParameterDescriptor paramm = (ToolParameterDescriptor)pp; String label = paramm.getAlias(); String propName = paramm.getName(); if (label != null && !label.isEmpty() && propertySet.isPropertyDefined(propName)) { Property property = propertySet.getProperty(propName); property.getDescriptor().setDisplayName(label); } }); }); PropertyPane parametersPane = new PropertyPane(propertySet); final JPanel parametersPanel = parametersPane.createPanel(); parametersPanel.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (!(evt.getNewValue() instanceof JTextField)) return; JTextField field = (JTextField) evt.getNewValue(); String text = field.getText(); if (text != null && text.isEmpty()) { field.setCaretPosition(text.length()); } } }); parametersPanel.setBorder(new EmptyBorder(4, 4, 4, 4)); //parametersPanel.setPreferredSize(ioParamPanel.getPreferredSize()); return new JScrollPane(parametersPanel); } private void updateTargetProductFields() { TargetProductSelectorModel model = targetProductSelector.getModel(); Property property = propertySet.getProperty(ToolAdapterConstants.TOOL_TARGET_PRODUCT_FILE); model.setSaveToFileSelected(false); if (!operatorDescriptor.isHandlingOutputName()) { Object value = property.getValue(); if (value != null) { File file = operatorDescriptor.resolveVariables(new File(property.getValueAsText())); if (!file.isAbsolute()) { file = new File(operatorDescriptor.getWorkingDir(), file.getAbsolutePath()); } String productName = FileUtils.getFilenameWithoutExtension(file); if (fileExtension == null) { fileExtension = FileUtils.getExtension(file); } model.setProductName(productName); } } else { try { model.setProductName("Output Product"); if (property != null) { property.setValue(null); } targetProductSelector.setEnabled(false); targetProductSelector.getSaveToFileCheckBox().setEnabled(false); } catch (ValidationException e) { Logger.getLogger(ToolExecutionForm.class.getName()).severe(e.getMessage()); } } targetProductSelector.getProductDirTextField().setEnabled(false); } private class SourceProductChangeListener extends AbstractSelectionChangeListener { private static final String TARGET_PRODUCT_NAME_SUFFIX = "_processed"; @Override public void selectionChanged(SelectionChangeEvent event) { if (!operatorDescriptor.isHandlingOutputName()) { Property targetProperty = propertySet.getProperty(ToolAdapterConstants.TOOL_TARGET_PRODUCT_FILE); Object value = targetProperty.getValue(); String productName = ""; final Product selectedProduct = (Product) event.getSelection().getSelectedValue(); if (selectedProduct != null) { productName = FileUtils.getFilenameWithoutExtension(selectedProduct.getName()); } final TargetProductSelectorModel targetProductSelectorModel = targetProductSelector.getModel(); productName += TARGET_PRODUCT_NAME_SUFFIX; targetProductSelectorModel.setProductName(productName); if (value != null) { File oldValue = operatorDescriptor.resolveVariables(value instanceof File ? (File) value : new File((String) value)); if (fileExtension == null) fileExtension = TIF_EXTENSION; File current; File workingDir = operatorDescriptor.getWorkingDir(); File parent; if (oldValue != null && (parent = oldValue.getParentFile()) != null) { current = new File(parent.getAbsolutePath(), productName + fileExtension); } else { current = new File(workingDir, productName + fileExtension); } propertySet.setValue(ToolAdapterConstants.TOOL_TARGET_PRODUCT_FILE, current); } else { File workingDir = operatorDescriptor.resolveVariables(operatorDescriptor.getWorkingDir()); try { targetProperty.setValue(new File(workingDir, productName + TIF_EXTENSION)); } catch (ValidationException ignored) { } } } } } }