]> git.gag.com Git - debian/openrocket/commitdiff
printing updates
authorplaa <plaa@180e2498-e6e9-4542-8430-84ac67f01cd8>
Sat, 14 May 2011 20:21:36 +0000 (20:21 +0000)
committerplaa <plaa@180e2498-e6e9-4542-8430-84ac67f01cd8>
Sat, 14 May 2011 20:21:36 +0000 (20:21 +0000)
git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@124 180e2498-e6e9-4542-8430-84ac67f01cd8

19 files changed:
build.xml
src/net/sf/openrocket/gui/components/ColorChooserButton.java [new file with mode: 0644]
src/net/sf/openrocket/gui/components/ColorIcon.java [new file with mode: 0644]
src/net/sf/openrocket/gui/configdialog/RocketComponentConfig.java
src/net/sf/openrocket/gui/dialogs/PrintDialog.java
src/net/sf/openrocket/gui/dialogs/PrintPanel.java [deleted file]
src/net/sf/openrocket/gui/dialogs/PrintSettingsDialog.java [new file with mode: 0644]
src/net/sf/openrocket/gui/main/BasicFrame.java
src/net/sf/openrocket/gui/main/ExceptionHandler.java
src/net/sf/openrocket/gui/print/PaperOrientation.java [new file with mode: 0644]
src/net/sf/openrocket/gui/print/PaperSize.java
src/net/sf/openrocket/gui/print/PrintController.java
src/net/sf/openrocket/gui/print/PrintServiceDialog.java [deleted file]
src/net/sf/openrocket/gui/print/PrintSettings.java [new file with mode: 0644]
src/net/sf/openrocket/gui/print/PrintUtilities.java
src/net/sf/openrocket/gui/print/TemplateProperties.java
src/net/sf/openrocket/util/AbstractChangeSource.java [new file with mode: 0644]
src/net/sf/openrocket/util/Prefs.java
test/net/sf/openrocket/gui/print/TestPaperSize.java [new file with mode: 0644]

index 30f62d25b5109c18b6956348dc39aa65dc75851f..84462ba713150f6ef3819f6baaa66c5e1abb7842 100644 (file)
--- a/build.xml
+++ b/build.xml
        <target name="todo" depends="checktodo"/>
        <target name="checktodo">
                <tempfile property="todo.file" prefix="checktodo-"/>
-               <echo>Checking project for critical TODOs.</echo>
+               <echo>Checking project for FIXMEs.</echo>
                <concat destfile="${todo.file}">
                        <fileset dir="${src.dir}">
                            <include name="**/*.java"/>
                        </fileset>
                        <filterchain>
                                <linecontainsregexp>
-                                       <regexp pattern="TODO:.*CRITICAL"/>
+                                       <regexp pattern="(FIXME|TODO:.*CRITICAL)"/>
                                </linecontainsregexp>
                        </filterchain>
                </concat>
diff --git a/src/net/sf/openrocket/gui/components/ColorChooserButton.java b/src/net/sf/openrocket/gui/components/ColorChooserButton.java
new file mode 100644 (file)
index 0000000..15e4adc
--- /dev/null
@@ -0,0 +1,71 @@
+package net.sf.openrocket.gui.components;
+
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.JButton;
+import javax.swing.JColorChooser;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+
+import net.sf.openrocket.logging.LogHelper;
+import net.sf.openrocket.startup.Application;
+
+/**
+ * A color chooser button.  The currently selected color can be queried or set using the
+ * {@link #getSelectedColor()} and {@link #setSelectedColor(Color)}, and changes listened
+ * to by listening to property events with property name {@link #COLOR_KEY}.
+ * 
+ * @author Sampo Niskanen <sampo.niskanen@iki.fi>
+ */
+public class ColorChooserButton extends JButton {
+       private static final LogHelper log = Application.getLogger();
+       
+       public static final String COLOR_KEY = "selectedColor";
+       
+       
+       public ColorChooserButton(Color initial) {
+               
+               setSelectedColor(initial);
+               
+               // Add action listener that opens color chooser dialog
+               this.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               log.user("Activating color chooser");
+                               final JColorChooser chooser = new JColorChooser(getSelectedColor());
+                               chooser.setPreviewPanel(new JPanel());
+                               final JDialog dialog = JColorChooser.createDialog(ColorChooserButton.this, "Select color", true,
+                                               chooser, new ActionListener() {
+                                                       @Override
+                                                       public void actionPerformed(ActionEvent e2) {
+                                                               Color c = chooser.getColor();
+                                                               log.user("User selected color " + c);
+                                                               setSelectedColor(chooser.getColor());
+                                                       }
+                                               }, null);
+                               log.info("Closing color chooser");
+                               dialog.setVisible(true);
+                       }
+               });
+               
+       }
+       
+       
+       public void addColorPropertyChangeListener(PropertyChangeListener listener) {
+               this.addPropertyChangeListener(COLOR_KEY, listener);
+       }
+       
+       public void setSelectedColor(Color c) {
+               log.debug("Selecting color " + c);
+               this.setIcon(new ColorIcon(c));
+               this.putClientProperty(COLOR_KEY, c);
+       }
+       
+       public Color getSelectedColor() {
+               return (Color) this.getClientProperty(COLOR_KEY);
+       }
+       
+}
diff --git a/src/net/sf/openrocket/gui/components/ColorIcon.java b/src/net/sf/openrocket/gui/components/ColorIcon.java
new file mode 100644 (file)
index 0000000..747a426
--- /dev/null
@@ -0,0 +1,35 @@
+package net.sf.openrocket.gui.components;
+
+import java.awt.Color;
+
+import javax.swing.Icon;
+
+/**
+ * An Icon that displays a specific color, suitable for drawing into a button.
+ * 
+ * @author Sampo Niskanen <sampo.niskanen@iki.fi>
+ */
+public class ColorIcon implements Icon {
+       private final Color color;
+       
+       public ColorIcon(Color c) {
+               this.color = c;
+       }
+       
+       @Override
+       public int getIconHeight() {
+               return 15;
+       }
+       
+       @Override
+       public int getIconWidth() {
+               return 25;
+       }
+       
+       @Override
+       public void paintIcon(java.awt.Component c, java.awt.Graphics g, int x, int y) {
+               g.setColor(color);
+               g.fill3DRect(x, y, getIconWidth(), getIconHeight(), false);
+       }
+       
+}
index d6d607463ebfec9e5cdb30ddc5f17b976e740bb6..44925a354bff4503e865fe3158e4616a7dcf3f0c 100644 (file)
@@ -2,8 +2,6 @@ package net.sf.openrocket.gui.configdialog;
 
 
 import java.awt.Color;
-import java.awt.Component;
-import java.awt.Graphics;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.FocusEvent;
@@ -13,7 +11,6 @@ import java.util.Iterator;
 import java.util.List;
 
 import javax.swing.BorderFactory;
-import javax.swing.Icon;
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
 import javax.swing.JColorChooser;
@@ -33,6 +30,7 @@ import net.sf.openrocket.gui.adaptors.DoubleModel;
 import net.sf.openrocket.gui.adaptors.EnumModel;
 import net.sf.openrocket.gui.adaptors.MaterialModel;
 import net.sf.openrocket.gui.components.BasicSlider;
+import net.sf.openrocket.gui.components.ColorIcon;
 import net.sf.openrocket.gui.components.StyledLabel;
 import net.sf.openrocket.gui.components.StyledLabel.Style;
 import net.sf.openrocket.gui.components.UnitSelector;
@@ -136,7 +134,7 @@ public class RocketComponentConfig extends JPanel {
                
                // Component color and "Use default color" checkbox
                if (colorButton != null && colorDefault != null) {
-                       colorButton.setIcon(new ColorIcon(component.getColor()));
+                       colorButton.setIcon(new ColorIcon(getColor()));
                        
                        if ((component.getColor() == null) != colorDefault.isSelected())
                                colorDefault.setSelected(component.getColor() == null);
@@ -347,7 +345,7 @@ public class RocketComponentConfig extends JPanel {
 
                panel.add(new JLabel("Component color:"), "gapleft para, gapright 10lp");
                
-               colorButton = new JButton(new ColorIcon(component.getColor()));
+               colorButton = new JButton(new ColorIcon(getColor()));
                colorButton.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
@@ -409,7 +407,15 @@ public class RocketComponentConfig extends JPanel {
        }
        
        
-
+       private Color getColor() {
+               Color c = component.getColor();
+               if (c == null) {
+                       c = Prefs.getDefaultColor(component.getClass());
+               }
+               return c;
+       }
+       
+       
 
        protected JPanel shoulderTab() {
                JPanel panel = new JPanel(new MigLayout("fill"));
@@ -578,35 +584,6 @@ public class RocketComponentConfig extends JPanel {
        }
        
        
-       private class ColorIcon implements Icon {
-               private final Color color;
-               
-               public ColorIcon(Color c) {
-                       this.color = c;
-               }
-               
-               @Override
-               public int getIconHeight() {
-                       return 15;
-               }
-               
-               @Override
-               public int getIconWidth() {
-                       return 25;
-               }
-               
-               @Override
-               public void paintIcon(Component c, Graphics g, int x, int y) {
-                       if (color == null) {
-                               g.setColor(Prefs.getDefaultColor(component.getClass()));
-                       } else {
-                               g.setColor(color);
-                       }
-                       g.fill3DRect(x, y, getIconWidth(), getIconHeight(), false);
-               }
-               
-       }
-       
        protected void register(Invalidatable model) {
                this.invalidatables.add(model);
        }
@@ -617,4 +594,4 @@ public class RocketComponentConfig extends JPanel {
                }
        }
        
-}
+}
\ No newline at end of file
index cfd36be394dc5ee84f288a1e7af129d05047ee76..1d5556ba0c3b734f8af17f651bcde3cefa685071 100644 (file)
 /*
- * PrintDialog.java
+ * PrintPanel.java
  */
 package net.sf.openrocket.gui.dialogs;
 
-import net.sf.openrocket.document.OpenRocketDocument;
-import net.sf.openrocket.gui.print.PDFPrintStreamDoc;
-import net.sf.openrocket.gui.print.PrintServiceDialog;
-import net.sf.openrocket.gui.print.PrintUtilities;
-
-import javax.print.DocFlavor;
-import javax.print.DocPrintJob;
-import javax.print.PrintService;
-import javax.print.PrintServiceLookup;
-import javax.print.attribute.Attribute;
-import javax.print.attribute.AttributeSet;
-import javax.print.attribute.HashPrintRequestAttributeSet;
-import javax.print.attribute.PrintRequestAttributeSet;
-import javax.print.attribute.standard.Destination;
-import javax.print.attribute.standard.Fidelity;
+import java.awt.Desktop;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Iterator;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
 import javax.swing.JDialog;
-import java.awt.Dialog;
-import java.awt.GraphicsEnvironment;
-import java.awt.HeadlessException;
-import java.io.ByteArrayOutputStream;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.filechooser.FileFilter;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+
+import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.document.OpenRocketDocument;
+import net.sf.openrocket.gui.main.ExceptionHandler;
+import net.sf.openrocket.gui.print.PrintController;
+import net.sf.openrocket.gui.print.PrintSettings;
+import net.sf.openrocket.gui.print.PrintableContext;
+import net.sf.openrocket.gui.print.TemplateProperties;
+import net.sf.openrocket.gui.print.components.CheckTreeManager;
+import net.sf.openrocket.gui.print.components.RocketPrintTree;
+import net.sf.openrocket.logging.LogHelper;
+import net.sf.openrocket.rocketcomponent.Rocket;
+import net.sf.openrocket.startup.Application;
+import net.sf.openrocket.util.GUIUtil;
+import net.sf.openrocket.util.Prefs;
 
 /**
- * This class is not a dialog by inheritance, but is by delegation.  It front-ends a java print dialog by
- * augmenting it with application specific (rocket) settings.
+ * This class isolates the Swing components used to create a panel that is added to a standard Java print dialog.
  */
-public class PrintDialog {
-
-    /**
-     * The service UI dialog.
-     */
-    private PrintServiceDialog dialog;
-
-    /**
-     * A javax doc flavor specific for printing PDF documents.
-     */
-    private static final DocFlavor.INPUT_STREAM PDF = DocFlavor.INPUT_STREAM.PDF;
-
-    /**
-     * Construct a print dialog using an Open Rocket document - which contains the rocket data to ultimately be
-     * printed.
-     *
-     * @param orDocument the rocket container
-     */
-    public PrintDialog(OpenRocketDocument orDocument) {
-        PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
-        PrintService svc = PrintServiceLookup.lookupDefaultPrintService();
-        PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet();
-        attrs.add(PrintUtilities.getDefaultMedia().getMediaSizeName());
-
-        final PrintPanel panel = new PrintPanel(orDocument, this);
-        try {
-            PrintService ps = printDialog(100, 100, services, svc, PDF, attrs, panel);
-            if (ps != null) {
-                DocPrintJob dpj = ps.createPrintJob();
-                ByteArrayOutputStream baos = panel.generateReport();
-                dpj.print(new PDFPrintStreamDoc(baos, null), attrs);
-            }
-        }
-        catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Get the set of attributes from the service ui print dialog.
-     *
-     * @return a set of print attributes
-     */
-    PrintRequestAttributeSet getAttributes() {
-        return dialog.getAttributes();
-    }
-
-    /**
-     * Get the service ui dialog.  This is the actual dialog that gets displayed - we co-opt it for adding a rocket
-     * specific tab.
-     *
-     * @return the Java service ui print dialog
-     */
-    JDialog getDialog() {
-        return dialog;
-    }
-
-    /**
-     * Mimics the ServiceUI.printDialog method, but with enhancements for our own print settings tab.
-     *
-     * @param x              location of dialog including border in screen coordinates
-     * @param y              location of dialog including border in screen coordinates
-     * @param services       to be browsable, must be non-null.
-     * @param defaultService - initial PrintService to display.
-     * @param flavor         - the flavor to be printed, or null.
-     * @param attributes     on input is the initial application supplied preferences. This cannot be null but may be
-     *                       empty. On output the attributes reflect changes made by the user.
-     * @param addnl          a panel to be added, as a tab, to the internal tabbed pane of the resulting print dialog
-     * @return print service selected by the user, or null if the user cancelled the dialog.
-     * @throws HeadlessException        if GraphicsEnvironment.isHeadless() returns true.
-     * @throws IllegalArgumentException if services is null or empty, or attributes is null, or the initial PrintService
-     *                                  is not in the list of browsable services.
-     */
-    private PrintService printDialog(int x, int y,
-                                     PrintService[] services,
-                                     PrintService defaultService,
-                                     DocFlavor flavor,
-                                     PrintRequestAttributeSet attributes,
-                                     PrintPanel addnl)
-            throws HeadlessException, IllegalArgumentException {
-        int defaultIndex = -1;
-
-        if (GraphicsEnvironment.isHeadless()) {
-            throw new HeadlessException();
-        }
-        else if (attributes == null) {
-            throw new IllegalArgumentException("attributes must be non-null");
-        }
-
-        if (defaultService != null && services != null) {
-            for (int i = 0; i < services.length; i++) {
-                if (services[i].equals(defaultService)) {
-                    defaultIndex = i;
-                    break;
-                }
-            }
-
-            //If the default service is not found just go with the first in the list
-            if (defaultIndex < 0) {
-                defaultIndex = 0;
-            }
-        }
-        else {
-            defaultIndex = -1;
-        }
-
-        dialog = new PrintServiceDialog(
-                                        x,
-                                        y,
-                                        services, defaultIndex,
-                                        flavor, attributes,
-                                        (Dialog) null, addnl);
-        dialog.setVisible(true);
-
-        if (dialog.getStatus() == PrintServiceDialog.APPROVE) {
-            PrintRequestAttributeSet newas = dialog.getAttributes();
-            Class dstCategory = Destination.class;
-            Class fdCategory = Fidelity.class;
-
-            if (attributes.containsKey(dstCategory) &&
-                    !newas.containsKey(dstCategory)) {
-                attributes.remove(dstCategory);
-            }
-
-            attributes.addAll(newas);
-
-            Fidelity fd = (Fidelity) attributes.get(fdCategory);
-            if (fd != null) {
-                if (fd == Fidelity.FIDELITY_TRUE) {
-                    removeUnsupportedAttributes(dialog.getPrintService(),
-                                                flavor, attributes);
-                }
-            }
-            return dialog.getPrintService();
-        }
-        else {
-            return null;
-        }
-    }
-
-    /**
-     * Removes any attributes from the given AttributeSet that are unsupported by the given PrintService/DocFlavor
-     * combination.
-     *
-     * @param ps     the print service for which unsupported attributes will be determined
-     * @param flavor the document flavor; PDF in our case
-     * @param aset   the set of attributes requested
-     */
-    private static void removeUnsupportedAttributes(PrintService ps,
-                                                    DocFlavor flavor,
-                                                    AttributeSet aset) {
-        AttributeSet asUnsupported = ps.getUnsupportedAttributes(flavor,
-                                                                 aset);
-
-        if (asUnsupported != null) {
-            Attribute[] usAttrs = asUnsupported.toArray();
-
-            for (Attribute usAttr : usAttrs) {
-                Class<? extends Attribute> category = usAttr.getCategory();
-
-                if (ps.isAttributeCategorySupported(category)) {
-                    Attribute attr =
-                            (Attribute) ps.getDefaultAttributeValue(category);
-
-                    if (attr != null) {
-                        aset.add(attr);
-                    }
-                    else {
-                        aset.remove(category);
-                    }
-                }
-                else {
-                    aset.remove(category);
-                }
-            }
-        }
-    }
+public class PrintDialog extends JDialog implements TreeSelectionListener {
+       
+       private static final LogHelper log = Application.getLogger();
+       
+       private static final String SETTINGS_BUTTON_TEXT = "Settings";
+       private static final String PREVIEW_BUTTON_TEXT = "Preview & Print";
+       private static final String SAVE_AS_PDF_BUTTON_TEXT = "Save as PDF";
+       private static final String SHOW_BY_STAGE = "Show By Stage";
+       
+       private final RocketPrintTree stagedTree;
+       private final RocketPrintTree noStagedTree;
+       private OpenRocketDocument document;
+       private RocketPrintTree currentTree;
+       private Desktop desktop = null;
+       
+       private JButton previewButton;
+       private JButton saveAsPDF;
+       private JButton cancel;
+       
+       /**
+        * Constructor.
+        *
+        * @param orDocument the OR rocket container
+        */
+       public PrintDialog(Window parent, OpenRocketDocument orDocument) {
+               super(parent, "Print or export", ModalityType.APPLICATION_MODAL);
+               
+
+               JPanel panel = new JPanel(new MigLayout("fill, gap rel unrel"));
+               this.add(panel);
+               
+
+               // before any Desktop APIs are used, first check whether the API is
+               // supported by this particular VM on this particular host
+               if (Desktop.isDesktopSupported()) {
+                       desktop = Desktop.getDesktop();
+               }
+               
+               document = orDocument;
+               Rocket rocket = orDocument.getRocket();
+               
+               noStagedTree = RocketPrintTree.create(rocket.getName());
+               noStagedTree.setShowsRootHandles(false);
+               CheckTreeManager ctm = new net.sf.openrocket.gui.print.components.CheckTreeManager(noStagedTree);
+               ctm.addTreeSelectionListener(this);
+               
+               final int stages = rocket.getStageCount();
+               
+
+               JLabel label = new JLabel("Select elements to include:");
+               panel.add(label, "wrap unrel");
+               
+               // Create the tree
+               if (stages > 1) {
+                       stagedTree = RocketPrintTree.create(rocket.getName(), rocket.getChildren());
+                       ctm = new CheckTreeManager(stagedTree);
+                       stagedTree.setShowsRootHandles(false);
+                       ctm.addTreeSelectionListener(this);
+               } else {
+                       stagedTree = noStagedTree;
+               }
+               currentTree = stagedTree;
+               
+               // Add the tree to the UI
+               final JScrollPane scrollPane = new JScrollPane(stagedTree);
+               panel.add(scrollPane, "width 400lp, height 200lp, grow, wrap para");
+               
+
+               // Checkboxes and buttons
+               final JCheckBox sortByStage = new JCheckBox(SHOW_BY_STAGE);
+               sortByStage.setEnabled(stages > 1);
+               sortByStage.setSelected(stages > 1);
+               sortByStage.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               if (sortByStage.isEnabled()) {
+                                       if (((JCheckBox) e.getSource()).isSelected()) {
+                                               scrollPane.setViewportView(stagedTree);
+                                               stagedTree.setExpandsSelectedPaths(true);
+                                               currentTree = stagedTree;
+                                       }
+                                       else {
+                                               scrollPane.setViewportView(noStagedTree);
+                                               noStagedTree.setExpandsSelectedPaths(true);
+                                               currentTree = noStagedTree;
+                                       }
+                               }
+                       }
+               });
+               panel.add(sortByStage, "aligny top, split");
+               
+
+               panel.add(new JPanel(), "growx");
+               
+
+               JButton settingsButton = new JButton(SETTINGS_BUTTON_TEXT);
+               settingsButton.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               PrintSettings settings = Prefs.getPrintSettings();
+                               log.debug("settings=" + settings);
+                               PrintSettingsDialog settingsDialog = new PrintSettingsDialog(PrintDialog.this, settings);
+                               settingsDialog.setVisible(true);
+                               Prefs.setPrintSettings(settings);
+                       }
+               });
+               panel.add(settingsButton, "wrap para");
+               
+
+               previewButton = new JButton(PREVIEW_BUTTON_TEXT);
+               previewButton.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               onPreview();
+                               PrintDialog.this.setVisible(false);
+                       }
+               });
+               panel.add(previewButton, "split, right, gap para");
+               
+
+               saveAsPDF = new JButton(SAVE_AS_PDF_BUTTON_TEXT);
+               saveAsPDF.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               if (onSavePDF()) {
+                                       PrintDialog.this.setVisible(false);
+                               }
+                       }
+               });
+               panel.add(saveAsPDF, "right, gap para");
+               
+
+               cancel = new JButton("Cancel");
+               cancel.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               PrintDialog.this.setVisible(false);
+                       }
+               });
+               panel.add(cancel, "right, gap para");
+               
+
+               expandAll(currentTree, true);
+               if (currentTree != noStagedTree) {
+                       expandAll(noStagedTree, true);
+               }
+               
+
+               GUIUtil.setDisposableDialogOptions(this, previewButton);
+               
+       }
+       
+       
+       @Override
+       public void valueChanged(final TreeSelectionEvent e) {
+               final TreePath path = e.getNewLeadSelectionPath();
+               if (path != null) {
+                       previewButton.setEnabled(true);
+                       saveAsPDF.setEnabled(true);
+               } else {
+                       previewButton.setEnabled(false);
+                       saveAsPDF.setEnabled(false);
+               }
+       }
+       
+       /**
+        * If expand is true, expands all nodes in the tree. Otherwise, collapses all nodes in the theTree.
+        *
+        * @param theTree   the tree to expand/contract
+        * @param expand expand if true, contract if not
+        */
+       public void expandAll(RocketPrintTree theTree, boolean expand) {
+               TreeNode root = (TreeNode) theTree.getModel().getRoot();
+               // Traverse theTree from root
+               expandAll(theTree, new TreePath(root), expand);
+       }
+       
+       /**
+        * Recursively walk a tree, and if expand is true, expands all nodes in the tree. Otherwise, collapses all nodes in
+        * the theTree.
+        *
+        * @param theTree   the tree to expand/contract
+        * @param parent the node to iterate/recurse over
+        * @param expand expand if true, contract if not
+        */
+       private void expandAll(RocketPrintTree theTree, TreePath parent, boolean expand) {
+               theTree.addSelectionPath(parent);
+               // Traverse children
+               TreeNode node = (TreeNode) parent.getLastPathComponent();
+               if (node.getChildCount() >= 0) {
+                       for (Enumeration<?> e = node.children(); e.hasMoreElements();) {
+                               TreeNode n = (TreeNode) e.nextElement();
+                               TreePath path = parent.pathByAddingChild(n);
+                               expandAll(theTree, path, expand);
+                       }
+               }
+               // Expansion or collapse must be done bottom-up
+               if (expand) {
+                       theTree.expandPath(parent);
+               } else {
+                       theTree.collapsePath(parent);
+               }
+       }
+       
+       
 
+       /**
+        * Generate a report using a temporary file.  The file will be deleted upon JVM exit.
+        *
+        * @param paper the name of the paper size
+        *
+        * @return a file, populated with the "printed" output (the rocket info)
+        *
+        * @throws IOException thrown if the file could not be generated
+        */
+       private File generateReport(PrintSettings settings) throws IOException {
+               final File f = File.createTempFile("openrocket-", ".pdf");
+               f.deleteOnExit();
+               return generateReport(f, settings);
+       }
+       
+       /**
+        * Generate a report to a specified file.
+        *
+        * @param f     the file to which rocket data will be written
+        * @param paper the name of the paper size
+        *
+        * @return a file, populated with the "printed" output (the rocket info)
+        *
+        * @throws IOException thrown if the file could not be generated
+        */
+       private File generateReport(File f, PrintSettings settings) throws IOException {
+               Iterator<PrintableContext> toBePrinted = currentTree.getToBePrinted();
+               new PrintController().print(document, toBePrinted, new FileOutputStream(f), settings);
+               return f;
+       }
+       
+       
+       /**
+        * Handler for when the Preview button is clicked.
+        */
+       private void onPreview() {
+               if (desktop != null) {
+                       try {
+                               PrintSettings settings = Prefs.getPrintSettings();
+                               // TODO: HIGH: Remove UIManager, and pass settings to the actual printing methods
+                               TemplateProperties.setColors(settings);
+                               File f = generateReport(settings);
+                               desktop.open(f);
+                       } catch (IOException e) {
+                               log.error("Could not create temporary file for previewing.", e);
+                               JOptionPane.showMessageDialog(this, "Could not create a temporary file for previewing.",
+                                                                                               "Error creating file", JOptionPane.ERROR_MESSAGE);
+                       }
+               } else {
+                       JOptionPane.showMessageDialog(this,
+                                                                                       "Your environment does not support automatically opening the default PDF viewer.",
+                                                                                       "Error creating file", JOptionPane.INFORMATION_MESSAGE);
+               }
+       }
+       
+       /**
+        * Handler for when the "Save as PDF" button is clicked.
+        *
+        * @return      true if the PDF was saved
+        */
+       private boolean onSavePDF() {
+               
+               JFileChooser chooser = new JFileChooser();
+               // Note: source for ExampleFileFilter can be found in FileChooserDemo,
+               // under the demo/jfc directory in the Java 2 SDK, Standard Edition.
+               FileFilter filter = new FileFilter() {
+                       
+                       //Accept all directories and all pdf files.
+                       @Override
+                       public boolean accept(File f) {
+                               if (f.isDirectory())
+                                       return true;
+                               return f.getName().toLowerCase().endsWith(".pdf");
+                       }
+                       
+                       //The description of this filter
+                       @Override
+                       public String getDescription() {
+                               return "PDF files";
+                       }
+               };
+               chooser.setFileFilter(filter);
+               int returnVal = chooser.showSaveDialog(this);
+               if (returnVal == JFileChooser.APPROVE_OPTION) {
+                       
+                       try {
+                               String fname = chooser.getSelectedFile().getCanonicalPath();
+                               if (!getExtension(fname).equals("pdf")) {
+                                       fname = fname + ".pdf";
+                               }
+                               File f = new File(fname);
+                               PrintSettings settings = Prefs.getPrintSettings();
+                               // TODO: HIGH: Remove UIManager, and pass settings to the actual printing methods
+                               TemplateProperties.setColors(settings);
+                               generateReport(f, settings);
+                       } catch (IOException e) {
+                               ExceptionHandler.handleErrorCondition(e);
+                       }
+                       return true;
+               } else {
+                       return false;
+               }
+       }
+       
+       /**
+        * Get the extension of a file.
+        */
+       private static String getExtension(String s) {
+               String ext = null;
+               int i = s.lastIndexOf('.');
+               
+               if (i > 0 && i < s.length() - 1) {
+                       ext = s.substring(i + 1).toLowerCase();
+               }
+               return ext != null ? ext : "";
+       }
 }
diff --git a/src/net/sf/openrocket/gui/dialogs/PrintPanel.java b/src/net/sf/openrocket/gui/dialogs/PrintPanel.java
deleted file mode 100644 (file)
index 4bc748c..0000000
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * PrintPanel.java
- */
-package net.sf.openrocket.gui.dialogs;
-
-import net.miginfocom.swing.MigLayout;
-import net.sf.openrocket.document.OpenRocketDocument;
-import net.sf.openrocket.gui.components.ColorChooser;
-import net.sf.openrocket.gui.print.PrintController;
-import net.sf.openrocket.gui.print.PrintUtilities;
-import net.sf.openrocket.gui.print.PrintableContext;
-import net.sf.openrocket.gui.print.TemplateProperties;
-import net.sf.openrocket.gui.print.components.CheckTreeManager;
-import net.sf.openrocket.gui.print.components.RocketPrintTree;
-import net.sf.openrocket.logging.LogHelper;
-import net.sf.openrocket.rocketcomponent.Rocket;
-import net.sf.openrocket.startup.Application;
-
-import javax.print.attribute.PrintRequestAttributeSet;
-import javax.print.attribute.standard.MediaSizeName;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JColorChooser;
-import javax.swing.JComponent;
-import javax.swing.JDialog;
-import javax.swing.JFileChooser;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.UIManager;
-import javax.swing.event.TreeSelectionEvent;
-import javax.swing.event.TreeSelectionListener;
-import javax.swing.filechooser.FileFilter;
-import javax.swing.tree.TreeNode;
-import javax.swing.tree.TreePath;
-import java.awt.Color;
-import java.awt.Desktop;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.Iterator;
-
-/**
- * This class isolates the Swing components used to create a panel that is added to a standard Java print dialog.
- */
-public class PrintPanel extends JPanel implements TreeSelectionListener {
-
-    private static final LogHelper log = Application.getLogger();
-
-    private static final String TAB_TITLE = "Rocket";
-    private static final String SETTINGS_BUTTON_TEXT = "Settings";
-    private static final String PREVIEW_BUTTON_TEXT = "Preview";
-    private static final String SAVE_AS_PDF_BUTTON_TEXT = "Save as PDF";
-    private static final String SHOW_BY_STAGE = "Show By Stage";
-
-    private final RocketPrintTree stagedTree;
-    private final RocketPrintTree noStagedTree;
-    private OpenRocketDocument rocDoc;
-    private RocketPrintTree currentTree;
-    private boolean bDesktopSupported = false;
-    private Desktop desktop;
-    private PrintDialog printDialog;
-
-    JButton previewButton;
-    JButton saveAsPDF;
-
-    /**
-     * Constructor.
-     *
-     * @param orDocument the OR rocket container
-     * @param theParent  the OR parent print dialog
-     */
-    public PrintPanel (OpenRocketDocument orDocument, PrintDialog theParent) {
-
-        super(new MigLayout("fill, gap rel unrel"));
-
-        // before any Desktop APIs are used, first check whether the API is
-        // supported by this particular VM on this particular host
-        if (Desktop.isDesktopSupported()) {
-            bDesktopSupported = true;
-            desktop = Desktop.getDesktop();
-        }
-
-        printDialog = theParent;
-        rocDoc = orDocument;
-        Rocket rocket = orDocument.getRocket();
-
-        noStagedTree = RocketPrintTree.create(rocket.getName());
-        noStagedTree.setShowsRootHandles(false);
-        CheckTreeManager ctm = new net.sf.openrocket.gui.print.components.CheckTreeManager(noStagedTree);
-        ctm.addTreeSelectionListener(this);
-
-        final int stages = rocket.getStageCount();
-
-        if (stages > 1) {
-            stagedTree = RocketPrintTree.create(rocket.getName(), rocket.getChildren());
-            ctm = new CheckTreeManager(stagedTree);
-            stagedTree.setShowsRootHandles(false);
-            ctm.addTreeSelectionListener(this);
-        }
-        else {
-            stagedTree = noStagedTree;
-        }
-        currentTree = stagedTree;
-
-        final JScrollPane scrollPane = new JScrollPane(stagedTree);
-        add(scrollPane, "width 416!, wrap");
-
-        final JCheckBox sortByStage = new JCheckBox(SHOW_BY_STAGE);
-        sortByStage.setEnabled(stages > 1);
-        sortByStage.setSelected(stages > 1);
-        sortByStage.addActionListener(new ActionListener() {
-            public void actionPerformed (ActionEvent e) {
-                if (sortByStage.isEnabled()) {
-                    if (((JCheckBox) e.getSource()).isSelected()) {
-                        scrollPane.setViewportView(stagedTree);
-                        stagedTree.setExpandsSelectedPaths(true);
-                        currentTree = stagedTree;
-                    }
-                    else {
-                        scrollPane.setViewportView(noStagedTree);
-                        noStagedTree.setExpandsSelectedPaths(true);
-                        currentTree = noStagedTree;
-                    }
-                }
-            }
-        });
-        add(sortByStage, "wrap");
-
-        saveAsPDF = new JButton(SAVE_AS_PDF_BUTTON_TEXT);
-        saveAsPDF.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed (ActionEvent e) {
-                onSavePDF(PrintPanel.this);
-            }
-        });
-        add(saveAsPDF, "span 2, tag save");
-
-        previewButton = new JButton(PREVIEW_BUTTON_TEXT);
-        previewButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed (ActionEvent e) {
-                onPreview();
-            }
-        });
-        add(previewButton, "x 150");
-
-        JButton settingsButton = new JButton(SETTINGS_BUTTON_TEXT);
-        settingsButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed (ActionEvent e) {
-                PrintSettingsDialog settingsDialog = new PrintSettingsDialog(printDialog.getDialog());
-                settingsDialog.setVisible(true);
-            }
-        });
-        add(settingsButton, "x 340");
-
-        expandAll(currentTree, true);
-        if (currentTree != noStagedTree) {
-            expandAll(noStagedTree, true);
-        }
-        setVisible(true);
-    }
-
-    /**
-     * The title of the tab that gets displayed for this panel, when placed in the print dialog.
-     *
-     * @return a title
-     */
-    public String getTitle () {
-        return TAB_TITLE;
-    }
-
-    @Override
-    public String getName() {
-        return getTitle();
-    }
-
-    @Override
-    public void valueChanged (final TreeSelectionEvent e) {
-        final TreePath path = e.getNewLeadSelectionPath();
-        if (path != null){
-            previewButton.setEnabled(true);
-            saveAsPDF.setEnabled(true);
-        }
-        else {
-            previewButton.setEnabled(false);
-            saveAsPDF.setEnabled(false);
-        }
-    }
-
-    /**
-     * If expand is true, expands all nodes in the tree. Otherwise, collapses all nodes in the theTree.
-     *
-     * @param theTree   the tree to expand/contract
-     * @param expand expand if true, contract if not
-     */
-    public void expandAll (RocketPrintTree theTree, boolean expand) {
-        TreeNode root = (TreeNode) theTree.getModel().getRoot();
-        // Traverse theTree from root
-        expandAll(theTree, new TreePath(root), expand);
-    }
-
-    /**
-     * Recursively walk a tree, and if expand is true, expands all nodes in the tree. Otherwise, collapses all nodes in
-     * the theTree.
-     *
-     * @param theTree   the tree to expand/contract
-     * @param parent the node to iterate/recurse over
-     * @param expand expand if true, contract if not
-     */
-    private void expandAll (RocketPrintTree theTree, TreePath parent, boolean expand) {
-        theTree.addSelectionPath(parent);
-        // Traverse children
-        TreeNode node = (TreeNode) parent.getLastPathComponent();
-        if (node.getChildCount() >= 0) {
-            for (Enumeration e = node.children(); e.hasMoreElements();) {
-                TreeNode n = (TreeNode) e.nextElement();
-                TreePath path = parent.pathByAddingChild(n);
-                expandAll(theTree, path, expand);
-            }
-        }
-        // Expansion or collapse must be done bottom-up
-        if (expand) {
-            theTree.expandPath(parent);
-        }
-        else {
-            theTree.collapsePath(parent);
-        }
-    }
-
-    /**
-     * Get a media size name (the name of a paper size).  If no page size is selected, it will default to the locale
-     * specific page size (LETTER in North America, A4 elsewhere).
-     *
-     * @return the name of a page size
-     */
-    private MediaSizeName getMediaSize () {
-        MediaSizeName paperSize = getMediaSize(printDialog.getAttributes());
-        if (paperSize == null) {
-            paperSize = PrintUtilities.getDefaultMedia().getMediaSizeName();
-        }
-        return paperSize;
-    }
-
-    /**
-     * Get the media size name (the name of a paper size) as selected by the user.
-     *
-     * @param atts the set of selected printer attributes
-     *
-     * @return a media size name, may be null
-     */
-    private MediaSizeName getMediaSize (PrintRequestAttributeSet atts) {
-        return (MediaSizeName) atts.get(javax.print.attribute.standard.Media.class);
-    }
-
-    /**
-     * Generate a report using a temporary file.  The file will be deleted upon JVM exit.
-     *
-     * @param paper the name of the paper size
-     *
-     * @return a file, populated with the "printed" output (the rocket info)
-     *
-     * @throws IOException thrown if the file could not be generated
-     */
-    private File generateReport (MediaSizeName paper) throws IOException {
-        final File f = File.createTempFile("oro", ".pdf");
-        f.deleteOnExit();
-        return generateReport(f, paper);
-    }
-
-    /**
-     * Generate a report to a specified file.
-     *
-     * @param f     the file to which rocket data will be written
-     * @param paper the name of the paper size
-     *
-     * @return a file, populated with the "printed" output (the rocket info)
-     *
-     * @throws IOException thrown if the file could not be generated
-     */
-    private File generateReport (File f, MediaSizeName paper) throws IOException {
-        Iterator<PrintableContext> toBePrinted = currentTree.getToBePrinted();
-        new PrintController().print(rocDoc, toBePrinted, new FileOutputStream(f), paper);
-        return f;
-    }
-
-    /**
-     * Generate a report to a byte array output stream.
-     *
-     * @return a stream populated with the "printed" output (the rocket info)
-     */
-    public ByteArrayOutputStream generateReport() {
-        Iterator<PrintableContext> toBePrinted = currentTree.getToBePrinted();
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        new PrintController().print(rocDoc, toBePrinted, baos, getMediaSize ());
-        return baos;
-    }
-
-    /**
-     * Handler for when the Preview button is clicked.
-     */
-    private void onPreview () {
-        if (bDesktopSupported) {
-            try {
-                MediaSizeName paperSize = getMediaSize();
-                File f = generateReport(paperSize);
-                desktop.open(f);
-            }
-            catch (IOException e) {
-                log.error("Could not create temporary file for previewing.", e);
-                JOptionPane.showMessageDialog(this, "Could not create a temporary file for previewing.",
-                                              "Error creating file", JOptionPane.ERROR_MESSAGE);
-            }
-        }
-        else {
-            JOptionPane.showMessageDialog(this,
-                                          "Your environment does not support automatically opening the default PDF viewer.",
-                                          "Error creating file", JOptionPane.INFORMATION_MESSAGE);
-        }
-    }
-
-    /**
-     * Handler for when the "Save as PDF" button is clicked.
-     *
-     * @param p the component to parent the save dialog to
-     */
-    private void onSavePDF (JComponent p) {
-
-        JFileChooser chooser = new JFileChooser();
-        // Note: source for ExampleFileFilter can be found in FileChooserDemo,
-        // under the demo/jfc directory in the Java 2 SDK, Standard Edition.
-        FileFilter filter = new FileFilter() {
-
-            //Accept all directories and all pdf files.
-            public boolean accept (File f) {
-                return true;
-            }
-
-            //The description of this filter
-            public String getDescription () {
-                return "pdf";
-            }
-        };
-        chooser.setFileFilter(filter);
-        int returnVal = chooser.showSaveDialog(p);
-        if (returnVal == JFileChooser.APPROVE_OPTION) {
-
-            try {
-                String fname = chooser.getSelectedFile().getCanonicalPath();
-                if (!getExtension(fname).equals("pdf")) {
-                    fname = fname + ".pdf";
-                }
-                File f = new File(fname);
-                generateReport(f, getMediaSize());
-            }
-            catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
-    /**
-     * Get the extension of a file.
-     */
-    private static String getExtension (String s) {
-        String ext = null;
-        int i = s.lastIndexOf('.');
-
-        if (i > 0 && i < s.length() - 1) {
-            ext = s.substring(i + 1).toLowerCase();
-        }
-        return ext != null ? ext : "";
-    }
-}
-
-/**
- * This class is a dialog for displaying advanced settings for printing rocket related info.
- */
-class PrintSettingsDialog extends JDialog {
-
-    /**
-     * The fill color chooser.
-     */
-    private ColorChooser fill;
-
-    /**
-     * The line color chooser.
-     */
-    private ColorChooser line;
-
-    /**
-     * Construct a dialog for setting the advanced rocket print settings.
-     *
-     * @param parent the owning dialog
-     */
-    public PrintSettingsDialog (JDialog parent) {
-        super(parent, "Advanced Settings", true);
-        setLayout(new MigLayout("fill"));
-
-        JPanel settingsPanel = new JPanel();
-        settingsPanel.setLayout(new MigLayout("gap rel"));
-
-        fill = addColorChooser(settingsPanel, "Template Fill", TemplateProperties.getFillColor());
-        line = addColorChooser(settingsPanel, "Template Line", TemplateProperties.getLineColor());
-
-        settingsPanel.add(fill);
-        settingsPanel.add(line);
-
-        add(settingsPanel, "wrap");
-
-        JButton closeButton = new JButton("Close");
-        closeButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed (ActionEvent e) {
-                UIManager.put(TemplateProperties.TEMPLATE_FILL_COLOR_PROPERTY, fill.getCurrentColor());
-                UIManager.put(TemplateProperties.TEMPLATE_LINE_COLOR_PROPERTY, line.getCurrentColor());
-                dispose();
-            }
-        });
-        add(closeButton, "right, gapright para");
-
-        setSize(400, 200);
-    }
-
-    /**
-     * Add a color chooser to a panel.
-     *
-     * @param panel        the parent panel to add the color chooser.
-     * @param label        the label that indicates which color property is being changed
-     * @param initialColor the initial, or current, color to display
-     *
-     * @return a swing component containing a label, a colorized field, and a button that when clicked opens a color
-     *         chooser dialog
-     */
-    private ColorChooser addColorChooser (JPanel panel, String label, Color initialColor) {
-        final JColorChooser colorChooser = new JColorChooser(initialColor);
-        return new ColorChooser(panel, colorChooser, label);
-    }
-
-}
diff --git a/src/net/sf/openrocket/gui/dialogs/PrintSettingsDialog.java b/src/net/sf/openrocket/gui/dialogs/PrintSettingsDialog.java
new file mode 100644 (file)
index 0000000..66286ab
--- /dev/null
@@ -0,0 +1,111 @@
+package net.sf.openrocket.gui.dialogs;
+
+import java.awt.Color;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.gui.adaptors.EnumModel;
+import net.sf.openrocket.gui.components.ColorChooserButton;
+import net.sf.openrocket.gui.print.PaperOrientation;
+import net.sf.openrocket.gui.print.PaperSize;
+import net.sf.openrocket.gui.print.PrintSettings;
+import net.sf.openrocket.logging.LogHelper;
+import net.sf.openrocket.startup.Application;
+import net.sf.openrocket.util.GUIUtil;
+
+/**
+ * This class is a dialog for displaying advanced settings for printing rocket related info.
+ */
+public class PrintSettingsDialog extends JDialog {
+       private static final LogHelper log = Application.getLogger();
+       
+       
+       /**
+        * Construct a dialog for setting the advanced rocket print settings.
+        *
+        * @param parent the owning dialog
+        */
+       public PrintSettingsDialog(Window parent, final PrintSettings settings) {
+               super(parent, "Print settings", ModalityType.APPLICATION_MODAL);
+               
+
+               JPanel panel = new JPanel(new MigLayout("fill"));
+               
+
+               panel.add(new JLabel("Template fill color:"));
+               final ColorChooserButton fillColorButton = new ColorChooserButton(settings.getTemplateFillColor());
+               fillColorButton.addColorPropertyChangeListener(new PropertyChangeListener() {
+                       @Override
+                       public void propertyChange(PropertyChangeEvent evt) {
+                               Color c = (Color) evt.getNewValue();
+                               log.info("Template fill color changed to " + c);
+                               settings.setTemplateFillColor(c);
+                       }
+               });
+               panel.add(fillColorButton, "wrap para");
+               
+
+               panel.add(new JLabel("Template border color:"));
+               final ColorChooserButton borderColorButton = new ColorChooserButton(settings.getTemplateBorderColor());
+               borderColorButton.addColorPropertyChangeListener(new PropertyChangeListener() {
+                       @Override
+                       public void propertyChange(PropertyChangeEvent evt) {
+                               Color c = (Color) evt.getNewValue();
+                               log.info("Template border color changed to " + c);
+                               settings.setTemplateBorderColor(c);
+                       }
+               });
+               panel.add(borderColorButton, "wrap para*2");
+               
+
+
+               JComboBox combo = new JComboBox(new EnumModel<PaperSize>(settings, "PaperSize"));
+               panel.add(new JLabel("Paper size:"));
+               panel.add(combo, "growx, wrap para");
+               
+
+               combo = new JComboBox(new EnumModel<PaperOrientation>(settings, "PaperOrientation"));
+               panel.add(new JLabel("Paper orientation:"));
+               panel.add(combo, "growx, wrap para*2");
+               
+
+
+
+
+               JButton button = new JButton("Reset");
+               button.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               log.user("Resetting print setting values to defaults");
+                               PrintSettings defaults = new PrintSettings();
+                               settings.loadFrom(defaults);
+                       }
+               });
+               panel.add(button, "spanx, split, right");
+               
+
+               JButton closeButton = new JButton("Close");
+               closeButton.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               PrintSettingsDialog.this.setVisible(false);
+                       }
+               });
+               panel.add(closeButton, "right");
+               
+               this.add(panel);
+               GUIUtil.setDisposableDialogOptions(this, closeButton);
+       }
+       
+
+}
index d7fd4ec179430991db3faf50f62abc4f27e7328f..2605dc7d6bd120bbc1796f432dcc7cc8315dde81 100644 (file)
@@ -483,7 +483,7 @@ public class BasicFrame extends JFrame {
                menu.add(item);
                
 
-               item = new JMenuItem("Print...", KeyEvent.VK_P);
+               item = new JMenuItem("Print / Export PDF...", KeyEvent.VK_P);
                item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK));
                item.getAccessibleContext().setAccessibleDescription("Print parts list and fin template");
                item.setIcon(Icons.FILE_PRINT);
@@ -1310,7 +1310,7 @@ public class BasicFrame extends JFrame {
                                        "Experimental feature", JOptionPane.WARNING_MESSAGE);
                        Prefs.putBoolean("printing.experimental.communicated", true);
                }
-               new PrintDialog(document);
+               new PrintDialog(this, document).setVisible(true);
        }
        
        /**
index cd4af70bad5fbfdc2bf97330383aaf34b4f79f0a..15e0cbf06b4a926952edf7df0b5cbc959916bb0b 100644 (file)
@@ -338,6 +338,22 @@ public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
                        }
                }
                
+
+               /*
+                * Detect and ignore bug 6933331 in Sun JRE 1.6.0_18 and others
+                */
+               if (t instanceof IllegalStateException) {
+                       StackTraceElement[] trace = t.getStackTrace();
+                       
+                       if (trace.length > 1 &&
+                                       trace[0].getClassName().equals("sun.awt.windows.WComponentPeer") &&
+                                       trace[0].getMethodName().equals("getBackBuffer")) {
+                               log.warn("Ignoring Sun JRE bug 6933331 " +
+                                               "(see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6933331): " + t);
+                               return true;
+                       }
+               }
+               
                /*
                 * Detect and ignore bug in Sun JRE 1.6.0_19
                 */
diff --git a/src/net/sf/openrocket/gui/print/PaperOrientation.java b/src/net/sf/openrocket/gui/print/PaperOrientation.java
new file mode 100644 (file)
index 0000000..0e973e0
--- /dev/null
@@ -0,0 +1,42 @@
+package net.sf.openrocket.gui.print;
+
+import com.itextpdf.text.Rectangle;
+import com.itextpdf.text.RectangleReadOnly;
+
+public enum PaperOrientation {
+       
+       PORTRAIT("Portrait") {
+               @Override
+               public Rectangle orient(Rectangle rect) {
+                       return new RectangleReadOnly(rect);
+               }
+       },
+       LANDSCAPE("Landscape") {
+               @Override
+               public Rectangle orient(Rectangle rect) {
+                       return new RectangleReadOnly(new Rectangle(rect).rotate());
+               }
+       };
+       
+
+       private final String name;
+       
+       private PaperOrientation(String name) {
+               this.name = name;
+       }
+       
+       /**
+        * Change the orientation of a portrait paper to the orientation represented by this
+        * orientation.
+        *  
+        * @param rect  the original paper size rectangle
+        * @return              the oriented paper size rectangle
+        */
+       public abstract Rectangle orient(Rectangle rect);
+       
+       
+       @Override
+       public String toString() {
+               return name;
+       }
+}
index 63930e2a2f4e6576e8e12575b585ca6f02e3278c..d3d07410570570791288f481d48ff3e4b3aa21f0 100644 (file)
-/*
- * PaperSize.java
- */
 package net.sf.openrocket.gui.print;
 
-import com.itextpdf.text.PageSize;
-import com.itextpdf.text.Rectangle;
-import com.itextpdf.text.RectangleReadOnly;
-
-import javax.print.attribute.standard.MediaSizeName;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Various mappings of paper sizes and their names.
- */
-public class PaperSize {
-
-    /** Map of name to MediaSizeName instance. */
-    private static Map<String, MediaSizeName> paperNames = new HashMap<String, MediaSizeName>();
-    /** Map of identifying name to displayable name. */
-    private static Map<String, String> displayableNames = new HashMap<String, String>();
-    /** Map of MediaSizeName to rectangle, which defines the paper size. */
-    private static Map<MediaSizeName, Rectangle> paperItext = new HashMap<MediaSizeName, Rectangle>();
-
-    /**
-     * Init.
-     */
-    static {
-        populateNameMap();
-        populateITextSizeMap();
-        populateDisplayableNameMap();
-    }
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Locale;
 
-    /** Disallow construction. */
-    private PaperSize() {}
+import net.sf.openrocket.logging.LogHelper;
+import net.sf.openrocket.startup.Application;
 
-    /**
-     * Map an identifying paper name to it's corresponding MediaSizeName.
-     *
-     * @param name  a paper name
-     *
-     * @return  the associated MediaSizeName (or null if not found).
-     */
-    public static MediaSizeName convert(String name) {
-        return paperNames.get(name);
-    }
-
-    /**
-     * Map a MediaSizeName to it's size Rectangle.
-     *
-     * @param name  a paper name
-     *
-     * @return a Rectangle or null
-     */
-    public static Rectangle convert(MediaSizeName name) {
-        return paperItext.get(name);
-    }
-
-    /**
-     * Map an identifying paper name to a displayable name (usually it's common name).
-     *
-     * @param name  a paper name
-     *
-     * @return a displayable name
-     */
-    public static String toDisplayable(String name) {
-        return displayableNames.get(name);
-    }
-
-    private static void populateNameMap() {
-        paperNames.put("iso-a0", MediaSizeName.ISO_A0);
-        paperNames.put("iso-a1", MediaSizeName.ISO_A1);
-        paperNames.put("iso-a2", MediaSizeName.ISO_A2);
-        paperNames.put("iso-a3", MediaSizeName.ISO_A3);
-        paperNames.put("iso-a4", MediaSizeName.ISO_A4);
-        paperNames.put("iso-a5", MediaSizeName.ISO_A5);
-        paperNames.put("iso-a6", MediaSizeName.ISO_A6);
-        paperNames.put("iso-a7", MediaSizeName.ISO_A7);
-        paperNames.put("iso-a8", MediaSizeName.ISO_A8);
-        paperNames.put("iso-a9", MediaSizeName.ISO_A9);
-        paperNames.put("iso-a10", MediaSizeName.ISO_A10);
-        paperNames.put("iso-b0", MediaSizeName.ISO_B0);
-        paperNames.put("iso-b1", MediaSizeName.ISO_B1);
-        paperNames.put("iso-b2", MediaSizeName.ISO_B2);
-        paperNames.put("iso-b3", MediaSizeName.ISO_B3);
-        paperNames.put("iso-b4", MediaSizeName.ISO_B4);
-        paperNames.put("iso-b5", MediaSizeName.ISO_B5);
-        paperNames.put("iso-b6", MediaSizeName.ISO_B6);
-        paperNames.put("iso-b7", MediaSizeName.ISO_B7);
-        paperNames.put("iso-b8", MediaSizeName.ISO_B8);
-        paperNames.put("iso-b9", MediaSizeName.ISO_B9);
-        paperNames.put("iso-b10", MediaSizeName.ISO_B10);
-        paperNames.put("na-letter", MediaSizeName.NA_LETTER);
-        paperNames.put("na-legal", MediaSizeName.NA_LEGAL);
-        paperNames.put("na-8x10", MediaSizeName.NA_8X10);
-        paperNames.put("na-5x7", MediaSizeName.NA_5X7);
-        paperNames.put("executive", MediaSizeName.EXECUTIVE);
-        paperNames.put("folio", MediaSizeName.FOLIO);
-        paperNames.put("invoice", MediaSizeName.INVOICE);
-        paperNames.put("tabloid", MediaSizeName.TABLOID);
-        paperNames.put("ledger", MediaSizeName.LEDGER);
-        paperNames.put("quarto", MediaSizeName.QUARTO);
-        paperNames.put("iso-c0", MediaSizeName.ISO_C0);
-        paperNames.put("iso-c1", MediaSizeName.ISO_C1);
-        paperNames.put("iso-c2", MediaSizeName.ISO_C2);
-        paperNames.put("iso-c3", MediaSizeName.ISO_C3);
-        paperNames.put("iso-c4", MediaSizeName.ISO_C4);
-        paperNames.put("iso-c5", MediaSizeName.ISO_C5);
-        paperNames.put("iso-c6", MediaSizeName.ISO_C6);
-        paperNames.put("iso-designated-long", MediaSizeName.ISO_DESIGNATED_LONG);
-        paperNames.put("jis-b0", MediaSizeName.JIS_B0);
-        paperNames.put("jis-b1", MediaSizeName.JIS_B1);
-        paperNames.put("jis-b2", MediaSizeName.JIS_B2);
-        paperNames.put("jis-b3", MediaSizeName.JIS_B3);
-        paperNames.put("jis-b4", MediaSizeName.JIS_B4);
-        paperNames.put("jis-b5", MediaSizeName.JIS_B5);
-        paperNames.put("jis-b6", MediaSizeName.JIS_B6);
-        paperNames.put("jis-b7", MediaSizeName.JIS_B7);
-        paperNames.put("jis-b8", MediaSizeName.JIS_B8);
-        paperNames.put("jis-b9", MediaSizeName.JIS_B9);
-        paperNames.put("jis-b10", MediaSizeName.JIS_B10);
-        paperNames.put("a", MediaSizeName.A);
-        paperNames.put("b", MediaSizeName.B);
-        paperNames.put("c", MediaSizeName.C);
-        paperNames.put("d", MediaSizeName.D);
-        paperNames.put("e", MediaSizeName.E);
-    }
-
-    private static void populateITextSizeMap() {
-        paperItext.put(MediaSizeName.ISO_A0, PageSize.A0);
-        paperItext.put(MediaSizeName.ISO_A1, PageSize.A1);
-        paperItext.put(MediaSizeName.ISO_A2, PageSize.A2);
-        paperItext.put(MediaSizeName.ISO_A3, PageSize.A3);
-        paperItext.put(MediaSizeName.ISO_A4, PageSize.A4);
-        paperItext.put(MediaSizeName.ISO_A5, PageSize.A5);
-        paperItext.put(MediaSizeName.ISO_A6, PageSize.A6);
-        paperItext.put(MediaSizeName.ISO_A7, PageSize.A7);
-        paperItext.put(MediaSizeName.ISO_A8, PageSize.A8);
-        paperItext.put(MediaSizeName.ISO_A9, PageSize.A9);
-        paperItext.put(MediaSizeName.ISO_A10, PageSize.A10);
-        paperItext.put(MediaSizeName.ISO_B0, PageSize.B0);
-        paperItext.put(MediaSizeName.ISO_B1, PageSize.B1);
-        paperItext.put(MediaSizeName.ISO_B2, PageSize.B2);
-        paperItext.put(MediaSizeName.ISO_B3, PageSize.B3);
-        paperItext.put(MediaSizeName.ISO_B4, PageSize.B4);
-        paperItext.put(MediaSizeName.ISO_B5, PageSize.B5);
-        paperItext.put(MediaSizeName.ISO_B6, PageSize.B6);
-        paperItext.put(MediaSizeName.ISO_B7, PageSize.B7);
-        paperItext.put(MediaSizeName.ISO_B8, PageSize.B8);
-        paperItext.put(MediaSizeName.ISO_B9, PageSize.B9);
-        paperItext.put(MediaSizeName.ISO_B10, PageSize.B10);
-        paperItext.put(MediaSizeName.NA_LETTER, PageSize.LETTER);
-        paperItext.put(MediaSizeName.NA_LEGAL, PageSize.LEGAL);
-        paperItext.put(MediaSizeName.EXECUTIVE, PageSize.EXECUTIVE);
-        paperItext.put(MediaSizeName.A, PageSize.LETTER);
-        paperItext.put(MediaSizeName.B, PageSize._11X17);
-        paperItext.put(MediaSizeName.C, new RectangleReadOnly(PrintUnit.INCHES.toPoints(17), PrintUnit.INCHES.toPoints(22)));
-        paperItext.put(MediaSizeName.D, new RectangleReadOnly(PrintUnit.INCHES.toPoints(22), PrintUnit.INCHES.toPoints(34)));
-        paperItext.put(MediaSizeName.E, new RectangleReadOnly(PrintUnit.INCHES.toPoints(34), PrintUnit.INCHES.toPoints(44)));
-    }
+import com.itextpdf.text.PageSize;
+import com.itextpdf.text.Rectangle;
 
-    /**
-     * Create a name map from standard to displayable names
-     */
-    private static void populateDisplayableNameMap() {
-        displayableNames.put("iso-a0", "A0");
-        displayableNames.put("iso-a1", "A1");
-        displayableNames.put("iso-a2", "A2");
-        displayableNames.put("iso-a3", "A3");
-        displayableNames.put("iso-a4", "A4");
-        displayableNames.put("iso-a5", "A5");
-        displayableNames.put("iso-a6", "A6");
-        displayableNames.put("iso-a7", "A7");
-        displayableNames.put("iso-a8", "A8");
-        displayableNames.put("iso-a9", "A9");
-        displayableNames.put("iso-a10", "A10");
-        displayableNames.put("iso-b0", "B0");
-        displayableNames.put("iso-b1", "B1");
-        displayableNames.put("iso-b2", "B2");
-        displayableNames.put("iso-b3", "B3");
-        displayableNames.put("iso-b4", "B4");
-        displayableNames.put("iso-b5", "B5");
-        displayableNames.put("iso-b6", "B6");
-        displayableNames.put("iso-b7", "B7");
-        displayableNames.put("iso-b8", "B8");
-        displayableNames.put("iso-b9", "B9");
-        displayableNames.put("iso-b10", "B10");
-        displayableNames.put("na-letter", "US Letter");
-        displayableNames.put("na-legal", "US Legal");
-        displayableNames.put("na-8x10", "US 8x10 inch");
-        displayableNames.put("na-5x7", "US 5x7 inch");
-        displayableNames.put("executive", "Executive");
-        displayableNames.put("folio", "Folio");
-        displayableNames.put("invoice", "Invoice");
-        displayableNames.put("tabloid", "Tabloid");
-        displayableNames.put("ledger", "Ledger");
-        displayableNames.put("quarto", "Quarto");
-        displayableNames.put("iso-c0", "C0");
-        displayableNames.put("iso-c1", "C1");
-        displayableNames.put("iso-c2", "C2");
-        displayableNames.put("iso-c3", "C3");
-        displayableNames.put("iso-c4", "C4");
-        displayableNames.put("iso-c5", "C5");
-        displayableNames.put("iso-c6", "C6");
-        displayableNames.put("iso-designated-long", "ISO Designated Long Size");
-        displayableNames.put("jis-b0", "Japanese B0");
-        displayableNames.put("jis-b1", "Japanese B1");
-        displayableNames.put("jis-b2", "Japanese B2");
-        displayableNames.put("jis-b3", "Japanese B3");
-        displayableNames.put("jis-b4", "Japanese B4");
-        displayableNames.put("jis-b5", "Japanese B5");
-        displayableNames.put("jis-b6", "Japanese B6");
-        displayableNames.put("jis-b7", "Japanese B7");
-        displayableNames.put("jis-b8", "Japanese B8");
-        displayableNames.put("jis-b9", "Japanese B9");
-        displayableNames.put("jis-b10", "Japanese B10");
-        displayableNames.put("a", "US Letter");
-        displayableNames.put("b", "Engineering ANSI B");
-        displayableNames.put("c", "Engineering ANSI C");
-        displayableNames.put("d", "Engineering ANSI D");
-        displayableNames.put("e", "Engineering ANSI E");
-        displayableNames.put("arch-a", "Architectural A");
-        displayableNames.put("arch-b", "Architectural B");
-        displayableNames.put("arch-c", "Architectural C");
-        displayableNames.put("arch-d", "Architectural D");
-        displayableNames.put("arch-e", "Architectural E");
-        displayableNames.put("japanese-postcard", "Japanese Postcard");
-        displayableNames.put("oufuko-postcard", "Oufuko Postcard");
-        displayableNames.put("italian-envelope", "Italian Envelope");
-        displayableNames.put("personal-envelope", "Personal Envelope");
-        displayableNames.put("na-number-11-envelope", "#11 Envelope");
-        displayableNames.put("na-number-12-envelope", "#12 Envelope");
-        displayableNames.put("na-number-14-envelope", "#14 Envelope");
-        displayableNames.put("na-10x13-envelope", "10\"x13\" Envelope");
-        displayableNames.put("na-9x12-envelope", "9\"x12\" Envelope");
-        displayableNames.put("na-number-10-envelope", "#10 Envelope");
-        displayableNames.put("na-7x9-envelope", "7\"x9\" Envelope");
-        displayableNames.put("na-9x11-envelope", "9\"x11\" Envelope");
-        displayableNames.put("na-10x14-envelope", "10\"x14\" Envelope");
-        displayableNames.put("na-number-9-envelope", "#9 Envelope");
-        displayableNames.put("na-6x9-envelope", "6\"x9\" Envelope");
-        displayableNames.put("na-10x15-envelope", "10\"x15\" Envelope");
-        displayableNames.put("monarch-envelope", "Monarch Envelope");
-    }
+public enum PaperSize {
+       A3("A3", PageSize.A3),
+       A4("A4", PageSize.A4),
+       A5("A5", PageSize.A5),
+       LETTER("Letter", PageSize.LETTER),
+       LEGAL("Legal", PageSize.LEGAL);
+       
+       private final String name;
+       private final Rectangle size;
+       
+       private PaperSize(String name, Rectangle size) {
+               this.name = name;
+               this.size = size;
+       }
+       
+       public Rectangle getSize() {
+               return size;
+       }
+       
+       @Override
+       public String toString() {
+               return name;
+       }
+       
+       
 
+       //////////////////////////
+       
+       private static final LogHelper log = Application.getLogger();
+       private static PaperSize defaultSize = null;
+       
+       /**
+        * Return the default paper size for the current system.
+        * @return      the default paper size
+        */
+       public static PaperSize getDefault() {
+               if (defaultSize == null) {
+                       
+                       // Test environment variable "PAPERSIZE" (Unix)
+                       defaultSize = getDefaultFromEnvironmentVariable();
+                       if (defaultSize != null) {
+                               log.info("Selecting default paper size from PAPERSIZE environment variable: " + defaultSize);
+                               return defaultSize;
+                       }
+                       
+                       // Test /etc/papersize (Unix)
+                       defaultSize = getDefaultFromEtcPapersize();
+                       if (defaultSize != null) {
+                               log.info("Selecting default paper size from /etc/papersize: " + defaultSize);
+                               return defaultSize;
+                       }
+                       
+                       // Test user.country
+                       defaultSize = getDefaultForCountry(System.getProperty("user.country"));
+                       if (defaultSize != null) {
+                               log.info("Selecting default paper size based on user.country: " + defaultSize);
+                               return defaultSize;
+                       }
+                       
+                       // Test locale country
+                       defaultSize = getDefaultForCountry(Locale.getDefault().getCountry());
+                       if (defaultSize != null) {
+                               log.info("Selecting default paper size based on locale country: " + defaultSize);
+                               return defaultSize;
+                       }
+                       
+                       // Fallback to A4
+                       defaultSize = A4;
+                       log.info("Selecting default paper size fallback: " + defaultSize);
+               }
+               
+               return defaultSize;
+       }
+       
+       
+       /**
+        * Attempt to read the default paper size from the "PAPERSIZE" environment variable.
+        * 
+        * @return      the default paper size if successful, or <code>null</code> if unable to read/parse file.
+        */
+       private static PaperSize getDefaultFromEnvironmentVariable() {
+               String str = System.getenv("PAPERSIZE");
+               return getSizeFromString(str);
+       }
+       
+       /**
+        * Attempt to read the default paper size from the file defined by the environment variable
+        * PAPERCONF or from /etc/papersize.
+        * 
+        * @return      the default paper size if successful, or <code>null</code> if unable to read/parse file.
+        */
+       private static PaperSize getDefaultFromEtcPapersize() {
+               
+               // Find file to read
+               String file = System.getenv("PAPERCONF");
+               if (file == null) {
+                       file = "/etc/papersize";
+               }
+               
+               // Attempt to read the file
+               BufferedReader in = null;
+               try {
+                       
+                       String str;
+                       in = new BufferedReader(new FileReader(file));
+                       while ((str = in.readLine()) != null) {
+                               if (str.matches("^\\s*(#.*|$)")) {
+                                       continue;
+                               }
+                               break;
+                       }
+                       
+                       return getSizeFromString(str);
+                       
+               } catch (IOException e) {
+                       
+                       // Could not read file
+                       return null;
+                       
+               } finally {
+                       if (in != null) {
+                               try {
+                                       in.close();
+                               } catch (IOException e) {
+                               }
+                       }
+               }
+       }
+       
+       
+       /**
+        * Get a paper size based on a string.  The string is trimmed and case-insensitively 
+        * compared to the base names of the paper sizes.
+        * 
+        * @param size  the size string (may be null)
+        * @return              the corresponding paper size, or null if unknown
+        */
+       static PaperSize getSizeFromString(String size) {
+               if (size == null) {
+                       return null;
+               }
+               
+               size = size.trim();
+               for (PaperSize p : PaperSize.values()) {
+                       if (p.name.equalsIgnoreCase(size)) {
+                               return p;
+                       }
+               }
+               return null;
+       }
+       
+       
+       /**
+        * Get default paper size for a specific country.  This method falls back to A4 for
+        * any country not known to use Letter.
+        * 
+        * @param country       the 2-char country code (may be null)
+        * @return                      the paper size, or <code>null</code> if country is not a country code
+        */
+       static PaperSize getDefaultForCountry(String country) {
+               /*
+                * List is based on info from http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/territory_language_information.html
+                * OpenOffice.org agrees with this:  http://wiki.services.openoffice.org/wiki/DefaultPaperSize#Summary
+                */
+               final String[] letterCountries = { "BZ", "CA", "CL", "CO", "CR", "SV", "GT", "MX", "NI", "PA", "PH", "PR", "US", "VE" };
+               
+               if (country == null || !country.matches("^[a-zA-Z][a-zA-Z]$")) {
+                       return null;
+               }
+               
+               country = country.toUpperCase();
+               for (String c : letterCountries) {
+                       if (c.equals(country)) {
+                               return LETTER;
+                       }
+               }
+               return A4;
+       }
+       
 }
index 1ff040bb74c89c4a76aa6c826047ce00a5e7ea83..0a71bbbe1cca1655d02710d07163016033a8442c 100644 (file)
@@ -4,6 +4,15 @@
  */
 package net.sf.openrocket.gui.print;
 
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.Set;
+
+import net.sf.openrocket.document.OpenRocketDocument;
+import net.sf.openrocket.gui.print.visitor.FinSetVisitorStrategy;
+import net.sf.openrocket.gui.print.visitor.PartsDetailVisitorStrategy;
+
 import com.itextpdf.text.Document;
 import com.itextpdf.text.DocumentException;
 import com.itextpdf.text.ExceptionConverter;
@@ -11,107 +20,92 @@ import com.itextpdf.text.Rectangle;
 import com.itextpdf.text.pdf.PdfBoolean;
 import com.itextpdf.text.pdf.PdfName;
 import com.itextpdf.text.pdf.PdfWriter;
-import net.sf.openrocket.document.OpenRocketDocument;
-import net.sf.openrocket.gui.print.visitor.FinSetVisitorStrategy;
-import net.sf.openrocket.gui.print.visitor.PartsDetailVisitorStrategy;
-
-import javax.print.attribute.standard.MediaSizeName;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Iterator;
-import java.util.Set;
 
 /**
  * This is the main active object for printing.  It performs all actions necessary to create and populate the print
  * file.
  */
 public class PrintController {
-
-    /**
-     * Print the selected components to a PDF document.
-     *
-     * @param doc         the OR document
-     * @param toBePrinted the user chosen items to print
-     * @param outputFile  the file being written to
-     * @param msn         the paper size
-     */
-    public void print(OpenRocketDocument doc, Iterator<PrintableContext> toBePrinted, OutputStream outputFile,
-                      MediaSizeName msn) {
-
-        Document idoc = new Document(convertWithDefault(msn));
-        PdfWriter writer = null;
-        try {
-            writer = PdfWriter.getInstance(idoc, outputFile);
-            writer.setStrictImageSequence(true);
-
-            writer.addViewerPreference(PdfName.PRINTSCALING, PdfName.NONE);
-            writer.addViewerPreference(PdfName.PICKTRAYBYPDFSIZE, PdfBoolean.PDFTRUE);
-            try {
-                idoc.open();
-                Thread.sleep(1000);
-            }
-            catch (InterruptedException e) {
-            }
-            while (toBePrinted.hasNext()) {
-                PrintableContext printableContext = toBePrinted.next();
-
-                Set<Integer> stages = printableContext.getStageNumber();
-
-                switch (printableContext.getPrintable()) {
-                    case DESIGN_REPORT:
-                        DesignReport dp = new DesignReport(doc, idoc);
-                        dp.writeToDocument(writer);
-                        idoc.newPage();
-                        break;
-                    case FIN_TEMPLATE:
-                        final FinSetVisitorStrategy finWriter = new FinSetVisitorStrategy(idoc,
-                                                                                          writer,
-                                                                                          stages);
-                        finWriter.writeToDocument(doc.getRocket());
-                        break;
-                    case PARTS_DETAIL:
-                        final PartsDetailVisitorStrategy detailVisitor = new PartsDetailVisitorStrategy(idoc,
-                                                                                                        writer,
-                                                                                                        stages);
-                        detailVisitor.writeToDocument(doc.getRocket());
-                        detailVisitor.close();
-                        idoc.newPage();
-                        break;
-                }
-            }
-            //Stupid iText throws a really nasty exception if there is no data when close is called.
-            if (writer.getCurrentDocumentSize() <= 140) {
-                writer.setPageEmpty(false);
-            }
-            writer.close();
-            idoc.close();
-        }
-        catch (DocumentException e) {
-        }
-        catch (ExceptionConverter ec) {
-        }
-        finally {
-            if (outputFile != null) {
-                try {
-                    outputFile.close();
-                }
-                catch (IOException e) {
-                }
-            }
-        }
-    }
-
-    /**
-     * Convert a media size name to a rectangle that defines the bounds of the corresponding paper size.
-     *
-     * @param msn the MediaSizeName to convert
-     * @return the corresponding Rectangle
-     */
-    private Rectangle convertWithDefault(final MediaSizeName msn) {
-        Rectangle result = PaperSize.convert(msn);
-        if (result == null) {
-            result = PaperSize.convert(PrintUtilities.getDefaultMedia().getMediaSizeName());
-        }
-        return result;
-    }
+       
+       /**
+        * Print the selected components to a PDF document.
+        *
+        * @param doc         the OR document
+        * @param toBePrinted the user chosen items to print
+        * @param outputFile  the file being written to
+        * @param msn         the paper size
+        */
+       public void print(OpenRocketDocument doc, Iterator<PrintableContext> toBePrinted, OutputStream outputFile,
+                                               PrintSettings settings) {
+               
+               Document idoc = new Document(getSize(settings));
+               PdfWriter writer = null;
+               try {
+                       writer = PdfWriter.getInstance(idoc, outputFile);
+                       writer.setStrictImageSequence(true);
+                       
+                       writer.addViewerPreference(PdfName.PRINTSCALING, PdfName.NONE);
+                       writer.addViewerPreference(PdfName.PICKTRAYBYPDFSIZE, PdfBoolean.PDFTRUE);
+                       try {
+                               idoc.open();
+                               Thread.sleep(1000);
+                       } catch (InterruptedException e) {
+                       }
+                       while (toBePrinted.hasNext()) {
+                               PrintableContext printableContext = toBePrinted.next();
+                               
+                               Set<Integer> stages = printableContext.getStageNumber();
+                               
+                               switch (printableContext.getPrintable()) {
+                               case DESIGN_REPORT:
+                                       DesignReport dp = new DesignReport(doc, idoc);
+                                       dp.writeToDocument(writer);
+                                       idoc.newPage();
+                                       break;
+                               case FIN_TEMPLATE:
+                                       final FinSetVisitorStrategy finWriter = new FinSetVisitorStrategy(idoc,
+                                                                                                                                                                                       writer,
+                                                                                                                                                                                       stages);
+                                       finWriter.writeToDocument(doc.getRocket());
+                                       break;
+                               case PARTS_DETAIL:
+                                       final PartsDetailVisitorStrategy detailVisitor = new PartsDetailVisitorStrategy(idoc,
+                                                                                                                                                                                                               writer,
+                                                                                                                                                                                                               stages);
+                                       detailVisitor.writeToDocument(doc.getRocket());
+                                       detailVisitor.close();
+                                       idoc.newPage();
+                                       break;
+                               }
+                       }
+                       //Stupid iText throws a really nasty exception if there is no data when close is called.
+                       if (writer.getCurrentDocumentSize() <= 140) {
+                               writer.setPageEmpty(false);
+                       }
+                       writer.close();
+                       idoc.close();
+               } catch (DocumentException e) {
+               } catch (ExceptionConverter ec) {
+               } finally {
+                       if (outputFile != null) {
+                               try {
+                                       outputFile.close();
+                               } catch (IOException e) {
+                               }
+                       }
+               }
+       }
+       
+       /**
+        * Get the correct paper size from the print settings.
+        * 
+        * @param settings      the print settings
+        * @return                      the paper size
+        */
+       private Rectangle getSize(PrintSettings settings) {
+               PaperSize size = settings.getPaperSize();
+               PaperOrientation orientation = settings.getPaperOrientation();
+               return orientation.orient(size.getSize());
+       }
+       
 }
diff --git a/src/net/sf/openrocket/gui/print/PrintServiceDialog.java b/src/net/sf/openrocket/gui/print/PrintServiceDialog.java
deleted file mode 100644 (file)
index 4aedaba..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
-/*\r
- * PrintServiceDialog.java\r
- *\r
- */\r
-package net.sf.openrocket.gui.print;\r
-\r
-import net.miginfocom.swing.MigLayout;\r
-\r
-import javax.print.DocFlavor;\r
-import javax.print.PrintService;\r
-import javax.print.ServiceUIFactory;\r
-import javax.print.attribute.HashPrintRequestAttributeSet;\r
-import javax.print.attribute.PrintRequestAttribute;\r
-import javax.print.attribute.PrintRequestAttributeSet;\r
-import javax.print.attribute.standard.Destination;\r
-import javax.print.attribute.standard.Media;\r
-import javax.print.attribute.standard.MediaSizeName;\r
-import javax.print.attribute.standard.MediaTray;\r
-import javax.swing.AbstractAction;\r
-import javax.swing.ActionMap;\r
-import javax.swing.BorderFactory;\r
-import javax.swing.InputMap;\r
-import javax.swing.JButton;\r
-import javax.swing.JComboBox;\r
-import javax.swing.JDialog;\r
-import javax.swing.JLabel;\r
-import javax.swing.JPanel;\r
-import javax.swing.JTabbedPane;\r
-import javax.swing.KeyStroke;\r
-import javax.swing.border.EmptyBorder;\r
-import javax.swing.event.PopupMenuEvent;\r
-import javax.swing.event.PopupMenuListener;\r
-import java.awt.Container;\r
-import java.awt.Dialog;\r
-import java.awt.event.ActionEvent;\r
-import java.awt.event.ActionListener;\r
-import java.awt.event.ItemEvent;\r
-import java.awt.event.ItemListener;\r
-import java.awt.event.WindowAdapter;\r
-import java.awt.event.WindowEvent;\r
-import java.util.ArrayList;\r
-import java.util.Iterator;\r
-import java.util.Set;\r
-import java.util.TreeSet;\r
-\r
-public class PrintServiceDialog extends JDialog implements ActionListener {\r
-\r
-    public static final int APPROVE = 1;\r
-    private JButton btnCancel, btnPrint;\r
-    private boolean pdfFlavorSupported = true;\r
-    private PrintService services[];\r
-    private int defaultServiceIndex = -1;\r
-    private int status;\r
-    private PrintRequestAttributeSet asOriginal;\r
-    private HashPrintRequestAttributeSet asCurrent;\r
-    private PrintService psCurrent;\r
-    private DocFlavor docFlavor;\r
-    private GeneralPanel pnlGeneral;\r
-    private static final String GENERAL_TAB_TITLE = "General";\r
-    private static final String PRINT_BUTTON_LABEL = "Print";\r
-    private static final String CANCEL_BUTTON_LABEL = "Cancel";\r
-\r
-    private class MediaPanel extends JPanel\r
-            implements ItemListener {\r
-\r
-        private static final String strTitle = "Media";\r
-        private static final String SOURCE = "Source:";\r
-        private static final String SIZE = "Size:";\r
-\r
-        private JLabel lblSize, lblSource;\r
-        private JComboBox cbSize, cbSource;\r
-        private ArrayList<MediaSizeName> sizes;\r
-        private ArrayList sources;\r
-\r
-        private String getMediaName(String s) {\r
-            String s1 = s.replace(' ', '-');\r
-            s1 = s1.replace('#', 'n');\r
-            return PaperSize.toDisplayable(s1);\r
-        }\r
-\r
-        public void itemStateChanged(ItemEvent itemevent) {\r
-            Object obj = itemevent.getSource();\r
-            if (itemevent.getStateChange() == ItemEvent.SELECTED) {\r
-                if (obj == cbSize) {\r
-                    int i = cbSize.getSelectedIndex();\r
-                    if (i >= 0 && i < sizes.size()) {\r
-                        if (cbSource.getItemCount() > 1 && cbSource.getSelectedIndex() >= 1) {\r
-                            int k = cbSource.getSelectedIndex() - 1;\r
-                            MediaTray mediatray = (MediaTray) sources.get(k);\r
-                            asCurrent.add(new MediaWrapper(mediatray));\r
-                        }\r
-                        asCurrent.add(sizes.get(i));\r
-                    }\r
-                }\r
-                else if (obj == cbSource) {\r
-                    int j = cbSource.getSelectedIndex();\r
-                    if (j >= 1 && j < sources.size() + 1) {\r
-                        asCurrent.remove(MediaWrapper.class);\r
-                        asCurrent.add((MediaTray) sources.get(j - 1));\r
-                    }\r
-                    else if (j == 0) {\r
-                        asCurrent.remove(MediaWrapper.class);\r
-                        if (cbSize.getItemCount() > 0) {\r
-                            int l = cbSize.getSelectedIndex();\r
-                            asCurrent.add(sizes.get(l));\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-\r
-        public void updateInfo() {\r
-            boolean flag = false;\r
-            cbSize.removeItemListener(this);\r
-            cbSize.removeAllItems();\r
-            cbSource.removeItemListener(this);\r
-            cbSource.removeAllItems();\r
-            cbSource.addItem(getMediaName("auto-select"));\r
-            sizes.clear();\r
-            sources.clear();\r
-            if (psCurrent != null && psCurrent.isAttributeCategorySupported(Media.class)) {\r
-                flag = true;\r
-                Object obj = null;\r
-                try {\r
-                    obj = psCurrent.getSupportedAttributeValues(Media.class, docFlavor, asCurrent);\r
-                }\r
-                catch (IllegalArgumentException iae) {\r
-                    pdfFlavorSupported = false;\r
-                    //dgp\r
-                }\r
-                if (obj instanceof Media[]) {\r
-                    Media amedia[] = (Media[]) obj;\r
-                    Set<SortableMediaSizeName> sizeSet = new TreeSet<SortableMediaSizeName>();\r
-\r
-                    for (int i = 0; i < amedia.length; i++) {\r
-                        Media media = amedia[i];\r
-                        if (media instanceof MediaSizeName) {\r
-                            sizeSet.add(new SortableMediaSizeName((MediaSizeName) media));\r
-                        }\r
-                        else if (media instanceof MediaTray) {\r
-                            sources.add(media);\r
-                            cbSource.addItem(getMediaName(media.toString()));\r
-                        }\r
-                    }\r
-\r
-                    //The set eliminates duplicates.\r
-                    for (Iterator<SortableMediaSizeName> mediaSizeNameIterator = sizeSet.iterator(); mediaSizeNameIterator\r
-                            .hasNext();) {\r
-                        SortableMediaSizeName media = mediaSizeNameIterator.next();\r
-\r
-                        sizes.add(media.getMediaSizeName());\r
-                        cbSize.addItem(media.toString());\r
-                    }\r
-\r
-                }\r
-            }\r
-            boolean flag1 = flag && sizes.size() > 0;\r
-            lblSize.setEnabled(flag1);\r
-            cbSize.setEnabled(flag1);\r
-            cbSource.setEnabled(false);\r
-            lblSource.setEnabled(false);\r
-            if (flag && psCurrent != null) {\r
-                Media media = (Media) asCurrent.get(Media.class);\r
-                boolean attributeValueSupported = false;\r
-                try {\r
-                    attributeValueSupported = media == null ? false : psCurrent.isAttributeValueSupported(media,\r
-                                                                                                          docFlavor,\r
-                                                                                                          asCurrent);\r
-                }\r
-                catch (IllegalArgumentException iae) {\r
-                    pdfFlavorSupported = false;\r
-                }\r
-                if (media == null || !attributeValueSupported) {\r
-                    media = (Media) psCurrent.getDefaultAttributeValue(Media.class);\r
-                    if (media == null && sizes.size() > 0) {\r
-                        media = sizes.get(0);\r
-                    }\r
-                    if (media != null) {\r
-                        asCurrent.add(media);\r
-                    }\r
-                }\r
-                if (media != null) {\r
-                    if (media instanceof MediaSizeName) {\r
-                        MediaSizeName mediasizename = (MediaSizeName) media;\r
-                        cbSize.setSelectedIndex(sizes.indexOf(mediasizename));\r
-                    }\r
-                    else if (media instanceof MediaTray) {\r
-                        MediaTray mediatray = (MediaTray) media;\r
-                        cbSource.setSelectedIndex(sources.indexOf(mediatray) + 1);\r
-                    }\r
-                }\r
-                else {\r
-                    cbSize.setSelectedIndex(sizes.size() <= 0 ? -1 : 0);\r
-                    cbSource.setSelectedIndex(0);\r
-                }\r
-                int j = cbSize.getSelectedIndex();\r
-                if (j >= 0 && j < sizes.size()) {\r
-                    asCurrent.add(sizes.get(j));\r
-                }\r
-                j = cbSource.getSelectedIndex();\r
-                if (j >= 1 && j < sources.size() + 1) {\r
-                    asCurrent.add((MediaTray) sources.get(j - 1));\r
-                }\r
-            }\r
-            cbSize.addItemListener(this);\r
-            cbSource.addItemListener(this);\r
-        }\r
-\r
-        public MediaPanel() {\r
-            super(new MigLayout("fill, gap rel unrel"));\r
-            sizes = new ArrayList<MediaSizeName>();\r
-            sources = new ArrayList();\r
-            setBorder(BorderFactory.createTitledBorder(strTitle));\r
-            cbSize = new JComboBox();\r
-            cbSource = new JComboBox();\r
-            lblSize = new JLabel(SIZE, 11);\r
-            lblSize.setDisplayedMnemonic(PrintServiceDialog.getMnemonic(SIZE));\r
-            lblSize.setLabelFor(cbSize);\r
-            add(lblSize);\r
-            add(cbSize, "wrap");\r
-            lblSource = new JLabel(SOURCE, 11);\r
-            lblSource.setDisplayedMnemonic(PrintServiceDialog.getMnemonic(SOURCE));\r
-            lblSource.setLabelFor(cbSource);\r
-            add(lblSource);\r
-            add(cbSource);\r
-        }\r
-\r
-        class SortableMediaSizeName implements Comparable {\r
-            MediaSizeName delegate;\r
-\r
-            String displayableName;\r
-\r
-            SortableMediaSizeName(MediaSizeName msn) {\r
-                delegate = msn;\r
-                displayableName = getMediaName(delegate.toString());\r
-                if (displayableName == null) {\r
-                    displayableName = delegate.toString();\r
-                }\r
-            }\r
-\r
-            /**\r
-             * Returns a string value corresponding to this enumeration value.\r
-             */\r
-            @Override\r
-            public String toString() {\r
-                return displayableName;\r
-            }\r
-\r
-            @Override\r
-            public int compareTo(final Object o) {\r
-                String name = displayableName;\r
-                if (name != null) {\r
-                    return name.compareTo(o.toString());\r
-                }\r
-                return 1;\r
-            }\r
-\r
-            @Override\r
-            public boolean equals(final Object o) {\r
-                if (this == o) {\r
-                    return true;\r
-                }\r
-                if (o == null || getClass() != o.getClass()) {\r
-                    return false;\r
-                }\r
-\r
-                final SortableMediaSizeName that = (SortableMediaSizeName) o;\r
-\r
-                return displayableName.equals(that.displayableName);\r
-            }\r
-\r
-            @Override\r
-            public int hashCode() {\r
-                return displayableName.hashCode();\r
-            }\r
-\r
-            MediaSizeName getMediaSizeName() {\r
-                return delegate;\r
-            }\r
-        }\r
-    }\r
-\r
-    private class PrintServicePanel extends JPanel\r
-            implements ActionListener, ItemListener, PopupMenuListener {\r
-\r
-        private final String strTitle = "Print Service";\r
-        private JButton btnProperties;\r
-        private JComboBox cbName;\r
-        private ServiceUIFactory uiFactory;\r
-        private boolean changedService;\r
-\r
-        public PrintServicePanel() {\r
-            super(new MigLayout("fill, gap rel unrel"));\r
-            changedService = false;\r
-            if (psCurrent != null) {\r
-                uiFactory = psCurrent.getServiceUIFactory();\r
-            }\r
-            setBorder(BorderFactory.createTitledBorder(strTitle));\r
-            String as[] = new String[services.length];\r
-            for (int i = 0; i < as.length; i++) {\r
-                as[i] = services[i].getName();\r
-            }\r
-\r
-            cbName = new JComboBox(as);\r
-            if (defaultServiceIndex != -1 && defaultServiceIndex < services.length) {\r
-                cbName.setSelectedIndex(defaultServiceIndex);\r
-            }\r
-            cbName.addItemListener(this);\r
-            cbName.addPopupMenuListener(this);\r
-            JLabel jlabel = new JLabel(("Name:"), 11);\r
-            jlabel.setDisplayedMnemonic(PrintServiceDialog.getMnemonic("Name"));\r
-            jlabel.setLabelFor(cbName);\r
-            add(jlabel);\r
-            add(cbName);\r
-            btnProperties = PrintServiceDialog.createButton("Properties...", this);\r
-            add(btnProperties, "wrap");\r
-        }\r
-\r
-        public void actionPerformed(ActionEvent actionevent) {\r
-            Object obj = actionevent.getSource();\r
-            if (obj == btnProperties && uiFactory != null) {\r
-                JDialog jdialog = (JDialog) uiFactory.getUI(ServiceUIFactory.MAIN_UIROLE, "javax.swing.JDialog");\r
-                if (jdialog != null) {\r
-                    jdialog.show();\r
-                }\r
-                else {\r
-                    btnProperties.setEnabled(false);\r
-                }\r
-            }\r
-        }\r
-\r
-        /**\r
-         * {@inheritDoc}\r
-         *\r
-         * @param itemevent  the event that indicates what changed\r
-         */\r
-        @Override\r
-        public void itemStateChanged(ItemEvent itemevent) {\r
-            if (itemevent.getStateChange() == ItemEvent.SELECTED) {\r
-                int i = cbName.getSelectedIndex();\r
-                if (services != null && i >= 0 && i < services.length && !services[i].equals(psCurrent)) {\r
-                    psCurrent = services[i];\r
-                    uiFactory = psCurrent.getServiceUIFactory();\r
-                    changedService = true;\r
-                    if (asOriginal != null) {\r
-                        Destination destination = (Destination) asOriginal.get(\r
-                                Destination.class);\r
-                        if ((destination != null) && psCurrent.isAttributeCategorySupported(\r
-                                Destination.class)) {\r
-                            asCurrent.add(destination);\r
-                        }\r
-                        else {\r
-                            asCurrent.remove(Destination.class);\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        /**\r
-         * {@inheritDoc}\r
-         *\r
-         * @param popupmenuevent\r
-         */\r
-        @Override\r
-        public void popupMenuWillBecomeVisible(PopupMenuEvent popupmenuevent) {\r
-            changedService = false;\r
-        }\r
-\r
-        /**\r
-         * {@inheritDoc}\r
-         *\r
-         * @param popupmenuevent\r
-         */\r
-        @Override\r
-        public void popupMenuWillBecomeInvisible(PopupMenuEvent popupmenuevent) {\r
-            if (changedService) {\r
-                changedService = false;\r
-                updatePanels();\r
-            }\r
-        }\r
-\r
-        /**\r
-         * {@inheritDoc}\r
-         *\r
-         * @param popupmenuevent\r
-         */\r
-        @Override\r
-        public void popupMenuCanceled(PopupMenuEvent popupmenuevent) {\r
-        }\r
-\r
-        /**\r
-         * Modify the enablement of the properties button.\r
-         */\r
-        public void updateInfo() {\r
-            btnProperties.setEnabled(uiFactory != null);\r
-        }\r
-\r
-    }\r
-\r
-    /**\r
-     * The panel for general print services info.\r
-     */\r
-    private class GeneralPanel extends JPanel {\r
-\r
-        private PrintServicePanel pnlPrintService;\r
-        private MediaPanel pnlMedia;\r
-\r
-        public GeneralPanel() {\r
-            super(new MigLayout("fill, gap rel unrel"));\r
-            pnlPrintService = new PrintServicePanel();\r
-            add(pnlPrintService, "wrap");\r
-            pnlMedia = new MediaPanel();\r
-            add(pnlMedia, "wrap");\r
-        }\r
-\r
-        public void updateInfo() {\r
-            pnlPrintService.updateInfo();\r
-            pnlMedia.updateInfo();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Constructor.\r
-     *\r
-     * @param x the <i>x</i>-coordinate of the new location's\r
-     *          top-left corner in the parent's coordinate space\r
-     * @param y the <i>y</i>-coordinate of the new location's\r
-     *          top-left corner in the parent's coordinate space\r
-     * @param aPrintService  the array of installed print services\r
-     * @param defaultServiceIndex  the default service index (index into aPrintService)\r
-     * @param docflavor  the document flavor (i.e. PDF)\r
-     * @param attributeSet  the set of required attributes\r
-     * @param dialog  the parent\r
-     * @param additional  other panels to add in tabs\r
-     */\r
-    public PrintServiceDialog(int x, int y, PrintService[] aPrintService,\r
-                              int defaultServiceIndex, DocFlavor docflavor, PrintRequestAttributeSet attributeSet,\r
-                              Dialog dialog, JPanel... additional) {\r
-        super(dialog, PRINT_BUTTON_LABEL, true);\r
-        setLayout(new MigLayout("fill, gap rel unrel"));\r
-        services = aPrintService;\r
-        this.defaultServiceIndex = defaultServiceIndex;\r
-        asOriginal = attributeSet;\r
-        asCurrent = new HashPrintRequestAttributeSet(attributeSet);\r
-\r
-        if (services != null && defaultServiceIndex < services.length && defaultServiceIndex >= 0) {\r
-            psCurrent = services[defaultServiceIndex];\r
-        }\r
-        docFlavor = docflavor;\r
-        Container container = getContentPane();\r
-        container.setLayout(new MigLayout("fill, gap rel unrel"));\r
-//        container.setLayout(new BorderLayout());\r
-        final JTabbedPane tpTabs = new JTabbedPane();\r
-        tpTabs.setBorder(new EmptyBorder(5, 5, 5, 5));\r
-\r
-        if (additional != null) {\r
-            for (JPanel anAdditional : additional) {\r
-                tpTabs.add(anAdditional, anAdditional.getName(), 0);\r
-            }\r
-        }\r
-        if (psCurrent != null) {\r
-            pnlGeneral = new GeneralPanel();\r
-            tpTabs.add(GENERAL_TAB_TITLE, pnlGeneral);\r
-        }\r
-\r
-        container.add(tpTabs, "growx");\r
-        updatePanels();\r
-\r
-        JPanel jpanel = new JPanel(new MigLayout());\r
-        btnPrint = createExitButton(PRINT_BUTTON_LABEL, this);\r
-        jpanel.add(btnPrint, "x 300");\r
-        getRootPane().setDefaultButton(btnPrint);\r
-        btnPrint.setEnabled(pdfFlavorSupported && psCurrent != null);\r
-\r
-        btnCancel = createExitButton(CANCEL_BUTTON_LABEL, this);\r
-        handleEscKey(btnCancel);\r
-        jpanel.add(btnCancel, "x 380");\r
-        container.add(jpanel, "South");\r
-        addWindowListener(new WindowAdapter() {\r
-            public void windowClosing(WindowEvent windowevent) {\r
-                dispose(2);\r
-            }\r
-        }\r
-        );\r
-        setResizable(false);\r
-        setLocation(x, y);\r
-        pack();\r
-    }\r
-\r
-    private void handleEscKey(JButton jbutton) {\r
-        AbstractAction abstractaction = new AbstractAction() {\r
-\r
-            public void actionPerformed(ActionEvent actionevent) {\r
-                dispose(2);\r
-            }\r
-\r
-        };\r
-        KeyStroke keystroke = KeyStroke.getKeyStroke('\033', false);\r
-        InputMap inputmap = jbutton.getInputMap(2);\r
-        ActionMap actionmap = jbutton.getActionMap();\r
-        if (inputmap != null && actionmap != null) {\r
-            inputmap.put(keystroke, "cancel");\r
-            actionmap.put("cancel", abstractaction);\r
-        }\r
-    }\r
-\r
-    public int getStatus() {\r
-        return status;\r
-    }\r
-\r
-    public PrintRequestAttributeSet getAttributes() {\r
-        if (status == 1) {\r
-            return asCurrent;\r
-        }\r
-        else {\r
-            return asOriginal;\r
-        }\r
-    }\r
-\r
-    public PrintService getPrintService() {\r
-        if (status == 1) {\r
-            return psCurrent;\r
-        }\r
-        else {\r
-            return null;\r
-        }\r
-    }\r
-\r
-    public void dispose(int i) {\r
-        status = i;\r
-        super.dispose();\r
-    }\r
-\r
-    public void actionPerformed(ActionEvent actionevent) {\r
-        Object obj = actionevent.getSource();\r
-        boolean flag = false;\r
-        if (obj == btnPrint) {\r
-            flag = true;\r
-            if (pnlGeneral != null) {\r
-                asCurrent.remove(Destination.class);\r
-            }\r
-        }\r
-        dispose(flag ? 1 : 2);\r
-    }\r
-\r
-\r
-    private void updatePanels() {\r
-        if (pnlGeneral != null) {\r
-            pnlGeneral.updateInfo();\r
-        }\r
-    }\r
-\r
-    private static char getMnemonic(String s) {\r
-        if (s != null && s.length() > 0) {\r
-            return s.charAt(0);\r
-        }\r
-        else {\r
-            return '\0';\r
-        }\r
-    }\r
-\r
-    private static JButton createButton(String s, ActionListener actionlistener) {\r
-        JButton jbutton = new JButton(s);\r
-        jbutton.setMnemonic(getMnemonic(s));\r
-        jbutton.addActionListener(actionlistener);\r
-        return jbutton;\r
-    }\r
-\r
-    private static JButton createExitButton(String s, ActionListener actionlistener) {\r
-        JButton jbutton = new JButton(s);\r
-        jbutton.addActionListener(actionlistener);\r
-        jbutton.getAccessibleContext().setAccessibleDescription(s);\r
-        return jbutton;\r
-    }\r
-\r
-    static class MediaWrapper\r
-            implements PrintRequestAttribute {\r
-\r
-        private Media media;\r
-\r
-        MediaWrapper(Media theMedia) {\r
-            media = theMedia;\r
-        }\r
-\r
-        Media getMedia() {\r
-            return media;\r
-        }\r
-\r
-        public final Class getCategory() {\r
-            return this.getClass();\r
-        }\r
-\r
-        public final String getName() {\r
-            return "mw";\r
-        }\r
-\r
-        public String toString() {\r
-            return media.toString();\r
-        }\r
-\r
-        public int hashCode() {\r
-            return media.hashCode();\r
-        }\r
-\r
-    }\r
-\r
-}\r
diff --git a/src/net/sf/openrocket/gui/print/PrintSettings.java b/src/net/sf/openrocket/gui/print/PrintSettings.java
new file mode 100644 (file)
index 0000000..6537f40
--- /dev/null
@@ -0,0 +1,89 @@
+package net.sf.openrocket.gui.print;
+
+import java.awt.Color;
+
+import net.sf.openrocket.util.AbstractChangeSource;
+
+/**
+ * A class containing all printing settings.
+ */
+public class PrintSettings extends AbstractChangeSource {
+       
+       private Color templateFillColor = Color.LIGHT_GRAY;
+       private Color templateBorderColor = Color.DARK_GRAY;
+       
+       private PaperSize paperSize = PaperSize.getDefault();
+       private PaperOrientation paperOrientation = PaperOrientation.PORTRAIT;
+       
+       
+       public Color getTemplateFillColor() {
+               return templateFillColor;
+       }
+       
+       public void setTemplateFillColor(Color templateFillColor) {
+               // Implicitly tests against setting null
+               if (templateFillColor.equals(this.templateFillColor)) {
+                       return;
+               }
+               this.templateFillColor = templateFillColor;
+               fireChangeEvent();
+       }
+       
+       public Color getTemplateBorderColor() {
+               return templateBorderColor;
+       }
+       
+       public void setTemplateBorderColor(Color templateBorderColor) {
+               // Implicitly tests against setting null
+               if (templateBorderColor.equals(this.templateBorderColor)) {
+                       return;
+               }
+               this.templateBorderColor = templateBorderColor;
+               fireChangeEvent();
+       }
+       
+       public PaperSize getPaperSize() {
+               return paperSize;
+       }
+       
+       public void setPaperSize(PaperSize paperSize) {
+               if (paperSize.equals(this.paperSize)) {
+                       return;
+               }
+               this.paperSize = paperSize;
+               fireChangeEvent();
+       }
+       
+       public PaperOrientation getPaperOrientation() {
+               return paperOrientation;
+       }
+       
+       public void setPaperOrientation(PaperOrientation orientation) {
+               if (orientation.equals(paperOrientation)) {
+                       return;
+               }
+               this.paperOrientation = orientation;
+               fireChangeEvent();
+       }
+       
+       
+
+       /**
+        * Load settings from the specified print settings.
+        * @param settings      the settings to load
+        */
+       public void loadFrom(PrintSettings settings) {
+               this.templateFillColor = settings.templateFillColor;
+               this.templateBorderColor = settings.templateBorderColor;
+               this.paperSize = settings.paperSize;
+               this.paperOrientation = settings.paperOrientation;
+               fireChangeEvent();
+       }
+       
+       
+       @Override
+       public String toString() {
+               return "PrintSettings [templateFillColor=" + templateFillColor + ", templateBorderColor=" + templateBorderColor + ", paperSize=" + paperSize + ", paperOrientation=" + paperOrientation + "]";
+       }
+       
+}
index a7efd907db61d03e6731f295d539f2de1a71ac41..7f096efcf03da2c8888056788fe1c80c34db0941 100644 (file)
 package net.sf.openrocket.gui.print;
 
 
-import com.itextpdf.text.*;
-import com.itextpdf.text.Font;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+
+import javax.swing.RepaintManager;
+
 import net.sf.openrocket.logging.LogHelper;
 import net.sf.openrocket.startup.Application;
 
-import javax.print.DocFlavor;
-import javax.print.PrintService;
-import javax.print.PrintServiceLookup;
-import javax.print.ServiceUI;
-import javax.print.attribute.HashPrintRequestAttributeSet;
-import javax.print.attribute.PrintRequestAttributeSet;
-import javax.print.attribute.standard.MediaSize;
-import javax.swing.*;
-import java.awt.*;
-import java.awt.print.PageFormat;
-import java.awt.print.Printable;
-import java.awt.print.PrinterException;
-import java.awt.print.PrinterJob;
-import java.util.Locale;
+import com.itextpdf.text.Chunk;
+import com.itextpdf.text.Document;
+import com.itextpdf.text.DocumentException;
+import com.itextpdf.text.Font;
+import com.itextpdf.text.Paragraph;
 
 /**
  * Utilities methods and fonts used for printing.
  */
 public class PrintUtilities implements Printable {
-
-    /**
-     * The logger.
-     */
-    private static final LogHelper log = Application.getLogger();
-
-    public static final int NORMAL_FONT_SIZE = Font.DEFAULTSIZE - 3;
-    public static final int SMALL_FONT_SIZE = NORMAL_FONT_SIZE - 3;
-
-    public static final Font BOLD = new Font(Font.FontFamily.HELVETICA, NORMAL_FONT_SIZE, Font.BOLD);
-    public static final Font BIG_BOLD = new Font(Font.FontFamily.HELVETICA, NORMAL_FONT_SIZE + 3, Font.BOLD);
-    public static final Font BOLD_UNDERLINED = new Font(Font.FontFamily.HELVETICA, NORMAL_FONT_SIZE,
-                                                        Font.BOLD | Font.UNDERLINE);
-    public static final Font NORMAL = new Font(Font.FontFamily.HELVETICA, NORMAL_FONT_SIZE);
-    public static final Font SMALL = new Font(Font.FontFamily.HELVETICA, SMALL_FONT_SIZE);
-
-
-    private Component componentToBePrinted;
-
-    public static void printComponent (Component c) {
-        new PrintUtilities(c).print();
-    }
-
-    public PrintUtilities (Component componentToBePrinted) {
-        this.componentToBePrinted = componentToBePrinted;
-    }
-
-    public void print () {
-        PrinterJob printJob = PrinterJob.getPrinterJob();
-        printJob.setPrintable(this);
-        if (printJob.printDialog()) {
-            try {
-                printJob.print();
-            }
-            catch (PrinterException pe) {
-                System.out.println("Error printing: " + pe);
-            }
-        }
-    }
-
-    public int print (Graphics g, PageFormat pageFormat, int pageIndex) {
-        if (pageIndex > 0) {
-            return (NO_SUCH_PAGE);
-        }
-        else {
-            Graphics2D g2d = (Graphics2D) g;
-            translateToJavaOrigin(g2d, pageFormat);
-            disableDoubleBuffering(componentToBePrinted);
-            componentToBePrinted.paint(g2d);
-            enableDoubleBuffering(componentToBePrinted);
-            return (PAGE_EXISTS);
-        }
-    }
-
-    public static void disableDoubleBuffering (Component c) {
-        RepaintManager currentManager = RepaintManager.currentManager(c);
-        currentManager.setDoubleBufferingEnabled(false);
-    }
-
-    public static void enableDoubleBuffering (Component c) {
-        RepaintManager currentManager = RepaintManager.currentManager(c);
-        currentManager.setDoubleBufferingEnabled(true);
-    }
-
-    public static PrintService askUserForPDFPrintService () {
-        return askUserForPrintService(DocFlavor.INPUT_STREAM.PDF);
-    }
-
-    public static PrintService askUserForPrintService (DocFlavor flavor) {
-        PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
-        PrintService svc = PrintServiceLookup.lookupDefaultPrintService();
-        PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet();
-        attrs.add(getDefaultMedia().getMediaSizeName());
-
-        return ServiceUI.printDialog(null, 100, 100, services, svc, flavor, attrs);
-    }
-
-    /**
-     * Sets the paper size for pages using these attributes to the default size for the default locale. The default size
-     * for locales in the United States and Canada is MediaType.NA_LETTER. The default size for all other locales is
-     * MediaType.ISO_A4.
-     */
-    public static MediaSize getDefaultMedia () {
-        String defaultCountry = Locale.getDefault().getCountry();
-        if (defaultCountry != null &&
-            (defaultCountry.equals(Locale.US.getCountry()) ||
-             defaultCountry.equals(Locale.CANADA.getCountry()))) {
-            return MediaSize.NA.LETTER;
-        }
-        else {
-            return MediaSize.ISO.A4;
-        }
-    }
-
-    /**
-     * Translate the page format coordinates onto the graphics object using Java's origin (top left).
-     *
-     * @param g2d        the graphics object
-     * @param pageFormat the print page format
-     */
-    public static void translateToJavaOrigin (Graphics2D g2d, PageFormat pageFormat) {
-        g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
-    }
-
-    /**
-     * Add text as a new paragraph in a given font to the document.
-     *
-     * @param document  the document
-     * @param font      the font
-     * @param title     the title
-     */
-    public static void addText (Document document, com.itextpdf.text.Font font, String title) {
-        Chunk sectionHeader = new Chunk(title);
-        sectionHeader.setFont(font);
-        try {
-            Paragraph p = new Paragraph();
-            p.add(sectionHeader);
-            document.add(p);
-        }
-        catch (DocumentException e) {
-            log.error("Could not add paragraph.", e);
-        }
-    }
+       
+       /**
+        * The logger.
+        */
+       private static final LogHelper log = Application.getLogger();
+       
+       public static final int NORMAL_FONT_SIZE = Font.DEFAULTSIZE - 3;
+       public static final int SMALL_FONT_SIZE = NORMAL_FONT_SIZE - 3;
+       
+       public static final Font BOLD = new Font(Font.FontFamily.HELVETICA, NORMAL_FONT_SIZE, Font.BOLD);
+       public static final Font BIG_BOLD = new Font(Font.FontFamily.HELVETICA, NORMAL_FONT_SIZE + 3, Font.BOLD);
+       public static final Font BOLD_UNDERLINED = new Font(Font.FontFamily.HELVETICA, NORMAL_FONT_SIZE,
+                                                                                                               Font.BOLD | Font.UNDERLINE);
+       public static final Font NORMAL = new Font(Font.FontFamily.HELVETICA, NORMAL_FONT_SIZE);
+       public static final Font SMALL = new Font(Font.FontFamily.HELVETICA, SMALL_FONT_SIZE);
+       
+
+       private Component componentToBePrinted;
+       
+       public PrintUtilities(Component componentToBePrinted) {
+               this.componentToBePrinted = componentToBePrinted;
+       }
+       
+       @Override
+       public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
+               if (pageIndex > 0) {
+                       return (NO_SUCH_PAGE);
+               } else {
+                       Graphics2D g2d = (Graphics2D) g;
+                       translateToJavaOrigin(g2d, pageFormat);
+                       disableDoubleBuffering(componentToBePrinted);
+                       componentToBePrinted.paint(g2d);
+                       enableDoubleBuffering(componentToBePrinted);
+                       return (PAGE_EXISTS);
+               }
+       }
+       
+       public static void disableDoubleBuffering(Component c) {
+               RepaintManager currentManager = RepaintManager.currentManager(c);
+               currentManager.setDoubleBufferingEnabled(false);
+       }
+       
+       public static void enableDoubleBuffering(Component c) {
+               RepaintManager currentManager = RepaintManager.currentManager(c);
+               currentManager.setDoubleBufferingEnabled(true);
+       }
+       
+       
+       /**
+        * Translate the page format coordinates onto the graphics object using Java's origin (top left).
+        *
+        * @param g2d        the graphics object
+        * @param pageFormat the print page format
+        */
+       public static void translateToJavaOrigin(Graphics2D g2d, PageFormat pageFormat) {
+               g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
+       }
+       
+       /**
+        * Add text as a new paragraph in a given font to the document.
+        *
+        * @param document  the document
+        * @param font      the font
+        * @param title     the title
+        */
+       public static void addText(Document document, com.itextpdf.text.Font font, String title) {
+               Chunk sectionHeader = new Chunk(title);
+               sectionHeader.setFont(font);
+               try {
+                       Paragraph p = new Paragraph();
+                       p.add(sectionHeader);
+                       document.add(p);
+               } catch (DocumentException e) {
+                       log.error("Could not add paragraph.", e);
+               }
+       }
 }
index f98f7ea36c265c54a51414f8a4d0aacb78e49130..6f88e576bc2a1c0bc1d64b166a63a8dfd0996d6d 100644 (file)
@@ -3,47 +3,74 @@
  */
 package net.sf.openrocket.gui.print;
 
-import javax.swing.UIManager;
 import java.awt.Color;
 
+import javax.swing.UIManager;
+
 /**
  * This class is responsible for managing various properties of print templates (fin, nose cone, transitions, etc.).
+ * 
+ * TODO: HIGH:  Remove this entire class, and instead pass the PrintSettings object to the print methods.
  */
 public class TemplateProperties {
-
-    /**
-     * The property that defines the fill color.
-     */
-    public static final String TEMPLATE_FILL_COLOR_PROPERTY = "template.fill.color";
-
-    /**
-     * The property that defines the line color.
-     */
-    public static final String TEMPLATE_LINE_COLOR_PROPERTY = "template.line.color";
-
-    /**
-     * Get the current fill color.
-     * 
-     * @return  a color to be used as the fill in template shapes
-     */
-    public static Color getFillColor () {
-        Color fillColor = UIManager.getColor(TemplateProperties.TEMPLATE_FILL_COLOR_PROPERTY);
-        if (fillColor == null) {
-            fillColor = Color.lightGray;
-        }
-        return fillColor;
-    }
-
-    /**
-     * Get the current line color.
-     * 
-     * @return  a color to be used as the line in template shapes
-     */
-    public static Color getLineColor () {
-        Color lineColor = UIManager.getColor(TemplateProperties.TEMPLATE_LINE_COLOR_PROPERTY);
-        if (lineColor == null) {
-            lineColor = Color.darkGray;
-        }
-        return lineColor;
-    }
+       
+       /**
+        * The property that defines the fill color.
+        */
+       public static final String TEMPLATE_FILL_COLOR_PROPERTY = "template.fill.color";
+       
+       /**
+        * The property that defines the line color.
+        */
+       public static final String TEMPLATE_LINE_COLOR_PROPERTY = "template.line.color";
+       
+       /**
+        * Get the current fill color.
+        * 
+        * @return  a color to be used as the fill in template shapes
+        */
+       public static Color getFillColor() {
+               Color fillColor = UIManager.getColor(TemplateProperties.TEMPLATE_FILL_COLOR_PROPERTY);
+               if (fillColor == null) {
+                       fillColor = Color.lightGray;
+               }
+               return fillColor;
+       }
+       
+       
+       /**
+        * Set the template fill color.
+        */
+       public static void setFillColor(Color c) {
+               UIManager.put(TemplateProperties.TEMPLATE_FILL_COLOR_PROPERTY, c);
+       }
+       
+       
+       /**
+        * Get the current line color.
+        * 
+        * @return  a color to be used as the line in template shapes
+        */
+       public static Color getLineColor() {
+               Color lineColor = UIManager.getColor(TemplateProperties.TEMPLATE_LINE_COLOR_PROPERTY);
+               if (lineColor == null) {
+                       lineColor = Color.darkGray;
+               }
+               return lineColor;
+       }
+       
+       /**
+        * Set the template line color.
+        */
+       public static void setLineColor(Color c) {
+               UIManager.put(TemplateProperties.TEMPLATE_LINE_COLOR_PROPERTY, c);
+       }
+       
+       /**
+        * Set the template colors from the print settings.
+        */
+       public static void setColors(PrintSettings settings) {
+               setFillColor(settings.getTemplateFillColor());
+               setLineColor(settings.getTemplateBorderColor());
+       }
 }
diff --git a/src/net/sf/openrocket/util/AbstractChangeSource.java b/src/net/sf/openrocket/util/AbstractChangeSource.java
new file mode 100644 (file)
index 0000000..14109da
--- /dev/null
@@ -0,0 +1,47 @@
+package net.sf.openrocket.util;
+
+import java.util.List;
+
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import net.sf.openrocket.logging.LogHelper;
+import net.sf.openrocket.startup.Application;
+
+/**
+ * Abstract implementation of a ChangeSource.
+ * 
+ * @author Sampo Niskanen <sampo.niskanen@iki.fi>
+ */
+public abstract class AbstractChangeSource implements ChangeSource {
+       private static final LogHelper log = Application.getLogger();
+       
+       private final List<ChangeListener> listeners = new ArrayList<ChangeListener>();
+       
+       private final ChangeEvent event = new ChangeEvent(this);
+       
+       
+       @Override
+       public final void addChangeListener(ChangeListener listener) {
+               listeners.add(listener);
+               log.verbose(1, "Adding change listeners, listener count is now " + listeners.size());
+       }
+       
+       @Override
+       public final void removeChangeListener(ChangeListener listener) {
+               listeners.remove(listener);
+               log.verbose(1, "Removing change listeners, listener count is now " + listeners.size());
+       }
+       
+       
+       /**
+        * Fire a change event to all listeners.
+        */
+       protected void fireChangeEvent() {
+               ChangeListener[] array = listeners.toArray(new ChangeListener[0]);
+               
+               for (ChangeListener l : array) {
+                       l.stateChanged(event);
+               }
+       }
+}
index ac3144e2ccc4a307da86f999d93dde4f477a0b6f..9cd9e7abf8bb06d72fee8f4cd44fa72b3425882a 100644 (file)
@@ -22,6 +22,7 @@ import net.sf.openrocket.arch.SystemInfo;
 import net.sf.openrocket.database.Databases;
 import net.sf.openrocket.document.Simulation;
 import net.sf.openrocket.gui.main.ExceptionHandler;
+import net.sf.openrocket.gui.print.PrintSettings;
 import net.sf.openrocket.logging.LogHelper;
 import net.sf.openrocket.material.Material;
 import net.sf.openrocket.rocketcomponent.BodyComponent;
@@ -306,6 +307,47 @@ public class Prefs {
                storeVersion();
        }
        
+       
+       /**
+        * Retrieve an enum value from the user preferences.
+        * 
+        * @param <T>   the enum type
+        * @param key   the key
+        * @param def   the default value, cannot be null
+        * @return              the value in the preferences, or the default value
+        */
+       public static <T extends Enum<T>> T getEnum(String key, T def) {
+               if (def == null) {
+                       throw new BugException("Default value cannot be null");
+               }
+               
+               String value = getString(key, null);
+               if (value == null) {
+                       return def;
+               }
+               
+               try {
+                       return Enum.valueOf(def.getDeclaringClass(), value);
+               } catch (IllegalArgumentException e) {
+                       return def;
+               }
+       }
+       
+       /**
+        * Store an enum value to the user preferences.
+        * 
+        * @param key           the key
+        * @param value         the value to store, or null to remove the value
+        */
+       public static void putEnum(String key, Enum<?> value) {
+               if (value == null) {
+                       putString(key, null);
+               } else {
+                       putString(key, value.name());
+               }
+       }
+       
+       
        /**
         * Return a boolean preference.
         * 
@@ -443,6 +485,26 @@ public class Prefs {
                if (color == null)
                        return Color.BLACK;
                
+               Color clr = parseColor(color);
+               if (clr != null) {
+                       return clr;
+               } else {
+                       return Color.BLACK;
+               }
+       }
+       
+       public static void setDefaultColor(Class<? extends RocketComponent> c, Color color) {
+               if (color == null)
+                       return;
+               set("componentColors", c, stringifyColor(color));
+       }
+       
+       
+       private static Color parseColor(String color) {
+               if (color == null) {
+                       return null;
+               }
+               
                String[] rgb = color.split(",");
                if (rgb.length == 3) {
                        try {
@@ -453,17 +515,17 @@ public class Prefs {
                        } catch (NumberFormatException ignore) {
                        }
                }
-               
-               return Color.BLACK;
+               return null;
        }
        
-       public static void setDefaultColor(Class<? extends RocketComponent> c, Color color) {
-               if (color == null)
-                       return;
+       
+       private static String stringifyColor(Color color) {
                String string = color.getRed() + "," + color.getGreen() + "," + color.getBlue();
-               set("componentColors", c, string);
+               return string;
        }
        
+       
+
        public static Color getMotorBorderColor() {
                // TODO: MEDIUM:  Motor color (settable?)
                return new Color(0, 0, 0, 200);
@@ -623,6 +685,35 @@ public class Prefs {
        }
        
        
+       ////  Printing
+       
+       public static PrintSettings getPrintSettings() {
+               PrintSettings settings = new PrintSettings();
+               Color c;
+               
+               c = parseColor(getString("print.template.fillColor", null));
+               if (c != null) {
+                       settings.setTemplateFillColor(c);
+               }
+               
+               c = parseColor(getString("print.template.borderColor", null));
+               if (c != null) {
+                       settings.setTemplateBorderColor(c);
+               }
+               
+               settings.setPaperSize(getEnum("print.paper.size", settings.getPaperSize()));
+               settings.setPaperOrientation(getEnum("print.paper.orientation", settings.getPaperOrientation()));
+               
+               return settings;
+       }
+       
+       public static void setPrintSettings(PrintSettings settings) {
+               putString("print.template.fillColor", stringifyColor(settings.getTemplateFillColor()));
+               putString("print.template.borderColor", stringifyColor(settings.getTemplateBorderColor()));
+               putEnum("print.paper.size", settings.getPaperSize());
+               putEnum("print.paper.orientation", settings.getPaperOrientation());
+       }
+       
        ////  Background flight data computation
        
        public static boolean computeFlightInBackground() {
diff --git a/test/net/sf/openrocket/gui/print/TestPaperSize.java b/test/net/sf/openrocket/gui/print/TestPaperSize.java
new file mode 100644 (file)
index 0000000..82677cd
--- /dev/null
@@ -0,0 +1,36 @@
+package net.sf.openrocket.gui.print;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class TestPaperSize {
+       
+       @Test
+       public void testGetDefaultForCountry() {
+               assertEquals(PaperSize.LETTER, PaperSize.getDefaultForCountry("US"));
+               assertEquals(PaperSize.LETTER, PaperSize.getDefaultForCountry("cA"));
+               assertEquals(PaperSize.LETTER, PaperSize.getDefaultForCountry("mx"));
+               
+               assertEquals(PaperSize.A4, PaperSize.getDefaultForCountry("FI"));
+               assertEquals(PaperSize.A4, PaperSize.getDefaultForCountry("xy"));
+               
+               assertNull(PaperSize.getDefaultForCountry("FIN"));
+               assertNull(PaperSize.getDefaultForCountry("a"));
+               assertNull(PaperSize.getDefaultForCountry("A4"));
+               assertNull(PaperSize.getDefaultForCountry(null));
+       }
+       
+       @Test
+       public void testGetSizeFromString() {
+               assertEquals(PaperSize.LETTER, PaperSize.getSizeFromString("Letter"));
+               assertEquals(PaperSize.LEGAL, PaperSize.getSizeFromString("  legal\t"));
+               assertEquals(PaperSize.A4, PaperSize.getSizeFromString("  A4\n"));
+               assertEquals(PaperSize.A3, PaperSize.getSizeFromString("A3"));
+               
+               assertNull(PaperSize.getSizeFromString("#A4"));
+               assertNull(PaperSize.getSizeFromString(""));
+               assertNull(PaperSize.getSizeFromString(null));
+       }
+       
+}