package net.sf.openrocket.gui.util;
import java.awt.Window;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.file.CSVExport;
import net.sf.openrocket.gui.dialogs.SwingWorkerDialog;
import net.sf.openrocket.simulation.FlightDataBranch;
import net.sf.openrocket.simulation.FlightDataType;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.Unit;
import net.sf.openrocket.util.BugException;
public class SaveCSVWorker extends SwingWorker<Void, Void> {
private static final int BYTES_PER_FIELD_PER_POINT = 7;
private final File file;
private final Simulation simulation;
private final FlightDataBranch branch;
private final FlightDataType[] fields;
private final Unit[] units;
private final String fieldSeparator;
private final String commentStarter;
private final boolean simulationComments;
private final boolean fieldComments;
private final boolean eventComments;
public SaveCSVWorker(File file, Simulation simulation, FlightDataBranch branch,
FlightDataType[] fields, Unit[] units, String fieldSeparator, String commentStarter,
boolean simulationComments, boolean fieldComments, boolean eventComments) {
this.file = file;
this.simulation = simulation;
this.branch = branch;
this.fields = fields;
this.units = units;
this.fieldSeparator = fieldSeparator;
this.commentStarter = commentStarter;
this.simulationComments = simulationComments;
this.fieldComments = fieldComments;
this.eventComments = eventComments;
}
@Override
protected Void doInBackground() throws Exception {
int estimate = BYTES_PER_FIELD_PER_POINT * fields.length * branch.getLength();
estimate = Math.max(estimate, 1000);
// Create the ProgressOutputStream that provides progress estimates
@SuppressWarnings("resource")
ProgressOutputStream os = new ProgressOutputStream(
new BufferedOutputStream(new FileOutputStream(file)),
estimate, this) {
@Override
protected void setProgress(int progress) {
SaveCSVWorker.this.setProgress(progress);
}
};
try {
CSVExport.exportCSV(os, simulation, branch, fields, units, fieldSeparator,
commentStarter, simulationComments, fieldComments, eventComments);
} finally {
try {
os.close();
} catch (Exception e) {
Application.getExceptionHandler().handleErrorCondition("Error closing file", e);
}
}
return null;
}
/**
* Exports a CSV file using a progress dialog if necessary.
*
* @return <code>true</code> if the save was successful, <code>false</code> otherwise.
*/
public static boolean export(File file, Simulation simulation, FlightDataBranch branch,
FlightDataType[] fields, Unit[] units, String fieldSeparator, String commentStarter,
boolean simulationComments, boolean fieldComments, boolean eventComments,
Window parent) {
SaveCSVWorker worker = new SaveCSVWorker(file, simulation, branch, fields, units,
fieldSeparator, commentStarter, simulationComments, fieldComments,
eventComments);
if (!SwingWorkerDialog.runWorker(parent, "Exporting flight data",
"Writing " + file.getName() + "...", worker)) {
// User cancelled the save
file.delete();
return false;
}
try {
worker.get();
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause instanceof IOException) {
JOptionPane.showMessageDialog(parent, new String[] {
"An I/O error occurred while saving:",
e.getMessage() }, "Saving failed", JOptionPane.ERROR_MESSAGE);
return false;
} else {
throw new BugException("Unknown error when saving file", e);
}
} catch (InterruptedException e) {
throw new BugException("EDT was interrupted", e);
}
return true;
}
}