/*
* 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.timeseries.ui;
import com.bc.ceres.swing.TableLayout;
import com.jidesoft.swing.FolderChooser;
import org.esa.snap.core.dataio.ProductIOPlugIn;
import org.esa.snap.core.dataio.ProductIOPlugInManager;
import org.esa.snap.core.ui.UIUtils;
import org.esa.snap.core.ui.tool.ToolButtonFactory;
import org.esa.snap.rcp.SnapApp;
import org.esa.snap.timeseries.core.timeseries.datamodel.ProductLocation;
import org.esa.snap.timeseries.core.timeseries.datamodel.ProductLocationType;
import org.esa.snap.util.SystemUtils;
import org.esa.snap.util.io.SnapFileChooser;
import org.esa.snap.util.io.SnapFileFilter;
import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.filechooser.FileFilter;
import java.awt.Component;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.Iterator;
import java.util.prefs.Preferences;
/**
* UI element for managing product locations.
* @author Marco Peters
*/
public class ProductLocationsPane extends JPanel {
private static final String PROPERTY_KEY_LAST_OPEN_TS_DIR = "timeseries.file.lastOpenDir";
public static final String ALL_FILES = "ALL_FILES";
private ProductLocationsPaneModel model;
private JList sourceList;
private AbstractButton addButton;
private AbstractButton removeButton;
public ProductLocationsPane() {
this(new DefaultProductLocationsPaneModel());
}
public ProductLocationsPane(ProductLocationsPaneModel model) {
this.model = model;
createPane();
}
public void setModel(ProductLocationsPaneModel model, boolean enabled) {
this.model = model;
updatePane(enabled);
}
private void createPane() {
final TableLayout tableLayout = new TableLayout(2);
tableLayout.setTableAnchor(TableLayout.Anchor.NORTHWEST);
tableLayout.setColumnFill(0, TableLayout.Fill.BOTH);
tableLayout.setColumnFill(1, TableLayout.Fill.HORIZONTAL);
tableLayout.setTablePadding(4, 4);
tableLayout.setTableWeightY(1.0);
tableLayout.setColumnWeightX(0, 1.0);
tableLayout.setColumnWeightX(1, 0.0);
tableLayout.setColumnWeightY(1, 0.0);
tableLayout.setCellRowspan(0, 0, 2);
setLayout(tableLayout);
sourceList = new JList(model);
sourceList.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
boolean cellHasFocus) {
final JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected,
cellHasFocus);
if (value instanceof ProductLocation) {
final ProductLocation location = (ProductLocation) value;
String path = location.getPath();
if (location.getProductLocationType() != ProductLocationType.FILE) {
if (!path.endsWith(File.separator)) {
path += File.separator;
}
}
if (location.getProductLocationType() == ProductLocationType.DIRECTORY) {
path += "*";
}
if (location.getProductLocationType() == ProductLocationType.DIRECTORY_REC) {
path += "**";
}
label.setText(path);
}
return label;
}
});
addButton = ToolButtonFactory.createButton(UIUtils.loadImageIcon("icons/Plus24.gif"), false);
addButton.addActionListener(e -> {
final JPopupMenu popup = new JPopupMenu("Add");
final Rectangle buttonBounds = addButton.getBounds();
popup.add(new AddDirectoryAction(false));
popup.add(new AddDirectoryAction(true));
popup.add(new AddFileAction());
popup.show(addButton, 1, buttonBounds.height + 1);
});
removeButton = ToolButtonFactory.createButton(UIUtils.loadImageIcon("icons/Minus24.gif"), false);
removeButton.addActionListener(e -> model.remove(sourceList.getSelectedIndices()));
add(new JScrollPane(sourceList));
add(addButton);
add(removeButton, TableLayout.cell(1, 1));
}
private void updatePane(boolean enabled) {
sourceList.setModel(model);
addButton.setEnabled(enabled);
removeButton.setEnabled(enabled);
}
private class AddDirectoryAction extends AbstractAction {
private boolean recursive;
private AddDirectoryAction(boolean recursive) {
this("Add Directory" + (recursive ? " Recursive" : ""));
this.recursive = recursive;
}
protected AddDirectoryAction(String title) {
super(title);
}
@Override
public void actionPerformed(ActionEvent e) {
final FolderChooser folderChooser = new FolderChooser();
final Preferences preferences = SnapApp.getDefault().getPreferences();
String lastDir = preferences.get(PROPERTY_KEY_LAST_OPEN_TS_DIR, SystemUtils.getUserHomeDir().getPath());
folderChooser.setCurrentDirectory(new File(lastDir));
final int result = folderChooser.showOpenDialog(ProductLocationsPane.this);
if (result != JFileChooser.APPROVE_OPTION) {
return;
}
File currentDir = folderChooser.getSelectedFolder();
model.addDirectory(currentDir, recursive);
if (currentDir != null) {
preferences.put(PROPERTY_KEY_LAST_OPEN_TS_DIR, currentDir.getAbsolutePath());
}
}
}
private class AddFileAction extends AbstractAction {
private AddFileAction() {
super("Add Product(s)");
}
@Override
public void actionPerformed(ActionEvent e) {
final SnapApp snapApp = SnapApp.getDefault();
final Preferences preferences = snapApp.getPreferences();
String lastDir = preferences.get(PROPERTY_KEY_LAST_OPEN_TS_DIR, SystemUtils.getUserHomeDir().getPath());
String lastFormat = preferences.get("app.file.lastOpenDir", ALL_FILES);
// todo - decide where to put those properties
// String lastFormat = preferences.get(VisatApp.PROPERTY_KEY_APP_LAST_OPEN_DIR, VisatApp.ALL_FILES_IDENTIFIER);
SnapFileChooser fileChooser = new SnapFileChooser();
fileChooser.setCurrentDirectory(new File(lastDir));
fileChooser.setAcceptAllFileFilterUsed(true);
fileChooser.setDialogTitle("Select Product(s)");
fileChooser.setMultiSelectionEnabled(true);
FileFilter actualFileFilter = fileChooser.getAcceptAllFileFilter();
Iterator allReaderPlugIns = ProductIOPlugInManager.getInstance().getAllReaderPlugIns();
while (allReaderPlugIns.hasNext()) {
final ProductIOPlugIn plugIn = (ProductIOPlugIn) allReaderPlugIns.next();
SnapFileFilter productFileFilter = plugIn.getProductFileFilter();
fileChooser.addChoosableFileFilter(productFileFilter);
if (!ALL_FILES.equals(lastFormat) &&
productFileFilter.getFormatName().equals(lastFormat)) {
actualFileFilter = productFileFilter;
}
}
fileChooser.setFileFilter(actualFileFilter);
int result = fileChooser.showDialog(snapApp.getMainFrame(), "Open Product"); /*I18N*/
if (result != JFileChooser.APPROVE_OPTION) {
return;
}
String currentDir = fileChooser.getCurrentDirectory().getAbsolutePath();
preferences.put(PROPERTY_KEY_LAST_OPEN_TS_DIR, currentDir);
if (fileChooser.getFileFilter() instanceof SnapFileFilter) {
String currentFormat = ((SnapFileFilter) fileChooser.getFileFilter()).getFormatName();
if (currentFormat != null) {
preferences.put("app.file.lastOpenFormat", currentFormat);
// todo - decide where to put those properties
// preferences.put(VisatApp.PROPERTY_KEY_APP_LAST_OPEN_FORMAT, currentFormat);
}
} else {
preferences.put("app.file.lastOpenFormat", ALL_FILES);
}
final File[] selectedFiles = fileChooser.getSelectedFiles();
model.addFiles(selectedFiles);
}
}
}