/* * Copyright (c) 2012 European Synchrotron Radiation Facility, * Diamond Light Source Ltd. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package fable.framework.imageprint; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.printing.PrintDialog; import org.eclipse.swt.printing.PrinterData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Dialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import fable.framework.imageprint.PrintSettings.Orientation; import fable.framework.imageprint.PrintSettings.Units; /** * ImagePrintSetupDialog is a dialog to set print settings. It works with a copy * of the image and disposes the copy when done. * * @author Kenneth Evans, Jr. */ public class ImagePrintSetupDialog extends Dialog { private static final int TEXT_WIDTH = 75; private static final int CANVAS_BORDER = 10; private static final Point CANVAS_SIZE = new Point(300, 300); private Point canvasSize = CANVAS_SIZE; public static final String[][] hAlignNames = { { "Left", Integer.toString(SWT.LEFT) }, { "Center", Integer.toString(SWT.CENTER) }, { "Right", Integer.toString(SWT.RIGHT) }, { "Fill", Integer.toString(SWT.FILL) }, }; public static final String[][] vAlignNames = { { "Top", Integer.toString(SWT.TOP) }, { "Center", Integer.toString(SWT.CENTER) }, { "Bottom", Integer.toString(SWT.BOTTOM) }, { "Fill", Integer.toString(SWT.FILL) }, }; /** * The local copy of the input settings. Is returned on OK. */ private PrintSettings settings; private Image image; private Canvas canvas; private Text leftText; private Text rightText; private Text topText; private Text bottomText; private Combo hAlignCombo; private Combo vAlignCombo; private Button landscapeButton; private Button portraitButton; private boolean success = false; /** * ImagePrintSetupDialog constructor with default style. * * @param parent * The parent of this control * @param image * The image for the preview. Will not show an image preview if * null. * @param settings * The input PrintSettings. Will construct a default one if null. */ public ImagePrintSetupDialog(Shell parent, Image image, PrintSettings settings) { this(parent, SWT.DIALOG_TRIM, image, settings); } /** * ImagePrintSetupDialog constructor * * @param parent * The parent of this control * @param style * The style settings. * @param image * The image for the preview. Will not show an image preview if * null. * @param settings * The input PrintSettings. Will construct a default one if null. */ public ImagePrintSetupDialog(Shell parent, int style, Image image, PrintSettings settings) { super(parent, style); // Create a copy of the image in case it changes under us if (image != null) { this.image = new Image(image.getDevice(), image, SWT.IMAGE_COPY); } else { this.image = null; } if (settings != null) { this.settings = settings.clone(); } else { this.settings = new PrintSettings(); } } /** * Creates and then opens the dialog. Note that setting or getting whether * to use portrait or not must be handled separately. * * @return The new value of the PrintSettings. */ public PrintSettings open() { Display display = getParent().getDisplay(); Shell shell = new Shell(getParent(), getStyle() | SWT.RESIZE); shell.setText("Print Setup"); createContents(shell); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } if (image != null && !image.isDisposed()) { image.dispose(); image = null; } if (success) { return settings; } else { return null; } } /** * Creates the controls for the dialog. * * @param shell */ private void createContents(final Shell shell) { GridLayout grid = new GridLayout(); grid.numColumns = 1; shell.setLayout(grid); Composite top = new Composite(shell, SWT.NONE); GridDataFactory.fillDefaults().grab(true, true).applyTo(top); grid = new GridLayout(); grid.numColumns = 2; top.setLayout(grid); Composite controls = new Composite(top, SWT.NONE); GridDataFactory.fillDefaults().applyTo(controls); grid = new GridLayout(); grid.numColumns = 1; controls.setLayout(grid); Composite preview = new Composite(top, SWT.NONE); GridDataFactory.fillDefaults().grab(true, true).applyTo(preview); grid = new GridLayout(); grid.numColumns = 1; preview.setLayout(grid); if (image != null) { canvas = new Canvas(preview, SWT.BORDER); GridDataFactory.fillDefaults().grab(true, true).hint(canvasSize) .applyTo(canvas); canvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent ev) { paint(ev); } }); } // Margins Group group = new Group(controls, SWT.NONE); group.setText("Margins"); grid = new GridLayout(); grid.numColumns = 4; group.setLayout(grid); GridDataFactory.fillDefaults().applyTo(group); Label label = new Label(group, SWT.NONE); label.setText("Left"); leftText = new Text(group, SWT.BORDER | SWT.SINGLE | SWT.RIGHT); leftText.setText(settings.getLeftString()); leftText.setToolTipText("Set the left margin"); GridDataFactory.fillDefaults().hint(TEXT_WIDTH, SWT.DEFAULT).applyTo( leftText); leftText.addSelectionListener(new SelectionAdapter() { public void widgetDefaultSelected(SelectionEvent event) { String text = leftText.getText(); PrintSettings.ValueWithUnits vwu = settings .parseUnitsString(text); PrintSettings.ValueWithUnits vwu1 = settings.scaleToInches(vwu); settings.setLeft(vwu1.getVal()); leftText.setText(settings.getLeftString()); canvas.redraw(); } }); label = new Label(group, SWT.NONE); label.setText("Right"); rightText = new Text(group, SWT.BORDER | SWT.SINGLE | SWT.RIGHT); rightText.setText(settings.getRightString()); rightText.setToolTipText("Set the right margin"); GridDataFactory.fillDefaults().hint(TEXT_WIDTH, SWT.DEFAULT).applyTo( rightText); rightText.addSelectionListener(new SelectionAdapter() { public void widgetDefaultSelected(SelectionEvent event) { String text = rightText.getText(); PrintSettings.ValueWithUnits vwu = settings .parseUnitsString(text); PrintSettings.ValueWithUnits vwu1 = settings.scaleToInches(vwu); settings.setRight(vwu1.getVal()); rightText.setText(settings.getRightString()); canvas.redraw(); } }); label = new Label(group, SWT.NONE); label.setText("Top"); topText = new Text(group, SWT.BORDER | SWT.SINGLE | SWT.RIGHT); topText.setText(settings.getTopString()); topText.setToolTipText("Set the top margin"); GridDataFactory.fillDefaults().hint(TEXT_WIDTH, SWT.DEFAULT).applyTo( topText); topText.addSelectionListener(new SelectionAdapter() { public void widgetDefaultSelected(SelectionEvent event) { String text = topText.getText(); PrintSettings.ValueWithUnits vwu = settings .parseUnitsString(text); PrintSettings.ValueWithUnits vwu1 = settings.scaleToInches(vwu); settings.setTop(vwu1.getVal()); topText.setText(settings.getTopString()); canvas.redraw(); } }); label = new Label(group, SWT.NONE); label.setText("Bottom"); bottomText = new Text(group, SWT.BORDER | SWT.SINGLE | SWT.RIGHT); bottomText.setText(settings.getBottomString()); bottomText.setToolTipText("Set the bottom margin"); GridDataFactory.fillDefaults().hint(TEXT_WIDTH, SWT.DEFAULT).applyTo( bottomText); bottomText.addSelectionListener(new SelectionAdapter() { public void widgetDefaultSelected(SelectionEvent event) { String text = bottomText.getText(); PrintSettings.ValueWithUnits vwu = settings .parseUnitsString(text); PrintSettings.ValueWithUnits vwu1 = settings.scaleToInches(vwu); settings.setBottom(vwu1.getVal()); bottomText.setText(settings.getBottomString()); canvas.redraw(); } }); // Alignment group = new Group(controls, SWT.NONE); group.setText("Alignment"); grid = new GridLayout(); grid.numColumns = 2; group.setLayout(grid); GridDataFactory.fillDefaults().applyTo(group); label = new Label(group, SWT.NONE); label.setText("Horizontal"); hAlignCombo = new Combo(group, SWT.NULL); hAlignCombo.setToolTipText("Set the horizontal alignment"); GridDataFactory.fillDefaults().hint(TEXT_WIDTH, SWT.DEFAULT).applyTo( hAlignCombo); int len = hAlignNames.length; int curItem = -1; String[] items = new String[len]; int val; for (int i = 0; i < len; i++) { items[i] = hAlignNames[i][0]; val = Integer.parseInt(hAlignNames[i][1]); if (val == settings.getHorizontalAlign()) { curItem = i; } } hAlignCombo.setItems(items); hAlignCombo.select(curItem); hAlignCombo.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { int idx = hAlignCombo.getSelectionIndex(); int val = Integer.parseInt(hAlignNames[idx][1]); settings.setHorizontalAlign(val); canvas.redraw(); } }); label = new Label(group, SWT.NONE); label.setText("Vertical"); vAlignCombo = new Combo(group, SWT.NULL); vAlignCombo.setToolTipText("Set the horizontal alignment"); GridDataFactory.fillDefaults().hint(TEXT_WIDTH, SWT.DEFAULT).applyTo( vAlignCombo); len = vAlignNames.length; items = new String[len]; for (int i = 0; i < len; i++) { items[i] = vAlignNames[i][0]; val = Integer.parseInt(vAlignNames[i][1]); if (val == settings.getVerticalAlign()) { curItem = i; } } vAlignCombo.setItems(items); vAlignCombo.select(curItem); vAlignCombo.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { int idx = vAlignCombo.getSelectionIndex(); int val = Integer.parseInt(vAlignNames[idx][1]); settings.setVerticalAlign(val); canvas.redraw(); } }); // Units group = new Group(controls, SWT.NONE); group.setText("Units"); grid = new GridLayout(); grid.numColumns = 3; group.setLayout(grid); GridDataFactory.fillDefaults().applyTo(group); Button button = new Button(group, SWT.RADIO); button.setText("in"); button.setToolTipText("Set default units to inches"); button.setSelection(settings.getUnits() == Units.INCH); button.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { settings.setUnits(Units.INCH); resetMarginStrings(); } }); button = new Button(group, SWT.RADIO); button.setText("cm"); button.setToolTipText("Set default units to centimeters"); button.setSelection(settings.getUnits() == Units.CENTIMETER); button.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { settings.setUnits(Units.CENTIMETER); resetMarginStrings(); } }); button = new Button(group, SWT.RADIO); button.setText("mm"); button.setSelection(settings.getUnits() == Units.MILLIMETER); button.setToolTipText("Set default units to millimeters"); button.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { settings.setUnits(Units.MILLIMETER); resetMarginStrings(); } }); // Orientation group = new Group(controls, SWT.NONE); group.setText("Orientation"); grid = new GridLayout(); grid.numColumns = 2; group.setLayout(grid); GridDataFactory.fillDefaults().applyTo(group); portraitButton = new Button(group, SWT.RADIO); portraitButton.setText("Portrait"); portraitButton.setToolTipText("Use Portrait for the preview"); portraitButton .setSelection(settings.getOrientation() != Orientation.LANDSCAPE); portraitButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { settings.setOrientation(Orientation.PORTRAIT); canvas.redraw(); } }); landscapeButton = new Button(group, SWT.RADIO); landscapeButton.setText("Landscape"); landscapeButton.setToolTipText("Use Portrait for the preview"); landscapeButton .setSelection(settings.getOrientation() == Orientation.LANDSCAPE); landscapeButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { settings.setOrientation(Orientation.LANDSCAPE); canvas.redraw(); } }); label = new Label(group, SWT.NONE); label.setText("Note: The orientation is for the preview\n" + "The printer orientation will still have to\n" + "be set for the printer when you print."); GridDataFactory.fillDefaults().span(new Point(2, 1)).applyTo(label); // Print buttons Composite composite = new Composite(controls, SWT.NONE); grid = new GridLayout(); grid.numColumns = 2; composite.setLayout(grid); GridDataFactory.fillDefaults().applyTo(composite); button = new Button(composite, SWT.PUSH); button.setText("Select Printer"); button.setToolTipText("Select a printer (Will not actually print)"); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo( composite); button.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent ev) { // Make a printer dialog to let the user select a printer PrintDialog dialog = new PrintDialog(shell); PrinterData printerData = dialog.open(); if (printerData == null) { // The user canceled the dialog return; } // Set this printer data into the settings and redraw settings.setPrinterData(printerData); canvas.redraw(); } }); button = new Button(composite, SWT.PUSH); button.setText("Print"); button.setToolTipText("Print now"); GridDataFactory.fillDefaults().align(SWT.CENTER, SWT.CENTER).applyTo( composite); button.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent ev) { ImagePrintUtils.dialogPrintImage(shell, image, shell .getDisplay().getDPI(), settings); } }); // Bottom composite Composite bottom = new Composite(shell, SWT.NONE); GridDataFactory.fillDefaults().grab(true, false).applyTo(bottom); FormLayout form = new FormLayout(); bottom.setLayout(form); Button cancelButton = new Button(bottom, SWT.PUSH); FormData cancelData = new FormData(); cancelData.top = new FormAttachment(group, 8); cancelData.right = new FormAttachment(100, -4); cancelButton.setLayoutData(cancelData); cancelButton.setText("&Cancel"); cancelButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent ev) { success = false; shell.close(); } }); Button okButton = new Button(bottom, SWT.PUSH); FormData okData = new FormData(); okData.top = new FormAttachment(group, 8); okData.right = new FormAttachment(cancelButton, -8); okButton.setLayoutData(okData); okButton.setText("&OK"); okButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent ev) { success = true; shell.close(); } }); } /** * Resets the text in the margin controls to represent the current units. */ private void resetMarginStrings() { leftText.setText(settings.getLeftString()); rightText.setText(settings.getRightString()); topText.setText(settings.getTopString()); bottomText.setText(settings.getBottomString()); } /** * Paint method for the canvas. * * @param ev */ private void paint(PaintEvent ev) { GC gc = ev.gc; // Do not dispose Rectangle canvasBounds = canvas.getClientArea(); canvasBounds.x += CANVAS_BORDER; canvasBounds.y += CANVAS_BORDER; canvasBounds.width -= 2 * CANVAS_BORDER; canvasBounds.height -= 2 * CANVAS_BORDER; if (settings.getPrinterData()!=null) ImagePrintUtils.paintPreview(gc, canvas, canvasBounds, image, settings); } /** * @return The value of canvasSize. */ public Point getCanvasSize() { return canvasSize; } /** * @param canvasSize * The new value for canvasSize. */ public void setCanvasSize(Point canvasSize) { this.canvasSize = canvasSize; } }