package net.sourceforge.fidocadj.dialogs.print; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.swing.*; import javax.swing.event.*; import java.io.*; import java.awt.print.*; import javax.imageio.*; import javax.swing.plaf.basic.BasicArrowButton; import net.sourceforge.fidocadj.globals.*; import net.sourceforge.fidocadj.dialogs.mindimdialog.MinimumSizeDialog; import net.sourceforge.fidocadj.dialogs.*; import net.sourceforge.fidocadj.circuit.model.DrawingModel; import net.sourceforge.fidocadj.layers.LayerDesc; /** Choose file format, size and options of the graphic exporting. The class dialogPrint implements a modal dialog to select printing options. <pre> This file is part of FidoCadJ. FidoCadJ is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. FidoCadJ is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with FidoCadJ. If not, @see <a href=http://www.gnu.org/licenses/>http://www.gnu.org/licenses/</a>. Copyright 2007-2015 by Davide Bucci </pre> @author Davide Bucci */ public class DialogPrint extends MinimumSizeDialog { private final JCheckBox mirror_CB; private final JCheckBox fit_CB; private final JCheckBox bw_CB; private final JCheckBox landscape_CB; private final PrintPreview prp; private final JTextField tTopMargin; private final JTextField tBottomMargin; private final JTextField tLeftMargin; private final JTextField tRightMargin; private final JCheckBox onlyLayerCB; private final JLabel pageNum; private final JComboBox<LayerDesc> layerSel; private double maxHorisontalMargin; private double maxVerticalMargin; private boolean oldLandscapeState=false; private int currentLayerSelected=-1; // This contains the number of pages when the drawing is not resized to // fit one page. private int numberOfPages=0; // This contains the current page to be printed. private int currentPage=0; private boolean print; // Indicates that the print should be done /** Standard constructor: it needs the parent frame. @param parent the dialog's parent. @param drawingModel the drawing model to be employed. @param pageDescription the description of the page to be printed. */ public DialogPrint (JFrame parent, DrawingModel drawingModel, PageFormat pageDescription) { super(400,350, parent,Globals.messages.getString("Print_dlg"), true); addComponentListener(this); print=false; final int LCOLUMN=5; final int ECOLUMN=6; // Ensure that under MacOSX >= 10.5 Leopard, this dialog will appear // as a document modal sheet getRootPane().putClientProperty("apple.awt.documentModalSheet", Boolean.TRUE); GridBagLayout bgl=new GridBagLayout(); GridBagConstraints constraints=new GridBagConstraints(); Container contentPane=getContentPane(); contentPane.setLayout(bgl); constraints.insets.right=30; JLabel empty=new JLabel(" "); constraints.weightx=100; constraints.weighty=100; constraints.gridx=0; constraints.gridy=0; constraints.gridwidth=1; constraints.gridheight=1; contentPane.add(empty, constraints); // Add " " label JLabel empty1=new JLabel(" "); constraints.weightx=100; constraints.weighty=100; constraints.gridx=ECOLUMN+2; constraints.gridy=0; constraints.gridwidth=1; constraints.gridheight=1; contentPane.add(empty1, constraints); // Add " " label prp=new PrintPreview(false, pageDescription, this); prp.add(Box.createVerticalStrut(256)); prp.add(Box.createHorizontalStrut(256)); prp.setDrawingModel(drawingModel); constraints.anchor=GridBagConstraints.EAST; constraints.fill=GridBagConstraints.BOTH; constraints.weightx=100; constraints.weighty=100; constraints.gridx=1; constraints.gridy=0; constraints.gridwidth=3; constraints.gridheight=9; constraints.insets = new Insets(10,0,10,0); contentPane.add(prp, constraints); // Print preview! final BasicArrowButton decr = new BasicArrowButton(BasicArrowButton.WEST); numberOfPages=prp.getTotalNumberOfPages(); pageNum=new JLabel(""+(currentPage+1)+"/"+numberOfPages); constraints.anchor=GridBagConstraints.EAST; constraints.fill=GridBagConstraints.BOTH; constraints.weightx=100; constraints.weighty=100; constraints.gridx=2; constraints.gridy=9; constraints.gridwidth=1; constraints.gridheight=1; constraints.insets = new Insets(2,0,0,0); contentPane.add(pageNum, constraints); // Num of pages constraints.anchor=GridBagConstraints.EAST; constraints.fill=GridBagConstraints.BOTH; constraints.weightx=100; constraints.weighty=100; constraints.gridx=1; constraints.gridy=9; constraints.gridwidth=1; constraints.gridheight=1; constraints.insets = new Insets(2,0,0,0); contentPane.add(decr, constraints); // Decrement page decr.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { if(currentPage>0) --currentPage; currentPage=prp.setCurrentPage(currentPage); prp.updatePreview(); prp.repaint(); pageNum.setText(""+(currentPage+1)+"/"+numberOfPages); } }); final BasicArrowButton incr = new BasicArrowButton(BasicArrowButton.EAST); constraints.anchor=GridBagConstraints.EAST; constraints.fill=GridBagConstraints.BOTH; constraints.weightx=100; constraints.weighty=100; constraints.gridx=3; constraints.gridy=9; constraints.gridwidth=1; constraints.gridheight=1; contentPane.add(incr, constraints); // Increment page incr.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { if(currentPage<numberOfPages-1) ++currentPage; currentPage=prp.setCurrentPage(currentPage); prp.updatePreview(); prp.repaint(); pageNum.setText(""+(currentPage+1)+"/"+numberOfPages); } }); if(numberOfPages>1) { incr.setEnabled(true); decr.setEnabled(true); } else { incr.setEnabled(false); decr.setEnabled(false); } JLabel lTopMargin=new JLabel(Globals.messages.getString("TopMargin")); constraints.anchor=GridBagConstraints.WEST; constraints.fill=GridBagConstraints.HORIZONTAL; constraints.weightx=100; constraints.weighty=100; constraints.gridx=ECOLUMN; constraints.gridy=0; constraints.gridwidth=1; constraints.gridheight=1; constraints.insets = new Insets(5,0,0,0); contentPane.add(lTopMargin, constraints); // Top margin label DocumentListener dl=new DocumentListener() { private void patata() { try { double tm=Double.parseDouble(tTopMargin.getText()); double bm=Double.parseDouble(tBottomMargin.getText()); double lm=Double.parseDouble(tLeftMargin.getText()); double rm=Double.parseDouble(tRightMargin.getText()); prp.setMargins(tm,bm,lm,rm); numberOfPages=prp.getTotalNumberOfPages(); currentPage=prp.setCurrentPage(currentPage); prp.updatePreview(); pageNum.setText(""+(currentPage+1)+"/"+numberOfPages); } catch (java.lang.NumberFormatException n) { } prp.repaint(); } public void changedUpdate(DocumentEvent e) { patata(); } public void removeUpdate(DocumentEvent e) { patata(); } public void insertUpdate(DocumentEvent e) { patata(); } }; // The event listener for all those checkboxes ChangeListener updatePreview = new ChangeListener() { public void stateChanged(ChangeEvent changeEvent) { numberOfPages=prp.getTotalNumberOfPages(); /*if(fit_CB.isSelected()) { currentPage = 0; incr.setEnabled(false); decr.setEnabled(false); } else { if(numberOfPages>1) { incr.setEnabled(true); decr.setEnabled(true); } }*/ if(numberOfPages>1) { incr.setEnabled(true); decr.setEnabled(true); } else { incr.setEnabled(false); decr.setEnabled(false); } currentPage=prp.setCurrentPage(currentPage); prp.updatePreview(); prp.repaint(); pageNum.setText(""+(currentPage+1)+"/"+numberOfPages); } }; tTopMargin=new JTextField(10); constraints.weightx=100; constraints.weighty=100; constraints.gridx=LCOLUMN; constraints.gridy=0; constraints.gridwidth=1; constraints.gridheight=1; constraints.insets = new Insets(3,5,0,0); contentPane.add(tTopMargin, constraints); // Top margin text tTopMargin.getDocument().addDocumentListener(dl); JLabel lBottomMargin=new JLabel( Globals.messages.getString("BottomMargin")); constraints.anchor=GridBagConstraints.WEST; constraints.weightx=100; constraints.weighty=100; constraints.gridx=ECOLUMN; constraints.gridy=1; constraints.gridwidth=1; constraints.gridheight=1; constraints.insets = new Insets(0,0,0,0); contentPane.add(lBottomMargin, constraints); // Bottom margin label tBottomMargin=new JTextField(10); Dimension ddmin=tBottomMargin.getMinimumSize(); ddmin.width=100; tBottomMargin.setMinimumSize(ddmin); constraints.weightx=100; constraints.weighty=100; constraints.gridx=LCOLUMN; constraints.gridy=1; constraints.gridwidth=1; constraints.gridheight=1; constraints.insets = new Insets(0,5,0,0); contentPane.add(tBottomMargin, constraints); // Bottom margin text tBottomMargin.getDocument().addDocumentListener(dl); JLabel lLeftMargin=new JLabel(Globals.messages.getString("LeftMargin")); constraints.anchor=GridBagConstraints.WEST; constraints.weightx=100; constraints.weighty=100; constraints.gridx=ECOLUMN; constraints.gridy=2; constraints.gridwidth=1; constraints.gridheight=1; contentPane.add(lLeftMargin, constraints); // Left margin label tLeftMargin=new JTextField(10); constraints.weightx=100; constraints.weighty=100; constraints.gridx=LCOLUMN; constraints.gridy=2; constraints.gridwidth=1; constraints.gridheight=1; contentPane.add(tLeftMargin, constraints); // Left margin text tLeftMargin.getDocument().addDocumentListener(dl); JLabel lRightMargin=new JLabel( Globals.messages.getString("RightMargin")); constraints.anchor=GridBagConstraints.WEST; constraints.weightx=100; constraints.weighty=100; constraints.gridx=ECOLUMN; constraints.gridy=3; constraints.gridwidth=1; constraints.gridheight=1; contentPane.add(lRightMargin, constraints); // Right margin label tRightMargin=new JTextField(10); constraints.weightx=100; constraints.weighty=100; constraints.gridx=LCOLUMN; constraints.gridy=3; constraints.gridwidth=1; constraints.gridheight=1; contentPane.add(tRightMargin, constraints); // Right margin text tRightMargin.getDocument().addDocumentListener(dl); onlyLayerCB=new JCheckBox(Globals.messages.getString( "PrintOnlyLayer")); constraints.gridx=LCOLUMN; constraints.gridy=4; constraints.gridwidth=1; constraints.gridheight=1; constraints.anchor=GridBagConstraints.WEST; contentPane.add(onlyLayerCB, constraints); // Print only 1 layer cb onlyLayerCB.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent changeEvent) { if(onlyLayerCB.isSelected()) { if(layerSel!=null) { layerSel.setEnabled(true); currentLayerSelected=layerSel.getSelectedIndex(); } } else { layerSel.setEnabled(false); } prp.updatePreview(); prp.repaint(); } }); layerSel = new JComboBox<LayerDesc>(drawingModel.getLayers()); layerSel.setRenderer(new LayerCellRenderer()); layerSel.setEnabled(false); constraints.weightx=100; constraints.weighty=100; constraints.gridx=LCOLUMN+1; constraints.gridy=4; constraints.gridwidth=1; constraints.gridheight=1; contentPane.add(layerSel, constraints); // Layer selection layerSel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { if (layerSel.getSelectedIndex()>=0) { currentLayerSelected=layerSel.getSelectedIndex(); if(onlyLayerCB.isSelected()) { prp.updatePreview(); prp.repaint(); } } } }); mirror_CB=new JCheckBox(Globals.messages.getString("Mirror")); constraints.gridx=LCOLUMN; constraints.gridy=5; constraints.gridwidth=2; constraints.gridheight=1; constraints.anchor=GridBagConstraints.WEST; contentPane.add(mirror_CB, constraints); // Add Print Mirror cb mirror_CB.addChangeListener(updatePreview); fit_CB=new JCheckBox(Globals.messages.getString("FitPage")); constraints.gridx=LCOLUMN; constraints.gridy=6; constraints.gridwidth=2; constraints.gridheight=1; constraints.anchor=GridBagConstraints.WEST; contentPane.add(fit_CB, constraints); // Add Fit to page cb fit_CB.addChangeListener(updatePreview); bw_CB=new JCheckBox(Globals.messages.getString("B_W")); constraints.gridx=LCOLUMN; constraints.gridy=7; constraints.gridwidth=2; constraints.gridheight=1; constraints.anchor=GridBagConstraints.WEST; contentPane.add(bw_CB, constraints); // Add BlackWhite cb bw_CB.addChangeListener(updatePreview); landscape_CB=new JCheckBox(Globals.messages.getString("Landscape")); constraints.gridx=LCOLUMN; constraints.gridy=8; constraints.gridwidth=2; constraints.gridheight=1; constraints.anchor=GridBagConstraints.WEST; contentPane.add(landscape_CB, constraints); // Add landscape cb landscape_CB.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent changeEvent) { // If the page was rotated, the margins should be adapted // so they always correspond to the same place in the page. if(!oldLandscapeState && landscape_CB.isSelected()) { String d=tLeftMargin.getText(); tLeftMargin.setText(tBottomMargin.getText()); tBottomMargin.setText(tRightMargin.getText()); tRightMargin.setText(tTopMargin.getText()); tTopMargin.setText(d); } else if(oldLandscapeState && !landscape_CB.isSelected()){ String d=tTopMargin.getText(); tTopMargin.setText(tRightMargin.getText()); tRightMargin.setText(tBottomMargin.getText()); tBottomMargin.setText(tLeftMargin.getText()); tLeftMargin.setText(d); } numberOfPages=prp.getTotalNumberOfPages(); prp.updatePreview(); prp.repaint(); oldLandscapeState=landscape_CB.isSelected(); } }); // Put the OK and Cancel buttons and make them active. JButton ok=new JButton(Globals.messages.getString("Ok_btn")); JButton cancel=new JButton(Globals.messages.getString("Cancel_btn")); constraints.gridx=1; constraints.gridy=10; constraints.gridwidth=7; constraints.gridheight=1; constraints.insets = new Insets(20,0,0,0); //top padding constraints.anchor=GridBagConstraints.EAST; // Put the OK and Cancel buttons and make them active. Box b=Box.createHorizontalBox(); b.add(Box.createHorizontalGlue()); ok.setPreferredSize(cancel.getPreferredSize()); if (Globals.okCancelWinOrder) { b.add(ok); b.add(Box.createHorizontalStrut(12)); b.add(cancel); } else { b.add(cancel); b.add(Box.createHorizontalStrut(12)); b.add(ok); } ok.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { if(validateInput()) { print=true; setVisible(false); } } }); cancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { print=false; setVisible(false); } }); // Here is an action in which the dialog is closed AbstractAction cancelAction = new AbstractAction () { public void actionPerformed (ActionEvent e) { setVisible(false); } }; constraints.insets = new Insets(10,0,10,0); contentPane.add(b, constraints); // Add OK/cancel dialog DialogUtil.addCancelEscape (this, cancelAction); pack(); DialogUtil.center(this); getRootPane().setDefaultButton(ok); } /** Check if the drawing should be mirrored. @return true wether the mirroring should be done. */ public boolean getMirror() { return mirror_CB.isSelected(); } /** Check if the drawing should be fit to the page @return true wether the fitting should be done. */ public boolean getFit() { return fit_CB.isSelected(); } /** Check if the page orientation should be landscape @return true wether the orientation is landscape. */ public boolean getLandscape() { return landscape_CB.isSelected(); } /** Get the layer to be printed if a single layer is what the user need. @return the layer to be printed if greater or equal than 0 or -1 if all layers should be printed. */ public int getSingleLayerToPrint() { if (!onlyLayerCB.isSelected()) return -1; return currentLayerSelected; } /** Check if the black and white checkbox is selected. @return true if the checkbox is active. */ public boolean getBW() { return bw_CB.isSelected(); } /** Set the mirror attribute @param m true if the printout should be done in mirroring mode. */ public void setMirror(boolean m) { mirror_CB.setSelected(m); } /** Set the resize to fit option @param f true if the drawing should be stretched in order to fit the page. */ public void setFit(boolean f) { fit_CB.setSelected(f); } /** Set the landscape mode @param l true if the output should be in landscape mode. It will be in portrait orientation otherwise. */ public void setLandscape(boolean l) { landscape_CB.setSelected(l); oldLandscapeState=l; } /** Set the size of the margins, in centimeters. The orientation of those margins should correspond to the page in the portrait orientation. @param tm top margin. @param bm bottom margin. @param lm left margin. @param rm right margin. */ public void setMargins(double tm, double bm, double lm, double rm) { tTopMargin.setText(Globals.roundTo(tm,3)); tBottomMargin.setText(Globals.roundTo(bm,3)); tLeftMargin.setText(Globals.roundTo(lm,3)); tRightMargin.setText(Globals.roundTo(rm,3)); } /** Check if the input is valid. @return true if the input is valid. */ private boolean validateInput() { double tm; double bm; double lm; double rm; try { tm=Double.parseDouble(tTopMargin.getText()); bm=Double.parseDouble(tBottomMargin.getText()); lm=Double.parseDouble(tLeftMargin.getText()); rm=Double.parseDouble(tRightMargin.getText()); } catch (java.lang.NumberFormatException n) { JOptionPane.showMessageDialog(this, Globals.messages.getString("Format_invalid"), "", JOptionPane.INFORMATION_MESSAGE); return false; } if(tm+bm>=maxVerticalMargin || lm+rm>=maxHorisontalMargin) { JOptionPane.showMessageDialog(this, Globals.messages.getString("Margins_too_large"), "", JOptionPane.INFORMATION_MESSAGE); return false; } return true; } /** Defines the limits for the sum of the horisontal and vertical margins. @param maxhor the limit of the left+right margins (in cm) @param maxvert the limit of the top+bottom margins (in cm) */ public void setMaxMargins(double maxhor, double maxvert) { maxHorisontalMargin=maxhor; maxVerticalMargin=maxvert; } /** Get the size of the top margin, in centimeters. @return the margin size. */ public double getTMargin() { return Double.parseDouble(tTopMargin.getText()); } /** Get the size of the bottom margin, in centimeters. @return the margin size. */ public double getBMargin() { return Double.parseDouble(tBottomMargin.getText()); } /** Get the size of the left margin, in centimeters. @return the margin size. */ public double getLMargin() { return Double.parseDouble(tLeftMargin.getText()); } /** Get the size of the right margin, in centimeters. @return the margin size. */ public double getRMargin() { return Double.parseDouble(tRightMargin.getText()); } /** Print in black and white @param l if true, print in black and white, if false respect the colors associated to the layers. */ public void setBW(boolean l) { bw_CB.setSelected(l); } /** Indicates that the printing should be done: the user selected the "ok" button @return a boolean value which indicates if the printing should be done */ public boolean shouldPrint() { return print; } }