printing updates
This commit is contained in:
parent
8f9bdc832f
commit
a61f50113a
@ -132,7 +132,7 @@
|
||||
<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"/>
|
||||
@ -142,7 +142,7 @@
|
||||
</fileset>
|
||||
<filterchain>
|
||||
<linecontainsregexp>
|
||||
<regexp pattern="TODO:.*CRITICAL"/>
|
||||
<regexp pattern="(FIXME|TODO:.*CRITICAL)"/>
|
||||
</linecontainsregexp>
|
||||
</filterchain>
|
||||
</concat>
|
||||
|
||||
71
src/net/sf/openrocket/gui/components/ColorChooserButton.java
Normal file
71
src/net/sf/openrocket/gui/components/ColorChooserButton.java
Normal file
@ -0,0 +1,71 @@
|
||||
package net.sf.openrocket.gui.components;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JColorChooser;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import net.sf.openrocket.logging.LogHelper;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
/**
|
||||
* A color chooser button. The currently selected color can be queried or set using the
|
||||
* {@link #getSelectedColor()} and {@link #setSelectedColor(Color)}, and changes listened
|
||||
* to by listening to property events with property name {@link #COLOR_KEY}.
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
public class ColorChooserButton extends JButton {
|
||||
private static final LogHelper log = Application.getLogger();
|
||||
|
||||
public static final String COLOR_KEY = "selectedColor";
|
||||
|
||||
|
||||
public ColorChooserButton(Color initial) {
|
||||
|
||||
setSelectedColor(initial);
|
||||
|
||||
// Add action listener that opens color chooser dialog
|
||||
this.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
log.user("Activating color chooser");
|
||||
final JColorChooser chooser = new JColorChooser(getSelectedColor());
|
||||
chooser.setPreviewPanel(new JPanel());
|
||||
final JDialog dialog = JColorChooser.createDialog(ColorChooserButton.this, "Select color", true,
|
||||
chooser, new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e2) {
|
||||
Color c = chooser.getColor();
|
||||
log.user("User selected color " + c);
|
||||
setSelectedColor(chooser.getColor());
|
||||
}
|
||||
}, null);
|
||||
log.info("Closing color chooser");
|
||||
dialog.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void addColorPropertyChangeListener(PropertyChangeListener listener) {
|
||||
this.addPropertyChangeListener(COLOR_KEY, listener);
|
||||
}
|
||||
|
||||
public void setSelectedColor(Color c) {
|
||||
log.debug("Selecting color " + c);
|
||||
this.setIcon(new ColorIcon(c));
|
||||
this.putClientProperty(COLOR_KEY, c);
|
||||
}
|
||||
|
||||
public Color getSelectedColor() {
|
||||
return (Color) this.getClientProperty(COLOR_KEY);
|
||||
}
|
||||
|
||||
}
|
||||
35
src/net/sf/openrocket/gui/components/ColorIcon.java
Normal file
35
src/net/sf/openrocket/gui/components/ColorIcon.java
Normal file
@ -0,0 +1,35 @@
|
||||
package net.sf.openrocket.gui.components;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
/**
|
||||
* An Icon that displays a specific color, suitable for drawing into a button.
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
public class ColorIcon implements Icon {
|
||||
private final Color color;
|
||||
|
||||
public ColorIcon(Color c) {
|
||||
this.color = c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return 15;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return 25;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon(java.awt.Component c, java.awt.Graphics g, int x, int y) {
|
||||
g.setColor(color);
|
||||
g.fill3DRect(x, y, getIconWidth(), getIconHeight(), false);
|
||||
}
|
||||
|
||||
}
|
||||
@ -2,8 +2,6 @@ package net.sf.openrocket.gui.configdialog;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
@ -13,7 +11,6 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JColorChooser;
|
||||
@ -33,6 +30,7 @@ import net.sf.openrocket.gui.adaptors.DoubleModel;
|
||||
import net.sf.openrocket.gui.adaptors.EnumModel;
|
||||
import net.sf.openrocket.gui.adaptors.MaterialModel;
|
||||
import net.sf.openrocket.gui.components.BasicSlider;
|
||||
import net.sf.openrocket.gui.components.ColorIcon;
|
||||
import net.sf.openrocket.gui.components.StyledLabel;
|
||||
import net.sf.openrocket.gui.components.StyledLabel.Style;
|
||||
import net.sf.openrocket.gui.components.UnitSelector;
|
||||
@ -136,7 +134,7 @@ public class RocketComponentConfig extends JPanel {
|
||||
|
||||
// Component color and "Use default color" checkbox
|
||||
if (colorButton != null && colorDefault != null) {
|
||||
colorButton.setIcon(new ColorIcon(component.getColor()));
|
||||
colorButton.setIcon(new ColorIcon(getColor()));
|
||||
|
||||
if ((component.getColor() == null) != colorDefault.isSelected())
|
||||
colorDefault.setSelected(component.getColor() == null);
|
||||
@ -347,7 +345,7 @@ public class RocketComponentConfig extends JPanel {
|
||||
|
||||
panel.add(new JLabel("Component color:"), "gapleft para, gapright 10lp");
|
||||
|
||||
colorButton = new JButton(new ColorIcon(component.getColor()));
|
||||
colorButton = new JButton(new ColorIcon(getColor()));
|
||||
colorButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@ -409,7 +407,15 @@ public class RocketComponentConfig extends JPanel {
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Color getColor() {
|
||||
Color c = component.getColor();
|
||||
if (c == null) {
|
||||
c = Prefs.getDefaultColor(component.getClass());
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected JPanel shoulderTab() {
|
||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||
@ -578,35 +584,6 @@ public class RocketComponentConfig extends JPanel {
|
||||
}
|
||||
|
||||
|
||||
private class ColorIcon implements Icon {
|
||||
private final Color color;
|
||||
|
||||
public ColorIcon(Color c) {
|
||||
this.color = c;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return 15;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return 25;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
if (color == null) {
|
||||
g.setColor(Prefs.getDefaultColor(component.getClass()));
|
||||
} else {
|
||||
g.setColor(color);
|
||||
}
|
||||
g.fill3DRect(x, y, getIconWidth(), getIconHeight(), false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void register(Invalidatable model) {
|
||||
this.invalidatables.add(model);
|
||||
}
|
||||
@ -617,4 +594,4 @@ public class RocketComponentConfig extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,209 +1,370 @@
|
||||
/*
|
||||
* 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 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.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 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 {
|
||||
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);
|
||||
|
||||
|
||||
/**
|
||||
* The service UI dialog.
|
||||
*/
|
||||
private PrintServiceDialog dialog;
|
||||
JPanel panel = new JPanel(new MigLayout("fill, gap rel unrel"));
|
||||
this.add(panel);
|
||||
|
||||
|
||||
/**
|
||||
* A javax doc flavor specific for printing PDF documents.
|
||||
*/
|
||||
private static final DocFlavor.INPUT_STREAM PDF = DocFlavor.INPUT_STREAM.PDF;
|
||||
// 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();
|
||||
|
||||
|
||||
/**
|
||||
* 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());
|
||||
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");
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
// 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");
|
||||
|
||||
|
||||
/**
|
||||
* Get the set of attributes from the service ui print dialog.
|
||||
*
|
||||
* @return a set of print attributes
|
||||
*/
|
||||
PrintRequestAttributeSet getAttributes() {
|
||||
return dialog.getAttributes();
|
||||
}
|
||||
panel.add(new JPanel(), "growx");
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
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");
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
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");
|
||||
|
||||
|
||||
if (GraphicsEnvironment.isHeadless()) {
|
||||
throw new HeadlessException();
|
||||
}
|
||||
else if (attributes == null) {
|
||||
throw new IllegalArgumentException("attributes must be non-null");
|
||||
}
|
||||
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");
|
||||
|
||||
|
||||
if (defaultService != null && services != null) {
|
||||
for (int i = 0; i < services.length; i++) {
|
||||
if (services[i].equals(defaultService)) {
|
||||
defaultIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cancel = new JButton("Cancel");
|
||||
cancel.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
PrintDialog.this.setVisible(false);
|
||||
}
|
||||
});
|
||||
panel.add(cancel, "right, gap para");
|
||||
|
||||
|
||||
//If the default service is not found just go with the first in the list
|
||||
if (defaultIndex < 0) {
|
||||
defaultIndex = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
defaultIndex = -1;
|
||||
}
|
||||
expandAll(currentTree, true);
|
||||
if (currentTree != noStagedTree) {
|
||||
expandAll(noStagedTree, true);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 : "";
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,445 +0,0 @@
|
||||
/*
|
||||
* PrintPanel.java
|
||||
*/
|
||||
package net.sf.openrocket.gui.dialogs;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.gui.components.ColorChooser;
|
||||
import net.sf.openrocket.gui.print.PrintController;
|
||||
import net.sf.openrocket.gui.print.PrintUtilities;
|
||||
import net.sf.openrocket.gui.print.PrintableContext;
|
||||
import net.sf.openrocket.gui.print.TemplateProperties;
|
||||
import net.sf.openrocket.gui.print.components.CheckTreeManager;
|
||||
import net.sf.openrocket.gui.print.components.RocketPrintTree;
|
||||
import net.sf.openrocket.logging.LogHelper;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
import javax.print.attribute.PrintRequestAttributeSet;
|
||||
import javax.print.attribute.standard.MediaSizeName;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JColorChooser;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.event.TreeSelectionListener;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
import javax.swing.tree.TreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.awt.Color;
|
||||
import java.awt.Desktop;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* This class isolates the Swing components used to create a panel that is added to a standard Java print dialog.
|
||||
*/
|
||||
public class PrintPanel extends JPanel implements TreeSelectionListener {
|
||||
|
||||
private static final LogHelper log = Application.getLogger();
|
||||
|
||||
private static final String TAB_TITLE = "Rocket";
|
||||
private static final String SETTINGS_BUTTON_TEXT = "Settings";
|
||||
private static final String PREVIEW_BUTTON_TEXT = "Preview";
|
||||
private static final String SAVE_AS_PDF_BUTTON_TEXT = "Save as PDF";
|
||||
private static final String SHOW_BY_STAGE = "Show By Stage";
|
||||
|
||||
private final RocketPrintTree stagedTree;
|
||||
private final RocketPrintTree noStagedTree;
|
||||
private OpenRocketDocument rocDoc;
|
||||
private RocketPrintTree currentTree;
|
||||
private boolean bDesktopSupported = false;
|
||||
private Desktop desktop;
|
||||
private PrintDialog printDialog;
|
||||
|
||||
JButton previewButton;
|
||||
JButton saveAsPDF;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param orDocument the OR rocket container
|
||||
* @param theParent the OR parent print dialog
|
||||
*/
|
||||
public PrintPanel (OpenRocketDocument orDocument, PrintDialog theParent) {
|
||||
|
||||
super(new MigLayout("fill, gap rel unrel"));
|
||||
|
||||
// before any Desktop APIs are used, first check whether the API is
|
||||
// supported by this particular VM on this particular host
|
||||
if (Desktop.isDesktopSupported()) {
|
||||
bDesktopSupported = true;
|
||||
desktop = Desktop.getDesktop();
|
||||
}
|
||||
|
||||
printDialog = theParent;
|
||||
rocDoc = orDocument;
|
||||
Rocket rocket = orDocument.getRocket();
|
||||
|
||||
noStagedTree = RocketPrintTree.create(rocket.getName());
|
||||
noStagedTree.setShowsRootHandles(false);
|
||||
CheckTreeManager ctm = new net.sf.openrocket.gui.print.components.CheckTreeManager(noStagedTree);
|
||||
ctm.addTreeSelectionListener(this);
|
||||
|
||||
final int stages = rocket.getStageCount();
|
||||
|
||||
if (stages > 1) {
|
||||
stagedTree = RocketPrintTree.create(rocket.getName(), rocket.getChildren());
|
||||
ctm = new CheckTreeManager(stagedTree);
|
||||
stagedTree.setShowsRootHandles(false);
|
||||
ctm.addTreeSelectionListener(this);
|
||||
}
|
||||
else {
|
||||
stagedTree = noStagedTree;
|
||||
}
|
||||
currentTree = stagedTree;
|
||||
|
||||
final JScrollPane scrollPane = new JScrollPane(stagedTree);
|
||||
add(scrollPane, "width 416!, wrap");
|
||||
|
||||
final JCheckBox sortByStage = new JCheckBox(SHOW_BY_STAGE);
|
||||
sortByStage.setEnabled(stages > 1);
|
||||
sortByStage.setSelected(stages > 1);
|
||||
sortByStage.addActionListener(new ActionListener() {
|
||||
public void actionPerformed (ActionEvent e) {
|
||||
if (sortByStage.isEnabled()) {
|
||||
if (((JCheckBox) e.getSource()).isSelected()) {
|
||||
scrollPane.setViewportView(stagedTree);
|
||||
stagedTree.setExpandsSelectedPaths(true);
|
||||
currentTree = stagedTree;
|
||||
}
|
||||
else {
|
||||
scrollPane.setViewportView(noStagedTree);
|
||||
noStagedTree.setExpandsSelectedPaths(true);
|
||||
currentTree = noStagedTree;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
add(sortByStage, "wrap");
|
||||
|
||||
saveAsPDF = new JButton(SAVE_AS_PDF_BUTTON_TEXT);
|
||||
saveAsPDF.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed (ActionEvent e) {
|
||||
onSavePDF(PrintPanel.this);
|
||||
}
|
||||
});
|
||||
add(saveAsPDF, "span 2, tag save");
|
||||
|
||||
previewButton = new JButton(PREVIEW_BUTTON_TEXT);
|
||||
previewButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed (ActionEvent e) {
|
||||
onPreview();
|
||||
}
|
||||
});
|
||||
add(previewButton, "x 150");
|
||||
|
||||
JButton settingsButton = new JButton(SETTINGS_BUTTON_TEXT);
|
||||
settingsButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed (ActionEvent e) {
|
||||
PrintSettingsDialog settingsDialog = new PrintSettingsDialog(printDialog.getDialog());
|
||||
settingsDialog.setVisible(true);
|
||||
}
|
||||
});
|
||||
add(settingsButton, "x 340");
|
||||
|
||||
expandAll(currentTree, true);
|
||||
if (currentTree != noStagedTree) {
|
||||
expandAll(noStagedTree, true);
|
||||
}
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* The title of the tab that gets displayed for this panel, when placed in the print dialog.
|
||||
*
|
||||
* @return a title
|
||||
*/
|
||||
public String getTitle () {
|
||||
return TAB_TITLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return getTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueChanged (final TreeSelectionEvent e) {
|
||||
final TreePath path = e.getNewLeadSelectionPath();
|
||||
if (path != null){
|
||||
previewButton.setEnabled(true);
|
||||
saveAsPDF.setEnabled(true);
|
||||
}
|
||||
else {
|
||||
previewButton.setEnabled(false);
|
||||
saveAsPDF.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If expand is true, expands all nodes in the tree. Otherwise, collapses all nodes in the theTree.
|
||||
*
|
||||
* @param theTree the tree to expand/contract
|
||||
* @param expand expand if true, contract if not
|
||||
*/
|
||||
public void expandAll (RocketPrintTree theTree, boolean expand) {
|
||||
TreeNode root = (TreeNode) theTree.getModel().getRoot();
|
||||
// Traverse theTree from root
|
||||
expandAll(theTree, new TreePath(root), expand);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively walk a tree, and if expand is true, expands all nodes in the tree. Otherwise, collapses all nodes in
|
||||
* the theTree.
|
||||
*
|
||||
* @param theTree the tree to expand/contract
|
||||
* @param parent the node to iterate/recurse over
|
||||
* @param expand expand if true, contract if not
|
||||
*/
|
||||
private void expandAll (RocketPrintTree theTree, TreePath parent, boolean expand) {
|
||||
theTree.addSelectionPath(parent);
|
||||
// Traverse children
|
||||
TreeNode node = (TreeNode) parent.getLastPathComponent();
|
||||
if (node.getChildCount() >= 0) {
|
||||
for (Enumeration e = node.children(); e.hasMoreElements();) {
|
||||
TreeNode n = (TreeNode) e.nextElement();
|
||||
TreePath path = parent.pathByAddingChild(n);
|
||||
expandAll(theTree, path, expand);
|
||||
}
|
||||
}
|
||||
// Expansion or collapse must be done bottom-up
|
||||
if (expand) {
|
||||
theTree.expandPath(parent);
|
||||
}
|
||||
else {
|
||||
theTree.collapsePath(parent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a media size name (the name of a paper size). If no page size is selected, it will default to the locale
|
||||
* specific page size (LETTER in North America, A4 elsewhere).
|
||||
*
|
||||
* @return the name of a page size
|
||||
*/
|
||||
private MediaSizeName getMediaSize () {
|
||||
MediaSizeName paperSize = getMediaSize(printDialog.getAttributes());
|
||||
if (paperSize == null) {
|
||||
paperSize = PrintUtilities.getDefaultMedia().getMediaSizeName();
|
||||
}
|
||||
return paperSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the media size name (the name of a paper size) as selected by the user.
|
||||
*
|
||||
* @param atts the set of selected printer attributes
|
||||
*
|
||||
* @return a media size name, may be null
|
||||
*/
|
||||
private MediaSizeName getMediaSize (PrintRequestAttributeSet atts) {
|
||||
return (MediaSizeName) atts.get(javax.print.attribute.standard.Media.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a report using a temporary file. The file will be deleted upon JVM exit.
|
||||
*
|
||||
* @param paper the name of the paper size
|
||||
*
|
||||
* @return a file, populated with the "printed" output (the rocket info)
|
||||
*
|
||||
* @throws IOException thrown if the file could not be generated
|
||||
*/
|
||||
private File generateReport (MediaSizeName paper) throws IOException {
|
||||
final File f = File.createTempFile("oro", ".pdf");
|
||||
f.deleteOnExit();
|
||||
return generateReport(f, paper);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a report to a specified file.
|
||||
*
|
||||
* @param f the file to which rocket data will be written
|
||||
* @param paper the name of the paper size
|
||||
*
|
||||
* @return a file, populated with the "printed" output (the rocket info)
|
||||
*
|
||||
* @throws IOException thrown if the file could not be generated
|
||||
*/
|
||||
private File generateReport (File f, MediaSizeName paper) throws IOException {
|
||||
Iterator<PrintableContext> toBePrinted = currentTree.getToBePrinted();
|
||||
new PrintController().print(rocDoc, toBePrinted, new FileOutputStream(f), paper);
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a report to a byte array output stream.
|
||||
*
|
||||
* @return a stream populated with the "printed" output (the rocket info)
|
||||
*/
|
||||
public ByteArrayOutputStream generateReport() {
|
||||
Iterator<PrintableContext> toBePrinted = currentTree.getToBePrinted();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
new PrintController().print(rocDoc, toBePrinted, baos, getMediaSize ());
|
||||
return baos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for when the Preview button is clicked.
|
||||
*/
|
||||
private void onPreview () {
|
||||
if (bDesktopSupported) {
|
||||
try {
|
||||
MediaSizeName paperSize = getMediaSize();
|
||||
File f = generateReport(paperSize);
|
||||
desktop.open(f);
|
||||
}
|
||||
catch (IOException e) {
|
||||
log.error("Could not create temporary file for previewing.", e);
|
||||
JOptionPane.showMessageDialog(this, "Could not create a temporary file for previewing.",
|
||||
"Error creating file", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
"Your environment does not support automatically opening the default PDF viewer.",
|
||||
"Error creating file", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for when the "Save as PDF" button is clicked.
|
||||
*
|
||||
* @param p the component to parent the save dialog to
|
||||
*/
|
||||
private void onSavePDF (JComponent p) {
|
||||
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
// Note: source for ExampleFileFilter can be found in FileChooserDemo,
|
||||
// under the demo/jfc directory in the Java 2 SDK, Standard Edition.
|
||||
FileFilter filter = new FileFilter() {
|
||||
|
||||
//Accept all directories and all pdf files.
|
||||
public boolean accept (File f) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//The description of this filter
|
||||
public String getDescription () {
|
||||
return "pdf";
|
||||
}
|
||||
};
|
||||
chooser.setFileFilter(filter);
|
||||
int returnVal = chooser.showSaveDialog(p);
|
||||
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||
|
||||
try {
|
||||
String fname = chooser.getSelectedFile().getCanonicalPath();
|
||||
if (!getExtension(fname).equals("pdf")) {
|
||||
fname = fname + ".pdf";
|
||||
}
|
||||
File f = new File(fname);
|
||||
generateReport(f, getMediaSize());
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the extension of a file.
|
||||
*/
|
||||
private static String getExtension (String s) {
|
||||
String ext = null;
|
||||
int i = s.lastIndexOf('.');
|
||||
|
||||
if (i > 0 && i < s.length() - 1) {
|
||||
ext = s.substring(i + 1).toLowerCase();
|
||||
}
|
||||
return ext != null ? ext : "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is a dialog for displaying advanced settings for printing rocket related info.
|
||||
*/
|
||||
class PrintSettingsDialog extends JDialog {
|
||||
|
||||
/**
|
||||
* The fill color chooser.
|
||||
*/
|
||||
private ColorChooser fill;
|
||||
|
||||
/**
|
||||
* The line color chooser.
|
||||
*/
|
||||
private ColorChooser line;
|
||||
|
||||
/**
|
||||
* Construct a dialog for setting the advanced rocket print settings.
|
||||
*
|
||||
* @param parent the owning dialog
|
||||
*/
|
||||
public PrintSettingsDialog (JDialog parent) {
|
||||
super(parent, "Advanced Settings", true);
|
||||
setLayout(new MigLayout("fill"));
|
||||
|
||||
JPanel settingsPanel = new JPanel();
|
||||
settingsPanel.setLayout(new MigLayout("gap rel"));
|
||||
|
||||
fill = addColorChooser(settingsPanel, "Template Fill", TemplateProperties.getFillColor());
|
||||
line = addColorChooser(settingsPanel, "Template Line", TemplateProperties.getLineColor());
|
||||
|
||||
settingsPanel.add(fill);
|
||||
settingsPanel.add(line);
|
||||
|
||||
add(settingsPanel, "wrap");
|
||||
|
||||
JButton closeButton = new JButton("Close");
|
||||
closeButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed (ActionEvent e) {
|
||||
UIManager.put(TemplateProperties.TEMPLATE_FILL_COLOR_PROPERTY, fill.getCurrentColor());
|
||||
UIManager.put(TemplateProperties.TEMPLATE_LINE_COLOR_PROPERTY, line.getCurrentColor());
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
add(closeButton, "right, gapright para");
|
||||
|
||||
setSize(400, 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a color chooser to a panel.
|
||||
*
|
||||
* @param panel the parent panel to add the color chooser.
|
||||
* @param label the label that indicates which color property is being changed
|
||||
* @param initialColor the initial, or current, color to display
|
||||
*
|
||||
* @return a swing component containing a label, a colorized field, and a button that when clicked opens a color
|
||||
* chooser dialog
|
||||
*/
|
||||
private ColorChooser addColorChooser (JPanel panel, String label, Color initialColor) {
|
||||
final JColorChooser colorChooser = new JColorChooser(initialColor);
|
||||
return new ColorChooser(panel, colorChooser, label);
|
||||
}
|
||||
|
||||
}
|
||||
111
src/net/sf/openrocket/gui/dialogs/PrintSettingsDialog.java
Normal file
111
src/net/sf/openrocket/gui/dialogs/PrintSettingsDialog.java
Normal file
@ -0,0 +1,111 @@
|
||||
package net.sf.openrocket.gui.dialogs;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.adaptors.EnumModel;
|
||||
import net.sf.openrocket.gui.components.ColorChooserButton;
|
||||
import net.sf.openrocket.gui.print.PaperOrientation;
|
||||
import net.sf.openrocket.gui.print.PaperSize;
|
||||
import net.sf.openrocket.gui.print.PrintSettings;
|
||||
import net.sf.openrocket.logging.LogHelper;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.GUIUtil;
|
||||
|
||||
/**
|
||||
* This class is a dialog for displaying advanced settings for printing rocket related info.
|
||||
*/
|
||||
public class PrintSettingsDialog extends JDialog {
|
||||
private static final LogHelper log = Application.getLogger();
|
||||
|
||||
|
||||
/**
|
||||
* Construct a dialog for setting the advanced rocket print settings.
|
||||
*
|
||||
* @param parent the owning dialog
|
||||
*/
|
||||
public PrintSettingsDialog(Window parent, final PrintSettings settings) {
|
||||
super(parent, "Print settings", ModalityType.APPLICATION_MODAL);
|
||||
|
||||
|
||||
JPanel panel = new JPanel(new MigLayout("fill"));
|
||||
|
||||
|
||||
panel.add(new JLabel("Template fill color:"));
|
||||
final ColorChooserButton fillColorButton = new ColorChooserButton(settings.getTemplateFillColor());
|
||||
fillColorButton.addColorPropertyChangeListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
Color c = (Color) evt.getNewValue();
|
||||
log.info("Template fill color changed to " + c);
|
||||
settings.setTemplateFillColor(c);
|
||||
}
|
||||
});
|
||||
panel.add(fillColorButton, "wrap para");
|
||||
|
||||
|
||||
panel.add(new JLabel("Template border color:"));
|
||||
final ColorChooserButton borderColorButton = new ColorChooserButton(settings.getTemplateBorderColor());
|
||||
borderColorButton.addColorPropertyChangeListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
Color c = (Color) evt.getNewValue();
|
||||
log.info("Template border color changed to " + c);
|
||||
settings.setTemplateBorderColor(c);
|
||||
}
|
||||
});
|
||||
panel.add(borderColorButton, "wrap para*2");
|
||||
|
||||
|
||||
|
||||
JComboBox combo = new JComboBox(new EnumModel<PaperSize>(settings, "PaperSize"));
|
||||
panel.add(new JLabel("Paper size:"));
|
||||
panel.add(combo, "growx, wrap para");
|
||||
|
||||
|
||||
combo = new JComboBox(new EnumModel<PaperOrientation>(settings, "PaperOrientation"));
|
||||
panel.add(new JLabel("Paper orientation:"));
|
||||
panel.add(combo, "growx, wrap para*2");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
JButton button = new JButton("Reset");
|
||||
button.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
log.user("Resetting print setting values to defaults");
|
||||
PrintSettings defaults = new PrintSettings();
|
||||
settings.loadFrom(defaults);
|
||||
}
|
||||
});
|
||||
panel.add(button, "spanx, split, right");
|
||||
|
||||
|
||||
JButton closeButton = new JButton("Close");
|
||||
closeButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
PrintSettingsDialog.this.setVisible(false);
|
||||
}
|
||||
});
|
||||
panel.add(closeButton, "right");
|
||||
|
||||
this.add(panel);
|
||||
GUIUtil.setDisposableDialogOptions(this, closeButton);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -483,7 +483,7 @@ public class BasicFrame extends JFrame {
|
||||
menu.add(item);
|
||||
|
||||
|
||||
item = new JMenuItem("Print...", KeyEvent.VK_P);
|
||||
item = new JMenuItem("Print / Export PDF...", KeyEvent.VK_P);
|
||||
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK));
|
||||
item.getAccessibleContext().setAccessibleDescription("Print parts list and fin template");
|
||||
item.setIcon(Icons.FILE_PRINT);
|
||||
@ -1310,7 +1310,7 @@ public class BasicFrame extends JFrame {
|
||||
"Experimental feature", JOptionPane.WARNING_MESSAGE);
|
||||
Prefs.putBoolean("printing.experimental.communicated", true);
|
||||
}
|
||||
new PrintDialog(document);
|
||||
new PrintDialog(this, document).setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -338,6 +338,22 @@ public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Detect and ignore bug 6933331 in Sun JRE 1.6.0_18 and others
|
||||
*/
|
||||
if (t instanceof IllegalStateException) {
|
||||
StackTraceElement[] trace = t.getStackTrace();
|
||||
|
||||
if (trace.length > 1 &&
|
||||
trace[0].getClassName().equals("sun.awt.windows.WComponentPeer") &&
|
||||
trace[0].getMethodName().equals("getBackBuffer")) {
|
||||
log.warn("Ignoring Sun JRE bug 6933331 " +
|
||||
"(see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6933331): " + t);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect and ignore bug in Sun JRE 1.6.0_19
|
||||
*/
|
||||
|
||||
42
src/net/sf/openrocket/gui/print/PaperOrientation.java
Normal file
42
src/net/sf/openrocket/gui/print/PaperOrientation.java
Normal file
@ -0,0 +1,42 @@
|
||||
package net.sf.openrocket.gui.print;
|
||||
|
||||
import com.itextpdf.text.Rectangle;
|
||||
import com.itextpdf.text.RectangleReadOnly;
|
||||
|
||||
public enum PaperOrientation {
|
||||
|
||||
PORTRAIT("Portrait") {
|
||||
@Override
|
||||
public Rectangle orient(Rectangle rect) {
|
||||
return new RectangleReadOnly(rect);
|
||||
}
|
||||
},
|
||||
LANDSCAPE("Landscape") {
|
||||
@Override
|
||||
public Rectangle orient(Rectangle rect) {
|
||||
return new RectangleReadOnly(new Rectangle(rect).rotate());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private final String name;
|
||||
|
||||
private PaperOrientation(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the orientation of a portrait paper to the orientation represented by this
|
||||
* orientation.
|
||||
*
|
||||
* @param rect the original paper size rectangle
|
||||
* @return the oriented paper size rectangle
|
||||
*/
|
||||
public abstract Rectangle orient(Rectangle rect);
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@ -1,247 +1,193 @@
|
||||
/*
|
||||
* PaperSize.java
|
||||
*/
|
||||
package net.sf.openrocket.gui.print;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import net.sf.openrocket.logging.LogHelper;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/** Disallow construction. */
|
||||
private PaperSize() {}
|
||||
|
||||
/**
|
||||
* 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)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -4,6 +4,15 @@
|
||||
*/
|
||||
package net.sf.openrocket.gui.print;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.gui.print.visitor.FinSetVisitorStrategy;
|
||||
import net.sf.openrocket.gui.print.visitor.PartsDetailVisitorStrategy;
|
||||
|
||||
import com.itextpdf.text.Document;
|
||||
import com.itextpdf.text.DocumentException;
|
||||
import com.itextpdf.text.ExceptionConverter;
|
||||
@ -11,107 +20,92 @@ import com.itextpdf.text.Rectangle;
|
||||
import com.itextpdf.text.pdf.PdfBoolean;
|
||||
import com.itextpdf.text.pdf.PdfName;
|
||||
import com.itextpdf.text.pdf.PdfWriter;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.gui.print.visitor.FinSetVisitorStrategy;
|
||||
import net.sf.openrocket.gui.print.visitor.PartsDetailVisitorStrategy;
|
||||
|
||||
import javax.print.attribute.standard.MediaSizeName;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This is the main active object for printing. It performs all actions necessary to create and populate the print
|
||||
* file.
|
||||
*/
|
||||
public class PrintController {
|
||||
|
||||
/**
|
||||
* Print the selected components to a PDF document.
|
||||
*
|
||||
* @param doc the OR document
|
||||
* @param toBePrinted the user chosen items to print
|
||||
* @param outputFile the file being written to
|
||||
* @param msn the paper size
|
||||
*/
|
||||
public void print(OpenRocketDocument doc, Iterator<PrintableContext> toBePrinted, OutputStream outputFile,
|
||||
MediaSizeName msn) {
|
||||
|
||||
Document idoc = new Document(convertWithDefault(msn));
|
||||
PdfWriter writer = null;
|
||||
try {
|
||||
writer = PdfWriter.getInstance(idoc, outputFile);
|
||||
writer.setStrictImageSequence(true);
|
||||
|
||||
writer.addViewerPreference(PdfName.PRINTSCALING, PdfName.NONE);
|
||||
writer.addViewerPreference(PdfName.PICKTRAYBYPDFSIZE, PdfBoolean.PDFTRUE);
|
||||
try {
|
||||
idoc.open();
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
}
|
||||
while (toBePrinted.hasNext()) {
|
||||
PrintableContext printableContext = toBePrinted.next();
|
||||
|
||||
Set<Integer> stages = printableContext.getStageNumber();
|
||||
|
||||
switch (printableContext.getPrintable()) {
|
||||
case DESIGN_REPORT:
|
||||
DesignReport dp = new DesignReport(doc, idoc);
|
||||
dp.writeToDocument(writer);
|
||||
idoc.newPage();
|
||||
break;
|
||||
case FIN_TEMPLATE:
|
||||
final FinSetVisitorStrategy finWriter = new FinSetVisitorStrategy(idoc,
|
||||
writer,
|
||||
stages);
|
||||
finWriter.writeToDocument(doc.getRocket());
|
||||
break;
|
||||
case PARTS_DETAIL:
|
||||
final PartsDetailVisitorStrategy detailVisitor = new PartsDetailVisitorStrategy(idoc,
|
||||
writer,
|
||||
stages);
|
||||
detailVisitor.writeToDocument(doc.getRocket());
|
||||
detailVisitor.close();
|
||||
idoc.newPage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Stupid iText throws a really nasty exception if there is no data when close is called.
|
||||
if (writer.getCurrentDocumentSize() <= 140) {
|
||||
writer.setPageEmpty(false);
|
||||
}
|
||||
writer.close();
|
||||
idoc.close();
|
||||
}
|
||||
catch (DocumentException e) {
|
||||
}
|
||||
catch (ExceptionConverter ec) {
|
||||
}
|
||||
finally {
|
||||
if (outputFile != null) {
|
||||
try {
|
||||
outputFile.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a media size name to a rectangle that defines the bounds of the corresponding paper size.
|
||||
*
|
||||
* @param msn the MediaSizeName to convert
|
||||
* @return the corresponding Rectangle
|
||||
*/
|
||||
private Rectangle convertWithDefault(final MediaSizeName msn) {
|
||||
Rectangle result = PaperSize.convert(msn);
|
||||
if (result == null) {
|
||||
result = PaperSize.convert(PrintUtilities.getDefaultMedia().getMediaSizeName());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the selected components to a PDF document.
|
||||
*
|
||||
* @param doc the OR document
|
||||
* @param toBePrinted the user chosen items to print
|
||||
* @param outputFile the file being written to
|
||||
* @param msn the paper size
|
||||
*/
|
||||
public void print(OpenRocketDocument doc, Iterator<PrintableContext> toBePrinted, OutputStream outputFile,
|
||||
PrintSettings settings) {
|
||||
|
||||
Document idoc = new Document(getSize(settings));
|
||||
PdfWriter writer = null;
|
||||
try {
|
||||
writer = PdfWriter.getInstance(idoc, outputFile);
|
||||
writer.setStrictImageSequence(true);
|
||||
|
||||
writer.addViewerPreference(PdfName.PRINTSCALING, PdfName.NONE);
|
||||
writer.addViewerPreference(PdfName.PICKTRAYBYPDFSIZE, PdfBoolean.PDFTRUE);
|
||||
try {
|
||||
idoc.open();
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
while (toBePrinted.hasNext()) {
|
||||
PrintableContext printableContext = toBePrinted.next();
|
||||
|
||||
Set<Integer> stages = printableContext.getStageNumber();
|
||||
|
||||
switch (printableContext.getPrintable()) {
|
||||
case DESIGN_REPORT:
|
||||
DesignReport dp = new DesignReport(doc, idoc);
|
||||
dp.writeToDocument(writer);
|
||||
idoc.newPage();
|
||||
break;
|
||||
case FIN_TEMPLATE:
|
||||
final FinSetVisitorStrategy finWriter = new FinSetVisitorStrategy(idoc,
|
||||
writer,
|
||||
stages);
|
||||
finWriter.writeToDocument(doc.getRocket());
|
||||
break;
|
||||
case PARTS_DETAIL:
|
||||
final PartsDetailVisitorStrategy detailVisitor = new PartsDetailVisitorStrategy(idoc,
|
||||
writer,
|
||||
stages);
|
||||
detailVisitor.writeToDocument(doc.getRocket());
|
||||
detailVisitor.close();
|
||||
idoc.newPage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Stupid iText throws a really nasty exception if there is no data when close is called.
|
||||
if (writer.getCurrentDocumentSize() <= 140) {
|
||||
writer.setPageEmpty(false);
|
||||
}
|
||||
writer.close();
|
||||
idoc.close();
|
||||
} catch (DocumentException e) {
|
||||
} catch (ExceptionConverter ec) {
|
||||
} finally {
|
||||
if (outputFile != null) {
|
||||
try {
|
||||
outputFile.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the correct paper size from the print settings.
|
||||
*
|
||||
* @param settings the print settings
|
||||
* @return the paper size
|
||||
*/
|
||||
private Rectangle getSize(PrintSettings settings) {
|
||||
PaperSize size = settings.getPaperSize();
|
||||
PaperOrientation orientation = settings.getPaperOrientation();
|
||||
return orientation.orient(size.getSize());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,609 +0,0 @@
|
||||
/*
|
||||
* PrintServiceDialog.java
|
||||
*
|
||||
*/
|
||||
package net.sf.openrocket.gui.print;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.print.DocFlavor;
|
||||
import javax.print.PrintService;
|
||||
import javax.print.ServiceUIFactory;
|
||||
import javax.print.attribute.HashPrintRequestAttributeSet;
|
||||
import javax.print.attribute.PrintRequestAttribute;
|
||||
import javax.print.attribute.PrintRequestAttributeSet;
|
||||
import javax.print.attribute.standard.Destination;
|
||||
import javax.print.attribute.standard.Media;
|
||||
import javax.print.attribute.standard.MediaSizeName;
|
||||
import javax.print.attribute.standard.MediaTray;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.ActionMap;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.InputMap;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
import javax.swing.event.PopupMenuListener;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class PrintServiceDialog extends JDialog implements ActionListener {
|
||||
|
||||
public static final int APPROVE = 1;
|
||||
private JButton btnCancel, btnPrint;
|
||||
private boolean pdfFlavorSupported = true;
|
||||
private PrintService services[];
|
||||
private int defaultServiceIndex = -1;
|
||||
private int status;
|
||||
private PrintRequestAttributeSet asOriginal;
|
||||
private HashPrintRequestAttributeSet asCurrent;
|
||||
private PrintService psCurrent;
|
||||
private DocFlavor docFlavor;
|
||||
private GeneralPanel pnlGeneral;
|
||||
private static final String GENERAL_TAB_TITLE = "General";
|
||||
private static final String PRINT_BUTTON_LABEL = "Print";
|
||||
private static final String CANCEL_BUTTON_LABEL = "Cancel";
|
||||
|
||||
private class MediaPanel extends JPanel
|
||||
implements ItemListener {
|
||||
|
||||
private static final String strTitle = "Media";
|
||||
private static final String SOURCE = "Source:";
|
||||
private static final String SIZE = "Size:";
|
||||
|
||||
private JLabel lblSize, lblSource;
|
||||
private JComboBox cbSize, cbSource;
|
||||
private ArrayList<MediaSizeName> sizes;
|
||||
private ArrayList sources;
|
||||
|
||||
private String getMediaName(String s) {
|
||||
String s1 = s.replace(' ', '-');
|
||||
s1 = s1.replace('#', 'n');
|
||||
return PaperSize.toDisplayable(s1);
|
||||
}
|
||||
|
||||
public void itemStateChanged(ItemEvent itemevent) {
|
||||
Object obj = itemevent.getSource();
|
||||
if (itemevent.getStateChange() == ItemEvent.SELECTED) {
|
||||
if (obj == cbSize) {
|
||||
int i = cbSize.getSelectedIndex();
|
||||
if (i >= 0 && i < sizes.size()) {
|
||||
if (cbSource.getItemCount() > 1 && cbSource.getSelectedIndex() >= 1) {
|
||||
int k = cbSource.getSelectedIndex() - 1;
|
||||
MediaTray mediatray = (MediaTray) sources.get(k);
|
||||
asCurrent.add(new MediaWrapper(mediatray));
|
||||
}
|
||||
asCurrent.add(sizes.get(i));
|
||||
}
|
||||
}
|
||||
else if (obj == cbSource) {
|
||||
int j = cbSource.getSelectedIndex();
|
||||
if (j >= 1 && j < sources.size() + 1) {
|
||||
asCurrent.remove(MediaWrapper.class);
|
||||
asCurrent.add((MediaTray) sources.get(j - 1));
|
||||
}
|
||||
else if (j == 0) {
|
||||
asCurrent.remove(MediaWrapper.class);
|
||||
if (cbSize.getItemCount() > 0) {
|
||||
int l = cbSize.getSelectedIndex();
|
||||
asCurrent.add(sizes.get(l));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void updateInfo() {
|
||||
boolean flag = false;
|
||||
cbSize.removeItemListener(this);
|
||||
cbSize.removeAllItems();
|
||||
cbSource.removeItemListener(this);
|
||||
cbSource.removeAllItems();
|
||||
cbSource.addItem(getMediaName("auto-select"));
|
||||
sizes.clear();
|
||||
sources.clear();
|
||||
if (psCurrent != null && psCurrent.isAttributeCategorySupported(Media.class)) {
|
||||
flag = true;
|
||||
Object obj = null;
|
||||
try {
|
||||
obj = psCurrent.getSupportedAttributeValues(Media.class, docFlavor, asCurrent);
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
pdfFlavorSupported = false;
|
||||
//dgp
|
||||
}
|
||||
if (obj instanceof Media[]) {
|
||||
Media amedia[] = (Media[]) obj;
|
||||
Set<SortableMediaSizeName> sizeSet = new TreeSet<SortableMediaSizeName>();
|
||||
|
||||
for (int i = 0; i < amedia.length; i++) {
|
||||
Media media = amedia[i];
|
||||
if (media instanceof MediaSizeName) {
|
||||
sizeSet.add(new SortableMediaSizeName((MediaSizeName) media));
|
||||
}
|
||||
else if (media instanceof MediaTray) {
|
||||
sources.add(media);
|
||||
cbSource.addItem(getMediaName(media.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
//The set eliminates duplicates.
|
||||
for (Iterator<SortableMediaSizeName> mediaSizeNameIterator = sizeSet.iterator(); mediaSizeNameIterator
|
||||
.hasNext();) {
|
||||
SortableMediaSizeName media = mediaSizeNameIterator.next();
|
||||
|
||||
sizes.add(media.getMediaSizeName());
|
||||
cbSize.addItem(media.toString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
boolean flag1 = flag && sizes.size() > 0;
|
||||
lblSize.setEnabled(flag1);
|
||||
cbSize.setEnabled(flag1);
|
||||
cbSource.setEnabled(false);
|
||||
lblSource.setEnabled(false);
|
||||
if (flag && psCurrent != null) {
|
||||
Media media = (Media) asCurrent.get(Media.class);
|
||||
boolean attributeValueSupported = false;
|
||||
try {
|
||||
attributeValueSupported = media == null ? false : psCurrent.isAttributeValueSupported(media,
|
||||
docFlavor,
|
||||
asCurrent);
|
||||
}
|
||||
catch (IllegalArgumentException iae) {
|
||||
pdfFlavorSupported = false;
|
||||
}
|
||||
if (media == null || !attributeValueSupported) {
|
||||
media = (Media) psCurrent.getDefaultAttributeValue(Media.class);
|
||||
if (media == null && sizes.size() > 0) {
|
||||
media = sizes.get(0);
|
||||
}
|
||||
if (media != null) {
|
||||
asCurrent.add(media);
|
||||
}
|
||||
}
|
||||
if (media != null) {
|
||||
if (media instanceof MediaSizeName) {
|
||||
MediaSizeName mediasizename = (MediaSizeName) media;
|
||||
cbSize.setSelectedIndex(sizes.indexOf(mediasizename));
|
||||
}
|
||||
else if (media instanceof MediaTray) {
|
||||
MediaTray mediatray = (MediaTray) media;
|
||||
cbSource.setSelectedIndex(sources.indexOf(mediatray) + 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
cbSize.setSelectedIndex(sizes.size() <= 0 ? -1 : 0);
|
||||
cbSource.setSelectedIndex(0);
|
||||
}
|
||||
int j = cbSize.getSelectedIndex();
|
||||
if (j >= 0 && j < sizes.size()) {
|
||||
asCurrent.add(sizes.get(j));
|
||||
}
|
||||
j = cbSource.getSelectedIndex();
|
||||
if (j >= 1 && j < sources.size() + 1) {
|
||||
asCurrent.add((MediaTray) sources.get(j - 1));
|
||||
}
|
||||
}
|
||||
cbSize.addItemListener(this);
|
||||
cbSource.addItemListener(this);
|
||||
}
|
||||
|
||||
public MediaPanel() {
|
||||
super(new MigLayout("fill, gap rel unrel"));
|
||||
sizes = new ArrayList<MediaSizeName>();
|
||||
sources = new ArrayList();
|
||||
setBorder(BorderFactory.createTitledBorder(strTitle));
|
||||
cbSize = new JComboBox();
|
||||
cbSource = new JComboBox();
|
||||
lblSize = new JLabel(SIZE, 11);
|
||||
lblSize.setDisplayedMnemonic(PrintServiceDialog.getMnemonic(SIZE));
|
||||
lblSize.setLabelFor(cbSize);
|
||||
add(lblSize);
|
||||
add(cbSize, "wrap");
|
||||
lblSource = new JLabel(SOURCE, 11);
|
||||
lblSource.setDisplayedMnemonic(PrintServiceDialog.getMnemonic(SOURCE));
|
||||
lblSource.setLabelFor(cbSource);
|
||||
add(lblSource);
|
||||
add(cbSource);
|
||||
}
|
||||
|
||||
class SortableMediaSizeName implements Comparable {
|
||||
MediaSizeName delegate;
|
||||
|
||||
String displayableName;
|
||||
|
||||
SortableMediaSizeName(MediaSizeName msn) {
|
||||
delegate = msn;
|
||||
displayableName = getMediaName(delegate.toString());
|
||||
if (displayableName == null) {
|
||||
displayableName = delegate.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string value corresponding to this enumeration value.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return displayableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final Object o) {
|
||||
String name = displayableName;
|
||||
if (name != null) {
|
||||
return name.compareTo(o.toString());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final SortableMediaSizeName that = (SortableMediaSizeName) o;
|
||||
|
||||
return displayableName.equals(that.displayableName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return displayableName.hashCode();
|
||||
}
|
||||
|
||||
MediaSizeName getMediaSizeName() {
|
||||
return delegate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class PrintServicePanel extends JPanel
|
||||
implements ActionListener, ItemListener, PopupMenuListener {
|
||||
|
||||
private final String strTitle = "Print Service";
|
||||
private JButton btnProperties;
|
||||
private JComboBox cbName;
|
||||
private ServiceUIFactory uiFactory;
|
||||
private boolean changedService;
|
||||
|
||||
public PrintServicePanel() {
|
||||
super(new MigLayout("fill, gap rel unrel"));
|
||||
changedService = false;
|
||||
if (psCurrent != null) {
|
||||
uiFactory = psCurrent.getServiceUIFactory();
|
||||
}
|
||||
setBorder(BorderFactory.createTitledBorder(strTitle));
|
||||
String as[] = new String[services.length];
|
||||
for (int i = 0; i < as.length; i++) {
|
||||
as[i] = services[i].getName();
|
||||
}
|
||||
|
||||
cbName = new JComboBox(as);
|
||||
if (defaultServiceIndex != -1 && defaultServiceIndex < services.length) {
|
||||
cbName.setSelectedIndex(defaultServiceIndex);
|
||||
}
|
||||
cbName.addItemListener(this);
|
||||
cbName.addPopupMenuListener(this);
|
||||
JLabel jlabel = new JLabel(("Name:"), 11);
|
||||
jlabel.setDisplayedMnemonic(PrintServiceDialog.getMnemonic("Name"));
|
||||
jlabel.setLabelFor(cbName);
|
||||
add(jlabel);
|
||||
add(cbName);
|
||||
btnProperties = PrintServiceDialog.createButton("Properties...", this);
|
||||
add(btnProperties, "wrap");
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent actionevent) {
|
||||
Object obj = actionevent.getSource();
|
||||
if (obj == btnProperties && uiFactory != null) {
|
||||
JDialog jdialog = (JDialog) uiFactory.getUI(ServiceUIFactory.MAIN_UIROLE, "javax.swing.JDialog");
|
||||
if (jdialog != null) {
|
||||
jdialog.show();
|
||||
}
|
||||
else {
|
||||
btnProperties.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param itemevent the event that indicates what changed
|
||||
*/
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent itemevent) {
|
||||
if (itemevent.getStateChange() == ItemEvent.SELECTED) {
|
||||
int i = cbName.getSelectedIndex();
|
||||
if (services != null && i >= 0 && i < services.length && !services[i].equals(psCurrent)) {
|
||||
psCurrent = services[i];
|
||||
uiFactory = psCurrent.getServiceUIFactory();
|
||||
changedService = true;
|
||||
if (asOriginal != null) {
|
||||
Destination destination = (Destination) asOriginal.get(
|
||||
Destination.class);
|
||||
if ((destination != null) && psCurrent.isAttributeCategorySupported(
|
||||
Destination.class)) {
|
||||
asCurrent.add(destination);
|
||||
}
|
||||
else {
|
||||
asCurrent.remove(Destination.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param popupmenuevent
|
||||
*/
|
||||
@Override
|
||||
public void popupMenuWillBecomeVisible(PopupMenuEvent popupmenuevent) {
|
||||
changedService = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param popupmenuevent
|
||||
*/
|
||||
@Override
|
||||
public void popupMenuWillBecomeInvisible(PopupMenuEvent popupmenuevent) {
|
||||
if (changedService) {
|
||||
changedService = false;
|
||||
updatePanels();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @param popupmenuevent
|
||||
*/
|
||||
@Override
|
||||
public void popupMenuCanceled(PopupMenuEvent popupmenuevent) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the enablement of the properties button.
|
||||
*/
|
||||
public void updateInfo() {
|
||||
btnProperties.setEnabled(uiFactory != null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The panel for general print services info.
|
||||
*/
|
||||
private class GeneralPanel extends JPanel {
|
||||
|
||||
private PrintServicePanel pnlPrintService;
|
||||
private MediaPanel pnlMedia;
|
||||
|
||||
public GeneralPanel() {
|
||||
super(new MigLayout("fill, gap rel unrel"));
|
||||
pnlPrintService = new PrintServicePanel();
|
||||
add(pnlPrintService, "wrap");
|
||||
pnlMedia = new MediaPanel();
|
||||
add(pnlMedia, "wrap");
|
||||
}
|
||||
|
||||
public void updateInfo() {
|
||||
pnlPrintService.updateInfo();
|
||||
pnlMedia.updateInfo();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param x the <i>x</i>-coordinate of the new location's
|
||||
* top-left corner in the parent's coordinate space
|
||||
* @param y the <i>y</i>-coordinate of the new location's
|
||||
* top-left corner in the parent's coordinate space
|
||||
* @param aPrintService the array of installed print services
|
||||
* @param defaultServiceIndex the default service index (index into aPrintService)
|
||||
* @param docflavor the document flavor (i.e. PDF)
|
||||
* @param attributeSet the set of required attributes
|
||||
* @param dialog the parent
|
||||
* @param additional other panels to add in tabs
|
||||
*/
|
||||
public PrintServiceDialog(int x, int y, PrintService[] aPrintService,
|
||||
int defaultServiceIndex, DocFlavor docflavor, PrintRequestAttributeSet attributeSet,
|
||||
Dialog dialog, JPanel... additional) {
|
||||
super(dialog, PRINT_BUTTON_LABEL, true);
|
||||
setLayout(new MigLayout("fill, gap rel unrel"));
|
||||
services = aPrintService;
|
||||
this.defaultServiceIndex = defaultServiceIndex;
|
||||
asOriginal = attributeSet;
|
||||
asCurrent = new HashPrintRequestAttributeSet(attributeSet);
|
||||
|
||||
if (services != null && defaultServiceIndex < services.length && defaultServiceIndex >= 0) {
|
||||
psCurrent = services[defaultServiceIndex];
|
||||
}
|
||||
docFlavor = docflavor;
|
||||
Container container = getContentPane();
|
||||
container.setLayout(new MigLayout("fill, gap rel unrel"));
|
||||
// container.setLayout(new BorderLayout());
|
||||
final JTabbedPane tpTabs = new JTabbedPane();
|
||||
tpTabs.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
|
||||
if (additional != null) {
|
||||
for (JPanel anAdditional : additional) {
|
||||
tpTabs.add(anAdditional, anAdditional.getName(), 0);
|
||||
}
|
||||
}
|
||||
if (psCurrent != null) {
|
||||
pnlGeneral = new GeneralPanel();
|
||||
tpTabs.add(GENERAL_TAB_TITLE, pnlGeneral);
|
||||
}
|
||||
|
||||
container.add(tpTabs, "growx");
|
||||
updatePanels();
|
||||
|
||||
JPanel jpanel = new JPanel(new MigLayout());
|
||||
btnPrint = createExitButton(PRINT_BUTTON_LABEL, this);
|
||||
jpanel.add(btnPrint, "x 300");
|
||||
getRootPane().setDefaultButton(btnPrint);
|
||||
btnPrint.setEnabled(pdfFlavorSupported && psCurrent != null);
|
||||
|
||||
btnCancel = createExitButton(CANCEL_BUTTON_LABEL, this);
|
||||
handleEscKey(btnCancel);
|
||||
jpanel.add(btnCancel, "x 380");
|
||||
container.add(jpanel, "South");
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent windowevent) {
|
||||
dispose(2);
|
||||
}
|
||||
}
|
||||
);
|
||||
setResizable(false);
|
||||
setLocation(x, y);
|
||||
pack();
|
||||
}
|
||||
|
||||
private void handleEscKey(JButton jbutton) {
|
||||
AbstractAction abstractaction = new AbstractAction() {
|
||||
|
||||
public void actionPerformed(ActionEvent actionevent) {
|
||||
dispose(2);
|
||||
}
|
||||
|
||||
};
|
||||
KeyStroke keystroke = KeyStroke.getKeyStroke('\033', false);
|
||||
InputMap inputmap = jbutton.getInputMap(2);
|
||||
ActionMap actionmap = jbutton.getActionMap();
|
||||
if (inputmap != null && actionmap != null) {
|
||||
inputmap.put(keystroke, "cancel");
|
||||
actionmap.put("cancel", abstractaction);
|
||||
}
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public PrintRequestAttributeSet getAttributes() {
|
||||
if (status == 1) {
|
||||
return asCurrent;
|
||||
}
|
||||
else {
|
||||
return asOriginal;
|
||||
}
|
||||
}
|
||||
|
||||
public PrintService getPrintService() {
|
||||
if (status == 1) {
|
||||
return psCurrent;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void dispose(int i) {
|
||||
status = i;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent actionevent) {
|
||||
Object obj = actionevent.getSource();
|
||||
boolean flag = false;
|
||||
if (obj == btnPrint) {
|
||||
flag = true;
|
||||
if (pnlGeneral != null) {
|
||||
asCurrent.remove(Destination.class);
|
||||
}
|
||||
}
|
||||
dispose(flag ? 1 : 2);
|
||||
}
|
||||
|
||||
|
||||
private void updatePanels() {
|
||||
if (pnlGeneral != null) {
|
||||
pnlGeneral.updateInfo();
|
||||
}
|
||||
}
|
||||
|
||||
private static char getMnemonic(String s) {
|
||||
if (s != null && s.length() > 0) {
|
||||
return s.charAt(0);
|
||||
}
|
||||
else {
|
||||
return '\0';
|
||||
}
|
||||
}
|
||||
|
||||
private static JButton createButton(String s, ActionListener actionlistener) {
|
||||
JButton jbutton = new JButton(s);
|
||||
jbutton.setMnemonic(getMnemonic(s));
|
||||
jbutton.addActionListener(actionlistener);
|
||||
return jbutton;
|
||||
}
|
||||
|
||||
private static JButton createExitButton(String s, ActionListener actionlistener) {
|
||||
JButton jbutton = new JButton(s);
|
||||
jbutton.addActionListener(actionlistener);
|
||||
jbutton.getAccessibleContext().setAccessibleDescription(s);
|
||||
return jbutton;
|
||||
}
|
||||
|
||||
static class MediaWrapper
|
||||
implements PrintRequestAttribute {
|
||||
|
||||
private Media media;
|
||||
|
||||
MediaWrapper(Media theMedia) {
|
||||
media = theMedia;
|
||||
}
|
||||
|
||||
Media getMedia() {
|
||||
return media;
|
||||
}
|
||||
|
||||
public final Class getCategory() {
|
||||
return this.getClass();
|
||||
}
|
||||
|
||||
public final String getName() {
|
||||
return "mw";
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return media.toString();
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return media.hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
89
src/net/sf/openrocket/gui/print/PrintSettings.java
Normal file
89
src/net/sf/openrocket/gui/print/PrintSettings.java
Normal file
@ -0,0 +1,89 @@
|
||||
package net.sf.openrocket.gui.print;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import net.sf.openrocket.util.AbstractChangeSource;
|
||||
|
||||
/**
|
||||
* A class containing all printing settings.
|
||||
*/
|
||||
public class PrintSettings extends AbstractChangeSource {
|
||||
|
||||
private Color templateFillColor = Color.LIGHT_GRAY;
|
||||
private Color templateBorderColor = Color.DARK_GRAY;
|
||||
|
||||
private PaperSize paperSize = PaperSize.getDefault();
|
||||
private PaperOrientation paperOrientation = PaperOrientation.PORTRAIT;
|
||||
|
||||
|
||||
public Color getTemplateFillColor() {
|
||||
return templateFillColor;
|
||||
}
|
||||
|
||||
public void setTemplateFillColor(Color templateFillColor) {
|
||||
// Implicitly tests against setting null
|
||||
if (templateFillColor.equals(this.templateFillColor)) {
|
||||
return;
|
||||
}
|
||||
this.templateFillColor = templateFillColor;
|
||||
fireChangeEvent();
|
||||
}
|
||||
|
||||
public Color getTemplateBorderColor() {
|
||||
return templateBorderColor;
|
||||
}
|
||||
|
||||
public void setTemplateBorderColor(Color templateBorderColor) {
|
||||
// Implicitly tests against setting null
|
||||
if (templateBorderColor.equals(this.templateBorderColor)) {
|
||||
return;
|
||||
}
|
||||
this.templateBorderColor = templateBorderColor;
|
||||
fireChangeEvent();
|
||||
}
|
||||
|
||||
public PaperSize getPaperSize() {
|
||||
return paperSize;
|
||||
}
|
||||
|
||||
public void setPaperSize(PaperSize paperSize) {
|
||||
if (paperSize.equals(this.paperSize)) {
|
||||
return;
|
||||
}
|
||||
this.paperSize = paperSize;
|
||||
fireChangeEvent();
|
||||
}
|
||||
|
||||
public PaperOrientation getPaperOrientation() {
|
||||
return paperOrientation;
|
||||
}
|
||||
|
||||
public void setPaperOrientation(PaperOrientation orientation) {
|
||||
if (orientation.equals(paperOrientation)) {
|
||||
return;
|
||||
}
|
||||
this.paperOrientation = orientation;
|
||||
fireChangeEvent();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load settings from the specified print settings.
|
||||
* @param settings the settings to load
|
||||
*/
|
||||
public void loadFrom(PrintSettings settings) {
|
||||
this.templateFillColor = settings.templateFillColor;
|
||||
this.templateBorderColor = settings.templateBorderColor;
|
||||
this.paperSize = settings.paperSize;
|
||||
this.paperOrientation = settings.paperOrientation;
|
||||
fireChangeEvent();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PrintSettings [templateFillColor=" + templateFillColor + ", templateBorderColor=" + templateBorderColor + ", paperSize=" + paperSize + ", paperOrientation=" + paperOrientation + "]";
|
||||
}
|
||||
|
||||
}
|
||||
@ -4,151 +4,101 @@
|
||||
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);
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,47 +3,74 @@
|
||||
*/
|
||||
package net.sf.openrocket.gui.print;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
* This class is responsible for managing various properties of print templates (fin, nose cone, transitions, etc.).
|
||||
*
|
||||
* TODO: HIGH: Remove this entire class, and instead pass the PrintSettings object to the print methods.
|
||||
*/
|
||||
public class TemplateProperties {
|
||||
|
||||
/**
|
||||
* The property that defines the fill color.
|
||||
*/
|
||||
public static final String TEMPLATE_FILL_COLOR_PROPERTY = "template.fill.color";
|
||||
|
||||
/**
|
||||
* The property that defines the line color.
|
||||
*/
|
||||
public static final String TEMPLATE_LINE_COLOR_PROPERTY = "template.line.color";
|
||||
|
||||
/**
|
||||
* Get the current fill color.
|
||||
*
|
||||
* @return a color to be used as the fill in template shapes
|
||||
*/
|
||||
public static Color getFillColor () {
|
||||
Color fillColor = UIManager.getColor(TemplateProperties.TEMPLATE_FILL_COLOR_PROPERTY);
|
||||
if (fillColor == null) {
|
||||
fillColor = Color.lightGray;
|
||||
}
|
||||
return fillColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current line color.
|
||||
*
|
||||
* @return a color to be used as the line in template shapes
|
||||
*/
|
||||
public static Color getLineColor () {
|
||||
Color lineColor = UIManager.getColor(TemplateProperties.TEMPLATE_LINE_COLOR_PROPERTY);
|
||||
if (lineColor == null) {
|
||||
lineColor = Color.darkGray;
|
||||
}
|
||||
return lineColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* The property that defines the fill color.
|
||||
*/
|
||||
public static final String TEMPLATE_FILL_COLOR_PROPERTY = "template.fill.color";
|
||||
|
||||
/**
|
||||
* The property that defines the line color.
|
||||
*/
|
||||
public static final String TEMPLATE_LINE_COLOR_PROPERTY = "template.line.color";
|
||||
|
||||
/**
|
||||
* Get the current fill color.
|
||||
*
|
||||
* @return a color to be used as the fill in template shapes
|
||||
*/
|
||||
public static Color getFillColor() {
|
||||
Color fillColor = UIManager.getColor(TemplateProperties.TEMPLATE_FILL_COLOR_PROPERTY);
|
||||
if (fillColor == null) {
|
||||
fillColor = Color.lightGray;
|
||||
}
|
||||
return fillColor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the template fill color.
|
||||
*/
|
||||
public static void setFillColor(Color c) {
|
||||
UIManager.put(TemplateProperties.TEMPLATE_FILL_COLOR_PROPERTY, c);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the current line color.
|
||||
*
|
||||
* @return a color to be used as the line in template shapes
|
||||
*/
|
||||
public static Color getLineColor() {
|
||||
Color lineColor = UIManager.getColor(TemplateProperties.TEMPLATE_LINE_COLOR_PROPERTY);
|
||||
if (lineColor == null) {
|
||||
lineColor = Color.darkGray;
|
||||
}
|
||||
return lineColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the template line color.
|
||||
*/
|
||||
public static void setLineColor(Color c) {
|
||||
UIManager.put(TemplateProperties.TEMPLATE_LINE_COLOR_PROPERTY, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the template colors from the print settings.
|
||||
*/
|
||||
public static void setColors(PrintSettings settings) {
|
||||
setFillColor(settings.getTemplateFillColor());
|
||||
setLineColor(settings.getTemplateBorderColor());
|
||||
}
|
||||
}
|
||||
|
||||
47
src/net/sf/openrocket/util/AbstractChangeSource.java
Normal file
47
src/net/sf/openrocket/util/AbstractChangeSource.java
Normal file
@ -0,0 +1,47 @@
|
||||
package net.sf.openrocket.util;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import net.sf.openrocket.logging.LogHelper;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
|
||||
/**
|
||||
* Abstract implementation of a ChangeSource.
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
*/
|
||||
public abstract class AbstractChangeSource implements ChangeSource {
|
||||
private static final LogHelper log = Application.getLogger();
|
||||
|
||||
private final List<ChangeListener> listeners = new ArrayList<ChangeListener>();
|
||||
|
||||
private final ChangeEvent event = new ChangeEvent(this);
|
||||
|
||||
|
||||
@Override
|
||||
public final void addChangeListener(ChangeListener listener) {
|
||||
listeners.add(listener);
|
||||
log.verbose(1, "Adding change listeners, listener count is now " + listeners.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void removeChangeListener(ChangeListener listener) {
|
||||
listeners.remove(listener);
|
||||
log.verbose(1, "Removing change listeners, listener count is now " + listeners.size());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fire a change event to all listeners.
|
||||
*/
|
||||
protected void fireChangeEvent() {
|
||||
ChangeListener[] array = listeners.toArray(new ChangeListener[0]);
|
||||
|
||||
for (ChangeListener l : array) {
|
||||
l.stateChanged(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22,6 +22,7 @@ import net.sf.openrocket.arch.SystemInfo;
|
||||
import net.sf.openrocket.database.Databases;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.gui.main.ExceptionHandler;
|
||||
import net.sf.openrocket.gui.print.PrintSettings;
|
||||
import net.sf.openrocket.logging.LogHelper;
|
||||
import net.sf.openrocket.material.Material;
|
||||
import net.sf.openrocket.rocketcomponent.BodyComponent;
|
||||
@ -306,6 +307,47 @@ public class Prefs {
|
||||
storeVersion();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve an enum value from the user preferences.
|
||||
*
|
||||
* @param <T> the enum type
|
||||
* @param key the key
|
||||
* @param def the default value, cannot be null
|
||||
* @return the value in the preferences, or the default value
|
||||
*/
|
||||
public static <T extends Enum<T>> T getEnum(String key, T def) {
|
||||
if (def == null) {
|
||||
throw new BugException("Default value cannot be null");
|
||||
}
|
||||
|
||||
String value = getString(key, null);
|
||||
if (value == null) {
|
||||
return def;
|
||||
}
|
||||
|
||||
try {
|
||||
return Enum.valueOf(def.getDeclaringClass(), value);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an enum value to the user preferences.
|
||||
*
|
||||
* @param key the key
|
||||
* @param value the value to store, or null to remove the value
|
||||
*/
|
||||
public static void putEnum(String key, Enum<?> value) {
|
||||
if (value == null) {
|
||||
putString(key, null);
|
||||
} else {
|
||||
putString(key, value.name());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a boolean preference.
|
||||
*
|
||||
@ -443,6 +485,26 @@ public class Prefs {
|
||||
if (color == null)
|
||||
return Color.BLACK;
|
||||
|
||||
Color clr = parseColor(color);
|
||||
if (clr != null) {
|
||||
return clr;
|
||||
} else {
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
public static void setDefaultColor(Class<? extends RocketComponent> c, Color color) {
|
||||
if (color == null)
|
||||
return;
|
||||
set("componentColors", c, stringifyColor(color));
|
||||
}
|
||||
|
||||
|
||||
private static Color parseColor(String color) {
|
||||
if (color == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String[] rgb = color.split(",");
|
||||
if (rgb.length == 3) {
|
||||
try {
|
||||
@ -453,17 +515,17 @@ public class Prefs {
|
||||
} catch (NumberFormatException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
return Color.BLACK;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void setDefaultColor(Class<? extends RocketComponent> c, Color color) {
|
||||
if (color == null)
|
||||
return;
|
||||
|
||||
private static String stringifyColor(Color color) {
|
||||
String string = color.getRed() + "," + color.getGreen() + "," + color.getBlue();
|
||||
set("componentColors", c, string);
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static Color getMotorBorderColor() {
|
||||
// TODO: MEDIUM: Motor color (settable?)
|
||||
return new Color(0, 0, 0, 200);
|
||||
@ -623,6 +685,35 @@ public class Prefs {
|
||||
}
|
||||
|
||||
|
||||
//// Printing
|
||||
|
||||
public static PrintSettings getPrintSettings() {
|
||||
PrintSettings settings = new PrintSettings();
|
||||
Color c;
|
||||
|
||||
c = parseColor(getString("print.template.fillColor", null));
|
||||
if (c != null) {
|
||||
settings.setTemplateFillColor(c);
|
||||
}
|
||||
|
||||
c = parseColor(getString("print.template.borderColor", null));
|
||||
if (c != null) {
|
||||
settings.setTemplateBorderColor(c);
|
||||
}
|
||||
|
||||
settings.setPaperSize(getEnum("print.paper.size", settings.getPaperSize()));
|
||||
settings.setPaperOrientation(getEnum("print.paper.orientation", settings.getPaperOrientation()));
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
public static void setPrintSettings(PrintSettings settings) {
|
||||
putString("print.template.fillColor", stringifyColor(settings.getTemplateFillColor()));
|
||||
putString("print.template.borderColor", stringifyColor(settings.getTemplateBorderColor()));
|
||||
putEnum("print.paper.size", settings.getPaperSize());
|
||||
putEnum("print.paper.orientation", settings.getPaperOrientation());
|
||||
}
|
||||
|
||||
//// Background flight data computation
|
||||
|
||||
public static boolean computeFlightInBackground() {
|
||||
|
||||
36
test/net/sf/openrocket/gui/print/TestPaperSize.java
Normal file
36
test/net/sf/openrocket/gui/print/TestPaperSize.java
Normal file
@ -0,0 +1,36 @@
|
||||
package net.sf.openrocket.gui.print;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestPaperSize {
|
||||
|
||||
@Test
|
||||
public void testGetDefaultForCountry() {
|
||||
assertEquals(PaperSize.LETTER, PaperSize.getDefaultForCountry("US"));
|
||||
assertEquals(PaperSize.LETTER, PaperSize.getDefaultForCountry("cA"));
|
||||
assertEquals(PaperSize.LETTER, PaperSize.getDefaultForCountry("mx"));
|
||||
|
||||
assertEquals(PaperSize.A4, PaperSize.getDefaultForCountry("FI"));
|
||||
assertEquals(PaperSize.A4, PaperSize.getDefaultForCountry("xy"));
|
||||
|
||||
assertNull(PaperSize.getDefaultForCountry("FIN"));
|
||||
assertNull(PaperSize.getDefaultForCountry("a"));
|
||||
assertNull(PaperSize.getDefaultForCountry("A4"));
|
||||
assertNull(PaperSize.getDefaultForCountry(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSizeFromString() {
|
||||
assertEquals(PaperSize.LETTER, PaperSize.getSizeFromString("Letter"));
|
||||
assertEquals(PaperSize.LEGAL, PaperSize.getSizeFromString(" legal\t"));
|
||||
assertEquals(PaperSize.A4, PaperSize.getSizeFromString(" A4\n"));
|
||||
assertEquals(PaperSize.A3, PaperSize.getSizeFromString("A3"));
|
||||
|
||||
assertNull(PaperSize.getSizeFromString("#A4"));
|
||||
assertNull(PaperSize.getSizeFromString(""));
|
||||
assertNull(PaperSize.getSizeFromString(null));
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user