<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>
--- /dev/null
+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);
+ }
+
+}
--- /dev/null
+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);
+ }
+
+}
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;
import java.util.List;
import javax.swing.BorderFactory;
-import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
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;
// 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);
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) {
}
-
+ 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"));
}
- 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);
}
}
}
-}
+}
\ No newline at end of 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 : "";
+ }
}
+++ /dev/null
-/*
- * 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);
- }
-
-}
--- /dev/null
+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);
+ }
+
+
+}
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);
"Experimental feature", JOptionPane.WARNING_MESSAGE);
Prefs.putBoolean("printing.experimental.communicated", true);
}
- new PrintDialog(document);
+ new PrintDialog(this, document).setVisible(true);
}
/**
}
}
+
+ /*
+ * 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
*/
--- /dev/null
+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;
+ }
+}
-/*
- * 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;
+ }
+
}
*/
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;
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());
+ }
+
}
+++ /dev/null
-/*\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
--- /dev/null
+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 + "]";
+ }
+
+}
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);
+ }
+ }
}
*/
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());
+ }
}
--- /dev/null
+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);
+ }
+ }
+}
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;
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.
*
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 {
} 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);
}
+ //// 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() {
--- /dev/null
+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));
+ }
+
+}