+package net.sf.openrocket.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.FlightDataBranch.Type;
+import net.sf.openrocket.unit.Unit;
+
+
+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 FlightDataBranch.Type[] 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,
+ Type[] 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
+ 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) {
+ System.err.println("Error closing file: ");
+ e.printStackTrace();
+ }
+ }
+ 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,
+ Type[] 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 RuntimeException("Unknown error when saving file", e);
+ }
+
+ } catch (InterruptedException e) {
+ throw new RuntimeException("EDT was interrupted", e);
+ }
+
+ return true;
+ }
+}