Fix refresh bug which sometimes happens when the plot configuration is changed. ...
[debian/openrocket] / core / src / net / sf / openrocket / gui / util / SaveCSVWorker.java
1 package net.sf.openrocket.gui.util;
2
3 import java.awt.Window;
4 import java.io.BufferedOutputStream;
5 import java.io.File;
6 import java.io.FileOutputStream;
7 import java.io.IOException;
8 import java.util.concurrent.ExecutionException;
9
10 import javax.swing.JOptionPane;
11 import javax.swing.SwingWorker;
12
13 import net.sf.openrocket.document.Simulation;
14 import net.sf.openrocket.file.CSVExport;
15 import net.sf.openrocket.gui.dialogs.SwingWorkerDialog;
16 import net.sf.openrocket.simulation.FlightDataBranch;
17 import net.sf.openrocket.simulation.FlightDataType;
18 import net.sf.openrocket.startup.Application;
19 import net.sf.openrocket.unit.Unit;
20 import net.sf.openrocket.util.BugException;
21
22
23 public class SaveCSVWorker extends SwingWorker<Void, Void> {
24         
25         private static final int BYTES_PER_FIELD_PER_POINT = 7;
26
27         private final File file;
28         private final Simulation simulation;
29         private final FlightDataBranch branch;
30         private final FlightDataType[] fields;
31         private final Unit[] units;
32         private final String fieldSeparator;
33         private final String commentStarter;
34         private final boolean simulationComments;
35         private final boolean fieldComments;
36         private final boolean eventComments;
37         
38         
39         public SaveCSVWorker(File file, Simulation simulation, FlightDataBranch branch,
40                         FlightDataType[] fields, Unit[] units, String fieldSeparator, String commentStarter,
41                         boolean simulationComments, boolean fieldComments, boolean eventComments) {
42                 this.file = file;
43                 this.simulation = simulation;
44                 this.branch = branch;
45                 this.fields = fields;
46                 this.units = units;
47                 this.fieldSeparator = fieldSeparator;
48                 this.commentStarter = commentStarter;
49                 this.simulationComments = simulationComments;
50                 this.fieldComments = fieldComments;
51                 this.eventComments = eventComments;
52         }
53
54
55         @Override
56         protected Void doInBackground() throws Exception {
57                 
58                 int estimate = BYTES_PER_FIELD_PER_POINT * fields.length * branch.getLength();
59                 estimate = Math.max(estimate, 1000);
60                 
61                 // Create the ProgressOutputStream that provides progress estimates
62                 ProgressOutputStream os = new ProgressOutputStream(
63                                 new BufferedOutputStream(new FileOutputStream(file)), 
64                                 estimate, this) {
65                         
66                         @Override
67                         protected void setProgress(int progress) {
68                                 SaveCSVWorker.this.setProgress(progress);
69                         }
70                         
71                 };
72                 
73                 try {
74                         CSVExport.exportCSV(os, simulation, branch, fields, units, fieldSeparator, 
75                                         commentStarter, simulationComments, fieldComments, eventComments);
76                 } finally {
77                         try {
78                                 os.close();
79                         } catch (Exception e) {
80                                 Application.getExceptionHandler().handleErrorCondition("Error closing file", e);
81                         }
82                 }
83                 return null;
84         }
85         
86         
87         
88         /**
89          * Exports a CSV file using a progress dialog if necessary.
90          *
91          * @return      <code>true</code> if the save was successful, <code>false</code> otherwise.
92          */
93         public static boolean export(File file, Simulation simulation, FlightDataBranch branch,
94                         FlightDataType[] fields, Unit[] units, String fieldSeparator, String commentStarter,
95                         boolean simulationComments, boolean fieldComments, boolean eventComments,
96                         Window parent) {
97                 
98
99                 SaveCSVWorker worker = new SaveCSVWorker(file, simulation, branch, fields, units,
100                                 fieldSeparator, commentStarter, simulationComments, fieldComments, 
101                                 eventComments);
102                 
103             if (!SwingWorkerDialog.runWorker(parent, "Exporting flight data", 
104                         "Writing " + file.getName() + "...", worker)) {
105                 
106                 // User cancelled the save
107                 file.delete();
108                 return false;
109             }
110             
111             try {
112                         worker.get();
113                 } catch (ExecutionException e) {
114                         Throwable cause = e.getCause();
115                         
116                         if (cause instanceof IOException) {
117                         JOptionPane.showMessageDialog(parent, new String[] { 
118                                         "An I/O error occurred while saving:",
119                                         e.getMessage() }, "Saving failed", JOptionPane.ERROR_MESSAGE);
120                         return false;
121                         } else {
122                                 throw new BugException("Unknown error when saving file", e);
123                         }
124                         
125                 } catch (InterruptedException e) {
126                         throw new BugException("EDT was interrupted", e);
127                 }
128                 
129                 return true;
130         }
131 }