4 package net.sf.openrocket.gui.dialogs;
7 import java.awt.Desktop;
8 import java.awt.Window;
9 import java.awt.event.ActionEvent;
10 import java.awt.event.ActionListener;
12 import java.io.FileOutputStream;
13 import java.io.IOException;
14 import java.util.Enumeration;
15 import java.util.Iterator;
17 import javax.swing.JButton;
18 import javax.swing.JCheckBox;
19 import javax.swing.JDialog;
20 import javax.swing.JFileChooser;
21 import javax.swing.JLabel;
22 import javax.swing.JOptionPane;
23 import javax.swing.JPanel;
24 import javax.swing.JScrollPane;
25 import javax.swing.event.TreeSelectionEvent;
26 import javax.swing.event.TreeSelectionListener;
27 import javax.swing.tree.TreeNode;
28 import javax.swing.tree.TreePath;
30 import net.miginfocom.swing.MigLayout;
31 import net.sf.openrocket.document.OpenRocketDocument;
32 import net.sf.openrocket.gui.print.PrintController;
33 import net.sf.openrocket.gui.print.PrintSettings;
34 import net.sf.openrocket.gui.print.PrintableContext;
35 import net.sf.openrocket.gui.print.TemplateProperties;
36 import net.sf.openrocket.gui.print.components.CheckTreeManager;
37 import net.sf.openrocket.gui.print.components.RocketPrintTree;
38 import net.sf.openrocket.gui.util.FileHelper;
39 import net.sf.openrocket.gui.util.GUIUtil;
40 import net.sf.openrocket.gui.util.SwingPreferences;
41 import net.sf.openrocket.l10n.Translator;
42 import net.sf.openrocket.logging.LogHelper;
43 import net.sf.openrocket.rocketcomponent.Rocket;
44 import net.sf.openrocket.startup.Application;
47 * This class isolates the Swing components used to create a panel that is added to a standard Java print dialog.
49 public class PrintDialog extends JDialog implements TreeSelectionListener {
51 private static final LogHelper log = Application.getLogger();
52 private static final Translator trans = Application.getTranslator();
54 private final Desktop desktop;
56 private final RocketPrintTree stagedTree;
57 private final RocketPrintTree noStagedTree;
58 private OpenRocketDocument document;
59 private RocketPrintTree currentTree;
61 private JButton previewButton;
62 private JButton saveAsPDF;
63 private JButton cancel;
65 private double rotation = 0d;
67 private final static SwingPreferences prefs = (SwingPreferences) Application.getPreferences();
72 * @param parent the parent awt component
73 * @param orDocument the OR rocket container
74 * @param theRotation the angle of rocket figure rotation
76 public PrintDialog(Window parent, OpenRocketDocument orDocument, double theRotation) {
77 super(parent, trans.get("title"), ModalityType.APPLICATION_MODAL);
80 JPanel panel = new JPanel(new MigLayout("fill, gap rel unrel"));
82 rotation = theRotation;
84 // before any Desktop APIs are used, first check whether the API is
85 // supported by this particular VM on this particular host
86 if (Desktop.isDesktopSupported()) {
87 desktop = Desktop.getDesktop();
92 document = orDocument;
93 Rocket rocket = orDocument.getRocket();
95 noStagedTree = RocketPrintTree.create(rocket.getName());
96 noStagedTree.setShowsRootHandles(false);
97 CheckTreeManager ctm = new net.sf.openrocket.gui.print.components.CheckTreeManager(noStagedTree);
98 ctm.addTreeSelectionListener(this);
100 final int stages = rocket.getStageCount();
103 JLabel label = new JLabel(trans.get("lbl.selectElements"));
104 panel.add(label, "wrap unrel");
108 stagedTree = RocketPrintTree.create(rocket.getName(), rocket.getChildren());
109 ctm = new CheckTreeManager(stagedTree);
110 stagedTree.setShowsRootHandles(false);
111 ctm.addTreeSelectionListener(this);
113 stagedTree = noStagedTree;
115 currentTree = stagedTree;
117 // Add the tree to the UI
118 final JScrollPane scrollPane = new JScrollPane(stagedTree);
119 panel.add(scrollPane, "width 400lp, height 200lp, grow, wrap para");
122 // Checkboxes and buttons
123 final JCheckBox sortByStage = new JCheckBox(trans.get("checkbox.showByStage"));
124 sortByStage.setEnabled(stages > 1);
125 sortByStage.setSelected(stages > 1);
126 sortByStage.addActionListener(new ActionListener() {
128 public void actionPerformed(ActionEvent e) {
129 if (sortByStage.isEnabled()) {
130 if (((JCheckBox) e.getSource()).isSelected()) {
131 scrollPane.setViewportView(stagedTree);
132 stagedTree.setExpandsSelectedPaths(true);
133 currentTree = stagedTree;
136 scrollPane.setViewportView(noStagedTree);
137 noStagedTree.setExpandsSelectedPaths(true);
138 currentTree = noStagedTree;
143 panel.add(sortByStage, "aligny top, split");
146 panel.add(new JPanel(), "growx");
149 JButton settingsButton = new JButton(trans.get("printdlg.but.settings"));
150 settingsButton.addActionListener(new ActionListener() {
152 public void actionPerformed(ActionEvent e) {
153 PrintSettings settings = getPrintSettings();
154 log.debug("settings=" + settings);
155 PrintSettingsDialog settingsDialog = new PrintSettingsDialog(PrintDialog.this, settings);
156 settingsDialog.setVisible(true);
157 setPrintSettings(settings);
160 panel.add(settingsButton, "wrap para");
163 previewButton = new JButton(trans.get("but.previewAndPrint"));
164 previewButton.addActionListener(new ActionListener() {
166 public void actionPerformed(ActionEvent e) {
168 PrintDialog.this.setVisible(false);
171 panel.add(previewButton, "split, right, gap para");
174 saveAsPDF = new JButton(trans.get("printdlg.but.saveaspdf"));
175 saveAsPDF.addActionListener(new ActionListener() {
177 public void actionPerformed(ActionEvent e) {
179 PrintDialog.this.setVisible(false);
183 panel.add(saveAsPDF, "right, gap para");
186 cancel = new JButton(trans.get("button.cancel"));
187 cancel.addActionListener(new ActionListener() {
189 public void actionPerformed(ActionEvent e) {
190 PrintDialog.this.setVisible(false);
193 panel.add(cancel, "right, gap para");
196 expandAll(currentTree, true);
197 if (currentTree != noStagedTree) {
198 expandAll(noStagedTree, true);
202 GUIUtil.setDisposableDialogOptions(this, previewButton);
208 public void valueChanged(final TreeSelectionEvent e) {
209 final TreePath path = e.getNewLeadSelectionPath();
211 previewButton.setEnabled(true);
212 saveAsPDF.setEnabled(true);
214 previewButton.setEnabled(false);
215 saveAsPDF.setEnabled(false);
220 * If expand is true, expands all nodes in the tree. Otherwise, collapses all nodes in the theTree.
222 * @param theTree the tree to expand/contract
223 * @param expand expand if true, contract if not
225 public void expandAll(RocketPrintTree theTree, boolean expand) {
226 TreeNode root = (TreeNode) theTree.getModel().getRoot();
227 // Traverse theTree from root
228 expandAll(theTree, new TreePath(root), expand);
232 * Recursively walk a tree, and if expand is true, expands all nodes in the tree. Otherwise, collapses all nodes in
235 * @param theTree the tree to expand/contract
236 * @param parent the node to iterate/recurse over
237 * @param expand expand if true, contract if not
239 private void expandAll(RocketPrintTree theTree, TreePath parent, boolean expand) {
240 theTree.addSelectionPath(parent);
242 TreeNode node = (TreeNode) parent.getLastPathComponent();
243 if (node.getChildCount() >= 0) {
244 for (Enumeration<?> e = node.children(); e.hasMoreElements();) {
245 TreeNode n = (TreeNode) e.nextElement();
246 TreePath path = parent.pathByAddingChild(n);
247 expandAll(theTree, path, expand);
250 // Expansion or collapse must be done bottom-up
252 theTree.expandPath(parent);
254 theTree.collapsePath(parent);
261 * Generate a report using a temporary file. The file will be deleted upon JVM exit.
263 * @param settings the container of different print settings
265 * @return a file, populated with the "printed" output (the rocket info)
267 * @throws IOException thrown if the file could not be generated
269 private File generateReport(PrintSettings settings) throws IOException {
270 final File f = File.createTempFile("openrocket-", ".pdf");
272 return generateReport(f, settings);
276 * Generate a report to a specified file.
278 * @param f the file to which rocket data will be written
279 * @param settings the container of different print settings
281 * @return a file, populated with the "printed" output (the rocket info)
283 * @throws IOException thrown if the file could not be generated
285 private File generateReport(File f, PrintSettings settings) throws IOException {
286 Iterator<PrintableContext> toBePrinted = currentTree.getToBePrinted();
287 new PrintController().print(document, toBePrinted, new FileOutputStream(f), settings, rotation);
293 * Handler for when the Preview button is clicked.
295 private void onPreview() {
296 if (desktop != null) {
298 PrintSettings settings = getPrintSettings();
299 // TODO: HIGH: Remove UIManager, and pass settings to the actual printing methods
300 TemplateProperties.setColors(settings);
301 File f = generateReport(settings);
303 } catch (IOException e) {
304 log.error("Could not open preview.", e);
305 JOptionPane.showMessageDialog(this, new String[] {
306 trans.get("error.preview.desc1"),
307 trans.get("error.preview.desc2") },
308 trans.get("error.preview.title"),
309 JOptionPane.ERROR_MESSAGE);
312 JOptionPane.showMessageDialog(this, new String[] {
313 trans.get("error.preview.desc1"),
314 trans.get("error.preview.desc2") },
315 trans.get("error.preview.title"),
316 JOptionPane.INFORMATION_MESSAGE);
321 * Handler for when the "Save as PDF" button is clicked.
323 * @return true if the PDF was saved
325 private boolean onSavePDF() {
327 JFileChooser chooser = new JFileChooser();
328 chooser.setFileFilter(FileHelper.PDF_FILTER);
330 // Select initial directory
331 File dir = document.getFile();
333 dir = dir.getParentFile();
336 dir = prefs.getDefaultDirectory();
338 chooser.setCurrentDirectory(dir);
340 int returnVal = chooser.showSaveDialog(this);
341 File file = chooser.getSelectedFile();
342 if (returnVal == JFileChooser.APPROVE_OPTION && file != null) {
344 file = FileHelper.ensureExtension(file, "pdf");
345 if (!FileHelper.confirmWrite(file, this)) {
351 PrintSettings settings = getPrintSettings();
352 // TODO: HIGH: Remove UIManager, and pass settings to the actual printing methods
353 TemplateProperties.setColors(settings);
354 generateReport(file, settings);
356 } catch (IOException e) {
357 FileHelper.errorWriting(e, this);
366 public PrintSettings getPrintSettings() {
367 PrintSettings settings = new PrintSettings();
370 c = prefs.getColor("print.template.fillColor", (java.awt.Color) null);
372 settings.setTemplateFillColor(c);
375 c = prefs.getColor("print.template.borderColor", (java.awt.Color) null);
377 settings.setTemplateBorderColor(c);
380 settings.setPaperSize(prefs.getEnum("print.paper.size", settings.getPaperSize()));
381 settings.setPaperOrientation(prefs.getEnum("print.paper.orientation", settings.getPaperOrientation()));
386 public void setPrintSettings(PrintSettings settings) {
387 prefs.putColor("print.template.fillColor", settings.getTemplateFillColor() );
388 prefs.putColor("print.template.borderColor", settings.getTemplateBorderColor() );
389 prefs.putEnum("print.paper.size", settings.getPaperSize());
390 prefs.putEnum("print.paper.orientation", settings.getPaperOrientation());