AdditiveLoadFileOrUrlChooser.java
/**
* VStar: a statistical analysis tool for variable star data.
* Copyright (C) 2013 AAVSO (http://www.aavso.org/)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.aavso.tools.vstar.ui.dialog;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import org.aavso.tools.vstar.plugin.InputType;
import org.aavso.tools.vstar.plugin.ObservationSourcePluginBase;
import org.aavso.tools.vstar.plugin.PluginComponentFactory;
import org.aavso.tools.vstar.ui.dialog.plugin.manager.PluginManager;
import org.aavso.tools.vstar.ui.resources.PluginLoader;
import org.aavso.tools.vstar.util.Pair;
import org.aavso.tools.vstar.util.help.Help;
import org.aavso.tools.vstar.util.locale.LocaleProps;
/**
* This class aggregates a JFileChooser and additive load checkbox and URL entry
* components.
*/
public class AdditiveLoadFileOrUrlChooser {
private JFileChooser fileChooser;
private JCheckBox additiveLoadCheckbox;
private boolean urlProvided;
private boolean obsTextProvided;
private JButton urlRequestButton;
private JButton obsTextRequestButton;
private TextField urlField;
private TextArea obsTextField;
private TextArea velaFilterField;
private List<String> DEFAULT_EXTENSIONS = new ArrayList<String>();
private List<String> extensions = new ArrayList<String>();
private Map<String, ObservationSourcePluginBase> plugins;
private JComboBox<String> pluginChooser;
/**
* Constructor
*
* @param allowURL Should a URL entry be allowed?
* @param allowText Should a text entry be allowed?
*/
public AdditiveLoadFileOrUrlChooser(boolean allowURL, boolean allowText) {
fileChooser = new JFileChooser();
fileChooser.setMultiSelectionEnabled(true);
urlProvided = false;
plugins = new TreeMap<String, ObservationSourcePluginBase>();
// Default file extensions.
DEFAULT_EXTENSIONS.add("csv");
DEFAULT_EXTENSIONS.add("dat");
DEFAULT_EXTENSIONS.add("tsv");
DEFAULT_EXTENSIONS.add("txt");
setFileExtensions(DEFAULT_EXTENSIONS);
JPanel accessoryPane = new JPanel();
accessoryPane.setLayout(new BoxLayout(accessoryPane, BoxLayout.PAGE_AXIS));
accessoryPane.add(createAdditiveLoadCheckboxPane());
accessoryPane.add(createUrlPane());
accessoryPane.add(createObsTextPane());
if (!PluginManager.shouldAllObsSourcePluginsBeInFileMenu()) {
accessoryPane.add(createPluginsList());
}
Pair<TextArea, JPanel> pair = PluginComponentFactory.createVeLaFilterPane();
velaFilterField = pair.first;
accessoryPane.add(pair.second);
fileChooser.setAccessory(accessoryPane);
}
/**
* Returns the default file extensions.
*
* @return the list of file extension strings.
*/
public List<String> getDefaultFileExtensions() {
return extensions;
}
/**
* Set file chooser extensions filter.
*
* @param extensions the list of extensions to filter files with
*/
public synchronized void setFileExtensions(List<String> extensions) {
fileChooser.removeChoosableFileFilter(fileChooser.getFileFilter());
fileChooser.setFileFilter(new FileExtensionFilter(extensions));
}
/**
* Returns the content of the VeLa filter field.
*
* @return the string content of the VeLa filter field.
*/
public String getVeLaFilter() {
return velaFilterField.getValue().trim();
}
/**
* This component provides an additive load checkbox.
*/
private JPanel createAdditiveLoadCheckboxPane() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Additive Load"));
additiveLoadCheckbox = new JCheckBox("Add to current?");
panel.add(additiveLoadCheckbox);
return panel;
}
/**
* This component creates a URL request button and corresponding action.
*/
private JPanel createUrlPane() {
JPanel pane = new JPanel();
urlRequestButton = new JButton("Request URL");
urlRequestButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
urlField = new TextField("URL");
TextDialog urlDialog = new TextDialog("Enter URL", urlField);
if (!urlDialog.isCancelled() && !urlField.getValue().matches("^\\s*$")) {
urlProvided = true;
fileChooser.approveSelection();
}
}
});
pane.add(urlRequestButton);
return pane;
}
/**
* This component creates an observation text request button and corresponding
* action.
*/
private JPanel createObsTextPane() {
JPanel pane = new JPanel();
obsTextRequestButton = new JButton("Request Observation Text");
obsTextRequestButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
obsTextField = new TextArea("Observation Text", "", 30, 60, false, false);
TextDialog obsTextDialog = new TextDialog("Enter Observation Text", true, true, obsTextField);
if (!obsTextDialog.isCancelled() && !obsTextField.getValue().matches("^\\s*$")) {
obsTextProvided = true;
fileChooser.approveSelection();
}
}
});
pane.add(obsTextRequestButton);
return pane;
}
/**
* Create plugin list and add a listener to change extensions when a plugin is
* selected.
*/
private JPanel createPluginsList() {
JPanel pane = new JPanel();
pane.setBorder(BorderFactory.createTitledBorder("Source"));
for (ObservationSourcePluginBase plugin : PluginLoader.getObservationSourcePlugins()) {
switch (plugin.getInputType()) {
case FILE:
case FILE_OR_URL:
String name = plugin.getDisplayName();
if (name.equals(LocaleProps.get("FILE_MENU_NEW_STAR_FROM_FILE"))) {
// Handle localised "New Star from File"
name = LocaleProps.get("TEXT_FORMAT_FILE");
} else {
// Shorten other "New Star from " plugin names.
name = name.replace("New Star from ", "");
name = name.replace(" File", "");
name = name.replace("...", "");
}
plugins.put(name, plugin);
default:
}
}
pluginChooser = new JComboBox<String>(plugins.keySet().toArray(new String[0]));
pluginChooser.setSelectedItem(LocaleProps.get("TEXT_FORMAT_FILE"));
// pluginChooser.setBorder(BorderFactory.createTitledBorder("Source"));
pluginChooser.addActionListener(e -> {
updateFileAndUrlWidgetsForPlugin();
});
pane.add(pluginChooser);
JButton helpButton = new JButton("?");
helpButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Optional<ObservationSourcePluginBase> plugin = getSelectedPlugin();
Help.openPluginHelp(plugin.isPresent() ? plugin.get().getDocName() : null);
}
});
pane.add(helpButton);
return pane;
}
/**
* Show the file dialog.
*
* @param parent The parent component to which this dialog should be positioned
* relative.
* @return Whether the dialog was "approved".
*/
public synchronized boolean showDialog(Component parent) {
if (!PluginManager.shouldAllObsSourcePluginsBeInFileMenu()) {
updateFileAndUrlWidgetsForPlugin();
}
int result = fileChooser.showOpenDialog(parent);
return result == JFileChooser.APPROVE_OPTION;
}
/**
* Set the multiple file selection state.
*
* @param isAllowed Is multiple file selection permitted?
*/
public void setMultiFileSelectionState(boolean isAllowed) {
fileChooser.setMultiSelectionEnabled(isAllowed);
}
/**
* @return The selected files.
*/
public File[] getSelectedFiles() {
File[] selectedFiles = null;
if (fileChooser.isMultiSelectionEnabled()) {
selectedFiles = fileChooser.getSelectedFiles();
} else {
selectedFiles = new File[] { fileChooser.getSelectedFile() };
}
return selectedFiles;
}
/**
* Was a URL string of some kind provided and accepted?
*
* @return True or false.
*/
public boolean isUrlProvided() {
return urlProvided;
}
/**
* @param urlProvided the urlProvided to set
*/
public synchronized void setUrlProvided(boolean urlProvided) {
this.urlProvided = urlProvided;
}
/**
* @return The URL string.
*/
public String getUrlString() {
return urlField.getValue().trim();
}
public boolean isObsTextProvided() {
return obsTextProvided;
}
public void setObsTextProvided(boolean obsTextProvided) {
this.obsTextProvided = obsTextProvided;
}
public String getObsTextString() {
return obsTextField.getValue().trim();
}
/**
* Return whether or not the load is additive.
*
* @return Whether or not the load is additive.
*/
public boolean isLoadAdditive() {
return additiveLoadCheckbox.isSelected();
}
/**
* Return the optional currently selected observation source plugin.
*
* @return The optional plugin instance.
*/
public Optional<ObservationSourcePluginBase> getSelectedPlugin() {
Optional<ObservationSourcePluginBase> plugin;
if (PluginManager.shouldAllObsSourcePluginsBeInFileMenu()) {
plugin = Optional.empty();
} else {
plugin = Optional.of(plugins.get(pluginChooser.getSelectedItem()));
}
return plugin;
}
/**
* Reset this file selector's state before use.
*/
public synchronized void reset() {
setUrlProvided(false);
setObsTextProvided(false);
}
// Helpers
private void updateFileAndUrlWidgetsForPlugin() {
String name = (String) pluginChooser.getSelectedItem();
ObservationSourcePluginBase plugin = plugins.get(name);
fileChooser.setMultiSelectionEnabled(plugin.isMultipleFileSelectionAllowed());
if (plugin.getAdditionalFileExtensions() != null) {
List<String> newFileExtensions = new ArrayList<String>();
newFileExtensions.addAll(plugin.getAdditionalFileExtensions());
setFileExtensions(newFileExtensions);
} else {
setFileExtensions(DEFAULT_EXTENSIONS);
}
boolean urlAllowed = plugin.getInputType() == InputType.FILE_OR_URL;
urlRequestButton.setEnabled(urlAllowed);
obsTextRequestButton.setEnabled(plugin.isTextSource());
}
}