package org.signalml.app.view.document.opensignal.elements;
import static org.signalml.app.util.i18n.SvarogI18n._;
import static org.signalml.app.util.i18n.SvarogI18n._R;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.JTabbedPane;
import org.apache.log4j.Logger;
import org.signalml.app.SvarogApplication;
import org.signalml.app.action.document.RegisterCodecAction;
import org.signalml.app.document.ManagedDocumentType;
import org.signalml.app.document.signal.SignalMLDocument;
import org.signalml.app.model.document.opensignal.AbstractOpenSignalDescriptor;
import org.signalml.app.model.document.opensignal.SignalMLDescriptor;
import org.signalml.app.model.document.opensignal.elements.FileOpenSignalMethod;
import org.signalml.app.model.document.opensignal.elements.SignalSource;
import org.signalml.app.view.common.components.filechooser.FileChooserPanel;
import org.signalml.app.view.common.dialogs.errors.Dialogs;
import org.signalml.app.view.workspace.ViewerElementManager;
import org.signalml.app.worker.document.OpenSignalMLDocumentWorker;
import org.signalml.codec.SignalMLCodec;
import org.signalml.codec.SignalMLCodecManager;
import org.signalml.domain.signal.raw.RawSignalDescriptor;
import org.signalml.domain.signal.raw.RawSignalDescriptorReader;
import org.signalml.util.Util;
public class SignalSourceTabbedPane extends JTabbedPane implements PropertyChangeListener, ItemListener {
protected static final Logger logger = Logger.getLogger(SignalSourceTabbedPane.class);
public static final String OPEN_SIGNAL_DESCRIPTOR_PROPERTY = "openSignalDescriptorProperty";
private ViewerElementManager viewerElementManager;
/**
* The panel for choosing a file to be opened.
*/
private FileChooserPanel fileChooserPanel;
private ChooseExperimentPanel chooseExperimentPanel;
private AbstractOpenSignalDescriptor openSignalDescriptor;
private Object fileTypeMethod = FileOpenSignalMethod.AUTODETECT;
public SignalSourceTabbedPane(ViewerElementManager viewerElementManager) {
this.viewerElementManager = viewerElementManager;
addTab(_("FILE"), getFileChooserPanel());
addTab(_("ONLINE"), getChooseExperimentPanel());
}
/**
* Returns the panel for choosing which signal file should be opened.
* @return the panel for choosing which signal file should be opened
*/
public FileChooserPanel getFileChooserPanel() {
if (fileChooserPanel == null) {
fileChooserPanel = new FileChooserPanel(ManagedDocumentType.SIGNAL);
String lastFileChooserPath = SvarogApplication.getApplicationConfiguration().getLastFileChooserPath();
getFileChooserPanel().getFileChooser().setCurrentDirectory(new File(lastFileChooserPath));
fileChooserPanel.getFileChooser().addPropertyChangeListener(this);
}
return fileChooserPanel;
}
public ChooseExperimentPanel getChooseExperimentPanel() {
if (chooseExperimentPanel == null) {
chooseExperimentPanel = new ChooseExperimentPanel();
chooseExperimentPanel.addPropertyChangeListener(this);
}
return chooseExperimentPanel;
}
public SignalSource getSelectedSignalSource() {
if (getSelectedComponent() == getFileChooserPanel())
return SignalSource.FILE;
return SignalSource.OPENBCI;
}
@Override
public void propertyChange(PropertyChangeEvent event) {
String propertyName = event.getPropertyName();
if (JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals(propertyName)
|| RegisterCodecAction.CODEC_REGISTERED.equals(propertyName)) {
updatedSelectedFile();
}
else if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(propertyName)) {
openSignalDescriptor = null;
fireOpenSignalDescriptorChanged();
}
else if (ChooseExperimentPanel.EXPERIMENT_SELECTED_PROPERTY.equals(propertyName)) {
updateSelectedExperiment();
}
}
protected void updateSelectedExperiment() {
openSignalDescriptor = chooseExperimentPanel.getSelectedExperiment();
fireOpenSignalDescriptorChanged();
}
protected void updatedSelectedFile() {
File file = fileChooserPanel.getSelectedFile();
if (file == null || file.isDirectory()) {
openSignalDescriptor = null;
fireOpenSignalDescriptorChanged();
return;
}
if (fileTypeMethod == FileOpenSignalMethod.AUTODETECT)
autodetectFileTypeAndReadMetadata(file);
else if (fileTypeMethod == FileOpenSignalMethod.RAW)
readRawFileMetadata(file);
else if (fileTypeMethod instanceof SignalMLCodec) {
SignalMLCodec codec = (SignalMLCodec) fileTypeMethod;
readSignalMLMetadata(file, codec);
}
else {
openSignalDescriptor = null;
}
fireOpenSignalDescriptorChanged();
}
protected void autodetectFileTypeAndReadMetadata(File file) {
String extension = Util.getFileExtension(file, false);
if ("edf".equalsIgnoreCase(extension) || "d".equals(extension)){
String formatName = null;
if (extension.equalsIgnoreCase("edf")) {
formatName = "EDF";
}
else if (extension.equalsIgnoreCase("d")) {
formatName = "EASYS";
}
SignalMLCodecManager codecManager = viewerElementManager.getCodecManager();
SignalMLCodec codec = codecManager.getCodecForFormat(formatName);
if (codec == null) {
openSignalDescriptor = null;
Dialogs.showError(_("No SignalML codec was found to open this file!"));
fireOpenSignalDescriptorChanged();
return;
}
readSignalMLMetadata(file, codec);
} else {
readRawFileMetadata(file);
}
}
protected void fireOpenSignalDescriptorChanged() {
firePropertyChange(OPEN_SIGNAL_DESCRIPTOR_PROPERTY, null, openSignalDescriptor);
}
protected void readSignalMLMetadata(File signalFile, SignalMLCodec codec) {
File file = getFileChooserPanel().getSelectedFile();
OpenSignalMLDocumentWorker worker = new OpenSignalMLDocumentWorker(codec, file);
worker.execute();
SignalMLDocument signalMLDocument = null;
try {
signalMLDocument = worker.get();
openSignalDescriptor = new SignalMLDescriptor(signalMLDocument);
openSignalDescriptor.setCorrectlyRead(true);
signalMLDocument.closeDocument();
} catch (Exception e) {
Dialogs.showError(_R("There was an error while loading the file - did you select a correct SignalML file?"));
logger.error("", e);
openSignalDescriptor = null;
}
}
protected void readRawFileMetadata(File signalFile) {
File xmlManifestFile = Util.changeOrAddFileExtension(signalFile, "xml");
if (!xmlManifestFile.exists())
xmlManifestFile = Util.changeOrAddFileExtension(signalFile, "svarog.info");
RawSignalDescriptorReader reader = new RawSignalDescriptorReader();
openSignalDescriptor = null;
if (!xmlManifestFile.exists()) {
if (Dialogs.DIALOG_OPTIONS.YES == Dialogs.showWarningYesNoDialog(_("XML manifest not found - would you like to choose the XML file manualy?"))) {
JFileChooser fileChooser = new JFileChooser(signalFile);
fileChooser.showOpenDialog(null);
xmlManifestFile = fileChooser.getSelectedFile();
if (xmlManifestFile == null)
return;
}
else {
openSignalDescriptor = new RawSignalDescriptor();
openSignalDescriptor.setCorrectlyRead(false);
return;
}
}
try {
openSignalDescriptor = reader.readDocument(xmlManifestFile);
openSignalDescriptor.setCorrectlyRead(true);
} catch (Exception e) {
logger.error("", e);
Dialogs.showError(_("There was an error while reading the XML manifest. Please input the signal parameters manually."));
openSignalDescriptor = new RawSignalDescriptor();
openSignalDescriptor.setCorrectlyRead(false);
}
}
public AbstractOpenSignalDescriptor getOpenSignalDescriptor() {
return openSignalDescriptor;
}
@Override
protected void fireStateChanged() {
if (this.getSelectedComponent() == fileChooserPanel) {
updatedSelectedFile();
}
else {
updateSelectedExperiment();
}
super.fireStateChanged();
}
/**
* Invoked when the selected file type changed.
* @param
*/
@Override
public void itemStateChanged(ItemEvent event) {
if (event.getStateChange() == ItemEvent.SELECTED) {
fileTypeMethod = event.getItem();
fireStateChanged();
}
}
public void onDialogCloseWithOK() {
if (getSelectedSignalSource() == SignalSource.FILE)
getFileChooserPanel().getFileChooser().lastDirectoryChanged();
}
}