/*
* PrinterDialog.java
*
* Copyright (C) 2016 Dale Anson
* Portions Copyright 2000-2007 Sun Microsystems, Inc.
*
* This program 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 2
* of the License, or any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.gjt.sp.jedit.print;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import javax.swing.*;
import javax.swing.event.*;
import org.gjt.sp.jedit.GUIUtilities;
import org.gjt.sp.jedit.View;
import org.gjt.sp.jedit.browser.VFSBrowser;
import org.gjt.sp.jedit.gui.FontSelector;
import org.gjt.sp.jedit.gui.NumericTextField;
import org.gjt.sp.jedit.gui.VariableGridLayout;
import org.gjt.sp.jedit.jEdit;
import org.gjt.sp.util.GenericGUIUtilities;
// import org.gjt.sp.util.Log;
// Technical guide on the Java printing system:
// https://docs.oracle.com/javase/7/docs/technotes/guides/jps/spec/JPSTOC.fm.html
public class PrinterDialog extends JDialog implements ListSelectionListener
{
private View view;
private String jobName = null;
private PrintService selectedPrintService = null;
private PrintRequestAttributeSet attributes;
private JTabbedPane tabs;
private JList<PrintService> printers;
private JSpinner copies = null;
private JComboBox<String> paperSize;
private List<Media> paperSizes;
private JComboBox<Priority> priority;
private JComboBox<Finishings> finishing;
private JComboBox<Sides> sides;
private JComboBox<NumberUp> pagesPerSide;
private JComboBox<PresentationDirection> pageOrdering;
private JComboBox<MediaTray> paperSource;
private JComboBox<OrientationRequested> orientation;
private boolean pageSetupOnly;
private boolean canceled = false;
private Map<String, String> messageMap;
private PageSetupPanel pageSetupPanel;
public static int ALL = 0;
public static int ODD = 1;
public static int EVEN = 2;
public static int RANGE = 3;
public static int CURRENT_PAGE = 4;
public static int SELECTION = 5;
public static int onlyPrintPages = ALL;
private int printRangeType = ALL;
private DocFlavor DOC_FLAVOR = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
private boolean reversePrinting = false;
public PrinterDialog( View owner, PrintRequestAttributeSet attributes, boolean pageSetupOnly )
{
super( owner, Dialog.ModalityType.APPLICATION_MODAL );
try
{
view = owner;
this.pageSetupOnly = pageSetupOnly;
setTitle( pageSetupOnly ? jEdit.getProperty( "print.dialog.pageSetupTitle" ) : jEdit.getProperty( "print.dialog.title" ) );
if ( attributes != null )
{
this.attributes = new HashPrintRequestAttributeSet( attributes );
}
else
{
this.attributes = new HashPrintRequestAttributeSet();
}
Attribute jobNameAttr = this.attributes.get( JobName.class );
if ( jobNameAttr != null )
{
jobName = jobNameAttr.toString();
}
this.attributes.remove( Destination.class );
Attribute[] attrs = attributes.toArray();
// for debugging
/*
* for ( Attribute a : attrs )
* {
* Log.log( Log.DEBUG, this, "+++++ before: " + a.getName() + " = " + a );
* }
*/
initMessages();
JPanel contents = new JPanel( new BorderLayout() );
contents.setBorder( BorderFactory.createEmptyBorder( 11, 11, 12, 12 ) );
tabs = new JTabbedPane();
tabs.setBorder( BorderFactory.createEmptyBorder( 0, 0, 11, 0 ) );
tabs.add( jEdit.getProperty( "print.dialog.General", "General" ), new GeneralPanel() );
tabs.add( jEdit.getProperty( "print.dialog.Page_Setup", "Page Setup" ), pageSetupPanel = new PageSetupPanel() );
tabs.add( jEdit.getProperty( "print.dialog.Job", "Job" ), new JobPanel() );
tabs.add( jEdit.getProperty( "print.dialog.Advanced", "Advanced" ), new AdvancedPanel() );
tabs.add( jEdit.getProperty( "print.dialog.jEdit", "jEdit" ), new jEditPanel() );
if ( pageSetupOnly )
{
tabs.setSelectedIndex( 1 );
tabs.setEnabledAt( 0, false );
tabs.setEnabledAt( 1, true );
tabs.setEnabledAt( 2, false );
tabs.setEnabledAt( 3, false );
tabs.setEnabledAt( 4, false );
}
contents.add( tabs, BorderLayout.CENTER );
JButton previewButton = new JButton( jEdit.getProperty( "print.dialog.preview", "Preview" ) );
previewButton.addActionListener( getPreviewButtonListener() );
JButton okButton = new JButton( jEdit.getProperty( "common.ok" ) );
okButton.addActionListener( getOkButtonListener() );
JButton cancelButton = new JButton( jEdit.getProperty( "common.cancel" ) );
cancelButton.addActionListener( getCancelButtonListener() );
JPanel buttonPanel = new JPanel( new FlowLayout( FlowLayout.RIGHT, 6, 6 ) );
GenericGUIUtilities.makeSameSize( previewButton, okButton, cancelButton );
buttonPanel.add( previewButton );
buttonPanel.add( okButton );
buttonPanel.add( cancelButton );
contents.add( buttonPanel, BorderLayout.SOUTH );
setContentPane( contents );
// auto-select the default printer
PrintService defaultPrintService = PrintServiceLookup.lookupDefaultPrintService();
if ( defaultPrintService != null )
{
printers.setSelectedValue( defaultPrintService, true );
}
else
{
printers.setSelectedIndex( 0 );
}
// loads some default values if needed
valueChanged( null );
// set margin values, need to do this here after the other values have been set
pageSetupPanel.setDefaultMargins();
pack();
setLocationRelativeTo( jEdit.getActiveView().getTextArea() );
setVisible( true );
}
catch ( Exception e )
{
e.printStackTrace();
}
}
private ActionListener getPreviewButtonListener()
{
return new ActionListener()
{
public void actionPerformed( ActionEvent ae )
{
// check margins and so on
String checkMarginsMessage = pageSetupPanel.recalculate();
if ( checkMarginsMessage != null )
{
JOptionPane.showMessageDialog( PrinterDialog.this, checkMarginsMessage, jEdit.getProperty( "print-error.title" ), JOptionPane.ERROR_MESSAGE );
return;
}
// gather all the attributes from the tabs
for ( int i = 0; i < tabs.getTabCount(); i++ )
{
PrinterPanel panel = ( PrinterPanel )tabs.getComponentAt( i );
AttributeSet panelAttributes = panel.getAttributes();
if (panelAttributes != null)
{
PrinterDialog.this.attributes.addAll( attributes );
}
}
// adjust the print range to filter based on odd/even pages
PageRanges pr = ( PageRanges )PrinterDialog.this.attributes.get( PageRanges.class );
try
{
PageRanges mergedRanges = mergeRanges( pr );
if (mergedRanges != null)
{
PrinterDialog.this.attributes.add( mergedRanges );
}
}
catch ( PrintException e )
{
e.printStackTrace();
JOptionPane.showMessageDialog( PrinterDialog.this, jEdit.getProperty( "print-error.message", new String[] {e.getMessage()} ), jEdit.getProperty( "print-error.title" ), JOptionPane.ERROR_MESSAGE );
return;
}
new PrintPreview( view, view.getBuffer(), PrinterDialog.this.getPrintService(), PrinterDialog.this.attributes );
}
};
}
private ActionListener getOkButtonListener()
{
return new ActionListener()
{
public void actionPerformed( ActionEvent ae )
{
// check margins and so on
String checkMarginsMessage = pageSetupPanel.recalculate();
if ( checkMarginsMessage != null )
{
JOptionPane.showMessageDialog( PrinterDialog.this, checkMarginsMessage, jEdit.getProperty( "print-error.title" ), JOptionPane.ERROR_MESSAGE );
return;
}
// gather all the attributes from the tabs
for ( int i = 0; i < tabs.getTabCount(); i++ )
{
PrinterPanel panel = ( PrinterPanel )tabs.getComponentAt( i );
AttributeSet panelAttributes = panel.getAttributes();
if (panelAttributes != null)
{
PrinterDialog.this.attributes.addAll( attributes );
}
}
// adjust the print range to filter based on odd/even pages
PageRanges pr = ( PageRanges )PrinterDialog.this.attributes.get( PageRanges.class );
try
{
PageRanges mergedRanges = mergeRanges( pr );
if (mergedRanges != null)
{
PrinterDialog.this.attributes.add( mergedRanges );
}
}
catch ( PrintException e )
{
e.printStackTrace();
JOptionPane.showMessageDialog( PrinterDialog.this, jEdit.getProperty( "print-error.message", new String[] {e.getMessage()} ), jEdit.getProperty( "print-error.title" ), JOptionPane.ERROR_MESSAGE );
return;
}
// if printing to a file, get the filename to use
if ( !pageSetupOnly && getPrintService() instanceof StreamPrintService )
{
// create default filename
String filename = "out";
if ( jobName != null )
{
File f = new File( jobName );
filename = f.getName();
}
filename = new StringBuilder( filename ).append( ".ps" ).toString();
File initialFile = new File( System.getProperty( "user.home" ), filename );
// show file chooser
String[] files = GUIUtilities.showVFSFileDialog( PrinterDialog.this, view, initialFile.getAbsolutePath(), VFSBrowser.SAVE_DIALOG, false );
if ( files != null && files.length > 0 )
{
File file = new File( files[0] );
selectedPrintService = getPostscriptPrintService( file );
}
else
{
return;
}
}
// for debugging
/*
* Attribute[] attrs = PrinterDialog.this.attributes.toArray();
* for ( Attribute a : attrs )
* {
* Log.log( Log.DEBUG, this, "+++++ after: " + a.getName() + " = " + a );
* }
*/
PrinterDialog.this.setVisible( false );
PrinterDialog.this.dispose();
}
};
}
private ActionListener getCancelButtonListener()
{
return new ActionListener()
{
public void actionPerformed( ActionEvent ae )
{
PrinterDialog.this.setVisible( false );
PrinterDialog.this.dispose();
canceled = true;
}
};
}
/**
* @return The print service selected by the user.
*/
public PrintService getPrintService()
{
return selectedPrintService;
}
/**
* @return An attribute set containing all the values as selected by the user.
*/
public PrintRequestAttributeSet getAttributes()
{
return attributes;
}
/**
* @return <code>true</code> if the user clicked the 'cancel' button.
*/
public boolean isCanceled()
{
return canceled;
}
/**
* @return <code>true</code> if the pages should be printed in reverse order,
* that is, the last page is printed first and the first page is printed last.
*/
public boolean getReverse()
{
return reversePrinting;
}
/**
* @returns One of ALL, RANGE, CURRENT, or SELECTION, depending on whether the
* user has elected to print all pages, a range of pages, just the current page
* or just the selected text.
*/
public int getPrintRangeType()
{
return printRangeType;
}
private PrintService[] getPrintServices()
{
PrintService[] printServices = PrintServiceLookup.lookupPrintServices( DOC_FLAVOR, null );
List<PrintService> services = new ArrayList<PrintService>( Arrays.asList( printServices ) );
PrintService service = getPostscriptPrintService( null );
if ( service != null )
{
services.add( service );
}
printServices = services.toArray( new PrintService [0] );
return printServices;
}
private StreamPrintService getPostscriptPrintService( File outfile )
{
if ( outfile == null )
{
outfile = new File( System.getProperty( "user.home" ), "out.ps" );
}
String mimetype = "application/postscript";
StreamPrintServiceFactory[] factories = StreamPrintServiceFactory.lookupStreamPrintServiceFactories( DOC_FLAVOR, mimetype );
FileOutputStream fos;
StreamPrintService printService = null;
if ( factories.length > 0 )
{
try
{
fos = new FileOutputStream( outfile );
printService = factories[0].getPrintService( fos );
}
catch ( Exception e )
{
return null;
}
}
return printService;
}
// finds the intersection of the pages selected in the General tab (All pages
// or a page range) with the all, odd, or even setting for the 'only print'
// setting in the Page Setup tab.
private PageRanges mergeRanges( PageRanges pr ) throws PrintException
{
if ( pr == null || onlyPrintPages == ALL )
{
return pr;
}
List<Integer> pages = new ArrayList<Integer>();
int[][] ranges = pr.getMembers();
for ( int i = 0; i < ranges.length; i++ )
{
int[] range = ranges[i];
int start = range[0];
// this limits printing to the first 250 pages. If the user selects 'All pages'
// from the General tab, then the range is 1 to Integer.MAX_VALUE, so to print just
// the even or odd numbered pages would need an array of 1073741823 values, which
// is unreasonable.
int end = range.length == 1 ? range[0] : Math.min( range[0] + 500, range[1] );
for ( int pageIndex = start; pageIndex <= end; pageIndex++ )
{
if ( pageIndex % 2 == 0 && onlyPrintPages == EVEN )
{
pages.add( pageIndex );
}
else
if ( pageIndex % 2 == 1 && onlyPrintPages == ODD )
{
pages.add( pageIndex );
}
}
}
if ( pages.isEmpty() )
{
throw new PrintException( "No pages are selected to print.\nPlease check the 'Range' setting on the General tab and\nthe 'Only print' setting on the Page Setup tab." );
}
StringBuilder sb = new StringBuilder();
for ( Integer page : pages )
{
sb.append( page ).append( ',' );
}
sb.deleteCharAt( sb.length() - 1 );
return new PageRanges( sb.toString() );
}
@SuppressWarnings( {"unchecked"} )
public void valueChanged( ListSelectionEvent e )
{
selectedPrintService = printers.getSelectedValue();
// get the supported attribute categories and values
Map<Class, Object> categoryValueMap = new HashMap<Class, Object>();
Class<?>[] classes = selectedPrintService.getSupportedAttributeCategories();
for ( Class c : classes )
{
Object values = selectedPrintService.getSupportedAttributeValues( c, DocFlavor.SERVICE_FORMATTED.PRINTABLE, null );
categoryValueMap.put( c, values );
}
// set range for number of copies
SpinnerNumberModel copiesModel = new SpinnerNumberModel( 1, 1, 999, 1 );
Object value = categoryValueMap.get( Copies.class );
if ( value != null )
{
String maxCopies = value.toString();
if ( maxCopies.indexOf( '-' ) > 0 )
{
maxCopies = maxCopies.substring( maxCopies.indexOf( '-' ) + 1 );
}
copiesModel = new SpinnerNumberModel( 1, 1, ( int )Integer.valueOf( maxCopies ), 1 );
}
copies.setModel( copiesModel );
// paper sizes
value = categoryValueMap.get( Media.class );
Set<MediaSizeName> sizeNames = new HashSet<MediaSizeName>();
for ( Media m : ( Media[] )value )
{
if ( m instanceof MediaSizeName )
{
sizeNames.add( ( MediaSizeName )m );
}
}
MediaSizeName[] sizes = sizeNames.toArray( new MediaSizeName [sizeNames.size()] );
Arrays.sort( sizes, new Comparator<MediaSizeName>()
{
public int compare( MediaSizeName a, MediaSizeName b )
{
return a.toString().compareTo( b.toString() );
}
} );
Media previousPaper = ( Media )attributes.get( Media.class );
MediaSizeName previousSize = null;
if ( previousPaper instanceof MediaSizeName )
{
previousSize = ( MediaSizeName )previousPaper;
}
String[] paperNames = new String [sizes.length];
paperSizes = new ArrayList<Media>();
int index = -1;
int letterSizeIndex = 0;
for ( int i = 0; i < sizes.length; i++ )
{
MediaSizeName m = sizes[i];
if ( MediaSizeName.NA_LETTER.equals( m ) )
{
letterSizeIndex = i;
}
else
if ( m.equals( previousSize ) )
{
index = i;
}
paperSizes.add( m );
paperNames[i] = getMessage( m.toString() );
}
index = index == -1 ? letterSizeIndex : index;
paperSize.setModel( new DefaultComboBoxModel<String>( paperNames ) );
paperSize.setEnabled( true );
paperSize.setSelectedIndex( index );
// finishing
value = categoryValueMap.get( Finishings.class );
if ( value == null )
{
finishing.setModel( new DefaultComboBoxModel<Finishings>() );
finishing.setEnabled( false );
}
else
{
Finishings[] finishings = ( Finishings[] )value;
if ( finishings.length == 0 || ( finishings.length == 1 && Finishings.NONE.equals( finishings[0] ) ) )
{
finishing.setModel( new DefaultComboBoxModel<Finishings>() );
finishing.setEnabled( false );
}
else
{
finishing.setModel( new DefaultComboBoxModel<Finishings>( finishings ) );
finishing.setEnabled( true );
}
}
// sides
value = categoryValueMap.get( Sides.class );
if ( value == null )
{
sides.setEnabled( false );
}
else
{
sides.setModel( new DefaultComboBoxModel<Sides>( ( Sides[] )value ) );
Sides previousSides = ( Sides )attributes.get( Sides.class );
sides.setSelectedItem( previousSides == null ? Sides.ONE_SIDED : previousSides );
sides.setEnabled( true );
}
// pages per side
value = categoryValueMap.get( NumberUp.class );
if ( value == null )
{
pagesPerSide.setEnabled( false );
}
else
{
NumberUp[] numberUp = ( NumberUp[] )value;
Arrays.sort( numberUp, new Comparator<NumberUp>()
{
public int compare( NumberUp a, NumberUp b )
{
int m = a.getValue();
int n = b.getValue();
if ( m < n )
{
return -1;
}
else
if ( m == n )
{
return 0;
}
else
{
return 1;
}
}
} );
pagesPerSide.setModel( new DefaultComboBoxModel<NumberUp>( numberUp ) );
pagesPerSide.setEnabled( true );
}
// ordering of pages per side
value = categoryValueMap.get( PresentationDirection.class );
if ( value == null )
{
pageOrdering.setEnabled( false );
}
else
{
PresentationDirection[] po = ( PresentationDirection[] )value;
pageOrdering.setModel( new DefaultComboBoxModel<PresentationDirection>( po ) );
pageOrdering.setEnabled( true );
}
// paper source tray
value = categoryValueMap.get( Media.class );
if ( value == null )
{
paperSource.setEnabled( false );
}
else
{
Set<MediaTray> trayNames = new HashSet<MediaTray>();
for ( Media m : ( Media[] )value )
{
if ( m instanceof MediaTray )
{
trayNames.add( ( MediaTray )m );
}
}
if ( trayNames.size() > 0 )
{
MediaTray[] trays = trayNames.toArray( new MediaTray [trayNames.size()] );
paperSource.setModel( new DefaultComboBoxModel<MediaTray>( trays ) );
paperSource.setEnabled( true );
}
else
{
paperSource.setEnabled( false );
}
}
// orientation, eg. portrait or landscape
value = categoryValueMap.get( OrientationRequested.class );
if ( value == null )
{
orientation.setEnabled( false );
}
else
{
OrientationRequested[] or = ( OrientationRequested[] )value;
orientation.setModel( new DefaultComboBoxModel<OrientationRequested>( or ) );
orientation.setEnabled( true );
OrientationRequested previousOrientation = ( OrientationRequested )attributes.get( OrientationRequested.class );
orientation.setSelectedItem( previousOrientation == null ? OrientationRequested.PORTRAIT : previousOrientation );
}
}
private abstract class PrinterPanel extends JPanel
{
public PrinterPanel()
{
super( new BorderLayout() );
setBorder( BorderFactory.createEmptyBorder( 11, 11, 11, 11 ) );
}
abstract AttributeSet getAttributes()
;
}
private class GeneralPanel extends PrinterPanel
{
JRadioButton allPages;
JRadioButton pages;
JRadioButton currentPage;
JRadioButton selection;
JCheckBox collate;
JCheckBox reverse;
JTextField pagesField;
// TODO: current page and selection are not implemented yet. Note there
// are no standard printer attributes to specify either of these.
public GeneralPanel()
{
super();
printers = new JList<PrintService>( getPrintServices() );
printers.setCellRenderer( new PrintServiceCellRenderer() );
printers.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
printers.addListSelectionListener( PrinterDialog.this );
selectedPrintService = printers.getModel().getElementAt( 0 );
JPanel rangePanel = new JPanel( new GridLayout( 4, 2, 6, 6 ) );
rangePanel.setBorder( BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), jEdit.getProperty( "print.dialog.Range", "Range" ) ),
BorderFactory.createEmptyBorder( 11, 11, 11, 11 ) ) );
allPages = new JRadioButton( jEdit.getProperty( "print.dialog.All_pages", "All pages" ) );
allPages.setSelected( true );
allPages.addActionListener( new ActionListener()
{
public void actionPerformed( ActionEvent ae )
{
pagesField.setEnabled( pages.isSelected() );
}
}
);
pages = new JRadioButton( jEdit.getProperty( "print.dialog.Pages", "Pages" ) + ':' );
pagesField = new JTextField();
pagesField.setEnabled( false );
pages.addActionListener( new ActionListener()
{
public void actionPerformed( ActionEvent ae )
{
pagesField.setEnabled( pages.isSelected() );
}
}
);
currentPage = new JRadioButton( jEdit.getProperty( "print.dialog.Current_page", "Current page" ) );
selection = new JRadioButton( jEdit.getProperty( "print.dialog.Selection", "Selection" ) );
new MyButtonGroup( allPages, pages, currentPage, selection );
Box pagesBox = Box.createHorizontalBox();
pagesBox.add( pages );
pagesBox.add( Box.createHorizontalStrut( 6 ) );
pagesBox.add( pagesField );
rangePanel.add( allPages );
rangePanel.add( Box.createGlue() );
rangePanel.add( pagesBox );
rangePanel.add( Box.createGlue() );
rangePanel.add( currentPage );
rangePanel.add( Box.createGlue() );
rangePanel.add( selection );
JPanel copiesPanel = new JPanel( new GridLayout( 3, 2, 6, 6 ) );
copiesPanel.setBorder( BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), jEdit.getProperty( "print.dialog.Copies", "Copies" ) ),
BorderFactory.createEmptyBorder( 11, 11, 11, 11 ) ) );
JLabel copiesLabel = new JLabel( jEdit.getProperty( "print.dialog.Copies", "Copies" + ':' ) );
copies = new JSpinner( new SpinnerNumberModel( 1, 1, 999, 1 ) );
copies.addChangeListener( new ChangeListener()
{
public void stateChanged( ChangeEvent e )
{
JSpinner spinner = ( JSpinner )e.getSource();
int value = ( int )spinner.getValue();
collate.setEnabled( value > 1 );
collate.setSelected( value > 1 );
}
} );
collate = new JCheckBox( jEdit.getProperty( "print.dialog.Collate", "Collate" ) );
collate.setSelected( false );
collate.setEnabled( false );
reverse = new JCheckBox( jEdit.getProperty( "print.dialog.Reverse", "Reverse" ) );
reverse.setSelected( false );
reverse.setEnabled( true );
copiesPanel.add( copiesLabel );
copiesPanel.add( copies );
copiesPanel.add( collate );
copiesPanel.add( Box.createGlue() );
copiesPanel.add( reverse );
JPanel content = new JPanel( new BorderLayout() );
JPanel top = new JPanel( new BorderLayout() );
JPanel bottom = new JPanel( new GridLayout( 1, 2, 6, 6 ) );
top.add( new JScrollPane( printers ), BorderLayout.CENTER );
bottom.add( rangePanel );
bottom.add( copiesPanel );
content.add( top, BorderLayout.CENTER );
content.add( bottom, BorderLayout.SOUTH );
add( content );
}
public AttributeSet getAttributes()
{
AttributeSet as = new HashAttributeSet();
if ( allPages.isSelected() )
{
as.add( new PageRanges( 1, 1000 ) );
printRangeType = ALL;
}
else
if ( pages.isSelected() )
{
String pageRange = pagesField.getText();
if ( pageRange != null )
{
try
{
as.add( new PageRanges( pageRange ) );
}
catch ( Exception e )
{
e.printStackTrace();
}
}
printRangeType = RANGE;
}
else
if ( currentPage.isSelected() )
{
as.add( new PageRanges( 1 ) );
printRangeType = CURRENT_PAGE;
}
else
if ( selection.isSelected() )
{
as.add( new PageRanges( 1, 1000 ) );
printRangeType = SELECTION;
}
if ( collate.isSelected() )
{
as.add( SheetCollate.COLLATED );
}
as.add( new Copies( ( Integer )copies.getValue() ) );
reversePrinting = reverse.isSelected();
return as;
}
// print service cell renderer
class PrintServiceCellRenderer extends JLabel implements ListCellRenderer <PrintService>
{
public PrintServiceCellRenderer()
{
setOpaque( true );
}
public Component getListCellRendererComponent( JList<? extends PrintService> list,
PrintService value,
int index,
boolean isSelected,
boolean cellHasFocus )
{
setText( value == null ? "" : value.getName() );
Color background;
Color foreground;
if ( isSelected )
{
background = jEdit.getColorProperty( "view.selectionColor" );
foreground = jEdit.getColorProperty( "view.fgColor" );
}
else
{
background = jEdit.getColorProperty( "view.bgColor" );
foreground = jEdit.getColorProperty( "view.fgColor" );
}
setBackground( background );
setForeground( foreground );
Dimension d = new Dimension( ( int )getSize().getWidth(), ( int )getSize().getHeight() + 5 );
setSize( d );
return this;
}
}
}
private class PageSetupPanel extends PrinterPanel
{
private JComboBox<String> onlyPrint;
private JComboBox<String> outputTray;
NumericTextField topMarginField;
NumericTextField leftMarginField;
NumericTextField rightMarginField;
NumericTextField bottomMarginField;
public PageSetupPanel()
{
super();
JPanel layoutPanel = new JPanel( new VariableGridLayout( VariableGridLayout.FIXED_NUM_COLUMNS, 2, 6, 6 ) );
layoutPanel.setBorder( BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), jEdit.getProperty( "print.dialog.Layout", "Layout" ) ), BorderFactory.createEmptyBorder( 11, 11, 11, 11 ) ) );
sides = new JComboBox<Sides>();
sides.setEnabled( false );
sides.setRenderer( new SidesCellRenderer() );
pagesPerSide = new JComboBox<NumberUp>();
pagesPerSide.setEnabled( false );
pagesPerSide.addActionListener( new ActionListener()
{
public void actionPerformed( ActionEvent ae )
{
NumberUp nu = ( NumberUp )pagesPerSide.getSelectedItem();
if ( nu != null && nu.getValue() == 1 )
{
pageOrdering.setEnabled( false );
}
}
}
);
// disable this when pagesPerSide is 1
pageOrdering = new JComboBox<PresentationDirection>();
pageOrdering.setEnabled( false );
onlyPrint = new JComboBox<String>();
onlyPrint.addItem( jEdit.getProperty( "print.dialog.All_sheets", "All sheets" ) ); // ALL
onlyPrint.addItem( jEdit.getProperty( "print.dialog.Odd_sheets", "Odd sheets" ) ); // ODD
onlyPrint.addItem( jEdit.getProperty( "print.dialog.Even_sheets", "Even sheets" ) ); // EVEN
onlyPrint.setSelectedIndex( 0 );
onlyPrint.setEnabled( true );
// TODO: scale?
layoutPanel.add( new JLabel( jEdit.getProperty( "print.dialog.Two-sided", "Two-sided" ) + ':' ) );
layoutPanel.add( sides );
layoutPanel.add( new JLabel( jEdit.getProperty( "print.dialog.Pages_per_side", "Pages per side" ) + ':' ) );
layoutPanel.add( pagesPerSide );
layoutPanel.add( new JLabel( jEdit.getProperty( "print.dialog.Page_ordering", "Page ordering" ) + ':' ) );
layoutPanel.add( pageOrdering );
layoutPanel.add( new JLabel( jEdit.getProperty( "print.dialog.Only_print", "Only print" ) + ':' ) );
layoutPanel.add( onlyPrint );
JPanel paperPanel = new JPanel( new VariableGridLayout( VariableGridLayout.FIXED_NUM_COLUMNS, 2, 6, 6 ) );
paperPanel.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), jEdit.getProperty( "print.dialog.Paper", "Paper" ) ), BorderFactory.createEmptyBorder( 11, 11, 11, 11 ) ) );
paperSource = new JComboBox<MediaTray>();
paperSource.setEnabled( false );
outputTray = new JComboBox<String>();
outputTray.setEnabled( false );
paperSize = new JComboBox<String>();
paperSize.setEnabled( false );
paperSize.addActionListener( new ActionListener()
{
public void actionPerformed( ActionEvent ae )
{
PageSetupPanel.this.setDefaultMargins();
}
}
);
orientation = new JComboBox<OrientationRequested>();
orientation.setEnabled( false );
orientation.setRenderer( new OrientationCellRenderer() );
orientation.addActionListener( new ActionListener()
{
public void actionPerformed( ActionEvent ae )
{
PageSetupPanel.this.setDefaultMargins();
}
}
);
paperPanel.add( new JLabel( jEdit.getProperty( "print.dialog.Paper_source", "Paper source" ) + ':' ) );
paperPanel.add( paperSource );
paperPanel.add( new JLabel( jEdit.getProperty( "print.dialog.Output_tray", "Output tray" ) + ':' ) );
paperPanel.add( outputTray );
paperPanel.add( new JLabel( jEdit.getProperty( "print.dialog.Paper_size", "Paper size" ) + ':' ) );
paperPanel.add( paperSize );
paperPanel.add( new JLabel( jEdit.getProperty( "print.dialog.Orientation", "Orientation" ) + ':' ) );
paperPanel.add( orientation );
JPanel marginPanel = new JPanel( new VariableGridLayout( VariableGridLayout.FIXED_NUM_COLUMNS, 2, 6, 6 ) );
marginPanel.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), jEdit.getProperty( "print.dialog.Margins", "Margins" ) ), BorderFactory.createEmptyBorder( 11, 11, 11, 11 ) ) );
boolean unitIsMM = getUnits() == MediaPrintableArea.MM;
topMarginField = new NumericTextField( "", true, unitIsMM );
leftMarginField = new NumericTextField( "", true, unitIsMM );
rightMarginField = new NumericTextField( "", true, unitIsMM );
bottomMarginField = new NumericTextField( "", true, unitIsMM );
String unitsLabel = unitIsMM ? " (mm)" : " (in)";
marginPanel.add( new JLabel( jEdit.getProperty( "print.dialog.Top", "Top" ) + unitsLabel ) );
marginPanel.add( topMarginField );
marginPanel.add( new JLabel( jEdit.getProperty( "print.dialog.Left", "Left" ) + unitsLabel ) );
marginPanel.add( leftMarginField );
marginPanel.add( new JLabel( jEdit.getProperty( "print.dialog.Right", "Right" ) + unitsLabel ) );
marginPanel.add( rightMarginField );
marginPanel.add( new JLabel( jEdit.getProperty( "print.dialog.Bottom", "Bottom" ) + unitsLabel ) );
marginPanel.add( bottomMarginField );
JPanel finishingPanel = new JPanel( new FlowLayout( FlowLayout.LEFT ) );
finishingPanel.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), jEdit.getProperty( "print.dialog.Finishing", "Finishing" ) ), BorderFactory.createEmptyBorder( 11, 11, 11, 11 ) ) );
finishing = new JComboBox<Finishings>();
finishing.setEnabled( false );
finishing.setRenderer( new FinishingCellRenderer() );
Box finishingBox = Box.createHorizontalBox();
finishingBox.add( new JLabel( jEdit.getProperty( "print.dialog.Finishing", "Finishing" ) + ':' ) );
finishingBox.add( Box.createHorizontalStrut( 6 ) );
finishingBox.add( finishing );
finishingPanel.add( finishingBox );
JPanel content = new JPanel( new VariableGridLayout( VariableGridLayout.FIXED_NUM_COLUMNS, 2, 6, 6 ) );
content.add( layoutPanel );
content.add( paperPanel );
content.add( marginPanel );
content.add( finishingPanel );
add( content );
}
// sides renderer
class SidesCellRenderer extends JLabel implements ListCellRenderer <Sides>
{
public SidesCellRenderer()
{
setOpaque( true );
}
public Component getListCellRendererComponent( JList<? extends Sides> list,
Sides value,
int index,
boolean isSelected,
boolean cellHasFocus )
{
setText( value == null ? "" : getMessage( value.toString() ) );
return this;
}
}
// orientation renderer
class OrientationCellRenderer extends JLabel implements ListCellRenderer <OrientationRequested>
{
public OrientationCellRenderer()
{
setOpaque( true );
}
public Component getListCellRendererComponent( JList<? extends OrientationRequested> list,
OrientationRequested value,
int index,
boolean isSelected,
boolean cellHasFocus )
{
setText( value == null ? "" : getMessage( value.toString() ) );
return this;
}
}
// finishing renderer
class FinishingCellRenderer extends JLabel implements ListCellRenderer <Finishings>
{
public FinishingCellRenderer()
{
setOpaque( true );
}
public Component getListCellRendererComponent( JList<? extends Finishings> list,
Finishings value,
int index,
boolean isSelected,
boolean cellHasFocus )
{
setText( value == null ? "" : getMessage( value.toString() ) );
return this;
}
}
public AttributeSet getAttributes()
{
AttributeSet as = new HashAttributeSet();
if ( sides.isEnabled() )
{
as.add( ( Sides )sides.getSelectedItem() );
}
if ( pagesPerSide.isEnabled() )
{
as.add( ( NumberUp )pagesPerSide.getSelectedItem() );
}
if ( pageOrdering.isEnabled() )
{
as.add( ( PresentationDirection )pageOrdering.getSelectedItem() );
}
onlyPrintPages = onlyPrint.getSelectedIndex();
if ( paperSource.isEnabled() )
{
as.add( ( MediaTray )paperSource.getSelectedItem() );
}
if ( paperSize.isEnabled() )
{
as.add( paperSizes.get( paperSize.getSelectedIndex() ) );
}
if ( orientation.isEnabled() )
{
as.add( ( OrientationRequested )orientation.getSelectedItem() );
}
float topMargin = topMarginField.getValue().floatValue();
float leftMargin = leftMarginField.getValue().floatValue();
float rightMargin = rightMarginField.getValue().floatValue();
float bottomMargin = bottomMarginField.getValue().floatValue();
Margins margins = new Margins( topMargin, leftMargin, rightMargin, bottomMargin );
as.add( margins );
return as;
}
// recalculates the media printable area when the printer, paper size,
// margin, or orientation changes
// returns null on okay, error message otherwise
protected String recalculate()
{
if ( !PrinterDialog.this.isShowing() )
{
return null;
}
// get the printable area for the selected paper size and orientation
int units = getUnits();
MediaPrintableArea supportedArea = getSupportedPrintableArea();
// Log.log( Log.DEBUG, this, "supportedArea = " + supportedArea.getX( units ) + ", " + supportedArea.getY( units ) + ", " + supportedArea.getWidth( units ) + ", " + supportedArea.getHeight( units ) );
// get the selected paper size
Media media = paperSizes.get( paperSize.getSelectedIndex() );
// get paper width and height
MediaSize mediaSize = null;
if ( media instanceof MediaSizeName )
{
MediaSizeName name = ( MediaSizeName )media;
mediaSize = MediaSize.getMediaSizeForName( name );
}
float paperWidth = mediaSize.getX( units );
float paperHeight = mediaSize.getY( units );
// get the user desired margins
float topMargin = topMarginField.getValue().floatValue();
float leftMargin = leftMarginField.getValue().floatValue();
float rightMargin = rightMarginField.getValue().floatValue();
float bottomMargin = bottomMarginField.getValue().floatValue();
// get the selected orientation and adjust the margins and width/height
OrientationRequested orientationRequested = ( OrientationRequested )orientation.getSelectedItem();
rotateMargins( topMargin, leftMargin, rightMargin, bottomMargin, orientationRequested );
// calculate new printable area
float x = leftMargin;
float y = topMargin;
float width = paperWidth - leftMargin - rightMargin;
float height = paperHeight - topMargin - bottomMargin;
// check that the new printable area fits inside the supported area
if ( x < supportedArea.getX( units ) )
{
return jEdit.getProperty( "print.dialog.error.Invalid_left_margin", "Invalid left margin." );
}
if ( y < supportedArea.getY( units ) )
{
return jEdit.getProperty( "print.dialog.error.Invalid_top_margin", "Invalid top margin." );
}
if ( width <= 0 || x + width > supportedArea.getX( units ) + supportedArea.getWidth( units ) )
{
return jEdit.getProperty( "print.dialog.error.Invalid_left_andor_right_margin.", "Invalid left and/or right margin." );
}
if ( height <= 0 || y + height > supportedArea.getY( units ) + supportedArea.getHeight( units ) )
{
return jEdit.getProperty( "print.dialog.error.Invalid_top_andor_bottom_margin", "Invalid top and/or bottom margin." );
}
// Log.log( Log.DEBUG, this, "new printable area: " + x + ", " + y + ", " + width + ", " + height );
MediaPrintableArea area = new MediaPrintableArea( x, y, width, height, units );
attributes.add( area );
return null;
}
private MediaPrintableArea getSupportedPrintableArea()
{
MediaPrintableArea supportedArea = null;
HashPrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet();
if ( paperSizes != null )
{
attrs.add( paperSizes.get( paperSize.getSelectedIndex() ) );
}
if ( orientation != null && orientation.getSelectedItem() != null )
{
attrs.add( ( OrientationRequested )orientation.getSelectedItem() );
}
Object values = getPrintService().getSupportedAttributeValues( MediaPrintableArea.class, DocFlavor.SERVICE_FORMATTED.PRINTABLE, attrs );
if ( values != null )
{
MediaPrintableArea[] mpas = ( MediaPrintableArea[] )values;
supportedArea = mpas[0];
}
else
{
supportedArea = ( MediaPrintableArea )getPrintService().getDefaultAttributeValue( MediaPrintableArea.class );
}
return supportedArea;
}
private void rotateMargins( float topMargin, float leftMargin, float rightMargin, float bottomMargin, OrientationRequested orientationRequested )
{
if ( OrientationRequested.REVERSE_PORTRAIT.equals( orientationRequested ) )
{
float m = leftMargin;
leftMargin = rightMargin;
rightMargin = m;
m = topMargin;
topMargin = bottomMargin;
bottomMargin = m;
}
else
if ( OrientationRequested.LANDSCAPE.equals( orientationRequested ) )
{
float m = leftMargin;
leftMargin = bottomMargin;
bottomMargin = rightMargin;
rightMargin = topMargin;
topMargin = m;
}
else
if ( OrientationRequested.REVERSE_LANDSCAPE.equals( orientationRequested ) )
{
float m = leftMargin;
leftMargin = topMargin;
topMargin = rightMargin;
rightMargin = bottomMargin;
bottomMargin = m;
}
}
// set the values in the margin text fields to be either the minimum
// supported by the printer or the last used margins or the currently
// set margins, also sets a range on the text fields so the user can't
// enter a value too small or too large. Note that it is still possible
// for the user to enter invalid margin values, e.g.
// top margin + bottom margin > printable area height.
void setDefaultMargins()
{
int units = getUnits();
boolean integerOnly = units == MediaPrintableArea.MM;
// get the last margins the user set
Margins margins = ( Margins )attributes.get( Margins.class );
// get the minimum and maximum margins supported by the printer
float[] minMargins = getMinimumMargins();
float[] maxMargins = getMaximumMargins();
// use the printer margins if there are no last used margins
float[] marginValues = margins == null ? minMargins : margins.getMargins( units );
// set the margin text area values
NumericTextField[] numberFields = new NumericTextField[] {topMarginField, leftMarginField, rightMarginField, bottomMarginField};
for ( int i = 0; i < numberFields.length; i++ )
{
NumericTextField field = numberFields[i];
Float currentUserMargin = null;
String text = field.getText();
if ( text != null && !text.isEmpty() )
{
currentUserMargin = new Float( text );
}
Float value = new Float( marginValues[i] );
Float minMargin = new Float( minMargins[i] );
Float maxMargin = new Float( maxMargins[i] );
if ( currentUserMargin == null || currentUserMargin < minMargin || currentUserMargin > maxMargin )
{
// current user margin is invalid
field.setText( integerOnly ? String.valueOf( value.intValue() ) : String.valueOf( value ) );
}
field.setMinValue( integerOnly ? new Integer( minMargin.intValue() ) : new Float( minMargin ) );
field.setMaxValue( integerOnly ? new Integer( maxMargin.intValue() ) : new Float( maxMargin ) );
field.setToolTipText( "Min: " + minMargin + ", max: " + maxMargin );
}
}
// the default margins are the margins that allow the maximum supported
// printable area by the currently selected printer, paper, and orientation,
// returns float[]{topMargin, leftMargin, rightMargin, bottomMargin}
private float[] getMinimumMargins()
{
// get the printable area for the selected paper size and orientation
int units = getUnits();
boolean integerOnly = units == MediaPrintableArea.MM;
MediaPrintableArea supportedArea = getSupportedPrintableArea();
// Log.log( Log.DEBUG, this, "supportedArea = " + supportedArea.getX( units ) + ", " + supportedArea.getY( units ) + ", " + supportedArea.getWidth( units ) + ", " + supportedArea.getHeight( units ) );
// get the selected paper size
Media media = paperSizes.get( paperSize.getSelectedIndex() );
// get paper width and height
MediaSize mediaSize = null;
if ( media instanceof MediaSizeName )
{
MediaSizeName name = ( MediaSizeName )media;
mediaSize = MediaSize.getMediaSizeForName( name );
}
float paperWidth = mediaSize.getX( units );
float paperHeight = mediaSize.getY( units );
// calculate the default margins
float topMargin = supportedArea.getY( units );
topMargin = integerOnly ? new Double( Math.ceil( topMargin ) ).floatValue() : topMargin;
float leftMargin = supportedArea.getX( units );
leftMargin = integerOnly ? new Double( Math.ceil( leftMargin ) ).floatValue() : leftMargin;
float rightMargin = Math.max( 0.0f, paperWidth - leftMargin - supportedArea.getWidth( units ) );
rightMargin = integerOnly ? new Double( Math.ceil( rightMargin ) ).floatValue() : rightMargin;
float bottomMargin = Math.max( 0.0f, paperHeight - topMargin - supportedArea.getHeight( units ) );
bottomMargin = integerOnly ? new Double( Math.ceil( bottomMargin ) ).floatValue() : bottomMargin;
// adjust the margins for the paper orientation
OrientationRequested orientationRequested = ( OrientationRequested )orientation.getSelectedItem();
rotateMargins( topMargin, leftMargin, rightMargin, bottomMargin, orientationRequested );
// Log.log( Log.DEBUG, this, "getMinimumMargins returning " + topMargin + ", " + leftMargin + ", " + rightMargin + ", " + bottomMargin);
return new float[] {topMargin, leftMargin, rightMargin, bottomMargin};
}
private float[] getMaximumMargins()
{
// get the printable area for the selected paper size and orientation
int units = getUnits();
boolean integerOnly = units == MediaPrintableArea.MM;
MediaPrintableArea supportedArea = getSupportedPrintableArea();
// Log.log( Log.DEBUG, this, "supportedArea = " + supportedArea.getX( units ) + ", " + supportedArea.getY( units ) + ", " + supportedArea.getWidth( units ) + ", " + supportedArea.getHeight( units ) );
// get the selected paper size
Media media = paperSizes.get( paperSize.getSelectedIndex() );
// get paper width and height
MediaSize mediaSize = null;
if ( media instanceof MediaSizeName )
{
MediaSizeName name = ( MediaSizeName )media;
mediaSize = MediaSize.getMediaSizeForName( name );
}
float paperWidth = mediaSize.getX( units );
float paperHeight = mediaSize.getY( units );
// calculate the maximum margins
float topMargin = supportedArea.getY( units ) + supportedArea.getHeight( units );
topMargin = integerOnly ? new Double( Math.ceil( topMargin ) ).floatValue() : topMargin;
float leftMargin = supportedArea.getX( units ) + supportedArea.getWidth( units );
leftMargin = integerOnly ? new Double( Math.ceil( leftMargin ) ).floatValue() : leftMargin;
float rightMargin = paperWidth - supportedArea.getX( units );
rightMargin = integerOnly ? new Double( Math.ceil( rightMargin ) ).floatValue() : rightMargin;
float bottomMargin = paperHeight - supportedArea.getY( units );
bottomMargin = integerOnly ? new Double( Math.ceil( bottomMargin ) ).floatValue() : bottomMargin;
// adjust the margins for the paper orientation
OrientationRequested orientationRequested = ( OrientationRequested )orientation.getSelectedItem();
rotateMargins( topMargin, leftMargin, rightMargin, bottomMargin, orientationRequested );
// Log.log( Log.DEBUG, this, "getMinimumMargins returning " + topMargin + ", " + leftMargin + ", " + rightMargin + ", " + bottomMargin);
return new float[] {topMargin, leftMargin, rightMargin, bottomMargin};
}
// returns INCH or MM depending on Locale
// note that while Canada is mostly metric, Canadian paper sizes
// are essentially US ANSI sizes rounded to the nearest 5 mm
private int getUnits()
{
String country = Locale.getDefault().getCountry();
if ( "".equals( country ) || Locale.US.getCountry().equals( country ) || Locale.CANADA.getCountry().equals( country ) )
{
return MediaPrintableArea.INCH;
}
return MediaPrintableArea.MM;
}
}
private class JobPanel extends PrinterPanel
{
private JRadioButton nowButton;
private JRadioButton atButton;
private JRadioButton holdButton;
private JSpinner when;
// need 3 subpanels, Job Details, Print Document, and Finishing
public JobPanel()
{
super();
// job details panel
JPanel jobPanel = new JPanel( new FlowLayout( FlowLayout.LEFT ) );
jobPanel.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), jEdit.getProperty( "print.dialog.Job_Details", "Job Details" ) ), BorderFactory.createEmptyBorder( 11, 11, 11, 11 ) ) );
priority = new JComboBox<Priority>();
priority.addItem( Priority.LOW );
priority.addItem( Priority.MEDIUM );
priority.addItem( Priority.HIGH );
priority.addItem( Priority.URGENT );
priority.setSelectedItem( Priority.MEDIUM );
Box priorityBox = Box.createHorizontalBox();
priorityBox.add( new JLabel( jEdit.getProperty( "print.dialog.Priority", "Priority" ) + ':' ) );
priorityBox.add( Box.createHorizontalStrut( 6 ) );
priorityBox.add( priority );
jobPanel.add( priorityBox );
// when to print panel
JPanel printPanel = new JPanel( new VariableGridLayout( VariableGridLayout.FIXED_NUM_COLUMNS, 2, 6, 6 ) );
printPanel.setBorder( BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder( BorderFactory.createEtchedBorder(), jEdit.getProperty( "print.dialog.Print_Document", "Print Document" ) ),
BorderFactory.createEmptyBorder( 11, 11, 11, 11 ) ) );
// print now
nowButton = new JRadioButton( jEdit.getProperty( "print.dialog.Now", "Now" ) );
nowButton.setSelected( true );
// print later
atButton = new JRadioButton( jEdit.getProperty( "print.dialog.At", "At" ) );
atButton.setEnabled( true );
atButton.addActionListener( new ActionListener()
{
public void actionPerformed( ActionEvent ae )
{
when.setEnabled( atButton.isSelected() );
}
}
);
Calendar calendar = Calendar.getInstance( Locale.getDefault() );
Date initialDate = calendar.getTime();
calendar.add( Calendar.YEAR, 1 );
Date latestDate = calendar.getTime();
SpinnerDateModel dateModel = new SpinnerDateModel( initialDate, initialDate, latestDate, Calendar.YEAR );
when = new JSpinner( dateModel );
when.setEnabled( true );
// print hold
holdButton = new JRadioButton( jEdit.getProperty( "print.dialog.On_Hold", "On Hold" ) );
holdButton.setEnabled( true );
new MyButtonGroup( nowButton, atButton, holdButton );
printPanel.add( nowButton );
printPanel.add( Box.createGlue() );
printPanel.add( atButton );
printPanel.add( when );
printPanel.add( holdButton );
printPanel.add( Box.createGlue() );
JPanel content = new JPanel( new VariableGridLayout( VariableGridLayout.FIXED_NUM_COLUMNS, 2, 6, 6 ) );
content.add( jobPanel );
content.add( printPanel );
add( content, BorderLayout.NORTH );
}
public AttributeSet getAttributes()
{
AttributeSet as = new HashAttributeSet();
as.add( new JobPriority( ( ( Priority )priority.getSelectedItem() ).getValue() ) );
if ( finishing.isEnabled() )
{
as.add( ( Finishings )finishing.getSelectedItem() );
}
Date holdUntil = new Date( 0L ); // print now
if ( atButton.isSelected() )
{
// print later
holdUntil = ( ( SpinnerDateModel )when.getModel() ).getDate();
}
else
if ( holdButton.isSelected() )
{
// hold for a year, seems weird
Calendar later = Calendar.getInstance();
later.add( Calendar.YEAR, 1 );
holdUntil = later.getTime();
}
as.add( new JobHoldUntil( holdUntil ) );
return as;
}
}
private static class Priority
{
public static final Priority LOW = new Priority( 1, jEdit.getProperty( "print.dialog.Low", "Low" ) );
public static final Priority MEDIUM = new Priority( 50, jEdit.getProperty( "print.dialog.Medium", "Medium" ) );
public static final Priority HIGH = new Priority( 80, jEdit.getProperty( "print.dialog.High", "High" ) );
public static final Priority URGENT = new Priority( 100, jEdit.getProperty( "print.dialog.Urgent", "Urgent" ) );
private int value;
private String name;
private Priority( int value, String name )
{
this.value = value;
this.name = name;
}
@Override
public String toString()
{
return name;
}
public int getValue()
{
return value;
}
}
private class AdvancedPanel extends PrinterPanel
{
private JComboBox<PrintQuality> quality;
private JComboBox<Chromaticity> chromaticity;
public AdvancedPanel()
{
super();
quality = new JComboBox<PrintQuality>();
quality.addItem( PrintQuality.DRAFT );
quality.addItem( PrintQuality.NORMAL );
quality.addItem( PrintQuality.HIGH );
quality.setSelectedItem( PrintQuality.NORMAL );
quality.setRenderer( new QualityCellRenderer() );
chromaticity = new JComboBox<Chromaticity>();
chromaticity.addItem( Chromaticity.MONOCHROME );
chromaticity.addItem( Chromaticity.COLOR );
Chromaticity value = ( Chromaticity )attributes.get( Chromaticity.class );
if ( value != null )
{
if ( "color".equalsIgnoreCase( value.toString() ) )
{
chromaticity.setSelectedItem( Chromaticity.COLOR );
}
else
{
chromaticity.setSelectedItem( Chromaticity.MONOCHROME );
}
}
else
{
chromaticity.setSelectedItem( Chromaticity.MONOCHROME );
}
chromaticity.setRenderer( new ChromaticityCellRenderer() );
JPanel content = new JPanel( new VariableGridLayout( VariableGridLayout.FIXED_NUM_COLUMNS, 2, 6, 6 ) );
content.add( new JLabel( jEdit.getProperty( "print.dialog.Quality", "Quality" ) ) );
content.add( quality );
content.add( new JLabel( jEdit.getProperty( "print.dialog.Ink", "Ink" ) ) );
content.add( chromaticity );
add( content, BorderLayout.NORTH );
}
public AttributeSet getAttributes()
{
AttributeSet as = new HashAttributeSet();
as.add( ( Chromaticity )chromaticity.getSelectedItem() );
as.add( ( PrintQuality )quality.getSelectedItem() );
return as;
}
// quality renderer
class QualityCellRenderer extends JLabel implements ListCellRenderer <PrintQuality>
{
public QualityCellRenderer()
{
setOpaque( true );
}
public Component getListCellRendererComponent( JList<? extends PrintQuality> list,
PrintQuality value,
int index,
boolean isSelected,
boolean cellHasFocus )
{
setText( value == null ? "" : getMessage( value.toString() ) );
return this;
}
}
// Chromaticity renderer
class ChromaticityCellRenderer extends JLabel implements ListCellRenderer <Chromaticity>
{
public ChromaticityCellRenderer()
{
setOpaque( true );
}
public Component getListCellRendererComponent( JList<? extends Chromaticity> list,
Chromaticity value,
int index,
boolean isSelected,
boolean cellHasFocus )
{
setText( value == null ? "" : getMessage( value.toString() ) );
return this;
}
}
}
private class jEditPanel extends PrinterPanel
{
private FontSelector font;
private JCheckBox printHeader;
private JCheckBox printFooter;
private JCheckBox printLineNumbers;
private JCheckBox printFolds;
private JComboBox<String> tabSize;
public jEditPanel()
{
super();
/* Font */
font = new FontSelector( jEdit.getFontProperty( "print.font" ) );
/* Header */
printHeader = new JCheckBox( jEdit.getProperty( "options.print.header" ) );
printHeader.setSelected( jEdit.getBooleanProperty( "print.header" ) );
/* Footer */
printFooter = new JCheckBox( jEdit.getProperty("options.print.footer" ) );
printFooter.setSelected( jEdit.getBooleanProperty( "print.footer" ) );
/* Line numbering */
printLineNumbers = new JCheckBox( jEdit.getProperty( "options.print.lineNumbers" ) );
printLineNumbers.setSelected( jEdit.getBooleanProperty( "print.lineNumbers" ) );
/* Tab size */
String[] tabSizes = {"2", "4", "8"};
tabSize = new JComboBox<String>( tabSizes );
tabSize.setEditor( new NumericTextField( "", true, true ) );
tabSize.setEditable( true );
tabSize.setSelectedItem( jEdit.getProperty( "print.tabSize" ) );
/* Print Folds */
printFolds = new JCheckBox( jEdit.getProperty( "options.print.folds" ) );
printFolds.setSelected( jEdit.getBooleanProperty( "print.folds", true ) );
JPanel content = new JPanel( new VariableGridLayout( VariableGridLayout.FIXED_NUM_COLUMNS, 2, 6, 6 ) );
content.add( new JLabel(jEdit.getProperty( "options.print.font" ) ) );
content.add( font );
content.add( new JLabel(jEdit.getProperty( "options.print.tabSize" ) ) );
content.add( tabSize );
content.add( printHeader );
content.add( Box.createGlue());
content.add( printFooter );
content.add( Box.createGlue());
content.add( printLineNumbers );
content.add( Box.createGlue());
content.add( printFolds );
content.add( Box.createGlue());
add( content, BorderLayout.NORTH );
}
public AttributeSet getAttributes()
{
jEdit.setFontProperty( "print.font", font.getFont() );
jEdit.setBooleanProperty( "print.header", printHeader.isSelected() );
jEdit.setBooleanProperty( "print.footer", printFooter.isSelected() );
jEdit.setBooleanProperty( "print.lineNumbers", printLineNumbers.isSelected() );
jEdit.setProperty( "print.tabSize", ( String )tabSize.getSelectedItem() );
jEdit.setBooleanProperty( "print.folds", printFolds.isSelected() );
return null;
}
}
class MyButtonGroup extends ButtonGroup
{
// ButtonGroup should have this
public MyButtonGroup( AbstractButton... buttons )
{
super();
for ( AbstractButton b : buttons )
{
super.add( b );
}
}
}
// map to lookup the names returned from the print service as more human
// readable names
public void initMessages()
{
messageMap = new HashMap<String, String>();
messageMap.put( "Automatic-Feeder", jEdit.getProperty( "print.dialog.Automatic-Feeder", "Automatic Feeder" ) );
messageMap.put( "Cassette", jEdit.getProperty( "print.dialog.Cassette", "Cassette" ) );
messageMap.put( "Form-Source", jEdit.getProperty( "print.dialog.Form-Source", "Form Source" ) );
messageMap.put( "Large-Format", jEdit.getProperty( "print.dialog.Large-Format", "Large Format" ) );
messageMap.put( "Manual-Envelope", jEdit.getProperty( "print.dialog.Manual-Envelope", "Manual Envelope" ) );
messageMap.put( "Small-Format", jEdit.getProperty( "print.dialog.Small-Format", "Small Format" ) );
messageMap.put( "Tractor-Feeder", jEdit.getProperty( "print.dialog.Tractor-Feeder", "Tractor Feeder" ) );
messageMap.put( "a", jEdit.getProperty( "print.dialog.a", "Engineering A" ) );
messageMap.put( "accepting-jobs", jEdit.getProperty( "print.dialog.accepting-jobs", "Accepting jobs" ) );
messageMap.put( "auto-select", jEdit.getProperty( "print.dialog.auto-select", "Automatically Select" ) );
messageMap.put( "b", jEdit.getProperty( "print.dialog.b", "Engineering B" ) );
messageMap.put( "c", jEdit.getProperty( "print.dialog.c", "Engineering C" ) );
messageMap.put( "color", jEdit.getProperty( "print.dialog.Color", "Color" ) );
messageMap.put( "d", jEdit.getProperty( "print.dialog.d", "Engineering D" ) );
messageMap.put( "draft", jEdit.getProperty( "print.dialog.Draft", "Draft" ) );
messageMap.put( "e", jEdit.getProperty( "print.dialog.e", "Engineering E" ) );
messageMap.put( "envelope", jEdit.getProperty( "print.dialog.envelope", "Envelope" ) );
messageMap.put( "executive", jEdit.getProperty( "print.dialog.executive", "Executive" ) );
messageMap.put( "folio", jEdit.getProperty( "print.dialog.folio", "Folio" ) );
messageMap.put( "high", jEdit.getProperty( "print.dialog.High", "High" ) );
messageMap.put( "invite-envelope", jEdit.getProperty( "print.dialog.invite-envelope", "Invitation Envelope" ) );
messageMap.put( "invoice", jEdit.getProperty( "print.dialog.invoice", "Invoice" ) );
messageMap.put( "iso-2a0", jEdit.getProperty( "print.dialog.iso-2a0", "2A0 (ISO/DIN & JIS)" ) );
messageMap.put( "iso-4a0", jEdit.getProperty( "print.dialog.iso-4a0", "4A0 (ISO/DIN & JIS)" ) );
messageMap.put( "iso-a0", jEdit.getProperty( "print.dialog.iso-a0", "A0 (ISO/DIN & JIS)" ) );
messageMap.put( "iso-a1", jEdit.getProperty( "print.dialog.iso-a1", "A1 (ISO/DIN & JIS)" ) );
messageMap.put( "iso-a2", jEdit.getProperty( "print.dialog.iso-a2", "A2 (ISO/DIN & JIS)" ) );
messageMap.put( "iso-a3", jEdit.getProperty( "print.dialog.iso-a3", "A3 (ISO/DIN & JIS)" ) );
messageMap.put( "iso-a4", jEdit.getProperty( "print.dialog.iso-a4", "A4 (ISO/DIN & JIS)" ) );
messageMap.put( "iso-a5", jEdit.getProperty( "print.dialog.iso-a5", "A5 (ISO/DIN & JIS)" ) );
messageMap.put( "iso-a6", jEdit.getProperty( "print.dialog.iso-a6", "A6 (ISO/DIN & JIS)" ) );
messageMap.put( "iso-a7", jEdit.getProperty( "print.dialog.iso-a7", "A7 (ISO/DIN & JIS)" ) );
messageMap.put( "iso-a8", jEdit.getProperty( "print.dialog.iso-a8", "A8 (ISO/DIN & JIS)" ) );
messageMap.put( "iso-a9", jEdit.getProperty( "print.dialog.iso-a9", "A9 (ISO/DIN & JIS)" ) );
messageMap.put( "iso-a10", jEdit.getProperty( "print.dialog.iso-a10", "A10 (ISO/DIN & JIS)" ) );
messageMap.put( "iso-b0", jEdit.getProperty( "print.dialog.iso-b0", "B0 (ISO/DIN)" ) );
messageMap.put( "iso-b1", jEdit.getProperty( "print.dialog.iso-b1", "B1 (ISO/DIN)" ) );
messageMap.put( "iso-b2", jEdit.getProperty( "print.dialog.iso-b2", "B2 (ISO/DIN)" ) );
messageMap.put( "iso-b3", jEdit.getProperty( "print.dialog.iso-b3", "B3 (ISO/DIN)" ) );
messageMap.put( "iso-b4", jEdit.getProperty( "print.dialog.iso-b4", "B4 (ISO/DIN)" ) );
messageMap.put( "iso-b5", jEdit.getProperty( "print.dialog.iso-b5", "B5 (ISO/DIN)" ) );
messageMap.put( "iso-b6", jEdit.getProperty( "print.dialog.iso-b6", "B6 (ISO/DIN)" ) );
messageMap.put( "iso-b7", jEdit.getProperty( "print.dialog.iso-b7", "B7 (ISO/DIN)" ) );
messageMap.put( "iso-b8", jEdit.getProperty( "print.dialog.iso-b8", "B8 (ISO/DIN)" ) );
messageMap.put( "iso-b9", jEdit.getProperty( "print.dialog.iso-b9", "B9 (ISO/DIN)" ) );
messageMap.put( "iso-b10", jEdit.getProperty( "print.dialog.iso-b10", "B10 (ISO/DIN)" ) );
messageMap.put( "iso-c0", jEdit.getProperty( "print.dialog.iso-c0", "C0 (ISO/DIN)" ) );
messageMap.put( "iso-c1", jEdit.getProperty( "print.dialog.iso-c1", "C1 (ISO/DIN)" ) );
messageMap.put( "iso-c2", jEdit.getProperty( "print.dialog.iso-c2", "C2 (ISO/DIN)" ) );
messageMap.put( "iso-c3", jEdit.getProperty( "print.dialog.iso-c3", "C3 (ISO/DIN)" ) );
messageMap.put( "iso-c4", jEdit.getProperty( "print.dialog.iso-c4", "C4 (ISO/DIN)" ) );
messageMap.put( "iso-c5", jEdit.getProperty( "print.dialog.iso-c5", "C5 (ISO/DIN)" ) );
messageMap.put( "iso-c6", jEdit.getProperty( "print.dialog.iso-c6", "C6 (ISO/DIN)" ) );
messageMap.put( "iso-c7", jEdit.getProperty( "print.dialog.iso-c7", "C7 (ISO/DIN)" ) );
messageMap.put( "iso-c8", jEdit.getProperty( "print.dialog.iso-c8", "C8 (ISO/DIN)" ) );
messageMap.put( "iso-c9", jEdit.getProperty( "print.dialog.iso-c9", "C9 (ISO/DIN)" ) );
messageMap.put( "iso-c10", jEdit.getProperty( "print.dialog.iso-c10", "C10 (ISO/DIN)" ) );
messageMap.put( "iso-designated-long", jEdit.getProperty( "print.dialog.iso-designated-long", "ISO Designated Long" ) );
messageMap.put( "italian-envelope", jEdit.getProperty( "print.dialog.italian-envelope", "Italy Envelope" ) );
messageMap.put( "italy-envelope", jEdit.getProperty( "print.dialog.italy-envelope", "Italy Envelope" ) );
messageMap.put( "japanese-postcard", jEdit.getProperty( "print.dialog.japanese-postcard", "Postcard (JIS)" ) );
messageMap.put( "jis-b0", jEdit.getProperty( "print.dialog.jis-b0", "B0 (JIS)" ) );
messageMap.put( "jis-b1", jEdit.getProperty( "print.dialog.jis-b1", "B1 (JIS)" ) );
messageMap.put( "jis-b2", jEdit.getProperty( "print.dialog.jis-b2", "B2 (JIS)" ) );
messageMap.put( "jis-b3", jEdit.getProperty( "print.dialog.jis-b3", "B3 (JIS)" ) );
messageMap.put( "jis-b4", jEdit.getProperty( "print.dialog.jis-b4", "B4 (JIS)" ) );
messageMap.put( "jis-b5", jEdit.getProperty( "print.dialog.jis-b5", "B5 (JIS)" ) );
messageMap.put( "jis-b6", jEdit.getProperty( "print.dialog.jis-b6", "B6 (JIS)" ) );
messageMap.put( "jis-b7", jEdit.getProperty( "print.dialog.jis-b7", "B7 (JIS)" ) );
messageMap.put( "jis-b8", jEdit.getProperty( "print.dialog.jis-b8", "B8 (JIS)" ) );
messageMap.put( "jis-b9", jEdit.getProperty( "print.dialog.jis-b9", "B9 (JIS)" ) );
messageMap.put( "jis-b10", jEdit.getProperty( "print.dialog.jis-b10", "B10 (JIS)" ) );
messageMap.put( "landscape", jEdit.getProperty( "print.dialog.landscape", "Landscape" ) );
messageMap.put( "main", jEdit.getProperty( "print.dialog.main", "Main" ) );
messageMap.put( "manual", jEdit.getProperty( "print.dialog.manual", "Manual" ) );
messageMap.put( "middle", jEdit.getProperty( "print.dialog.middle", "Middle" ) );
messageMap.put( "monarch-envelope", jEdit.getProperty( "print.dialog.monarch-envelope", "Monarch Envelope" ) );
messageMap.put( "monochrome", jEdit.getProperty( "print.dialog.Monochrome", "Monochrome" ) );
messageMap.put( "na-5x7", jEdit.getProperty( "print.dialog.na-5x7", "5\") x 7\" Paper" ) );
messageMap.put( "na-6x9-envelope", jEdit.getProperty( "print.dialog.na-6x9-envelope", "6x9 Envelope" ) );
messageMap.put( "na-7x9-envelope", jEdit.getProperty( "print.dialog.na-7x9-envelope", "6x7 Envelope" ) );
messageMap.put( "na-8x10", jEdit.getProperty( "print.dialog.na-8x10", "8\") x 10\" Paper" ) );
messageMap.put( "na-9x11-envelope", jEdit.getProperty( "print.dialog.na-9x11-envelope", "9x11 Envelope" ) );
messageMap.put( "na-9x12-envelope", jEdit.getProperty( "print.dialog.na-9x12-envelope", "9x12 Envelope" ) );
messageMap.put( "na-10x13-envelope", jEdit.getProperty( "print.dialog.na-10x13-envelope", "10x15 Envelope" ) );
messageMap.put( "na-10x14-envelope", jEdit.getProperty( "print.dialog.na-10x14-envelope", "10x15 Envelope" ) );
messageMap.put( "na-10x15-envelope", jEdit.getProperty( "print.dialog.na-10x15-envelope", "10x15 Envelope" ) );
messageMap.put( "na-legal", jEdit.getProperty( "print.dialog.na-legal", "Legal" ) );
messageMap.put( "na-letter", jEdit.getProperty( "print.dialog.na-letter", "Letter" ) );
messageMap.put( "na-number-9-envelope", jEdit.getProperty( "print.dialog.na-number-9-envelope", "No. 9 Envelope" ) );
messageMap.put( "na-number-10-envelope", jEdit.getProperty( "print.dialog.na-number-10-envelope", "No. 10 Envelope" ) );
messageMap.put( "na-number-11-envelope", jEdit.getProperty( "print.dialog.na-number-11-envelope", "No. 11 Envelope" ) );
messageMap.put( "na-number-12-envelope", jEdit.getProperty( "print.dialog.na-number-12-envelope", "No. 12 Envelope" ) );
messageMap.put( "na-number-14-envelope", jEdit.getProperty( "print.dialog.na-number-14-envelope", "No. 14 Envelope" ) );
messageMap.put( "normal", jEdit.getProperty( "print.dialog.Normal", "Normal" ) );
messageMap.put( "not-accepting-jobs", jEdit.getProperty( "print.dialog.not-accepting-jobs", "Not accepting jobs" ) );
messageMap.put( "one-sided", jEdit.getProperty( "print.dialog.one-sided", "One sided" ) );
messageMap.put( "oufuko-postcard", jEdit.getProperty( "print.dialog.oufuko-postcard", "Double Postcard (JIS)" ) );
messageMap.put( "personal-envelope", jEdit.getProperty( "print.dialog.personal-envelope", "Personal Envelope" ) );
messageMap.put( "portrait", jEdit.getProperty( "print.dialog.portrait", "Portrait" ) );
messageMap.put( "quarto", jEdit.getProperty( "print.dialog.quarto", "Quarto" ) );
messageMap.put( "reverse-landscape", jEdit.getProperty( "print.dialog.reverse-landscape", "Reverse Landscape" ) );
messageMap.put( "reverse-portrait", jEdit.getProperty( "print.dialog.reverse-portrait", "Reverse Portrait" ) );
messageMap.put( "side", jEdit.getProperty( "print.dialog.side", "Side" ) );
messageMap.put( "tabloid", jEdit.getProperty( "print.dialog.tabloid", "Tabloid" ) );
messageMap.put( "top", jEdit.getProperty( "print.dialog.top", "Top" ) );
messageMap.put( "two-sided-long-edge", jEdit.getProperty( "print.dialog.two-sided-long-edge", "Two Sided, Long Edge" ) );
messageMap.put( "two-sided-short-edge", jEdit.getProperty( "print.dialog.two-sided-short-edge", "Two Sided, Short Edge" ) );
}
private String getMessage( String key )
{
String value = messageMap.get( key );
return value == null ? key : value;
}
}